1 // SPDX-License-Identifier: GPL-2.0
3 * (C) COPYRIGHT 2018 ARM Limited. All rights reserved.
4 * Author: James.Qian.Wang <james.qian.wang@arm.com>
8 #include <drm/drm_print.h>
10 #include "komeda_kms.h"
11 #include "malidp_io.h"
12 #include "komeda_framebuffer.h"
14 static void get_resources_id(u32 hw_id
, u32
*pipe_id
, u32
*comp_id
)
16 u32 id
= BLOCK_INFO_BLK_ID(hw_id
);
19 switch (BLOCK_INFO_BLK_TYPE(hw_id
)) {
20 case D71_BLK_TYPE_LPU_WB_LAYER
:
21 id
= KOMEDA_COMPONENT_WB_LAYER
;
23 case D71_BLK_TYPE_CU_SPLITTER
:
24 id
= KOMEDA_COMPONENT_SPLITTER
;
26 case D71_BLK_TYPE_CU_SCALER
:
27 pipe
= id
/ D71_PIPELINE_MAX_SCALERS
;
28 id
%= D71_PIPELINE_MAX_SCALERS
;
29 id
+= KOMEDA_COMPONENT_SCALER0
;
32 id
+= KOMEDA_COMPONENT_COMPIZ0
;
34 case D71_BLK_TYPE_LPU_LAYER
:
35 pipe
= id
/ D71_PIPELINE_MAX_LAYERS
;
36 id
%= D71_PIPELINE_MAX_LAYERS
;
37 id
+= KOMEDA_COMPONENT_LAYER0
;
39 case D71_BLK_TYPE_DOU_IPS
:
40 id
+= KOMEDA_COMPONENT_IPS0
;
42 case D71_BLK_TYPE_CU_MERGER
:
43 id
= KOMEDA_COMPONENT_MERGER
;
45 case D71_BLK_TYPE_DOU
:
46 id
= KOMEDA_COMPONENT_TIMING_CTRLR
;
59 static u32
get_valid_inputs(struct block_header
*blk
)
61 u32 valid_inputs
= 0, comp_id
;
64 for (i
= 0; i
< PIPELINE_INFO_N_VALID_INPUTS(blk
->pipeline_info
); i
++) {
65 get_resources_id(blk
->input_ids
[i
], NULL
, &comp_id
);
66 if (comp_id
== 0xFFFFFFFF)
68 valid_inputs
|= BIT(comp_id
);
74 static void get_values_from_reg(void __iomem
*reg
, u32 offset
,
79 for (i
= 0; i
< count
; i
++) {
80 addr
= offset
+ (i
<< 2);
81 /* 0xA4 is WO register */
83 val
[i
] = malidp_read32(reg
, addr
);
89 static void dump_block_header(struct seq_file
*sf
, void __iomem
*reg
)
91 struct block_header hdr
;
92 u32 i
, n_input
, n_output
;
94 d71_read_block_header(reg
, &hdr
);
95 seq_printf(sf
, "BLOCK_INFO:\t\t0x%X\n", hdr
.block_info
);
96 seq_printf(sf
, "PIPELINE_INFO:\t\t0x%X\n", hdr
.pipeline_info
);
98 n_output
= PIPELINE_INFO_N_OUTPUTS(hdr
.pipeline_info
);
99 n_input
= PIPELINE_INFO_N_VALID_INPUTS(hdr
.pipeline_info
);
101 for (i
= 0; i
< n_input
; i
++)
102 seq_printf(sf
, "VALID_INPUT_ID%u:\t0x%X\n",
103 i
, hdr
.input_ids
[i
]);
105 for (i
= 0; i
< n_output
; i
++)
106 seq_printf(sf
, "OUTPUT_ID%u:\t\t0x%X\n",
107 i
, hdr
.output_ids
[i
]);
110 static u32
to_rot_ctrl(u32 rot
)
114 switch (rot
& DRM_MODE_ROTATE_MASK
) {
115 case DRM_MODE_ROTATE_0
:
116 lr_ctrl
|= L_ROT(L_ROT_R0
);
118 case DRM_MODE_ROTATE_90
:
119 lr_ctrl
|= L_ROT(L_ROT_R90
);
121 case DRM_MODE_ROTATE_180
:
122 lr_ctrl
|= L_ROT(L_ROT_R180
);
124 case DRM_MODE_ROTATE_270
:
125 lr_ctrl
|= L_ROT(L_ROT_R270
);
129 if (rot
& DRM_MODE_REFLECT_X
)
131 if (rot
& DRM_MODE_REFLECT_Y
)
137 static inline u32
to_d71_input_id(struct komeda_component_output
*output
)
139 struct komeda_component
*comp
= output
->component
;
141 return comp
? (comp
->hw_id
+ output
->output_port
) : 0;
144 static void d71_layer_disable(struct komeda_component
*c
)
146 malidp_write32_mask(c
->reg
, BLK_CONTROL
, L_EN
, 0);
149 static void d71_layer_update(struct komeda_component
*c
,
150 struct komeda_component_state
*state
)
152 struct komeda_layer_state
*st
= to_layer_st(state
);
153 struct drm_plane_state
*plane_st
= state
->plane
->state
;
154 struct drm_framebuffer
*fb
= plane_st
->fb
;
155 struct komeda_fb
*kfb
= to_kfb(fb
);
156 u32 __iomem
*reg
= c
->reg
;
157 u32 ctrl_mask
= L_EN
| L_ROT(L_ROT_R270
) | L_HFLIP
| L_VFLIP
| L_TBU_EN
;
158 u32 ctrl
= L_EN
| to_rot_ctrl(st
->rot
);
161 for (i
= 0; i
< fb
->format
->num_planes
; i
++) {
163 BLK_P0_PTR_LOW
+ i
* LAYER_PER_PLANE_REGS
* 4,
164 lower_32_bits(st
->addr
[i
]));
166 BLK_P0_PTR_HIGH
+ i
* LAYER_PER_PLANE_REGS
* 4,
167 upper_32_bits(st
->addr
[i
]));
172 BLK_P0_STRIDE
+ i
* LAYER_PER_PLANE_REGS
* 4,
173 fb
->pitches
[i
] & 0xFFFF);
176 malidp_write32(reg
, LAYER_FMT
, kfb
->format_caps
->hw_id
);
177 malidp_write32(reg
, BLK_IN_SIZE
, HV_SIZE(st
->hsize
, st
->vsize
));
179 malidp_write32_mask(reg
, BLK_CONTROL
, ctrl_mask
, ctrl
);
182 static void d71_layer_dump(struct komeda_component
*c
, struct seq_file
*sf
)
188 get_values_from_reg(c
->reg
, LAYER_INFO
, 1, &v
[14]);
197 rgb2rgb
= !!(v
[14] & L_INFO_CM
);
199 dump_block_header(sf
, c
->reg
);
201 seq_printf(sf
, "%sLAYER_INFO:\t\t0x%X\n", prefix
, v
[14]);
203 get_values_from_reg(c
->reg
, 0xD0, 1, v
);
204 seq_printf(sf
, "%sCONTROL:\t\t0x%X\n", prefix
, v
[0]);
206 get_values_from_reg(c
->reg
, 0xD4, 1, v
);
207 seq_printf(sf
, "LR_RICH_CONTROL:\t0x%X\n", v
[0]);
209 get_values_from_reg(c
->reg
, 0xD8, 4, v
);
210 seq_printf(sf
, "%sFORMAT:\t\t0x%X\n", prefix
, v
[0]);
211 seq_printf(sf
, "%sIT_COEFFTAB:\t\t0x%X\n", prefix
, v
[1]);
212 seq_printf(sf
, "%sIN_SIZE:\t\t0x%X\n", prefix
, v
[2]);
213 seq_printf(sf
, "%sPALPHA:\t\t0x%X\n", prefix
, v
[3]);
215 get_values_from_reg(c
->reg
, 0x100, 3, v
);
216 seq_printf(sf
, "%sP0_PTR_LOW:\t\t0x%X\n", prefix
, v
[0]);
217 seq_printf(sf
, "%sP0_PTR_HIGH:\t\t0x%X\n", prefix
, v
[1]);
218 seq_printf(sf
, "%sP0_STRIDE:\t\t0x%X\n", prefix
, v
[2]);
220 get_values_from_reg(c
->reg
, 0x110, 2, v
);
221 seq_printf(sf
, "%sP1_PTR_LOW:\t\t0x%X\n", prefix
, v
[0]);
222 seq_printf(sf
, "%sP1_PTR_HIGH:\t\t0x%X\n", prefix
, v
[1]);
224 get_values_from_reg(c
->reg
, 0x118, 1, v
);
225 seq_printf(sf
, "LR_P1_STRIDE:\t\t0x%X\n", v
[0]);
227 get_values_from_reg(c
->reg
, 0x120, 2, v
);
228 seq_printf(sf
, "LR_P2_PTR_LOW:\t\t0x%X\n", v
[0]);
229 seq_printf(sf
, "LR_P2_PTR_HIGH:\t\t0x%X\n", v
[1]);
231 get_values_from_reg(c
->reg
, 0x130, 12, v
);
232 for (i
= 0; i
< 12; i
++)
233 seq_printf(sf
, "LR_YUV_RGB_COEFF%u:\t0x%X\n", i
, v
[i
]);
237 get_values_from_reg(c
->reg
, LAYER_RGB_RGB_COEFF0
, 12, v
);
238 for (i
= 0; i
< 12; i
++)
239 seq_printf(sf
, "LS_RGB_RGB_COEFF%u:\t0x%X\n", i
, v
[i
]);
242 get_values_from_reg(c
->reg
, 0x160, 3, v
);
243 seq_printf(sf
, "%sAD_CONTROL:\t\t0x%X\n", prefix
, v
[0]);
244 seq_printf(sf
, "%sAD_H_CROP:\t\t0x%X\n", prefix
, v
[1]);
245 seq_printf(sf
, "%sAD_V_CROP:\t\t0x%X\n", prefix
, v
[2]);
248 static struct komeda_component_funcs d71_layer_funcs
= {
249 .update
= d71_layer_update
,
250 .disable
= d71_layer_disable
,
251 .dump_register
= d71_layer_dump
,
254 static int d71_layer_init(struct d71_dev
*d71
,
255 struct block_header
*blk
, u32 __iomem
*reg
)
257 struct komeda_component
*c
;
258 struct komeda_layer
*layer
;
259 u32 pipe_id
, layer_id
, layer_info
;
261 get_resources_id(blk
->block_info
, &pipe_id
, &layer_id
);
262 c
= komeda_component_add(&d71
->pipes
[pipe_id
]->base
, sizeof(*layer
),
264 BLOCK_INFO_INPUT_ID(blk
->block_info
),
266 get_valid_inputs(blk
),
267 1, reg
, "LPU%d_LAYER%d", pipe_id
, layer_id
);
269 DRM_ERROR("Failed to add layer component\n");
274 layer_info
= malidp_read32(reg
, LAYER_INFO
);
276 if (layer_info
& L_INFO_RF
)
277 layer
->layer_type
= KOMEDA_FMT_RICH_LAYER
;
279 layer
->layer_type
= KOMEDA_FMT_SIMPLE_LAYER
;
281 set_range(&layer
->hsize_in
, 4, d71
->max_line_size
);
282 set_range(&layer
->vsize_in
, 4, d71
->max_vsize
);
284 malidp_write32(reg
, LAYER_PALPHA
, D71_PALPHA_DEF_MAP
);
286 layer
->supported_rots
= DRM_MODE_ROTATE_MASK
| DRM_MODE_REFLECT_MASK
;
291 static int d71_wb_layer_init(struct d71_dev
*d71
,
292 struct block_header
*blk
, u32 __iomem
*reg
)
294 DRM_DEBUG("Detect D71_Wb_Layer.\n");
299 static void d71_component_disable(struct komeda_component
*c
)
301 u32 __iomem
*reg
= c
->reg
;
304 malidp_write32(reg
, BLK_CONTROL
, 0);
306 for (i
= 0; i
< c
->max_active_inputs
; i
++)
307 malidp_write32(reg
, BLK_INPUT_ID0
+ (i
<< 2), 0);
310 static void compiz_enable_input(u32 __iomem
*id_reg
,
311 u32 __iomem
*cfg_reg
,
313 struct komeda_compiz_input_cfg
*cin
)
315 u32 ctrl
= CU_INPUT_CTRL_EN
;
316 u8 blend
= cin
->pixel_blend_mode
;
318 if (blend
== DRM_MODE_BLEND_PIXEL_NONE
)
319 ctrl
|= CU_INPUT_CTRL_PAD
;
320 else if (blend
== DRM_MODE_BLEND_PREMULTI
)
321 ctrl
|= CU_INPUT_CTRL_PMUL
;
323 ctrl
|= CU_INPUT_CTRL_ALPHA(cin
->layer_alpha
);
325 malidp_write32(id_reg
, BLK_INPUT_ID0
, input_hw_id
);
327 malidp_write32(cfg_reg
, CU_INPUT0_SIZE
,
328 HV_SIZE(cin
->hsize
, cin
->vsize
));
329 malidp_write32(cfg_reg
, CU_INPUT0_OFFSET
,
330 HV_OFFSET(cin
->hoffset
, cin
->voffset
));
331 malidp_write32(cfg_reg
, CU_INPUT0_CONTROL
, ctrl
);
334 static void d71_compiz_update(struct komeda_component
*c
,
335 struct komeda_component_state
*state
)
337 struct komeda_compiz_state
*st
= to_compiz_st(state
);
338 u32 __iomem
*reg
= c
->reg
;
339 u32 __iomem
*id_reg
, *cfg_reg
;
340 u32 index
, input_hw_id
;
342 for_each_changed_input(state
, index
) {
343 id_reg
= reg
+ index
;
344 cfg_reg
= reg
+ index
* CU_PER_INPUT_REGS
;
345 input_hw_id
= to_d71_input_id(&state
->inputs
[index
]);
346 if (state
->active_inputs
& BIT(index
)) {
347 compiz_enable_input(id_reg
, cfg_reg
,
348 input_hw_id
, &st
->cins
[index
]);
350 malidp_write32(id_reg
, BLK_INPUT_ID0
, 0);
351 malidp_write32(cfg_reg
, CU_INPUT0_CONTROL
, 0);
355 malidp_write32(reg
, BLK_SIZE
, HV_SIZE(st
->hsize
, st
->vsize
));
358 static void d71_compiz_dump(struct komeda_component
*c
, struct seq_file
*sf
)
362 dump_block_header(sf
, c
->reg
);
364 get_values_from_reg(c
->reg
, 0x80, 5, v
);
365 for (i
= 0; i
< 5; i
++)
366 seq_printf(sf
, "CU_INPUT_ID%u:\t\t0x%X\n", i
, v
[i
]);
368 get_values_from_reg(c
->reg
, 0xA0, 5, v
);
369 seq_printf(sf
, "CU_IRQ_RAW_STATUS:\t0x%X\n", v
[0]);
370 seq_printf(sf
, "CU_IRQ_CLEAR:\t\t0x%X\n", v
[1]);
371 seq_printf(sf
, "CU_IRQ_MASK:\t\t0x%X\n", v
[2]);
372 seq_printf(sf
, "CU_IRQ_STATUS:\t\t0x%X\n", v
[3]);
373 seq_printf(sf
, "CU_STATUS:\t\t0x%X\n", v
[4]);
375 get_values_from_reg(c
->reg
, 0xD0, 2, v
);
376 seq_printf(sf
, "CU_CONTROL:\t\t0x%X\n", v
[0]);
377 seq_printf(sf
, "CU_SIZE:\t\t0x%X\n", v
[1]);
379 get_values_from_reg(c
->reg
, 0xDC, 1, v
);
380 seq_printf(sf
, "CU_BG_COLOR:\t\t0x%X\n", v
[0]);
382 for (i
= 0, v
[4] = 0xE0; i
< 5; i
++, v
[4] += 0x10) {
383 get_values_from_reg(c
->reg
, v
[4], 3, v
);
384 seq_printf(sf
, "CU_INPUT%u_SIZE:\t\t0x%X\n", i
, v
[0]);
385 seq_printf(sf
, "CU_INPUT%u_OFFSET:\t0x%X\n", i
, v
[1]);
386 seq_printf(sf
, "CU_INPUT%u_CONTROL:\t0x%X\n", i
, v
[2]);
389 get_values_from_reg(c
->reg
, 0x130, 2, v
);
390 seq_printf(sf
, "CU_USER_LOW:\t\t0x%X\n", v
[0]);
391 seq_printf(sf
, "CU_USER_HIGH:\t\t0x%X\n", v
[1]);
394 static struct komeda_component_funcs d71_compiz_funcs
= {
395 .update
= d71_compiz_update
,
396 .disable
= d71_component_disable
,
397 .dump_register
= d71_compiz_dump
,
400 static int d71_compiz_init(struct d71_dev
*d71
,
401 struct block_header
*blk
, u32 __iomem
*reg
)
403 struct komeda_component
*c
;
404 struct komeda_compiz
*compiz
;
405 u32 pipe_id
, comp_id
;
407 get_resources_id(blk
->block_info
, &pipe_id
, &comp_id
);
409 c
= komeda_component_add(&d71
->pipes
[pipe_id
]->base
, sizeof(*compiz
),
411 BLOCK_INFO_INPUT_ID(blk
->block_info
),
413 CU_NUM_INPUT_IDS
, get_valid_inputs(blk
),
414 CU_NUM_OUTPUT_IDS
, reg
,
419 compiz
= to_compiz(c
);
421 set_range(&compiz
->hsize
, D71_MIN_LINE_SIZE
, d71
->max_line_size
);
422 set_range(&compiz
->vsize
, D71_MIN_VERTICAL_SIZE
, d71
->max_vsize
);
427 static void d71_improc_update(struct komeda_component
*c
,
428 struct komeda_component_state
*state
)
430 struct komeda_improc_state
*st
= to_improc_st(state
);
431 u32 __iomem
*reg
= c
->reg
;
432 u32 index
, input_hw_id
;
434 for_each_changed_input(state
, index
) {
435 input_hw_id
= state
->active_inputs
& BIT(index
) ?
436 to_d71_input_id(&state
->inputs
[index
]) : 0;
437 malidp_write32(reg
, BLK_INPUT_ID0
+ index
* 4, input_hw_id
);
440 malidp_write32(reg
, BLK_SIZE
, HV_SIZE(st
->hsize
, st
->vsize
));
443 static void d71_improc_dump(struct komeda_component
*c
, struct seq_file
*sf
)
447 dump_block_header(sf
, c
->reg
);
449 get_values_from_reg(c
->reg
, 0x80, 2, v
);
450 seq_printf(sf
, "IPS_INPUT_ID0:\t\t0x%X\n", v
[0]);
451 seq_printf(sf
, "IPS_INPUT_ID1:\t\t0x%X\n", v
[1]);
453 get_values_from_reg(c
->reg
, 0xC0, 1, v
);
454 seq_printf(sf
, "IPS_INFO:\t\t0x%X\n", v
[0]);
456 get_values_from_reg(c
->reg
, 0xD0, 3, v
);
457 seq_printf(sf
, "IPS_CONTROL:\t\t0x%X\n", v
[0]);
458 seq_printf(sf
, "IPS_SIZE:\t\t0x%X\n", v
[1]);
459 seq_printf(sf
, "IPS_DEPTH:\t\t0x%X\n", v
[2]);
461 get_values_from_reg(c
->reg
, 0x130, 12, v
);
462 for (i
= 0; i
< 12; i
++)
463 seq_printf(sf
, "IPS_RGB_RGB_COEFF%u:\t0x%X\n", i
, v
[i
]);
465 get_values_from_reg(c
->reg
, 0x170, 12, v
);
466 for (i
= 0; i
< 12; i
++)
467 seq_printf(sf
, "IPS_RGB_YUV_COEFF%u:\t0x%X\n", i
, v
[i
]);
470 static struct komeda_component_funcs d71_improc_funcs
= {
471 .update
= d71_improc_update
,
472 .disable
= d71_component_disable
,
473 .dump_register
= d71_improc_dump
,
476 static int d71_improc_init(struct d71_dev
*d71
,
477 struct block_header
*blk
, u32 __iomem
*reg
)
479 struct komeda_component
*c
;
480 struct komeda_improc
*improc
;
481 u32 pipe_id
, comp_id
, value
;
483 get_resources_id(blk
->block_info
, &pipe_id
, &comp_id
);
485 c
= komeda_component_add(&d71
->pipes
[pipe_id
]->base
, sizeof(*improc
),
487 BLOCK_INFO_INPUT_ID(blk
->block_info
),
488 &d71_improc_funcs
, IPS_NUM_INPUT_IDS
,
489 get_valid_inputs(blk
),
490 IPS_NUM_OUTPUT_IDS
, reg
, "DOU%d_IPS", pipe_id
);
492 DRM_ERROR("Failed to add improc component\n");
496 improc
= to_improc(c
);
497 improc
->supported_color_depths
= BIT(8) | BIT(10);
498 improc
->supported_color_formats
= DRM_COLOR_FORMAT_RGB444
|
499 DRM_COLOR_FORMAT_YCRCB444
|
500 DRM_COLOR_FORMAT_YCRCB422
;
501 value
= malidp_read32(reg
, BLK_INFO
);
502 if (value
& IPS_INFO_CHD420
)
503 improc
->supported_color_formats
|= DRM_COLOR_FORMAT_YCRCB420
;
505 improc
->supports_csc
= true;
506 improc
->supports_gamma
= true;
511 static void d71_timing_ctrlr_disable(struct komeda_component
*c
)
513 malidp_write32_mask(c
->reg
, BLK_CONTROL
, BS_CTRL_EN
, 0);
516 static void d71_timing_ctrlr_update(struct komeda_component
*c
,
517 struct komeda_component_state
*state
)
519 struct drm_crtc_state
*crtc_st
= state
->crtc
->state
;
520 u32 __iomem
*reg
= c
->reg
;
524 drm_display_mode_to_videomode(&crtc_st
->adjusted_mode
, &vm
);
526 malidp_write32(reg
, BS_ACTIVESIZE
, HV_SIZE(vm
.hactive
, vm
.vactive
));
527 malidp_write32(reg
, BS_HINTERVALS
, BS_H_INTVALS(vm
.hfront_porch
,
529 malidp_write32(reg
, BS_VINTERVALS
, BS_V_INTVALS(vm
.vfront_porch
,
532 value
= BS_SYNC_VSW(vm
.vsync_len
) | BS_SYNC_HSW(vm
.hsync_len
);
533 value
|= vm
.flags
& DISPLAY_FLAGS_VSYNC_HIGH
? BS_SYNC_VSP
: 0;
534 value
|= vm
.flags
& DISPLAY_FLAGS_HSYNC_HIGH
? BS_SYNC_HSP
: 0;
535 malidp_write32(reg
, BS_SYNC
, value
);
537 malidp_write32(reg
, BS_PROG_LINE
, D71_DEFAULT_PREPRETCH_LINE
- 1);
538 malidp_write32(reg
, BS_PREFETCH_LINE
, D71_DEFAULT_PREPRETCH_LINE
);
540 /* configure bs control register */
541 value
= BS_CTRL_EN
| BS_CTRL_VM
;
543 malidp_write32(reg
, BLK_CONTROL
, value
);
546 static void d71_timing_ctrlr_dump(struct komeda_component
*c
,
551 dump_block_header(sf
, c
->reg
);
553 get_values_from_reg(c
->reg
, 0xC0, 1, v
);
554 seq_printf(sf
, "BS_INFO:\t\t0x%X\n", v
[0]);
556 get_values_from_reg(c
->reg
, 0xD0, 8, v
);
557 seq_printf(sf
, "BS_CONTROL:\t\t0x%X\n", v
[0]);
558 seq_printf(sf
, "BS_PROG_LINE:\t\t0x%X\n", v
[1]);
559 seq_printf(sf
, "BS_PREFETCH_LINE:\t0x%X\n", v
[2]);
560 seq_printf(sf
, "BS_BG_COLOR:\t\t0x%X\n", v
[3]);
561 seq_printf(sf
, "BS_ACTIVESIZE:\t\t0x%X\n", v
[4]);
562 seq_printf(sf
, "BS_HINTERVALS:\t\t0x%X\n", v
[5]);
563 seq_printf(sf
, "BS_VINTERVALS:\t\t0x%X\n", v
[6]);
564 seq_printf(sf
, "BS_SYNC:\t\t0x%X\n", v
[7]);
566 get_values_from_reg(c
->reg
, 0x100, 3, v
);
567 seq_printf(sf
, "BS_DRIFT_TO:\t\t0x%X\n", v
[0]);
568 seq_printf(sf
, "BS_FRAME_TO:\t\t0x%X\n", v
[1]);
569 seq_printf(sf
, "BS_TE_TO:\t\t0x%X\n", v
[2]);
571 get_values_from_reg(c
->reg
, 0x110, 3, v
);
572 for (i
= 0; i
< 3; i
++)
573 seq_printf(sf
, "BS_T%u_INTERVAL:\t\t0x%X\n", i
, v
[i
]);
575 get_values_from_reg(c
->reg
, 0x120, 5, v
);
576 for (i
= 0; i
< 2; i
++) {
577 seq_printf(sf
, "BS_CRC%u_LOW:\t\t0x%X\n", i
, v
[i
<< 1]);
578 seq_printf(sf
, "BS_CRC%u_HIGH:\t\t0x%X\n", i
, v
[(i
<< 1) + 1]);
580 seq_printf(sf
, "BS_USER:\t\t0x%X\n", v
[4]);
583 static struct komeda_component_funcs d71_timing_ctrlr_funcs
= {
584 .update
= d71_timing_ctrlr_update
,
585 .disable
= d71_timing_ctrlr_disable
,
586 .dump_register
= d71_timing_ctrlr_dump
,
589 static int d71_timing_ctrlr_init(struct d71_dev
*d71
,
590 struct block_header
*blk
, u32 __iomem
*reg
)
592 struct komeda_component
*c
;
593 struct komeda_timing_ctrlr
*ctrlr
;
594 u32 pipe_id
, comp_id
;
596 get_resources_id(blk
->block_info
, &pipe_id
, &comp_id
);
598 c
= komeda_component_add(&d71
->pipes
[pipe_id
]->base
, sizeof(*ctrlr
),
599 KOMEDA_COMPONENT_TIMING_CTRLR
,
600 BLOCK_INFO_INPUT_ID(blk
->block_info
),
601 &d71_timing_ctrlr_funcs
,
602 1, BIT(KOMEDA_COMPONENT_IPS0
+ pipe_id
),
603 BS_NUM_OUTPUT_IDS
, reg
, "DOU%d_BS", pipe_id
);
605 DRM_ERROR("Failed to add display_ctrl component\n");
611 ctrlr
->supports_dual_link
= true;
616 int d71_probe_block(struct d71_dev
*d71
,
617 struct block_header
*blk
, u32 __iomem
*reg
)
619 struct d71_pipeline
*pipe
;
620 int blk_id
= BLOCK_INFO_BLK_ID(blk
->block_info
);
624 switch (BLOCK_INFO_BLK_TYPE(blk
->block_info
)) {
625 case D71_BLK_TYPE_GCU
:
628 case D71_BLK_TYPE_LPU
:
629 pipe
= d71
->pipes
[blk_id
];
630 pipe
->lpu_addr
= reg
;
633 case D71_BLK_TYPE_LPU_LAYER
:
634 err
= d71_layer_init(d71
, blk
, reg
);
637 case D71_BLK_TYPE_LPU_WB_LAYER
:
638 err
= d71_wb_layer_init(d71
, blk
, reg
);
641 case D71_BLK_TYPE_CU
:
642 pipe
= d71
->pipes
[blk_id
];
644 err
= d71_compiz_init(d71
, blk
, reg
);
647 case D71_BLK_TYPE_CU_SPLITTER
:
648 case D71_BLK_TYPE_CU_SCALER
:
649 case D71_BLK_TYPE_CU_MERGER
:
652 case D71_BLK_TYPE_DOU
:
653 pipe
= d71
->pipes
[blk_id
];
654 pipe
->dou_addr
= reg
;
657 case D71_BLK_TYPE_DOU_IPS
:
658 err
= d71_improc_init(d71
, blk
, reg
);
661 case D71_BLK_TYPE_DOU_FT_COEFF
:
662 pipe
= d71
->pipes
[blk_id
];
663 pipe
->dou_ft_coeff_addr
= reg
;
666 case D71_BLK_TYPE_DOU_BS
:
667 err
= d71_timing_ctrlr_init(d71
, blk
, reg
);
670 case D71_BLK_TYPE_GLB_LT_COEFF
:
673 case D71_BLK_TYPE_GLB_SCL_COEFF
:
674 d71
->glb_scl_coeff_addr
[blk_id
] = reg
;
678 DRM_ERROR("Unknown block (block_info: 0x%x) is found\n",