Re: [PATCH] accel/habanalabs: fix gaudi2_get_tpc_idle_status() return
On Mon, May 15, 2023 at 1:32 PM Dan Carpenter wrote: > > The gaudi2_get_tpc_idle_status() function returned the incorrect variable > so it always returned true. > > Fixes: d85f0531b928 ("accel/habanalabs: break is_idle function into > per-engine sub-routines") > Signed-off-by: Dan Carpenter > --- > From static analysis. Not tested. > > drivers/accel/habanalabs/gaudi2/gaudi2.c | 2 +- > 1 file changed, 1 insertion(+), 1 deletion(-) > > diff --git a/drivers/accel/habanalabs/gaudi2/gaudi2.c > b/drivers/accel/habanalabs/gaudi2/gaudi2.c > index b778cf764a68..5539c84ee717 100644 > --- a/drivers/accel/habanalabs/gaudi2/gaudi2.c > +++ b/drivers/accel/habanalabs/gaudi2/gaudi2.c > @@ -7231,7 +7231,7 @@ static bool gaudi2_get_tpc_idle_status(struct hl_device > *hdev, u64 *mask_arr, u8 > > gaudi2_iterate_tpcs(hdev, &tpc_iter); > > - return tpc_idle_data.is_idle; > + return *tpc_idle_data.is_idle; > } > > static bool gaudi2_get_decoder_idle_status(struct hl_device *hdev, u64 > *mask_arr, u8 mask_len, > -- > 2.39.2 > Reviewed-by: Oded Gabbay Applied to -next. Thanks, Oded
Re: [PATCH -next] habanalabs: Fix some kernel-doc comments
On Fri, May 12, 2023 at 9:47 AM Yang Li wrote: > > Make the description of @regs_range_array and @regs_range_array_size > to @user_regs_range_array and @user_regs_range_array_size to silence > the warnings: > > drivers/accel/habanalabs/common/security.c:506: warning: Function parameter > or member 'user_regs_range_array' not described in > 'hl_init_pb_ranges_single_dcore' > drivers/accel/habanalabs/common/security.c:506: warning: Function parameter > or member 'user_regs_range_array_size' not described in > 'hl_init_pb_ranges_single_dcore' > drivers/accel/habanalabs/common/security.c:506: warning: Excess function > parameter 'regs_range_array' description in 'hl_init_pb_ranges_single_dcore' > drivers/accel/habanalabs/common/security.c:506: warning: Excess function > parameter 'regs_range_array_size' description in > 'hl_init_pb_ranges_single_dcore' > > Reported-by: Abaci Robot > Link: https://bugzilla.openanolis.cn/show_bug.cgi?id=4940 > Signed-off-by: Yang Li > --- > drivers/accel/habanalabs/common/security.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > > diff --git a/drivers/accel/habanalabs/common/security.c > b/drivers/accel/habanalabs/common/security.c > index 297e6e44fd0c..dc23ff57c91a 100644 > --- a/drivers/accel/habanalabs/common/security.c > +++ b/drivers/accel/habanalabs/common/security.c > @@ -495,8 +495,8 @@ int hl_init_pb_single_dcore(struct hl_device *hdev, u32 > dcore_offset, > * @instance_offset: offset between instances > * @pb_blocks: blocks array > * @blocks_array_size: blocks array size > - * @regs_range_array: register range array > - * @regs_range_array_size: register range array size > + * @user_regs_range_array: register range array > + * @user_regs_range_array_size: register range array size > * > */ > int hl_init_pb_ranges_single_dcore(struct hl_device *hdev, u32 dcore_offset, > -- > 2.20.1.7.g153144c > Reviewed-by: Oded Gabbay Applied to -next. Thanks, Oded
Re: [PATCH v2 RESEND 4/7] swiotlb: Dynamically allocated bounce buffers
Hi Christoph, On Tue, 16 May 2023 08:13:09 +0200 Christoph Hellwig wrote: > On Mon, May 15, 2023 at 07:43:52PM +, Michael Kelley (LINUX) wrote: > > FWIW, I don't think the approach you have implemented here will be > > practical to use for CoCo VMs (SEV, TDX, whatever else). The problem > > is that dma_direct_alloc_pages() and dma_direct_free_pages() must > > call dma_set_decrypted() and dma_set_encrypted(), respectively. In CoCo > > VMs, these calls are expensive because they require a hypercall to the host, > > and the operation on the host isn't trivial either. I haven't measured the > > overhead, but doing a hypercall on every DMA map operation and on > > every unmap operation has long been something we thought we must > > avoid. The fixed swiotlb bounce buffer space solves this problem by > > doing set_decrypted() in batch at boot time, and never > > doing set_encrypted(). > > I also suspect it doesn't really scale too well due to the number of > allocations. I suspect a better way to implement things would be to > add more large chunks that are used just like the main swiotlb buffers. > > That is when we run out of space try to allocate another chunk of the > same size in the background, similar to what we do with the pool in > dma-pool.c. This means we'll do a fairly large allocation, so we'll > need compaction or even CMA to back it up, but the other big upside > is that it also reduces the number of buffers that need to be checked > in is_swiotlb_buffer or the free / sync side. I have considered this approach. The two main issues I ran into were: 1. MAX_ORDER allocations were too small (at least with 4K pages), and even then they would often fail. 2. Allocating from CMA did work but only from process context. I made a stab at modifying the CMA allocator to work from interrupt context, but there are non-trivial interactions with the buddy allocator. Making them safe from interrupt context looked like a major task. I also had some fears about the length of the dynamic buffer list. I observed maximum length for block devices, and then it roughly followed the queue depth. Walking a few hundred buffers was still fast enough. I admit the list length may become an issue with high-end NVMe and I/O-intensive applications. Last but not least, when many smaller swiotlb chunks are allocated, they must be kept in a list (or another data structure), somewhat reducing the performance win. OK, one thing I did *not* consider back then was allocating these additional swiotlb chunks per device. It looks a bit too wasteful. Petr T
Re: [PATCH v2 RESEND 4/7] swiotlb: Dynamically allocated bounce buffers
Hi Michael, On Mon, 15 May 2023 19:43:52 + "Michael Kelley (LINUX)" wrote: > From: Petr Tesarik Sent: Tuesday, May 9, 2023 > 2:18 AM > > > > The software IO TLB was designed with the assumption that it is not > > used much, especially on 64-bit systems, so a small fixed memory > > area (currently 64 MiB) is sufficient to handle the few cases which > > still require a bounce buffer. However, these cases are not so rare > > in some circumstances. > > > > First, if SEV is active, all DMA must be done through shared > > unencrypted pages, and SWIOTLB is used to make this happen without > > changing device drivers. The software IO TLB size is increased to 6% > > of total memory in sev_setup_arch(), but that is more of an > > approximation. The actual requirements may vary depending on which > > drivers are used and the amount of I/O. > > FWIW, I don't think the approach you have implemented here will be > practical to use for CoCo VMs (SEV, TDX, whatever else). The problem > is that dma_direct_alloc_pages() and dma_direct_free_pages() must > call dma_set_decrypted() and dma_set_encrypted(), respectively. In CoCo > VMs, these calls are expensive because they require a hypercall to the host, > and the operation on the host isn't trivial either. I haven't measured the > overhead, but doing a hypercall on every DMA map operation and on > every unmap operation has long been something we thought we must > avoid. The fixed swiotlb bounce buffer space solves this problem by > doing set_decrypted() in batch at boot time, and never > doing set_encrypted(). I know. For performance, alloc() and free() on each DMA map/unmap is not ideal even without CoCo. I have already tested some code locally to keep buffers around after unmap, effectively creating a per-device pool as described below. Right now, I don't have SEV-capable hardware for testing, but on bare metal, this pool brought performance back to that of fixed swiotlb buffers, for some scenarios making it even better. However, these per-device pools add more complexity, so I decided to start with a smaller patch series that can be reviewed more easily. If there is no objection in general, I'll send the second part with the per-device pools. > In Microsoft's first implementation of bounce buffering for SEV-SNP VMs, > we created custom bounce buffer code separate from swiotlb. This code > did similar what you've done, but maintained a per-device pool of allocated > buffers that could be reused, rather than freeing the memory (and marking > the memory encrypted again) on every DMA unmap operation. (The pool > was actually per-VMBus channel, but VMBus channels are per-device, so > the effect was the same.) The reusable pool avoided most of the calls to > set_decrypted()/set_encrypted() and made it practical from a performance > standpoint. But of course, the pool could grow arbitrarily large, so there > was additional complexity to decay and trim the pool size. LKML feedback > early on was to use swiotlb instead, which made sense, but at the cost of > needing to figure out the appropriate fixed size of the swiotlb, and likely > over-provisioning to avoid running out of bounce buffer space. > > Now we're considering again a more dynamic approach, which is good, but > we're encountering the same problems. > > See > https://lore.kernel.org/linux-hyperv/20210228150315.2552437-1-ltyker...@gmail.com/ > for this historical example. Thanks for the pointer. I'll definitely have a look! Petr T > Michael > > > > > Second, some embedded devices have very little RAM, so 64 MiB is not > > negligible. Sadly, these are exactly the devices that also often > > need a software IO TLB. Although minimum swiotlb size can be found > > empirically by extensive testing, it would be easier to allocate a > > small swiotlb at boot and let it grow on demand. > > > > Growing the SWIOTLB data structures at run time is impossible. The > > whole SWIOTLB region is contiguous in physical memory to allow > > combining adjacent slots and also to ensure that alignment > > constraints can be met. The SWIOTLB is too big for the buddy > > allocator (cf. MAX_ORDER). More importantly, even if a new SWIOTLB > > could be allocated (e.g. from CMA), it cannot be extended in-place > > (because surrounding pages may be already allocated for other > > purposes), and there is no mechanism for relocating already mapped > > bounce buffers: The DMA API gets only the address of a buffer, and > > the implementation (direct or IOMMU) checks whether it belongs to > > the software IO TLB. > > > > It is possible to allocate multiple smaller struct io_tlb_mem > > instances. However, they would have to be stored in a non-constant > > container (list or tree), which needs synchronization between > > readers and writers, creating contention in a hot path for all > > devices, not only those which need software IO TLB. > > > > Another option is to allocate a very large SWIOTLB at boot, but > > allow mi
[PATCH 6/7] drm/amd/display: Implement the retrieval of secure display CRC data
Retrieve secure display's CRC data from the DC hardware in vline0 irq handler, and store the values in secure display contexts. Signed-off-by: Alan Liu --- .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 50 --- 1 file changed, 42 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index 81e9995183ad..f0ccf29af4f8 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -529,6 +529,8 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) struct amdgpu_crtc *acrtc = NULL; struct amdgpu_device *adev = NULL; struct secure_display_context *secure_display_ctx = NULL; + bool reset_crc_frame_count = false, crc_is_updated = false; + uint32_t crc[3] = {0}; unsigned long flags1; if (crtc == NULL) @@ -543,15 +545,14 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) /* Early return if CRC capture is not enabled. */ if (!amdgpu_dm_is_valid_crc_source(cur_crc_src) || - !dm_is_crc_source_crtc(cur_crc_src)) - goto cleanup; - - if (!acrtc->dm_irq_params.window_param.activated) - goto cleanup; + !dm_is_crc_source_crtc(cur_crc_src)) { + spin_unlock_irqrestore(&drm_dev->event_lock, flags1); + return; + } - if (acrtc->dm_irq_params.window_param.skip_frame_cnt) { - acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1; - goto cleanup; + if (!acrtc->dm_irq_params.window_param.activated) { + spin_unlock_irqrestore(&drm_dev->event_lock, flags1); + return; } secure_display_ctx = &adev->dm.secure_display_ctxs[acrtc->crtc_id]; @@ -562,6 +563,11 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) secure_display_ctx->crtc = crtc; } + if (acrtc->dm_irq_params.window_param.skip_frame_cnt) { + acrtc->dm_irq_params.window_param.skip_frame_cnt -= 1; + goto cleanup; + } + if (acrtc->dm_irq_params.window_param.update_win) { /* prepare work for dmub to update ROI */ secure_display_ctx->rect.x = acrtc->dm_irq_params.window_param.x_start; @@ -572,6 +578,8 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) acrtc->dm_irq_params.window_param.y_start; schedule_work(&secure_display_ctx->forward_roi_work); + reset_crc_frame_count = true; + acrtc->dm_irq_params.window_param.update_win = false; /* Statically skip 1 frame, because we may need to wait below things @@ -582,12 +590,38 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) acrtc->dm_irq_params.window_param.skip_frame_cnt = 1; } else { + struct dc_stream_state *stream_state = to_dm_crtc_state(crtc->state)->stream; + + if (!dc_stream_get_crc(stream_state->ctx->dc, stream_state, + &crc[0], &crc[1], &crc[2])) + DRM_ERROR("Secure Display: fail to get crc\n"); + else + crc_is_updated = true; + /* prepare work for psp to read ROI/CRC and send to I2C */ schedule_work(&secure_display_ctx->notify_ta_work); } cleanup: spin_unlock_irqrestore(&drm_dev->event_lock, flags1); + + spin_lock_irqsave(&secure_display_ctx->crc.lock, flags1); + + if (reset_crc_frame_count || secure_display_ctx->crc.frame_count == UINT_MAX) + /* Reset the reference frame count after user update the ROI +* or it reaches the maximum value. +*/ + secure_display_ctx->crc.frame_count = 0; + else + secure_display_ctx->crc.frame_count += 1; + + if (crc_is_updated) { + secure_display_ctx->crc.crc_R = crc[0]; + secure_display_ctx->crc.crc_G = crc[1]; + secure_display_ctx->crc.crc_B = crc[2]; + } + + spin_unlock_irqrestore(&secure_display_ctx->crc.lock, flags1); } struct secure_display_context * -- 2.34.1
[PATCH 5/7] drm/amd/display: Processing secure display new ROI update in atomic commit
Check if there is a new ROI update during the atomic commit and process it. A new function amdgpu_dm_crtc_set_secure_display_crc_source() is implemented to control the state of CRC engine in hardware. Signed-off-by: Alan Liu --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 38 + .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 57 +++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h | 3 + 3 files changed, 98 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index 14b296e1d0f6..ee016d5be7ac 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8857,6 +8857,44 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) } } #endif + +#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY + if (new_crtc_state->active && dm_new_crtc_state->secure_display_state.roi_changed) { + struct drm_roi *roi_data = + (struct drm_roi *)dm_new_crtc_state->secure_display_state.roi_blob->data; + + if (roi_data->secure_display_enable) { + if (!amdgpu_dm_crc_window_is_activated(crtc)) { + /* Enable secure display: set crc source to "crtc" */ + amdgpu_dm_crtc_set_secure_display_crc_source(crtc, "crtc"); + + /* wait 1 more frame for CRC engine to start */ + acrtc->dm_irq_params.window_param.skip_frame_cnt = 1; + + spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); + acrtc->dm_irq_params.window_param.activated = true; + spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); + } + + /* Update ROI: copy ROI from dm_crtc_state to dm_irq_params */ + spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); + acrtc->dm_irq_params.window_param.x_start = roi_data->x_start; + acrtc->dm_irq_params.window_param.y_start = roi_data->y_start; + acrtc->dm_irq_params.window_param.x_end = roi_data->x_end; + acrtc->dm_irq_params.window_param.y_end = roi_data->y_end; + acrtc->dm_irq_params.window_param.update_win = true; + spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); + + } else { + if (amdgpu_dm_crc_window_is_activated(crtc)) { + /* Disable secure display: set crc source to "none" */ + amdgpu_dm_crtc_set_secure_display_crc_source(crtc, "none"); + } + } + + dm_new_crtc_state->secure_display_state.roi_changed = false; + } +#endif } for_each_new_crtc_in_state(state, crtc, new_crtc_state, j) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index a83cabb9b1a6..81e9995183ad 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -465,6 +465,63 @@ void amdgpu_dm_crtc_handle_crc_irq(struct drm_crtc *crtc) } #if defined(CONFIG_DRM_AMD_SECURE_DISPLAY) +int amdgpu_dm_crtc_set_secure_display_crc_source(struct drm_crtc *crtc, const char *src_name) +{ + enum amdgpu_dm_pipe_crc_source source = dm_parse_crc_source(src_name); + enum amdgpu_dm_pipe_crc_source cur_crc_src; + struct dm_crtc_state *crtc_state; + struct drm_device *drm_dev = crtc->dev; + struct amdgpu_crtc *acrtc = to_amdgpu_crtc(crtc); + bool enable = false; + bool enabled = false; + int ret = 0; + unsigned long flag; + + if (source < 0) { + DRM_DEBUG_DRIVER("Unknown CRC source %s for CRTC%d\n", +src_name, crtc->index); + return -EINVAL; + } + + enable = amdgpu_dm_is_valid_crc_source(source); + crtc_state = to_dm_crtc_state(crtc->state); + spin_lock_irqsave(&drm_dev->event_lock, flag); + cur_crc_src = acrtc->dm_irq_params.crc_src; + spin_unlock_irqrestore(&drm_dev->event_lock, flag); + + /* Reset secure_display when we change crc source */ + amdgpu_dm_set_crc_window_default(crtc, crtc_state->stream); + + if (amdgpu_dm_crtc_configure_crc_source(crtc, crtc_state, source)) { + ret = -EINVAL; + goto cleanup; + }
[PATCH 7/7] drm/amd/display: Block the requests for secure display ROI/CRC until data ready
When the user requests for secure display ROI or CRC data, the request will be blocked until the CRC result of current frame is calculated and updated to secure display ctx in vline0 irq handler. Signed-off-by: Alan Liu --- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 8 +++- drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h | 1 + drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c | 4 4 files changed, 13 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c index ee016d5be7ac..7b7ff9a5458a 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c @@ -8864,7 +8864,12 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) (struct drm_roi *)dm_new_crtc_state->secure_display_state.roi_blob->data; if (roi_data->secure_display_enable) { + struct secure_display_context *secure_display_ctx = + &dm->secure_display_ctxs[acrtc->crtc_id]; + if (!amdgpu_dm_crc_window_is_activated(crtc)) { + init_completion(&secure_display_ctx->crc.completion); + /* Enable secure display: set crc source to "crtc" */ amdgpu_dm_crtc_set_secure_display_crc_source(crtc, "crtc"); @@ -8874,7 +8879,8 @@ static void amdgpu_dm_atomic_commit_tail(struct drm_atomic_state *state) spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); acrtc->dm_irq_params.window_param.activated = true; spin_unlock_irqrestore(&adev_to_drm(adev)->event_lock, flags); - } + } else + reinit_completion(&secure_display_ctx->crc.completion); /* Update ROI: copy ROI from dm_crtc_state to dm_irq_params */ spin_lock_irqsave(&adev_to_drm(adev)->event_lock, flags); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index f0ccf29af4f8..85cedd207c8d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -619,6 +619,7 @@ void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc) secure_display_ctx->crc.crc_R = crc[0]; secure_display_ctx->crc.crc_G = crc[1]; secure_display_ctx->crc.crc_B = crc[2]; + complete_all(&secure_display_ctx->crc.completion); } spin_unlock_irqrestore(&secure_display_ctx->crc.lock, flags1); diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h index 1b85d60488b6..64a0fd0f165f 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h @@ -46,6 +46,7 @@ struct crc_data { uint32_t crc_B; uint32_t frame_count; spinlock_t lock; + struct completion completion; }; struct crc_window_param { diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 0e9834e0506d..af1c4a62a482 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -380,6 +380,10 @@ static int amdgpu_dm_crtc_atomic_get_property(struct drm_crtc *crtc, struct secure_display_context *secure_display_ctx = &adev->dm.secure_display_ctxs[crtc->index]; + if (amdgpu_dm_crc_window_is_activated(crtc)) + wait_for_completion_interruptible_timeout( + &secure_display_ctx->crc.completion, 10 * HZ); + if (property == adev->dm.secure_display_roi_property) *val = (dm_state->secure_display_state.roi_blob) ? dm_state->secure_display_state.roi_blob->base.id : 0; -- 2.34.1
[PATCH 4/7] drm/amd/display: Implement set/get functions for secure display CRC properties
Implement set/get functions as the callback for userspace to get the CRC result values of the corresponding ROI configuration of secure display. Signed-off-by: Alan Liu --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 1 + .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 38 ++- 2 files changed, 38 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 74e42257a608..b389b1d1c370 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -736,6 +736,7 @@ struct dm_crtc_state { #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY struct { struct drm_property_blob *roi_blob; + struct drm_property_blob *crc_blob; bool roi_changed : 1; } secure_display_state; #endif diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 4457eac8273e..0e9834e0506d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -359,6 +359,10 @@ static int amdgpu_dm_crtc_atomic_set_property(struct drm_crtc *crtc, dm_state->secure_display_state.roi_changed |= drm_property_replace_blob(old_blob, new_blob); + } else if (property == adev->dm.secure_display_crc_property) { + /* don't let user set CRC data */ + return -EPERM; + } else return -EINVAL; @@ -373,12 +377,44 @@ static int amdgpu_dm_crtc_atomic_get_property(struct drm_crtc *crtc, struct drm_device *dev = crtc->dev; struct amdgpu_device *adev = drm_to_adev(dev); struct dm_crtc_state *dm_state = to_dm_crtc_state(crtc_state); + struct secure_display_context *secure_display_ctx = + &adev->dm.secure_display_ctxs[crtc->index]; if (property == adev->dm.secure_display_roi_property) *val = (dm_state->secure_display_state.roi_blob) ? dm_state->secure_display_state.roi_blob->base.id : 0; - else + else if (property == adev->dm.secure_display_crc_property) { + struct drm_crc *blob_data; + struct drm_property_blob *blob; + unsigned long flag; + + if (!amdgpu_dm_crc_window_is_activated(crtc)) { + *val = 0; + return 0; + } + + /* save new value to blob */ + blob = drm_property_create_blob(dev, + sizeof(struct drm_crc), + NULL); + if (IS_ERR(blob)) { + *val = 0; + return -ENOMEM; + } + + blob_data = (struct drm_crc *) blob->data; + spin_lock_irqsave(&secure_display_ctx->crc.lock, flag); + blob_data->crc_r = secure_display_ctx->crc.crc_R; + blob_data->crc_g = secure_display_ctx->crc.crc_G; + blob_data->crc_b = secure_display_ctx->crc.crc_B; + blob_data->frame_count = secure_display_ctx->crc.frame_count; + spin_unlock_irqrestore(&secure_display_ctx->crc.lock, flag); + + drm_property_replace_blob(&dm_state->secure_display_state.crc_blob, blob); + *val = blob->base.id; + + } else return -EINVAL; return 0; -- 2.34.1
[PATCH 3/7] drm/amd/display: Add new blob properties for secure display CRC
Add a new blob properties and implement the property creation and attachment functions for the CRC result values of secure display. Signed-off-by: Alan Liu --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 3 +++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 1 + .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h | 10 .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 23 --- include/uapi/drm/drm_mode.h | 19 +++ 5 files changed, 53 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index ee57c659f230..74e42257a608 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -503,6 +503,9 @@ struct amdgpu_display_manager { /* properties for secure_display ROI configuration */ struct drm_property *secure_display_roi_property; + + /* properties for secure_display CRC information */ + struct drm_property *secure_display_crc_property; #endif /** * @hpd_rx_offload_wq: diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index e7259ec1d644..a83cabb9b1a6 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -550,6 +550,7 @@ amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev) DRM_ERROR("amdgpu: failed to create secure display properties.\n"); for (i = 0; i < adev->mode_info.num_crtc; i++) { + spin_lock_init(&secure_display_ctxs[i].crc.lock); INIT_WORK(&secure_display_ctxs[i].forward_roi_work, amdgpu_dm_forward_crc_window); INIT_WORK(&secure_display_ctxs[i].notify_ta_work, amdgpu_dm_crtc_notify_ta_to_read); secure_display_ctxs[i].crtc = &adev->mode_info.crtcs[i]->base; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h index 66f29e3de9f9..f2def8c20d83 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h @@ -40,6 +40,14 @@ enum amdgpu_dm_pipe_crc_source { }; #ifdef CONFIG_DRM_AMD_SECURE_DISPLAY +struct crc_data { + uint32_t crc_R; + uint32_t crc_G; + uint32_t crc_B; + uint32_t frame_count; + spinlock_t lock; +}; + struct crc_window_param { uint16_t x_start; uint16_t y_start; @@ -64,6 +72,8 @@ struct secure_display_context { /* Region of Interest (ROI) */ struct rect rect; + + struct crc_data crc; }; #endif diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index e1a17f2d6f2d..4457eac8273e 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -299,16 +299,30 @@ int amdgpu_dm_crtc_create_secure_display_properties(struct amdgpu_device *adev) { struct amdgpu_display_manager *dm = &adev->dm; struct drm_device *dev = adev_to_drm(adev); - struct drm_property *roi_prop; + struct drm_property *roi_prop, *crc_prop; roi_prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, "SECURE_DISPLAY_ROI", 0); - if (!roi_prop) - return -ENOMEM; + + crc_prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, + "SECURE_DISPLAY_CRC", 0); + + if (!roi_prop || !crc_prop) + goto fail; dm->secure_display_roi_property = roi_prop; + dm->secure_display_crc_property = crc_prop; return 0; + +fail: + if (roi_prop) + drm_property_destroy(dev, roi_prop); + + if (crc_prop) + drm_property_destroy(dev, roi_prop); + + return -ENOMEM; } void amdgpu_dm_crtc_attach_secure_display_properties(struct amdgpu_device *adev, @@ -318,6 +332,9 @@ void amdgpu_dm_crtc_attach_secure_display_properties(struct amdgpu_device *adev, if (dm->secure_display_roi_property) drm_object_attach_property(&crtc->base, dm->secure_display_roi_property, 0); + + if (dm->secure_display_crc_property) + drm_object_attach_property(&crtc->base, dm->secure_display_crc_property, 0); } static int amdgpu_dm_crtc_atomic_set_property(struct drm_crtc *crtc, diff --git a/include/uapi/drm/drm_mode.h b/include/uapi/drm/drm_mode.h index 98e0a0aaa1c3..8c488ce59e7a 100644 --- a/include/uapi/drm/drm_mode.h +++ b/include/uapi/drm/drm_mode.h @@ -1323,6 +1323,25 @@ struct drm_roi { __u8 pad[7]; }; +/** + * struct drm_crc - The CRC value of the corresponding ROI of secure display. + * @crc_r: CRC value of red color. + * @crc_g: CRC va
[PATCH 2/7] drm/amd/display: Implement set/get functions for secure display ROI properties
Implement set/get functions as the callback for userspace to update or get the secure display ROI configuration. Signed-off-by: Alan Liu --- .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 51 +++ 1 file changed, 51 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index 4af7ea6fbd65..e1a17f2d6f2d 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -319,6 +319,53 @@ void amdgpu_dm_crtc_attach_secure_display_properties(struct amdgpu_device *adev, if (dm->secure_display_roi_property) drm_object_attach_property(&crtc->base, dm->secure_display_roi_property, 0); } + +static int amdgpu_dm_crtc_atomic_set_property(struct drm_crtc *crtc, + struct drm_crtc_state *crtc_state, + struct drm_property *property, + uint64_t val) +{ + struct drm_device *dev = crtc->dev; + struct amdgpu_device *adev = drm_to_adev(dev); + struct dm_crtc_state *dm_state = to_dm_crtc_state(crtc_state); + + if (property == adev->dm.secure_display_roi_property) { + struct drm_property_blob *new_blob, **old_blob; + + old_blob = &dm_state->secure_display_state.roi_blob; + + if (val != 0) { + new_blob = drm_property_lookup_blob(dev, val); + if (!new_blob) + return -EINVAL; + } + dm_state->secure_display_state.roi_changed |= + drm_property_replace_blob(old_blob, new_blob); + + } else + return -EINVAL; + + return 0; +} + +static int amdgpu_dm_crtc_atomic_get_property(struct drm_crtc *crtc, + const struct drm_crtc_state *crtc_state, + struct drm_property *property, + uint64_t *val) +{ + struct drm_device *dev = crtc->dev; + struct amdgpu_device *adev = drm_to_adev(dev); + struct dm_crtc_state *dm_state = to_dm_crtc_state(crtc_state); + + if (property == adev->dm.secure_display_roi_property) + *val = (dm_state->secure_display_state.roi_blob) + ? dm_state->secure_display_state.roi_blob->base.id : 0; + + else + return -EINVAL; + + return 0; +} #endif #ifdef CONFIG_DEBUG_FS @@ -348,6 +395,10 @@ static const struct drm_crtc_funcs amdgpu_dm_crtc_funcs = { #if defined(CONFIG_DEBUG_FS) .late_register = amdgpu_dm_crtc_late_register, #endif +#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY + .atomic_set_property = amdgpu_dm_crtc_atomic_set_property, + .atomic_get_property = amdgpu_dm_crtc_atomic_get_property, +#endif }; static void dm_crtc_helper_disable(struct drm_crtc *crtc) -- 2.34.1
[PATCH 1/7] drm/amd/display: Add new blob properties for secure display ROI
Add a new blob properties as well as the create and attach functions for configuring region of interested (ROI) of secure display. Signed-off-by: Alan Liu --- .../gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h | 10 ++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c | 4 +++ .../drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h | 5 +++ .../amd/display/amdgpu_dm/amdgpu_dm_crtc.c| 31 +++ include/uapi/drm/drm_mode.h | 20 5 files changed, 70 insertions(+) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h index 2e2413fd73a4..ee57c659f230 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.h @@ -500,6 +500,9 @@ struct amdgpu_display_manager { * all crtcs. */ struct secure_display_context *secure_display_ctxs; + + /* properties for secure_display ROI configuration */ + struct drm_property *secure_display_roi_property; #endif /** * @hpd_rx_offload_wq: @@ -726,6 +729,13 @@ struct dm_crtc_state { struct dc_info_packet vrr_infopacket; int abm_level; + +#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY + struct { + struct drm_property_blob *roi_blob; + bool roi_changed : 1; + } secure_display_state; +#endif }; #define to_dm_crtc_state(x) container_of(x, struct dm_crtc_state, base) diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c index 0802f8e8fac5..e7259ec1d644 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.c @@ -546,10 +546,14 @@ amdgpu_dm_crtc_secure_display_create_contexts(struct amdgpu_device *adev) if (!secure_display_ctxs) return NULL; + if (amdgpu_dm_crtc_create_secure_display_properties(adev)) + DRM_ERROR("amdgpu: failed to create secure display properties.\n"); + for (i = 0; i < adev->mode_info.num_crtc; i++) { INIT_WORK(&secure_display_ctxs[i].forward_roi_work, amdgpu_dm_forward_crc_window); INIT_WORK(&secure_display_ctxs[i].notify_ta_work, amdgpu_dm_crtc_notify_ta_to_read); secure_display_ctxs[i].crtc = &adev->mode_info.crtcs[i]->base; + amdgpu_dm_crtc_attach_secure_display_properties(adev, &adev->mode_info.crtcs[i]->base); } return secure_display_ctxs; diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h index 748e80ef40d0..66f29e3de9f9 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crc.h @@ -97,10 +97,15 @@ bool amdgpu_dm_crc_window_is_activated(struct drm_crtc *crtc); void amdgpu_dm_crtc_handle_crc_window_irq(struct drm_crtc *crtc); struct secure_display_context *amdgpu_dm_crtc_secure_display_create_contexts( struct amdgpu_device *adev); +int amdgpu_dm_crtc_create_secure_display_properties(struct amdgpu_device *adev); +void amdgpu_dm_crtc_attach_secure_display_properties(struct amdgpu_device *adev, + struct drm_crtc *crtc); #else #define amdgpu_dm_crc_window_is_activated(x) #define amdgpu_dm_crtc_handle_crc_window_irq(x) #define amdgpu_dm_crtc_secure_display_create_contexts(x) +#define amdgpu_dm_crtc_create_secure_display_properties(x) +#define amdgpu_dm_crtc_attach_secure_display_properties(x) #endif #endif /* AMD_DAL_DEV_AMDGPU_DM_AMDGPU_DM_CRC_H_ */ diff --git a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c index e3762e806617..4af7ea6fbd65 100644 --- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c +++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_crtc.c @@ -265,6 +265,10 @@ static struct drm_crtc_state *dm_crtc_duplicate_state(struct drm_crtc *crtc) state->cm_is_degamma_srgb = cur->cm_is_degamma_srgb; state->crc_skip_count = cur->crc_skip_count; state->mpo_requested = cur->mpo_requested; + +#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY + state->secure_display_state = cur->secure_display_state; +#endif /* TODO Duplicate dc_stream after objects are stream object is flattened */ return &state->base; @@ -290,6 +294,33 @@ static void dm_crtc_reset_state(struct drm_crtc *crtc) __drm_atomic_helper_crtc_reset(crtc, &state->base); } +#ifdef CONFIG_DRM_AMD_SECURE_DISPLAY +int amdgpu_dm_crtc_create_secure_display_properties(struct amdgpu_device *adev) +{ + struct amdgpu_display_manager *dm = &adev->dm; + struct drm_device *dev = adev_to_drm(adev); + struct drm_property *roi_prop; + + roi_prop = drm_property_create(dev, DRM_MODE_PROP_BLOB, +
[PATCH 0/7] Secure display with new CRTC properties
Dear DRM development community, We'd like to introduce the implementation of the new crtc properties. First of all, please let me introduce the problem we try to address. With the popularity of electric vehicles, the car vendors have increasing requirement for ensuring the integrity of the critical content on the display. For example, tell-tales are icons to indicate malfunction or operation on a car system. For safty concern, car vendors always want to make sure these icons are not tampered and can be correctly displayed on the instrument cluster. To address this problem, since modern display control hardware is able to calculate the CRC checksum of the display content, we are thinking of a feature to let userspace specify a region of interest (ROI) on display, and we can utilize the hardware to calculate the CRC checksum as frames scanned out, and finally, provide the checksum for userspace for validation purpose. In this case, since the icons themselves are often fixed over static backgrounds, the CRC of the ROI pixels can be known in advance. So one of the usage of ROI and corresponding CRC result is that as users know the CRC checksum of the tell-tales in advance, at runtime they can retrieve the CRC value from kernel for validation as frames are scanned out. We implement this feature and call it secure display. To let userspace set ROI and retrieve the corresponding CRC value, we provide 2 new properties, SECURE_DISPLAY_ROI and SECURE_DISPLAY_CRC. Both of them are blob properties under CRTC, and the detailed struct of the two properties are listed below. One for userspace to set ROI to kernel, and the other for userspace to retrieve CRC values from kernel. Upon userspace submitting the 4 coordinate values with secure_display_enable true, kernel instructs DC hardware to calculate the CRC value accordingly as frames scanned out. The result CRC value of RGB colors are then stored in secure_display_crc property, with a reference frame count for userspace to know which frame the CRCs are calculated at. /** * struct drm_roi - The enablement and region of interest (ROI) of secure display * @x_start: Horizontal starting coordinate of ROI. * @y_start: Vertical starting coordinate of ROI. * @x_end: Horizontal ending coordinate of ROI. * @y_end: Vertical ending coordinate of ROI. * @secure_display_enable: To enable or disable secure display. * * Userspace uses this structure to configure the region of interest and * enablement for secure display. */ struct secure_display_roi { u32 x_start; u32 y_start; u32 x_end; u32 y_end; u8 secure_display_enable; }; /** * struct drm_crc - The CRC value of the corresponding ROI of secure display. * @crc_r: CRC value of red color. * @crc_g: CRC value of green color. * @crc_b: CRC value of blue color. * @frame_count: a referenced frame count to indicate which frame the CRC values * are generated at. * * Userspace uses this structure to retrieve the CRC value of the current ROI of * secure display. @frame_count will be reset once a new ROI is updated or it reaches * its maximum value. */ struct secure_display_crc { u32 crc_r; u32 crc_g; u32 crc_b; u32 crc_frame_count; } To better introduce the usage of this feature, we also have a paired Weston application as an reference app to use secure display via the properties. Please check the Weston application and see how the application set ROI and validate the content from the CRC here: https://gitlab.freedesktop.org/wayland/weston/-/merge_requests/1236 This application can draw patterns on the display, and allow users to set ROI and submit it to kernel via properties. With kernel keeping calculating the CRC, this example application takes the first CRC as source CRC, and keeps retrieving the new CRCs at each frame later. By comparing source CRC with the following CRC value, the application can validate if the display content got changed down the road. Finally, let me briefly introduce the patch series. In this upstream we have 7 patches. The first 4 patches are adding the new properties to drm, which are the changes to drm layer: 1. Add new blob properties for secure display ROI 2. Implement set/get functions for secure display ROI properties 3. Add new blob properties for secure display CRC 4. Implement set/get functions for secure display CRC properties The remaining 3 patches are only related to the processing of ROI and CRC data in our driver, also listed here for your reference. 5. Processing secure display new ROI update in atomic commit 6. Implement the retrieval of secure display CRC data 7. Block the requests for secure display ROI/CRC until data ready Thanks for the reading and welcome any advice from your
Re: [PATCH V6 6/6] drm: bridge: samsung-dsim: Support non-burst mode
On Tue, May 16, 2023 at 7:57 AM Adam Ford wrote: > > The high-speed clock is hard-coded to the burst-clock > frequency specified in the device tree. However, when > using devices like certain bridge chips without burst mode > and varying resolutions and refresh rates, it may be > necessary to set the high-speed clock dynamically based > on the desired pixel clock for the connected device. > > This also removes the need to set a clock speed from > the device tree for non-burst mode operation, since the > pixel clock rate is the rate requested from the attached > device like a bridge chip. This should have no impact > for people using burst-mode and setting the burst clock > rate is still required for those users. If the burst > clock is not present, change the error message to > dev_info indicating the clock use the pixel clock. > > Signed-off-by: Adam Ford > Tested-by: Chen-Yu Tsai > Tested-by: Frieder Schrempf > Reviewed-by: Frieder Schrempf > --- > drivers/gpu/drm/bridge/samsung-dsim.c | 27 +-- > 1 file changed, 21 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c > b/drivers/gpu/drm/bridge/samsung-dsim.c > index 3944b7cfbbdf..03b21d13f067 100644 > --- a/drivers/gpu/drm/bridge/samsung-dsim.c > +++ b/drivers/gpu/drm/bridge/samsung-dsim.c > @@ -655,16 +655,28 @@ static unsigned long samsung_dsim_set_pll(struct > samsung_dsim *dsi, > > dsi->hs_clock = fout; > > + dsi->hs_clock = fout; > + Not sure about the double assignment. Was this caused by a rebase? ChenYu > return fout; > } > > static int samsung_dsim_enable_clock(struct samsung_dsim *dsi) > { > - unsigned long hs_clk, byte_clk, esc_clk; > + unsigned long hs_clk, byte_clk, esc_clk, pix_clk; > unsigned long esc_div; > u32 reg; > + struct drm_display_mode *m = &dsi->mode; > + int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); > + > + /* m->clock is in KHz */ > + pix_clk = m->clock * 1000; > + > + /* Use burst_clk_rate if available, otherwise use the pix_clk */ > + if (dsi->burst_clk_rate) > + hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate); > + else > + hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * > bpp, dsi->lanes)); > > - hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate); > if (!hs_clk) { > dev_err(dsi->dev, "failed to configure DSI PLL\n"); > return -EFAULT; > @@ -935,7 +947,7 @@ static void samsung_dsim_set_display_mode(struct > samsung_dsim *dsi) > u32 reg; > > if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { > - int byte_clk_khz = dsi->burst_clk_rate / 1000 / 8; > + int byte_clk_khz = dsi->hs_clock / 1000 / 8; > int hfp = (m->hsync_start - m->hdisplay) * byte_clk_khz / > m->clock; > int hbp = (m->htotal - m->hsync_end) * byte_clk_khz / > m->clock; > int hsa = (m->hsync_end - m->hsync_start) * byte_clk_khz / > m->clock; > @@ -1785,10 +1797,13 @@ static int samsung_dsim_parse_dt(struct samsung_dsim > *dsi) > return PTR_ERR(pll_clk); > } > > + /* If it doesn't exist, use pixel clock instead of failing */ > ret = samsung_dsim_of_read_u32(node, "samsung,burst-clock-frequency", > - &dsi->burst_clk_rate, 0); > - if (ret < 0) > - return ret; > + &dsi->burst_clk_rate, 1); > + if (ret < 0) { > + dev_info(dev, "Using pixel clock for HS clock frequency\n"); > + dsi->burst_clk_rate = 0; > + } > > ret = samsung_dsim_of_read_u32(node, "samsung,esc-clock-frequency", >&dsi->esc_clk_rate, 0); > -- > 2.39.2 >
Re: [PATCH] drm/msm/a6xx: don't set IO_PGTABLE_QUIRK_ARM_OUTER_WBWA with coherent SMMU
On 10.04.2023 20:52, Dmitry Baryshkov wrote: > If the Adreno SMMU is dma-coherent, allocation will fail unless we > disable IO_PGTABLE_QUIRK_ARM_OUTER_WBWA. Skip setting this quirk for the > coherent SMMUs (like we have on sm8350 platform). > > Fixes: 54af0ceb7595 ("arm64: dts: qcom: sm8350: add GPU, GMU, GPU CC and SMMU > nodes") > Reported-by: David Heidelberg > Signed-off-by: Dmitry Baryshkov > Tested-by: David Heidelberg > --- Also required for SM8450 (and others) Reviewed-by: Konrad Dybcio Tested-by: Konrad Dybcio # SM8450 HDK Cc: Konrad > drivers/gpu/drm/msm/adreno/a6xx_gpu.c | 3 ++- > 1 file changed, 2 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > index 2942d2548ce6..f74495dcbd96 100644 > --- a/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > +++ b/drivers/gpu/drm/msm/adreno/a6xx_gpu.c > @@ -1793,7 +1793,8 @@ a6xx_create_address_space(struct msm_gpu *gpu, struct > platform_device *pdev) >* This allows GPU to set the bus attributes required to use system >* cache on behalf of the iommu page table walker. >*/ > - if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice)) > + if (!IS_ERR_OR_NULL(a6xx_gpu->htw_llc_slice) && > + !device_iommu_capable(&pdev->dev, IOMMU_CAP_CACHE_COHERENCY)) > quirks |= IO_PGTABLE_QUIRK_ARM_OUTER_WBWA; > > return adreno_iommu_create_address_space(gpu, pdev, quirks);
Re: [PATCH v3 05/12] dt-bindings: display/msm: Add SM6375 MDSS
On 7.05.2023 10:20, Krzysztof Kozlowski wrote: > On 05/05/2023 23:40, Konrad Dybcio wrote: >> Document the SM6375 MDSS. >> >> Signed-off-by: Konrad Dybcio >> --- >> .../bindings/display/msm/qcom,sm6375-mdss.yaml | 216 >> + >> 1 file changed, 216 insertions(+) >> > > Thank you for your patch. There is something to discuss/improve. > >> + >> +examples: >> + - | >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +display-subsystem@5e0 { >> +compatible = "qcom,sm6375-mdss"; >> +reg = <0x05e0 0x1000>; >> +reg-names = "mdss"; >> + >> +power-domains = <&dispcc MDSS_GDSC>; >> + >> +clocks = <&gcc GCC_DISP_AHB_CLK>, >> + <&dispcc DISP_CC_MDSS_AHB_CLK>, >> + <&dispcc DISP_CC_MDSS_MDP_CLK>; >> +clock-names = "iface", "ahb", "core"; >> + >> +interrupts = ; >> +interrupt-controller; >> +#interrupt-cells = <1>; >> + >> +iommus = <&apps_smmu 0x820 0x2>; >> +#address-cells = <1>; >> +#size-cells = <1>; >> +ranges; >> + >> +display-controller@5e01000 { >> +compatible = "qcom,sm6375-dpu"; >> +reg = <0x05e01000 0x8e030>, >> + <0x05eb 0x2008>; >> +reg-names = "mdp", "vbif"; >> + >> +clocks = <&dispcc DISP_CC_MDSS_AHB_CLK>, >> + <&gcc GCC_DISP_HF_AXI_CLK>, >> + <&dispcc DISP_CC_MDSS_MDP_CLK>, >> + <&dispcc DISP_CC_MDSS_MDP_LUT_CLK>, >> + <&dispcc DISP_CC_MDSS_ROT_CLK>, >> + <&dispcc DISP_CC_MDSS_VSYNC_CLK>, >> + <&gcc GCC_DISP_THROTTLE_CORE_CLK>; >> +clock-names = "iface", >> + "bus", >> + "core", >> + "lut", >> + "rot", >> + "vsync", >> + "throttle"; > > Are you sure you have clocks in correct order? I see warnings... Right, testing *both* the DTs and bindings after making changes sounds like a good thing to stop forgetting.. Konrad > > Best regards, > Krzysztof >
Re: [PATCH v3 1/2] iommu/arm-smmu-qcom: Fix missing adreno_smmu's
On 11.05.2023 16:59, Rob Clark wrote: > From: Rob Clark > > When the special handling of qcom,adreno-smmu was moved into > qcom_smmu_create(), it was overlooked that we didn't have all the > required entries in qcom_smmu_impl_of_match. So we stopped getting > adreno_smmu_priv on sc7180, breaking per-process pgtables. > > Fixes: 30b912a03d91 ("iommu/arm-smmu-qcom: Move the qcom,adreno-smmu check > into qcom_smmu_create") > Suggested-by: Lepton Wu > Signed-off-by: Rob Clark > --- > drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c | 7 +++ > 1 file changed, 7 insertions(+) > > diff --git a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > index d1b296b95c86..66e191773099 100644 > --- a/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > +++ b/drivers/iommu/arm/arm-smmu/arm-smmu-qcom.c > @@ -496,20 +496,21 @@ static const struct qcom_smmu_match_data > qcom_smmu_500_impl0_data = { > /* > * Do not add any more qcom,SOC-smmu-500 entries to this list, unless they > need > * special handling and can not be covered by the qcom,smmu-500 entry. > */ > static const struct of_device_id __maybe_unused qcom_smmu_impl_of_match[] = { > { .compatible = "qcom,msm8996-smmu-v2", .data = &msm8996_smmu_data }, > { .compatible = "qcom,msm8998-smmu-v2", .data = &qcom_smmu_v2_data }, > { .compatible = "qcom,qcm2290-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > { .compatible = "qcom,qdu1000-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > { .compatible = "qcom,sc7180-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > + { .compatible = "qcom,sc7180-smmu-v2", .data = &qcom_smmu_v2_data }, > { .compatible = "qcom,sc7280-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > { .compatible = "qcom,sc8180x-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > { .compatible = "qcom,sc8280xp-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > { .compatible = "qcom,sdm630-smmu-v2", .data = &qcom_smmu_v2_data }, > { .compatible = "qcom,sdm845-smmu-v2", .data = &qcom_smmu_v2_data }, > { .compatible = "qcom,sdm845-smmu-500", .data = &sdm845_smmu_500_data }, > { .compatible = "qcom,sm6115-smmu-500", .data = > &qcom_smmu_500_impl0_data}, > { .compatible = "qcom,sm6125-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > { .compatible = "qcom,sm6350-smmu-v2", .data = &qcom_smmu_v2_data }, > { .compatible = "qcom,sm6350-smmu-500", .data = > &qcom_smmu_500_impl0_data }, > @@ -540,12 +541,18 @@ struct arm_smmu_device *qcom_smmu_impl_init(struct > arm_smmu_device *smmu) > /* Match platform for ACPI boot */ > if (acpi_match_platform_list(qcom_acpi_platlist) >= 0) > return qcom_smmu_create(smmu, > &qcom_smmu_500_impl0_data); > } > #endif > > match = of_match_node(qcom_smmu_impl_of_match, np); > if (match) > return qcom_smmu_create(smmu, match->data); > > + /* If you hit this WARN_ON() you are missing an entry in the > + * qcom_smmu_impl_of_match[] table, and GPU per-process page- > + * tables will be broken. > + */ Nit: I think people generally do /* * but I'm not the maintainer Reviewed-by: Konrad Dybcio Cc: Konrad > + WARN_ON(of_device_is_compatible(np, "qcom,adreno-smmu")); > + > return smmu; > }
Re: [PATCH v10 4/8] drm/msm: Add MSM-specific DSC helper methods
On 5/15/2023 3:07 PM, Dmitry Baryshkov wrote: On 16/05/2023 01:01, Marijn Suijten wrote: On 2023-05-15 13:29:21, Jessica Zhang wrote: Const, as requested elsewhere. But this function is not used anywhere in any of the series (because we replaced the usages with more sensible member accesses like slice_chunk_size). Acked. I would prefer to keep this helper so that we have a way to easily get BPP information from the DRM DSC config in the future, but if you'd prefer we add this helper then, I'm also ok with that. The inverse helper is available ad DSC_BPP in drm_dsc_helper.c. Perhaps we can move the two variants to the header and define them uniformly? This isn't MSM-specific it seems (i.e. the format supports fractional bpp but no RC parameters appear to be defined for such a format yet). I think DSC_BPP was removed (around v2 or v3 if I read changelog correctly). Hi Dmitry, That's correct, we did have a DSC_BPP macro with the same functionality as msm_dsc_get_bpp_int, but it was renamed in v2 to msm_dsc_get_bpp_int (there's a typo in the changelog... I will correct that in the next revision). However, I do see a DSC_BPP macro in drm_dsc_helper.c that has a different functionality. Thanks, Jessica Zhang As for the fraction-point BPP, I think AMD supports .5 bpp granularity, see drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h -- With best wishes Dmitry
Re: [PATCH v10 4/8] drm/msm: Add MSM-specific DSC helper methods
On 5/15/2023 3:01 PM, Marijn Suijten wrote: On 2023-05-15 13:29:21, Jessica Zhang wrote: Const, as requested elsewhere. But this function is not used anywhere in any of the series (because we replaced the usages with more sensible member accesses like slice_chunk_size). Acked. I would prefer to keep this helper so that we have a way to easily get BPP information from the DRM DSC config in the future, but if you'd prefer we add this helper then, I'm also ok with that. The inverse helper is available ad DSC_BPP in drm_dsc_helper.c. Perhaps we can move the two variants to the header and define them uniformly? This isn't MSM-specific it seems (i.e. the format supports fractional bpp but no RC parameters appear to be defined for such a format yet). + * @dsc: Pointer to drm dsc config struct + * Returns: Integer value representing pclk per interface + * + * Note: This value will then be passed along to DSI and DP for some more + * calculations. This is because DSI and DP divide the pclk_per_intf value + * by different values depending on if widebus is enabled. Can you elaborate what this "note" is trying to tell users of this function? That they should not use bytes_per_line raw? That it doesn't actually represent bytes_per_line if the extra calculations mentioned here are not applied? The latter -- this method is used for calculating the pclk for DSI and DP. While it does get the raw bytes_per_line, there are some extra calculations needed before it can be set as the pclk_rate. These "extra calculations" are different between DP and DSI. For more context, please refer to the earlier revisions of this patch and the usage of the helper in dsi_host.c Note that I'm not just asking to explain it to me, but to explain it in the documentation. The function is named bytes_per_line() but then Returns: says it returns the pclk per interface, then the note says that it actually doesn't unless extra calculations are applied. We can explain the same much more concisely by rewriting Returns and dropping Note: Returns: Integer value representing bytes per line. DSI and DP need to perform further processing/calculations to turn this into pclk_per_intf, such as dividing by different values depending on if widebus is enabled. And so we have written the same, just more concisely. Feel free to reword it slightly, such as dropping the word "processing". Sure, sounds good. Not sure that this helper is useful though: it is only used where msm_dsc_get_slice_per_intf() was already called, so it makes more sense to the reader to just multiply slice_per_intf by slice_chunk_size than to defer to an opaque helper. I would prefer to keep this as a helper as this math is common between DP and DSI, and I believe the name of the helper accurately reflects what is being calculated. If there's any confusion with the name of the method, I am open to suggestions. The name is good, I'm just not too keen on it hiding the multiplication with msm_dsc_get_slice_per_intf() which is already also computed and available in DSI, and I assume DP too? Got it, I see why you want to make that change now. DP only uses get_slice_per_intf() to get eol_byte_num similarly to DSI, so I can just do that then. Thanks, Jessica Zhang - Marijn
Re: [PATCH] drm/i915/guc/slpc: Disable rps_boost debugfs
On Mon, 15 May 2023 15:58:26 -0700, Dixit, Ashutosh wrote: > > On Mon, 15 May 2023 15:23:58 -0700, Belgaumkar, Vinay wrote: > > > > > > On 5/12/2023 5:39 PM, Dixit, Ashutosh wrote: > > > On Fri, 12 May 2023 16:56:03 -0700, Vinay Belgaumkar wrote: > > > Hi Vinay, > > > > > >> rps_boost debugfs shows host turbo related info. This is not valid > > >> when SLPC is enabled. > > > A couple of thoughts about this. It appears people are know only about > > > rps_boost_info and don't know about guc_slpc_info? So: > > > > > > a. Instead of hiding the rps_boost_info file do we need to print there > > > saying "SLPC is enabled, go look at guc_slpc_info"? > > rps_boost_info has an eval() function which disables the interface when RPS > > is OFF. This is indeed the case here, so shouldn't we just follow that > > instead of trying to link the two? > > > > > > b. Or, even just call guc_slpc_info_show from rps_boost_show (so the two > > > files will show the same SLPC information)? > > > > slpc_info has a lot of other info like the SLPC state, not sure that > > matches up with the rps_boost_info name. > > OK, I have asked in https://gitlab.freedesktop.org/drm/intel/-/issues/7632: > > @mattst88: is it acceptable to hide the > /sys/kernel/debug/dri/0/i915_rps_boost_info file so that it doesn't cause > confusion. And then user would have to go look at > /sys/kernel/debug/dri/0/i915_guc_slpc_info or some such file when SLPC is > being used? That's what the patch above is doing. > > Let's see what we hear from @mattst88. @mattst88 agreed on #intel-gfx IRC, so ok by me: Reviewed-by: Ashutosh Dixit > > > > > > >> guc_slpc_info already shows the number of boosts. Add num_waiters there > > >> as well and disable rps_boost when SLPC is enabled. > > >> > > >> Bug: https://gitlab.freedesktop.org/drm/intel/-/issues/7632 > > >> Signed-off-by: Vinay Belgaumkar > > Thanks. > -- > Ashutosh
Re: [PATCH v8 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
On 5/15/2023 3:23 PM, Marijn Suijten wrote: On 2023-05-15 15:03:46, Abhinav Kumar wrote: On 5/15/2023 2:21 PM, Marijn Suijten wrote: On 2023-05-12 11:00:22, Kuogee Hsieh wrote: From: Abhinav Kumar Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and feature flag information. Each display compression engine (DCE) contains dual hard slice DSC encoders so both share same base address but with its own different sub block address. Can we have an explanation of hard vs soft slices in some commit message and/or code documentation? Not in this one. It wont look appropriate. I would rather remove "hard" to avoid confusion. That is totally fine, let's remove it instead. + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sblk_0), Downstream says that the size is 0x10 (and 0x100 for the enc sblk, 0x10 for the ctl sblk). This simply fills it up to the start of the enc sblk so that we can see all registers in the dump? After all only DSC_CMN_MAIN_CNF is defined in the main register space, so 0x10 is adequate. .len today is always only for the dump. and yes even here we have only 0x100 for the enc and 0x10 for the ctl. +static const struct dpu_dsc_sub_blks dsc_sblk_0 = { + .enc = {.base = 0x100, .len = 0x100}, + .ctl = {.base = 0xF00, .len = 0x10}, +}; The issue here is that, the dpu snapshot does not handle sub_blk parsing today. Its a to-do item. So for that reason, 0x100 was used here to atleast get the full encoder dumps. But then you don't see the ENC block? It starts at 0x100 (or 0x200) so then the length should be longer... it should in fact depend on even/odd DCE then? You are right that the length should be longer. It should be 0x29c then and ctl blocks will not be included anyway. The fundamental issue which remains despite increasing the length will be that the two blocks will print duplicate information. So dce_0_0 and dce_0_1 will print the same information twice as the base address is the same. Odd/even DCE intelligence is not there in these macros and will be an overkill to just support the dump. So overall, I dont think any of it is a good solution yet. I think the best way to do this will be to add sub-block parsing support to the DPU devcoredump. So what will happen is similar to downstream design in sde_dbg, when a block has sub-blocks we will respect the sub-block's len and not the parent block's as that will be more accurate. If 0x29c is going to help the cause till then we can change it. + DSC_BLK_1_2("dce_0", DSC_1, 0x8, 0x100, 0, dsc_sblk_1), Should we add an extra suffix to the name to indicate which hard-slice DSC encoder it is? i.e. "dce_0_0" and "dce_0_1" etc? Ok, that should be fine. We can add it. Great, thanks! + DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1), See comment below about loose BIT() in features. Responded below. +}; + static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dspp = sm8350_dspp, .pingpong_count = ARRAY_SIZE(sm8350_pp), .pingpong = sm8350_pp, + .dsc = sm8350_dsc, + .dsc_count = ARRAY_SIZE(sm8350_dsc), Count goes first **everywhere else**, let's not break consistency here. the order of DSC entries is swapped for all chipsets. Please refer to dpu_sc8180x_cfg, dpu_sm8250_cfg etc. Thanks for confirming that this is not the case in a followup mail :) So if you are talking about consistency, this is actually consistent with whats present in other chipsets. If you are very particular about this, then once this lands, you can change the order for all of them in another change. Same answer for all swap comments. +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +#define DSC_BLK_1_2(_name, _id, _base, _len, _features, _sblk) \ There are no address values here so this comment doesn't seem very useful, and it is already duplicated on every DSC block array, where the duplication is more visible. Drop the comment here? _base is the address. So base address. Does that clarify things? This is referring to the NOTE: comment above. There's _base as address here, yes, but there's no context here that it'll be used in duplicate fashion, unlike the SoC catalog files. The request is to just drop it here as it adds no value. The duplication is there. the base is same for both the entries with dce_0. +static const struct dpu_dsc_cfg sc8280xp_dsc[] = { + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sb
[PATCH V6 5/6] drm: bridge: samsung-dsim: Dynamically configure DPHY timing
The DPHY timings are currently hard coded. Since the input clock can be variable, the phy timings need to be variable too. To facilitate this, we need to cache the hs_clock based on what is generated from the PLL. The phy_mipi_dphy_get_default_config_for_hsclk function configures the DPHY timings in pico-seconds, and a small macro converts those timings into clock cycles based on the hs_clk. Signed-off-by: Adam Ford Signed-off-by: Lucas Stach Tested-by: Chen-Yu Tsai Tested-by: Frieder Schrempf Reviewed-by: Frieder Schrempf Tested-by: Michael Walle --- drivers/gpu/drm/bridge/samsung-dsim.c | 57 +++ include/drm/bridge/samsung-dsim.h | 1 + 2 files changed, 51 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 08266303c261..3944b7cfbbdf 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -218,6 +218,8 @@ #define OLD_SCLK_MIPI_CLK_NAME "pll_clk" +#define PS_TO_CYCLE(ps, hz) DIV64_U64_ROUND_CLOSEST(((ps) * (hz)), 1ULL) + static const char *const clk_names[5] = { "bus_clk", "sclk_mipi", @@ -651,6 +653,8 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi, reg = samsung_dsim_read(dsi, DSIM_STATUS_REG); } while ((reg & DSIM_PLL_STABLE) == 0); + dsi->hs_clock = fout; + return fout; } @@ -698,13 +702,46 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi) const struct samsung_dsim_driver_data *driver_data = dsi->driver_data; const unsigned int *reg_values = driver_data->reg_values; u32 reg; + struct phy_configure_opts_mipi_dphy cfg; + int clk_prepare, lpx, clk_zero, clk_post, clk_trail; + int hs_exit, hs_prepare, hs_zero, hs_trail; + unsigned long long byte_clock = dsi->hs_clock / 8; if (driver_data->has_freqband) return; + phy_mipi_dphy_get_default_config_for_hsclk(dsi->hs_clock, + dsi->lanes, &cfg); + + /* +* TODO: +* The tech reference manual for i.MX8M Mini/Nano/Plus +* doesn't state what the definition of the PHYTIMING +* bits are beyond their address and bit position. +* After reviewing NXP's downstream code, it appears +* that the various PHYTIMING registers take the number +* of cycles and use various dividers on them. This +* calculation does not result in an exact match to the +* downstream code, but it is very close, and it appears +* to sync at a variety of resolutions. If someone +* can get a more accurate mathematical equation needed +* for these registers, this should be updated. +*/ + + lpx = PS_TO_CYCLE(cfg.lpx, byte_clock); + hs_exit = PS_TO_CYCLE(cfg.hs_exit, byte_clock); + clk_prepare = PS_TO_CYCLE(cfg.clk_prepare, byte_clock); + clk_zero = PS_TO_CYCLE(cfg.clk_zero, byte_clock); + clk_post = PS_TO_CYCLE(cfg.clk_post, byte_clock); + clk_trail = PS_TO_CYCLE(cfg.clk_trail, byte_clock); + hs_prepare = PS_TO_CYCLE(cfg.hs_prepare, byte_clock); + hs_zero = PS_TO_CYCLE(cfg.hs_zero, byte_clock); + hs_trail = PS_TO_CYCLE(cfg.hs_trail, byte_clock); + /* B D-PHY: D-PHY Master & Slave Analog Block control */ reg = reg_values[PHYCTRL_ULPS_EXIT] | reg_values[PHYCTRL_VREG_LP] | reg_values[PHYCTRL_SLEW_UP]; + samsung_dsim_write(dsi, DSIM_PHYCTRL_REG, reg); /* @@ -712,7 +749,9 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi) * T HS-EXIT: Time that the transmitter drives LP-11 following a HS * burst */ - reg = reg_values[PHYTIMING_LPX] | reg_values[PHYTIMING_HS_EXIT]; + + reg = DSIM_PHYTIMING_LPX(lpx) | DSIM_PHYTIMING_HS_EXIT(hs_exit); + samsung_dsim_write(dsi, DSIM_PHYTIMING_REG, reg); /* @@ -728,10 +767,11 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi) * T CLK-TRAIL: Time that the transmitter drives the HS-0 state after * the last payload clock bit of a HS transmission burst */ - reg = reg_values[PHYTIMING_CLK_PREPARE] | - reg_values[PHYTIMING_CLK_ZERO] | - reg_values[PHYTIMING_CLK_POST] | - reg_values[PHYTIMING_CLK_TRAIL]; + + reg = DSIM_PHYTIMING1_CLK_PREPARE(clk_prepare) | + DSIM_PHYTIMING1_CLK_ZERO(clk_zero)| + DSIM_PHYTIMING1_CLK_POST(clk_post)| + DSIM_PHYTIMING1_CLK_TRAIL(clk_trail); samsung_dsim_write(dsi, DSIM_PHYTIMING1_REG, reg); @@ -744,8 +784,11 @@ static void samsung_dsim_set_phy_ctrl(struct samsung_dsim *dsi) * T HS-TRAIL: Time that the transmitter drives the flipped differential * state after last payload da
[PATCH V6 6/6] drm: bridge: samsung-dsim: Support non-burst mode
The high-speed clock is hard-coded to the burst-clock frequency specified in the device tree. However, when using devices like certain bridge chips without burst mode and varying resolutions and refresh rates, it may be necessary to set the high-speed clock dynamically based on the desired pixel clock for the connected device. This also removes the need to set a clock speed from the device tree for non-burst mode operation, since the pixel clock rate is the rate requested from the attached device like a bridge chip. This should have no impact for people using burst-mode and setting the burst clock rate is still required for those users. If the burst clock is not present, change the error message to dev_info indicating the clock use the pixel clock. Signed-off-by: Adam Ford Tested-by: Chen-Yu Tsai Tested-by: Frieder Schrempf Reviewed-by: Frieder Schrempf --- drivers/gpu/drm/bridge/samsung-dsim.c | 27 +-- 1 file changed, 21 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 3944b7cfbbdf..03b21d13f067 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -655,16 +655,28 @@ static unsigned long samsung_dsim_set_pll(struct samsung_dsim *dsi, dsi->hs_clock = fout; + dsi->hs_clock = fout; + return fout; } static int samsung_dsim_enable_clock(struct samsung_dsim *dsi) { - unsigned long hs_clk, byte_clk, esc_clk; + unsigned long hs_clk, byte_clk, esc_clk, pix_clk; unsigned long esc_div; u32 reg; + struct drm_display_mode *m = &dsi->mode; + int bpp = mipi_dsi_pixel_format_to_bpp(dsi->format); + + /* m->clock is in KHz */ + pix_clk = m->clock * 1000; + + /* Use burst_clk_rate if available, otherwise use the pix_clk */ + if (dsi->burst_clk_rate) + hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate); + else + hs_clk = samsung_dsim_set_pll(dsi, DIV_ROUND_UP(pix_clk * bpp, dsi->lanes)); - hs_clk = samsung_dsim_set_pll(dsi, dsi->burst_clk_rate); if (!hs_clk) { dev_err(dsi->dev, "failed to configure DSI PLL\n"); return -EFAULT; @@ -935,7 +947,7 @@ static void samsung_dsim_set_display_mode(struct samsung_dsim *dsi) u32 reg; if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { - int byte_clk_khz = dsi->burst_clk_rate / 1000 / 8; + int byte_clk_khz = dsi->hs_clock / 1000 / 8; int hfp = (m->hsync_start - m->hdisplay) * byte_clk_khz / m->clock; int hbp = (m->htotal - m->hsync_end) * byte_clk_khz / m->clock; int hsa = (m->hsync_end - m->hsync_start) * byte_clk_khz / m->clock; @@ -1785,10 +1797,13 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi) return PTR_ERR(pll_clk); } + /* If it doesn't exist, use pixel clock instead of failing */ ret = samsung_dsim_of_read_u32(node, "samsung,burst-clock-frequency", - &dsi->burst_clk_rate, 0); - if (ret < 0) - return ret; + &dsi->burst_clk_rate, 1); + if (ret < 0) { + dev_info(dev, "Using pixel clock for HS clock frequency\n"); + dsi->burst_clk_rate = 0; + } ret = samsung_dsim_of_read_u32(node, "samsung,esc-clock-frequency", &dsi->esc_clk_rate, 0); -- 2.39.2
[PATCH V6 4/6] drm: bridge: samsung-dsim: Select GENERIC_PHY_MIPI_DPHY
In order to support variable DPHY timings, it's necessary to enable GENERIC_PHY_MIPI_DPHY so phy_mipi_dphy_get_default_config can be used to determine the nominal values for a given resolution and refresh rate. Signed-off-by: Adam Ford Tested-by: Frieder Schrempf Reviewed-by: Frieder Schrempf Tested-by: Chen-Yu Tsai --- drivers/gpu/drm/bridge/Kconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index f076a09afac0..82c68b042444 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig @@ -227,6 +227,7 @@ config DRM_SAMSUNG_DSIM select DRM_KMS_HELPER select DRM_MIPI_DSI select DRM_PANEL_BRIDGE + select GENERIC_PHY_MIPI_DPHY help The Samsung MIPI DSIM bridge controller driver. This MIPI DSIM bridge can be found it on Exynos SoCs and -- 2.39.2
[PATCH V6 3/6] drm: bridge: samsung-dsim: Fetch pll-clock-frequency automatically
Make the pll-clock-frequency optional. If it's present, use it to maintain backwards compatibility with existing hardware. If it is absent, read clock rate of "sclk_mipi" to determine the rate. Since it can be optional, change the message from an error to dev_info. Signed-off-by: Adam Ford Tested-by: Chen-Yu Tsai Tested-by: Frieder Schrempf Reviewed-by: Frieder Schrempf --- drivers/gpu/drm/bridge/samsung-dsim.c | 23 --- 1 file changed, 16 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index bf4b33d2de76..08266303c261 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -1712,11 +1712,11 @@ static const struct mipi_dsi_host_ops samsung_dsim_ops = { }; static int samsung_dsim_of_read_u32(const struct device_node *np, - const char *propname, u32 *out_value) + const char *propname, u32 *out_value, bool optional) { int ret = of_property_read_u32(np, propname, out_value); - if (ret < 0) + if (ret < 0 && !optional) pr_err("%pOF: failed to get '%s' property\n", np, propname); return ret; @@ -1726,20 +1726,29 @@ static int samsung_dsim_parse_dt(struct samsung_dsim *dsi) { struct device *dev = dsi->dev; struct device_node *node = dev->of_node; + struct clk *pll_clk; int ret; ret = samsung_dsim_of_read_u32(node, "samsung,pll-clock-frequency", - &dsi->pll_clk_rate); - if (ret < 0) - return ret; + &dsi->pll_clk_rate, 1); + + /* If it doesn't exist, read it from the clock instead of failing */ + if (ret < 0) { + dev_info(dev, "Using sclk_mipi for pll clock frequency\n"); + pll_clk = devm_clk_get(dev, "sclk_mipi"); + if (!IS_ERR(pll_clk)) + dsi->pll_clk_rate = clk_get_rate(pll_clk); + else + return PTR_ERR(pll_clk); + } ret = samsung_dsim_of_read_u32(node, "samsung,burst-clock-frequency", - &dsi->burst_clk_rate); + &dsi->burst_clk_rate, 0); if (ret < 0) return ret; ret = samsung_dsim_of_read_u32(node, "samsung,esc-clock-frequency", - &dsi->esc_clk_rate); + &dsi->esc_clk_rate, 0); if (ret < 0) return ret; -- 2.39.2
[PATCH V6 2/6] drm: bridge: samsung-dsim: Fix PMS Calculator on imx8m[mnp]
According to Table 13-45 of the i.MX8M Mini Reference Manual, the min and max values for M and the frequency range for the VCO_out calculator were incorrect. This information was contradicted in other parts of the mini, nano and plus manuals. After reaching out to my NXP Rep, when confronting him about discrepencies in the Nano manual, he responded with: "Yes it is definitely wrong, the one that is part of the NOTE in MIPI_DPHY_M_PLLPMS register table against PMS_P, PMS_M and PMS_S is not correct. I will report this to Doc team, the one customer should be take into account is the Table 13-40 DPHY PLL Parameters and the Note above." These updated values also match what is used in the NXP downstream kernel. To fix this, make new variables to hold the min and max values of m and the minimum value of VCO_out, and update the PMS calculator to use these new variables instead of using hard-coded values to keep the backwards compatibility with other parts using this driver. Fixes: 4d562c70c4dc ("drm: bridge: samsung-dsim: Add i.MX8M Mini/Nano support") Signed-off-by: Adam Ford Reviewed-by: Lucas Stach Tested-by: Chen-Yu Tsai Tested-by: Frieder Schrempf Reviewed-by: Frieder Schrempf --- drivers/gpu/drm/bridge/samsung-dsim.c | 22 -- include/drm/bridge/samsung-dsim.h | 3 +++ 2 files changed, 23 insertions(+), 2 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index 2be3b58624c3..bf4b33d2de76 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -405,6 +405,9 @@ static const struct samsung_dsim_driver_data exynos3_dsi_driver_data = { .num_bits_resol = 11, .pll_p_offset = 13, .reg_values = reg_values, + .m_min = 41, + .m_max = 125, + .min_freq = 500, }; static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { @@ -418,6 +421,9 @@ static const struct samsung_dsim_driver_data exynos4_dsi_driver_data = { .num_bits_resol = 11, .pll_p_offset = 13, .reg_values = reg_values, + .m_min = 41, + .m_max = 125, + .min_freq = 500, }; static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = { @@ -429,6 +435,9 @@ static const struct samsung_dsim_driver_data exynos5_dsi_driver_data = { .num_bits_resol = 11, .pll_p_offset = 13, .reg_values = reg_values, + .m_min = 41, + .m_max = 125, + .min_freq = 500, }; static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = { @@ -441,6 +450,9 @@ static const struct samsung_dsim_driver_data exynos5433_dsi_driver_data = { .num_bits_resol = 12, .pll_p_offset = 13, .reg_values = exynos5433_reg_values, + .m_min = 41, + .m_max = 125, + .min_freq = 500, }; static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = { @@ -453,6 +465,9 @@ static const struct samsung_dsim_driver_data exynos5422_dsi_driver_data = { .num_bits_resol = 12, .pll_p_offset = 13, .reg_values = exynos5422_reg_values, + .m_min = 41, + .m_max = 125, + .min_freq = 500, }; static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = { @@ -469,6 +484,9 @@ static const struct samsung_dsim_driver_data imx8mm_dsi_driver_data = { */ .pll_p_offset = 14, .reg_values = imx8mm_dsim_reg_values, + .m_min = 64, + .m_max = 1023, + .min_freq = 1050, }; static const struct samsung_dsim_driver_data * @@ -547,12 +565,12 @@ static unsigned long samsung_dsim_pll_find_pms(struct samsung_dsim *dsi, tmp = (u64)fout * (_p << _s); do_div(tmp, fin); _m = tmp; - if (_m < 41 || _m > 125) + if (_m < driver_data->m_min || _m > driver_data->m_max) continue; tmp = (u64)_m * fin; do_div(tmp, _p); - if (tmp < 500 * MHZ || + if (tmp < driver_data->min_freq * MHZ || tmp > driver_data->max_freq * MHZ) continue; diff --git a/include/drm/bridge/samsung-dsim.h b/include/drm/bridge/samsung-dsim.h index ba5484de2b30..a1a5b2b89a7a 100644 --- a/include/drm/bridge/samsung-dsim.h +++ b/include/drm/bridge/samsung-dsim.h @@ -54,11 +54,14 @@ struct samsung_dsim_driver_data { unsigned int has_freqband:1; unsigned int has_clklane_stop:1; unsigned int num_clks; + unsigned int min_freq; unsigned int max_freq; unsigned int wait_for_reset; unsigned int num_bits_resol; unsigned int pll_p_offset; const unsigned int *reg_values; + u16 m_min; + u16 m_max; }; struct samsung_dsim_host_ops { -- 2.39.2
[PATCH V6 1/6] drm: bridge: samsung-dsim: fix blanking packet size calculation
From: Lucas Stach Scale the blanking packet sizes to match the ratio between HS clock and DPI interface clock. The controller seems to do internal scaling to the number of active lanes, so we don't take those into account. Signed-off-by: Lucas Stach Signed-off-by: Adam Ford Tested-by: Chen-Yu Tsai Tested-by: Frieder Schrempf --- drivers/gpu/drm/bridge/samsung-dsim.c | 18 +++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/bridge/samsung-dsim.c b/drivers/gpu/drm/bridge/samsung-dsim.c index e0a402a85787..2be3b58624c3 100644 --- a/drivers/gpu/drm/bridge/samsung-dsim.c +++ b/drivers/gpu/drm/bridge/samsung-dsim.c @@ -874,17 +874,29 @@ static void samsung_dsim_set_display_mode(struct samsung_dsim *dsi) u32 reg; if (dsi->mode_flags & MIPI_DSI_MODE_VIDEO) { + int byte_clk_khz = dsi->burst_clk_rate / 1000 / 8; + int hfp = (m->hsync_start - m->hdisplay) * byte_clk_khz / m->clock; + int hbp = (m->htotal - m->hsync_end) * byte_clk_khz / m->clock; + int hsa = (m->hsync_end - m->hsync_start) * byte_clk_khz / m->clock; + + /* remove packet overhead when possible */ + hfp = max(hfp - 6, 0); + hbp = max(hbp - 6, 0); + hsa = max(hsa - 6, 0); + + dev_dbg(dsi->dev, "calculated hfp: %u, hbp: %u, hsa: %u", + hfp, hbp, hsa); + reg = DSIM_CMD_ALLOW(0xf) | DSIM_STABLE_VFP(m->vsync_start - m->vdisplay) | DSIM_MAIN_VBP(m->vtotal - m->vsync_end); samsung_dsim_write(dsi, DSIM_MVPORCH_REG, reg); - reg = DSIM_MAIN_HFP(m->hsync_start - m->hdisplay) - | DSIM_MAIN_HBP(m->htotal - m->hsync_end); + reg = DSIM_MAIN_HFP(hfp) | DSIM_MAIN_HBP(hbp); samsung_dsim_write(dsi, DSIM_MHPORCH_REG, reg); reg = DSIM_MAIN_VSA(m->vsync_end - m->vsync_start) - | DSIM_MAIN_HSA(m->hsync_end - m->hsync_start); + | DSIM_MAIN_HSA(hsa); samsung_dsim_write(dsi, DSIM_MSYNC_REG, reg); } reg = DSIM_MAIN_HRESOL(m->hdisplay, num_bits_resol) | -- 2.39.2
[PATCH V6 0/6] drm: bridge: samsung-dsim: Support variable clocking
This series fixes the blanking pack size and the PMS calculation. It then adds support to allows the DSIM to dynamically DPHY clocks, and support non-burst mode while allowing the removal of the hard-coded clock values for the PLL for imx8m mini/nano/plus, and it allows the removal of the burst-clock device tree entry when burst-mode isn't supported by connected devices like an HDMI brige. In that event, the HS clock is set to the value requested by the bridge chip. This has been tested on both an i.MX8M Nano and i.MX8M Plus, and should work on i.MX8M Mini as well. Marek Szyprowski has tested it on various Exynos boards. Adam Ford (5): drm: bridge: samsung-dsim: Fix PMS Calculator on imx8m[mnp] drm: bridge: samsung-dsim: Fetch pll-clock-frequency automatically drm: bridge: samsung-dsim: Select GENERIC_PHY_MIPI_DPHY drm: bridge: samsung-dsim: Dynamically configure DPHY timing drm: bridge: samsung-dsim: Support non-burst mode Lucas Stach (1): drm: bridge: samsung-dsim: fix blanking packet size calculation drivers/gpu/drm/bridge/Kconfig| 1 + drivers/gpu/drm/bridge/samsung-dsim.c | 143 +- include/drm/bridge/samsung-dsim.h | 4 + 3 files changed, 125 insertions(+), 23 deletions(-) V6: Squash-in an additional error fix from Lucas Stach regarding the DPHY calcuations. Remove the dynamic_dphy variable and let everyone use the new calculations. Move the hs_clock caching from patch 6 to patch 5 to go along with the DPHY calcuations since they are now based on the recorded hs_clock rate. V5: Update error message to dev_info and change them to indicate what is happening without sounding like an error when optional device tree entries are missing. V4: Undo some accidental whitespace changes, rename PS_TO_CYCLE variables to ps and hz from PS and MHz. Remove if check before the samsung_dsim_set_phy_ctrl call since it's unnecessary. Added additional tested-by and reviewed-by comments. Squash patches 6 and 7 together since the supporting non-burst (patch 6) mode doesn't really work until patch 7 was applied. V3: When checking if the bust-clock is present, only check for it in the device tree, and don't check the presence of the MIPI_DSI_MODE_VIDEO_BURST flag as it breaks an existing Exynos board. Add a new patch to the series to select GENERIC_PHY_MIPI_DPHY in Kconfig otherwise the build breaks on the 32-bit Exynos. Change vco_min variable name to min_freq Added tested-by from Chen-Yu Tsai V2: Instead of using my packet blanking calculation, this integrates on from Lucas Stach which gets modified later in the series to cache the value of the HS-clock instead of having to do the calucations again. Instead of completely eliminating the PLL clock frequency from the device tree, this makes it optional to avoid breaking some Samsung devices. When the samsung,pll-clock-frequency is not found, it reads the value of the clock named "sclk_mipi" This also maintains backwards compatibility with older device trees. This also changes the DPHY calcuation from a Look-up table, a reverse engineered algorithm which uses phy_mipi_dphy_get_default_config to determine the standard nominal values and calculates the cycles necessary to update the DPHY timings accordingly. -- 2.39.2
Re: [PATCH v9 8/8] drm/msm/dpu: tear down DSC data path when DSC disabled
Tear down DSC datapath* on encoder cleanup* On 2023-05-15 14:25:28, Kuogee Hsieh wrote: > > Unset DSC_ACTIVE bit at dpu_hw_ctl_reset_intf_cfg_v1(), > dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() functions > to tear down DSC data path if DSC data path was setup previous. > > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 43 > + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 7 + > 2 files changed, 50 insertions(+) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index 5cae70e..ee999ce 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -1214,6 +1214,44 @@ static void dpu_encoder_virt_atomic_enable(struct > drm_encoder *drm_enc, > mutex_unlock(&dpu_enc->enc_lock); > } > > +static void dpu_encoder_dsc_pipe_clr(struct dpu_encoder_virt *dpu_enc, I'd have passed hw_ctl directly. > + struct dpu_hw_dsc *hw_dsc, > + struct dpu_hw_pingpong *hw_pp) > +{ > + struct dpu_encoder_phys *cur_master = dpu_enc->cur_master; > + struct dpu_hw_ctl *ctl; > + > + ctl = cur_master->hw_ctl; > + > + if (hw_dsc->ops.dsc_disable) > + hw_dsc->ops.dsc_disable(hw_dsc); > + > + if (hw_pp->ops.disable_dsc) > + hw_pp->ops.disable_dsc(hw_pp); > + > + if (hw_dsc->ops.dsc_bind_pingpong_blk) > + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, PINGPONG_NONE); > + > + if (ctl->ops.update_pending_flush_dsc) > + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); > +} > + > +static void dpu_encoder_unprep_dsc(struct dpu_encoder_virt *dpu_enc) > +{ > + /* coding only for 2LM, 2enc, 1 dsc config */ > + struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; > + struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; > + int i; > + > + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { > + hw_pp[i] = dpu_enc->hw_pp[i]; > + hw_dsc[i] = dpu_enc->hw_dsc[i]; > + > + if (hw_pp[i] && hw_dsc[i]) > + dpu_encoder_dsc_pipe_clr(dpu_enc, hw_dsc[i], hw_pp[i]); > + } > +} Define these two functions right above dpu_encoder_helper_phys_cleanup(), or right next to dpu_encoder_prep_dsc() and dpu_encoder_dsc_pipe_cfg(), intead of splitting dpu_encoder_virt_atomic_{en,dis}able() at a random point in this file. > + > static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc, > struct drm_atomic_state *state) > { > @@ -2090,6 +2128,9 @@ void dpu_encoder_helper_phys_cleanup(struct > dpu_encoder_phys *phys_enc) > phys_enc->hw_pp->merge_3d->idx); > } > > + if (dpu_enc->dsc) > + dpu_encoder_unprep_dsc(dpu_enc); > + > intf_cfg.stream_sel = 0; /* Don't care value for video mode */ > intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); Here. > > @@ -2101,6 +2142,8 @@ void dpu_encoder_helper_phys_cleanup(struct > dpu_encoder_phys *phys_enc) > if (phys_enc->hw_pp->merge_3d) > intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; > > + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); Since this is assigned unconditionally, can you assign this right below where intf_cfg.mode_3d is assigned so that we have a static and a conditional part? > + > if (ctl->ops.reset_intf_cfg) > ctl->ops.reset_intf_cfg(ctl, &intf_cfg); > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > index f3a50cc..aec3b08 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > @@ -577,6 +577,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct > dpu_hw_ctl *ctx, > u32 intf_active = 0; > u32 wb_active = 0; > u32 merge3d_active = 0; > + u32 dsc_active; Any idea why the others are zero-assigned above for no reason (no need to clean that up in this patch)? > > /* >* This API resets each portion of the CTL path namely, > @@ -606,6 +607,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct > dpu_hw_ctl *ctx, > wb_active &= ~BIT(cfg->wb - WB_0); > DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); > } > + > + if (cfg->dsc) { > + dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); Do we really need to read it back? dpu_hw_ctl_intf_cfg_v1() doesn't read it back either and plainly writes cfg->dsc. If we always have a complete overview of what DSC's are enabled/active for this CTL (which we have), this could just be written to 0. But let's leave that now and discuss this separately, as the above does the same for merge_3d, intf and wb. - Marijn > + dsc_active &= ~cfg->dsc;
Re: [PATCH] drm/i915/guc/slpc: Disable rps_boost debugfs
On Mon, 15 May 2023 15:23:58 -0700, Belgaumkar, Vinay wrote: > > > On 5/12/2023 5:39 PM, Dixit, Ashutosh wrote: > > On Fri, 12 May 2023 16:56:03 -0700, Vinay Belgaumkar wrote: > > Hi Vinay, > > > >> rps_boost debugfs shows host turbo related info. This is not valid > >> when SLPC is enabled. > > A couple of thoughts about this. It appears people are know only about > > rps_boost_info and don't know about guc_slpc_info? So: > > > > a. Instead of hiding the rps_boost_info file do we need to print there > > saying "SLPC is enabled, go look at guc_slpc_info"? > rps_boost_info has an eval() function which disables the interface when RPS > is OFF. This is indeed the case here, so shouldn't we just follow that > instead of trying to link the two? > > > > b. Or, even just call guc_slpc_info_show from rps_boost_show (so the two > > files will show the same SLPC information)? > > slpc_info has a lot of other info like the SLPC state, not sure that > matches up with the rps_boost_info name. OK, I have asked in https://gitlab.freedesktop.org/drm/intel/-/issues/7632: @mattst88: is it acceptable to hide the /sys/kernel/debug/dri/0/i915_rps_boost_info file so that it doesn't cause confusion. And then user would have to go look at /sys/kernel/debug/dri/0/i915_guc_slpc_info or some such file when SLPC is being used? That's what the patch above is doing. Let's see what we hear from @mattst88. > > > >> guc_slpc_info already shows the number of boosts. Add num_waiters there > >> as well and disable rps_boost when SLPC is enabled. > >> > >> Bug: https://gitlab.freedesktop.org/drm/intel/-/issues/7632 > >> Signed-off-by: Vinay Belgaumkar Thanks. -- Ashutosh
Re: [PATCH v9 6/8] drm/msm/dpu: separate DSC flush update out of interface
On 2023-05-15 14:25:26, Kuogee Hsieh wrote: > > Current DSC flush update is piggyback inside dpu_hw_ctl_intf_cfg_v1(). > This patch separates DSC flush away from dpu_hw_ctl_intf_cfg_v1() by > adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per > DSC engine and DSC flush bits at same time to make it consistent with > the location of flush programming of other dpu sub blocks. > > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 -- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 -- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 ++ > 3 files changed, 38 insertions(+), 8 deletions(-) I was still reviewing v8 when this v9 ended up in my inbox already: can you retroactively read and apply it for v10? - Marijn
Re: [PATCH v9 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
On 2023-05-15 14:25:27, Kuogee Hsieh wrote: > > From: Abhinav Kumar > > Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and > feature flag information. Each display compression engine (DCE) contains > dual hard slice DSC encoders so both share same base address but with > its own different sub block address. > > changes in v4: > -- delete DPU_DSC_HW_REV_1_1 > -- re arrange sc8280xp_dsc[] > > changes in v4: > -- fix checkpatch warning > > Signed-off-by: Abhinav Kumar > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 ++ > .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 ++ > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 25 > +- > 6 files changed, 89 insertions(+), 1 deletion(-) My review for this patch came in on v8 a minute prior to this v9: can you retroactively apply it? - Marijn
Re: [PATCH v9 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On 2023-05-15 14:25:25, Kuogee Hsieh wrote: > > Add support for DSC 1.2 by providing the necessary hooks to program > the DPU DSC 1.2 encoder. > > Changes in v3: > -- fixed kernel test rebot report that "__iomem *off" is declared but not >used at dpu_hw_dsc_config_1_2() > -- unrolling thresh loops > > Changes in v4: > -- delete DPU_DSC_HW_REV_1_1 > -- delete off and used real register name directly > > Changes in v7: > -- replace offset with sblk->enc.base > -- replace ss with slice > > Changes in v8: > -- fixed checkpatch warning > > Changes in v9: > -- address Marijn review comments Right... sigh. > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/Makefile | 1 + > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 31 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 386 > + > drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- > 5 files changed, 435 insertions(+), 4 deletions(-) > create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c > > diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile > index b814fc8..b9af5e4 100644 > --- a/drivers/gpu/drm/msm/Makefile > +++ b/drivers/gpu/drm/msm/Makefile > @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ > disp/dpu1/dpu_hw_catalog.o \ > disp/dpu1/dpu_hw_ctl.o \ > disp/dpu1/dpu_hw_dsc.o \ > + disp/dpu1/dpu_hw_dsc_1_2.o \ > disp/dpu1/dpu_hw_interrupts.o \ > disp/dpu1/dpu_hw_intf.o \ > disp/dpu1/dpu_hw_lm.o \ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index 83854e8..34fe1a3 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -1,6 +1,6 @@ > /* SPDX-License-Identifier: GPL-2.0-only */ > /* > - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. > + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights > reserved. > * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. > */ > > @@ -244,12 +244,18 @@ enum { > }; > > /** > - * DSC features > + * DSC sub-blocks/features > * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets > *the pixel output from this DSC. > + * @DPU_DSC_HW_REV_1_2DSC block supports DSC 1.1 and 1.2 > + * @DPU_DSC_NATIVE_422_EN Supports NATIVE_422_EN and NATIVE_420_EN > encoding I meant to rename the enum value to DSC_NATIVE_42x_EN, not the docs, but having those as a bonus is fine. > + * @DPU_DSC_MAX > */ > enum { > DPU_DSC_OUTPUT_CTRL = 0x1, > + DPU_DSC_HW_REV_1_2, > + DPU_DSC_NATIVE_422_EN, So 42x here :) > + DPU_DSC_MAX > }; > > /** > @@ -306,6 +312,14 @@ struct dpu_pp_blk { > }; > > /** > + * struct dpu_dsc_blk - DSC Encoder sub-blk information > + * @info: HW register and features supported by this sub-blk > + */ > +struct dpu_dsc_blk { > + DPU_HW_SUBBLK_INFO; > +}; > + > +/** > * enum dpu_qos_lut_usage - define QoS LUT use cases > */ > enum dpu_qos_lut_usage { > @@ -452,6 +466,16 @@ struct dpu_pingpong_sub_blks { > }; > > /** > + * struct dpu_dsc_sub_blks - DSC sub-blks > + * @enc: DSC encoder sub-block > + * @ctl: DSC controller sub-block > + */ > +struct dpu_dsc_sub_blks { > + struct dpu_dsc_blk enc; > + struct dpu_dsc_blk ctl; > +}; > + > +/** > * dpu_clk_ctrl_type - Defines top level clock control signals > */ > enum dpu_clk_ctrl_type { > @@ -605,10 +629,13 @@ struct dpu_merge_3d_cfg { > * struct dpu_dsc_cfg - information of DSC blocks > * @id enum identifying this block > * @base register offset of this block > + * @len: length of hardware block > * @features bit mask identifying sub-blocks/features > + * @sblk: sub-blocks information > */ > struct dpu_dsc_cfg { > DPU_HW_BLK_INFO; > + const struct dpu_dsc_sub_blks *sblk; > }; > > /** > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h > index 138080a..41e39d0 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h > @@ -1,5 +1,8 @@ > /* SPDX-License-Identifier: GPL-2.0-only */ > -/* Copyright (c) 2020-2022, Linaro Limited */ > +/* > + * Copyright (c) 2020-2022, Linaro Limited > + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved > + */ > > #ifndef _DPU_HW_DSC_H > #define _DPU_HW_DSC_H > @@ -69,6 +72,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct > dpu_dsc_cfg *cfg, > void __iomem *addr); > > /** > + * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver block DSC hw driver object. (v8 review) > + * @cfg: DSC catalog entry for which driver object is required > + * @addr
Re: [PATCH v9 3/8] drm/msm/dpu: test DPU_PINGPONG_DSC bit before assign DSC ops to PINGPONG
You forgot to address the title suggestion "before assign" isn't proper English. Copying from v8 review: "Guard PINGPONG DSC ops behind DPU_PINGPONG_DSC bit" On 2023-05-15 14:25:23, Kuogee Hsieh wrote: > > DPU < 7.0.0 has DPU_PINGPONG_DSC feature bit set to indicate it requires > both dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() to be > executed to complete DSC configuration if DSC hardware block is present. > Hence test DPU_PINGPONG_DSC feature bit and assign DSC related functions > to the ops of PINGPONG block accordingly if DPU_PINGPONG_DSC bit is set. > > changes in v6: > -- split patches, this patch has function handles DPU_PINGPONG_DSC bit > > changes in v9: > -- remove un condition assign dsc related functions to pingpong ops Remember that in the DRM subsystem, these horrible changelogs are allowed as part of the commit message. I already disagree with that, and as pointed out by Dmitry this particular one is unreadable. I typically see them through as noise, but this one could use a rewrite. I won't bother suggesting the right wording yet again though. > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov For the contents: Reviewed-by: Marijn Suijten > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > index 79e4576..437d9e6 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c > @@ -291,9 +291,12 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong > *c, > c->ops.get_line_count = dpu_hw_pp_get_line_count; > c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; > } > - c->ops.setup_dsc = dpu_hw_pp_setup_dsc; > - c->ops.enable_dsc = dpu_hw_pp_dsc_enable; > - c->ops.disable_dsc = dpu_hw_pp_dsc_disable; > + > + if (test_bit(DPU_PINGPONG_DSC, &features)) { > + c->ops.setup_dsc = dpu_hw_pp_setup_dsc; > + c->ops.enable_dsc = dpu_hw_pp_dsc_enable; > + c->ops.disable_dsc = dpu_hw_pp_dsc_disable; > + } > > if (test_bit(DPU_PINGPONG_DITHER, &features)) > c->ops.setup_dither = dpu_hw_pp_setup_dither; > -- > 2.7.4 >
Re: [PATCH] drm:amd:amdgpu: Fix missing buffer object unlock in failure path
On 5/3/23 16:15, Sukrut Bellary wrote: > smatch warning - > 1) drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c:3615 gfx_v9_0_kiq_resume() > warn: inconsistent returns 'ring->mqd_obj->tbo.base.resv'. > > 2) drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c:6901 gfx_v10_0_kiq_resume() > warn: inconsistent returns 'ring->mqd_obj->tbo.base.resv'. > > Signed-off-by: Sukrut Bellary > --- > drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c | 4 +++- > drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c | 4 +++- > 2 files changed, 6 insertions(+), 2 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > index 8bd07ff59671..66d5c5d68454 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v10_0.c > @@ -6891,8 +6891,10 @@ static int gfx_v10_0_kiq_resume(struct amdgpu_device > *adev) > return r; > > r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); > - if (unlikely(r != 0)) > + if (unlikely(r != 0)) { > + amdgpu_bo_unreserve(ring->mqd_obj); > return r; > + } > > gfx_v10_0_kiq_init_queue(ring); > amdgpu_bo_kunmap(ring->mqd_obj); > diff --git a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > index bce6919d666a..d5715d8a4128 100644 > --- a/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > +++ b/drivers/gpu/drm/amd/amdgpu/gfx_v9_0.c > @@ -3617,8 +3617,10 @@ static int gfx_v9_0_kiq_resume(struct amdgpu_device > *adev) > return r; > > r = amdgpu_bo_kmap(ring->mqd_obj, (void **)&ring->mqd_ptr); > - if (unlikely(r != 0)) > + if (unlikely(r != 0)) { > + amdgpu_bo_unreserve(ring->mqd_obj); > return r; > + } > > gfx_v9_0_kiq_init_queue(ring); > amdgpu_bo_kunmap(ring->mqd_obj); Follow-up. Could you please review this patch? -- Regards, Sukrut
Re: [PATCH] drm/i915/guc/slpc: Disable rps_boost debugfs
On 5/12/2023 5:39 PM, Dixit, Ashutosh wrote: On Fri, 12 May 2023 16:56:03 -0700, Vinay Belgaumkar wrote: Hi Vinay, rps_boost debugfs shows host turbo related info. This is not valid when SLPC is enabled. A couple of thoughts about this. It appears people are know only about rps_boost_info and don't know about guc_slpc_info? So: a. Instead of hiding the rps_boost_info file do we need to print there saying "SLPC is enabled, go look at guc_slpc_info"? rps_boost_info has an eval() function which disables the interface when RPS is OFF. This is indeed the case here, so shouldn't we just follow that instead of trying to link the two? b. Or, even just call guc_slpc_info_show from rps_boost_show (so the two files will show the same SLPC information)? slpc_info has a lot of other info like the SLPC state, not sure that matches up with the rps_boost_info name. Thanks, Vinay. Ashutosh guc_slpc_info already shows the number of boosts. Add num_waiters there as well and disable rps_boost when SLPC is enabled. Bug: https://gitlab.freedesktop.org/drm/intel/-/issues/7632 Signed-off-by: Vinay Belgaumkar
Re: [PATCH v8 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
On 2023-05-15 15:03:46, Abhinav Kumar wrote: > On 5/15/2023 2:21 PM, Marijn Suijten wrote: > > On 2023-05-12 11:00:22, Kuogee Hsieh wrote: > >> > >> From: Abhinav Kumar > >> > >> Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and > >> feature flag information. Each display compression engine (DCE) contains > >> dual hard slice DSC encoders so both share same base address but with > >> its own different sub block address. > > > > Can we have an explanation of hard vs soft slices in some commit message > > and/or code documentation? > > > > Not in this one. It wont look appropriate. I would rather remove "hard" > to avoid confusion. That is totally fine, let's remove it instead. > >> + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sblk_0), > > > > Downstream says that the size is 0x10 (and 0x100 for the enc sblk, 0x10 > > for the ctl sblk). This simply fills it up to the start of the enc sblk > > so that we can see all registers in the dump? After all only > > DSC_CMN_MAIN_CNF is defined in the main register space, so 0x10 is > > adequate. > > > > .len today is always only for the dump. and yes even here we have only > 0x100 for the enc and 0x10 for the ctl. > > +static const struct dpu_dsc_sub_blks dsc_sblk_0 = { > + .enc = {.base = 0x100, .len = 0x100}, > + .ctl = {.base = 0xF00, .len = 0x10}, > +}; > > The issue here is that, the dpu snapshot does not handle sub_blk parsing > today. Its a to-do item. So for that reason, 0x100 was used here to > atleast get the full encoder dumps. But then you don't see the ENC block? It starts at 0x100 (or 0x200) so then the length should be longer... it should in fact depend on even/odd DCE then? > > >> + DSC_BLK_1_2("dce_0", DSC_1, 0x8, 0x100, 0, dsc_sblk_1), > > > > Should we add an extra suffix to the name to indicate which hard-slice > > DSC encoder it is? i.e. "dce_0_0" and "dce_0_1" etc? > > Ok, that should be fine. We can add it. Great, thanks! > >> + DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), > >> dsc_sblk_0), > >> + DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), > >> dsc_sblk_1), > > > > > See comment below about loose BIT() in features. > > Responded below. > > > >> +}; > >> + > >> static const struct dpu_intf_cfg sm8350_intf[] = { > >>INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, > >> MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, > >>DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), > >> @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { > >>.dspp = sm8350_dspp, > >>.pingpong_count = ARRAY_SIZE(sm8350_pp), > >>.pingpong = sm8350_pp, > >> + .dsc = sm8350_dsc, > >> + .dsc_count = ARRAY_SIZE(sm8350_dsc), > > > > Count goes first **everywhere else**, let's not break consistency here. > > > > the order of DSC entries is swapped for all chipsets. Please refer to > dpu_sc8180x_cfg, dpu_sm8250_cfg etc. Thanks for confirming that this is not the case in a followup mail :) > So if you are talking about consistency, this is actually consistent > with whats present in other chipsets. > > If you are very particular about this, then once this lands, you can > change the order for all of them in another change. > > Same answer for all swap comments. > >> +/* > >> + * NOTE: Each display compression engine (DCE) contains dual hard > >> + * slice DSC encoders so both share same base address but with > >> + * its own different sub block address. > >> + */ > >> +#define DSC_BLK_1_2(_name, _id, _base, _len, _features, _sblk) \ > > > > There are no address values here so this comment doesn't seem very > > useful, and it is already duplicated on every DSC block array, where the > > duplication is more visible. Drop the comment here? > > > > _base is the address. So base address. Does that clarify things? This is referring to the NOTE: comment above. There's _base as address here, yes, but there's no context here that it'll be used in duplicate fashion, unlike the SoC catalog files. The request is to just drop it here as it adds no value. > >> + {\ > >> + .name = _name, .id = _id, \ > >> + .base = _base, .len = _len, \ > > > > The len is always 0x100 (downstream says 0x10), should we hardcode it > > here and drop _len? We can always add it back if a future revision > > starts changing it, but that's not the case currently. > > > >> + .features = BIT(DPU_DSC_HW_REV_1_2) | _features, \ > > > > We don't willy-nilly append bits like that: should there be global > > feature flags? > > So this approach is actually better. This macro is a DSC_1_2 macro so it > will have the 1.2 feature flag and other features like native_422 > support of that encoder are ORed on top of it. Nothing wrong with this. I agree it is better, but we seem to be very selective in whether to stick to the "old" principles in DPU versus applying a new pattern that isn't used elsewhere yet (i.e. your request to _not_
Re: [PATCH v9 2/8] drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0
On 2023-05-15 14:25:22, Kuogee Hsieh wrote: > > DPU < 7.0.0 requires the PINGPONG block to be involved during > DSC setting up. Since DPU >= 7.0.0, enabling and starting the DSC > encoder engine was moved to INTF with the help of the flush mechanism. > Add a DPU_PINGPONG_DSC feature bit to restrict the availability of > dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() on the > PINGPONG block to DPU < 7.0.0 hardware, as the registers are not > available on DPU 7.0.0 and higher anymore. > Add DPU_PINGPONG_DSC to PINGPONG_SDM845_MASK, PINGPONG_SDM845_TE2_MASK > and PINGPONG_SM8150_MASK which is used for all DPU < 7.0 chipsets. > > changes in v6: > -- split patches and rearrange to keep catalog related files at this patch > > changes in v9: > -- delete add BIT(DPU_PINGPONG_DSC) to PINGPONG_SDM845_TE2_MASK delete add? > > changes in v7: > -- rewording commit text as suggested at review comments > > Signed-off-by: Kuogee Hsieh For the contents: Reviewed-by: Marijn Suijten But please keep the changelist in order and with proper wording, or move it below the cut (--- below) otherwise. - Marijn > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++- > 2 files changed, 5 insertions(+), 3 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 82b58c6..f2a1535 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -76,13 +76,13 @@ > (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) > > #define PINGPONG_SDM845_MASK \ > - (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE)) > + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE) | > BIT(DPU_PINGPONG_DSC)) > > #define PINGPONG_SDM845_TE2_MASK \ > (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) > > #define PINGPONG_SM8150_MASK \ > - (BIT(DPU_PINGPONG_DITHER)) > + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) > > #define CTL_SC7280_MASK \ > (BIT(DPU_CTL_ACTIVE_CFG) | \ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index 6ee48f0..83854e8 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -144,7 +144,8 @@ enum { > * @DPU_PINGPONG_TE2Additional tear check block for split pipes > * @DPU_PINGPONG_SPLIT PP block supports split fifo > * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo > - * @DPU_PINGPONG_DITHER,Dither blocks > + * @DPU_PINGPONG_DITHER Dither blocks > + * @DPU_PINGPONG_DSCPP block supports DSC > * @DPU_PINGPONG_MAX > */ > enum { > @@ -153,6 +154,7 @@ enum { > DPU_PINGPONG_SPLIT, > DPU_PINGPONG_SLAVE, > DPU_PINGPONG_DITHER, > + DPU_PINGPONG_DSC, > DPU_PINGPONG_MAX > }; > > -- > 2.7.4 >
Re: [PATCH v9 1/8] drm/msm/dpu: add dsc blocks to the catalog of MSM8998 and SC8180X
Once again, capitalize DSC in the title. On 2023-05-15 14:25:21, Kuogee Hsieh wrote: > > From: Abhinav Kumar > > There are some platforms has DSC blocks which have not been declared in There are some platforms has? How about (as suggested in earlier review): Some platforms have... > the catalog. Complete DSC 1.1 support for all platforms by adding the > missing blocks to MSM8998 and SC8180X. > > Signed-off-by: Abhinav Kumar > Reviewed-by: Dmitry Baryshkov After fixing the grammar: Reviewed-by: Marijn Suijten Thanks! > --- > drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ > drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ > 2 files changed, 18 insertions(+) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > index c0dd477..521cfd5 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h > @@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = { > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), > }; > > +static const struct dpu_dsc_cfg msm8998_dsc[] = { > + DSC_BLK("dsc_0", DSC_0, 0x8, 0), > + DSC_BLK("dsc_1", DSC_1, 0x80400, 0), > +}; > + > static const struct dpu_dspp_cfg msm8998_dspp[] = { > DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, >&msm8998_dspp_sblk), > @@ -199,6 +204,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { > .dspp = msm8998_dspp, > .pingpong_count = ARRAY_SIZE(msm8998_pp), > .pingpong = msm8998_pp, > + .dsc_count = ARRAY_SIZE(msm8998_dsc), > + .dsc = msm8998_dsc, > .intf_count = ARRAY_SIZE(msm8998_intf), > .intf = msm8998_intf, > .vbif_count = ARRAY_SIZE(msm8998_vbif), > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > index e8057a1..fec1665 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h > @@ -142,6 +142,15 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] > = { > MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200), > }; > > +static const struct dpu_dsc_cfg sc8180x_dsc[] = { > + DSC_BLK("dsc_0", DSC_0, 0x8, BIT(DPU_DSC_OUTPUT_CTRL)), > + DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)), > + DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)), > + DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)), > + DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)), > + DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)), > +}; > + > static const struct dpu_intf_cfg sc8180x_intf[] = { > INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, > MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), > @@ -206,6 +215,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { > .mixer = sc8180x_lm, > .pingpong_count = ARRAY_SIZE(sc8180x_pp), > .pingpong = sc8180x_pp, > + .dsc_count = ARRAY_SIZE(sc8180x_dsc), > + .dsc = sc8180x_dsc, > .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d), > .merge_3d = sc8180x_merge_3d, > .intf_count = ARRAY_SIZE(sc8180x_intf), > -- > 2.7.4 >
Re: [Freedreno] [PATCH v8 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
On 5/15/2023 3:03 PM, Abhinav Kumar wrote: On 5/15/2023 2:21 PM, Marijn Suijten wrote: On 2023-05-12 11:00:22, Kuogee Hsieh wrote: From: Abhinav Kumar Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and feature flag information. Each display compression engine (DCE) contains dual hard slice DSC encoders so both share same base address but with its own different sub block address. Can we have an explanation of hard vs soft slices in some commit message and/or code documentation? Not in this one. It wont look appropriate. I would rather remove "hard" to avoid confusion. changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- re arrange sc8280xp_dsc[] changes in v4: -- fix checkpatch warning Signed-off-by: Abhinav Kumar Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 ++ .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 ++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 25 +- 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 500cfd0..c4c93c8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8350_dsc[] = { + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sblk_0), Downstream says that the size is 0x10 (and 0x100 for the enc sblk, 0x10 for the ctl sblk). This simply fills it up to the start of the enc sblk so that we can see all registers in the dump? After all only DSC_CMN_MAIN_CNF is defined in the main register space, so 0x10 is adequate. .len today is always only for the dump. and yes even here we have only 0x100 for the enc and 0x10 for the ctl. +static const struct dpu_dsc_sub_blks dsc_sblk_0 = { + .enc = {.base = 0x100, .len = 0x100}, + .ctl = {.base = 0xF00, .len = 0x10}, +}; The issue here is that, the dpu snapshot does not handle sub_blk parsing today. Its a to-do item. So for that reason, 0x100 was used here to atleast get the full encoder dumps. + DSC_BLK_1_2("dce_0", DSC_1, 0x8, 0x100, 0, dsc_sblk_1), Should we add an extra suffix to the name to indicate which hard-slice DSC encoder it is? i.e. "dce_0_0" and "dce_0_1" etc? Ok, that should be fine. We can add it. + DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1), See comment below about loose BIT() in features. Responded below. +}; + static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dspp = sm8350_dspp, .pingpong_count = ARRAY_SIZE(sm8350_pp), .pingpong = sm8350_pp, + .dsc = sm8350_dsc, + .dsc_count = ARRAY_SIZE(sm8350_dsc), Count goes first **everywhere else**, let's not break consistency here. the order of DSC entries is swapped for all chipsets. Please refer to dpu_sc8180x_cfg, dpu_sm8250_cfg etc. So if you are talking about consistency, this is actually consistent with whats present in other chipsets. If you are very particular about this, then once this lands, you can change the order for all of them in another change. Same answer for all swap comments. Actually, I am wrong here, I misread the entries. Sure, I can fix this up. Please ignore this response and you can check the others. .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, .intf_count = ARRAY_SIZE(sm8350_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 5646713..42c66fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -93,6 +93,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; +/* NOTE: sc7280 only has one dsc hard slice encoder */ DSC +static const struct dpu_dsc_cfg sc7280_dsc[] = { + DSC_BLK
Re: [PATCH v10 4/8] drm/msm: Add MSM-specific DSC helper methods
On 16/05/2023 01:01, Marijn Suijten wrote: On 2023-05-15 13:29:21, Jessica Zhang wrote: Const, as requested elsewhere. But this function is not used anywhere in any of the series (because we replaced the usages with more sensible member accesses like slice_chunk_size). Acked. I would prefer to keep this helper so that we have a way to easily get BPP information from the DRM DSC config in the future, but if you'd prefer we add this helper then, I'm also ok with that. The inverse helper is available ad DSC_BPP in drm_dsc_helper.c. Perhaps we can move the two variants to the header and define them uniformly? This isn't MSM-specific it seems (i.e. the format supports fractional bpp but no RC parameters appear to be defined for such a format yet). I think DSC_BPP was removed (around v2 or v3 if I read changelog correctly). As for the fraction-point BPP, I think AMD supports .5 bpp granularity, see drivers/gpu/drm/amd/display/dc/dml/dsc/qp_tables.h -- With best wishes Dmitry
Re: [PATCH v8 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
On 5/15/2023 2:21 PM, Marijn Suijten wrote: On 2023-05-12 11:00:22, Kuogee Hsieh wrote: From: Abhinav Kumar Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and feature flag information. Each display compression engine (DCE) contains dual hard slice DSC encoders so both share same base address but with its own different sub block address. Can we have an explanation of hard vs soft slices in some commit message and/or code documentation? Not in this one. It wont look appropriate. I would rather remove "hard" to avoid confusion. changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- re arrange sc8280xp_dsc[] changes in v4: -- fix checkpatch warning Signed-off-by: Abhinav Kumar Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 ++ .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 ++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 25 +- 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 500cfd0..c4c93c8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8350_dsc[] = { + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sblk_0), Downstream says that the size is 0x10 (and 0x100 for the enc sblk, 0x10 for the ctl sblk). This simply fills it up to the start of the enc sblk so that we can see all registers in the dump? After all only DSC_CMN_MAIN_CNF is defined in the main register space, so 0x10 is adequate. .len today is always only for the dump. and yes even here we have only 0x100 for the enc and 0x10 for the ctl. +static const struct dpu_dsc_sub_blks dsc_sblk_0 = { + .enc = {.base = 0x100, .len = 0x100}, + .ctl = {.base = 0xF00, .len = 0x10}, +}; The issue here is that, the dpu snapshot does not handle sub_blk parsing today. Its a to-do item. So for that reason, 0x100 was used here to atleast get the full encoder dumps. + DSC_BLK_1_2("dce_0", DSC_1, 0x8, 0x100, 0, dsc_sblk_1), Should we add an extra suffix to the name to indicate which hard-slice DSC encoder it is? i.e. "dce_0_0" and "dce_0_1" etc? Ok, that should be fine. We can add it. + DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1), See comment below about loose BIT() in features. Responded below. +}; + static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dspp = sm8350_dspp, .pingpong_count = ARRAY_SIZE(sm8350_pp), .pingpong = sm8350_pp, + .dsc = sm8350_dsc, + .dsc_count = ARRAY_SIZE(sm8350_dsc), Count goes first **everywhere else**, let's not break consistency here. the order of DSC entries is swapped for all chipsets. Please refer to dpu_sc8180x_cfg, dpu_sm8250_cfg etc. So if you are talking about consistency, this is actually consistent with whats present in other chipsets. If you are very particular about this, then once this lands, you can change the order for all of them in another change. Same answer for all swap comments. .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, .intf_count = ARRAY_SIZE(sm8350_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 5646713..42c66fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -93,6 +93,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; +/* NOTE: sc7280 only has one dsc hard slice encoder */ DSC +static const struct dpu_dsc_cfg sc7280_dsc[] = { + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0), +}; + static const struct dpu_intf_cfg sc7280_intf
Re: [PATCH v10 4/8] drm/msm: Add MSM-specific DSC helper methods
On 2023-05-15 13:29:21, Jessica Zhang wrote: > > Const, as requested elsewhere. But this function is not used anywhere > > in any of the series (because we replaced the usages with more sensible > > member accesses like slice_chunk_size). > > Acked. > > I would prefer to keep this helper so that we have a way to easily get > BPP information from the DRM DSC config in the future, but if you'd > prefer we add this helper then, I'm also ok with that. The inverse helper is available ad DSC_BPP in drm_dsc_helper.c. Perhaps we can move the two variants to the header and define them uniformly? This isn't MSM-specific it seems (i.e. the format supports fractional bpp but no RC parameters appear to be defined for such a format yet). > >> + * @dsc: Pointer to drm dsc config struct > >> + * Returns: Integer value representing pclk per interface > >> + * > >> + * Note: This value will then be passed along to DSI and DP for some more > >> + * calculations. This is because DSI and DP divide the pclk_per_intf value > >> + * by different values depending on if widebus is enabled. > > > > Can you elaborate what this "note" is trying to tell users of this > > function? That they should not use bytes_per_line raw? That it doesn't > > actually represent bytes_per_line if the extra calculations mentioned > > here are not applied? > > The latter -- this method is used for calculating the pclk for DSI and > DP. While it does get the raw bytes_per_line, there are some extra > calculations needed before it can be set as the pclk_rate. These "extra > calculations" are different between DP and DSI. > > For more context, please refer to the earlier revisions of this patch > and the usage of the helper in dsi_host.c Note that I'm not just asking to explain it to me, but to explain it in the documentation. The function is named bytes_per_line() but then Returns: says it returns the pclk per interface, then the note says that it actually doesn't unless extra calculations are applied. We can explain the same much more concisely by rewriting Returns and dropping Note: Returns: Integer value representing bytes per line. DSI and DP need to perform further processing/calculations to turn this into pclk_per_intf, such as dividing by different values depending on if widebus is enabled. And so we have written the same, just more concisely. Feel free to reword it slightly, such as dropping the word "processing". > > Not sure that this helper is useful though: it is > > only used where msm_dsc_get_slice_per_intf() was already called, so it > > makes more sense to the reader to just multiply slice_per_intf by > > slice_chunk_size than to defer to an opaque helper. > > I would prefer to keep this as a helper as this math is common between > DP and DSI, and I believe the name of the helper accurately reflects > what is being calculated. > > If there's any confusion with the name of the method, I am open to > suggestions. The name is good, I'm just not too keen on it hiding the multiplication with msm_dsc_get_slice_per_intf() which is already also computed and available in DSI, and I assume DP too? - Marijn
Re: [PATCH v9 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
On Tue, 16 May 2023 at 00:26, Kuogee Hsieh wrote: > > From: Abhinav Kumar > > Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and > feature flag information. Each display compression engine (DCE) contains > dual hard slice DSC encoders so both share same base address but with > its own different sub block address. > > changes in v4: > -- delete DPU_DSC_HW_REV_1_1 > -- re arrange sc8280xp_dsc[] > > changes in v4: > -- fix checkpatch warning Two entries for v4? > > Signed-off-by: Abhinav Kumar > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 ++ > .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 ++ > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 25 > +- > 6 files changed, 89 insertions(+), 1 deletion(-) > -- With best wishes Dmitry
Re: [PATCH v9 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On Tue, 16 May 2023 at 00:26, Kuogee Hsieh wrote: > > Add support for DSC 1.2 by providing the necessary hooks to program > the DPU DSC 1.2 encoder. > > Changes in v3: > -- fixed kernel test rebot report that "__iomem *off" is declared but not >used at dpu_hw_dsc_config_1_2() > -- unrolling thresh loops > > Changes in v4: > -- delete DPU_DSC_HW_REV_1_1 > -- delete off and used real register name directly > > Changes in v7: > -- replace offset with sblk->enc.base > -- replace ss with slice > > Changes in v8: > -- fixed checkpatch warning > > Changes in v9: > -- address Marijn review comments Which ones? This is not a changelog entry. > > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov -- With best wishes Dmitry
Re: [PATCH v9 3/8] drm/msm/dpu: test DPU_PINGPONG_DSC bit before assign DSC ops to PINGPONG
On Tue, 16 May 2023 at 00:25, Kuogee Hsieh wrote: > > DPU < 7.0.0 has DPU_PINGPONG_DSC feature bit set to indicate it requires > both dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() to be > executed to complete DSC configuration if DSC hardware block is present. > Hence test DPU_PINGPONG_DSC feature bit and assign DSC related functions > to the ops of PINGPONG block accordingly if DPU_PINGPONG_DSC bit is set. > > changes in v6: > -- split patches, this patch has function handles DPU_PINGPONG_DSC bit > > changes in v9: > -- remove un condition assign dsc related functions to pingpong ops Huh? This is beyond my parsing skills. > > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 ++--- > 1 file changed, 6 insertions(+), 3 deletions(-) -- With best wishes Dmitry
Re: [PATCH v9 2/8] drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0
On Tue, 16 May 2023 at 00:25, Kuogee Hsieh wrote: > > DPU < 7.0.0 requires the PINGPONG block to be involved during > DSC setting up. Since DPU >= 7.0.0, enabling and starting the DSC > encoder engine was moved to INTF with the help of the flush mechanism. > Add a DPU_PINGPONG_DSC feature bit to restrict the availability of > dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() on the > PINGPONG block to DPU < 7.0.0 hardware, as the registers are not > available on DPU 7.0.0 and higher anymore. > Add DPU_PINGPONG_DSC to PINGPONG_SDM845_MASK, PINGPONG_SDM845_TE2_MASK > and PINGPONG_SM8150_MASK which is used for all DPU < 7.0 chipsets. > > changes in v6: > -- split patches and rearrange to keep catalog related files at this patch > > changes in v9: > -- delete add BIT(DPU_PINGPONG_DSC) to PINGPONG_SDM845_TE2_MASK > > changes in v7: > -- rewording commit text as suggested at review comments This is definitely not in an order. Please keep the changelogs sorted in way easy for other people to read. > > Signed-off-by: Kuogee Hsieh > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++- > 2 files changed, 5 insertions(+), 3 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 82b58c6..f2a1535 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c > @@ -76,13 +76,13 @@ > (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) > > #define PINGPONG_SDM845_MASK \ > - (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE)) > + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE) | > BIT(DPU_PINGPONG_DSC)) > > #define PINGPONG_SDM845_TE2_MASK \ > (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) > > #define PINGPONG_SM8150_MASK \ > - (BIT(DPU_PINGPONG_DITHER)) > + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) > > #define CTL_SC7280_MASK \ > (BIT(DPU_CTL_ACTIVE_CFG) | \ > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > index 6ee48f0..83854e8 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h > @@ -144,7 +144,8 @@ enum { > * @DPU_PINGPONG_TE2Additional tear check block for split pipes > * @DPU_PINGPONG_SPLIT PP block supports split fifo > * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo > - * @DPU_PINGPONG_DITHER,Dither blocks > + * @DPU_PINGPONG_DITHER Dither blocks > + * @DPU_PINGPONG_DSCPP block supports DSC > * @DPU_PINGPONG_MAX > */ > enum { > @@ -153,6 +154,7 @@ enum { > DPU_PINGPONG_SPLIT, > DPU_PINGPONG_SLAVE, > DPU_PINGPONG_DITHER, > + DPU_PINGPONG_DSC, > DPU_PINGPONG_MAX > }; > > -- > 2.7.4 > -- With best wishes Dmitry
Re: [PATCH v8 6/8] drm/msm/dpu: separate DSC flush update out of interface
On 2023-05-12 11:00:21, Kuogee Hsieh wrote: > > Current DSC flush update is piggyback inside dpu_hw_ctl_intf_cfg_v1(). Can you rewrite "is piggyback"? Something like "Currently DSC flushing happens during interface configuration". And it's intf configuration **on the CTL**, which makes this extra confusing. > This patch separates DSC flush away from dpu_hw_ctl_intf_cfg_v1() by Drop "This patch". Then, separates -> Separate > adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per > DSC engine and DSC flush bits at same time to make it consistent with Make that per-DSC with a hyphen. > the location of flush programming of other dpu sub blocks. DPU sub-blocks. > > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 -- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 -- > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 ++ > 3 files changed, 38 insertions(+), 8 deletions(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > index ffa6f04..5cae70e 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c > @@ -1834,12 +1834,18 @@ dpu_encoder_dsc_initial_line_calc(struct > drm_dsc_config *dsc, > return DIV_ROUND_UP(total_pixels, dsc->slice_width); > } > > -static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, > +static void dpu_encoder_dsc_pipe_cfg(struct dpu_encoder_virt *dpu_enc, Why not pass hw_ctl directly? The other blocks are directly passed as well, and the caller already has cur_master. Otherwise we might as well inline the for loops. Same question for the new _clr call added in patch 8/8. > + struct dpu_hw_dsc *hw_dsc, >struct dpu_hw_pingpong *hw_pp, >struct drm_dsc_config *dsc, >u32 common_mode, >u32 initial_lines) > { > + struct dpu_encoder_phys *cur_master = dpu_enc->cur_master; > + struct dpu_hw_ctl *ctl; > + > + ctl = cur_master->hw_ctl; Assign this directly at declaration, just like cur_master (but irrelevant if you pass this directly instead). > + > if (hw_dsc->ops.dsc_config) > hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines); > > @@ -1854,6 +1860,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc > *hw_dsc, > > if (hw_pp->ops.enable_dsc) > hw_pp->ops.enable_dsc(hw_pp); > + > + if (ctl->ops.update_pending_flush_dsc) > + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); > } > > static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, > @@ -1898,7 +1907,8 @@ static void dpu_encoder_prep_dsc(struct > dpu_encoder_virt *dpu_enc, > initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); > > for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) > - dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, > dsc_common_mode, initial_lines); > + dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc, > + dsc_common_mode, initial_lines); > } > > void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) > diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > index 4f7cfa9..f3a50cc 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c > @@ -139,6 +139,11 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct > dpu_hw_ctl *ctx) > CTL_DSPP_n_FLUSH(dspp - DSPP_0), > ctx->pending_dspp_flush_mask[dspp - DSPP_0]); > } > + > + if (ctx->pending_flush_mask & BIT(DSC_IDX)) > + DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, > + ctx->pending_dsc_flush_mask); When are we setting this to zero again? Same question for the other masks, only the global pending_flush_mask and pending_dspp_flush_mask are reset in dpu_hw_ctl_clear_pending_flush. > + > DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); > } > > @@ -285,6 +290,13 @@ static void > dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx, > ctx->pending_flush_mask |= BIT(MERGE_3D_IDX); > } > > +static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx, > +enum dpu_dsc dsc_num) > +{ > + ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0); > + ctx->pending_flush_mask |= BIT(DSC_IDX); > +} > + > static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, > enum dpu_dspp dspp, u32 dspp_sub_blk) > { > @@ -502,9 +514,6 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx,
Re: [PATCH] drm/amdgpu: remove unnecessary (void*) conversions
Applied. Thanks! Alex On Mon, May 15, 2023 at 3:18 AM Su Hui wrote: > > No need cast (void*) to (struct amdgpu_device *). > > Signed-off-by: Su Hui > --- > drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 4 ++-- > drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c | 2 +- > drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 2 +- > 6 files changed, 7 insertions(+), 7 deletions(-) > > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c > index f60753f97ac5..c837e0bf2cfc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c > @@ -1470,7 +1470,7 @@ int amdgpu_debugfs_regs_init(struct amdgpu_device *adev) > > static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) > { > - struct amdgpu_device *adev = (struct amdgpu_device *)m->private; > + struct amdgpu_device *adev = m->private; > struct drm_device *dev = adev_to_drm(adev); > int r = 0, i; > > @@ -1581,7 +1581,7 @@ static int amdgpu_debugfs_benchmark(void *data, u64 val) > > static int amdgpu_debugfs_vm_info_show(struct seq_file *m, void *unused) > { > - struct amdgpu_device *adev = (struct amdgpu_device *)m->private; > + struct amdgpu_device *adev = m->private; > struct drm_device *dev = adev_to_drm(adev); > struct drm_file *file; > int r; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c > index f52d0ba91a77..f0615a43b3cc 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_fence.c > @@ -835,7 +835,7 @@ static const struct dma_fence_ops amdgpu_job_fence_ops = { > #if defined(CONFIG_DEBUG_FS) > static int amdgpu_debugfs_fence_info_show(struct seq_file *m, void *unused) > { > - struct amdgpu_device *adev = (struct amdgpu_device *)m->private; > + struct amdgpu_device *adev = m->private; > int i; > > for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c > index 863cb668e000..28f79cf8c3fb 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_gem.c > @@ -948,7 +948,7 @@ int amdgpu_mode_dumb_create(struct drm_file *file_priv, > #if defined(CONFIG_DEBUG_FS) > static int amdgpu_debugfs_gem_info_show(struct seq_file *m, void *unused) > { > - struct amdgpu_device *adev = (struct amdgpu_device *)m->private; > + struct amdgpu_device *adev = m->private; > struct drm_device *dev = adev_to_drm(adev); > struct drm_file *file; > int r; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c > index 4ff348e10e4d..49a4238a120e 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ib.c > @@ -436,7 +436,7 @@ int amdgpu_ib_ring_tests(struct amdgpu_device *adev) > > static int amdgpu_debugfs_sa_info_show(struct seq_file *m, void *unused) > { > - struct amdgpu_device *adev = (struct amdgpu_device *)m->private; > + struct amdgpu_device *adev = m->private; > > seq_printf(m, "- DELAYED - > \n"); > amdgpu_sa_bo_dump_debug_info(&adev->ib_pools[AMDGPU_IB_POOL_DELAYED], > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > index 0efb38539d70..9f9274249b57 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_kms.c > @@ -1441,7 +1441,7 @@ void amdgpu_disable_vblank_kms(struct drm_crtc *crtc) > > static int amdgpu_debugfs_firmware_info_show(struct seq_file *m, void > *unused) > { > - struct amdgpu_device *adev = (struct amdgpu_device *)m->private; > + struct amdgpu_device *adev = m->private; > struct drm_amdgpu_info_firmware fw_info; > struct drm_amdgpu_query_fw query_fw; > struct atom_context *ctx = adev->mode_info.atom_context; > diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > index 2cd081cbf706..21f340ed4cca 100644 > --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c > @@ -2164,7 +2164,7 @@ int amdgpu_ttm_evict_resources(struct amdgpu_device > *adev, int mem_type) > > static int amdgpu_ttm_page_pool_show(struct seq_file *m, void *unused) > { > - struct amdgpu_device *adev = (struct amdgpu_device *)m->private; > + struct amdgpu_device *adev = m->private; > > return ttm_pool_debugfs(&adev->mman.bdev.pool, m); > } > -- > 2.30.2 >
Re: [PATCH v8 1/8] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
On 5/15/2023 2:23 PM, Marijn Suijten wrote: On 2023-05-15 13:58:35, Abhinav Kumar wrote: On 5/15/2023 1:07 PM, Marijn Suijten wrote: On 2023-05-15 11:20:02, Abhinav Kumar wrote: On 5/14/2023 2:39 PM, Marijn Suijten wrote: DSC*, and mention 1.1 explicitly (since this skips the 1.2 blocks, while the series is clearly aimed at 1.1...). This was done for the DSC 1.2 HW block patch after all. in catalog -> to catalog But it's just two platforms, you can fit MSM8998 and SC8180X in the title. On 2023-05-12 11:00:16, Kuogee Hsieh wrote: From: Abhinav Kumar There are some platforms has DSC blocks but it is not declared at catalog. Some platforms have DSC blocks which have not yet been declared in the catalog.* For completeness, this patch adds DSC blocks for platforms which missed them. Drop "this patch": Complete DSC 1.1 support for all platforms by adding the missing blocks to MSM8998 and SC8180X. Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ How about SC7180, and any other DPU 6.x revision? Will let kuogee respond to the other nits. There is no DSC in sc7180 / sm6115 / qcm2290. So this patch is complete. Thank you for checking as I didn't have the DTS close (and it seems SC7180 would have supported this, but no). I did check other SoCs in the DPU 6.x range that are currently floating in my tree and on the list, which do need their DSC 1.1 block added (both a single block at 0x81000 downstream, 0x8 upstream), if you can in a resend Konrad: DPU 6.4 in SM6350: https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-6-9837d6b35...@linaro.org/ DPU 6.9 in SM6375: https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-8-9837d6b35...@linaro.org/ If these are still on the list, can Konrad add them to his change as that way his catalog change will be complete? Otherwise I would prefer to add them in a follow up change because marking this change as dependent on a catalog change which adds a new chipset is not right. The question was for Konrad (and I addressed him by name, not you) as his series is not merged and the DSC blocks can be added to it directly without depending on this series. DSC 1.1 is after all available for some time now. Thanks for clarifying. Your reply was cut-off "if you can in a resend Konrad" so not sure what you were trying to tell. - Marijn
[PATCH v9 8/8] drm/msm/dpu: tear down DSC data path when DSC disabled
Unset DSC_ACTIVE bit at dpu_hw_ctl_reset_intf_cfg_v1(), dpu_encoder_unprep_dsc() and dpu_encoder_dsc_pipe_clr() functions to tear down DSC data path if DSC data path was setup previous. Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 43 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 7 + 2 files changed, 50 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index 5cae70e..ee999ce 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1214,6 +1214,44 @@ static void dpu_encoder_virt_atomic_enable(struct drm_encoder *drm_enc, mutex_unlock(&dpu_enc->enc_lock); } +static void dpu_encoder_dsc_pipe_clr(struct dpu_encoder_virt *dpu_enc, +struct dpu_hw_dsc *hw_dsc, +struct dpu_hw_pingpong *hw_pp) +{ + struct dpu_encoder_phys *cur_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl; + + ctl = cur_master->hw_ctl; + + if (hw_dsc->ops.dsc_disable) + hw_dsc->ops.dsc_disable(hw_dsc); + + if (hw_pp->ops.disable_dsc) + hw_pp->ops.disable_dsc(hw_pp); + + if (hw_dsc->ops.dsc_bind_pingpong_blk) + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, PINGPONG_NONE); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); +} + +static void dpu_encoder_unprep_dsc(struct dpu_encoder_virt *dpu_enc) +{ + /* coding only for 2LM, 2enc, 1 dsc config */ + struct dpu_hw_dsc *hw_dsc[MAX_CHANNELS_PER_ENC]; + struct dpu_hw_pingpong *hw_pp[MAX_CHANNELS_PER_ENC]; + int i; + + for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) { + hw_pp[i] = dpu_enc->hw_pp[i]; + hw_dsc[i] = dpu_enc->hw_dsc[i]; + + if (hw_pp[i] && hw_dsc[i]) + dpu_encoder_dsc_pipe_clr(dpu_enc, hw_dsc[i], hw_pp[i]); + } +} + static void dpu_encoder_virt_atomic_disable(struct drm_encoder *drm_enc, struct drm_atomic_state *state) { @@ -2090,6 +2128,9 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) phys_enc->hw_pp->merge_3d->idx); } + if (dpu_enc->dsc) + dpu_encoder_unprep_dsc(dpu_enc); + intf_cfg.stream_sel = 0; /* Don't care value for video mode */ intf_cfg.mode_3d = dpu_encoder_helper_get_3d_blend_mode(phys_enc); @@ -2101,6 +2142,8 @@ void dpu_encoder_helper_phys_cleanup(struct dpu_encoder_phys *phys_enc) if (phys_enc->hw_pp->merge_3d) intf_cfg.merge_3d = phys_enc->hw_pp->merge_3d->idx; + intf_cfg.dsc = dpu_encoder_helper_get_dsc(phys_enc); + if (ctl->ops.reset_intf_cfg) ctl->ops.reset_intf_cfg(ctl, &intf_cfg); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index f3a50cc..aec3b08 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -577,6 +577,7 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, u32 intf_active = 0; u32 wb_active = 0; u32 merge3d_active = 0; + u32 dsc_active; /* * This API resets each portion of the CTL path namely, @@ -606,6 +607,12 @@ static void dpu_hw_ctl_reset_intf_cfg_v1(struct dpu_hw_ctl *ctx, wb_active &= ~BIT(cfg->wb - WB_0); DPU_REG_WRITE(c, CTL_WB_ACTIVE, wb_active); } + + if (cfg->dsc) { + dsc_active = DPU_REG_READ(c, CTL_DSC_ACTIVE); + dsc_active &= ~cfg->dsc; + DPU_REG_WRITE(c, CTL_DSC_ACTIVE, dsc_active); + } } static void dpu_hw_ctl_set_fetch_pipe_active(struct dpu_hw_ctl *ctx, -- 2.7.4
[PATCH v9 4/8] drm/msm/dpu: Introduce PINGPONG_NONE to disconnect DSC from PINGPONG
Disabling the crossbar mux between DSC and PINGPONG currently requires a bogus enum dpu_pingpong value to be passed when calling dsc_bind_pingpong_blk() with enable=false, even though the register value written is independent of the current PINGPONG block. Replace that `bool enable` parameter with a new PINGPONG_NONE dpu_pingpong flag that triggers the write of the "special" 0xF "crossbar disabled" value to the register instead. Changes in v4: -- more details to commit text Changes in v5: -- rewording commit text suggested by Marijn -- add DRM_DEBUG_KMS for DSC unbinding case Changes in v8: -- fix checkpatch warning Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov Reviewed-by: Marijn Suijten --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 2 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 14 +++--- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 1 - drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h | 3 ++- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index cf1de5d..ffa6f04 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1850,7 +1850,7 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, hw_pp->ops.setup_dsc(hw_pp); if (hw_dsc->ops.dsc_bind_pingpong_blk) - hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, true, hw_pp->idx); + hw_dsc->ops.dsc_bind_pingpong_blk(hw_dsc, hw_pp->idx); if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c index 4a6bbcc..f134fb0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c @@ -157,7 +157,6 @@ static void dpu_hw_dsc_config_thresh(struct dpu_hw_dsc *hw_dsc, static void dpu_hw_dsc_bind_pingpong_blk( struct dpu_hw_dsc *hw_dsc, - bool enable, const enum dpu_pingpong pp) { struct dpu_hw_blk_reg_map *c = &hw_dsc->hw; @@ -166,14 +165,15 @@ static void dpu_hw_dsc_bind_pingpong_blk( dsc_ctl_offset = DSC_CTL(hw_dsc->idx); - if (enable) + if (pp) mux_cfg = (pp - PINGPONG_0) & 0x7; - DRM_DEBUG_KMS("%s dsc:%d %s pp:%d\n", - enable ? "Binding" : "Unbinding", - hw_dsc->idx - DSC_0, - enable ? "to" : "from", - pp - PINGPONG_0); + if (pp) + DRM_DEBUG_KMS("Binding dsc:%d to pp:%d\n", + hw_dsc->idx - DSC_0, pp - PINGPONG_0); + else + DRM_DEBUG_KMS("Unbinding dsc:%d from any pp\n", + hw_dsc->idx - DSC_0); DPU_REG_WRITE(c, dsc_ctl_offset, mux_cfg); } diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 287ec5f..138080a 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -44,7 +44,6 @@ struct dpu_hw_dsc_ops { struct drm_dsc_config *dsc); void (*dsc_bind_pingpong_blk)(struct dpu_hw_dsc *hw_dsc, - bool enable, enum dpu_pingpong pp); }; diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h index 1913a19..02a0f48 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h @@ -191,7 +191,8 @@ enum dpu_dsc { }; enum dpu_pingpong { - PINGPONG_0 = 1, + PINGPONG_NONE, + PINGPONG_0, PINGPONG_1, PINGPONG_2, PINGPONG_3, -- 2.7.4
[PATCH v9 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
Add support for DSC 1.2 by providing the necessary hooks to program the DPU DSC 1.2 encoder. Changes in v3: -- fixed kernel test rebot report that "__iomem *off" is declared but not used at dpu_hw_dsc_config_1_2() -- unrolling thresh loops Changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- delete off and used real register name directly Changes in v7: -- replace offset with sblk->enc.base -- replace ss with slice Changes in v8: -- fixed checkpatch warning Changes in v9: -- address Marijn review comments Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 31 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 386 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 5 files changed, 435 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index b814fc8..b9af5e4 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_hw_dsc_1_2.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 83854e8..34fe1a3 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. */ @@ -244,12 +244,18 @@ enum { }; /** - * DSC features + * DSC sub-blocks/features * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets *the pixel output from this DSC. + * @DPU_DSC_HW_REV_1_2DSC block supports DSC 1.1 and 1.2 + * @DPU_DSC_NATIVE_422_EN Supports NATIVE_422_EN and NATIVE_420_EN encoding + * @DPU_DSC_MAX */ enum { DPU_DSC_OUTPUT_CTRL = 0x1, + DPU_DSC_HW_REV_1_2, + DPU_DSC_NATIVE_422_EN, + DPU_DSC_MAX }; /** @@ -306,6 +312,14 @@ struct dpu_pp_blk { }; /** + * struct dpu_dsc_blk - DSC Encoder sub-blk information + * @info: HW register and features supported by this sub-blk + */ +struct dpu_dsc_blk { + DPU_HW_SUBBLK_INFO; +}; + +/** * enum dpu_qos_lut_usage - define QoS LUT use cases */ enum dpu_qos_lut_usage { @@ -452,6 +466,16 @@ struct dpu_pingpong_sub_blks { }; /** + * struct dpu_dsc_sub_blks - DSC sub-blks + * @enc: DSC encoder sub-block + * @ctl: DSC controller sub-block + */ +struct dpu_dsc_sub_blks { + struct dpu_dsc_blk enc; + struct dpu_dsc_blk ctl; +}; + +/** * dpu_clk_ctrl_type - Defines top level clock control signals */ enum dpu_clk_ctrl_type { @@ -605,10 +629,13 @@ struct dpu_merge_3d_cfg { * struct dpu_dsc_cfg - information of DSC blocks * @id enum identifying this block * @base register offset of this block + * @len: length of hardware block * @features bit mask identifying sub-blocks/features + * @sblk: sub-blocks information */ struct dpu_dsc_cfg { DPU_HW_BLK_INFO; + const struct dpu_dsc_sub_blks *sblk; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 138080a..41e39d0 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2020-2022, Linaro Limited */ +/* + * Copyright (c) 2020-2022, Linaro Limited + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ #ifndef _DPU_HW_DSC_H #define _DPU_HW_DSC_H @@ -69,6 +72,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, void __iomem *addr); /** + * dpu_hw_dsc_init_1_2() - initializes the v1.2 DSC hw driver block + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Returns: Error code or allocated dpu_hw_dsc context + */ +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct dpu_dsc_cfg *cfg, + void __iomem *addr); + +/** * dpu_hw_dsc_destroy - destroys dsc driver context * @dsc: Pointer to dsc driver context returned by dpu_hw_dsc_init */ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c new file mode 100
[PATCH v9 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
From: Abhinav Kumar Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and feature flag information. Each display compression engine (DCE) contains dual hard slice DSC encoders so both share same base address but with its own different sub block address. changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- re arrange sc8280xp_dsc[] changes in v4: -- fix checkpatch warning Signed-off-by: Abhinav Kumar Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 ++ .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 ++ .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 25 +- 6 files changed, 89 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h index 500cfd0..c4c93c8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h @@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sm8350_dsc[] = { + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0", DSC_1, 0x8, 0x100, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1), +}; + static const struct dpu_intf_cfg sm8350_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { .dspp = sm8350_dspp, .pingpong_count = ARRAY_SIZE(sm8350_pp), .pingpong = sm8350_pp, + .dsc = sm8350_dsc, + .dsc_count = ARRAY_SIZE(sm8350_dsc), .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), .merge_3d = sm8350_merge_3d, .intf_count = ARRAY_SIZE(sm8350_intf), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h index 5646713..42c66fe 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h @@ -93,6 +93,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, -1), }; +/* NOTE: sc7280 only has one dsc hard slice encoder */ +static const struct dpu_dsc_cfg sc7280_dsc[] = { + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0), +}; + static const struct dpu_intf_cfg sc7280_intf[] = { INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -149,6 +154,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { .mixer = sc7280_lm, .pingpong_count = ARRAY_SIZE(sc7280_pp), .pingpong = sc7280_pp, + .dsc_count = ARRAY_SIZE(sc7280_dsc), + .dsc = sc7280_dsc, .intf_count = ARRAY_SIZE(sc7280_intf), .intf = sc7280_intf, .vbif_count = ARRAY_SIZE(sdm845_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h index 808aacd..1901fff 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h @@ -141,6 +141,20 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), }; +/* + * NOTE: Each display compression engine (DCE) contains dual hard + * slice DSC encoders so both share same base address but with + * its own different sub block address. + */ +static const struct dpu_dsc_cfg sc8280xp_dsc[] = { + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_0", DSC_1, 0x8, 0x100, 0, dsc_sblk_1), + DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_0), + DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), dsc_sblk_1), + DSC_BLK_1_2("dce_2", DSC_4, 0x82000, 0x100, 0, dsc_sblk_0), + DSC_BLK_1_2("dce_2", DSC_5, 0x82000, 0x100, 0, dsc_sblk_1), +}; + /* TODO: INTF 3, 8 and 7 are used for MST, marked as INTF_NONE for now */ static const
[PATCH v9 3/8] drm/msm/dpu: test DPU_PINGPONG_DSC bit before assign DSC ops to PINGPONG
DPU < 7.0.0 has DPU_PINGPONG_DSC feature bit set to indicate it requires both dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() to be executed to complete DSC configuration if DSC hardware block is present. Hence test DPU_PINGPONG_DSC feature bit and assign DSC related functions to the ops of PINGPONG block accordingly if DPU_PINGPONG_DSC bit is set. changes in v6: -- split patches, this patch has function handles DPU_PINGPONG_DSC bit changes in v9: -- remove un condition assign dsc related functions to pingpong ops Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c | 9 ++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c index 79e4576..437d9e6 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c @@ -291,9 +291,12 @@ static void _setup_pingpong_ops(struct dpu_hw_pingpong *c, c->ops.get_line_count = dpu_hw_pp_get_line_count; c->ops.disable_autorefresh = dpu_hw_pp_disable_autorefresh; } - c->ops.setup_dsc = dpu_hw_pp_setup_dsc; - c->ops.enable_dsc = dpu_hw_pp_dsc_enable; - c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + + if (test_bit(DPU_PINGPONG_DSC, &features)) { + c->ops.setup_dsc = dpu_hw_pp_setup_dsc; + c->ops.enable_dsc = dpu_hw_pp_dsc_enable; + c->ops.disable_dsc = dpu_hw_pp_dsc_disable; + } if (test_bit(DPU_PINGPONG_DITHER, &features)) c->ops.setup_dither = dpu_hw_pp_setup_dither; -- 2.7.4
[PATCH v9 6/8] drm/msm/dpu: separate DSC flush update out of interface
Current DSC flush update is piggyback inside dpu_hw_ctl_intf_cfg_v1(). This patch separates DSC flush away from dpu_hw_ctl_intf_cfg_v1() by adding dpu_hw_ctl_update_pending_flush_dsc_v1() to handle both per DSC engine and DSC flush bits at same time to make it consistent with the location of flush programming of other dpu sub blocks. Signed-off-by: Kuogee Hsieh Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c | 14 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 22 -- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 ++ 3 files changed, 38 insertions(+), 8 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c index ffa6f04..5cae70e 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c @@ -1834,12 +1834,18 @@ dpu_encoder_dsc_initial_line_calc(struct drm_dsc_config *dsc, return DIV_ROUND_UP(total_pixels, dsc->slice_width); } -static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, +static void dpu_encoder_dsc_pipe_cfg(struct dpu_encoder_virt *dpu_enc, +struct dpu_hw_dsc *hw_dsc, struct dpu_hw_pingpong *hw_pp, struct drm_dsc_config *dsc, u32 common_mode, u32 initial_lines) { + struct dpu_encoder_phys *cur_master = dpu_enc->cur_master; + struct dpu_hw_ctl *ctl; + + ctl = cur_master->hw_ctl; + if (hw_dsc->ops.dsc_config) hw_dsc->ops.dsc_config(hw_dsc, dsc, common_mode, initial_lines); @@ -1854,6 +1860,9 @@ static void dpu_encoder_dsc_pipe_cfg(struct dpu_hw_dsc *hw_dsc, if (hw_pp->ops.enable_dsc) hw_pp->ops.enable_dsc(hw_pp); + + if (ctl->ops.update_pending_flush_dsc) + ctl->ops.update_pending_flush_dsc(ctl, hw_dsc->idx); } static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, @@ -1898,7 +1907,8 @@ static void dpu_encoder_prep_dsc(struct dpu_encoder_virt *dpu_enc, initial_lines = dpu_encoder_dsc_initial_line_calc(dsc, enc_ip_w); for (i = 0; i < MAX_CHANNELS_PER_ENC; i++) - dpu_encoder_dsc_pipe_cfg(hw_dsc[i], hw_pp[i], dsc, dsc_common_mode, initial_lines); + dpu_encoder_dsc_pipe_cfg(dpu_enc, hw_dsc[i], hw_pp[i], dsc, +dsc_common_mode, initial_lines); } void dpu_encoder_prepare_for_kickoff(struct drm_encoder *drm_enc) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c index 4f7cfa9..f3a50cc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c @@ -139,6 +139,11 @@ static inline void dpu_hw_ctl_trigger_flush_v1(struct dpu_hw_ctl *ctx) CTL_DSPP_n_FLUSH(dspp - DSPP_0), ctx->pending_dspp_flush_mask[dspp - DSPP_0]); } + + if (ctx->pending_flush_mask & BIT(DSC_IDX)) + DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, + ctx->pending_dsc_flush_mask); + DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, ctx->pending_flush_mask); } @@ -285,6 +290,13 @@ static void dpu_hw_ctl_update_pending_flush_merge_3d_v1(struct dpu_hw_ctl *ctx, ctx->pending_flush_mask |= BIT(MERGE_3D_IDX); } +static void dpu_hw_ctl_update_pending_flush_dsc_v1(struct dpu_hw_ctl *ctx, + enum dpu_dsc dsc_num) +{ + ctx->pending_dsc_flush_mask |= BIT(dsc_num - DSC_0); + ctx->pending_flush_mask |= BIT(DSC_IDX); +} + static void dpu_hw_ctl_update_pending_flush_dspp(struct dpu_hw_ctl *ctx, enum dpu_dspp dspp, u32 dspp_sub_blk) { @@ -502,9 +514,6 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if ((test_bit(DPU_CTL_VM_CFG, &ctx->caps->features))) mode_sel = CTL_DEFAULT_GROUP_ID << 28; - if (cfg->dsc) - DPU_REG_WRITE(&ctx->hw, CTL_DSC_FLUSH, cfg->dsc); - if (cfg->intf_mode_sel == DPU_CTL_MODE_SEL_CMD) mode_sel |= BIT(17); @@ -524,10 +533,8 @@ static void dpu_hw_ctl_intf_cfg_v1(struct dpu_hw_ctl *ctx, if (cfg->merge_3d) DPU_REG_WRITE(c, CTL_MERGE_3D_ACTIVE, BIT(cfg->merge_3d - MERGE_3D_0)); - if (cfg->dsc) { - DPU_REG_WRITE(&ctx->hw, CTL_FLUSH, DSC_IDX); + if (cfg->dsc) DPU_REG_WRITE(c, CTL_DSC_ACTIVE, cfg->dsc); - } } static void dpu_hw_ctl_intf_cfg(struct dpu_hw_ctl *ctx, @@ -630,6 +637,9 @@ static void _setup_ctl_ops(struct dpu_hw_ctl_ops *ops, ops->update_pending_flush_merge_3d = dpu_hw_ctl_update_pending_flush_merge_3d_v1; ops->update_pen
[PATCH v9 2/8] drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0
DPU < 7.0.0 requires the PINGPONG block to be involved during DSC setting up. Since DPU >= 7.0.0, enabling and starting the DSC encoder engine was moved to INTF with the help of the flush mechanism. Add a DPU_PINGPONG_DSC feature bit to restrict the availability of dpu_hw_pp_setup_dsc() and dpu_hw_pp_dsc_{enable,disable}() on the PINGPONG block to DPU < 7.0.0 hardware, as the registers are not available on DPU 7.0.0 and higher anymore. Add DPU_PINGPONG_DSC to PINGPONG_SDM845_MASK, PINGPONG_SDM845_TE2_MASK and PINGPONG_SM8150_MASK which is used for all DPU < 7.0 chipsets. changes in v6: -- split patches and rearrange to keep catalog related files at this patch changes in v9: -- delete add BIT(DPU_PINGPONG_DSC) to PINGPONG_SDM845_TE2_MASK changes in v7: -- rewording commit text as suggested at review comments Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 4 ++-- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 4 +++- 2 files changed, 5 insertions(+), 3 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 82b58c6..f2a1535 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c @@ -76,13 +76,13 @@ (BIT(DPU_DIM_LAYER) | BIT(DPU_MIXER_COMBINED_ALPHA)) #define PINGPONG_SDM845_MASK \ - (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_TE) | BIT(DPU_PINGPONG_DSC)) #define PINGPONG_SDM845_TE2_MASK \ (PINGPONG_SDM845_MASK | BIT(DPU_PINGPONG_TE2)) #define PINGPONG_SM8150_MASK \ - (BIT(DPU_PINGPONG_DITHER)) + (BIT(DPU_PINGPONG_DITHER) | BIT(DPU_PINGPONG_DSC)) #define CTL_SC7280_MASK \ (BIT(DPU_CTL_ACTIVE_CFG) | \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index 6ee48f0..83854e8 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -144,7 +144,8 @@ enum { * @DPU_PINGPONG_TE2Additional tear check block for split pipes * @DPU_PINGPONG_SPLIT PP block supports split fifo * @DPU_PINGPONG_SLAVE PP block is a suitable slave for split fifo - * @DPU_PINGPONG_DITHER,Dither blocks + * @DPU_PINGPONG_DITHER Dither blocks + * @DPU_PINGPONG_DSCPP block supports DSC * @DPU_PINGPONG_MAX */ enum { @@ -153,6 +154,7 @@ enum { DPU_PINGPONG_SPLIT, DPU_PINGPONG_SLAVE, DPU_PINGPONG_DITHER, + DPU_PINGPONG_DSC, DPU_PINGPONG_MAX }; -- 2.7.4
[PATCH v9 1/8] drm/msm/dpu: add dsc blocks to the catalog of MSM8998 and SC8180X
From: Abhinav Kumar There are some platforms has DSC blocks which have not been declared in the catalog. Complete DSC 1.1 support for all platforms by adding the missing blocks to MSM8998 and SC8180X. Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ 2 files changed, 18 insertions(+) diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h index c0dd477..521cfd5 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h @@ -126,6 +126,11 @@ static const struct dpu_pingpong_cfg msm8998_pp[] = { DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 15)), }; +static const struct dpu_dsc_cfg msm8998_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x8, 0), + DSC_BLK("dsc_1", DSC_1, 0x80400, 0), +}; + static const struct dpu_dspp_cfg msm8998_dspp[] = { DSPP_BLK("dspp_0", DSPP_0, 0x54000, DSPP_MSM8998_MASK, &msm8998_dspp_sblk), @@ -199,6 +204,8 @@ const struct dpu_mdss_cfg dpu_msm8998_cfg = { .dspp = msm8998_dspp, .pingpong_count = ARRAY_SIZE(msm8998_pp), .pingpong = msm8998_pp, + .dsc_count = ARRAY_SIZE(msm8998_dsc), + .dsc = msm8998_dsc, .intf_count = ARRAY_SIZE(msm8998_intf), .intf = msm8998_intf, .vbif_count = ARRAY_SIZE(msm8998_vbif), diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h index e8057a1..fec1665 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h @@ -142,6 +142,15 @@ static const struct dpu_merge_3d_cfg sc8180x_merge_3d[] = { MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x83200), }; +static const struct dpu_dsc_cfg sc8180x_dsc[] = { + DSC_BLK("dsc_0", DSC_0, 0x8, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_1", DSC_1, 0x80400, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_2", DSC_2, 0x80800, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_3", DSC_3, 0x80c00, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_4", DSC_4, 0x81000, BIT(DPU_DSC_OUTPUT_CTRL)), + DSC_BLK("dsc_5", DSC_5, 0x81400, BIT(DPU_DSC_OUTPUT_CTRL)), +}; + static const struct dpu_intf_cfg sc8180x_intf[] = { INTF_BLK("intf_0", INTF_0, 0x6a000, 0x280, INTF_DP, MSM_DP_CONTROLLER_0, 24, INTF_SC7180_MASK, DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), @@ -206,6 +215,8 @@ const struct dpu_mdss_cfg dpu_sc8180x_cfg = { .mixer = sc8180x_lm, .pingpong_count = ARRAY_SIZE(sc8180x_pp), .pingpong = sc8180x_pp, + .dsc_count = ARRAY_SIZE(sc8180x_dsc), + .dsc = sc8180x_dsc, .merge_3d_count = ARRAY_SIZE(sc8180x_merge_3d), .merge_3d = sc8180x_merge_3d, .intf_count = ARRAY_SIZE(sc8180x_intf), -- 2.7.4
[PATCH v9 0/8] add DSC 1.2 dpu supports
This series adds the DPU side changes to support DSC 1.2 encoder. This was validated with both DSI DSC 1.2 panel and DP DSC 1.2 monitor. The DSI and DP parts will be pushed later on top of this change. This seriel is rebase on [1], [2] and catalog fixes from rev-4 of [3]. [1]: https://patchwork.freedesktop.org/series/116851/ [2]: https://patchwork.freedesktop.org/series/116615/ [3]: https://patchwork.freedesktop.org/series/112332/ Abhinav Kumar (2): drm/msm/dpu: add dsc blocks to the catalog of MSM8998 and SC8180X drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets Kuogee Hsieh (6): drm/msm/dpu: add DPU_PINGPONG_DSC feature bit for DPU < 7.0.0 drm/msm/dpu: test DPU_PINGPONG_DSC bit before assign DSC ops to PINGPONG drm/msm/dpu: Introduce PINGPONG_NONE to disconnect DSC from PINGPONG drm/msm/dpu: add support for DSC encoder v1.2 engine drm/msm/dpu: separate DSC flush update out of interface drm/msm/dpu: tear down DSC data path when DSC disabled drivers/gpu/drm/msm/Makefile | 1 + .../drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h| 7 + .../drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h| 11 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 + .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 + .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 + drivers/gpu/drm/msm/disp/dpu1/dpu_encoder.c| 59 +++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 29 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 35 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.c | 29 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_ctl.h | 10 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.c | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 15 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 386 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_mdss.h| 3 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_pingpong.c| 9 +- drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 19 files changed, 651 insertions(+), 29 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c -- 2.7.4
Re: [PATCH v8 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
By the way, can we replace "relevant chipsets" in the title with "DPU >= 7.0" like the other titles? - Marijn On 2023-05-12 11:00:22, Kuogee Hsieh wrote:
Re: [PATCH v8 1/8] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
On 2023-05-15 13:58:35, Abhinav Kumar wrote: > > > > On 5/15/2023 1:07 PM, Marijn Suijten wrote: > > On 2023-05-15 11:20:02, Abhinav Kumar wrote: > >> > >> > >> > >> On 5/14/2023 2:39 PM, Marijn Suijten wrote: > >>> DSC*, and mention 1.1 explicitly (since this skips the 1.2 blocks, while > >>> the series is clearly aimed at 1.1...). This was done for the DSC 1.2 > >>> HW block patch after all. > >>> > >>> in catalog -> to catalog > >>> > >>> But it's just two platforms, you can fit MSM8998 and SC8180X in the > >>> title. > >>> > >>> On 2023-05-12 11:00:16, Kuogee Hsieh wrote: > > From: Abhinav Kumar > > There are some platforms has DSC blocks but it is not declared at > catalog. > >>> > >>> Some platforms have DSC blocks which have not yet been declared in the > >>> catalog.* > >>> > For completeness, this patch adds DSC blocks for platforms which missed > them. > >>> > >>> Drop "this patch": > >>> > >>> Complete DSC 1.1 support for all platforms by adding the missing > >>> blocks to MSM8998 and SC8180X. > >>> > > Signed-off-by: Abhinav Kumar > Reviewed-by: Dmitry Baryshkov > --- > drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ > drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 > +++ > >>> > >>> How about SC7180, and any other DPU 6.x revision? > >>> > >> > >> Will let kuogee respond to the other nits. There is no DSC in sc7180 / > >> sm6115 / qcm2290. So this patch is complete. > > > > Thank you for checking as I didn't have the DTS close (and it seems > > SC7180 would have supported this, but no). I did check other SoCs in > > the DPU 6.x range that are currently floating in my tree and on the > > list, which do need their DSC 1.1 block added (both a single block at > > 0x81000 downstream, 0x8 upstream), if you can in a resend Konrad: > > > > DPU 6.4 in SM6350: > > https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-6-9837d6b35...@linaro.org/ > > DPU 6.9 in SM6375: > > https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-8-9837d6b35...@linaro.org/ > > > > If these are still on the list, can Konrad add them to his change as > that way his catalog change will be complete? Otherwise I would prefer > to add them in a follow up change because marking this change as > dependent on a catalog change which adds a new chipset is not right. The question was for Konrad (and I addressed him by name, not you) as his series is not merged and the DSC blocks can be added to it directly without depending on this series. DSC 1.1 is after all available for some time now. - Marijn
Re: [PATCH v8 7/8] drm/msm/dpu: add DSC 1.2 hw blocks for relevant chipsets
On 2023-05-12 11:00:22, Kuogee Hsieh wrote: > > From: Abhinav Kumar > > Add DSC 1.2 hardware blocks to the catalog with necessary sub-block and > feature flag information. Each display compression engine (DCE) contains > dual hard slice DSC encoders so both share same base address but with > its own different sub block address. Can we have an explanation of hard vs soft slices in some commit message and/or code documentation? > > changes in v4: > -- delete DPU_DSC_HW_REV_1_1 > -- re arrange sc8280xp_dsc[] > > changes in v4: > -- fix checkpatch warning > > Signed-off-by: Abhinav Kumar > Signed-off-by: Kuogee Hsieh > Reviewed-by: Dmitry Baryshkov > --- > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h | 14 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h | 7 ++ > .../drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h | 16 ++ > .../gpu/drm/msm/disp/dpu1/catalog/dpu_8_1_sm8450.h | 14 > .../gpu/drm/msm/disp/dpu1/catalog/dpu_9_0_sm8550.h | 14 > drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.c | 25 > +- > 6 files changed, 89 insertions(+), 1 deletion(-) > > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > index 500cfd0..c4c93c8 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_0_sm8350.h > @@ -153,6 +153,18 @@ static const struct dpu_merge_3d_cfg sm8350_merge_3d[] = > { > MERGE_3D_BLK("merge_3d_2", MERGE_3D_2, 0x5), > }; > > +/* > + * NOTE: Each display compression engine (DCE) contains dual hard > + * slice DSC encoders so both share same base address but with > + * its own different sub block address. > + */ > +static const struct dpu_dsc_cfg sm8350_dsc[] = { > + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, 0, dsc_sblk_0), Downstream says that the size is 0x10 (and 0x100 for the enc sblk, 0x10 for the ctl sblk). This simply fills it up to the start of the enc sblk so that we can see all registers in the dump? After all only DSC_CMN_MAIN_CNF is defined in the main register space, so 0x10 is adequate. > + DSC_BLK_1_2("dce_0", DSC_1, 0x8, 0x100, 0, dsc_sblk_1), Should we add an extra suffix to the name to indicate which hard-slice DSC encoder it is? i.e. "dce_0_0" and "dce_0_1" etc? > + DSC_BLK_1_2("dce_1", DSC_2, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), > dsc_sblk_0), > + DSC_BLK_1_2("dce_1", DSC_3, 0x81000, 0x100, BIT(DPU_DSC_NATIVE_422_EN), > dsc_sblk_1), See comment below about loose BIT() in features. > +}; > + > static const struct dpu_intf_cfg sm8350_intf[] = { > INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, > MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), > @@ -215,6 +227,8 @@ const struct dpu_mdss_cfg dpu_sm8350_cfg = { > .dspp = sm8350_dspp, > .pingpong_count = ARRAY_SIZE(sm8350_pp), > .pingpong = sm8350_pp, > + .dsc = sm8350_dsc, > + .dsc_count = ARRAY_SIZE(sm8350_dsc), Count goes first **everywhere else**, let's not break consistency here. > .merge_3d_count = ARRAY_SIZE(sm8350_merge_3d), > .merge_3d = sm8350_merge_3d, > .intf_count = ARRAY_SIZE(sm8350_intf), > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > index 5646713..42c66fe 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_7_2_sc7280.h > @@ -93,6 +93,11 @@ static const struct dpu_pingpong_cfg sc7280_pp[] = { > PP_BLK_DITHER("pingpong_3", PINGPONG_3, 0x6c000, 0, sc7280_pp_sblk, -1, > -1), > }; > > +/* NOTE: sc7280 only has one dsc hard slice encoder */ DSC > +static const struct dpu_dsc_cfg sc7280_dsc[] = { > + DSC_BLK_1_2("dce_0", DSC_0, 0x8, 0x100, BIT(DPU_DSC_NATIVE_422_EN), > dsc_sblk_0), > +}; > + > static const struct dpu_intf_cfg sc7280_intf[] = { > INTF_BLK("intf_0", INTF_0, 0x34000, 0x280, INTF_DP, > MSM_DP_CONTROLLER_0, 24, INTF_SC7280_MASK, > DPU_IRQ_IDX(MDP_SSPP_TOP0_INTR, 24), > @@ -149,6 +154,8 @@ const struct dpu_mdss_cfg dpu_sc7280_cfg = { > .mixer = sc7280_lm, > .pingpong_count = ARRAY_SIZE(sc7280_pp), > .pingpong = sc7280_pp, > + .dsc_count = ARRAY_SIZE(sc7280_dsc), > + .dsc = sc7280_dsc, > .intf_count = ARRAY_SIZE(sc7280_intf), > .intf = sc7280_intf, > .vbif_count = ARRAY_SIZE(sdm845_vbif), > diff --git a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > index 808aacd..1901fff 100644 > --- a/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > +++ b/drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_8_0_sc8280xp.h > @@ -141,6 +141,20 @@ static const struct dpu_merge_3d_cfg sc8280xp_merge_3d[] > = { > M
Re: [PATCH v8 1/8] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
On 5/15/2023 1:07 PM, Marijn Suijten wrote: On 2023-05-15 11:20:02, Abhinav Kumar wrote: On 5/14/2023 2:39 PM, Marijn Suijten wrote: DSC*, and mention 1.1 explicitly (since this skips the 1.2 blocks, while the series is clearly aimed at 1.1...). This was done for the DSC 1.2 HW block patch after all. in catalog -> to catalog But it's just two platforms, you can fit MSM8998 and SC8180X in the title. On 2023-05-12 11:00:16, Kuogee Hsieh wrote: From: Abhinav Kumar There are some platforms has DSC blocks but it is not declared at catalog. Some platforms have DSC blocks which have not yet been declared in the catalog.* For completeness, this patch adds DSC blocks for platforms which missed them. Drop "this patch": Complete DSC 1.1 support for all platforms by adding the missing blocks to MSM8998 and SC8180X. Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ How about SC7180, and any other DPU 6.x revision? Will let kuogee respond to the other nits. There is no DSC in sc7180 / sm6115 / qcm2290. So this patch is complete. Thank you for checking as I didn't have the DTS close (and it seems SC7180 would have supported this, but no). I did check other SoCs in the DPU 6.x range that are currently floating in my tree and on the list, which do need their DSC 1.1 block added (both a single block at 0x81000 downstream, 0x8 upstream), if you can in a resend Konrad: DPU 6.4 in SM6350: https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-6-9837d6b35...@linaro.org/ DPU 6.9 in SM6375: https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-8-9837d6b35...@linaro.org/ If these are still on the list, can Konrad add them to his change as that way his catalog change will be complete? Otherwise I would prefer to add them in a follow up change because marking this change as dependent on a catalog change which adds a new chipset is not right. Thanks! - Marijn
Re: [PATCH v10 4/8] drm/msm: Add MSM-specific DSC helper methods
On 5/14/2023 2:25 PM, Marijn Suijten wrote: On 2023-05-12 14:32:14, Jessica Zhang wrote: Introduce MSM-specific DSC helper methods, as some calculations are common between DP and DSC. Signed-off-by: Jessica Zhang --- drivers/gpu/drm/msm/msm_dsc_helper.h | 65 1 file changed, 65 insertions(+) diff --git a/drivers/gpu/drm/msm/msm_dsc_helper.h b/drivers/gpu/drm/msm/msm_dsc_helper.h new file mode 100644 index ..0d2a097b428d --- /dev/null +++ b/drivers/gpu/drm/msm/msm_dsc_helper.h @@ -0,0 +1,65 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ + +#ifndef MSM_DSC_HELPER_H_ +#define MSM_DSC_HELPER_H_ + +#include +#include +#include + +/* + * Helper methods for MSM specific DSC calculations that are common between timing engine, + * DSI, and DP. + */ Isn't this more common to have directly below the copyright statement, above the includes? Hi Marijn, Acked. + +/** + * msm_dsc_get_bpp_int() - get bits per pixel integer value + * @dsc: Pointer to drm dsc config struct + * Returns: BPP integer value + */ +static inline int msm_dsc_get_bpp_int(struct drm_dsc_config *dsc) Const, as requested elsewhere. But this function is not used anywhere in any of the series (because we replaced the usages with more sensible member accesses like slice_chunk_size). Acked. I would prefer to keep this helper so that we have a way to easily get BPP information from the DRM DSC config in the future, but if you'd prefer we add this helper then, I'm also ok with that. +{ + WARN_ON_ONCE(dsc->bits_per_pixel & 0xf); + return dsc->bits_per_pixel >> 4; +} + +/** + * msm_dsc_get_slice_per_intf() - get number of slices per interface + * @dsc: Pointer to drm dsc config struct + * @intf_width: interface width Width of the interface (to query), *in pixels* Acked. + * Returns: Integer representing the slice per interface the *number of slices* per interface. Also, the returned value applies specifically to *the given interface* (width). Acked. + */ +static inline int msm_dsc_get_slice_per_intf(struct drm_dsc_config *dsc, int intf_width) Const pointer. Also: sliceS_per_intf? It's pluiral in the docs too. Should the argument and return value be u32, to match the uses? Same for everything below. Acked. +{ + return DIV_ROUND_UP(intf_width, dsc->slice_width); +} + +/** + * msm_dsc_get_bytes_per_line() - Calculate bytes per line Calculate -> (lowecase) get (to match all the other helpers in this file) Acked. + * @dsc: Pointer to drm dsc config struct + * Returns: Integer value representing pclk per interface + * + * Note: This value will then be passed along to DSI and DP for some more + * calculations. This is because DSI and DP divide the pclk_per_intf value + * by different values depending on if widebus is enabled. Can you elaborate what this "note" is trying to tell users of this function? That they should not use bytes_per_line raw? That it doesn't actually represent bytes_per_line if the extra calculations mentioned here are not applied? The latter -- this method is used for calculating the pclk for DSI and DP. While it does get the raw bytes_per_line, there are some extra calculations needed before it can be set as the pclk_rate. These "extra calculations" are different between DP and DSI. For more context, please refer to the earlier revisions of this patch and the usage of the helper in dsi_host.c + */ +static inline int msm_dsc_get_bytes_per_line(struct drm_dsc_config *dsc) const, return u32. Acked. +{ + return dsc->slice_count * dsc->slice_chunk_size; This is a u8 times a u16. Could it overflow a u16 and should we hence cast one of the expressions to u32 first? Acked. +} + +/** + * msm_dsc_get_bytes_per_intf() - get total bytes per interface + * @dsc: Pointer to drm dsc config struct + * @intf_width: interface width + * Returns: u32 value representing bytes per interface Nit: no need to repeat the type, I think? Just "number of bytes per interface" is more concise. Acked. + */ +static inline u32 msm_dsc_get_bytes_per_intf(struct drm_dsc_config *dsc, int intf_width) And one more const. Acked. Not sure that this helper is useful though: it is only used where msm_dsc_get_slice_per_intf() was already called, so it makes more sense to the reader to just multiply slice_per_intf by slice_chunk_size than to defer to an opaque helper. I would prefer to keep this as a helper as this math is common between DP and DSI, and I believe the name of the helper accurately reflects what is being calculated. If there's any confusion with the name of the method, I am open to suggestions. Thanks, Jessica Zhang - Marijn +{ + return dsc->slice_chunk_size * msm_dsc_get_slice_per_intf(dsc, intf_width); +} + +#endif /* MSM_DSC_HELPER_H_ */ -- 2.40.1
Re: [PATCH v8 2/2] drm/i915: Allow user to set cache at BO creation
> Hi Fei, > > On Fri, May 12, 2023 at 04:28:25PM -0700, fei.y...@intel.com wrote: >> From: Fei Yang >> >> To comply with the design that buffer objects shall have immutable >> cache setting through out their life cycle, {set, get}_caching ioctl's >> are no longer supported from MTL onward. With that change caching >> policy can only be set at object creation time. The current code >> applies a default (platform dependent) cache setting for all objects. >> However this is not optimal for performance tuning. The patch extends >> the existing gem_create uAPI to let user set PAT index for the object >> at creation time. >> The new extension is platform independent, so UMD's can switch to using >> this extension for older platforms as well, while {set, get}_caching are >> still supported on these legacy paltforms for compatibility reason. >> >> IGT posted at https://patchwork.freedesktop.org/series/117695/ > > Test gem_create@create-ext-set-pat > >> Tested with https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/22878 >> >> Tested-by: Jordan Justen > > we need here an explicit ack to have the paper work in place. So > that I still have to ask Jordan and Mesa folks to give an ack if > things look right. Will update once an a-b is in place. > Thanks! > Andi > >> Cc: Chris Wilson >> Cc: Matt Roper >> Cc: Andi Shyti >> Signed-off-by: Fei Yang >> Reviewed-by: Andi Shyti > >PS: > > nitnitnitpick: the tags need to come in chronological order. So > that: > > - first you wrote it (Sob: Fei...) > - then you sent it (Cc: ...) > - then it has been reviewd (R-b) > - finally tested (T-b) > > I see that many people put the "Cc:" before the "Sob:" and I > consider it a matter of taste (which might mean "I first prepare > the mail (Cc:) and then I send it (Sob:)"). > > But... don't mind too much at these things. > >Andi
Re: [PATCH v8 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On 2023-05-15 10:06:33, Kuogee Hsieh wrote: > >> +static inline int _dsc_calc_ob_max_addr(struct dpu_hw_dsc *hw_dsc, int > >> num_ss) > > Can you write out "ob" fully? > > > > These don't need to be marked "inline", same below. Please add newlines around your reply, like I did here, to make it easier to spot them in the context. As asked in another thread, shorten the original message around it if it's not relevant for your reply message (see bits). > are you means all functions in this file doe snot to be marked as inline? https://www.kernel.org/doc/local/inline.html In general, inline is fine for math functions that are small and useful to be inlined (and functions in headers that get compiled multiple times but need to be deduplicated when all the objects are linked together). It has no sensible meaning on callback functions (of which their pointer get assigned to a struct member), however. In DPU1 for example, only dpu_hw_ctl.c erroneously does this for callbacks (and this patch, but I presume you'll fix this up in v9). > >> +{ > >> + int max_addr = 2400 / num_ss; > > ss -> slice (or subslice), right? > ... > slice (softslice) Thanks if you can fix this up in v9! - Marijn
Re: [PATCH v8 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On 2023-05-15 10:46:48, Kuogee Hsieh wrote: > > Friendly request to strip/snip unneeded context (as done in this reply) > > to make it easier to spot the conversation, and replies to it. > > > > - Marijn > > Thanks for suggestion. > > How can I do that? > > just manually delete unneeded context? > > Or are they other way (tricks) to do it automatically? Fortunately, no: it is up to you to decide what context is relevant, which is typically the text (and/or diff snippets) you are replying to. - Marijn
Re: [PATCH v8 1/8] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
On 2023-05-15 11:20:02, Abhinav Kumar wrote: > > > > On 5/14/2023 2:39 PM, Marijn Suijten wrote: > > DSC*, and mention 1.1 explicitly (since this skips the 1.2 blocks, while > > the series is clearly aimed at 1.1...). This was done for the DSC 1.2 > > HW block patch after all. > > > > in catalog -> to catalog > > > > But it's just two platforms, you can fit MSM8998 and SC8180X in the > > title. > > > > On 2023-05-12 11:00:16, Kuogee Hsieh wrote: > >> > >> From: Abhinav Kumar > >> > >> There are some platforms has DSC blocks but it is not declared at catalog. > > > > Some platforms have DSC blocks which have not yet been declared in the > > catalog.* > > > >> For completeness, this patch adds DSC blocks for platforms which missed > >> them. > > > > Drop "this patch": > > > > Complete DSC 1.1 support for all platforms by adding the missing > > blocks to MSM8998 and SC8180X. > > > >> > >> Signed-off-by: Abhinav Kumar > >> Reviewed-by: Dmitry Baryshkov > >> --- > >> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ > >> drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ > > > > How about SC7180, and any other DPU 6.x revision? > > > > Will let kuogee respond to the other nits. There is no DSC in sc7180 / > sm6115 / qcm2290. So this patch is complete. Thank you for checking as I didn't have the DTS close (and it seems SC7180 would have supported this, but no). I did check other SoCs in the DPU 6.x range that are currently floating in my tree and on the list, which do need their DSC 1.1 block added (both a single block at 0x81000 downstream, 0x8 upstream), if you can in a resend Konrad: DPU 6.4 in SM6350: https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-6-9837d6b35...@linaro.org/ DPU 6.9 in SM6375: https://lore.kernel.org/linux-arm-msm/20230411-topic-straitlagoon_mdss-v3-8-9837d6b35...@linaro.org/ Thanks! - Marijn
RE: [PATCH v2 RESEND 4/7] swiotlb: Dynamically allocated bounce buffers
From: Petr Tesarik Sent: Tuesday, May 9, 2023 2:18 AM > > The software IO TLB was designed with the assumption that it is not > used much, especially on 64-bit systems, so a small fixed memory > area (currently 64 MiB) is sufficient to handle the few cases which > still require a bounce buffer. However, these cases are not so rare > in some circumstances. > > First, if SEV is active, all DMA must be done through shared > unencrypted pages, and SWIOTLB is used to make this happen without > changing device drivers. The software IO TLB size is increased to 6% > of total memory in sev_setup_arch(), but that is more of an > approximation. The actual requirements may vary depending on which > drivers are used and the amount of I/O. FWIW, I don't think the approach you have implemented here will be practical to use for CoCo VMs (SEV, TDX, whatever else). The problem is that dma_direct_alloc_pages() and dma_direct_free_pages() must call dma_set_decrypted() and dma_set_encrypted(), respectively. In CoCo VMs, these calls are expensive because they require a hypercall to the host, and the operation on the host isn't trivial either. I haven't measured the overhead, but doing a hypercall on every DMA map operation and on every unmap operation has long been something we thought we must avoid. The fixed swiotlb bounce buffer space solves this problem by doing set_decrypted() in batch at boot time, and never doing set_encrypted(). In Microsoft's first implementation of bounce buffering for SEV-SNP VMs, we created custom bounce buffer code separate from swiotlb. This code did similar what you've done, but maintained a per-device pool of allocated buffers that could be reused, rather than freeing the memory (and marking the memory encrypted again) on every DMA unmap operation. (The pool was actually per-VMBus channel, but VMBus channels are per-device, so the effect was the same.) The reusable pool avoided most of the calls to set_decrypted()/set_encrypted() and made it practical from a performance standpoint. But of course, the pool could grow arbitrarily large, so there was additional complexity to decay and trim the pool size. LKML feedback early on was to use swiotlb instead, which made sense, but at the cost of needing to figure out the appropriate fixed size of the swiotlb, and likely over-provisioning to avoid running out of bounce buffer space. Now we're considering again a more dynamic approach, which is good, but we're encountering the same problems. See https://lore.kernel.org/linux-hyperv/20210228150315.2552437-1-ltyker...@gmail.com/ for this historical example. Michael > > Second, some embedded devices have very little RAM, so 64 MiB is not > negligible. Sadly, these are exactly the devices that also often > need a software IO TLB. Although minimum swiotlb size can be found > empirically by extensive testing, it would be easier to allocate a > small swiotlb at boot and let it grow on demand. > > Growing the SWIOTLB data structures at run time is impossible. The > whole SWIOTLB region is contiguous in physical memory to allow > combining adjacent slots and also to ensure that alignment > constraints can be met. The SWIOTLB is too big for the buddy > allocator (cf. MAX_ORDER). More importantly, even if a new SWIOTLB > could be allocated (e.g. from CMA), it cannot be extended in-place > (because surrounding pages may be already allocated for other > purposes), and there is no mechanism for relocating already mapped > bounce buffers: The DMA API gets only the address of a buffer, and > the implementation (direct or IOMMU) checks whether it belongs to > the software IO TLB. > > It is possible to allocate multiple smaller struct io_tlb_mem > instances. However, they would have to be stored in a non-constant > container (list or tree), which needs synchronization between > readers and writers, creating contention in a hot path for all > devices, not only those which need software IO TLB. > > Another option is to allocate a very large SWIOTLB at boot, but > allow migrating pages to other users (like CMA does). This approach > might work, but there are many open issues: > > 1. After a page is migrated away from SWIOTLB, it must not be used >as a (direct) DMA buffer. Otherwise SWIOTLB code would have to >check which pages have been migrated to determine whether a given >buffer address belongs to a bounce buffer or not, effectively >introducing all the issues of multiple SWIOTLB instances. > > 2. Unlike SWIOTLB, CMA cannot be used from atomic contexts, and that >for many different reasons. This might be changed in theory, but >it would take a lot of investigation and time. OTOH improvement >to the SWIOTLB is needed now. > > 3. If SWIOTLB is implemented separately from CMA and not as its >part, users have to solve the dilemma of how to distribute >precious DMA-able memory between them. > > The present patch is a simplistic solution. Bounce buffers are > alloca
Re: [RFC PATCH v2 02/13] drm/msm/dpu: take plane rotation into account for wide planes
On 5/15/2023 12:12 PM, Dmitry Baryshkov wrote: On Mon, 15 May 2023 at 21:45, Abhinav Kumar wrote: On 5/14/2023 10:01 AM, Dmitry Baryshkov wrote: On Sat, 13 May 2023 at 01:12, Abhinav Kumar wrote: On 3/20/2023 6:18 PM, Dmitry Baryshkov wrote: Take into account the plane rotation and flipping when calculating src positions for the wide plane parts. Signed-off-by: Dmitry Baryshkov Do we need to have a fixes tag for this? This means we dont consider rotation while calculating src position today which is a bug? Hmm, I thought that I had a check forbidding rotation with the current approach, but I don't see it. Most probably I thought about it and then forgot to add it. The proper fix should be to disallow it for static SSPP case. I'll include the patch into v3. --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 27 ++- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 2e63eb0a2f3f..d43e04fc4578 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -887,16 +887,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - pipe_cfg->src_rect = new_plane_state->src; - - /* state->src is 16.16, src_rect is not */ - pipe_cfg->src_rect.x1 >>= 16; - pipe_cfg->src_rect.x2 >>= 16; - pipe_cfg->src_rect.y1 >>= 16; - pipe_cfg->src_rect.y2 >>= 16; - - pipe_cfg->dst_rect = new_plane_state->dst; - fb_rect.x2 = new_plane_state->fb->width; fb_rect.y2 = new_plane_state->fb->height; @@ -912,6 +902,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, max_linewidth = pdpu->catalog->caps->max_linewidth; + /* state->src is 16.16, src_rect is not */ + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); + + pipe_cfg->dst_rect = new_plane_state->dst; + + drm_rect_rotate(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { /* * In parallel multirect case only the half of the usual width @@ -959,6 +958,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; } + drm_rect_rotate_inv(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if (r_pipe->sspp) Dont you need to check for if (r_pipe_cfg) here and not if (r_pipe->sspp) because parameter you are passing is the r_pipe_cfg to drm_rect_rotate_inv(). Of course not. r_pipe_cfg is a pointer to the field in pstate. We know that it can not be NULL. Ack, and my bad for not checking that r_pipe_cfg points to a field in pstate but it was just weird though that you are checking for r_pipe->sspp before calling a method which really doesnt care if its null or not. How about you use drm_rect_visible(r_pipe_cfg->src_rect) If its not set, it wont be visible too. I think it is better for the uniformity to check for r_pipe->sspp: this is the condition that is used all over the driver to check that r_pipe is used. hmmm okay not entirely convinced this was the right way to begin with then because some places do need a valid sspp for the function getting called so thats fine but some do not. its incorrect uniformity, but I am not going to complain about it now. will think of cleaning it up once this lands. So we rotated the pipe_cfg once, then rotated_inv it to restore the rectangle to its original state, but r_pipe_cfg's rectangle was never rotated as it was not allocated before this function so it will remain in inverse rotated state now right? No. r_pipe_cfg is set beforehand to the half of the rotated pipe_cfg. Ok i got it now. Instead of directly operating on the plane_state's rectangle which makes you to invert again why not just use a temporary drm_rect which stores the rotated pipe_cfg->src_rect. That way you dont have to invert anything? I don't think this will work. I explicitly rotate & invert rotation to get correct coordinates for both source and destination rectangles. Doing it otherwise would require us to manually implement this in the DPU driver. Ok got it, i guess this will need more changes within the if (src_width > max_width) this is fine then. Will ack this once i finish reviews on the others. + drm_rect_rotate_inv(&r_pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt); if (ret)
Re: [RFC PATCH v2 02/13] drm/msm/dpu: take plane rotation into account for wide planes
On Mon, 15 May 2023 at 21:45, Abhinav Kumar wrote: > > > > On 5/14/2023 10:01 AM, Dmitry Baryshkov wrote: > > On Sat, 13 May 2023 at 01:12, Abhinav Kumar > > wrote: > >> > >> > >> > >> On 3/20/2023 6:18 PM, Dmitry Baryshkov wrote: > >>> Take into account the plane rotation and flipping when calculating src > >>> positions for the wide plane parts. > >>> > >>> Signed-off-by: Dmitry Baryshkov > >> > >> Do we need to have a fixes tag for this? This means we dont consider > >> rotation while calculating src position today which is a bug? > > > > Hmm, I thought that I had a check forbidding rotation with the current > > approach, but I don't see it. Most probably I thought about it and > > then forgot to add it. > > The proper fix should be to disallow it for static SSPP case. I'll > > include the patch into v3. > > > >> > >>> --- > >>>drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 27 ++- > >>>1 file changed, 17 insertions(+), 10 deletions(-) > >>> > >>> diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > >>> b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > >>> index 2e63eb0a2f3f..d43e04fc4578 100644 > >>> --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > >>> +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c > >>> @@ -887,16 +887,6 @@ static int dpu_plane_atomic_check(struct drm_plane > >>> *plane, > >>>return -EINVAL; > >>>} > >>> > >>> - pipe_cfg->src_rect = new_plane_state->src; > >>> - > >>> - /* state->src is 16.16, src_rect is not */ > >>> - pipe_cfg->src_rect.x1 >>= 16; > >>> - pipe_cfg->src_rect.x2 >>= 16; > >>> - pipe_cfg->src_rect.y1 >>= 16; > >>> - pipe_cfg->src_rect.y2 >>= 16; > >>> - > >>> - pipe_cfg->dst_rect = new_plane_state->dst; > >>> - > >>>fb_rect.x2 = new_plane_state->fb->width; > >>>fb_rect.y2 = new_plane_state->fb->height; > >>> > >>> @@ -912,6 +902,15 @@ static int dpu_plane_atomic_check(struct drm_plane > >>> *plane, > >>> > >>>max_linewidth = pdpu->catalog->caps->max_linewidth; > >>> > >>> + /* state->src is 16.16, src_rect is not */ > >>> + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); > >>> + > >>> + pipe_cfg->dst_rect = new_plane_state->dst; > >>> + > >>> + drm_rect_rotate(&pipe_cfg->src_rect, > >>> + new_plane_state->fb->width, > >>> new_plane_state->fb->height, > >>> + new_plane_state->rotation); > >>> + > >>>if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { > >>>/* > >>> * In parallel multirect case only the half of the usual > >>> width > >>> @@ -959,6 +958,14 @@ static int dpu_plane_atomic_check(struct drm_plane > >>> *plane, > >>>r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; > >>>} > >>> > >>> + drm_rect_rotate_inv(&pipe_cfg->src_rect, > >>> + new_plane_state->fb->width, > >>> new_plane_state->fb->height, > >>> + new_plane_state->rotation); > >>> + if (r_pipe->sspp) > >> > >> Dont you need to check for if (r_pipe_cfg) here and not if > >> (r_pipe->sspp) because parameter you are passing is the r_pipe_cfg to > >> drm_rect_rotate_inv(). > > > > Of course not. r_pipe_cfg is a pointer to the field in pstate. We know > > that it can not be NULL. > > > > Ack, and my bad for not checking that r_pipe_cfg points to a field in > pstate but it was just weird though that you are checking for > r_pipe->sspp before calling a method which really doesnt care if its > null or not. How about you use drm_rect_visible(r_pipe_cfg->src_rect) > > If its not set, it wont be visible too. I think it is better for the uniformity to check for r_pipe->sspp: this is the condition that is used all over the driver to check that r_pipe is used. > > >> > >> So we rotated the pipe_cfg once, then rotated_inv it to restore the > >> rectangle to its original state, but r_pipe_cfg's rectangle was never > >> rotated as it was not allocated before this function so it will remain > >> in inverse rotated state now right? > > > > No. r_pipe_cfg is set beforehand to the half of the rotated pipe_cfg. > > > > Ok i got it now. Instead of directly operating on the plane_state's > rectangle which makes you to invert again why not just use a temporary > drm_rect which stores the rotated pipe_cfg->src_rect. That way you dont > have to invert anything? I don't think this will work. I explicitly rotate & invert rotation to get correct coordinates for both source and destination rectangles. Doing it otherwise would require us to manually implement this in the DPU driver. > > >>> + drm_rect_rotate_inv(&r_pipe_cfg->src_rect, > >>> + new_plane_state->fb->width, > >>> new_plane_state->fb->height, > >>> + new_plane_state->rotation); > >>> + > >>>ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt); > >>>if (ret) > >
Re: [PATCH v5 1/6] mm/gup: remove unused vmas parameter from get_user_pages()
On Sun, May 14, 2023, Lorenzo Stoakes wrote: > No invocation of get_user_pages() use the vmas parameter, so remove it. > > The GUP API is confusing and caveated. Recent changes have done much to > improve that, however there is more we can do. Exporting vmas is a prime > target as the caller has to be extremely careful to preclude their use > after the mmap_lock has expired or otherwise be left with dangling > pointers. > > Removing the vmas parameter focuses the GUP functions upon their primary > purpose - pinning (and outputting) pages as well as performing the actions > implied by the input flags. > > This is part of a patch series aiming to remove the vmas parameter > altogether. > > Suggested-by: Matthew Wilcox (Oracle) > Acked-by: Greg Kroah-Hartman > Acked-by: David Hildenbrand > Reviewed-by: Jason Gunthorpe > Acked-by: Christian K�nig (for radeon parts) > Acked-by: Jarkko Sakkinen > Signed-off-by: Lorenzo Stoakes > --- > arch/x86/kernel/cpu/sgx/ioctl.c | 2 +- > drivers/gpu/drm/radeon/radeon_ttm.c | 2 +- > drivers/misc/sgi-gru/grufault.c | 2 +- > include/linux/mm.h | 3 +-- > mm/gup.c| 9 +++-- > mm/gup_test.c | 5 ++--- > virt/kvm/kvm_main.c | 2 +- > 7 files changed, 10 insertions(+), 15 deletions(-) Acked-by: Sean Christopherson (KVM) > diff --git a/virt/kvm/kvm_main.c b/virt/kvm/kvm_main.c > index cb5c13eee193..eaa5bb8dbadc 100644 > --- a/virt/kvm/kvm_main.c > +++ b/virt/kvm/kvm_main.c > @@ -2477,7 +2477,7 @@ static inline int check_user_page_hwpoison(unsigned > long addr) > { > int rc, flags = FOLL_HWPOISON | FOLL_WRITE; > > - rc = get_user_pages(addr, 1, flags, NULL, NULL); > + rc = get_user_pages(addr, 1, flags, NULL); > return rc == -EHWPOISON; Unrelated to this patch, I think there's a pre-existing bug here. If gup() returns a valid page, KVM will leak the refcount and unintentionally pin the page. That's highly unlikely as check_user_page_hwpoison() is called iff get_user_pages_unlocked() fails (called by hva_to_pfn_slow()), but it's theoretically possible that userspace could change the VMAs between hva_to_pfn_slow() and check_user_page_hwpoison() since KVM doesn't hold any relevant locks at this point. E.g. if there's no VMA during hva_to_pfn_{fast,slow}(), npages==-EFAULT and KVM will invoke check_user_page_hwpoison(). If userspace installs a valid mapping after hva_to_pfn_slow() but before KVM acquires mmap_lock, then gup() will find a valid page. I _think_ the fix is to simply delete this code. The bug was introduced by commit fafc3dbaac64 ("KVM: Replace is_hwpoison_address with __get_user_pages"). At that time, KVM didn't check for "npages == -EHWPOISON" from the first call to get_user_pages_unlocked(). Later on, commit 0857b9e95c1a ("KVM: Enable async page fault processing") reworked the caller to be: mmap_read_lock(current->mm); if (npages == -EHWPOISON || (!async && check_user_page_hwpoison(addr))) { pfn = KVM_PFN_ERR_HWPOISON; goto exit; } where async really means NOWAIT, so that the hwpoison use of gup() didn't sleep. KVM: Enable async page fault processing If asynchronous hva_to_pfn() is requested call GUP with FOLL_NOWAIT to avoid sleeping on IO. Check for hwpoison is done at the same time, otherwise check_user_page_hwpoison() will call GUP again and will put vcpu to sleep. There are other potential problems too, e.g. the hwpoison call doesn't honor the recently introduced @interruptible flag. I don't see any reason to keep check_user_page_hwpoison(), KVM can simply rely on the "npages == -EHWPOISON" check. get_user_pages_unlocked() is guaranteed to be called with roughly equivalent flags, and the flags that aren't equivalent are arguably bugs in check_user_page_hwpoison(), e.g. assuming FOLL_WRITE is wrong. TL;DR: Go ahead with this change, I'll submit a separate patch to delete the buggy KVM code.
[PATCH] drm: panel-orientation-quirks: Change Air's quirk to support Air Plus
It turned out that Aya Neo Air Plus had a different board name than expected. This patch changes Aya Neo Air's quirk to account for that, as both devices share "Air" in DMI product name. Tested on Air claiming to be an Air Pro, and on Air Plus. Signed-off-by: Maya Matuszczyk --- drivers/gpu/drm/drm_panel_orientation_quirks.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/drm_panel_orientation_quirks.c b/drivers/gpu/drm/drm_panel_orientation_quirks.c index b1a38e6ce2f8..0cb646cb04ee 100644 --- a/drivers/gpu/drm/drm_panel_orientation_quirks.c +++ b/drivers/gpu/drm/drm_panel_orientation_quirks.c @@ -179,7 +179,7 @@ static const struct dmi_system_id orientation_data[] = { }, {/* AYA NEO AIR */ .matches = { DMI_EXACT_MATCH(DMI_SYS_VENDOR, "AYANEO"), - DMI_MATCH(DMI_BOARD_NAME, "AIR"), + DMI_MATCH(DMI_PRODUCT_NAME, "AIR"), }, .driver_data = (void *)&lcd1080x1920_leftside_up, }, {/* AYA NEO NEXT */ -- 2.40.1
Re: [RFC PATCH v2 02/13] drm/msm/dpu: take plane rotation into account for wide planes
On 5/14/2023 10:01 AM, Dmitry Baryshkov wrote: On Sat, 13 May 2023 at 01:12, Abhinav Kumar wrote: On 3/20/2023 6:18 PM, Dmitry Baryshkov wrote: Take into account the plane rotation and flipping when calculating src positions for the wide plane parts. Signed-off-by: Dmitry Baryshkov Do we need to have a fixes tag for this? This means we dont consider rotation while calculating src position today which is a bug? Hmm, I thought that I had a check forbidding rotation with the current approach, but I don't see it. Most probably I thought about it and then forgot to add it. The proper fix should be to disallow it for static SSPP case. I'll include the patch into v3. --- drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c | 27 ++- 1 file changed, 17 insertions(+), 10 deletions(-) diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c index 2e63eb0a2f3f..d43e04fc4578 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_plane.c @@ -887,16 +887,6 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, return -EINVAL; } - pipe_cfg->src_rect = new_plane_state->src; - - /* state->src is 16.16, src_rect is not */ - pipe_cfg->src_rect.x1 >>= 16; - pipe_cfg->src_rect.x2 >>= 16; - pipe_cfg->src_rect.y1 >>= 16; - pipe_cfg->src_rect.y2 >>= 16; - - pipe_cfg->dst_rect = new_plane_state->dst; - fb_rect.x2 = new_plane_state->fb->width; fb_rect.y2 = new_plane_state->fb->height; @@ -912,6 +902,15 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, max_linewidth = pdpu->catalog->caps->max_linewidth; + /* state->src is 16.16, src_rect is not */ + drm_rect_fp_to_int(&pipe_cfg->src_rect, &new_plane_state->src); + + pipe_cfg->dst_rect = new_plane_state->dst; + + drm_rect_rotate(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if (drm_rect_width(&pipe_cfg->src_rect) > max_linewidth) { /* * In parallel multirect case only the half of the usual width @@ -959,6 +958,14 @@ static int dpu_plane_atomic_check(struct drm_plane *plane, r_pipe_cfg->dst_rect.x1 = pipe_cfg->dst_rect.x2; } + drm_rect_rotate_inv(&pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + if (r_pipe->sspp) Dont you need to check for if (r_pipe_cfg) here and not if (r_pipe->sspp) because parameter you are passing is the r_pipe_cfg to drm_rect_rotate_inv(). Of course not. r_pipe_cfg is a pointer to the field in pstate. We know that it can not be NULL. Ack, and my bad for not checking that r_pipe_cfg points to a field in pstate but it was just weird though that you are checking for r_pipe->sspp before calling a method which really doesnt care if its null or not. How about you use drm_rect_visible(r_pipe_cfg->src_rect) If its not set, it wont be visible too. So we rotated the pipe_cfg once, then rotated_inv it to restore the rectangle to its original state, but r_pipe_cfg's rectangle was never rotated as it was not allocated before this function so it will remain in inverse rotated state now right? No. r_pipe_cfg is set beforehand to the half of the rotated pipe_cfg. Ok i got it now. Instead of directly operating on the plane_state's rectangle which makes you to invert again why not just use a temporary drm_rect which stores the rotated pipe_cfg->src_rect. That way you dont have to invert anything? + drm_rect_rotate_inv(&r_pipe_cfg->src_rect, + new_plane_state->fb->width, new_plane_state->fb->height, + new_plane_state->rotation); + ret = dpu_plane_atomic_check_pipe(pdpu, pipe, pipe_cfg, fmt); if (ret) return ret; -- With best wishes Dmitry
[PATCH v1] drm/bridge: tc358768: remove unneeded semicolon
From: Francesco Dolcini Remove unneeded stray semicolon. Reported-by: kernel test robot Link: https://lore.kernel.org/oe-kbuild-all/202305152341.oisjrpv6-...@intel.com/ Signed-off-by: Francesco Dolcini --- drivers/gpu/drm/bridge/tc358768.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/bridge/tc358768.c b/drivers/gpu/drm/bridge/tc358768.c index 03c7e82e4109..97ae3a9c90da 100644 --- a/drivers/gpu/drm/bridge/tc358768.c +++ b/drivers/gpu/drm/bridge/tc358768.c @@ -952,7 +952,7 @@ tc358768_atomic_get_input_bus_fmts(struct drm_bridge *bridge, case 24: input_fmts[0] = MEDIA_BUS_FMT_RGB888_1X24; break; - }; + } *num_input_fmts = MAX_INPUT_SEL_FORMATS; -- 2.25.1
Re: [PATCH v8 1/8] drm/msm/dpu: add dsc blocks for remaining chipsets in catalog
On 5/14/2023 2:39 PM, Marijn Suijten wrote: DSC*, and mention 1.1 explicitly (since this skips the 1.2 blocks, while the series is clearly aimed at 1.1...). This was done for the DSC 1.2 HW block patch after all. in catalog -> to catalog But it's just two platforms, you can fit MSM8998 and SC8180X in the title. On 2023-05-12 11:00:16, Kuogee Hsieh wrote: From: Abhinav Kumar There are some platforms has DSC blocks but it is not declared at catalog. Some platforms have DSC blocks which have not yet been declared in the catalog.* For completeness, this patch adds DSC blocks for platforms which missed them. Drop "this patch": Complete DSC 1.1 support for all platforms by adding the missing blocks to MSM8998 and SC8180X. Signed-off-by: Abhinav Kumar Reviewed-by: Dmitry Baryshkov --- drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_3_0_msm8998.h | 7 +++ drivers/gpu/drm/msm/disp/dpu1/catalog/dpu_5_1_sc8180x.h | 11 +++ How about SC7180, and any other DPU 6.x revision? Will let kuogee respond to the other nits. There is no DSC in sc7180 / sm6115 / qcm2290. So this patch is complete. Rest of the patch looks good and complete. - Marijn 2 files changed, 18 insertions(+)
Re: [PATCH v2 02/12] drm/armada: Use regular fbdev I/O helpers
On Mon, May 15, 2023 at 07:55:44PM +0200, Sam Ravnborg wrote: > Hi Thomas, > > On Mon, May 15, 2023 at 11:40:23AM +0200, Thomas Zimmermann wrote: > > Use the regular fbdev helpers for framebuffer I/O instead of DRM's > > helpers. Armada does not use damage handling, so DRM's fbdev helpers > > are mere wrappers around the fbdev code. > > > > By using fbdev helpers directly within each DRM fbdev emulation, > > we can eventually remove DRM's wrapper functions entirely. > > > > v2: > > * use FB_IO_HELPERS option > > > > Signed-off-by: Thomas Zimmermann > > Cc: Russell King > > --- > > drivers/gpu/drm/armada/Kconfig| 1 + > > drivers/gpu/drm/armada/armada_fbdev.c | 9 - > > 2 files changed, 5 insertions(+), 5 deletions(-) > > > > diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig > > index f5c66d89ba99..5afade25e217 100644 > > --- a/drivers/gpu/drm/armada/Kconfig > > +++ b/drivers/gpu/drm/armada/Kconfig > > @@ -3,6 +3,7 @@ config DRM_ARMADA > > tristate "DRM support for Marvell Armada SoCs" > > depends on DRM && HAVE_CLK && ARM && MMU > > select DRM_KMS_HELPER > > + select FB_IO_HELPERS if DRM_FBDEV_EMULATION > > help > > Support the "LCD" controllers found on the Marvell Armada 510 > > devices. There are two controllers on the device, each controller > > diff --git a/drivers/gpu/drm/armada/armada_fbdev.c > > b/drivers/gpu/drm/armada/armada_fbdev.c > > index 0a5fd1aa86eb..6c3bbaf53569 100644 > > --- a/drivers/gpu/drm/armada/armada_fbdev.c > > +++ b/drivers/gpu/drm/armada/armada_fbdev.c > > @@ -5,6 +5,7 @@ > > */ > > > > #include > > +#include > > #include > > #include > > > > @@ -34,11 +35,9 @@ static void armada_fbdev_fb_destroy(struct fb_info *info) > > static const struct fb_ops armada_fb_ops = { > > .owner = THIS_MODULE, > > DRM_FB_HELPER_DEFAULT_OPS, > > - .fb_read= drm_fb_helper_cfb_read, > > - .fb_write = drm_fb_helper_cfb_write, > I had expected to see > .fb_read = fb_io_read, > > But maybe this only used when using damage handling? > > Likewise for drm_fb_helper_cfb_write. > > ?? > > > - .fb_fillrect= drm_fb_helper_cfb_fillrect, > > - .fb_copyarea= drm_fb_helper_cfb_copyarea, > > - .fb_imageblit = drm_fb_helper_cfb_imageblit, > > + .fb_fillrect= cfb_fillrect, > > + .fb_copyarea= cfb_copyarea, > > + .fb_imageblit = cfb_imageblit, > > This part is as expected. Well, to me it looks like this has gone through an entire circular set of revisions: commit e8b70e4dd7b5dad7c2379de6e0851587bf86bfd6 Author: Archit Taneja Date: Wed Jul 22 14:58:04 2015 +0530 drm/armada: Use new drm_fb_helper functions - .fb_fillrect= cfb_fillrect, - .fb_copyarea= cfb_copyarea, - .fb_imageblit = cfb_imageblit, + .fb_fillrect= drm_fb_helper_cfb_fillrect, + .fb_copyarea= drm_fb_helper_cfb_copyarea, + .fb_imageblit = drm_fb_helper_cfb_imageblit, commit 983780918c759fdbbf0bf033e701bbff75d2af23 Author: Thomas Zimmermann Date: Thu Nov 3 16:14:40 2022 +0100 drm/fb-helper: Perform all fbdev I/O with the same implementation + .fb_read= drm_fb_helper_cfb_read, + .fb_write = drm_fb_helper_cfb_write, and now effectively those two changes are being reverted, so we'd now be back to the pre-July 2015 state of affairs. As I believe the fbdev layer has been stable, this change merely reverts the driver back to what it once was. -- RMK's Patch system: https://www.armlinux.org.uk/developer/patches/ FTTP is here! 80Mbps down 10Mbps up. Decent connectivity at last!
Re: [PATCH v8 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On Mon, 15 May 2023 at 20:47, Kuogee Hsieh wrote: > > > On 5/14/2023 2:46 PM, Marijn Suijten wrote: > > On 2023-05-12 21:19:19, Dmitry Baryshkov wrote: > > >>> +static inline void dpu_hw_dsc_bind_pingpong_blk_1_2(struct dpu_hw_dsc > >>> *hw_dsc, > >>> + const enum dpu_pingpong > >>> pp) > >>> +{ > >>> + struct dpu_hw_blk_reg_map *hw; > >>> + const struct dpu_dsc_sub_blks *sblk; > >>> + int mux_cfg = 0xf; /* Disabled */ > >>> + > >>> + hw = &hw_dsc->hw; > >>> + > >>> + sblk = hw_dsc->caps->sblk; > >>> + > >>> + if (pp) > >>> + mux_cfg = (pp - PINGPONG_0) & 0x7; > >> Do we need an unbind support here like we do for the DSC 1.1? > >> > >>> + > >>> + DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CTL, mux_cfg); > >>> +} > > > > > > Friendly request to strip/snip unneeded context (as done in this reply) > > to make it easier to spot the conversation, and replies to it. > > > > - Marijn > > Thanks for suggestion. > > How can I do that? > > just manually delete unneeded context? > > Or are they other way (tricks) to do it automatically? No automation can deduce what is irrelevant to the mail. So we do this manually. -- With best wishes Dmitry
[PATCH 5.4 130/282] linux/vt_buffer.h: allow either builtin or modular for macros
From: Randy Dunlap [ Upstream commit 2b76ffe81e32afd6d318dc4547e2ba8c46207b77 ] Fix build errors on ARCH=alpha when CONFIG_MDA_CONSOLE=m. This allows the ARCH macros to be the only ones defined. In file included from ../drivers/video/console/mdacon.c:37: ../arch/alpha/include/asm/vga.h:17:40: error: expected identifier or '(' before 'volatile' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~~~ ../include/linux/vt_buffer.h:24:34: note: in definition of macro 'scr_writew' 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^~~~ ../include/linux/vt_buffer.h:24:40: error: expected ')' before '=' token 24 | #define scr_writew(val, addr) (*(addr) = (val)) |^ ../arch/alpha/include/asm/vga.h:17:20: note: in expansion of macro 'scr_writew' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~ ../arch/alpha/include/asm/vga.h:25:29: error: expected identifier or '(' before 'volatile' 25 | static inline u16 scr_readw(volatile const u16 *addr) | ^~~~ Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: dri-devel@lists.freedesktop.org Cc: linux-fb...@vger.kernel.org Link: https://lore.kernel.org/r/20230329021529.16188-1-rdun...@infradead.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/linux/vt_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h index 848db1b1569ff..919d999a8c1db 100644 --- a/include/linux/vt_buffer.h +++ b/include/linux/vt_buffer.h @@ -16,7 +16,7 @@ #include -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) +#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE) #include #endif -- 2.39.2
Re: [PATCH v2 02/12] drm/armada: Use regular fbdev I/O helpers
Hi Thomas, On Mon, May 15, 2023 at 11:40:23AM +0200, Thomas Zimmermann wrote: > Use the regular fbdev helpers for framebuffer I/O instead of DRM's > helpers. Armada does not use damage handling, so DRM's fbdev helpers > are mere wrappers around the fbdev code. > > By using fbdev helpers directly within each DRM fbdev emulation, > we can eventually remove DRM's wrapper functions entirely. > > v2: > * use FB_IO_HELPERS option > > Signed-off-by: Thomas Zimmermann > Cc: Russell King > --- > drivers/gpu/drm/armada/Kconfig| 1 + > drivers/gpu/drm/armada/armada_fbdev.c | 9 - > 2 files changed, 5 insertions(+), 5 deletions(-) > > diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig > index f5c66d89ba99..5afade25e217 100644 > --- a/drivers/gpu/drm/armada/Kconfig > +++ b/drivers/gpu/drm/armada/Kconfig > @@ -3,6 +3,7 @@ config DRM_ARMADA > tristate "DRM support for Marvell Armada SoCs" > depends on DRM && HAVE_CLK && ARM && MMU > select DRM_KMS_HELPER > + select FB_IO_HELPERS if DRM_FBDEV_EMULATION > help > Support the "LCD" controllers found on the Marvell Armada 510 > devices. There are two controllers on the device, each controller > diff --git a/drivers/gpu/drm/armada/armada_fbdev.c > b/drivers/gpu/drm/armada/armada_fbdev.c > index 0a5fd1aa86eb..6c3bbaf53569 100644 > --- a/drivers/gpu/drm/armada/armada_fbdev.c > +++ b/drivers/gpu/drm/armada/armada_fbdev.c > @@ -5,6 +5,7 @@ > */ > > #include > +#include > #include > #include > > @@ -34,11 +35,9 @@ static void armada_fbdev_fb_destroy(struct fb_info *info) > static const struct fb_ops armada_fb_ops = { > .owner = THIS_MODULE, > DRM_FB_HELPER_DEFAULT_OPS, > - .fb_read= drm_fb_helper_cfb_read, > - .fb_write = drm_fb_helper_cfb_write, I had expected to see .fb_read = fb_io_read, But maybe this only used when using damage handling? Likewise for drm_fb_helper_cfb_write. ?? > - .fb_fillrect= drm_fb_helper_cfb_fillrect, > - .fb_copyarea= drm_fb_helper_cfb_copyarea, > - .fb_imageblit = drm_fb_helper_cfb_imageblit, > + .fb_fillrect= cfb_fillrect, > + .fb_copyarea= cfb_copyarea, > + .fb_imageblit = cfb_imageblit, This part is as expected. Sam > .fb_destroy = armada_fbdev_fb_destroy, > }; > > -- > 2.40.1
Re: [PATCH v8 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On 5/14/2023 2:46 PM, Marijn Suijten wrote: On 2023-05-12 21:19:19, Dmitry Baryshkov wrote: +static inline void dpu_hw_dsc_bind_pingpong_blk_1_2(struct dpu_hw_dsc *hw_dsc, + const enum dpu_pingpong pp) +{ + struct dpu_hw_blk_reg_map *hw; + const struct dpu_dsc_sub_blks *sblk; + int mux_cfg = 0xf; /* Disabled */ + + hw = &hw_dsc->hw; + + sblk = hw_dsc->caps->sblk; + + if (pp) + mux_cfg = (pp - PINGPONG_0) & 0x7; Do we need an unbind support here like we do for the DSC 1.1? + + DPU_REG_WRITE(hw, sblk->ctl.base + DSC_CTL, mux_cfg); +} Friendly request to strip/snip unneeded context (as done in this reply) to make it easier to spot the conversation, and replies to it. - Marijn Thanks for suggestion. How can I do that? just manually delete unneeded context? Or are they other way (tricks) to do it automatically?
Re: [PATCH v2 03/12] drm/exynos: Use regular fbdev I/O helpers
Hi Thomas, On Mon, May 15, 2023 at 11:40:24AM +0200, Thomas Zimmermann wrote: > Use the regular fbdev helpers for framebuffer I/O instead of DRM's > helpers. Exynos does not use damage handling, so DRM's fbdev helpers > are mere wrappers around the fbdev code. > > By using fbdev helpers directly within each DRM fbdev emulation, > we can eventually remove DRM's wrapper functions entirely. > > v2: > * use FB_IO_HELPERS option > > Signed-off-by: Thomas Zimmermann > Cc: Inki Dae > Cc: Seung-Woo Kim > Cc: Kyungmin Park > Cc: Krzysztof Kozlowski > Cc: Alim Akhtar > --- > drivers/gpu/drm/exynos/Kconfig| 1 + > drivers/gpu/drm/exynos/Makefile | 2 +- > drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 10 +- > 3 files changed, 7 insertions(+), 6 deletions(-) > > diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig > index 0cb92d651ff1..7ca7e1dab52c 100644 > --- a/drivers/gpu/drm/exynos/Kconfig > +++ b/drivers/gpu/drm/exynos/Kconfig > @@ -7,6 +7,7 @@ config DRM_EXYNOS > select DRM_DISPLAY_HELPER if DRM_EXYNOS_DP > select DRM_KMS_HELPER > select VIDEOMODE_HELPERS > + select FB_IO_HELPERS if DRM_FBDEV_EMULATION > select SND_SOC_HDMI_CODEC if SND_SOC > help > Choose this option if you have a Samsung SoC Exynos chipset. > diff --git a/drivers/gpu/drm/exynos/Makefile b/drivers/gpu/drm/exynos/Makefile > index 2fd2f3ee4fcf..233a66036584 100644 > --- a/drivers/gpu/drm/exynos/Makefile > +++ b/drivers/gpu/drm/exynos/Makefile > @@ -6,7 +6,6 @@ > exynosdrm-y := exynos_drm_drv.o exynos_drm_crtc.o exynos_drm_fb.o \ > exynos_drm_gem.o exynos_drm_plane.o exynos_drm_dma.o > > -exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o > exynosdrm-$(CONFIG_DRM_EXYNOS_FIMD) += exynos_drm_fimd.o > exynosdrm-$(CONFIG_DRM_EXYNOS5433_DECON) += exynos5433_drm_decon.o > exynosdrm-$(CONFIG_DRM_EXYNOS7_DECON)+= exynos7_drm_decon.o > @@ -23,5 +22,6 @@ exynosdrm-$(CONFIG_DRM_EXYNOS_ROTATOR) += > exynos_drm_rotator.o > exynosdrm-$(CONFIG_DRM_EXYNOS_SCALER)+= exynos_drm_scaler.o > exynosdrm-$(CONFIG_DRM_EXYNOS_GSC) += exynos_drm_gsc.o > exynosdrm-$(CONFIG_DRM_EXYNOS_MIC) += exynos_drm_mic.o > +exynosdrm-$(CONFIG_DRM_FBDEV_EMULATION) += exynos_drm_fbdev.o What does this change do? Maybe something that was left by accident? Sam > > obj-$(CONFIG_DRM_EXYNOS) += exynosdrm.o > diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c > b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c > index ea4b3d248aac..bdd1d087 100644 > --- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c > +++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c > @@ -8,6 +8,8 @@ > * Seung-Woo Kim > */ > > +#include > + > #include > #include > #include > @@ -49,11 +51,9 @@ static const struct fb_ops exynos_drm_fb_ops = { > .owner = THIS_MODULE, > DRM_FB_HELPER_DEFAULT_OPS, > .fb_mmap= exynos_drm_fb_mmap, > - .fb_read= drm_fb_helper_cfb_read, > - .fb_write = drm_fb_helper_cfb_write, > - .fb_fillrect= drm_fb_helper_cfb_fillrect, > - .fb_copyarea= drm_fb_helper_cfb_copyarea, > - .fb_imageblit = drm_fb_helper_cfb_imageblit, > + .fb_fillrect= cfb_fillrect, > + .fb_copyarea= cfb_copyarea, > + .fb_imageblit = cfb_imageblit, > .fb_destroy = exynos_drm_fb_destroy, > }; > > -- > 2.40.1
[PATCH 5.10 204/381] linux/vt_buffer.h: allow either builtin or modular for macros
From: Randy Dunlap [ Upstream commit 2b76ffe81e32afd6d318dc4547e2ba8c46207b77 ] Fix build errors on ARCH=alpha when CONFIG_MDA_CONSOLE=m. This allows the ARCH macros to be the only ones defined. In file included from ../drivers/video/console/mdacon.c:37: ../arch/alpha/include/asm/vga.h:17:40: error: expected identifier or '(' before 'volatile' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~~~ ../include/linux/vt_buffer.h:24:34: note: in definition of macro 'scr_writew' 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^~~~ ../include/linux/vt_buffer.h:24:40: error: expected ')' before '=' token 24 | #define scr_writew(val, addr) (*(addr) = (val)) |^ ../arch/alpha/include/asm/vga.h:17:20: note: in expansion of macro 'scr_writew' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~ ../arch/alpha/include/asm/vga.h:25:29: error: expected identifier or '(' before 'volatile' 25 | static inline u16 scr_readw(volatile const u16 *addr) | ^~~~ Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: dri-devel@lists.freedesktop.org Cc: linux-fb...@vger.kernel.org Link: https://lore.kernel.org/r/20230329021529.16188-1-rdun...@infradead.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/linux/vt_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h index 848db1b1569ff..919d999a8c1db 100644 --- a/include/linux/vt_buffer.h +++ b/include/linux/vt_buffer.h @@ -16,7 +16,7 @@ #include -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) +#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE) #include #endif -- 2.39.2
Re: [PATCH v8 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On 5/14/2023 3:18 PM, Marijn Suijten wrote: On 2023-05-12 11:00:20, Kuogee Hsieh wrote: Add support for DSC 1.2 by providing the necessary hooks to program the DPU DSC 1.2 encoder. Changes in v3: -- fixed kernel test rebot report that "__iomem *off" is declared but not used at dpu_hw_dsc_config_1_2() -- unrolling thresh loops Changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- delete off and used real register name directly Changes in v7: -- replace offset with sblk->enc.base -- replace ss with slice Changes in v8: -- fixed checkpatch warning Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 32 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 382 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 5 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index b814fc8..b9af5e4 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_hw_dsc_1_2.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index dc0a4da..4eda2cc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. */ @@ -244,12 +244,18 @@ enum { }; /** - * DSC features + * DSC sub-blocks/features * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets *the pixel output from this DSC. + * @DPU_DSC_HW_REV_1_2DSC block supports dsc 1.1 and 1.2 Nit: dsc -> DSC + * @DPU_DSC_NATIVE_422_EN Supports native422 and native420 encoding NATIVE_42x_EN? + * @DPU_DSC_MAX */ enum { DPU_DSC_OUTPUT_CTRL = 0x1, + DPU_DSC_HW_REV_1_2, + DPU_DSC_NATIVE_422_EN, + DPU_DSC_MAX }; /** @@ -306,6 +312,14 @@ struct dpu_pp_blk { }; /** + * struct dpu_dsc_blk - DSC Encoder sub-blk information + * @info: HW register and features supported by this sub-blk + */ +struct dpu_dsc_blk { + DPU_HW_SUBBLK_INFO; +}; + +/** * enum dpu_qos_lut_usage - define QoS LUT use cases */ enum dpu_qos_lut_usage { @@ -452,6 +466,17 @@ struct dpu_pingpong_sub_blks { }; /** + * struct dpu_dsc_sub_blks - DSC sub-blks + * @enc: DSC encoder sub block + * @ctl: DSC controller sub block Nit: sub-block, for both. + * No need for this empty line. + */ +struct dpu_dsc_sub_blks { + struct dpu_dsc_blk enc; + struct dpu_dsc_blk ctl; +}; + +/** * dpu_clk_ctrl_type - Defines top level clock control signals */ enum dpu_clk_ctrl_type { @@ -605,10 +630,13 @@ struct dpu_merge_3d_cfg { * struct dpu_dsc_cfg - information of DSC blocks * @id enum identifying this block * @base register offset of this block + * @len: length of hardware block * @features bit mask identifying sub-blocks/features + * @sblk sub-blocks information Add trailing colon like you did for @len (we will add it to every other field doc in a future fixing pass). */ struct dpu_dsc_cfg { DPU_HW_BLK_INFO; + const struct dpu_dsc_sub_blks *sblk; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 138080a..44fd624 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2020-2022, Linaro Limited */ +/* + * Copyright (c) 2020-2022, Linaro Limited + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ #ifndef _DPU_HW_DSC_H #define _DPU_HW_DSC_H @@ -69,6 +72,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, void __iomem *addr); /** + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block Add () We recently normalized this to "DSC hw driver object." + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Returns: Error code or allocated dpu_hw_dsc context + */ +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct
Re: [PATCH v8 5/8] drm/msm/dpu: add support for DSC encoder v1.2 engine
On 5/14/2023 3:18 PM, Marijn Suijten wrote: On 2023-05-12 11:00:20, Kuogee Hsieh wrote: Add support for DSC 1.2 by providing the necessary hooks to program the DPU DSC 1.2 encoder. Changes in v3: -- fixed kernel test rebot report that "__iomem *off" is declared but not used at dpu_hw_dsc_config_1_2() -- unrolling thresh loops Changes in v4: -- delete DPU_DSC_HW_REV_1_1 -- delete off and used real register name directly Changes in v7: -- replace offset with sblk->enc.base -- replace ss with slice Changes in v8: -- fixed checkpatch warning Signed-off-by: Kuogee Hsieh --- drivers/gpu/drm/msm/Makefile | 1 + drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h | 32 ++- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h | 14 +- drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c | 382 + drivers/gpu/drm/msm/disp/dpu1/dpu_rm.c | 7 +- 5 files changed, 432 insertions(+), 4 deletions(-) create mode 100644 drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc_1_2.c diff --git a/drivers/gpu/drm/msm/Makefile b/drivers/gpu/drm/msm/Makefile index b814fc8..b9af5e4 100644 --- a/drivers/gpu/drm/msm/Makefile +++ b/drivers/gpu/drm/msm/Makefile @@ -65,6 +65,7 @@ msm-$(CONFIG_DRM_MSM_DPU) += \ disp/dpu1/dpu_hw_catalog.o \ disp/dpu1/dpu_hw_ctl.o \ disp/dpu1/dpu_hw_dsc.o \ + disp/dpu1/dpu_hw_dsc_1_2.o \ disp/dpu1/dpu_hw_interrupts.o \ disp/dpu1/dpu_hw_intf.o \ disp/dpu1/dpu_hw_lm.o \ diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h index dc0a4da..4eda2cc 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_catalog.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2022. Qualcomm Innovation Center, Inc. All rights reserved. + * Copyright (c) 2022-2023, Qualcomm Innovation Center, Inc. All rights reserved. * Copyright (c) 2015-2018, 2020 The Linux Foundation. All rights reserved. */ @@ -244,12 +244,18 @@ enum { }; /** - * DSC features + * DSC sub-blocks/features * @DPU_DSC_OUTPUT_CTRL Configure which PINGPONG block gets *the pixel output from this DSC. + * @DPU_DSC_HW_REV_1_2DSC block supports dsc 1.1 and 1.2 Nit: dsc -> DSC + * @DPU_DSC_NATIVE_422_EN Supports native422 and native420 encoding NATIVE_42x_EN? + * @DPU_DSC_MAX */ enum { DPU_DSC_OUTPUT_CTRL = 0x1, + DPU_DSC_HW_REV_1_2, + DPU_DSC_NATIVE_422_EN, + DPU_DSC_MAX }; /** @@ -306,6 +312,14 @@ struct dpu_pp_blk { }; /** + * struct dpu_dsc_blk - DSC Encoder sub-blk information + * @info: HW register and features supported by this sub-blk + */ +struct dpu_dsc_blk { + DPU_HW_SUBBLK_INFO; +}; + +/** * enum dpu_qos_lut_usage - define QoS LUT use cases */ enum dpu_qos_lut_usage { @@ -452,6 +466,17 @@ struct dpu_pingpong_sub_blks { }; /** + * struct dpu_dsc_sub_blks - DSC sub-blks + * @enc: DSC encoder sub block + * @ctl: DSC controller sub block Nit: sub-block, for both. + * No need for this empty line. + */ +struct dpu_dsc_sub_blks { + struct dpu_dsc_blk enc; + struct dpu_dsc_blk ctl; +}; + +/** * dpu_clk_ctrl_type - Defines top level clock control signals */ enum dpu_clk_ctrl_type { @@ -605,10 +630,13 @@ struct dpu_merge_3d_cfg { * struct dpu_dsc_cfg - information of DSC blocks * @id enum identifying this block * @base register offset of this block + * @len: length of hardware block * @features bit mask identifying sub-blocks/features + * @sblk sub-blocks information Add trailing colon like you did for @len (we will add it to every other field doc in a future fixing pass). */ struct dpu_dsc_cfg { DPU_HW_BLK_INFO; + const struct dpu_dsc_sub_blks *sblk; }; /** diff --git a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h index 138080a..44fd624 100644 --- a/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h +++ b/drivers/gpu/drm/msm/disp/dpu1/dpu_hw_dsc.h @@ -1,5 +1,8 @@ /* SPDX-License-Identifier: GPL-2.0-only */ -/* Copyright (c) 2020-2022, Linaro Limited */ +/* + * Copyright (c) 2020-2022, Linaro Limited + * Copyright (c) 2023 Qualcomm Innovation Center, Inc. All rights reserved + */ #ifndef _DPU_HW_DSC_H #define _DPU_HW_DSC_H @@ -69,6 +72,15 @@ struct dpu_hw_dsc *dpu_hw_dsc_init(const struct dpu_dsc_cfg *cfg, void __iomem *addr); /** + * dpu_hw_dsc_init_1_2 - initializes the v1.2 DSC hw driver block Add () We recently normalized this to "DSC hw driver object." + * @cfg: DSC catalog entry for which driver object is required + * @addr: Mapped register io address of MDP + * Returns: Error code or allocated dpu_hw_dsc context + */ +struct dpu_hw_dsc *dpu_hw_dsc_init_1_2(const struct
Re: [PATCH v10 1/8] drm/display/dsc: Add flatness and initial scale value calculations
On 5/13/2023 1:28 PM, Marijn Suijten wrote: On 2023-05-12 14:32:11, Jessica Zhang wrote: Add helpers to calculate det_thresh_flatness and initial_scale_value as these calculations are defined within the DSC spec. Reviewed-by: Marijn Suijten Signed-off-by: Jessica Zhang --- include/drm/display/drm_dsc_helper.h | 10 ++ 1 file changed, 10 insertions(+) diff --git a/include/drm/display/drm_dsc_helper.h b/include/drm/display/drm_dsc_helper.h index 0bb0c3afd740..060b22ec02eb 100644 --- a/include/drm/display/drm_dsc_helper.h +++ b/include/drm/display/drm_dsc_helper.h @@ -25,5 +25,15 @@ void drm_dsc_set_rc_buf_thresh(struct drm_dsc_config *vdsc_cfg); int drm_dsc_setup_rc_params(struct drm_dsc_config *vdsc_cfg, enum drm_dsc_params_kind kind); int drm_dsc_compute_rc_parameters(struct drm_dsc_config *vdsc_cfg); +static inline int drm_dsc_initial_scale_value(const struct drm_dsc_config *dsc) Should this truncate and return u8? Hi Marijn, Acked. +{ + return 8 * dsc->rc_model_size / (dsc->rc_model_size - dsc->initial_offset); +} + +static inline int drm_dsc_flatness_det_thresh(const struct drm_dsc_config *dsc) Should this return u32? Acked. Thanks, Jessica Zhang - Marijn +{ + return 2 << (dsc->bits_per_component - 8); +} + #endif /* _DRM_DSC_HELPER_H_ */ -- 2.40.1
[PATCH 4.19 085/191] linux/vt_buffer.h: allow either builtin or modular for macros
From: Randy Dunlap [ Upstream commit 2b76ffe81e32afd6d318dc4547e2ba8c46207b77 ] Fix build errors on ARCH=alpha when CONFIG_MDA_CONSOLE=m. This allows the ARCH macros to be the only ones defined. In file included from ../drivers/video/console/mdacon.c:37: ../arch/alpha/include/asm/vga.h:17:40: error: expected identifier or '(' before 'volatile' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~~~ ../include/linux/vt_buffer.h:24:34: note: in definition of macro 'scr_writew' 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^~~~ ../include/linux/vt_buffer.h:24:40: error: expected ')' before '=' token 24 | #define scr_writew(val, addr) (*(addr) = (val)) |^ ../arch/alpha/include/asm/vga.h:17:20: note: in expansion of macro 'scr_writew' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~ ../arch/alpha/include/asm/vga.h:25:29: error: expected identifier or '(' before 'volatile' 25 | static inline u16 scr_readw(volatile const u16 *addr) | ^~~~ Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: dri-devel@lists.freedesktop.org Cc: linux-fb...@vger.kernel.org Link: https://lore.kernel.org/r/20230329021529.16188-1-rdun...@infradead.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/linux/vt_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h index 848db1b1569ff..919d999a8c1db 100644 --- a/include/linux/vt_buffer.h +++ b/include/linux/vt_buffer.h @@ -16,7 +16,7 @@ #include -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) +#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE) #include #endif -- 2.39.2
Re: [PATCH v4 04/13] dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
On 15/05/2023 18:28, neil.armstr...@linaro.org wrote: >> It's just a link stored in automated responses, what's here childish? >> It's still valid in current cycle! Look: >> >> https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597 >> >> What's the difference? Srsly, I can point you to submitting patches >> without reference to specific line if you wish... Or you can check by >> yourself. >> >> I give the same reviews to so many people that have templates and Elixir >> happens to be the only place allowing bookmarking specific line. Which >> is helpful for beginners because the entire doc is huge. >> >> I can make an exception for you and never paste direct links. > > I value those kind of links for beginners and newcomers, really, it's a good > thing to do and we should all do the same. Hm, if I understand correctly, you felt being patronized by my link? I apologize for that. It was not my intention and there is really no need to feel like that. Look, I have many, many templates so I can speed up review. This one I gave to many: https://lore.kernel.org/all/?q=f%3Akrzysztof+%22Please+wrap+commit+message+according+to+Linux+coding+style%22 Writing same review every damn time is a boring, absolutely huge waste of time. People just make too many same mistakes. Better to hit key shortcut. Over the time most of my templates grew a bit, because when I wrote "Please wrap to 75" submitter did not know what to wrap or why. To save myself work I extend the template to something more. The entire text and link is for the beginner, not for you. Best regards, Krzysztof
[PATCH 4.14 046/116] linux/vt_buffer.h: allow either builtin or modular for macros
From: Randy Dunlap [ Upstream commit 2b76ffe81e32afd6d318dc4547e2ba8c46207b77 ] Fix build errors on ARCH=alpha when CONFIG_MDA_CONSOLE=m. This allows the ARCH macros to be the only ones defined. In file included from ../drivers/video/console/mdacon.c:37: ../arch/alpha/include/asm/vga.h:17:40: error: expected identifier or '(' before 'volatile' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~~~ ../include/linux/vt_buffer.h:24:34: note: in definition of macro 'scr_writew' 24 | #define scr_writew(val, addr) (*(addr) = (val)) | ^~~~ ../include/linux/vt_buffer.h:24:40: error: expected ')' before '=' token 24 | #define scr_writew(val, addr) (*(addr) = (val)) |^ ../arch/alpha/include/asm/vga.h:17:20: note: in expansion of macro 'scr_writew' 17 | static inline void scr_writew(u16 val, volatile u16 *addr) |^~ ../arch/alpha/include/asm/vga.h:25:29: error: expected identifier or '(' before 'volatile' 25 | static inline u16 scr_readw(volatile const u16 *addr) | ^~~~ Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2") Signed-off-by: Randy Dunlap Cc: Greg Kroah-Hartman Cc: Jiri Slaby Cc: dri-devel@lists.freedesktop.org Cc: linux-fb...@vger.kernel.org Link: https://lore.kernel.org/r/20230329021529.16188-1-rdun...@infradead.org Signed-off-by: Greg Kroah-Hartman Signed-off-by: Sasha Levin --- include/linux/vt_buffer.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/vt_buffer.h b/include/linux/vt_buffer.h index 848db1b1569ff..919d999a8c1db 100644 --- a/include/linux/vt_buffer.h +++ b/include/linux/vt_buffer.h @@ -16,7 +16,7 @@ #include -#if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_MDA_CONSOLE) +#if IS_ENABLED(CONFIG_VGA_CONSOLE) || IS_ENABLED(CONFIG_MDA_CONSOLE) #include #endif -- 2.39.2
Re: [PATCH v4 01/13] dt-bindings: clk: g12a-clkc: export VCLK2_SEL and add CTS_ENCL clock ids
On 15/05/2023 18:22, neil.armstr...@linaro.org wrote: >>> Meson is the only or almost the only platform making such changes. I >>> don't get why, because the conflict could be easily avoided with using >>> different names for defines in bindings and local clock. Approach of >>> having bindings strictly tied with driver commit is never desired. > > If we did it now, we would have make it differently and expose all the clock > IDs on the bindings like on Qcom, be sure of that. No, you just keep different names. The only problem here is that your clock name is the same thus you cannot split bindings into separate patch. > >> >> Also one more argument maybe not relevant here but for other cases - >> this makes literally impossible to include the clock ID in DTS in the >> same kernel revision, because you must not merge driver branch to DTS >> branch. SoC folks were complaining about this many times. > > Actually we handle this very simply by having such patches merged in a > immutable > branch merged in the clock and DT pull-requests, it worked perfectly so far > and neither Stephen or Arnd complained about that. Arnd, Olof, Any changes in the policies? Do you allow now driver branches (with driver code) to be merged into DT branch? Best regards, Krzysztof
Re: [PATCH v4 04/13] dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
On 15/05/2023 18:22, Krzysztof Kozlowski wrote: On 15/05/2023 18:15, Neil Armstrong wrote: On 13/05/2023 20:32, Krzysztof Kozlowski wrote: On 12/05/2023 15:11, Neil Armstrong wrote: The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a), with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue on the same Amlogic SoCs. Please wrap commit message according to Linux coding style / submission process (neither too early nor over the limit): https://elixir.bootlin.com/linux/v5.18-rc4/source/Documentation/process/submitting-patches.rst#L586 This message may be automatic, but context is always important when reviewing, this commit message is a re-spin on v3 that was reviewed by rob but I decided to remove the review tags since I added a new clock and did some other cleanups. While the process describes "how the patch itself *should* be formatted", it's a best effort and not a blocker. Other issues are blockers. I agree with that I'll fix the wrapping since you pointed out, but referring to the submitting-patches.rst file (from a very old v5.18-rc4 version) is kind of childish. It's just a link stored in automated responses, what's here childish? It's still valid in current cycle! Look: https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597 What's the difference? Srsly, I can point you to submitting patches without reference to specific line if you wish... Or you can check by yourself. I give the same reviews to so many people that have templates and Elixir happens to be the only place allowing bookmarking specific line. Which is helpful for beginners because the entire doc is huge. I can make an exception for you and never paste direct links. I value those kind of links for beginners and newcomers, really, it's a good thing to do and we should all do the same. But I always take in account who I'm reviewing, and adapt my comments, I think it's sane to not appear as rude because we all forget to check some stuff when send patches upstream, or at least I often forget... Anyway, don't make exceptions or change your process for me, I'll live with it. Neil Best regards, Krzysztof
Re: [PATCH v4 01/13] dt-bindings: clk: g12a-clkc: export VCLK2_SEL and add CTS_ENCL clock ids
On 15/05/2023 18:15, Krzysztof Kozlowski wrote: On 15/05/2023 18:13, Krzysztof Kozlowski wrote: On 15/05/2023 18:06, Neil Armstrong wrote: On 13/05/2023 20:28, Krzysztof Kozlowski wrote: On 12/05/2023 15:11, Neil Armstrong wrote: Expose VCLK2_SEL clock id and add new ids for the CTS_ENCL and CTS_ENCL_SEL clocks on G12A compatible SoCs. Signed-off-by: Neil Armstrong --- drivers/clk/meson/g12a.h | 1 - include/dt-bindings/clock/g12a-clkc.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) Bindings must be a separate patch from the driver changes. If this causes bisectability issues, this means entire solution breaks ABI and is not appropriate anyway... This is basically how we handled CLK IDs on Amlogic clk bindings for the last years, the amount of changes is very low and rather exceptional compared to early development stage. The commits with bindings are used in devicetree-rebasing repo, so we want them to be separate. A lot of commits changes the bindings and other part of the kernel source, it was solved with git filter-repo a long time ago. While I understand in an ideal world those commits should only touch Documentation/bindings, it's sometime not possible. Meson is the only or almost the only platform making such changes. I don't get why, because the conflict could be easily avoided with using different names for defines in bindings and local clock. Approach of having bindings strictly tied with driver commit is never desired. If we did it now, we would have make it differently and expose all the clock IDs on the bindings like on Qcom, be sure of that. Also one more argument maybe not relevant here but for other cases - this makes literally impossible to include the clock ID in DTS in the same kernel revision, because you must not merge driver branch to DTS branch. SoC folks were complaining about this many times. Actually we handle this very simply by having such patches merged in a immutable branch merged in the clock and DT pull-requests, it worked perfectly so far and neither Stephen or Arnd complained about that. Best regards, Krzysztof
Re: [PATCH v4 04/13] dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
On 15/05/2023 18:15, Neil Armstrong wrote: > On 13/05/2023 20:32, Krzysztof Kozlowski wrote: >> On 12/05/2023 15:11, Neil Armstrong wrote: >>> The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver >>> (ver 1.21a), >>> with a custom glue managing the IP resets, clock and data input similar to >>> the DW-HDMI Glue >>> on the same Amlogic SoCs. >> >> Please wrap commit message according to Linux coding style / submission >> process (neither too early nor over the limit): >> https://elixir.bootlin.com/linux/v5.18-rc4/source/Documentation/process/submitting-patches.rst#L586 > > This message may be automatic, but context is always important when reviewing, > this commit message is a re-spin on v3 that was reviewed by rob but I decided > to remove the review > tags since I added a new clock and did some other cleanups. > > While the process describes "how the patch itself *should* be formatted", > it's a best effort > and not a blocker. Other issues are blockers. > > I'll fix the wrapping since you pointed out, but referring to the > submitting-patches.rst > file (from a very old v5.18-rc4 version) is kind of childish. It's just a link stored in automated responses, what's here childish? It's still valid in current cycle! Look: https://elixir.bootlin.com/linux/v6.4-rc1/source/Documentation/process/submitting-patches.rst#L597 What's the difference? Srsly, I can point you to submitting patches without reference to specific line if you wish... Or you can check by yourself. I give the same reviews to so many people that have templates and Elixir happens to be the only place allowing bookmarking specific line. Which is helpful for beginners because the entire doc is huge. I can make an exception for you and never paste direct links. Best regards, Krzysztof
[PATCH] dt-bindings: display: bridge: tc358867: Document TC358867/TC9595 compatible
The TC358867/TC9595 devices are compatible with the predecessor TC358767. Document compatible strings for the new devices, so they can be discerned in board DTs. Update the title to match description in the process. Signed-off-by: Marek Vasut --- Cc: Andrey Gusakov Cc: Andrzej Hajda Cc: Conor Dooley Cc: Daniel Vetter Cc: David Airlie Cc: Jernej Skrabec Cc: Jonas Karlman Cc: Krzysztof Kozlowski Cc: Laurent Pinchart Cc: Neil Armstrong Cc: Rob Herring Cc: Robert Foss Cc: devicet...@vger.kernel.org Cc: dri-devel@lists.freedesktop.org --- .../bindings/display/bridge/toshiba,tc358767.yaml | 14 +++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml index e1494b5007cba..0521261b04a9c 100644 --- a/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml +++ b/Documentation/devicetree/bindings/display/bridge/toshiba,tc358767.yaml @@ -4,16 +4,24 @@ $id: http://devicetree.org/schemas/display/bridge/toshiba,tc358767.yaml# $schema: http://devicetree.org/meta-schemas/core.yaml# -title: Toshiba TC358767 eDP bridge +title: Toshiba TC358767/TC358867/TC9595 DSI/DPI/eDP bridge maintainers: - Andrey Gusakov -description: The TC358767 is bridge device which converts DSI/DPI to eDP/DP +description: | + The TC358767/TC358867/TC9595 is bridge device which + converts DSI/DPI to eDP/DP . properties: compatible: -const: toshiba,tc358767 +oneOf: + - items: + - enum: + - toshiba,tc358867 + - toshiba,tc9595 + - const: toshiba,tc358767 + - const: toshiba,tc358767 reg: enum: -- 2.39.2
Re: [PATCH v4 04/13] dt-bindings: display: add Amlogic MIPI DSI Host Controller bindings
On 13/05/2023 20:32, Krzysztof Kozlowski wrote: On 12/05/2023 15:11, Neil Armstrong wrote: The Amlogic G12A, G12B & SM1 SoCs embeds a Synopsys DW-MIPI-DSI transceiver (ver 1.21a), with a custom glue managing the IP resets, clock and data input similar to the DW-HDMI Glue on the same Amlogic SoCs. Please wrap commit message according to Linux coding style / submission process (neither too early nor over the limit): https://elixir.bootlin.com/linux/v5.18-rc4/source/Documentation/process/submitting-patches.rst#L586 This message may be automatic, but context is always important when reviewing, this commit message is a re-spin on v3 that was reviewed by rob but I decided to remove the review tags since I added a new clock and did some other cleanups. While the process describes "how the patch itself *should* be formatted", it's a best effort and not a blocker. I'll fix the wrapping since you pointed out, but referring to the submitting-patches.rst file (from a very old v5.18-rc4 version) is kind of childish. Subject: drop second/last, redundant "bindings". The "dt-bindings" prefix is already stating that these are bindings. Signed-off-by: Neil Armstrong Signed-off-by: Neil Armstrong --- .../display/amlogic,meson-g12a-dw-mipi-dsi.yaml| 117 + 1 file changed, 117 insertions(+) diff --git a/Documentation/devicetree/bindings/display/amlogic,meson-g12a-dw-mipi-dsi.yaml b/Documentation/devicetree/bindings/display/amlogic,meson-g12a-dw-mipi-dsi.yaml new file mode 100644 index ..8169c7e93ff5 --- /dev/null +++ b/Documentation/devicetree/bindings/display/amlogic,meson-g12a-dw-mipi-dsi.yaml @@ -0,0 +1,117 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +# Copyright 2020 BayLibre, SAS +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/display/amlogic,meson-g12a-dw-mipi-dsi.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Amlogic specific extensions to the Synopsys Designware MIPI DSI Host Controller + +maintainers: + - Neil Armstrong + +description: | + The Amlogic Meson Synopsys Designware Integration is composed of + - A Synopsys DesignWare MIPI DSI Host Controller IP + - A TOP control block controlling the Clocks & Resets of the IP + +allOf: + - $ref: dsi-controller.yaml# + +properties: + compatible: +enum: + - amlogic,meson-g12a-dw-mipi-dsi + + reg: +maxItems: 1 + + clocks: +minItems: 3 Missing maxItems Ack + + clock-names: +minItems: 3 +items: + - const: pclk + - const: bit_clk + - const: px_clk + - const: meas_clk Drop _clk suffixes. pclk can stay, it's a bit odd but recently Rob clarified that suffix with underscore should not be there. Ack + + resets: +minItems: 1 maxItems instead Ack + + reset-names: +items: + - const: top + + phys: +minItems: 1 Ditto Ack + + phy-names: +items: + - const: dphy + + ports: +$ref: /schemas/graph.yaml#/properties/ports + +properties: + port@0: +$ref: /schemas/graph.yaml#/properties/port +description: Input node to receive pixel data. + + port@1: +$ref: /schemas/graph.yaml#/properties/port +description: DSI output node to panel. + +required: + - port@0 + - port@1 + +required: + - compatible + - reg + - clocks + - clock-names + - resets + - reset-names + - phys + - phy-names + - ports + +unevaluatedProperties: false + +examples: + - | +dsi@7000 { + compatible = "amlogic,meson-g12a-dw-mipi-dsi"; + reg = <0x6000 0x400>; Your reg does not match unit address. The dt_binding_check should actually complain about it. Well, it doesn't, will fix Thanks, Neil Best regards, Krzysztof
Re: [PATCH v4 01/13] dt-bindings: clk: g12a-clkc: export VCLK2_SEL and add CTS_ENCL clock ids
On 15/05/2023 18:13, Krzysztof Kozlowski wrote: > On 15/05/2023 18:06, Neil Armstrong wrote: >> On 13/05/2023 20:28, Krzysztof Kozlowski wrote: >>> On 12/05/2023 15:11, Neil Armstrong wrote: Expose VCLK2_SEL clock id and add new ids for the CTS_ENCL and CTS_ENCL_SEL clocks on G12A compatible SoCs. Signed-off-by: Neil Armstrong --- drivers/clk/meson/g12a.h | 1 - include/dt-bindings/clock/g12a-clkc.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) >>> >>> Bindings must be a separate patch from the driver changes. If this >>> causes bisectability issues, this means entire solution breaks ABI and >>> is not appropriate anyway... >> >> This is basically how we handled CLK IDs on Amlogic clk bindings for the >> last years, the amount of changes is very low and rather exceptional >> compared to early development stage. > > The commits with bindings are used in devicetree-rebasing repo, so we > want them to be separate. > > Meson is the only or almost the only platform making such changes. I > don't get why, because the conflict could be easily avoided with using > different names for defines in bindings and local clock. Approach of > having bindings strictly tied with driver commit is never desired. Also one more argument maybe not relevant here but for other cases - this makes literally impossible to include the clock ID in DTS in the same kernel revision, because you must not merge driver branch to DTS branch. SoC folks were complaining about this many times. Best regards, Krzysztof
Re: [PATCH v4 01/13] dt-bindings: clk: g12a-clkc: export VCLK2_SEL and add CTS_ENCL clock ids
On 15/05/2023 18:06, Neil Armstrong wrote: > On 13/05/2023 20:28, Krzysztof Kozlowski wrote: >> On 12/05/2023 15:11, Neil Armstrong wrote: >>> Expose VCLK2_SEL clock id and add new ids for the CTS_ENCL and CTS_ENCL_SEL >>> clocks on G12A compatible SoCs. >>> >>> Signed-off-by: Neil Armstrong >>> --- >>> drivers/clk/meson/g12a.h | 1 - >>> include/dt-bindings/clock/g12a-clkc.h | 3 +++ >>> 2 files changed, 3 insertions(+), 1 deletion(-) >> >> Bindings must be a separate patch from the driver changes. If this >> causes bisectability issues, this means entire solution breaks ABI and >> is not appropriate anyway... > > This is basically how we handled CLK IDs on Amlogic clk bindings for the > last years, the amount of changes is very low and rather exceptional > compared to early development stage. The commits with bindings are used in devicetree-rebasing repo, so we want them to be separate. Meson is the only or almost the only platform making such changes. I don't get why, because the conflict could be easily avoided with using different names for defines in bindings and local clock. Approach of having bindings strictly tied with driver commit is never desired. Best regards, Krzysztof
Re: [PATCH v4 01/13] dt-bindings: clk: g12a-clkc: export VCLK2_SEL and add CTS_ENCL clock ids
On 13/05/2023 20:28, Krzysztof Kozlowski wrote: On 12/05/2023 15:11, Neil Armstrong wrote: Expose VCLK2_SEL clock id and add new ids for the CTS_ENCL and CTS_ENCL_SEL clocks on G12A compatible SoCs. Signed-off-by: Neil Armstrong --- drivers/clk/meson/g12a.h | 1 - include/dt-bindings/clock/g12a-clkc.h | 3 +++ 2 files changed, 3 insertions(+), 1 deletion(-) Bindings must be a separate patch from the driver changes. If this causes bisectability issues, this means entire solution breaks ABI and is not appropriate anyway... This is basically how we handled CLK IDs on Amlogic clk bindings for the last years, the amount of changes is very low and rather exceptional compared to early development stage. Neil Best regards, Krzysztof
Re: [PATCH v6 3/8] drm/bridge: mhdp8546: Add minimal format negotiation
Hi Tomi, On 12-May-23 14:45, Tomi Valkeinen wrote: > On 09/05/2023 12:30, Aradhya Bhatia wrote: >> From: Nikhil Devshatwar >> >> With new connector model, mhdp bridge will not create the connector and >> SoC driver will rely on format negotiation to setup the encoder format. >> >> Support minimal format negotiations hooks in the drm_bridge_funcs. >> Complete format negotiation can be added based on EDID data. >> This patch adds the minimal required support to avoid failure >> after moving to new connector model. >> >> Signed-off-by: Nikhil Devshatwar >> Reviewed-by: Tomi Valkeinen > > You need to add your SoB to this and the other patches. Okay! > >> --- >> >> Notes: >> >> changes from v1: >> * cosmetic fixes, commit message update. >> >> changes from v5: >> * dropped the default_bus_format variable and directly assigned >> MEDIA_BUS_FMT_RGB121212_1X36 to input_fmts. >> >> .../drm/bridge/cadence/cdns-mhdp8546-core.c | 25 +++ >> 1 file changed, 25 insertions(+) >> >> diff --git a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> index f6822dfa3805..623e4235c94f 100644 >> --- a/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> +++ b/drivers/gpu/drm/bridge/cadence/cdns-mhdp8546-core.c >> @@ -2146,6 +2146,30 @@ cdns_mhdp_bridge_atomic_reset(struct drm_bridge >> *bridge) >> return &cdns_mhdp_state->base; >> } >> +static u32 *cdns_mhdp_get_input_bus_fmts(struct drm_bridge *bridge, >> + struct drm_bridge_state *bridge_state, >> + struct drm_crtc_state *crtc_state, >> + struct drm_connector_state *conn_state, >> + u32 output_fmt, >> + unsigned int *num_input_fmts) >> +{ >> + u32 *input_fmts; >> + >> + *num_input_fmts = 0; >> + >> + if (output_fmt != MEDIA_BUS_FMT_FIXED) >> + return NULL; > > The tfp410 and sii902x drivers don't have the above check. Why does mhdp > need it? Or the other way, why don't tfp410 and sii902x need it? I had removed this condition in order to follow status quo, from the ITE-66121 HDMI bridge driver. The idea would have been to drop this for MHDP as well, but I guess I overlooked this one. However... > I guess at the moment we always do get MEDIA_BUS_FMT_FIXED as the out > fmt (in all three bridge drivers), don't we? ... I tested again to ensure that the above is indeed the case. And ended up catching some odd behavior. It turns out that for all the HDMI bridges (TFP410, SII902X, ITE-66121), the format negotiation doesn't stop at output_fmt = MEDIA_BUS_FMT_FIXED. The {bridge}_get_input_format API gets called again with the output_fmt = MEDIA_BUS_FMT_RGB24_1X24. This doesn't happen with the MHDP driver. Format negotiation with MHDP bridge stops after one round, at output_fmt = MEDIA_BUS_FMT_FIXED. Regards Aradhya
[PATCH v13 2/2] MAINTAINERS: add maintainers for DRM LOONGSON driver
This patch add Li Yi and Sui Jingfeng as maintainer to drm/loongson driver Signed-off-by: Sui Jingfeng --- MAINTAINERS | 8 1 file changed, 8 insertions(+) diff --git a/MAINTAINERS b/MAINTAINERS index 402e26d0cdbc..8cdb75f653bc 100644 --- a/MAINTAINERS +++ b/MAINTAINERS @@ -6945,6 +6945,14 @@ T: git git://anongit.freedesktop.org/drm/drm-misc F: drivers/gpu/drm/lima/ F: include/uapi/drm/lima_drm.h +DRM DRIVERS FOR LOONGSON +M: Li Yi +M: Sui Jingfeng +L: dri-devel@lists.freedesktop.org +S: Supported +T: git git://anongit.freedesktop.org/drm/drm-misc +F: drivers/gpu/drm/loongson/ + DRM DRIVERS FOR MEDIATEK M: Chun-Kuang Hu M: Philipp Zabel -- 2.25.1
[PATCH v13 0/2] drm: add kms driver for loongson display controller
Loongson display controller IP has been integrated in both Loongson north bridge chipset(ls7a1000/ls7a2000) and Loongson SoCs(ls2k1000/ls2k2000), it has been even included in Loongson self-made BMC products. This display controller is a PCI device. It has two display pipes and each display pipe support a primary plane and a cursor plane. For the DC in the ls7a1000 and ls2k1000, each display pipe has a DVO output interface which provide RGB888 signals, vertical & horizontal synchronisations and pixel clock. Each CRTC is able to support 1920x1080@60Hz, the maximum resolution of each display pipe is 2048x2048 according to the hardware spec. For the DC in LS7A2000, each display pipe is equipped with a built-in HDMI encoder which is compliant with the HDMI 1.4 specification, thus it support 3840x2160@30Hz. The first display pipe is also equipped with a transparent vga encoder which is parallel with the HDMI encoder. The DC in LS7A2000 is more complete compare with the one in old chips, besides above feature, it has two hardware cursors, two hardware vblank counter and two scanout position recorders unit. It also support tiled framebuffer format which can be scanout the tiled framebuffer rendered by the LoongGPU directly. v1 -> v2: 1) Use hpd status reg when polling for ls7a2000 2) Fix all warnings emerged when compile with W=1 v2 -> v3: 1) Add COMPILE_TEST in Kconfig and make the driver off by default 2) Alphabetical sorting headers (Thomas) 3) Untangle register access functions as much as possible (Thomas) 4) Switch to TTM based memory manager and prefer cached mapping for Loongson SoC (Thomas) 5) Add chip id detection method, now all models are distinguishable. 6) Revise builtin HDMI phy driver, nearly all main stream mode below 4K@30Hz is tested, this driver supported these mode very well including clone display mode and extend display mode. v3 -> v4: 1) Quickly fix a small mistake. v4 -> v5: 1) Drop potential support for Loongson 2K series SoC temporary, this part should be resend with the DT binding patch in the future. 2) Add per display pipe debugfs support to the builtin HDMI encoder. 3) Rewrite atomic_update() for hardware cursors plane(Thomas) 4) Rewrite encoder and connector initialization part, untangle it according to the chip(Thomas). v5 -> v6: 1) Remove stray code which didn't get used, say lsdc_of_get_reserved_ram 2) Fix all typos I could found, make sentences and code more readable 3) Untangle lsdc_hdmi*_connector_detect() function according to the pipe 4) After a serious consideration, we rename this driver as loongson. Because we also have drivers toward the LoongGPU IP in LS7A2000 and LS2K2000. Besides, there are also drivers about the external encoder, HDMI audio driver and vbios support etc. This patch only provide DC driver part, my teammate Li Yi believe that loongson will be more suitable for loongson graphics than lsdc in the long run. loongson.ko = LSDC + LoongGPU + encoders driver + vbios/DT ... v6 -> v7: 1) Add prime support, self-sharing is works. sharing buffer with etnaviv is also tested, and its works with limitation. 2) Implement buffer objects tracking with list_head. 3) S3(sleep to RAM) is tested on ls3a5000+ls7a2000 evb and it works. 4) Rewrite lsdc_bo_move, since ttm core stop allocating resources during BO creation. Patch V1 ~ V6 of this series no longer works on latest kernel. Thus, we send V7 to revival them. v7 -> v8: 1) Zero a compile warnnings on 32-bit platform, compile with W=1 2) Revise lsdc_bo_gpu_offset() and minor cleanup 3) Pageflip tested on the virtual terminal with following commands modetest -M loongson -s 32:1920x1080 -v modetest -M loongson -s 34:1920x1080 -v -F tiles It works like a charm, when running pageflip test with dual screnn configuration, another two additional bo created by the modetest emerged, VRAM usage up to 40+MB, well we have at least 64MB, still enough. # cat bos bo[]: size: 8112kB VRAM bo[0001]: size: 16kB VRAM bo[0002]: size: 16kB VRAM bo[0003]: size:16208kB VRAM bo[0004]: size: 8112kB VRAM bo[0005]: size: 8112kB VRAM v8 -> v9: 1) Select I2C and I2C_ALGOBIT in Kconfig and should depend on MMU. 2) Using pci_get_domain_bus_and_slot to get the GPU device. 3) Other minor improvements. Those patches are tested on ls3a5000 + ls7a1000 CRB, ls3a5000 + ls7a2000 evb, and lemote a1901 board(ls3a4000 + ls7a1000). On loongson mips CPU, the write combine support should be enabled, to get a decent performance for writing framebuffer data to the VRAM. v9 -> v10: 1) Revise lsdc_drm_freeze() to implement S3 completely and correctly. I suddenly realized that pinned buffer can not move and VRAM lost power when sleep to RAM. Thus, the data in the buffer who is pinned in VRAM will get lost when resume. Yet it's not big problem because we are s