Skip to content

Commit a780a82

Browse files
Abhinav Kumarlumag
authored andcommitted
drm/msm/dpu: add an API to setup the CDM block for writeback
Add an API dpu_encoder_helper_phys_setup_cdm() which can be used by the writeback encoder to setup the CDM block. Currently, this is defined and used within the writeback's physical encoder layer however, the function can be modified to be used to setup the CDM block even for non-writeback interfaces. Until those modifications are planned and made, keep it local to writeback. changes in v3: - call bind_pingpong_blk() directly as disable() is dropped - add dpu_csc10_rgb2yuv_601l to dpu_hw_util.h and use it - fix kbot error on the function doc - document that dpu_encoder_helper_phys_setup_cdm() doesn't handle DPU_CHROMA_H1V2 changes in v2: - add the RGB2YUV CSC matrix to dpu util as needed by CDM - use dpu_hw_get_csc_cfg() to get and program CSC - drop usage of setup_csc_data() and setup_cdwn() cdm ops as they both have been merged into enable() - drop reduntant hw_cdm and hw_pp checks Reported-by: kernel test robot <lkp@intel.com> Closes: https://lore.kernel.org/oe-kbuild-all/202312102149.qmbCdsg2-lkp@intel.com/ Signed-off-by: Abhinav Kumar <quic_abhinavk@quicinc.com> Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org> Patchwork: https://patchwork.freedesktop.org/patch/571833/ Link: https://lore.kernel.org/r/20231212205254.12422-12-quic_abhinavk@quicinc.com Signed-off-by: Dmitry Baryshkov <dmitry.baryshkov@linaro.org>
1 parent 53d5abe commit a780a82

3 files changed

Lines changed: 112 additions & 1 deletion

File tree

drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,10 @@
1414
#include "dpu_hw_intf.h"
1515
#include "dpu_hw_wb.h"
1616
#include "dpu_hw_pingpong.h"
17+
#include "dpu_hw_cdm.h"
1718
#include "dpu_hw_ctl.h"
1819
#include "dpu_hw_top.h"
20+
#include "dpu_hw_util.h"
1921
#include "dpu_encoder.h"
2022
#include "dpu_crtc.h"
2123

@@ -150,6 +152,7 @@ enum dpu_intr_idx {
150152
* @hw_pp: Hardware interface to the ping pong registers
151153
* @hw_intf: Hardware interface to the intf registers
152154
* @hw_wb: Hardware interface to the wb registers
155+
* @hw_cdm: Hardware interface to the CDM registers
153156
* @dpu_kms: Pointer to the dpu_kms top level
154157
* @cached_mode: DRM mode cached at mode_set time, acted on in enable
155158
* @enabled: Whether the encoder has enabled and running a mode
@@ -178,6 +181,7 @@ struct dpu_encoder_phys {
178181
struct dpu_hw_pingpong *hw_pp;
179182
struct dpu_hw_intf *hw_intf;
180183
struct dpu_hw_wb *hw_wb;
184+
struct dpu_hw_cdm *hw_cdm;
181185
struct dpu_kms *dpu_kms;
182186
struct drm_display_mode cached_mode;
183187
enum dpu_enc_split_role split_role;
@@ -207,6 +211,7 @@ static inline int dpu_encoder_phys_inc_pending(struct dpu_encoder_phys *phys)
207211
* @wbirq_refcount: Reference count of writeback interrupt
208212
* @wb_done_timeout_cnt: number of wb done irq timeout errors
209213
* @wb_cfg: writeback block config to store fb related details
214+
* @cdm_cfg: cdm block config needed to store writeback block's CDM configuration
210215
* @wb_conn: backpointer to writeback connector
211216
* @wb_job: backpointer to current writeback job
212217
* @dest: dpu buffer layout for current writeback output buffer
@@ -216,6 +221,7 @@ struct dpu_encoder_phys_wb {
216221
atomic_t wbirq_refcount;
217222
int wb_done_timeout_cnt;
218223
struct dpu_hw_wb_cfg wb_cfg;
224+
struct dpu_hw_cdm_cfg cdm_cfg;
219225
struct drm_writeback_connector *wb_conn;
220226
struct drm_writeback_job *wb_job;
221227
struct dpu_hw_fmt_layout dest;

drivers/gpu/drm/msm/disp/dpu1/dpu_encoder_phys_wb.c

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,96 @@ static void dpu_encoder_phys_wb_setup_ctl(struct dpu_encoder_phys *phys_enc)
259259
}
260260
}
261261

262+
/**
263+
* dpu_encoder_helper_phys_setup_cdm - setup chroma down sampling block
264+
* This API does not handle DPU_CHROMA_H1V2.
265+
* @phys_enc:Pointer to physical encoder
266+
*/
267+
static void dpu_encoder_helper_phys_setup_cdm(struct dpu_encoder_phys *phys_enc)
268+
{
269+
struct dpu_hw_cdm *hw_cdm;
270+
struct dpu_hw_cdm_cfg *cdm_cfg;
271+
struct dpu_hw_pingpong *hw_pp;
272+
struct dpu_encoder_phys_wb *wb_enc;
273+
const struct msm_format *format;
274+
const struct dpu_format *dpu_fmt;
275+
struct drm_writeback_job *wb_job;
276+
int ret;
277+
278+
if (!phys_enc)
279+
return;
280+
281+
wb_enc = to_dpu_encoder_phys_wb(phys_enc);
282+
cdm_cfg = &wb_enc->cdm_cfg;
283+
hw_pp = phys_enc->hw_pp;
284+
hw_cdm = phys_enc->hw_cdm;
285+
wb_job = wb_enc->wb_job;
286+
287+
format = msm_framebuffer_format(wb_enc->wb_job->fb);
288+
dpu_fmt = dpu_get_dpu_format_ext(format->pixel_format, wb_job->fb->modifier);
289+
290+
if (!hw_cdm)
291+
return;
292+
293+
if (!DPU_FORMAT_IS_YUV(dpu_fmt)) {
294+
DPU_DEBUG("[enc:%d] cdm_disable fmt:%x\n", DRMID(phys_enc->parent),
295+
dpu_fmt->base.pixel_format);
296+
if (hw_cdm->ops.bind_pingpong_blk)
297+
hw_cdm->ops.bind_pingpong_blk(hw_cdm, PINGPONG_NONE);
298+
299+
return;
300+
}
301+
302+
memset(cdm_cfg, 0, sizeof(struct dpu_hw_cdm_cfg));
303+
304+
cdm_cfg->output_width = wb_job->fb->width;
305+
cdm_cfg->output_height = wb_job->fb->height;
306+
cdm_cfg->output_fmt = dpu_fmt;
307+
cdm_cfg->output_type = CDM_CDWN_OUTPUT_WB;
308+
cdm_cfg->output_bit_depth = DPU_FORMAT_IS_DX(dpu_fmt) ?
309+
CDM_CDWN_OUTPUT_10BIT : CDM_CDWN_OUTPUT_8BIT;
310+
cdm_cfg->csc_cfg = &dpu_csc10_rgb2yuv_601l;
311+
312+
/* enable 10 bit logic */
313+
switch (cdm_cfg->output_fmt->chroma_sample) {
314+
case DPU_CHROMA_RGB:
315+
cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
316+
cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
317+
break;
318+
case DPU_CHROMA_H2V1:
319+
cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
320+
cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
321+
break;
322+
case DPU_CHROMA_420:
323+
cdm_cfg->h_cdwn_type = CDM_CDWN_COSITE;
324+
cdm_cfg->v_cdwn_type = CDM_CDWN_OFFSITE;
325+
break;
326+
case DPU_CHROMA_H1V2:
327+
default:
328+
DPU_ERROR("[enc:%d] unsupported chroma sampling type\n",
329+
DRMID(phys_enc->parent));
330+
cdm_cfg->h_cdwn_type = CDM_CDWN_DISABLE;
331+
cdm_cfg->v_cdwn_type = CDM_CDWN_DISABLE;
332+
break;
333+
}
334+
335+
DPU_DEBUG("[enc:%d] cdm_enable:%d,%d,%X,%d,%d,%d,%d]\n",
336+
DRMID(phys_enc->parent), cdm_cfg->output_width,
337+
cdm_cfg->output_height, cdm_cfg->output_fmt->base.pixel_format,
338+
cdm_cfg->output_type, cdm_cfg->output_bit_depth,
339+
cdm_cfg->h_cdwn_type, cdm_cfg->v_cdwn_type);
340+
341+
if (hw_cdm->ops.enable) {
342+
cdm_cfg->pp_id = hw_pp->idx;
343+
ret = hw_cdm->ops.enable(hw_cdm, cdm_cfg);
344+
if (ret < 0) {
345+
DPU_ERROR("[enc:%d] failed to enable CDM; ret:%d\n",
346+
DRMID(phys_enc->parent), ret);
347+
return;
348+
}
349+
}
350+
}
351+
262352
/**
263353
* dpu_encoder_phys_wb_atomic_check - verify and fixup given atomic states
264354
* @phys_enc: Pointer to physical encoder
@@ -375,8 +465,9 @@ static void dpu_encoder_phys_wb_setup(
375465

376466
dpu_encoder_phys_wb_setup_fb(phys_enc, fb);
377467

378-
dpu_encoder_phys_wb_setup_ctl(phys_enc);
468+
dpu_encoder_helper_phys_setup_cdm(phys_enc);
379469

470+
dpu_encoder_phys_wb_setup_ctl(phys_enc);
380471
}
381472

382473
/**

drivers/gpu/drm/msm/disp/dpu1/dpu_hw_util.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@
1919
#define MISR_CTRL_STATUS_CLEAR BIT(10)
2020
#define MISR_CTRL_FREE_RUN_MASK BIT(31)
2121

22+
#define TO_S15D16(_x_)((_x_) << 7)
23+
2224
static const struct dpu_csc_cfg dpu_csc_YUV2RGB_601L = {
2325
{
2426
/* S15.16 format */
@@ -49,6 +51,18 @@ static const struct dpu_csc_cfg dpu_csc10_YUV2RGB_601L = {
4951
{ 0x00, 0x3ff, 0x00, 0x3ff, 0x00, 0x3ff,},
5052
};
5153

54+
static const struct dpu_csc_cfg dpu_csc10_rgb2yuv_601l = {
55+
{
56+
TO_S15D16(0x0083), TO_S15D16(0x0102), TO_S15D16(0x0032),
57+
TO_S15D16(0x1fb5), TO_S15D16(0x1f6c), TO_S15D16(0x00e1),
58+
TO_S15D16(0x00e1), TO_S15D16(0x1f45), TO_S15D16(0x1fdc)
59+
},
60+
{ 0x00, 0x00, 0x00 },
61+
{ 0x0040, 0x0200, 0x0200 },
62+
{ 0x000, 0x3ff, 0x000, 0x3ff, 0x000, 0x3ff },
63+
{ 0x040, 0x3ac, 0x040, 0x3c0, 0x040, 0x3c0 },
64+
};
65+
5266
/*
5367
* This is the common struct maintained by each sub block
5468
* for mapping the register offsets in this block to the

0 commit comments

Comments
 (0)