diff options
Diffstat (limited to 'drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c')
-rw-r--r-- | drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 209 |
1 files changed, 71 insertions, 138 deletions
diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index f549daf30fe6..b01183b309b9 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -95,8 +95,6 @@ struct dpu_plane { enum dpu_sspp pipe; uint32_t features; /* capabilities from catalog */ - uint32_t nformats; - uint32_t formats[64]; struct dpu_hw_pipe *pipe_hw; struct dpu_hw_pipe_cfg pipe_cfg; @@ -121,6 +119,12 @@ struct dpu_plane { bool debugfs_default_scale; }; +static const uint64_t supported_format_modifiers[] = { + DRM_FORMAT_MOD_QCOM_COMPRESSED, + DRM_FORMAT_MOD_LINEAR, + DRM_FORMAT_MOD_INVALID +}; + #define to_dpu_plane(x) container_of(x, struct dpu_plane, base) static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane) @@ -137,7 +141,7 @@ static struct dpu_kms *_dpu_plane_get_kms(struct drm_plane *plane) * @src_wdith: width of source buffer * Return: fill level corresponding to the source buffer/format or 0 if error */ -static inline int _dpu_plane_calc_fill_level(struct drm_plane *plane, +static int _dpu_plane_calc_fill_level(struct drm_plane *plane, const struct dpu_format *fmt, u32 src_width) { struct dpu_plane *pdpu, *tmp; @@ -365,19 +369,6 @@ static void _dpu_plane_set_qos_ctrl(struct drm_plane *plane, &pdpu->pipe_qos_cfg); } -static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) -{ - struct dpu_plane *pdpu = to_dpu_plane(plane); - struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); - - if (!pdpu->is_rt_pipe) - return; - - pm_runtime_get_sync(&dpu_kms->pdev->dev); - _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL); - pm_runtime_put_sync(&dpu_kms->pdev->dev); -} - /** * _dpu_plane_set_ot_limit - set OT limit for the given plane * @plane: Pointer to drm plane @@ -430,24 +421,14 @@ static void _dpu_plane_set_qos_remap(struct drm_plane *plane) dpu_vbif_set_qos_remap(dpu_kms, &qos_params); } -/** - * _dpu_plane_get_aspace: gets the address space - */ -static inline struct msm_gem_address_space *_dpu_plane_get_aspace( - struct dpu_plane *pdpu) -{ - struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); - - return kms->base.aspace; -} - -static inline void _dpu_plane_set_scanout(struct drm_plane *plane, +static void _dpu_plane_set_scanout(struct drm_plane *plane, struct dpu_plane_state *pstate, struct dpu_hw_pipe_cfg *pipe_cfg, struct drm_framebuffer *fb) { struct dpu_plane *pdpu = to_dpu_plane(plane); - struct msm_gem_address_space *aspace = _dpu_plane_get_aspace(pdpu); + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); + struct msm_gem_address_space *aspace = kms->base.aspace; int ret; ret = dpu_format_populate_layout(aspace, fb, &pipe_cfg->layout); @@ -525,7 +506,7 @@ static void _dpu_plane_setup_scaler3(struct dpu_plane *pdpu, scale_cfg->enable = 1; } -static inline void _dpu_plane_setup_csc(struct dpu_plane *pdpu) +static void _dpu_plane_setup_csc(struct dpu_plane *pdpu) { static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = { { @@ -801,7 +782,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, struct drm_gem_object *obj; struct msm_gem_object *msm_obj; struct dma_fence *fence; - struct msm_gem_address_space *aspace = _dpu_plane_get_aspace(pdpu); + struct dpu_kms *kms = _dpu_plane_get_kms(&pdpu->base); int ret; if (!new_state->fb) @@ -810,7 +791,7 @@ static int dpu_plane_prepare_fb(struct drm_plane *plane, DPU_DEBUG_PLANE(pdpu, "FB[%u]\n", fb->base.id); /* cache aspace */ - pstate->aspace = aspace; + pstate->aspace = kms->base.aspace; /* * TODO: Need to sort out the msm_framebuffer_prepare() call below so @@ -1179,8 +1160,6 @@ static void dpu_plane_destroy(struct drm_plane *plane) mutex_destroy(&pdpu->lock); - drm_plane_helper_disable(plane, NULL); - /* this will destroy the states as well */ drm_plane_cleanup(plane); @@ -1193,19 +1172,8 @@ static void dpu_plane_destroy(struct drm_plane *plane) static void dpu_plane_destroy_state(struct drm_plane *plane, struct drm_plane_state *state) { - struct dpu_plane_state *pstate; - - if (!plane || !state) { - DPU_ERROR("invalid arg(s), plane %d state %d\n", - plane != 0, state != 0); - return; - } - - pstate = to_dpu_plane_state(state); - __drm_atomic_helper_plane_destroy_state(state); - - kfree(pstate); + kfree(to_dpu_plane_state(state)); } static struct drm_plane_state * @@ -1271,30 +1239,29 @@ static void dpu_plane_reset(struct drm_plane *plane) } #ifdef CONFIG_DEBUG_FS -static ssize_t _dpu_plane_danger_read(struct file *file, - char __user *buff, size_t count, loff_t *ppos) +static void dpu_plane_danger_signal_ctrl(struct drm_plane *plane, bool enable) { - struct dpu_kms *kms = file->private_data; - struct dpu_mdss_cfg *cfg = kms->catalog; - int len = 0; - char buf[40] = {'\0'}; - - if (!cfg) - return -ENODEV; + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct dpu_kms *dpu_kms = _dpu_plane_get_kms(plane); - if (*ppos) - return 0; /* the end */ + if (!pdpu->is_rt_pipe) + return; - len = snprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl); - if (len < 0 || len >= sizeof(buf)) - return 0; + pm_runtime_get_sync(&dpu_kms->pdev->dev); + _dpu_plane_set_qos_ctrl(plane, enable, DPU_PLANE_QOS_PANIC_CTRL); + pm_runtime_put_sync(&dpu_kms->pdev->dev); +} - if ((count < sizeof(buf)) || copy_to_user(buff, buf, len)) - return -EFAULT; +static ssize_t _dpu_plane_danger_read(struct file *file, + char __user *buff, size_t count, loff_t *ppos) +{ + struct dpu_kms *kms = file->private_data; + int len; + char buf[40]; - *ppos += len; /* increase offset */ + len = scnprintf(buf, sizeof(buf), "%d\n", !kms->has_danger_ctrl); - return len; + return simple_read_from_buffer(buff, count, ppos, buf, len); } static void _dpu_plane_set_danger_state(struct dpu_kms *kms, bool enable) @@ -1324,23 +1291,12 @@ static ssize_t _dpu_plane_danger_write(struct file *file, const char __user *user_buf, size_t count, loff_t *ppos) { struct dpu_kms *kms = file->private_data; - struct dpu_mdss_cfg *cfg = kms->catalog; int disable_panic; - char buf[10]; - - if (!cfg) - return -EFAULT; - - if (count >= sizeof(buf)) - return -EFAULT; - - if (copy_from_user(buf, user_buf, count)) - return -EFAULT; - - buf[count] = 0; /* end of string */ + int ret; - if (kstrtoint(buf, 0, &disable_panic)) - return -EFAULT; + ret = kstrtouint_from_user(user_buf, count, 0, &disable_panic); + if (ret) + return ret; if (disable_panic) { /* Disable panic signal for all active pipes */ @@ -1365,33 +1321,10 @@ static const struct file_operations dpu_plane_danger_enable = { 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"); - return -EINVAL; - } - - priv = plane->dev->dev_private; - if (!priv || !priv->kms) { - DPU_ERROR("invalid KMS reference\n"); - return -EINVAL; - } - - 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; + struct dpu_plane *pdpu = to_dpu_plane(plane); + struct dpu_kms *kms = _dpu_plane_get_kms(plane); + const struct dpu_sspp_cfg *cfg = pdpu->pipe_hw->cap; + const struct dpu_sspp_sub_blks *sblk = cfg->sblk; /* create overall sub-directory for the pipe */ pdpu->debugfs_root = @@ -1462,25 +1395,11 @@ static int _dpu_plane_init_debugfs(struct drm_plane *plane) return 0; } - -static void _dpu_plane_destroy_debugfs(struct drm_plane *plane) -{ - struct dpu_plane *pdpu; - - if (!plane) - return; - pdpu = to_dpu_plane(plane); - - debugfs_remove_recursive(pdpu->debugfs_root); -} #else static int _dpu_plane_init_debugfs(struct drm_plane *plane) { return 0; } -static void _dpu_plane_destroy_debugfs(struct drm_plane *plane) -{ -} #endif static int dpu_plane_late_register(struct drm_plane *plane) @@ -1490,7 +1409,26 @@ static int dpu_plane_late_register(struct drm_plane *plane) static void dpu_plane_early_unregister(struct drm_plane *plane) { - _dpu_plane_destroy_debugfs(plane); + struct dpu_plane *pdpu = to_dpu_plane(plane); + + debugfs_remove_recursive(pdpu->debugfs_root); +} + +static bool dpu_plane_format_mod_supported(struct drm_plane *plane, + uint32_t format, uint64_t modifier) +{ + if (modifier == DRM_FORMAT_MOD_LINEAR) + return true; + + if (modifier == DRM_FORMAT_MOD_QCOM_COMPRESSED) { + int i; + for (i = 0; i < ARRAY_SIZE(qcom_compressed_supported_formats); i++) { + if (format == qcom_compressed_supported_formats[i]) + return true; + } + } + + return false; } static const struct drm_plane_funcs dpu_plane_funcs = { @@ -1502,6 +1440,7 @@ static const struct drm_plane_funcs dpu_plane_funcs = { .atomic_destroy_state = dpu_plane_destroy_state, .late_register = dpu_plane_late_register, .early_unregister = dpu_plane_early_unregister, + .format_mod_supported = dpu_plane_format_mod_supported, }; static const struct drm_plane_helper_funcs dpu_plane_helper_funcs = { @@ -1527,11 +1466,12 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, unsigned long possible_crtcs, u32 master_plane_id) { struct drm_plane *plane = NULL, *master_plane = NULL; - const struct dpu_format_extended *format_list; + const uint32_t *format_list; struct dpu_plane *pdpu; struct msm_drm_private *priv = dev->dev_private; struct dpu_kms *kms = to_dpu_kms(priv->kms); int zpos_max = DPU_ZPOS_MAX; + uint32_t num_formats; int ret = -EINVAL; /* create and zero local structure */ @@ -1539,7 +1479,7 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, if (!pdpu) { DPU_ERROR("[%u]failed to allocate local plane struct\n", pipe); ret = -ENOMEM; - goto exit; + return ERR_PTR(ret); } /* cache local stuff for later */ @@ -1574,24 +1514,18 @@ struct drm_plane *dpu_plane_init(struct drm_device *dev, goto clean_sspp; } - if (!master_plane_id) - format_list = pdpu->pipe_sblk->format_list; - else + if (pdpu->is_virtual) { format_list = pdpu->pipe_sblk->virt_format_list; - - pdpu->nformats = dpu_populate_formats(format_list, - pdpu->formats, - 0, - ARRAY_SIZE(pdpu->formats)); - - if (!pdpu->nformats) { - DPU_ERROR("[%u]no valid formats for plane\n", pipe); - goto clean_sspp; + num_formats = pdpu->pipe_sblk->virt_num_formats; + } + else { + format_list = pdpu->pipe_sblk->format_list; + num_formats = pdpu->pipe_sblk->num_formats; } ret = drm_universal_plane_init(dev, plane, 0xff, &dpu_plane_funcs, - pdpu->formats, pdpu->nformats, - NULL, type, NULL); + format_list, num_formats, + supported_format_modifiers, type, NULL); if (ret) goto clean_sspp; @@ -1625,6 +1559,5 @@ clean_sspp: dpu_hw_sspp_destroy(pdpu->pipe_hw); clean_plane: kfree(pdpu); -exit: return ERR_PTR(ret); } |