@@ -44,13 +44,6 @@
#define DEFAULT_DPU_LINE_WIDTH 2048
#define DEFAULT_DPU_OUTPUT_LINE_WIDTH 2560
-#define MAX_HORZ_DECIMATION 4
-#define MAX_VERT_DECIMATION 4
-
-#define MAX_UPSCALE_RATIO 20
-#define MAX_DOWNSCALE_RATIO 4
-#define SSPP_UNITY_SCALE 1
-
#define STRCAT(X, Y) (X Y)
/*************************************************************
@@ -58,9 +51,12 @@
*************************************************************/
/* DPU top level caps */
static const struct dpu_caps sdm845_dpu_caps = {
+ .max_sspp_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
+ .max_sspp_pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
.max_mixer_width = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
.max_mixer_blendstages = 0xb,
.qseed_type = DPU_SSPP_SCALER_QSEED3,
+ .csc_type = DPU_SSPP_CSC_10BIT,
.ubwc_version = DPU_HW_UBWC_VER_20,
.has_src_split = true,
.has_dim_layer = true,
@@ -128,19 +124,8 @@
* SSPP sub blocks config
*************************************************************/
-/* SSPP common configuration */
-static const struct dpu_sspp_blks_common sdm845_sspp_common = {
- .maxlinewidth = DEFAULT_DPU_OUTPUT_LINE_WIDTH,
- .pixel_ram_size = DEFAULT_PIXEL_RAM_SIZE,
- .maxhdeciexp = MAX_HORZ_DECIMATION,
- .maxvdeciexp = MAX_VERT_DECIMATION,
-};
-
#define _VIG_SBLK(num) \
{ \
- .common = &sdm845_sspp_common, \
- .maxdwnscale = MAX_DOWNSCALE_RATIO, \
- .maxupscale = MAX_UPSCALE_RATIO, \
.src_blk = {.name = STRCAT("sspp_src_", num), \
.id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
.scaler_blk = {.name = STRCAT("sspp_scaler", num), \
@@ -149,17 +134,12 @@
.csc_blk = {.name = STRCAT("sspp_csc", num), \
.id = DPU_SSPP_CSC_10BIT, \
.base = 0x1a00, .len = 0x100,}, \
- .format_list = plane_formats_yuv, \
}
#define _DMA_SBLK(num) \
{ \
- .common = &sdm845_sspp_common, \
- .maxdwnscale = SSPP_UNITY_SCALE, \
- .maxupscale = SSPP_UNITY_SCALE, \
.src_blk = {.name = STRCAT("sspp_src_", num), \
.id = DPU_SSPP_SRC, .base = 0x00, .len = 0x150,}, \
- .format_list = plane_formats, \
}
static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = _VIG_SBLK("0");
@@ -63,6 +63,10 @@
#define CRTC_DUAL_MIXERS 2
+#define MAX_UPSCALE_RATIO 20
+#define MAX_DOWNSCALE_RATIO 4
+#define SSPP_UNITY_SCALE 1
+
#define MAX_XIN_COUNT 16
/**
@@ -290,19 +294,26 @@ struct dpu_qos_lut_tbl {
/**
* struct dpu_caps - define DPU capabilities
- * @max_mixer_width max layer mixer line width support.
- * @max_mixer_blendstages max layer mixer blend stages or
+ * @max_sspp_width max: pixelwidth supported by this pipe
+ * @max_sspp_pixel_ram_size: size of latency hiding and
+ * de-tiling buffer in bytes
+ * @max_mixer_width: max layer mixer line width support
+ * @max_mixer_blendstages: max layer mixer blend stages or
* supported z order
- * @qseed_type qseed2 or qseed3 support.
- * @ubwc_version UBWC feature version (0x0 for not supported)
- * @has_src_split source split feature status
- * @has_dim_layer dim layer feature status
- * @has_idle_pc indicate if idle power collapse feature is supported
+ * @qseed_type: qseed2 or qseed3 support
+ * @csc_type: csc or csc_10bit support
+ * @ubwc_version: UBWC feature version (0x0 for not supported)
+ * @has_src_split: source split feature status
+ * @has_dim_layer: dim layer feature status
+ * @has_idle_pc: indicate if idle power collapse feature is supported
*/
struct dpu_caps {
+ u32 max_sspp_width;
+ u32 max_sspp_pixel_ram_size;
u32 max_mixer_width;
u32 max_mixer_blendstages;
u32 qseed_type;
+ u32 csc_type;
u32 ubwc_version;
bool has_src_split;
bool has_dim_layer;
@@ -310,28 +321,9 @@ struct dpu_caps {
};
/**
- * struct dpu_sspp_blks_common : SSPP sub-blocks common configuration
- * @maxwidth: max pixelwidth supported by this pipe
- * @pixel_ram_size: size of latency hiding and de-tiling buffer in bytes
- * @maxhdeciexp: max horizontal decimation supported by this pipe
- * (max is 2^value)
- * @maxvdeciexp: max vertical decimation supported by this pipe
- * (max is 2^value)
- */
-struct dpu_sspp_blks_common {
- u32 maxlinewidth;
- u32 pixel_ram_size;
- u32 maxhdeciexp;
- u32 maxvdeciexp;
-};
-
-/**
* struct dpu_sspp_sub_blks : SSPP sub-blocks
- * common: Pointer to common configurations shared by sub blocks
* @creq_vblank: creq priority during vertical blanking
* @danger_vblank: danger priority during vertical blanking
- * @maxdwnscale: max downscale ratio supported(without DECIMATION)
- * @maxupscale: maxupscale ratio supported
* @max_per_pipe_bw: maximum allowable bandwidth of this pipe in kBps
* @src_blk:
* @scaler_blk:
@@ -340,14 +332,10 @@ struct dpu_sspp_blks_common {
* @memcolor:
* @pcc_blk:
* @igc_blk:
- * @format_list: Pointer to list of supported formats
*/
struct dpu_sspp_sub_blks {
- const struct dpu_sspp_blks_common *common;
u32 creq_vblank;
u32 danger_vblank;
- u32 maxdwnscale;
- u32 maxupscale;
u32 max_per_pipe_bw;
struct dpu_src_blk src_blk;
struct dpu_scaler_blk scaler_blk;
@@ -356,8 +344,6 @@ struct dpu_sspp_sub_blks {
struct dpu_pp_blk memcolor_blk;
struct dpu_pp_blk pcc_blk;
struct dpu_pp_blk igc_blk;
-
- const struct dpu_format_extended *format_list;
};
/**
@@ -616,13 +616,16 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
/* Create the planes */
for (i = 0; i < catalog->sspp_count; i++) {
- bool primary = true;
+ enum drm_plane_type type;
- if (catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR)
- || primary_planes_idx >= max_crtc_count)
- primary = false;
+ if (catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR))
+ type = DRM_PLANE_TYPE_CURSOR;
+ else if (primary_planes_idx < max_crtc_count)
+ type = DRM_PLANE_TYPE_PRIMARY;
+ else
+ type = DRM_PLANE_TYPE_OVERLAY;
- plane = dpu_plane_init(dev, catalog->sspp[i].id, primary,
+ plane = dpu_plane_init(dev, catalog->sspp[i].id, type,
(1UL << max_crtc_count) - 1);
if (IS_ERR(plane)) {
DPU_ERROR("dpu_plane_init failed\n");
@@ -631,9 +634,9 @@ static int _dpu_kms_drm_obj_init(struct dpu_kms *dpu_kms)
}
priv->planes[priv->num_planes++] = plane;
- if (primary)
+ if (type == DRM_PLANE_TYPE_PRIMARY)
primary_planes[primary_planes_idx++] = plane;
- if (catalog->sspp[i].features & BIT(DPU_SSPP_CURSOR))
+ if (type == DRM_PLANE_TYPE_CURSOR)
cursor_planes[cursor_planes_idx++] = plane;
}
@@ -151,6 +151,7 @@ static bool dpu_plane_sspp_enabled(struct drm_plane_state *state)
static inline int _dpu_plane_calc_fill_level(struct drm_plane *plane,
const struct dpu_format *fmt, u32 src_width)
{
+ struct dpu_kms *kms;
struct dpu_plane *pdpu;
struct dpu_plane_state *pstate;
u32 fixed_buff_size;
@@ -163,7 +164,9 @@ static inline int _dpu_plane_calc_fill_level(struct drm_plane *plane,
pdpu = to_dpu_plane(plane);
pstate = to_dpu_plane_state(plane->state);
- fixed_buff_size = pdpu->pipe_sblk->common->pixel_ram_size;
+
+ kms = _dpu_plane_get_kms(&pdpu->base);
+ fixed_buff_size = kms->catalog->caps->max_sspp_pixel_ram_size;
if (fmt->fetch_planes == DPU_PLANE_PSEUDO_PLANAR) {
if (fmt->chroma_sample == DPU_CHROMA_420) {
@@ -915,12 +918,14 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state)
{
int ret = 0;
+ struct dpu_kms *kms;
struct dpu_plane *pdpu;
struct dpu_plane_state *pstate;
const struct dpu_format *fmt;
struct dpu_rect src, dst;
uint32_t max_upscale, max_downscale, min_src_size, max_linewidth;
bool q16_data = true;
+ uint32_t caps = 0;
if (!plane || !state) {
DPU_ERROR("invalid arg(s), plane %d state %d\n",
@@ -932,11 +937,8 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
pdpu = to_dpu_plane(plane);
pstate = to_dpu_plane_state(state);
- if (!pdpu->pipe_sblk) {
- DPU_ERROR_PLANE(pdpu, "invalid catalog\n");
- ret = -EINVAL;
- goto exit;
- }
+ kms = _dpu_plane_get_kms(&pdpu->base);
+ max_linewidth = kms->catalog->caps->max_sspp_width;
/* src values are in Q16 fixed point, convert to integer */
POPULATE_RECT(&src, state->src_x, state->src_y, state->src_w,
@@ -944,10 +946,6 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
POPULATE_RECT(&dst, state->crtc_x, state->crtc_y, state->crtc_w,
state->crtc_h, !q16_data);
- max_upscale = pdpu->pipe_sblk->maxupscale;
- max_downscale = pdpu->pipe_sblk->maxdwnscale;
- max_linewidth = pdpu->pipe_sblk->common->maxlinewidth;
-
DPU_DEBUG_PLANE(pdpu, "check %d -> %d\n",
dpu_plane_enabled(plane->state), dpu_plane_enabled(state));
@@ -956,18 +954,19 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
fmt = to_dpu_format(msm_framebuffer_format(state->fb));
- min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
+ if (DPU_FORMAT_IS_YUV(fmt))
+ caps |= BIT(kms->catalog->caps->qseed_type) |
+ BIT(kms->catalog->caps->csc_type);
- if (DPU_FORMAT_IS_YUV(fmt) &&
- (!(pdpu->features & DPU_SSPP_SCALER) ||
- !(pdpu->features & (BIT(DPU_SSPP_CSC)
- | BIT(DPU_SSPP_CSC_10BIT))))) {
- DPU_ERROR_PLANE(pdpu,
- "plane doesn't have scaler/csc for yuv\n");
- ret = -EINVAL;
+ if ((src.w != dst.w) || (src.h != dst.h))
+ caps |= BIT(kms->catalog->caps->qseed_type);
+
+ max_upscale = (caps & DPU_SSPP_SCALER) ? MAX_UPSCALE_RATIO : 1;
+ max_downscale = (caps & DPU_SSPP_SCALER) ? MAX_DOWNSCALE_RATIO : 1;
+ min_src_size = DPU_FORMAT_IS_YUV(fmt) ? 2 : 1;
/* check src bounds */
- } else if (state->fb->width > MAX_IMG_WIDTH ||
+ if (state->fb->width > MAX_IMG_WIDTH ||
state->fb->height > MAX_IMG_HEIGHT ||
src.w < min_src_size || src.h < min_src_size ||
CHECK_LAYER_BOUNDS(src.x, src.w, state->fb->width) ||
@@ -989,14 +988,6 @@ static int dpu_plane_sspp_atomic_check(struct drm_plane *plane,
dst.x, dst.y, dst.w, dst.h);
ret = -EINVAL;
- /* decimation validation */
- } else if (!(pdpu->features & DPU_SSPP_SCALER) &&
- ((src.w != dst.w) || (src.h != dst.h))) {
- DPU_ERROR_PLANE(pdpu,
- "pipe doesn't support scaling %ux%u->%ux%u\n",
- src.w, src.h, dst.w, dst.h);
- ret = -EINVAL;
-
/* check decimated source width */
} else if (src.w > max_linewidth) {
DPU_ERROR_PLANE(pdpu,
@@ -1292,9 +1283,6 @@ static void dpu_plane_destroy(struct drm_plane *plane)
/* this will destroy the states as well */
drm_plane_cleanup(plane);
- if (pdpu->pipe_hw)
- dpu_hw_sspp_destroy(pdpu->pipe_hw);
-
kfree(pdpu);
}
}
@@ -1479,8 +1467,6 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane)
struct dpu_plane *pdpu;
struct dpu_kms *kms;
struct msm_drm_private *priv;
- const struct dpu_sspp_sub_blks *sblk = 0;
- const struct dpu_sspp_cfg *cfg = 0;
if (!plane || !plane->dev) {
DPU_ERROR("invalid arguments\n");
@@ -1496,14 +1482,6 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane)
kms = to_dpu_kms(priv->kms);
pdpu = to_dpu_plane(plane);
- if (pdpu && pdpu->pipe_hw)
- cfg = pdpu->pipe_hw->cap;
- if (cfg)
- sblk = cfg->sblk;
-
- if (!sblk)
- return 0;
-
/* create overall sub-directory for the pipe */
pdpu->debugfs_root =
debugfs_create_dir(pdpu->pipe_name,
@@ -1512,60 +1490,6 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane)
if (!pdpu->debugfs_root)
return -ENOMEM;
- /* don't error check these */
- debugfs_create_x32("features", 0600,
- pdpu->debugfs_root, &pdpu->features);
-
- /* add register dump support */
- dpu_debugfs_setup_regset32(&pdpu->debugfs_src,
- sblk->src_blk.base + cfg->base,
- sblk->src_blk.len,
- kms);
- dpu_debugfs_create_regset32("src_blk", 0400,
- pdpu->debugfs_root, &pdpu->debugfs_src);
-
- if (cfg->features & BIT(DPU_SSPP_SCALER_QSEED3) ||
- cfg->features & BIT(DPU_SSPP_SCALER_QSEED2)) {
- dpu_debugfs_setup_regset32(&pdpu->debugfs_scaler,
- sblk->scaler_blk.base + cfg->base,
- sblk->scaler_blk.len,
- kms);
- dpu_debugfs_create_regset32("scaler_blk", 0400,
- pdpu->debugfs_root,
- &pdpu->debugfs_scaler);
- debugfs_create_bool("default_scaling",
- 0600,
- pdpu->debugfs_root,
- &pdpu->debugfs_default_scale);
- }
-
- if (cfg->features & BIT(DPU_SSPP_CSC) ||
- cfg->features & BIT(DPU_SSPP_CSC_10BIT)) {
- dpu_debugfs_setup_regset32(&pdpu->debugfs_csc,
- sblk->csc_blk.base + cfg->base,
- sblk->csc_blk.len,
- kms);
- dpu_debugfs_create_regset32("csc_blk", 0400,
- pdpu->debugfs_root, &pdpu->debugfs_csc);
- }
-
- debugfs_create_u32("xin_id",
- 0400,
- pdpu->debugfs_root,
- (u32 *) &cfg->xin_id);
- debugfs_create_u32("clk_ctrl",
- 0400,
- pdpu->debugfs_root,
- (u32 *) &cfg->clk_ctrl);
- debugfs_create_x32("creq_vblank",
- 0600,
- pdpu->debugfs_root,
- (u32 *) &sblk->creq_vblank);
- debugfs_create_x32("danger_vblank",
- 0600,
- pdpu->debugfs_root,
- (u32 *) &sblk->danger_vblank);
-
debugfs_create_file("disable_danger",
0600,
pdpu->debugfs_root,
@@ -1629,14 +1553,13 @@ enum dpu_sspp dpu_plane_pipe(struct drm_plane *plane)
/* initialize plane */
struct drm_plane *dpu_plane_init(struct drm_device *dev,
- uint32_t pipe, bool primary_plane,
+ uint32_t pipe, enum drm_plane_type type,
unsigned long possible_crtcs)
{
struct drm_plane *plane = NULL;
struct dpu_plane *pdpu;
struct msm_drm_private *priv;
struct dpu_kms *kms;
- enum drm_plane_type type;
int zpos_max = DPU_ZPOS_MAX;
int ret = -EINVAL;
@@ -1670,54 +1593,22 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
goto exit;
}
- /* cache local stuff for later */
plane = &pdpu->base;
- pdpu->pipe = pipe;
-
- /* initialize underlying h/w driver */
- pdpu->pipe_hw = dpu_hw_sspp_init(pipe, kms->mmio, kms->catalog);
- if (IS_ERR(pdpu->pipe_hw)) {
- DPU_ERROR("[%u]SSPP init failed\n", pipe);
- ret = PTR_ERR(pdpu->pipe_hw);
- goto clean_plane;
- } else if (!pdpu->pipe_hw->cap || !pdpu->pipe_hw->cap->sblk) {
- DPU_ERROR("[%u]SSPP init returned invalid cfg\n", pipe);
- goto clean_sspp;
- }
-
- /* cache features mask for later */
- pdpu->features = pdpu->pipe_hw->cap->features;
- pdpu->pipe_sblk = pdpu->pipe_hw->cap->sblk;
- if (!pdpu->pipe_sblk) {
- DPU_ERROR("[%u]invalid sblk\n", pipe);
- goto clean_sspp;
- }
-
- pdpu->nformats = dpu_populate_formats(
- pdpu->pipe_sblk->format_list,
- pdpu->formats,
- 0,
+ pdpu->nformats = dpu_populate_formats(plane_formats_yuv,
+ pdpu->formats, 0,
ARRAY_SIZE(pdpu->formats));
if (!pdpu->nformats) {
DPU_ERROR("[%u]no valid formats for plane\n", pipe);
- goto clean_sspp;
+ goto clean_plane;
}
- if (pdpu->features & BIT(DPU_SSPP_CURSOR))
- type = DRM_PLANE_TYPE_CURSOR;
- else if (primary_plane)
- type = DRM_PLANE_TYPE_PRIMARY;
- else
- type = DRM_PLANE_TYPE_OVERLAY;
ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs,
pdpu->formats, pdpu->nformats,
NULL, type, NULL);
if (ret)
- goto clean_sspp;
-
- pdpu->catalog = kms->catalog;
+ goto clean_plane;
if (kms->catalog->mixer_count &&
kms->catalog->mixer[0].sblk->maxblendstages) {
@@ -1742,9 +1633,6 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev,
pipe, plane->base.id);
return plane;
-clean_sspp:
- if (pdpu && pdpu->pipe_hw)
- dpu_hw_sspp_destroy(pdpu->pipe_hw);
clean_plane:
kfree(pdpu);
exit:
@@ -102,12 +102,11 @@ void dpu_plane_get_ctl_flush(struct drm_plane *plane, struct dpu_hw_ctl *ctl,
* dpu_plane_init - create new dpu plane for the given pipe
* @dev: Pointer to DRM device
* @pipe: dpu hardware pipe identifier
- * @primary_plane: true if this pipe is primary plane for crtc
+ * @type: plane type - PRIMARY/CURSOR/OVERLAY
* @possible_crtcs: bitmask of crtc that can be attached to the given pipe
- *
*/
struct drm_plane *dpu_plane_init(struct drm_device *dev,
- uint32_t pipe, bool primary_plane,
+ uint32_t pipe, enum drm_plane_type type,
unsigned long possible_crtcs);
/**
Expose all planes with superset of formats and with no hw pipe static binding. Accordingly, remove checks from atomic_check reflecting the decoupling. Signed-off-by: Sravanthi Kollukuduru <skolluku@codeaurora.org> --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 26 +--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 50 +++----- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 17 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 158 ++++--------------------- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 5 +- 5 files changed, 56 insertions(+), 200 deletions(-)