1 // SPDX-License-Identifier: GPL-2.0-only
3 * Hisilicon Hi6220 SoC ADE(Advanced Display Engine)'s crtc&plane driver
5 * Copyright (c) 2016 Linaro Limited.
6 * Copyright (c) 2014-2016 Hisilicon Limited.
9 * Xinliang Liu <z.liuxinliang@hisilicon.com>
10 * Xinliang Liu <xinliang.liu@linaro.org>
11 * Xinwei Kong <kong.kongxinwei@hisilicon.com>
14 #include <linux/bitops.h>
15 #include <linux/clk.h>
16 #include <linux/mfd/syscon.h>
17 #include <linux/platform_device.h>
18 #include <linux/regmap.h>
19 #include <linux/reset.h>
21 #include <video/display_timing.h>
23 #include <drm/drm_atomic.h>
24 #include <drm/drm_atomic_helper.h>
25 #include <drm/drm_crtc.h>
26 #include <drm/drm_drv.h>
27 #include <drm/drm_fb_cma_helper.h>
28 #include <drm/drm_fourcc.h>
29 #include <drm/drm_gem_cma_helper.h>
30 #include <drm/drm_plane_helper.h>
31 #include <drm/drm_probe_helper.h>
32 #include <drm/drm_vblank.h>
33 #include <drm/drm_gem_framebuffer_helper.h>
35 #include "kirin_drm_drv.h"
36 #include "kirin_ade_reg.h"
38 #define OUT_OVLY ADE_OVLY2 /* output overlay compositor */
44 struct regmap
*noc_regmap
;
45 struct clk
*ade_core_clk
;
46 struct clk
*media_noc_clk
;
47 struct clk
*ade_pix_clk
;
48 struct reset_control
*reset
;
49 struct work_struct display_reset_wq
;
53 struct drm_crtc
*crtc
;
56 static const struct kirin_format ade_formats
[] = {
58 { DRM_FORMAT_RGB565
, ADE_RGB_565
},
59 { DRM_FORMAT_BGR565
, ADE_BGR_565
},
61 { DRM_FORMAT_RGB888
, ADE_RGB_888
},
62 { DRM_FORMAT_BGR888
, ADE_BGR_888
},
64 { DRM_FORMAT_XRGB8888
, ADE_XRGB_8888
},
65 { DRM_FORMAT_XBGR8888
, ADE_XBGR_8888
},
66 { DRM_FORMAT_RGBA8888
, ADE_RGBA_8888
},
67 { DRM_FORMAT_BGRA8888
, ADE_BGRA_8888
},
68 { DRM_FORMAT_ARGB8888
, ADE_ARGB_8888
},
69 { DRM_FORMAT_ABGR8888
, ADE_ABGR_8888
},
72 static const u32 channel_formats
[] = {
74 DRM_FORMAT_RGB565
, DRM_FORMAT_BGR565
, DRM_FORMAT_RGB888
,
75 DRM_FORMAT_BGR888
, DRM_FORMAT_XRGB8888
, DRM_FORMAT_XBGR8888
,
76 DRM_FORMAT_RGBA8888
, DRM_FORMAT_BGRA8888
, DRM_FORMAT_ARGB8888
,
80 /* convert from fourcc format to ade format */
81 static u32
ade_get_format(u32 pixel_format
)
85 for (i
= 0; i
< ARRAY_SIZE(ade_formats
); i
++)
86 if (ade_formats
[i
].pixel_format
== pixel_format
)
87 return ade_formats
[i
].hw_format
;
90 DRM_ERROR("Not found pixel format!!fourcc_format= %d\n",
92 return ADE_FORMAT_UNSUPPORT
;
95 static void ade_update_reload_bit(void __iomem
*base
, u32 bit_num
, u32 val
)
97 u32 bit_ofst
, reg_num
;
99 bit_ofst
= bit_num
% 32;
100 reg_num
= bit_num
/ 32;
102 ade_update_bits(base
+ ADE_RELOAD_DIS(reg_num
), bit_ofst
,
106 static u32
ade_read_reload_bit(void __iomem
*base
, u32 bit_num
)
108 u32 tmp
, bit_ofst
, reg_num
;
110 bit_ofst
= bit_num
% 32;
111 reg_num
= bit_num
/ 32;
113 tmp
= readl(base
+ ADE_RELOAD_DIS(reg_num
));
114 return !!(BIT(bit_ofst
) & tmp
);
117 static void ade_init(struct ade_hw_ctx
*ctx
)
119 void __iomem
*base
= ctx
->base
;
121 /* enable clk gate */
122 ade_update_bits(base
+ ADE_CTRL1
, AUTO_CLK_GATE_EN_OFST
,
123 AUTO_CLK_GATE_EN
, ADE_ENABLE
);
125 writel(0, base
+ ADE_OVLY1_TRANS_CFG
);
126 writel(0, base
+ ADE_OVLY_CTL
);
127 writel(0, base
+ ADE_OVLYX_CTL(OUT_OVLY
));
128 /* clear reset and reload regs */
129 writel(MASK(32), base
+ ADE_SOFT_RST_SEL(0));
130 writel(MASK(32), base
+ ADE_SOFT_RST_SEL(1));
131 writel(MASK(32), base
+ ADE_RELOAD_DIS(0));
132 writel(MASK(32), base
+ ADE_RELOAD_DIS(1));
134 * for video mode, all the ade registers should
135 * become effective at frame end.
137 ade_update_bits(base
+ ADE_CTRL
, FRM_END_START_OFST
,
138 FRM_END_START_MASK
, REG_EFFECTIVE_IN_ADEEN_FRMEND
);
139 ade_update_bits(base
+ LDI_INT_EN
, UNDERFLOW_INT_EN_OFST
, MASK(1), 1);
142 static bool ade_crtc_mode_fixup(struct drm_crtc
*crtc
,
143 const struct drm_display_mode
*mode
,
144 struct drm_display_mode
*adjusted_mode
)
146 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
147 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
149 adjusted_mode
->clock
=
150 clk_round_rate(ctx
->ade_pix_clk
, mode
->clock
* 1000) / 1000;
155 static void ade_set_pix_clk(struct ade_hw_ctx
*ctx
,
156 struct drm_display_mode
*mode
,
157 struct drm_display_mode
*adj_mode
)
159 u32 clk_Hz
= mode
->clock
* 1000;
163 * Success should be guaranteed in mode_valid call back,
164 * so failure shouldn't happen here
166 ret
= clk_set_rate(ctx
->ade_pix_clk
, clk_Hz
);
168 DRM_ERROR("failed to set pixel clk %dHz (%d)\n", clk_Hz
, ret
);
169 adj_mode
->clock
= clk_get_rate(ctx
->ade_pix_clk
) / 1000;
172 static void ade_ldi_set_mode(struct ade_hw_ctx
*ctx
,
173 struct drm_display_mode
*mode
,
174 struct drm_display_mode
*adj_mode
)
176 void __iomem
*base
= ctx
->base
;
177 u32 width
= mode
->hdisplay
;
178 u32 height
= mode
->vdisplay
;
179 u32 hfp
, hbp
, hsw
, vfp
, vbp
, vsw
;
182 plr_flags
= (mode
->flags
& DRM_MODE_FLAG_NVSYNC
) ? FLAG_NVSYNC
: 0;
183 plr_flags
|= (mode
->flags
& DRM_MODE_FLAG_NHSYNC
) ? FLAG_NHSYNC
: 0;
184 hfp
= mode
->hsync_start
- mode
->hdisplay
;
185 hbp
= mode
->htotal
- mode
->hsync_end
;
186 hsw
= mode
->hsync_end
- mode
->hsync_start
;
187 vfp
= mode
->vsync_start
- mode
->vdisplay
;
188 vbp
= mode
->vtotal
- mode
->vsync_end
;
189 vsw
= mode
->vsync_end
- mode
->vsync_start
;
191 DRM_DEBUG_DRIVER("vsw exceeded 15\n");
195 writel((hbp
<< HBP_OFST
) | hfp
, base
+ LDI_HRZ_CTRL0
);
196 /* the configured value is actual value - 1 */
197 writel(hsw
- 1, base
+ LDI_HRZ_CTRL1
);
198 writel((vbp
<< VBP_OFST
) | vfp
, base
+ LDI_VRT_CTRL0
);
199 /* the configured value is actual value - 1 */
200 writel(vsw
- 1, base
+ LDI_VRT_CTRL1
);
201 /* the configured value is actual value - 1 */
202 writel(((height
- 1) << VSIZE_OFST
) | (width
- 1),
203 base
+ LDI_DSP_SIZE
);
204 writel(plr_flags
, base
+ LDI_PLR_CTRL
);
206 /* set overlay compositor output size */
207 writel(((width
- 1) << OUTPUT_XSIZE_OFST
) | (height
- 1),
208 base
+ ADE_OVLY_OUTPUT_SIZE(OUT_OVLY
));
211 writel(CTRAN_BYPASS_ON
, base
+ ADE_CTRAN_DIS(ADE_CTRAN6
));
212 /* the configured value is actual value - 1 */
213 writel(width
* height
- 1, base
+ ADE_CTRAN_IMAGE_SIZE(ADE_CTRAN6
));
214 ade_update_reload_bit(base
, CTRAN_OFST
+ ADE_CTRAN6
, 0);
216 ade_set_pix_clk(ctx
, mode
, adj_mode
);
218 DRM_DEBUG_DRIVER("set mode: %dx%d\n", width
, height
);
221 static int ade_power_up(struct ade_hw_ctx
*ctx
)
225 ret
= clk_prepare_enable(ctx
->media_noc_clk
);
227 DRM_ERROR("failed to enable media_noc_clk (%d)\n", ret
);
231 ret
= reset_control_deassert(ctx
->reset
);
233 DRM_ERROR("failed to deassert reset\n");
237 ret
= clk_prepare_enable(ctx
->ade_core_clk
);
239 DRM_ERROR("failed to enable ade_core_clk (%d)\n", ret
);
244 ctx
->power_on
= true;
248 static void ade_power_down(struct ade_hw_ctx
*ctx
)
250 void __iomem
*base
= ctx
->base
;
252 writel(ADE_DISABLE
, base
+ LDI_CTRL
);
254 writel(DSI_PCLK_OFF
, base
+ LDI_HDMI_DSI_GT
);
256 clk_disable_unprepare(ctx
->ade_core_clk
);
257 reset_control_assert(ctx
->reset
);
258 clk_disable_unprepare(ctx
->media_noc_clk
);
259 ctx
->power_on
= false;
262 static void ade_set_medianoc_qos(struct ade_hw_ctx
*ctx
)
264 struct regmap
*map
= ctx
->noc_regmap
;
266 regmap_update_bits(map
, ADE0_QOSGENERATOR_MODE
,
267 QOSGENERATOR_MODE_MASK
, BYPASS_MODE
);
268 regmap_update_bits(map
, ADE0_QOSGENERATOR_EXTCONTROL
,
269 SOCKET_QOS_EN
, SOCKET_QOS_EN
);
271 regmap_update_bits(map
, ADE1_QOSGENERATOR_MODE
,
272 QOSGENERATOR_MODE_MASK
, BYPASS_MODE
);
273 regmap_update_bits(map
, ADE1_QOSGENERATOR_EXTCONTROL
,
274 SOCKET_QOS_EN
, SOCKET_QOS_EN
);
277 static int ade_crtc_enable_vblank(struct drm_crtc
*crtc
)
279 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
280 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
281 void __iomem
*base
= ctx
->base
;
284 (void)ade_power_up(ctx
);
286 ade_update_bits(base
+ LDI_INT_EN
, FRAME_END_INT_EN_OFST
,
292 static void ade_crtc_disable_vblank(struct drm_crtc
*crtc
)
294 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
295 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
296 void __iomem
*base
= ctx
->base
;
298 if (!ctx
->power_on
) {
299 DRM_ERROR("power is down! vblank disable fail\n");
303 ade_update_bits(base
+ LDI_INT_EN
, FRAME_END_INT_EN_OFST
,
307 static void drm_underflow_wq(struct work_struct
*work
)
309 struct ade_hw_ctx
*ctx
= container_of(work
, struct ade_hw_ctx
,
311 struct drm_device
*drm_dev
= ctx
->crtc
->dev
;
312 struct drm_atomic_state
*state
;
314 state
= drm_atomic_helper_suspend(drm_dev
);
315 drm_atomic_helper_resume(drm_dev
, state
);
318 static irqreturn_t
ade_irq_handler(int irq
, void *data
)
320 struct ade_hw_ctx
*ctx
= data
;
321 struct drm_crtc
*crtc
= ctx
->crtc
;
322 void __iomem
*base
= ctx
->base
;
325 status
= readl(base
+ LDI_MSK_INT
);
326 DRM_DEBUG_VBL("LDI IRQ: status=0x%X\n", status
);
329 if (status
& BIT(FRAME_END_INT_EN_OFST
)) {
330 ade_update_bits(base
+ LDI_INT_CLR
, FRAME_END_INT_EN_OFST
,
332 drm_crtc_handle_vblank(crtc
);
334 if (status
& BIT(UNDERFLOW_INT_EN_OFST
)) {
335 ade_update_bits(base
+ LDI_INT_CLR
, UNDERFLOW_INT_EN_OFST
,
337 DRM_ERROR("LDI underflow!");
338 schedule_work(&ctx
->display_reset_wq
);
344 static void ade_display_enable(struct ade_hw_ctx
*ctx
)
346 void __iomem
*base
= ctx
->base
;
347 u32 out_fmt
= LDI_OUT_RGB_888
;
349 /* enable output overlay compositor */
350 writel(ADE_ENABLE
, base
+ ADE_OVLYX_CTL(OUT_OVLY
));
351 ade_update_reload_bit(base
, OVLY_OFST
+ OUT_OVLY
, 0);
353 /* display source setting */
354 writel(DISP_SRC_OVLY2
, base
+ ADE_DISP_SRC_CFG
);
357 writel(ADE_ENABLE
, base
+ ADE_EN
);
359 writel(NORMAL_MODE
, base
+ LDI_WORK_MODE
);
360 writel((out_fmt
<< BPP_OFST
) | DATA_GATE_EN
| LDI_EN
,
363 writel(DSI_PCLK_ON
, base
+ LDI_HDMI_DSI_GT
);
367 static void ade_rdma_dump_regs(void __iomem
*base
, u32 ch
)
369 u32 reg_ctrl
, reg_addr
, reg_size
, reg_stride
, reg_space
, reg_en
;
372 reg_ctrl
= RD_CH_CTRL(ch
);
373 reg_addr
= RD_CH_ADDR(ch
);
374 reg_size
= RD_CH_SIZE(ch
);
375 reg_stride
= RD_CH_STRIDE(ch
);
376 reg_space
= RD_CH_SPACE(ch
);
377 reg_en
= RD_CH_EN(ch
);
379 val
= ade_read_reload_bit(base
, RDMA_OFST
+ ch
);
380 DRM_DEBUG_DRIVER("[rdma%d]: reload(%d)\n", ch
+ 1, val
);
381 val
= readl(base
+ reg_ctrl
);
382 DRM_DEBUG_DRIVER("[rdma%d]: reg_ctrl(0x%08x)\n", ch
+ 1, val
);
383 val
= readl(base
+ reg_addr
);
384 DRM_DEBUG_DRIVER("[rdma%d]: reg_addr(0x%08x)\n", ch
+ 1, val
);
385 val
= readl(base
+ reg_size
);
386 DRM_DEBUG_DRIVER("[rdma%d]: reg_size(0x%08x)\n", ch
+ 1, val
);
387 val
= readl(base
+ reg_stride
);
388 DRM_DEBUG_DRIVER("[rdma%d]: reg_stride(0x%08x)\n", ch
+ 1, val
);
389 val
= readl(base
+ reg_space
);
390 DRM_DEBUG_DRIVER("[rdma%d]: reg_space(0x%08x)\n", ch
+ 1, val
);
391 val
= readl(base
+ reg_en
);
392 DRM_DEBUG_DRIVER("[rdma%d]: reg_en(0x%08x)\n", ch
+ 1, val
);
395 static void ade_clip_dump_regs(void __iomem
*base
, u32 ch
)
399 val
= ade_read_reload_bit(base
, CLIP_OFST
+ ch
);
400 DRM_DEBUG_DRIVER("[clip%d]: reload(%d)\n", ch
+ 1, val
);
401 val
= readl(base
+ ADE_CLIP_DISABLE(ch
));
402 DRM_DEBUG_DRIVER("[clip%d]: reg_clip_disable(0x%08x)\n", ch
+ 1, val
);
403 val
= readl(base
+ ADE_CLIP_SIZE0(ch
));
404 DRM_DEBUG_DRIVER("[clip%d]: reg_clip_size0(0x%08x)\n", ch
+ 1, val
);
405 val
= readl(base
+ ADE_CLIP_SIZE1(ch
));
406 DRM_DEBUG_DRIVER("[clip%d]: reg_clip_size1(0x%08x)\n", ch
+ 1, val
);
409 static void ade_compositor_routing_dump_regs(void __iomem
*base
, u32 ch
)
411 u8 ovly_ch
= 0; /* TODO: Only primary plane now */
414 val
= readl(base
+ ADE_OVLY_CH_XY0(ovly_ch
));
415 DRM_DEBUG_DRIVER("[overlay ch%d]: reg_ch_xy0(0x%08x)\n", ovly_ch
, val
);
416 val
= readl(base
+ ADE_OVLY_CH_XY1(ovly_ch
));
417 DRM_DEBUG_DRIVER("[overlay ch%d]: reg_ch_xy1(0x%08x)\n", ovly_ch
, val
);
418 val
= readl(base
+ ADE_OVLY_CH_CTL(ovly_ch
));
419 DRM_DEBUG_DRIVER("[overlay ch%d]: reg_ch_ctl(0x%08x)\n", ovly_ch
, val
);
422 static void ade_dump_overlay_compositor_regs(void __iomem
*base
, u32 comp
)
426 val
= ade_read_reload_bit(base
, OVLY_OFST
+ comp
);
427 DRM_DEBUG_DRIVER("[overlay%d]: reload(%d)\n", comp
+ 1, val
);
428 writel(ADE_ENABLE
, base
+ ADE_OVLYX_CTL(comp
));
429 DRM_DEBUG_DRIVER("[overlay%d]: reg_ctl(0x%08x)\n", comp
+ 1, val
);
430 val
= readl(base
+ ADE_OVLY_CTL
);
431 DRM_DEBUG_DRIVER("ovly_ctl(0x%08x)\n", val
);
434 static void ade_dump_regs(void __iomem
*base
)
438 /* dump channel regs */
439 for (i
= 0; i
< ADE_CH_NUM
; i
++) {
441 ade_rdma_dump_regs(base
, i
);
444 ade_clip_dump_regs(base
, i
);
446 /* dump compositor routing regs */
447 ade_compositor_routing_dump_regs(base
, i
);
450 /* dump overlay compositor regs */
451 ade_dump_overlay_compositor_regs(base
, OUT_OVLY
);
454 static void ade_dump_regs(void __iomem
*base
) { }
457 static void ade_crtc_atomic_enable(struct drm_crtc
*crtc
,
458 struct drm_crtc_state
*old_state
)
460 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
461 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
467 if (!ctx
->power_on
) {
468 ret
= ade_power_up(ctx
);
473 ade_set_medianoc_qos(ctx
);
474 ade_display_enable(ctx
);
475 ade_dump_regs(ctx
->base
);
476 drm_crtc_vblank_on(crtc
);
477 kcrtc
->enable
= true;
480 static void ade_crtc_atomic_disable(struct drm_crtc
*crtc
,
481 struct drm_crtc_state
*old_state
)
483 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
484 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
489 drm_crtc_vblank_off(crtc
);
491 kcrtc
->enable
= false;
494 static void ade_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
496 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
497 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
498 struct drm_display_mode
*mode
= &crtc
->state
->mode
;
499 struct drm_display_mode
*adj_mode
= &crtc
->state
->adjusted_mode
;
502 (void)ade_power_up(ctx
);
503 ade_ldi_set_mode(ctx
, mode
, adj_mode
);
506 static void ade_crtc_atomic_begin(struct drm_crtc
*crtc
,
507 struct drm_crtc_state
*old_state
)
509 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
510 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
511 struct drm_display_mode
*mode
= &crtc
->state
->mode
;
512 struct drm_display_mode
*adj_mode
= &crtc
->state
->adjusted_mode
;
515 (void)ade_power_up(ctx
);
516 ade_ldi_set_mode(ctx
, mode
, adj_mode
);
519 static void ade_crtc_atomic_flush(struct drm_crtc
*crtc
,
520 struct drm_crtc_state
*old_state
)
523 struct kirin_crtc
*kcrtc
= to_kirin_crtc(crtc
);
524 struct ade_hw_ctx
*ctx
= kcrtc
->hw_ctx
;
525 struct drm_pending_vblank_event
*event
= crtc
->state
->event
;
526 void __iomem
*base
= ctx
->base
;
528 /* only crtc is enabled regs take effect */
531 /* flush ade registers */
532 writel(ADE_ENABLE
, base
+ ADE_EN
);
536 crtc
->state
->event
= NULL
;
538 spin_lock_irq(&crtc
->dev
->event_lock
);
539 if (drm_crtc_vblank_get(crtc
) == 0)
540 drm_crtc_arm_vblank_event(crtc
, event
);
542 drm_crtc_send_vblank_event(crtc
, event
);
543 spin_unlock_irq(&crtc
->dev
->event_lock
);
547 static const struct drm_crtc_helper_funcs ade_crtc_helper_funcs
= {
548 .mode_fixup
= ade_crtc_mode_fixup
,
549 .mode_set_nofb
= ade_crtc_mode_set_nofb
,
550 .atomic_begin
= ade_crtc_atomic_begin
,
551 .atomic_flush
= ade_crtc_atomic_flush
,
552 .atomic_enable
= ade_crtc_atomic_enable
,
553 .atomic_disable
= ade_crtc_atomic_disable
,
556 static const struct drm_crtc_funcs ade_crtc_funcs
= {
557 .destroy
= drm_crtc_cleanup
,
558 .set_config
= drm_atomic_helper_set_config
,
559 .page_flip
= drm_atomic_helper_page_flip
,
560 .reset
= drm_atomic_helper_crtc_reset
,
561 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
562 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
563 .enable_vblank
= ade_crtc_enable_vblank
,
564 .disable_vblank
= ade_crtc_disable_vblank
,
567 static void ade_rdma_set(void __iomem
*base
, struct drm_framebuffer
*fb
,
568 u32 ch
, u32 y
, u32 in_h
, u32 fmt
)
570 struct drm_gem_cma_object
*obj
= drm_fb_cma_get_gem_obj(fb
, 0);
571 struct drm_format_name_buf format_name
;
572 u32 reg_ctrl
, reg_addr
, reg_size
, reg_stride
, reg_space
, reg_en
;
573 u32 stride
= fb
->pitches
[0];
574 u32 addr
= (u32
)obj
->paddr
+ y
* stride
;
576 DRM_DEBUG_DRIVER("rdma%d: (y=%d, height=%d), stride=%d, paddr=0x%x\n",
577 ch
+ 1, y
, in_h
, stride
, (u32
)obj
->paddr
);
578 DRM_DEBUG_DRIVER("addr=0x%x, fb:%dx%d, pixel_format=%d(%s)\n",
579 addr
, fb
->width
, fb
->height
, fmt
,
580 drm_get_format_name(fb
->format
->format
, &format_name
));
583 reg_ctrl
= RD_CH_CTRL(ch
);
584 reg_addr
= RD_CH_ADDR(ch
);
585 reg_size
= RD_CH_SIZE(ch
);
586 reg_stride
= RD_CH_STRIDE(ch
);
587 reg_space
= RD_CH_SPACE(ch
);
588 reg_en
= RD_CH_EN(ch
);
593 writel((fmt
<< 16) & 0x1f0000, base
+ reg_ctrl
);
594 writel(addr
, base
+ reg_addr
);
595 writel((in_h
<< 16) | stride
, base
+ reg_size
);
596 writel(stride
, base
+ reg_stride
);
597 writel(in_h
* stride
, base
+ reg_space
);
598 writel(ADE_ENABLE
, base
+ reg_en
);
599 ade_update_reload_bit(base
, RDMA_OFST
+ ch
, 0);
602 static void ade_rdma_disable(void __iomem
*base
, u32 ch
)
607 reg_en
= RD_CH_EN(ch
);
608 writel(0, base
+ reg_en
);
609 ade_update_reload_bit(base
, RDMA_OFST
+ ch
, 1);
612 static void ade_clip_set(void __iomem
*base
, u32 ch
, u32 fb_w
, u32 x
,
620 * clip width, no need to clip height
622 if (fb_w
== in_w
) { /* bypass */
629 clip_right
= fb_w
- (x
+ in_w
) - 1;
632 DRM_DEBUG_DRIVER("clip%d: clip_left=%d, clip_right=%d\n",
633 ch
+ 1, clip_left
, clip_right
);
635 writel(disable_val
, base
+ ADE_CLIP_DISABLE(ch
));
636 writel((fb_w
- 1) << 16 | (in_h
- 1), base
+ ADE_CLIP_SIZE0(ch
));
637 writel(clip_left
<< 16 | clip_right
, base
+ ADE_CLIP_SIZE1(ch
));
638 ade_update_reload_bit(base
, CLIP_OFST
+ ch
, 0);
641 static void ade_clip_disable(void __iomem
*base
, u32 ch
)
643 writel(1, base
+ ADE_CLIP_DISABLE(ch
));
644 ade_update_reload_bit(base
, CLIP_OFST
+ ch
, 1);
647 static bool has_Alpha_channel(int format
)
660 static void ade_get_blending_params(u32 fmt
, u8 glb_alpha
, u8
*alp_mode
,
661 u8
*alp_sel
, u8
*under_alp_sel
)
663 bool has_alpha
= has_Alpha_channel(fmt
);
668 if (has_alpha
&& glb_alpha
< 255)
669 *alp_mode
= ADE_ALP_PIXEL_AND_GLB
;
671 *alp_mode
= ADE_ALP_PIXEL
;
673 *alp_mode
= ADE_ALP_GLOBAL
;
678 *alp_sel
= ADE_ALP_MUL_COEFF_3
; /* 1 */
679 *under_alp_sel
= ADE_ALP_MUL_COEFF_2
; /* 0 */
682 static void ade_compositor_routing_set(void __iomem
*base
, u8 ch
,
684 u32 in_w
, u32 in_h
, u32 fmt
)
686 u8 ovly_ch
= 0; /* TODO: This is the zpos, only one plane now */
688 u32 x1
= x0
+ in_w
- 1;
689 u32 y1
= y0
+ in_h
- 1;
695 ade_get_blending_params(fmt
, glb_alpha
, &alp_mode
, &alp_sel
,
698 /* overlay routing setting
700 writel(x0
<< 16 | y0
, base
+ ADE_OVLY_CH_XY0(ovly_ch
));
701 writel(x1
<< 16 | y1
, base
+ ADE_OVLY_CH_XY1(ovly_ch
));
702 val
= (ch
+ 1) << CH_SEL_OFST
| BIT(CH_EN_OFST
) |
703 alp_sel
<< CH_ALP_SEL_OFST
|
704 under_alp_sel
<< CH_UNDER_ALP_SEL_OFST
|
705 glb_alpha
<< CH_ALP_GBL_OFST
|
706 alp_mode
<< CH_ALP_MODE_OFST
;
707 writel(val
, base
+ ADE_OVLY_CH_CTL(ovly_ch
));
708 /* connect this plane/channel to overlay2 compositor */
709 ade_update_bits(base
+ ADE_OVLY_CTL
, CH_OVLY_SEL_OFST(ovly_ch
),
710 CH_OVLY_SEL_MASK
, CH_OVLY_SEL_VAL(OUT_OVLY
));
713 static void ade_compositor_routing_disable(void __iomem
*base
, u32 ch
)
715 u8 ovly_ch
= 0; /* TODO: Only primary plane now */
717 /* disable this plane/channel */
718 ade_update_bits(base
+ ADE_OVLY_CH_CTL(ovly_ch
), CH_EN_OFST
,
720 /* dis-connect this plane/channel of overlay2 compositor */
721 ade_update_bits(base
+ ADE_OVLY_CTL
, CH_OVLY_SEL_OFST(ovly_ch
),
722 CH_OVLY_SEL_MASK
, 0);
726 * Typicaly, a channel looks like: DMA-->clip-->scale-->ctrans-->compositor
728 static void ade_update_channel(struct kirin_plane
*kplane
,
729 struct drm_framebuffer
*fb
, int crtc_x
,
730 int crtc_y
, unsigned int crtc_w
,
731 unsigned int crtc_h
, u32 src_x
,
732 u32 src_y
, u32 src_w
, u32 src_h
)
734 struct ade_hw_ctx
*ctx
= kplane
->hw_ctx
;
735 void __iomem
*base
= ctx
->base
;
736 u32 fmt
= ade_get_format(fb
->format
->format
);
741 DRM_DEBUG_DRIVER("channel%d: src:(%d, %d)-%dx%d, crtc:(%d, %d)-%dx%d",
742 ch
+ 1, src_x
, src_y
, src_w
, src_h
,
743 crtc_x
, crtc_y
, crtc_w
, crtc_h
);
748 ade_rdma_set(base
, fb
, ch
, src_y
, in_h
, fmt
);
750 /* 2) clip setting */
751 ade_clip_set(base
, ch
, fb
->width
, src_x
, in_w
, in_h
);
753 /* 3) TODO: scale setting for overlay planes */
755 /* 4) TODO: ctran/csc setting for overlay planes */
757 /* 5) compositor routing setting */
758 ade_compositor_routing_set(base
, ch
, crtc_x
, crtc_y
, in_w
, in_h
, fmt
);
761 static void ade_disable_channel(struct kirin_plane
*kplane
)
763 struct ade_hw_ctx
*ctx
= kplane
->hw_ctx
;
764 void __iomem
*base
= ctx
->base
;
767 DRM_DEBUG_DRIVER("disable channel%d\n", ch
+ 1);
769 /* disable read DMA */
770 ade_rdma_disable(base
, ch
);
773 ade_clip_disable(base
, ch
);
775 /* disable compositor routing */
776 ade_compositor_routing_disable(base
, ch
);
779 static int ade_plane_atomic_check(struct drm_plane
*plane
,
780 struct drm_plane_state
*state
)
782 struct drm_framebuffer
*fb
= state
->fb
;
783 struct drm_crtc
*crtc
= state
->crtc
;
784 struct drm_crtc_state
*crtc_state
;
785 u32 src_x
= state
->src_x
>> 16;
786 u32 src_y
= state
->src_y
>> 16;
787 u32 src_w
= state
->src_w
>> 16;
788 u32 src_h
= state
->src_h
>> 16;
789 int crtc_x
= state
->crtc_x
;
790 int crtc_y
= state
->crtc_y
;
791 u32 crtc_w
= state
->crtc_w
;
792 u32 crtc_h
= state
->crtc_h
;
798 fmt
= ade_get_format(fb
->format
->format
);
799 if (fmt
== ADE_FORMAT_UNSUPPORT
)
802 crtc_state
= drm_atomic_get_crtc_state(state
->state
, crtc
);
803 if (IS_ERR(crtc_state
))
804 return PTR_ERR(crtc_state
);
806 if (src_w
!= crtc_w
|| src_h
!= crtc_h
) {
810 if (src_x
+ src_w
> fb
->width
||
811 src_y
+ src_h
> fb
->height
)
814 if (crtc_x
< 0 || crtc_y
< 0)
817 if (crtc_x
+ crtc_w
> crtc_state
->adjusted_mode
.hdisplay
||
818 crtc_y
+ crtc_h
> crtc_state
->adjusted_mode
.vdisplay
)
824 static void ade_plane_atomic_update(struct drm_plane
*plane
,
825 struct drm_plane_state
*old_state
)
827 struct drm_plane_state
*state
= plane
->state
;
828 struct kirin_plane
*kplane
= to_kirin_plane(plane
);
830 ade_update_channel(kplane
, state
->fb
, state
->crtc_x
, state
->crtc_y
,
831 state
->crtc_w
, state
->crtc_h
,
832 state
->src_x
>> 16, state
->src_y
>> 16,
833 state
->src_w
>> 16, state
->src_h
>> 16);
836 static void ade_plane_atomic_disable(struct drm_plane
*plane
,
837 struct drm_plane_state
*old_state
)
839 struct kirin_plane
*kplane
= to_kirin_plane(plane
);
841 ade_disable_channel(kplane
);
844 static const struct drm_plane_helper_funcs ade_plane_helper_funcs
= {
845 .atomic_check
= ade_plane_atomic_check
,
846 .atomic_update
= ade_plane_atomic_update
,
847 .atomic_disable
= ade_plane_atomic_disable
,
850 static struct drm_plane_funcs ade_plane_funcs
= {
851 .update_plane
= drm_atomic_helper_update_plane
,
852 .disable_plane
= drm_atomic_helper_disable_plane
,
853 .destroy
= drm_plane_cleanup
,
854 .reset
= drm_atomic_helper_plane_reset
,
855 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
856 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
859 static void *ade_hw_ctx_alloc(struct platform_device
*pdev
,
860 struct drm_crtc
*crtc
)
862 struct resource
*res
;
863 struct device
*dev
= &pdev
->dev
;
864 struct device_node
*np
= pdev
->dev
.of_node
;
865 struct ade_hw_ctx
*ctx
= NULL
;
868 ctx
= devm_kzalloc(dev
, sizeof(*ctx
), GFP_KERNEL
);
870 DRM_ERROR("failed to alloc ade_hw_ctx\n");
871 return ERR_PTR(-ENOMEM
);
874 res
= platform_get_resource(pdev
, IORESOURCE_MEM
, 0);
875 ctx
->base
= devm_ioremap_resource(dev
, res
);
876 if (IS_ERR(ctx
->base
)) {
877 DRM_ERROR("failed to remap ade io base\n");
878 return ERR_PTR(-EIO
);
881 ctx
->reset
= devm_reset_control_get(dev
, NULL
);
882 if (IS_ERR(ctx
->reset
))
883 return ERR_PTR(-ENODEV
);
886 syscon_regmap_lookup_by_phandle(np
, "hisilicon,noc-syscon");
887 if (IS_ERR(ctx
->noc_regmap
)) {
888 DRM_ERROR("failed to get noc regmap\n");
889 return ERR_PTR(-ENODEV
);
892 ctx
->irq
= platform_get_irq(pdev
, 0);
894 DRM_ERROR("failed to get irq\n");
895 return ERR_PTR(-ENODEV
);
898 ctx
->ade_core_clk
= devm_clk_get(dev
, "clk_ade_core");
899 if (IS_ERR(ctx
->ade_core_clk
)) {
900 DRM_ERROR("failed to parse clk ADE_CORE\n");
901 return ERR_PTR(-ENODEV
);
904 ctx
->media_noc_clk
= devm_clk_get(dev
, "clk_codec_jpeg");
905 if (IS_ERR(ctx
->media_noc_clk
)) {
906 DRM_ERROR("failed to parse clk CODEC_JPEG\n");
907 return ERR_PTR(-ENODEV
);
910 ctx
->ade_pix_clk
= devm_clk_get(dev
, "clk_ade_pix");
911 if (IS_ERR(ctx
->ade_pix_clk
)) {
912 DRM_ERROR("failed to parse clk ADE_PIX\n");
913 return ERR_PTR(-ENODEV
);
916 /* vblank irq init */
917 ret
= devm_request_irq(dev
, ctx
->irq
, ade_irq_handler
,
918 IRQF_SHARED
, dev
->driver
->name
, ctx
);
920 return ERR_PTR(-EIO
);
922 INIT_WORK(&ctx
->display_reset_wq
, drm_underflow_wq
);
928 static void ade_hw_ctx_cleanup(void *hw_ctx
)
932 static const struct drm_mode_config_funcs ade_mode_config_funcs
= {
933 .fb_create
= drm_gem_fb_create
,
934 .atomic_check
= drm_atomic_helper_check
,
935 .atomic_commit
= drm_atomic_helper_commit
,
939 DEFINE_DRM_GEM_CMA_FOPS(ade_fops
);
941 static struct drm_driver ade_driver
= {
942 .driver_features
= DRIVER_GEM
| DRIVER_MODESET
| DRIVER_ATOMIC
,
944 .gem_free_object_unlocked
= drm_gem_cma_free_object
,
945 .gem_vm_ops
= &drm_gem_cma_vm_ops
,
946 .dumb_create
= drm_gem_cma_dumb_create_internal
,
947 .prime_handle_to_fd
= drm_gem_prime_handle_to_fd
,
948 .prime_fd_to_handle
= drm_gem_prime_fd_to_handle
,
949 .gem_prime_get_sg_table
= drm_gem_cma_prime_get_sg_table
,
950 .gem_prime_import_sg_table
= drm_gem_cma_prime_import_sg_table
,
951 .gem_prime_vmap
= drm_gem_cma_prime_vmap
,
952 .gem_prime_vunmap
= drm_gem_cma_prime_vunmap
,
953 .gem_prime_mmap
= drm_gem_cma_prime_mmap
,
956 .desc
= "Hisilicon Kirin620 SoC DRM Driver",
962 struct kirin_drm_data ade_driver_data
= {
963 .register_connects
= false,
964 .num_planes
= ADE_CH_NUM
,
965 .prim_plane
= ADE_CH1
,
966 .channel_formats
= channel_formats
,
967 .channel_formats_cnt
= ARRAY_SIZE(channel_formats
),
968 .config_max_width
= 2048,
969 .config_max_height
= 2048,
970 .driver
= &ade_driver
,
971 .crtc_helper_funcs
= &ade_crtc_helper_funcs
,
972 .crtc_funcs
= &ade_crtc_funcs
,
973 .plane_helper_funcs
= &ade_plane_helper_funcs
,
974 .plane_funcs
= &ade_plane_funcs
,
975 .mode_config_funcs
= &ade_mode_config_funcs
,
977 .alloc_hw_ctx
= ade_hw_ctx_alloc
,
978 .cleanup_hw_ctx
= ade_hw_ctx_cleanup
,