Re: [Freedreno] [PATCH 00/25] drm/msm/dpu: wide planes support
Hi Dmitry I have reviewed the series , some patches completely , some of them especially the plane to sspp mapping is something i still need to check. But I had one question on the design. I thought we were going to have a boot param to control whether driver will internally use both rectangles for the layer so that in the future if compositors can do this splitting, we can use that instead of driver doing it ( keep boot param disabled ? ). Thanks Abhinav On 2/9/2022 9:24 AM, Dmitry Baryshkov wrote: It took me a way longer to finish than I expected. And more patches that I initially hoped. This patchset brings in multirect usage to support using two SSPP rectangles for a single plane. Virtual planes support is omitted from this pull request, it will come later. Dmitry Baryshkov (25): drm/msm/dpu: rip out master planes support drm/msm/dpu: do not limit the zpos property drm/msm/dpu: add support for SSPP allocation to RM drm/msm/dpu: move SSPP debugfs creation to dpu_kms.c drm/msm/dpu: move pipe_hw to dpu_plane_state drm/msm/dpu: inline dpu_plane_get_ctl_flush drm/msm/dpu: drop dpu_plane_pipe function drm/msm/dpu: get rid of cached flush_mask drm/msm/dpu: dpu_crtc_blend_setup: split mixer and ctl logic drm/msm/dpu: introduce struct dpu_sw_pipe drm/msm/dpu: use dpu_sw_pipe for dpu_hw_sspp callbacks drm/msm/dpu: inline _dpu_plane_set_scanout drm/msm/dpu: pass dpu_format to _dpu_hw_sspp_setup_scaler3() drm/msm/dpu: move stride programming to dpu_hw_sspp_setup_sourceaddress drm/msm/dpu: remove dpu_hw_fmt_layout from struct dpu_hw_pipe_cfg drm/msm/dpu: drop EAGAIN check from dpu_format_populate_layout drm/msm/dpu: drop src_split and multirect check from dpu_crtc_atomic_check drm/msm/dpu: move the rest of plane checks to dpu_plane_atomic_check() drm/msm/dpu: don't use unsupported blend stages drm/msm/dpu: add dpu_hw_pipe_cfg to dpu_plane_state drm/msm/dpu: simplify dpu_plane_validate_src() drm/msm/dpu: rewrite plane's QoS-related functions to take dpu_sw_pipe and dpu_format drm/msm/dpu: rework dpu_plane_atomic_check() and dpu_plane_sspp_atomic_update() drm/msm/dpu: populate SmartDMA features in hw catalog drm/msm/dpu: add support for wide planes drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.c | 355 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_crtc.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_formats.c | 4 - .../gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c| 10 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c| 78 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h| 35 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.c | 136 +-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_sspp.h | 88 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.c | 21 +- drivers/gpu/drm/msm/disp/dpu1/dpu_kms.h | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 813 +- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 42 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c| 81 ++ drivers/gpu/drm/msm/disp/dpu1/dpu_rm.h| 6 + drivers/gpu/drm/msm/disp/dpu1/dpu_trace.h | 19 +- 15 files changed, 827 insertions(+), 863 deletions(-)
[Freedreno] [PATCH 3/3] drm/msm: Add a way to override processes comm/cmdline
From: Rob Clark In the cause of using the GPU via virtgpu, the host side process is really a sort of proxy, and not terribly interesting from the PoV of crash/fault logging. Add a way to override these per process so that we can see the guest process's name. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 40 +++-- drivers/gpu/drm/msm/msm_gpu.c | 11 +-- drivers/gpu/drm/msm/msm_gpu.h | 6 drivers/gpu/drm/msm/msm_submitqueue.c | 2 ++ include/uapi/drm/msm_drm.h | 2 ++ 5 files changed, 56 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 3d307b34854d..c68dc9c722c7 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -290,11 +290,45 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, uint32_t param, uint64_t value, uint32_t len) { - /* No pointer params yet */ - if (len != 0) - return -EINVAL; + switch (param) { + case MSM_PARAM_COMM: + case MSM_PARAM_CMDLINE: + /* kstrdup_quotable_cmdline() limits to PAGE_SIZE, so +* that should be a reasonable upper bound +*/ + if (len > PAGE_SIZE) + return -EINVAL; + break; + default: + if (len != 0) + return -EINVAL; + } switch (param) { + case MSM_PARAM_COMM: + case MSM_PARAM_CMDLINE: { + char *str, **paramp; + + str = kmalloc(len + 1, GFP_KERNEL); + if (copy_from_user(str, u64_to_user_ptr(value), len)) { + kfree(str); + return -EFAULT; + } + + /* Ensure string is null terminated: */ + str[len] = '\0'; + + if (param == MSM_PARAM_COMM) { + paramp = >comm; + } else { + paramp = >cmdline; + } + + kfree(*paramp); + *paramp = str; + + return 0; + } case MSM_PARAM_SYSPROF: if (!capable(CAP_SYS_ADMIN)) return -EPERM; diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 4ec62b601adc..68f3f8ade76d 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -364,14 +364,21 @@ static void retire_submits(struct msm_gpu *gpu); static void get_comm_cmdline(struct msm_gem_submit *submit, char **comm, char **cmd) { + struct msm_file_private *ctx = submit->queue->ctx; struct task_struct *task; + *comm = kstrdup(ctx->comm, GFP_KERNEL); + *cmd = kstrdup(ctx->cmdline, GFP_KERNEL); + task = get_pid_task(submit->pid, PIDTYPE_PID); if (!task) return; - *comm = kstrdup(task->comm, GFP_KERNEL); - *cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); + if (!*comm) + *comm = kstrdup(task->comm, GFP_KERNEL); + + if (!*cmd) + *cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); put_task_struct(task); } diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index c28c2ad9f52e..2c0203fd6ce3 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -355,6 +355,12 @@ struct msm_file_private { */ int sysprof; + /** comm: Overridden task comm, see MSM_PARAM_COMM */ + char *comm; + + /** cmdline: Overridden task cmdline, see MSM_PARAM_CMDLINE */ + char *cmdline; + /** * elapsed: * diff --git a/drivers/gpu/drm/msm/msm_submitqueue.c b/drivers/gpu/drm/msm/msm_submitqueue.c index 79b6ccd6ce64..f486a3cd4e55 100644 --- a/drivers/gpu/drm/msm/msm_submitqueue.c +++ b/drivers/gpu/drm/msm/msm_submitqueue.c @@ -61,6 +61,8 @@ void __msm_file_private_destroy(struct kref *kref) } msm_gem_address_space_put(ctx->aspace); + kfree(ctx->comm); + kfree(ctx->cmdline); kfree(ctx); } diff --git a/include/uapi/drm/msm_drm.h b/include/uapi/drm/msm_drm.h index 0aa1a8cb4e0d..794ad1948497 100644 --- a/include/uapi/drm/msm_drm.h +++ b/include/uapi/drm/msm_drm.h @@ -82,6 +82,8 @@ struct drm_msm_timespec { #define MSM_PARAM_FAULTS 0x09 /* RO */ #define MSM_PARAM_SUSPENDS 0x0a /* RO */ #define MSM_PARAM_SYSPROF0x0b /* WO: 1 preserves perfcntrs, 2 also disables suspend */ +#define MSM_PARAM_COMM 0x0c /* WO: override for task->comm */ +#define MSM_PARAM_CMDLINE0x0d /* WO: override for task cmdline */ /* For backwards compat. The original support for preemption was based on * a single ring per priority level so # of priority
[Freedreno] [PATCH 2/3] drm/msm: Split out helper to get comm/cmdline
From: Rob Clark Deduplicate this from fault_worker and recover_worker. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/msm_gpu.c | 32 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/drivers/gpu/drm/msm/msm_gpu.c b/drivers/gpu/drm/msm/msm_gpu.c index 8fe4aee96aa9..4ec62b601adc 100644 --- a/drivers/gpu/drm/msm/msm_gpu.c +++ b/drivers/gpu/drm/msm/msm_gpu.c @@ -362,6 +362,20 @@ find_submit(struct msm_ringbuffer *ring, uint32_t fence) static void retire_submits(struct msm_gpu *gpu); +static void get_comm_cmdline(struct msm_gem_submit *submit, char **comm, char **cmd) +{ + struct task_struct *task; + + task = get_pid_task(submit->pid, PIDTYPE_PID); + if (!task) + return; + + *comm = kstrdup(task->comm, GFP_KERNEL); + *cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); + + put_task_struct(task); +} + static void recover_worker(struct kthread_work *work) { struct msm_gpu *gpu = container_of(work, struct msm_gpu, recover_work); @@ -378,18 +392,11 @@ static void recover_worker(struct kthread_work *work) submit = find_submit(cur_ring, cur_ring->memptrs->fence + 1); if (submit) { - struct task_struct *task; - /* Increment the fault counts */ submit->queue->faults++; submit->aspace->faults++; - task = get_pid_task(submit->pid, PIDTYPE_PID); - if (task) { - comm = kstrdup(task->comm, GFP_KERNEL); - cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); - put_task_struct(task); - } + get_comm_cmdline(submit, , ); if (comm && cmd) { DRM_DEV_ERROR(dev->dev, "%s: offending task: %s (%s)\n", @@ -478,14 +485,7 @@ static void fault_worker(struct kthread_work *work) goto resume_smmu; if (submit) { - struct task_struct *task; - - task = get_pid_task(submit->pid, PIDTYPE_PID); - if (task) { - comm = kstrdup(task->comm, GFP_KERNEL); - cmd = kstrdup_quotable_cmdline(task, GFP_KERNEL); - put_task_struct(task); - } + get_comm_cmdline(submit, , ); /* * When we get GPU iova faults, we can get 1000s of them, -- 2.35.1
[Freedreno] [PATCH 1/3] drm/msm: Add support for pointer params
From: Rob Clark The 64b value field is already suffient to hold a pointer instead of immediate, but we also need a length field. Signed-off-by: Rob Clark --- drivers/gpu/drm/msm/adreno/adreno_gpu.c | 12 ++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 4 ++-- drivers/gpu/drm/msm/msm_drv.c | 8 drivers/gpu/drm/msm/msm_gpu.h | 4 ++-- drivers/gpu/drm/msm/msm_rd.c| 5 +++-- include/uapi/drm/msm_drm.h | 2 ++ 6 files changed, 23 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.c b/drivers/gpu/drm/msm/adreno/adreno_gpu.c index 9efc84929be0..3d307b34854d 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.c +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.c @@ -229,10 +229,14 @@ adreno_iommu_create_address_space(struct msm_gpu *gpu, } int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, -uint32_t param, uint64_t *value) +uint32_t param, uint64_t *value, uint32_t *len) { struct adreno_gpu *adreno_gpu = to_adreno_gpu(gpu); + /* No pointer params yet */ + if (*len != 0) + return -EINVAL; + switch (param) { case MSM_PARAM_GPU_ID: *value = adreno_gpu->info->revn; @@ -284,8 +288,12 @@ int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, } int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, -uint32_t param, uint64_t value) +uint32_t param, uint64_t value, uint32_t len) { + /* No pointer params yet */ + if (len != 0) + return -EINVAL; + switch (param) { case MSM_PARAM_SYSPROF: if (!capable(CAP_SYS_ADMIN)) diff --git a/drivers/gpu/drm/msm/adreno/adreno_gpu.h b/drivers/gpu/drm/msm/adreno/adreno_gpu.h index 0490c5fbb780..ab3b5ef80332 100644 --- a/drivers/gpu/drm/msm/adreno/adreno_gpu.h +++ b/drivers/gpu/drm/msm/adreno/adreno_gpu.h @@ -281,9 +281,9 @@ static inline int adreno_is_a650_family(struct adreno_gpu *gpu) } int adreno_get_param(struct msm_gpu *gpu, struct msm_file_private *ctx, -uint32_t param, uint64_t *value); +uint32_t param, uint64_t *value, uint32_t *len); int adreno_set_param(struct msm_gpu *gpu, struct msm_file_private *ctx, -uint32_t param, uint64_t value); +uint32_t param, uint64_t value, uint32_t len); const struct firmware *adreno_request_fw(struct adreno_gpu *adreno_gpu, const char *fwname); struct drm_gem_object *adreno_fw_create_bo(struct msm_gpu *gpu, diff --git a/drivers/gpu/drm/msm/msm_drv.c b/drivers/gpu/drm/msm/msm_drv.c index 780f9748aaaf..a5eed5738ac8 100644 --- a/drivers/gpu/drm/msm/msm_drv.c +++ b/drivers/gpu/drm/msm/msm_drv.c @@ -610,7 +610,7 @@ static int msm_ioctl_get_param(struct drm_device *dev, void *data, /* for now, we just have 3d pipe.. eventually this would need to * be more clever to dispatch to appropriate gpu module: */ - if (args->pipe != MSM_PIPE_3D0) + if ((args->pipe != MSM_PIPE_3D0) || (args->pad != 0)) return -EINVAL; gpu = priv->gpu; @@ -619,7 +619,7 @@ static int msm_ioctl_get_param(struct drm_device *dev, void *data, return -ENXIO; return gpu->funcs->get_param(gpu, file->driver_priv, -args->param, >value); +args->param, >value, >len); } static int msm_ioctl_set_param(struct drm_device *dev, void *data, @@ -629,7 +629,7 @@ static int msm_ioctl_set_param(struct drm_device *dev, void *data, struct drm_msm_param *args = data; struct msm_gpu *gpu; - if (args->pipe != MSM_PIPE_3D0) + if ((args->pipe != MSM_PIPE_3D0) || (args->pad != 0)) return -EINVAL; gpu = priv->gpu; @@ -638,7 +638,7 @@ static int msm_ioctl_set_param(struct drm_device *dev, void *data, return -ENXIO; return gpu->funcs->set_param(gpu, file->driver_priv, -args->param, args->value); +args->param, args->value, args->len); } static int msm_ioctl_gem_new(struct drm_device *dev, void *data, diff --git a/drivers/gpu/drm/msm/msm_gpu.h b/drivers/gpu/drm/msm/msm_gpu.h index a84140055920..c28c2ad9f52e 100644 --- a/drivers/gpu/drm/msm/msm_gpu.h +++ b/drivers/gpu/drm/msm/msm_gpu.h @@ -44,9 +44,9 @@ struct msm_gpu_config { */ struct msm_gpu_funcs { int (*get_param)(struct msm_gpu *gpu, struct msm_file_private *ctx, -uint32_t param, uint64_t *value); +uint32_t param, uint64_t *value, uint32_t *len); int (*set_param)(struct msm_gpu *gpu, struct msm_file_private *ctx, -uint32_t param, uint64_t value); +uint32_t param,
[Freedreno] [PATCH 0/3] drm/msm: Add comm/cmdline override
From: Rob Clark Add a way to override comm/cmdline per-drm_file. This is useful for VM scenarios where the host process is just a proxy for the actual guest process. Rob Clark (3): drm/msm: Add support for pointer params drm/msm: Split out helper to get comm/cmdline drm/msm: Add a way to override processes comm/cmdline drivers/gpu/drm/msm/adreno/adreno_gpu.c | 46 +++-- drivers/gpu/drm/msm/adreno/adreno_gpu.h | 4 +-- drivers/gpu/drm/msm/msm_drv.c | 8 ++--- drivers/gpu/drm/msm/msm_gpu.c | 39 - drivers/gpu/drm/msm/msm_gpu.h | 10 -- drivers/gpu/drm/msm/msm_rd.c| 5 +-- drivers/gpu/drm/msm/msm_submitqueue.c | 2 ++ include/uapi/drm/msm_drm.h | 4 +++ 8 files changed, 90 insertions(+), 28 deletions(-) -- 2.35.1
[Freedreno] 2022 X.Org Foundation Membership deadline for voting in the election
The 2022 X.Org Foundation elections are rapidly approaching. We will be forwarding the election schedule and nominating process to the membership shortly. Please note that only current members can vote in the upcoming election, and that the deadline for new memberships or renewals to vote in the upcoming election is 31 March 2022 at 23:59 UTC. If you are interested in joining the X.Org Foundation or in renewing your membership, please visit the membership system site at: https://members.x.org/ Lyude Paul, on behalf of the X.Org elections committee
[Freedreno] 2022 X.Org Board of Directors Elections Nomination period is NOW
The Board consists of directors elected from the membership. Each year, an election is held to bring the total number of directors to eight. The four members receiving the highest vote totals will serve as directors for two year terms. The directors who received two year terms starting in 2021 were Lyude Paul, Samuel Iglesias Gonsálvez, Manasi D Navare and Daniel Vetter. They will continue to serve until their term ends in 2023. Current directors whose term expires in 2022 are Emma Anholt, Keith Packard, Harry Wentland and Mark Filion. A director is expected to participate in the fortnightly IRC meeting to discuss current business and to attend the annual meeting of the X.Org Foundation, which will be held at a location determined in advance by the Board of Directors. A member may nominate themselves or any other member they feel is qualified. Nominations should be sent to the Election Committee at elections at x.org. Nominees shall be required to be current members of the X.Org Foundation, and submit a personal statement of up to 200 words that will be provided to prospective voters. The collected statements, along with the statement of contribution to the X.Org Foundation in the member's account page on http://members.x.org, will be made available to all voters to help them make their voting decisions. Nominations, membership applications or renewals and completed personal statements must be received no later than 23:59 UTC on 20th March 2022. The slate of candidates will be published 28th March 2022 and candidate Q will begin then. The deadline for Xorg membership applications and renewals is 31st March 2022. Cheers, Lyude Paul, on behalf of the X.Org BoD
[Freedreno] [PATCH v3 2/3] drm: introduce drm_writeback_connector_init_with_encoder API
For vendors drivers which pass an already allocated and initialized encoder especially for cases where the encoder hardware is shared OR the writeback encoder shares the resources with the rest of the display pipeline introduce a new API, drm_writeback_connector_init_with_encoder() which expects an initialized encoder as a parameter and only sets up the writeback connector. Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/drm_writeback.c | 42 + include/drm/drm_writeback.h | 5 + 2 files changed, 47 insertions(+) diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index 17c1471..373b7e9 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -265,6 +265,48 @@ int drm_writeback_connector_init(struct drm_device *dev, } EXPORT_SYMBOL(drm_writeback_connector_init); +/** + * drm_writeback_connector_init_with_encoder - Initialize a writeback connector and its properties + * using the encoder which already assigned and initialized + * + * @dev: DRM device + * @wb_connector: Writeback connector to initialize + * @con_funcs: Connector funcs vtable + * @enc_helper_funcs: Encoder helper funcs vtable to be used by the internal encoder + * @formats: Array of supported pixel formats for the writeback engine + * @n_formats: Length of the formats array + * + * This function creates the writeback-connector-specific properties if they + * have not been already created, initializes the connector as + * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property + * values. + * + * This function assumes that the drm_writebac_connector's encoder has already been + * created and initialized before invoking this function. + * + * In addition, this function also assumes that callers of this API will manage + * assigning the encoder helper functions, possible_crtcs and any other encoder + * specific operation which is otherwise handled by drm_writeback_connector_init(). + * + * Drivers should always use this function instead of drm_connector_init() to + * set up writeback connectors. + * + * Returns: 0 on success, or a negative error code + */ +int drm_writeback_connector_init_with_encoder(struct drm_device *dev, + struct drm_writeback_connector *wb_connector, + const struct drm_connector_funcs *con_funcs, const u32 *formats, + int n_formats) +{ + int ret = 0; + + ret = drm_writeback_connector_setup(dev, wb_connector, con_funcs, formats, + n_formats); + + return ret; +} +EXPORT_SYMBOL(drm_writeback_connector_init_with_encoder); + int drm_writeback_set_fb(struct drm_connector_state *conn_state, struct drm_framebuffer *fb) { diff --git a/include/drm/drm_writeback.h b/include/drm/drm_writeback.h index 5e002bc..5e752c8 100644 --- a/include/drm/drm_writeback.h +++ b/include/drm/drm_writeback.h @@ -168,6 +168,11 @@ int drm_writeback_connector_init(struct drm_device *dev, const struct drm_encoder_helper_funcs *enc_helper_funcs, const u32 *formats, int n_formats, uint32_t possible_crtcs); +int drm_writeback_connector_init_with_encoder(struct drm_device *dev, + struct drm_writeback_connector *wb_connector, + const struct drm_connector_funcs *con_funcs, const u32 *formats, + int n_formats); + int drm_writeback_set_fb(struct drm_connector_state *conn_state, struct drm_framebuffer *fb); -- 2.7.4
[Freedreno] [PATCH v3 3/3] drm/vc4: change vc4 driver to use drm_writeback_connector_init_with_encoder()
vc4 driver currently embeds the drm_encoder into struct vc4_txp and later on uses container_of to retrieve the vc4_txp from the drm_encoder. Since drm_encoder has now been made a pointer inside drm_writeback_connector, make vc4 driver use the new API so that the embedded encoder model can be retained in the driver and there is no change in functionality. changes in v3: - none Signed-off-by: Abhinav Kumar --- drivers/gpu/drm/vc4/vc4_txp.c | 22 ++ 1 file changed, 18 insertions(+), 4 deletions(-) diff --git a/drivers/gpu/drm/vc4/vc4_txp.c b/drivers/gpu/drm/vc4/vc4_txp.c index 32c4fb0..36dffcf 100644 --- a/drivers/gpu/drm/vc4/vc4_txp.c +++ b/drivers/gpu/drm/vc4/vc4_txp.c @@ -370,6 +370,10 @@ static const struct drm_encoder_helper_funcs vc4_txp_encoder_helper_funcs = { .disable = vc4_txp_encoder_disable, }; +static const struct drm_encoder_funcs vc4_txp_encoder_funcs = { + .destroy = drm_encoder_cleanup, +}; + static int vc4_txp_enable_vblank(struct drm_crtc *crtc) { return 0; @@ -498,13 +502,23 @@ static int vc4_txp_bind(struct device *dev, struct device *master, void *data) wb_conn = >connector; wb_conn->encoder = >drm_enc; + drm_encoder_helper_add(wb_conn->encoder, _txp_encoder_helper_funcs); + + ret = drm_encoder_init(drm, wb_conn->encoder, + _txp_encoder_funcs, + DRM_MODE_ENCODER_VIRTUAL, NULL); + + if (ret) + return ret; + drm_connector_helper_add(_conn->base, _txp_connector_helper_funcs); - ret = drm_writeback_connector_init(drm, wb_conn, - _txp_connector_funcs, _txp_encoder_helper_funcs, - drm_fmts, ARRAY_SIZE(drm_fmts), 0); - if (ret) + ret = drm_writeback_connector_init_with_encoder(drm, wb_conn, + _txp_connector_funcs, drm_fmts, ARRAY_SIZE(drm_fmts)); + if (ret) { + drm_encoder_cleanup(wb_conn->encoder); return ret; + } ret = vc4_crtc_init(drm, vc4_crtc, _txp_crtc_funcs, _txp_crtc_helper_funcs); -- 2.7.4
[Freedreno] [PATCH v3 1/3] drm: allow real encoder to be passed for drm_writeback_connector
For some vendor driver implementations, display hardware can be shared between the encoder used for writeback and the physical display. In addition resources such as clocks and interrupts can also be shared between writeback and the real encoder. To accommodate such vendor drivers and hardware, allow real encoder to be passed for drm_writeback_connector using a new drm_writeback_connector_init_with_encoder() API. In addition, to preserve the same call flows for the existing users of drm_writeback_connector_init(), also allow passing possible_crtcs as a parameter so that encoder can be initialized with it. changes in v3: - allow passing possible_crtcs for existing users of drm_writeback_connector_init() - squash the vendor changes into the same commit so that each patch in the series can compile individually Co-developed-by: Kandpal Suraj Signed-off-by: Abhinav Kumar --- .../drm/arm/display/komeda/komeda_wb_connector.c | 3 +- drivers/gpu/drm/arm/malidp_mw.c| 5 +- drivers/gpu/drm/drm_writeback.c| 103 + drivers/gpu/drm/rcar-du/rcar_du_writeback.c| 5 +- drivers/gpu/drm/vc4/vc4_txp.c | 19 ++-- drivers/gpu/drm/vkms/vkms_writeback.c | 3 +- include/drm/drm_writeback.h| 22 - 7 files changed, 103 insertions(+), 57 deletions(-) diff --git a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c index e465cc4..40774e6 100644 --- a/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c +++ b/drivers/gpu/drm/arm/display/komeda/komeda_wb_connector.c @@ -155,7 +155,6 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, kwb_conn->wb_layer = kcrtc->master->wb_layer; wb_conn = _conn->base; - wb_conn->encoder.possible_crtcs = BIT(drm_crtc_index(>base)); formats = komeda_get_layer_fourcc_list(>fmt_tbl, kwb_conn->wb_layer->layer_type, @@ -164,7 +163,7 @@ static int komeda_wb_connector_add(struct komeda_kms_dev *kms, err = drm_writeback_connector_init(>base, wb_conn, _wb_connector_funcs, _wb_encoder_helper_funcs, - formats, n_formats); + formats, n_formats, BIT(drm_crtc_index(>base))); komeda_put_fourcc_list(formats); if (err) { kfree(kwb_conn); diff --git a/drivers/gpu/drm/arm/malidp_mw.c b/drivers/gpu/drm/arm/malidp_mw.c index f5847a7..b882066 100644 --- a/drivers/gpu/drm/arm/malidp_mw.c +++ b/drivers/gpu/drm/arm/malidp_mw.c @@ -208,11 +208,12 @@ int malidp_mw_connector_init(struct drm_device *drm) struct malidp_drm *malidp = drm->dev_private; u32 *formats; int ret, n_formats; + uint32_t possible_crtcs; if (!malidp->dev->hw->enable_memwrite) return 0; - malidp->mw_connector.encoder.possible_crtcs = 1 << drm_crtc_index(>crtc); + possible_crtcs = 1 << drm_crtc_index(>crtc); drm_connector_helper_add(>mw_connector.base, _mw_connector_helper_funcs); @@ -223,7 +224,7 @@ int malidp_mw_connector_init(struct drm_device *drm) ret = drm_writeback_connector_init(drm, >mw_connector, _mw_connector_funcs, _mw_encoder_helper_funcs, - formats, n_formats); + formats, n_formats, possible_crtcs); kfree(formats); if (ret) return ret; diff --git a/drivers/gpu/drm/drm_writeback.c b/drivers/gpu/drm/drm_writeback.c index dccf4504..17c1471 100644 --- a/drivers/gpu/drm/drm_writeback.c +++ b/drivers/gpu/drm/drm_writeback.c @@ -149,36 +149,15 @@ static const struct drm_encoder_funcs drm_writeback_encoder_funcs = { .destroy = drm_encoder_cleanup, }; -/** - * drm_writeback_connector_init - Initialize a writeback connector and its properties - * @dev: DRM device - * @wb_connector: Writeback connector to initialize - * @con_funcs: Connector funcs vtable - * @enc_helper_funcs: Encoder helper funcs vtable to be used by the internal encoder - * @formats: Array of supported pixel formats for the writeback engine - * @n_formats: Length of the formats array - * - * This function creates the writeback-connector-specific properties if they - * have not been already created, initializes the connector as - * type DRM_MODE_CONNECTOR_WRITEBACK, and correctly initializes the property - * values. It will also create an internal encoder associated with the - * drm_writeback_connector and set it to use the @enc_helper_funcs vtable for - * the encoder helper. - * - * Drivers should always use
[Freedreno] [PATCH v3 0/3] Allow drm_writeback_connector to accept pointer to drm_encoder
There are some vendor drivers for which the writeback encoder shares hardware resources such as clocks and interrupts with the rest of the display pipeline. In addition, there can be use-cases where the writeback encoder could be a shared encoder between the physical display path and the writeback path. To accommodate for such cases, change the drm_writeback_connector to accept a pointer to drm_encoder. For existing users of drm_writeback_connector there will not be any change in functionality due to this change. This approach was first posted by Suraj Kandpal here [1] for both encoder and connector. But after discussions [2], the consensus was reached to split this change for the drm_encoder first and the drm_connector part can be reworked in a subsequent change later. Validation of this change was done using igt_writeback tests on MSM based RB5 board using the changes posted here [3]. For all other chipsets, these changes were compile-tested. [1] https://patchwork.kernel.org/project/dri-devel/patch/20220202081702.22119-1-suraj.kand...@intel.com/ [2] https://patchwork.kernel.org/project/dri-devel/patch/20220202085429.22261-6-suraj.kand...@intel.com/ [3] https://patchwork.freedesktop.org/series/99724/ changes in v3: - squash the vendor changes into the same commit so that each patch in the series can compile individually Abhinav Kumar (3): drm: allow real encoder to be passed for drm_writeback_connector drm: introduce drm_writeback_connector_init_with_encoder API drm/vc4: change vc4 driver to use drm_writeback_connector_init_with_encoder() .../drm/arm/display/komeda/komeda_wb_connector.c | 3 +- drivers/gpu/drm/arm/malidp_mw.c| 5 +- drivers/gpu/drm/drm_writeback.c| 145 +++-- drivers/gpu/drm/rcar-du/rcar_du_writeback.c| 5 +- drivers/gpu/drm/vc4/vc4_txp.c | 35 +++-- drivers/gpu/drm/vkms/vkms_writeback.c | 3 +- include/drm/drm_writeback.h| 27 +++- 7 files changed, 165 insertions(+), 58 deletions(-) -- 2.7.4
[Freedreno] [PATCH v5 9/9] drm/msm/dp: Support edp/dp without hpd
Some eDP sinks or platform boards will not support hpd. This patch adds support for those cases. Signed-off-by: Sankeerth Billakanti --- drivers/gpu/drm/msm/dp/dp_catalog.c | 6 -- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index f15316b..f8ddc73 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -596,8 +596,10 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) reftimer |= DP_DP_HPD_REFTIMER_ENABLE; dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); - /* Enable HPD */ - dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, DP_DP_HPD_CTRL_HPD_EN); + /* Enable HPD if supported*/ + if (!of_property_read_bool(catalog->dev->of_node, "no-hpd")) + dp_write_aux(catalog, REG_DP_DP_HPD_CTRL, + DP_DP_HPD_CTRL_HPD_EN); } u32 dp_catalog_link_is_connected(struct dp_catalog *dp_catalog) -- 2.7.4
[Freedreno] [PATCH v5 8/9] drm/msm/dp: Handle eDP mode_valid case
The panel-edp driver modes needs to be validated differently from DP because the link capabilities are not available for EDP by that time. Signed-off-by: Sankeerth Billakanti --- drivers/gpu/drm/msm/dp/dp_display.c | 6 ++ 1 file changed, 6 insertions(+) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 5775db8..8b150d1 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -1002,6 +1002,12 @@ enum drm_mode_status dp_bridge_mode_valid(struct drm_bridge *bridge, return -EINVAL; } + if (dp->connector_type == DRM_MODE_CONNECTOR_eDP) { + if (mode_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) + return MODE_CLOCK_HIGH; + return MODE_OK; + } + if ((dp->max_pclk_khz <= 0) || (dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) || (mode->clock > dp->max_pclk_khz)) -- 2.7.4
[Freedreno] [PATCH v5 7/9] drm/msm/dp: Support only IRQ_HPD and REPLUG interrupts for eDP
The panel-edp enables the eDP panel power during probe, get_modes and enable. The eDP connect and disconnect interrupts for the eDP/DP controller are directly dependent on panel power. As eDP display can be assumed as always connected, the controller driver can skip the eDP connect and disconnect interrupts. Any disruption in the link status will be indicated via the IRQ_HPD interrupts. So, the eDP controller driver can just enable the IRQ_HPD and replug interrupts. The DP controller driver still needs to enable all the interrupts. The interrupt register will still reflect the connect and disconnect interrupt status without generating an actual HW interrupt. The controller driver should not handle those masked interrupts. Signed-off-by: Sankeerth Billakanti --- drivers/gpu/drm/msm/dp/dp_catalog.c | 9 +++-- drivers/gpu/drm/msm/dp/dp_display.c | 24 ++-- 2 files changed, 25 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index 2c3b0f7..f15316b 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -592,10 +592,6 @@ void dp_catalog_ctrl_hpd_config(struct dp_catalog *dp_catalog) u32 reftimer = dp_read_aux(catalog, REG_DP_DP_HPD_REFTIMER); - /* enable HPD plug and unplug interrupts */ - dp_catalog_hpd_config_intr(dp_catalog, - DP_DP_HPD_PLUG_INT_MASK | DP_DP_HPD_UNPLUG_INT_MASK, true); - /* Configure REFTIMER and enable it */ reftimer |= DP_DP_HPD_REFTIMER_ENABLE; dp_write_aux(catalog, REG_DP_DP_HPD_REFTIMER, reftimer); @@ -622,13 +618,14 @@ u32 dp_catalog_hpd_get_intr_status(struct dp_catalog *dp_catalog) { struct dp_catalog_private *catalog = container_of(dp_catalog, struct dp_catalog_private, dp_catalog); - int isr = 0; + int isr, mask; isr = dp_read_aux(catalog, REG_DP_DP_HPD_INT_STATUS); dp_write_aux(catalog, REG_DP_DP_HPD_INT_ACK, (isr & DP_DP_HPD_INT_MASK)); + mask = dp_read_aux(catalog, REG_DP_DP_HPD_INT_MASK); - return isr; + return isr & (DP_DP_HPD_STATE_STATUS_MASK | mask); } int dp_catalog_ctrl_get_interrupt(struct dp_catalog *dp_catalog) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 688bbed..5775db8 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -687,7 +687,8 @@ static int dp_hpd_unplug_handle(struct dp_display_private *dp, u32 data) dp_display_handle_plugged_change(>dp_display, false); /* enable HDP plug interrupt to prepare for next plugin */ - dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); + if (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_DisplayPort) + dp_catalog_hpd_config_intr(dp->catalog, DP_DP_HPD_PLUG_INT_MASK, true); DRM_DEBUG_DP("After, type=%d hpd_state=%d\n", dp->dp_display.connector_type, state); @@ -1096,10 +1097,17 @@ void msm_dp_snapshot(struct msm_disp_state *disp_state, struct msm_dp *dp) static void dp_display_config_hpd(struct dp_display_private *dp) { - dp_display_host_init(dp); + dp_catalog_ctrl_hpd_config(dp->catalog); + /* Enable plug and unplug interrupts only for external DisplayPort */ + if (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_DisplayPort) + dp_catalog_hpd_config_intr(dp->catalog, + DP_DP_HPD_PLUG_INT_MASK | + DP_DP_HPD_UNPLUG_INT_MASK, + true); + /* Enable interrupt first time * we are leaving dp clocks on during disconnect * and never disable interrupt @@ -1383,6 +1391,12 @@ static int dp_pm_resume(struct device *dev) dp_catalog_ctrl_hpd_config(dp->catalog); + if (dp->dp_display.connector_type == DRM_MODE_CONNECTOR_DisplayPort) + dp_catalog_hpd_config_intr(dp->catalog, + DP_DP_HPD_PLUG_INT_MASK | + DP_DP_HPD_UNPLUG_INT_MASK, + true); + if (dp_catalog_link_is_connected(dp->catalog)) { /* * set sink to normal operation mode -- D0 @@ -1647,6 +1661,9 @@ void dp_bridge_enable(struct drm_bridge *drm_bridge) return; } + if (dp->connector_type == DRM_MODE_CONNECTOR_eDP) + dp_hpd_plug_handle(dp_display, 0); + mutex_lock(_display->event_mutex); /* stop sentinel checking */ @@ -1711,6 +1728,9 @@ void dp_bridge_post_disable(struct drm_bridge *drm_bridge) dp_display = container_of(dp, struct dp_display_private, dp_display); + if (dp->connector_type == DRM_MODE_CONNECTOR_eDP) +
[Freedreno] [PATCH v5 6/9] drm/msm/dp: wait for hpd high before any sink interaction
The source device should ensure the sink is ready before proceeding to read the sink capability or performing any aux transactions. The sink will indicate its readiness by asserting the HPD line. The eDP sink requires power from the source and its HPD line will be asserted only after the panel is powered on. The panel power will be enabled from the panel-edp driver. The controller driver needs to wait for the hpd line to be asserted by the sink. Signed-off-by: Sankeerth Billakanti --- drivers/gpu/drm/msm/dp/dp_aux.c | 6 ++ drivers/gpu/drm/msm/dp/dp_catalog.c | 23 +++ drivers/gpu/drm/msm/dp/dp_catalog.h | 1 + drivers/gpu/drm/msm/dp/dp_reg.h | 7 ++- 4 files changed, 36 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/dp/dp_aux.c b/drivers/gpu/drm/msm/dp/dp_aux.c index 6d36f63..2ddc303 100644 --- a/drivers/gpu/drm/msm/dp/dp_aux.c +++ b/drivers/gpu/drm/msm/dp/dp_aux.c @@ -337,6 +337,12 @@ static ssize_t dp_aux_transfer(struct drm_dp_aux *dp_aux, goto exit; } + ret = dp_catalog_aux_wait_for_hpd_connect_state(aux->catalog); + if (ret) { + DRM_DEBUG_DP("DP sink not ready for aux transactions\n"); + goto exit; + } + dp_aux_update_offset_and_segment(aux, msg); dp_aux_transfer_helper(aux, msg, true); diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.c b/drivers/gpu/drm/msm/dp/dp_catalog.c index fac815f..2c3b0f7 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.c +++ b/drivers/gpu/drm/msm/dp/dp_catalog.c @@ -242,6 +242,29 @@ void dp_catalog_aux_update_cfg(struct dp_catalog *dp_catalog) phy_calibrate(phy); } +int dp_catalog_aux_wait_for_hpd_connect_state(struct dp_catalog *dp_catalog) +{ + u32 state, hpd_en, timeout; + struct dp_catalog_private *catalog = container_of(dp_catalog, + struct dp_catalog_private, dp_catalog); + + hpd_en = dp_read_aux(catalog, REG_DP_DP_HPD_CTRL) & + DP_DP_HPD_CTRL_HPD_EN; + + /* no-hpd case */ + if (!hpd_en) + return 0; + + /* Poll for HPD connected status */ + timeout = dp_read_aux(catalog, REG_DP_DP_HPD_EVENT_TIME_0) & + DP_HPD_CONNECT_TIME_MASK; + + return readl_poll_timeout(catalog->io->dp_controller.aux.base + + REG_DP_DP_HPD_INT_STATUS, + state, state & DP_DP_HPD_STATE_STATUS_CONNECTED, + 2000, timeout); +} + static void dump_regs(void __iomem *base, int len) { int i; diff --git a/drivers/gpu/drm/msm/dp/dp_catalog.h b/drivers/gpu/drm/msm/dp/dp_catalog.h index 7dea101..45140a3 100644 --- a/drivers/gpu/drm/msm/dp/dp_catalog.h +++ b/drivers/gpu/drm/msm/dp/dp_catalog.h @@ -84,6 +84,7 @@ int dp_catalog_aux_clear_hw_interrupts(struct dp_catalog *dp_catalog); void dp_catalog_aux_reset(struct dp_catalog *dp_catalog); void dp_catalog_aux_enable(struct dp_catalog *dp_catalog, bool enable); void dp_catalog_aux_update_cfg(struct dp_catalog *dp_catalog); +int dp_catalog_aux_wait_for_hpd_connect_state(struct dp_catalog *dp_catalog); u32 dp_catalog_aux_get_irq(struct dp_catalog *dp_catalog); /* DP Controller APIs */ diff --git a/drivers/gpu/drm/msm/dp/dp_reg.h b/drivers/gpu/drm/msm/dp/dp_reg.h index 2686028..d68c71b 100644 --- a/drivers/gpu/drm/msm/dp/dp_reg.h +++ b/drivers/gpu/drm/msm/dp/dp_reg.h @@ -53,9 +53,14 @@ #define DP_DP_HPD_REFTIMER_ENABLE (1 << 16) #define REG_DP_DP_HPD_EVENT_TIME_0 (0x001C) -#define REG_DP_DP_HPD_EVENT_TIME_1 (0x0020) #define DP_DP_HPD_EVENT_TIME_0_VAL (0x3E800FA) +#define DP_HPD_GLITCH_TIME_MASK(0xFFFC) +#define DP_HPD_CONNECT_TIME_MASK (0x0003) + +#define REG_DP_DP_HPD_EVENT_TIME_1 (0x0020) #define DP_DP_HPD_EVENT_TIME_1_VAL (0x1F407D0) +#define DP_HPD_DISCONNECT_TIME_MASK(0xC000) +#define DP_IRQ_HPD_MAX_TIME_MASK (0x3FFF) #define REG_DP_AUX_CTRL(0x0030) #define DP_AUX_CTRL_ENABLE (0x0001) -- 2.7.4
[Freedreno] [PATCH v5 5/9] drm/msm/dp: Add eDP support via aux_bus
This patch adds support for generic eDP sink through aux_bus. The eDP/DP controller driver should support aux transactions originating from the panel-edp driver and hence should be initialized and ready. The panel bridge supporting the panel should be ready before the bridge connector is initialized. The generic panel probe needs the controller resources to be enabled to support aux tractions originating from it. So, the host_init and phy_init are moved to execute before the panel probe. The host_init has to return early if the core is already initialized so that the regulator and clock votes for the controller resources are balanced. EV_HPD_INIT_SETUP needs to execute immediately to enable the interrupts for the aux transactions from panel-edp to get the modes supported. Signed-off-by: Sankeerth Billakanti --- drivers/gpu/drm/msm/dp/dp_display.c | 65 +++-- drivers/gpu/drm/msm/dp/dp_drm.c | 10 +++--- drivers/gpu/drm/msm/dp/dp_parser.c | 21 +--- drivers/gpu/drm/msm/dp/dp_parser.h | 1 + 4 files changed, 70 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/msm/dp/dp_display.c b/drivers/gpu/drm/msm/dp/dp_display.c index 382b3aa..688bbed 100644 --- a/drivers/gpu/drm/msm/dp/dp_display.c +++ b/drivers/gpu/drm/msm/dp/dp_display.c @@ -10,6 +10,7 @@ #include #include #include +#include #include "msm_drv.h" #include "msm_kms.h" @@ -265,8 +266,6 @@ static int dp_display_bind(struct device *dev, struct device *master, goto end; } - dp->dp_display.next_bridge = dp->parser->next_bridge; - dp->aux->drm_dev = drm; rc = dp_aux_register(dp->aux); if (rc) { @@ -421,6 +420,11 @@ static void dp_display_host_init(struct dp_display_private *dp) dp->dp_display.connector_type, dp->core_initialized, dp->phy_initialized); + if (dp->core_initialized) { + DRM_DEBUG_DP("DP core already initialized\n"); + return; + } + dp_power_init(dp->power, false); dp_ctrl_reset_irq_ctrl(dp->ctrl, true); dp_aux_init(dp->aux); @@ -433,6 +437,11 @@ static void dp_display_host_deinit(struct dp_display_private *dp) dp->dp_display.connector_type, dp->core_initialized, dp->phy_initialized); + if (!dp->core_initialized) { + DRM_DEBUG_DP("DP core not initialized\n"); + return; + } + dp_ctrl_reset_irq_ctrl(dp->ctrl, false); dp_aux_deinit(dp->aux); dp_power_deinit(dp->power); @@ -1502,7 +1511,7 @@ void msm_dp_irq_postinstall(struct msm_dp *dp_display) dp_hpd_event_setup(dp); - dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 100); + dp_add_event(dp, EV_HPD_INIT_SETUP, 0, 0); } void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) @@ -1524,6 +1533,52 @@ void msm_dp_debugfs_init(struct msm_dp *dp_display, struct drm_minor *minor) } } +static int dp_display_get_next_bridge(struct msm_dp *dp) +{ + int rc = 0; + struct dp_display_private *dp_priv; + struct device_node *aux_bus; + struct device *dev; + + dp_priv = container_of(dp, struct dp_display_private, dp_display); + dev = _priv->pdev->dev; + aux_bus = of_get_child_by_name(dev->of_node, "aux-bus"); + + if (aux_bus) { + dp_display_host_init(dp_priv); + dp_catalog_ctrl_hpd_config(dp_priv->catalog); + enable_irq(dp_priv->irq); + dp_display_host_phy_init(dp_priv); + + devm_of_dp_aux_populate_ep_devices(dp_priv->aux); + + disable_irq(dp_priv->irq); + } + + /* +* External bridges are mandatory for eDP interfaces: one has to +* provide at least an eDP panel (which gets wrapped into panel-bridge). +* +* For DisplayPort interfaces external bridges are optional, so +* silently ignore an error if one is not present (-ENODEV). +*/ + rc = dp_parser_find_next_bridge(dp_priv->parser); + if (rc == -ENODEV) { + if (dp->connector_type == DRM_MODE_CONNECTOR_eDP) { + DRM_ERROR("eDP: next bridge is not present\n"); + return rc; + } + } else if (rc) { + if (rc != -EPROBE_DEFER) + DRM_ERROR("DP: error parsing next bridge: %d\n", rc); + return rc; + } + + dp->next_bridge = dp_priv->parser->next_bridge; + + return 0; +} + int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, struct drm_encoder *encoder) { @@ -1547,6 +1602,10 @@ int msm_dp_modeset_init(struct msm_dp *dp_display, struct drm_device *dev, dp_display->encoder = encoder; + ret = dp_display_get_next_bridge(dp_display); + if (ret) +
[Freedreno] [PATCH v5 4/9] drm/panel-edp: add LQ140M1JW46 edp panel entry
Add panel identification entry for the sharp LQ140M1JW46 eDP panel with power sequencing delay information. Signed-off-by: Sankeerth Billakanti --- drivers/gpu/drm/panel/panel-edp.c | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/panel/panel-edp.c b/drivers/gpu/drm/panel/panel-edp.c index f7bfcf6..e15e62f 100644 --- a/drivers/gpu/drm/panel/panel-edp.c +++ b/drivers/gpu/drm/panel/panel-edp.c @@ -1859,6 +1859,7 @@ static const struct edp_panel_entry edp_panels[] = { EDP_PANEL_ENTRY('K', 'D', 'B', 0x0624, _kd116n21_30nv_a010.delay, "116N21-30NV-A010"), EDP_PANEL_ENTRY('K', 'D', 'B', 0x1120, _200_500_e80_d50, "116N29-30NK-C007"), + EDP_PANEL_ENTRY('S', 'H', 'P', 0x1523, _lq140m1jw46.delay, "LQ140M1JW46"), EDP_PANEL_ENTRY('S', 'H', 'P', 0x154c, _200_500_p2e100, "LQ116M1JW10"), EDP_PANEL_ENTRY('S', 'T', 'A', 0x0100, _100_500_e200, "2081116HHD028001-51D"), -- 2.7.4
[Freedreno] [PATCH v5 3/9] arm64: dts: qcom: sc7280: Enable backlight for eDP panel
Enable backlight support for eDP panel on CRD platform for sc7280. Signed-off-by: Sankeerth Billakanti --- Changes in v5: - Separate out backlight nodes arch/arm64/boot/dts/qcom/sc7280-crd.dts | 18 ++ 1 file changed, 18 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280-crd.dts b/arch/arm64/boot/dts/qcom/sc7280-crd.dts index 2df654e..16d1a5b 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-crd.dts +++ b/arch/arm64/boot/dts/qcom/sc7280-crd.dts @@ -37,6 +37,15 @@ pinctrl-0 = <_panel_power>; }; + edp_backlight: edp-backlight { + compatible = "pwm-backlight"; + + power-supply = <_edp_bp>; + pwms = <_pwm 3 65535>; + + enable-gpios = <_gpios 7 GPIO_ACTIVE_HIGH>; + }; + vreg_edp_bp: vreg-edp-bp-regulator { compatible = "regulator-fixed"; regulator-name = "vreg_edp_bp"; @@ -123,7 +132,9 @@ ap_ts_pen_1v8: { edp_panel: edp-panel { compatible = "edp-panel"; + backlight = <_backlight>; power-supply = <_3v3_regulator>; + ports { #address-cells = <1>; #size-cells = <0>; @@ -172,6 +183,13 @@ ap_ts_pen_1v8: { }; }; +_pwm { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <_bl_pwm>; +}; + { edp_panel_power: edp-panel-power { pins = "gpio80"; -- 2.7.4
[Freedreno] [PATCH v5 2/9] arm64: dts: qcom: sc7280: Add support for eDP panel on CRD
Enable support for eDP interface via aux_bus on CRD platform. Signed-off-by: Sankeerth Billakanti --- Changes in v5: - Change the order of patches - Remove the backlight nodes - Remove the bias setting - Fix compilation issue - Model VREG_EDP_BP for backlight power Changes in v4: - Create new patch for name changes - Remove output-low Changes in v3: - Sort the nodes alphabetically - Use - instead of _ as node names - Place the backlight and panel nodes under root - Change the name of edp_out to mdss_edp_out - Change the names of regulator nodes - Delete unused properties in the board file Changes in v2: - Sort node references alphabetically - Improve readability - Move the pwm pinctrl to pwm node - Move the regulators to root - Define backlight power - Remove dummy regulator node - Cleanup pinctrl definitions arch/arm64/boot/dts/qcom/sc7280-crd.dts | 93 + 1 file changed, 93 insertions(+) diff --git a/arch/arm64/boot/dts/qcom/sc7280-crd.dts b/arch/arm64/boot/dts/qcom/sc7280-crd.dts index e2efbdd..2df654e 100644 --- a/arch/arm64/boot/dts/qcom/sc7280-crd.dts +++ b/arch/arm64/boot/dts/qcom/sc7280-crd.dts @@ -7,6 +7,7 @@ /dts-v1/; +#include #include "sc7280-idp.dtsi" #include "sc7280-idp-ec-h1.dtsi" @@ -21,6 +22,27 @@ chosen { stdout-path = "serial0:115200n8"; }; + + edp_3v3_regulator: edp-3v3-regulator { + compatible = "regulator-fixed"; + regulator-name = "edp_3v3_regulator"; + + regulator-min-microvolt = <330>; + regulator-max-microvolt = <330>; + + gpio = < 80 GPIO_ACTIVE_HIGH>; + enable-active-high; + + pinctrl-names = "default"; + pinctrl-0 = <_panel_power>; + }; + + vreg_edp_bp: vreg-edp-bp-regulator { + compatible = "regulator-fixed"; + regulator-name = "vreg_edp_bp"; + regulator-always-on; + regulator-boot-on; + }; }; _rsc { @@ -76,6 +98,58 @@ ap_ts_pen_1v8: { }; }; + { + status = "okay"; +}; + +_dp { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <_hot_plug_det>; + data-lanes = <0 1>; + vdda-1p2-supply = <_l6b_1p2>; + vdda-0p9-supply = <_l1b_0p8>; +}; + +_edp { + status = "okay"; + + data-lanes = <0 1 2 3>; + vdda-1p2-supply = <_l6b_1p2>; + vdda-0p9-supply = <_l10c_0p8>; + + aux-bus { + edp_panel: edp-panel { + compatible = "edp-panel"; + + power-supply = <_3v3_regulator>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + edp_panel_in: endpoint { + remote-endpoint = <_edp_out>; + }; + }; + }; + }; + }; +}; + +_edp_out { + remote-endpoint = <_panel_in>; +}; + +_edp_phy { + status = "okay"; +}; + +_mdp { + status = "okay"; +}; + _3v3_regulator { gpio = < 51 GPIO_ACTIVE_HIGH>; }; @@ -84,7 +158,26 @@ ap_ts_pen_1v8: { pins = "gpio51"; }; +_gpios { + edp_bl_power: edp-bl-power { + pins = "gpio7"; + function = "normal"; + qcom,drive-strength = ; + }; + + edp_bl_pwm: edp-bl-pwm { + pins = "gpio8"; + function = "func1"; + qcom,drive-strength = ; + }; +}; + { + edp_panel_power: edp-panel-power { + pins = "gpio80"; + function = "gpio"; + }; + tp_int_odl: tp-int-odl { pins = "gpio7"; function = "gpio"; -- 2.7.4
[Freedreno] [PATCH v5 1/9] arm64: dts: qcom: sc7280: rename edp_out label to mdss_edp_out
Rename the edp_out label in the sc7280 platform to mdss_edp_out so that the nodes related to mdss are all grouped together in the board specific files. Signed-off-by: Sankeerth Billakanti --- Changes in v5: - Change the order of patches - Modify commit text arch/arm64/boot/dts/qcom/sc7280.dtsi | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm64/boot/dts/qcom/sc7280.dtsi b/arch/arm64/boot/dts/qcom/sc7280.dtsi index c07765d..bcf7562 100644 --- a/arch/arm64/boot/dts/qcom/sc7280.dtsi +++ b/arch/arm64/boot/dts/qcom/sc7280.dtsi @@ -3332,7 +3332,7 @@ port@1 { reg = <1>; - edp_out: endpoint { }; + mdss_edp_out: endpoint { }; }; }; -- 2.7.4
[Freedreno] [PATCH v5 0/9] Add support for the eDP panel on sc7280 CRD
This series adds support for eDP on sc7280 CRD platform. These changes are dependent on the following series in order: https://patchwork.kernel.org/project/linux-arm-msm/list/?series=620127=* https://patchwork.kernel.org/project/linux-arm-msm/list/?series=616587=* https://patchwork.kernel.org/project/linux-arm-msm/list/?series=613654=* Sankeerth Billakanti (9): arm64: dts: qcom: sc7280: rename edp_out label to mdss_edp_out arm64: dts: qcom: sc7280: Add support for eDP panel on CRD arm64: dts: qcom: sc7280: Enable backlight for eDP panel drm/panel-edp: add LQ140M1JW46 edp panel entry drm/msm/dp: Add eDP support via aux_bus drm/msm/dp: wait for hpd high before any sink interaction drm/msm/dp: Support only IRQ_HPD and REPLUG interrupts for eDP drm/msm/dp: Handle eDP mode_valid case drm/msm/dp: Support edp/dp without hpd arch/arm64/boot/dts/qcom/sc7280-crd.dts | 111 arch/arm64/boot/dts/qcom/sc7280.dtsi| 2 +- drivers/gpu/drm/msm/dp/dp_aux.c | 6 ++ drivers/gpu/drm/msm/dp/dp_catalog.c | 38 --- drivers/gpu/drm/msm/dp/dp_catalog.h | 1 + drivers/gpu/drm/msm/dp/dp_display.c | 95 +-- drivers/gpu/drm/msm/dp/dp_drm.c | 10 +-- drivers/gpu/drm/msm/dp/dp_parser.c | 21 +- drivers/gpu/drm/msm/dp/dp_parser.h | 1 + drivers/gpu/drm/msm/dp/dp_reg.h | 7 +- drivers/gpu/drm/panel/panel-edp.c | 1 + 11 files changed, 254 insertions(+), 39 deletions(-) -- 2.7.4
Re: [Freedreno] [PATCH v3 5/5] drm/msm: allow compile time selection of driver components
On 3/16/2022 12:31 AM, Dmitry Baryshkov wrote: On 16/03/2022 03:28, Abhinav Kumar wrote: On 3/3/2022 7:21 PM, Dmitry Baryshkov wrote: MSM DRM driver already allows one to compile out the DP or DSI support. Add support for disabling other features like MDP4/MDP5/DPU drivers or direct HDMI output support. Suggested-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Kconfig | 50 -- drivers/gpu/drm/msm/Makefile | 18 ++-- drivers/gpu/drm/msm/msm_drv.h | 33 ++ drivers/gpu/drm/msm/msm_mdss.c | 13 +++-- 4 files changed, 106 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9b019598e042..3735fd41eb3b 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -46,12 +46,39 @@ config DRM_MSM_GPU_SUDO Only use this if you are a driver developer. This should *not* be enabled for production kernels. If unsure, say N. -config DRM_MSM_HDMI_HDCP - bool "Enable HDMI HDCP support in MSM DRM driver" +config DRM_MSM_MDSS + bool + depends on DRM_MSM + default n shouldnt DRM_MSM_MDSS be defaulted to y? No, it will be selected either by MDP5 or by DPU1. It is not used if DRM_MSM is compiled with just MDP4 or headless support in mind. Ok got it. Another question is the compilation validation of the combinations of these. So we need to try: 1) DRM_MSM_MDSS + DRM_MSM_MDP4 2) DRM_MSM_MDSS + DRM_MSM_MDP5 3) DRM_MSM_MDSS + DRM_MSM_DPU Earlier since all of them were compiled together any inter-dependencies will not show up. Now since we are separating it out, just wanted to make sure each of the combos compile? I think you meant: - headless - MDP4 - MDP5 - DPU1 - MDP4 + MDP5 - MDP4 + DPU1 - MDP5 + DPU1 - all three drivers Yes, each of these combinations. + +config DRM_MSM_MDP4 + bool "Enable MDP4 support in MSM DRM driver" depends on DRM_MSM default y help - Choose this option to enable HDCP state machine + Compile in support for the Mobile Display Processor v4 (MDP4) in + the MSM DRM driver. It is the older display controller found in + devices using APQ8064/MSM8960/MSM8x60 platforms. + +config DRM_MSM_MDP5 + bool "Enable MDP5 support in MSM DRM driver" + depends on DRM_MSM + select DRM_MSM_MDSS + default y + help + Compile in support for the Mobile Display Processor v5 (MDP4) in + the MSM DRM driver. It is the display controller found in devices + using e.g. APQ8016/MSM8916/APQ8096/MSM8996/MSM8974/SDM6x0 platforms. + +config DRM_MSM_DPU + bool "Enable DPU support in MSM DRM driver" + depends on DRM_MSM + select DRM_MSM_MDSS + default y + help + Compile in support for the Display Processing Unit in + the MSM DRM driver. It is the display controller found in devices + using e.g. SDM845 and newer platforms. config DRM_MSM_DP bool "Enable DisplayPort support in MSM DRM driver" @@ -116,3 +143,20 @@ config DRM_MSM_DSI_7NM_PHY help Choose this option if DSI PHY on SM8150/SM8250/SC7280 is used on the platform. + +config DRM_MSM_HDMI + bool "Enable HDMI support in MSM DRM driver" + depends on DRM_MSM + default y + help + Compile in support for the HDMI output MSM DRM driver. It can + be a primary or a secondary display on device. Note that this is used + only for the direct HDMI output. If the device outputs HDMI data + throught some kind of DSI-to-HDMI bridge, this option can be disabled. + +config DRM_MSM_HDMI_HDCP + bool "Enable HDMI HDCP support in MSM DRM driver" + depends on DRM_MSM && DRM_MSM_HDMI + default y + help + Choose this option to enable HDCP state machine diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index e76927b42033..5fe9c20ab9ee 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -16,6 +16,8 @@ msm-y := \ adreno/a6xx_gpu.o \ adreno/a6xx_gmu.o \ adreno/a6xx_hfi.o \ + +msm-$(CONFIG_DRM_MSM_HDMI) += \ hdmi/hdmi.o \ hdmi/hdmi_audio.o \ hdmi/hdmi_bridge.o \ @@ -27,8 +29,8 @@ msm-y := \ hdmi/hdmi_phy_8x60.o \ hdmi/hdmi_phy_8x74.o \ hdmi/hdmi_pll_8960.o \ - disp/mdp_format.o \ - disp/mdp_kms.o \ + +msm-$(CONFIG_DRM_MSM_MDP4) += \ disp/mdp4/mdp4_crtc.o \ disp/mdp4/mdp4_dtv_encoder.o \ disp/mdp4/mdp4_lcdc_encoder.o \ @@ -37,6 +39,8 @@ msm-y := \ disp/mdp4/mdp4_irq.o \ disp/mdp4/mdp4_kms.o \ disp/mdp4/mdp4_plane.o \ + +msm-$(CONFIG_DRM_MSM_MDP5) += \ disp/mdp5/mdp5_cfg.o \ disp/mdp5/mdp5_ctl.o \ disp/mdp5/mdp5_crtc.o \ @@ -47,6 +51,8 @@ msm-y := \ disp/mdp5/mdp5_mixer.o \ disp/mdp5/mdp5_plane.o \ disp/mdp5/mdp5_smp.o \ + +msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_core_perf.o \ disp/dpu1/dpu_crtc.o \
Re: [Freedreno] [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with drm_bridge_connector
> Subject: Re: [RFC PATCH v2 4/5] drm/msm/dp: replace dp_connector with > drm_bridge_connector > Date: Wed, 23 Feb 2022 16:40:56 -0800 > From: Kuogee Hsieh > To: Stephen Boyd , Dmitry Baryshkov > > CC: Abhinav Kumar , Bjorn Andersson > , Rob Clark , Sean Paul > , David Airlie , Daniel Vetter > , linux-arm-...@vger.kernel.org, dri- > de...@lists.freedesktop.org, freedreno@lists.freedesktop.org > > > On 2/23/2022 1:33 PM, Stephen Boyd wrote: > > Quoting Kuogee Hsieh (2022-02-23 10:27:26) > >> On 2/23/2022 10:22 AM, Dmitry Baryshkov wrote: > >>> On 23/02/2022 20:21, Kuogee Hsieh wrote: > >>> > >>> In the panel device node. > >>> > >>> Can you please share it too? > >> > >> { > >> edp_power_supply: edp_power { > >> compatible = "regulator-fixed"; > >> regulator-name = "edp_backlight_power"; > >> > >> regulator-always-on; > >> regulator-boot-on; > >> }; > >> > >> edp_backlight: edp_backlight { > >> compatible = "pwm-backlight"; > >> > >> pwms = <_pwm 3 65535>; > >> power-supply = <_power_supply>; > >> enable-gpio = <_gpios 7 GPIO_ACTIVE_HIGH>; > >> > >> pinctrl-names = "default"; > >> pinctrl-0 = <_pwm_default>; > >> }; > >> > >> edp_panel: edp_panel { > >> compatible = "sharp_lq140m1jw46"; > > Is that supposed to be sharp,lq140m1jw46 with a comma instead of an > > underscore? > > Stephen, > > This is our internal branch which does not have patches up to date yet. > > I will cherry-pick newer edp related patches which are under review now to > re test it. Tested-by: Sankeerth Billakanti Detect returned eDP not connected because the panel power was not on and mode_valid was failing because the DP mode_valid is different from eDP
Re: [Freedreno] [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and public functions
> Subject: [RFC PATCH v2 5/5] drm/msm/dp: remove extra wrappers and > public functions > Date: Sat, 12 Feb 2022 01:40:06 +0300 > From: Dmitry Baryshkov > To: Bjorn Andersson , Rob Clark > , Sean Paul , Abhinav Kumar > , Kuogee Hsieh > CC: Stephen Boyd , David Airlie , > Daniel Vetter , linux-arm-...@vger.kernel.org, dri- > de...@lists.freedesktop.org, freedreno@lists.freedesktop.org > > dp_bridge's functions are thin wrappers around the msm_dp_display_* > family. Squash dp_bridge callbacks into respective msm_dp_display > functions, removing the latter functions from public space. > > Signed-off-by: Dmitry Baryshkov Tested-by: Sankeerth Billakanti > --- > drivers/gpu/drm/msm/dp/dp_display.c | 54 +++--- > drivers/gpu/drm/msm/dp/dp_display.h | 1 - > drivers/gpu/drm/msm/dp/dp_drm.c | 72 ++--- > drivers/gpu/drm/msm/dp/dp_drm.h | 22 - > drivers/gpu/drm/msm/msm_drv.h | 31 - > 5 files changed, 60 insertions(+), 120 deletions(-) > > diff --git a/drivers/gpu/drm/msm/dp/dp_display.c > b/drivers/gpu/drm/msm/dp/dp_display.c > index 59e5e5b8e5b4..a9b641a68bff 100644 > --- a/drivers/gpu/drm/msm/dp/dp_display.c > +++ b/drivers/gpu/drm/msm/dp/dp_display.c > @@ -10,7 +10,6 @@ > #include > #include > #include > -#include >#include "msm_drv.h" > #include "msm_kms.h" > @@ -945,18 +944,36 @@ int dp_display_set_plugged_cb(struct msm_dp > *dp_display, > return 0; > } > -int dp_display_validate_mode(struct msm_dp *dp, u32 mode_pclk_khz) > +/** > + * dp_bridge_mode_valid - callback to determine if specified mode is > +valid > + * @bridge: Pointer to drm bridge structure > + * @info: display info > + * @mode: Pointer to drm mode structure > + * Returns: Validity status for specified mode */ enum drm_mode_status > +dp_bridge_mode_valid(struct drm_bridge *bridge, > + const struct drm_display_info *info, > + const struct drm_display_mode > *mode) > { > const u32 num_components = 3, default_bpp = 24; > struct dp_display_private *dp_display; > struct dp_link_info *link_info; > u32 mode_rate_khz = 0, supported_rate_khz = 0, mode_bpp = 0; > + struct msm_dp *dp; > + int mode_pclk_khz = mode->clock; > + > + dp = to_dp_bridge(bridge)->dp_display; > if (!dp || !mode_pclk_khz || !dp->connector) { > DRM_ERROR("invalid params\n"); > return -EINVAL; > } > + if ((dp->max_pclk_khz <= 0) || > + (dp->max_pclk_khz > DP_MAX_PIXEL_CLK_KHZ) || > + (mode->clock > dp->max_pclk_khz)) > + return MODE_BAD; > + > dp_display = container_of(dp, struct dp_display_private, > dp_display); > link_info = _display->panel->link_info; > @@ -1501,7 +1518,7 @@ int msm_dp_modeset_init(struct msm_dp > *dp_display, struct drm_device *dev, > dp_display->encoder = encoder; > - dp_display->bridge = msm_dp_bridge_init(dp_display, dev, > encoder); > + dp_display->bridge = dp_bridge_init(dp_display, dev, encoder); > if (IS_ERR(dp_display->bridge)) { > ret = PTR_ERR(dp_display->bridge); > DRM_DEV_ERROR(dev->dev, > @@ -1528,8 +1545,10 @@ int msm_dp_modeset_init(struct msm_dp > *dp_display, struct drm_device *dev, > return 0; > } > -int msm_dp_display_enable(struct msm_dp *dp, struct drm_encoder > *encoder) > +void dp_bridge_enable(struct drm_bridge *drm_bridge) > { > + struct msm_dp_bridge *dp_bridge = to_dp_bridge(drm_bridge); > + struct msm_dp *dp = dp_bridge->dp_display; > int rc = 0; > struct dp_display_private *dp_display; > u32 state; > @@ -1537,7 +1556,7 @@ int msm_dp_display_enable(struct msm_dp *dp, > struct drm_encoder *encoder) > dp_display = container_of(dp, struct dp_display_private, > dp_display); > if (!dp_display->dp_mode.drm_mode.clock) { > DRM_ERROR("invalid params\n"); > - return -EINVAL; > + return; > } > mutex_lock(_display->event_mutex); > @@ -1549,14 +1568,14 @@ int msm_dp_display_enable(struct msm_dp *dp, > struct drm_encoder *encoder) > if (rc) { > DRM_ERROR("Failed to perform a mode set, rc=%d\n", rc); > mutex_unlock(_display->event_mutex); > - return rc; > + return; > } > rc = dp_display_prepare(dp); > if (rc) { > DRM_ERROR("DP display prepare failed, rc=%d\n", rc); > mutex_unlock(_display->event_mutex); > - return rc; > + return; > } > state = dp_display->hpd_state; > @@ -1581,23 +1600,23 @@ int msm_dp_display_enable(struct msm_dp *dp, > struct drm_encoder *encoder) > dp_display->hpd_state = ST_CONNECTED; > mutex_unlock(_display->event_mutex); > - > - return rc; > } > -int msm_dp_display_pre_disable(struct
Re: [Freedreno] [PATCH v2 0/6] Allow drm_writeback_connector to accept pointer to drm_encoder
Hi Dmitry On 3/16/2022 12:40 AM, Dmitry Baryshkov wrote: Hi Abhinav, On 16/03/2022 02:11, Abhinav Kumar wrote: There are some vendor drivers for which the writeback encoder shares hardware resources such as clocks and interrupts with the rest of the display pipeline. In addition, there can be use-cases where the writeback encoder could be a shared encoder between the physical display path and the writeback path. To accommodate for such cases, change the drm_writeback_connector to accept a pointer to drm_encoder. For existing users of drm_writeback_connector there will not be any change in functionality due to this change. This approach was first posted by Suraj Kandpal here [1] for both encoder and connector. But after discussions [2], the consensus was reached to split this change for the drm_encoder first and the drm_connector part can be reworked in a subsequent change later. Validation of this change was done using igt_writeback tests on MSM based RB5 board using the changes posted here [3]. For all other chipsets, these changes were compile-tested. [1] https://patchwork.kernel.org/project/dri-devel/patch/20220202081702.22119-1-suraj.kand...@intel.com/ [2] https://patchwork.kernel.org/project/dri-devel/patch/20220202085429.22261-6-suraj.kand...@intel.com/ [3] https://patchwork.freedesktop.org/series/99724/ changes in v2: - introduce a new API drm_writeback_connector_init_with_encoder() - allow passing possible_crtcs for existing users of drm_writeback_connector_init() Abhinav Kumar (6): drm: allow real encoder to be passed for drm_writeback_connector drm/komeda: pass possible_crtcs as parameter for drm_writeback_connector drm/vkms: pass possible_crtcs as parameter for drm_writeback_connector drm/vc4: change vc4 driver to use drm_writeback_connector_init_with_encoder() drm/rcar_du: pass possible_crtcs as parameter for drm_writeback_connector drm/malidp: pass possible_crtcs as parameter for drm_writeback_connector I think we expect that at each commit point the kernel should be compilable. Could you please squash patches accordingly? I'd suggest the following patch sequence: - Add possible_crtcs to the drm_writeback_connector_init() including all the driver changes (all drivers must be compilable, including vc4) - Add drm_writeback_connector_init_with_encoder() - Modify vc4 to use new API WDYT? Yes I also thought if each commit point should be compilable. The way this started out was that in the original series https://patchwork.kernel.org/project/dri-devel/patch/20220202081702.22119-1-suraj.kand...@intel.com/ every commit was separated vendor-wise even though it will not compile individually. So I thought that, for ease of code-review perhaps it was alright to separate it that way so that individual vendors can review separately. But if we need to make each of the commits compilable we will have to squash the way you have mentioned. .../drm/arm/display/komeda/komeda_wb_connector.c | 3 +- drivers/gpu/drm/arm/malidp_mw.c | 5 +- drivers/gpu/drm/drm_writeback.c | 144 +++-- drivers/gpu/drm/rcar-du/rcar_du_writeback.c | 5 +- drivers/gpu/drm/vc4/vc4_txp.c | 30 - drivers/gpu/drm/vkms/vkms_writeback.c | 3 +- include/drm/drm_writeback.h | 27 +++- 7 files changed, 161 insertions(+), 56 deletions(-)
Re: [Freedreno] [PATCH v5] drm/msm/disp/dpu1: add inline rotation support for sc7280 target
On 15/03/2022 13:07, Vinod Polimera wrote: - Some DPU versions support inline rot90. It is supported only for limited amount of UBWC formats. - There are two versions of inline rotators, v1 (present on sm8250 and sm7250) and v2 (sc7280). These versions differ in the list of supported formats and in the scaler possibilities. Changes in RFC: - Rebase changes to the latest code base. - Append rotation config variables with v2 and remove unused variables.(Dmitry) - Move pixel_ext setup separately from scaler3 config.(Dmitry) - Add 270 degree rotation to supported rotation list.(Dmitry) Changes in V2: - Remove unused macros and fix indentation. - Add check if 90 rotation is supported and add supported rotations to rot_cfg. Changes in V3: - Fix indentation. - Move rot_supported to sspp capabilities. (Dmitry) - Config pixel_ext based on src_h/src_w directly. (Dmitry) - Misc changes. Changes in V4: - Pass boolean value to sspp blk based on supported rotations for each hw. Changes in V5: - update boolean value to true/false and add it for qcm2290. Co-developed-by: Kalyan Thota Signed-off-by: Kalyan Thota Signed-off-by: Vinod Polimera --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 187 ++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 18 +++ drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 113 --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.h | 2 + 4 files changed, 215 insertions(+), 105 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c index a4fe77c..060bf53 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -35,6 +35,9 @@ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ BIT(DPU_SSPP_CDP) | BIT(DPU_SSPP_EXCL_RECT)) +#define VIG_SC7280_MASK \ + (VIG_SC7180_MASK | BIT(DPU_SSPP_INLINE_ROTATION)) + #define DMA_SDM845_MASK \ (BIT(DPU_SSPP_SRC) | BIT(DPU_SSPP_QOS) | BIT(DPU_SSPP_QOS_8LVL) |\ BIT(DPU_SSPP_TS_PREFILL) | BIT(DPU_SSPP_TS_PREFILL_REC1) |\ @@ -203,6 +206,11 @@ static const uint32_t plane_formats_yuv[] = { DRM_FORMAT_YVU420, }; +static const u32 rotation_v2_formats[] = { + DRM_FORMAT_NV12, + /* TODO add formats after validation */ +}; + /* * DPU sub blocks config */ @@ -642,8 +650,7 @@ static const struct dpu_ctl_cfg qcm2290_ctl[] = { */ /* SSPP common configuration */ - -#define _VIG_SBLK(num, sdma_pri, qseed_ver) \ +#define _VIG_SBLK(num, sdma_pri, qseed_ver, rot_cfg) \ { \ .maxdwnscale = MAX_DOWNSCALE_RATIO, \ .maxupscale = MAX_UPSCALE_RATIO, \ @@ -660,6 +667,7 @@ static const struct dpu_ctl_cfg qcm2290_ctl[] = { .num_formats = ARRAY_SIZE(plane_formats_yuv), \ .virt_format_list = plane_formats, \ .virt_num_formats = ARRAY_SIZE(plane_formats), \ + .rotation_cfg = rot_cfg, \ } #define _DMA_SBLK(num, sdma_pri) \ @@ -676,22 +684,28 @@ static const struct dpu_ctl_cfg qcm2290_ctl[] = { } static const struct dpu_sspp_sub_blks msm8998_vig_sblk_0 = - _VIG_SBLK("0", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK("0", 0, DPU_SSPP_SCALER_QSEED3, NULL); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_1 = - _VIG_SBLK("1", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK("1", 0, DPU_SSPP_SCALER_QSEED3, NULL); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_2 = - _VIG_SBLK("2", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK("2", 0, DPU_SSPP_SCALER_QSEED3, NULL); static const struct dpu_sspp_sub_blks msm8998_vig_sblk_3 = - _VIG_SBLK("3", 0, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK("3", 0, DPU_SSPP_SCALER_QSEED3, NULL); + +static const struct dpu_rotation_cfg dpu_rot_sc7280_cfg_v2 = { + .rot_maxheight = 1088, + .rot_num_formats = ARRAY_SIZE(rotation_v2_formats), + .rot_format_list = rotation_v2_formats, +}; static const struct dpu_sspp_sub_blks sdm845_vig_sblk_0 = - _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK("0", 5, DPU_SSPP_SCALER_QSEED3, NULL); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_1 = - _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK("1", 6, DPU_SSPP_SCALER_QSEED3, NULL); static const struct dpu_sspp_sub_blks sdm845_vig_sblk_2 = - _VIG_SBLK("2", 7, DPU_SSPP_SCALER_QSEED3); + _VIG_SBLK("2", 7,
Re: [Freedreno] [PATCH v2 0/6] Allow drm_writeback_connector to accept pointer to drm_encoder
Hi Abhinav, On 16/03/2022 02:11, Abhinav Kumar wrote: There are some vendor drivers for which the writeback encoder shares hardware resources such as clocks and interrupts with the rest of the display pipeline. In addition, there can be use-cases where the writeback encoder could be a shared encoder between the physical display path and the writeback path. To accommodate for such cases, change the drm_writeback_connector to accept a pointer to drm_encoder. For existing users of drm_writeback_connector there will not be any change in functionality due to this change. This approach was first posted by Suraj Kandpal here [1] for both encoder and connector. But after discussions [2], the consensus was reached to split this change for the drm_encoder first and the drm_connector part can be reworked in a subsequent change later. Validation of this change was done using igt_writeback tests on MSM based RB5 board using the changes posted here [3]. For all other chipsets, these changes were compile-tested. [1] https://patchwork.kernel.org/project/dri-devel/patch/20220202081702.22119-1-suraj.kand...@intel.com/ [2] https://patchwork.kernel.org/project/dri-devel/patch/20220202085429.22261-6-suraj.kand...@intel.com/ [3] https://patchwork.freedesktop.org/series/99724/ changes in v2: - introduce a new API drm_writeback_connector_init_with_encoder() - allow passing possible_crtcs for existing users of drm_writeback_connector_init() Abhinav Kumar (6): drm: allow real encoder to be passed for drm_writeback_connector drm/komeda: pass possible_crtcs as parameter for drm_writeback_connector drm/vkms: pass possible_crtcs as parameter for drm_writeback_connector drm/vc4: change vc4 driver to use drm_writeback_connector_init_with_encoder() drm/rcar_du: pass possible_crtcs as parameter for drm_writeback_connector drm/malidp: pass possible_crtcs as parameter for drm_writeback_connector I think we expect that at each commit point the kernel should be compilable. Could you please squash patches accordingly? I'd suggest the following patch sequence: - Add possible_crtcs to the drm_writeback_connector_init() including all the driver changes (all drivers must be compilable, including vc4) - Add drm_writeback_connector_init_with_encoder() - Modify vc4 to use new API WDYT? .../drm/arm/display/komeda/komeda_wb_connector.c | 3 +- drivers/gpu/drm/arm/malidp_mw.c| 5 +- drivers/gpu/drm/drm_writeback.c| 144 +++-- drivers/gpu/drm/rcar-du/rcar_du_writeback.c| 5 +- drivers/gpu/drm/vc4/vc4_txp.c | 30 - drivers/gpu/drm/vkms/vkms_writeback.c | 3 +- include/drm/drm_writeback.h| 27 +++- 7 files changed, 161 insertions(+), 56 deletions(-) -- With best wishes Dmitry
Re: [Freedreno] [PATCH v3 5/5] drm/msm: allow compile time selection of driver components
On 16/03/2022 03:28, Abhinav Kumar wrote: On 3/3/2022 7:21 PM, Dmitry Baryshkov wrote: MSM DRM driver already allows one to compile out the DP or DSI support. Add support for disabling other features like MDP4/MDP5/DPU drivers or direct HDMI output support. Suggested-by: Stephen Boyd Signed-off-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Kconfig | 50 -- drivers/gpu/drm/msm/Makefile | 18 ++-- drivers/gpu/drm/msm/msm_drv.h | 33 ++ drivers/gpu/drm/msm/msm_mdss.c | 13 +++-- 4 files changed, 106 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig index 9b019598e042..3735fd41eb3b 100644 --- a/drivers/gpu/drm/msm/Kconfig +++ b/drivers/gpu/drm/msm/Kconfig @@ -46,12 +46,39 @@ config DRM_MSM_GPU_SUDO Only use this if you are a driver developer. This should *not* be enabled for production kernels. If unsure, say N. -config DRM_MSM_HDMI_HDCP - bool "Enable HDMI HDCP support in MSM DRM driver" +config DRM_MSM_MDSS + bool + depends on DRM_MSM + default n shouldnt DRM_MSM_MDSS be defaulted to y? No, it will be selected either by MDP5 or by DPU1. It is not used if DRM_MSM is compiled with just MDP4 or headless support in mind. Another question is the compilation validation of the combinations of these. So we need to try: 1) DRM_MSM_MDSS + DRM_MSM_MDP4 2) DRM_MSM_MDSS + DRM_MSM_MDP5 3) DRM_MSM_MDSS + DRM_MSM_DPU Earlier since all of them were compiled together any inter-dependencies will not show up. Now since we are separating it out, just wanted to make sure each of the combos compile? I think you meant: - headless - MDP4 - MDP5 - DPU1 - MDP4 + MDP5 - MDP4 + DPU1 - MDP5 + DPU1 - all three drivers + +config DRM_MSM_MDP4 + bool "Enable MDP4 support in MSM DRM driver" depends on DRM_MSM default y help - Choose this option to enable HDCP state machine + Compile in support for the Mobile Display Processor v4 (MDP4) in + the MSM DRM driver. It is the older display controller found in + devices using APQ8064/MSM8960/MSM8x60 platforms. + +config DRM_MSM_MDP5 + bool "Enable MDP5 support in MSM DRM driver" + depends on DRM_MSM + select DRM_MSM_MDSS + default y + help + Compile in support for the Mobile Display Processor v5 (MDP4) in + the MSM DRM driver. It is the display controller found in devices + using e.g. APQ8016/MSM8916/APQ8096/MSM8996/MSM8974/SDM6x0 platforms. + +config DRM_MSM_DPU + bool "Enable DPU support in MSM DRM driver" + depends on DRM_MSM + select DRM_MSM_MDSS + default y + help + Compile in support for the Display Processing Unit in + the MSM DRM driver. It is the display controller found in devices + using e.g. SDM845 and newer platforms. config DRM_MSM_DP bool "Enable DisplayPort support in MSM DRM driver" @@ -116,3 +143,20 @@ config DRM_MSM_DSI_7NM_PHY help Choose this option if DSI PHY on SM8150/SM8250/SC7280 is used on the platform. + +config DRM_MSM_HDMI + bool "Enable HDMI support in MSM DRM driver" + depends on DRM_MSM + default y + help + Compile in support for the HDMI output MSM DRM driver. It can + be a primary or a secondary display on device. Note that this is used + only for the direct HDMI output. If the device outputs HDMI data + throught some kind of DSI-to-HDMI bridge, this option can be disabled. + +config DRM_MSM_HDMI_HDCP + bool "Enable HDMI HDCP support in MSM DRM driver" + depends on DRM_MSM && DRM_MSM_HDMI + default y + help + Choose this option to enable HDCP state machine diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index e76927b42033..5fe9c20ab9ee 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -16,6 +16,8 @@ msm-y := \ adreno/a6xx_gpu.o \ adreno/a6xx_gmu.o \ adreno/a6xx_hfi.o \ + +msm-$(CONFIG_DRM_MSM_HDMI) += \ hdmi/hdmi.o \ hdmi/hdmi_audio.o \ hdmi/hdmi_bridge.o \ @@ -27,8 +29,8 @@ msm-y := \ hdmi/hdmi_phy_8x60.o \ hdmi/hdmi_phy_8x74.o \ hdmi/hdmi_pll_8960.o \ - disp/mdp_format.o \ - disp/mdp_kms.o \ + +msm-$(CONFIG_DRM_MSM_MDP4) += \ disp/mdp4/mdp4_crtc.o \ disp/mdp4/mdp4_dtv_encoder.o \ disp/mdp4/mdp4_lcdc_encoder.o \ @@ -37,6 +39,8 @@ msm-y := \ disp/mdp4/mdp4_irq.o \ disp/mdp4/mdp4_kms.o \ disp/mdp4/mdp4_plane.o \ + +msm-$(CONFIG_DRM_MSM_MDP5) += \ disp/mdp5/mdp5_cfg.o \ disp/mdp5/mdp5_ctl.o \ disp/mdp5/mdp5_crtc.o \ @@ -47,6 +51,8 @@ msm-y := \ disp/mdp5/mdp5_mixer.o \ disp/mdp5/mdp5_plane.o \ disp/mdp5/mdp5_smp.o \ + +msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_core_perf.o \ disp/dpu1/dpu_crtc.o \ disp/dpu1/dpu_encoder.o \ @@ -69,6 +75,13 @@ msm-y := \ disp/dpu1/dpu_plane.o \