1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Hisilicon Hibmc SoC drm driver
4 * Based on the bochs drm driver.
6 * Copyright (c) 2016 Huawei Limited.
9 * Rongrong Zou <zourongrong@huawei.com>
10 * Rongrong Zou <zourongrong@gmail.com>
11 * Jianhua Li <lijianhua@huawei.com>
14 #include <drm/drm_atomic.h>
15 #include <drm/drm_atomic_helper.h>
16 #include <drm/drm_plane_helper.h>
17 #include <drm/drm_probe_helper.h>
19 #include "hibmc_drm_drv.h"
20 #include "hibmc_drm_regs.h"
22 struct hibmc_display_panel_pll
{
29 struct hibmc_dislay_pll_config
{
30 unsigned long hdisplay
;
31 unsigned long vdisplay
;
32 u32 pll1_config_value
;
33 u32 pll2_config_value
;
36 static const struct hibmc_dislay_pll_config hibmc_pll_table
[] = {
37 {800, 600, CRT_PLL1_HS_40MHZ
, CRT_PLL2_HS_40MHZ
},
38 {1024, 768, CRT_PLL1_HS_65MHZ
, CRT_PLL2_HS_65MHZ
},
39 {1152, 864, CRT_PLL1_HS_80MHZ_1152
, CRT_PLL2_HS_80MHZ
},
40 {1280, 768, CRT_PLL1_HS_80MHZ
, CRT_PLL2_HS_80MHZ
},
41 {1280, 720, CRT_PLL1_HS_74MHZ
, CRT_PLL2_HS_74MHZ
},
42 {1280, 960, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
43 {1280, 1024, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
44 {1600, 1200, CRT_PLL1_HS_162MHZ
, CRT_PLL2_HS_162MHZ
},
45 {1920, 1080, CRT_PLL1_HS_148MHZ
, CRT_PLL2_HS_148MHZ
},
46 {1920, 1200, CRT_PLL1_HS_193MHZ
, CRT_PLL2_HS_193MHZ
},
49 #define PADDING(align, data) (((data) + (align) - 1) & (~((align) - 1)))
51 static int hibmc_plane_atomic_check(struct drm_plane
*plane
,
52 struct drm_plane_state
*state
)
54 struct drm_framebuffer
*fb
= state
->fb
;
55 struct drm_crtc
*crtc
= state
->crtc
;
56 struct drm_crtc_state
*crtc_state
;
57 u32 src_w
= state
->src_w
>> 16;
58 u32 src_h
= state
->src_h
>> 16;
63 crtc_state
= drm_atomic_get_crtc_state(state
->state
, crtc
);
64 if (IS_ERR(crtc_state
))
65 return PTR_ERR(crtc_state
);
67 if (src_w
!= state
->crtc_w
|| src_h
!= state
->crtc_h
) {
68 DRM_DEBUG_ATOMIC("scale not support\n");
72 if (state
->crtc_x
< 0 || state
->crtc_y
< 0) {
73 DRM_DEBUG_ATOMIC("crtc_x/y of drm_plane state is invalid\n");
77 if (state
->crtc_x
+ state
->crtc_w
>
78 crtc_state
->adjusted_mode
.hdisplay
||
79 state
->crtc_y
+ state
->crtc_h
>
80 crtc_state
->adjusted_mode
.vdisplay
) {
81 DRM_DEBUG_ATOMIC("visible portion of plane is invalid\n");
88 static void hibmc_plane_atomic_update(struct drm_plane
*plane
,
89 struct drm_plane_state
*old_state
)
91 struct drm_plane_state
*state
= plane
->state
;
96 struct hibmc_drm_private
*priv
= plane
->dev
->dev_private
;
97 struct hibmc_framebuffer
*hibmc_fb
;
103 hibmc_fb
= to_hibmc_framebuffer(state
->fb
);
104 bo
= gem_to_hibmc_bo(hibmc_fb
->obj
);
105 ret
= ttm_bo_reserve(&bo
->bo
, true, false, NULL
);
107 DRM_ERROR("failed to reserve ttm_bo: %d", ret
);
111 ret
= hibmc_bo_pin(bo
, TTM_PL_FLAG_VRAM
, &gpu_addr
);
112 ttm_bo_unreserve(&bo
->bo
);
114 DRM_ERROR("failed to pin hibmc_bo: %d", ret
);
118 writel(gpu_addr
, priv
->mmio
+ HIBMC_CRT_FB_ADDRESS
);
120 reg
= state
->fb
->width
* (state
->fb
->format
->cpp
[0]);
121 /* now line_pad is 16 */
122 reg
= PADDING(16, reg
);
124 line_l
= state
->fb
->width
* state
->fb
->format
->cpp
[0];
125 line_l
= PADDING(16, line_l
);
126 writel(HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_WIDTH
, reg
) |
127 HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_OFFS
, line_l
),
128 priv
->mmio
+ HIBMC_CRT_FB_WIDTH
);
130 /* SET PIXEL FORMAT */
131 reg
= readl(priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
132 reg
&= ~HIBMC_CRT_DISP_CTL_FORMAT_MASK
;
133 reg
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_FORMAT
,
134 state
->fb
->format
->cpp
[0] * 8 / 16);
135 writel(reg
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
138 static const u32 channel_formats1
[] = {
139 DRM_FORMAT_RGB565
, DRM_FORMAT_BGR565
, DRM_FORMAT_RGB888
,
140 DRM_FORMAT_BGR888
, DRM_FORMAT_XRGB8888
, DRM_FORMAT_XBGR8888
,
141 DRM_FORMAT_RGBA8888
, DRM_FORMAT_BGRA8888
, DRM_FORMAT_ARGB8888
,
145 static struct drm_plane_funcs hibmc_plane_funcs
= {
146 .update_plane
= drm_atomic_helper_update_plane
,
147 .disable_plane
= drm_atomic_helper_disable_plane
,
148 .destroy
= drm_plane_cleanup
,
149 .reset
= drm_atomic_helper_plane_reset
,
150 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
151 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
154 static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs
= {
155 .atomic_check
= hibmc_plane_atomic_check
,
156 .atomic_update
= hibmc_plane_atomic_update
,
159 static struct drm_plane
*hibmc_plane_init(struct hibmc_drm_private
*priv
)
161 struct drm_device
*dev
= priv
->dev
;
162 struct drm_plane
*plane
;
165 plane
= devm_kzalloc(dev
->dev
, sizeof(*plane
), GFP_KERNEL
);
167 DRM_ERROR("failed to alloc memory when init plane\n");
168 return ERR_PTR(-ENOMEM
);
172 * TODO: Now only support primary plane, overlay planes
175 ret
= drm_universal_plane_init(dev
, plane
, 1, &hibmc_plane_funcs
,
177 ARRAY_SIZE(channel_formats1
),
179 DRM_PLANE_TYPE_PRIMARY
,
182 DRM_ERROR("failed to init plane: %d\n", ret
);
186 drm_plane_helper_add(plane
, &hibmc_plane_helper_funcs
);
190 static void hibmc_crtc_atomic_enable(struct drm_crtc
*crtc
,
191 struct drm_crtc_state
*old_state
)
194 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
196 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
198 /* Enable display power gate & LOCALMEM power gate*/
199 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
200 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
201 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
202 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
203 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
204 hibmc_set_current_gate(priv
, reg
);
205 drm_crtc_vblank_on(crtc
);
208 static void hibmc_crtc_atomic_disable(struct drm_crtc
*crtc
,
209 struct drm_crtc_state
*old_state
)
212 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
214 drm_crtc_vblank_off(crtc
);
216 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_SLEEP
);
218 /* Enable display power gate & LOCALMEM power gate*/
219 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
220 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
221 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
222 reg
|= HIBMC_CURR_GATE_LOCALMEM(0);
223 reg
|= HIBMC_CURR_GATE_DISPLAY(0);
224 hibmc_set_current_gate(priv
, reg
);
227 static unsigned int format_pll_reg(void)
229 unsigned int pllreg
= 0;
230 struct hibmc_display_panel_pll pll
= {0};
233 * Note that all PLL's have the same format. Here,
234 * we just use Panel PLL parameter to work out the bit
235 * fields in the register.On returning a 32 bit number, the value can
236 * be applied to any PLL in the calling function.
238 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_BYPASS
, 0);
239 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POWER
, 1);
240 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_INPUT
, 0);
241 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POD
, pll
.POD
);
242 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_OD
, pll
.OD
);
243 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_N
, pll
.N
);
244 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_M
, pll
.M
);
249 static void set_vclock_hisilicon(struct drm_device
*dev
, unsigned long pll
)
252 struct hibmc_drm_private
*priv
= dev
->dev_private
;
254 val
= readl(priv
->mmio
+ CRT_PLL1_HS
);
255 val
&= ~(CRT_PLL1_HS_OUTER_BYPASS(1));
256 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
258 val
= CRT_PLL1_HS_INTER_BYPASS(1) | CRT_PLL1_HS_POWERON(1);
259 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
261 writel(pll
, priv
->mmio
+ CRT_PLL1_HS
);
263 usleep_range(1000, 2000);
265 val
= pll
& ~(CRT_PLL1_HS_POWERON(1));
266 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
268 usleep_range(1000, 2000);
270 val
&= ~(CRT_PLL1_HS_INTER_BYPASS(1));
271 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
273 usleep_range(1000, 2000);
275 val
|= CRT_PLL1_HS_OUTER_BYPASS(1);
276 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
279 static void get_pll_config(unsigned long x
, unsigned long y
,
280 u32
*pll1
, u32
*pll2
)
283 int count
= ARRAY_SIZE(hibmc_pll_table
);
285 for (i
= 0; i
< count
; i
++) {
286 if (hibmc_pll_table
[i
].hdisplay
== x
&&
287 hibmc_pll_table
[i
].vdisplay
== y
) {
288 *pll1
= hibmc_pll_table
[i
].pll1_config_value
;
289 *pll2
= hibmc_pll_table
[i
].pll2_config_value
;
294 /* if found none, we use default value */
295 *pll1
= CRT_PLL1_HS_25MHZ
;
296 *pll2
= CRT_PLL2_HS_25MHZ
;
300 * This function takes care the extra registers and bit fields required to
301 * setup a mode in board.
302 * Explanation about Display Control register:
303 * FPGA only supports 7 predefined pixel clocks, and clock select is
304 * in bit 4:0 of new register 0x802a8.
306 static unsigned int display_ctrl_adjust(struct drm_device
*dev
,
307 struct drm_display_mode
*mode
,
311 u32 pll1
; /* bit[31:0] of PLL */
312 u32 pll2
; /* bit[63:32] of PLL */
313 struct hibmc_drm_private
*priv
= dev
->dev_private
;
318 get_pll_config(x
, y
, &pll1
, &pll2
);
319 writel(pll2
, priv
->mmio
+ CRT_PLL2_HS
);
320 set_vclock_hisilicon(dev
, pll1
);
323 * Hisilicon has to set up the top-left and bottom-right
325 * Note that normal chip only use those two register for
326 * auto-centering mode.
328 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_TOP
, 0) |
329 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_LEFT
, 0),
330 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_TL
);
332 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM
, y
- 1) |
333 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_RIGHT
, x
- 1),
334 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_BR
);
337 * Assume common fields in ctrl have been properly set before
338 * calling this function.
339 * This function only sets the extra fields in ctrl.
342 /* Set bit 25 of display controller: Select CRT or VGA clock */
343 ctrl
&= ~HIBMC_CRT_DISP_CTL_CRTSELECT_MASK
;
344 ctrl
&= ~HIBMC_CRT_DISP_CTL_CLOCK_PHASE_MASK
;
346 ctrl
|= HIBMC_CRT_DISP_CTL_CRTSELECT(HIBMC_CRTSELECT_CRT
);
348 /* clock_phase_polarity is 0 */
349 ctrl
|= HIBMC_CRT_DISP_CTL_CLOCK_PHASE(0);
351 writel(ctrl
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
356 static void hibmc_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
359 struct drm_display_mode
*mode
= &crtc
->state
->mode
;
360 struct drm_device
*dev
= crtc
->dev
;
361 struct hibmc_drm_private
*priv
= dev
->dev_private
;
362 int width
= mode
->hsync_end
- mode
->hsync_start
;
363 int height
= mode
->vsync_end
- mode
->vsync_start
;
365 writel(format_pll_reg(), priv
->mmio
+ HIBMC_CRT_PLL_CTRL
);
366 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_TOTAL
, mode
->htotal
- 1) |
367 HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_DISP_END
, mode
->hdisplay
- 1),
368 priv
->mmio
+ HIBMC_CRT_HORZ_TOTAL
);
370 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_WIDTH
, width
) |
371 HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_START
, mode
->hsync_start
- 1),
372 priv
->mmio
+ HIBMC_CRT_HORZ_SYNC
);
374 writel(HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_TOTAL
, mode
->vtotal
- 1) |
375 HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_DISP_END
, mode
->vdisplay
- 1),
376 priv
->mmio
+ HIBMC_CRT_VERT_TOTAL
);
378 writel(HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_HEIGHT
, height
) |
379 HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_START
, mode
->vsync_start
- 1),
380 priv
->mmio
+ HIBMC_CRT_VERT_SYNC
);
382 val
= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_VSYNC_PHASE
, 0);
383 val
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_HSYNC_PHASE
, 0);
384 val
|= HIBMC_CRT_DISP_CTL_TIMING(1);
385 val
|= HIBMC_CRT_DISP_CTL_PLANE(1);
387 display_ctrl_adjust(dev
, mode
, val
);
390 static void hibmc_crtc_atomic_begin(struct drm_crtc
*crtc
,
391 struct drm_crtc_state
*old_state
)
394 struct drm_device
*dev
= crtc
->dev
;
395 struct hibmc_drm_private
*priv
= dev
->dev_private
;
397 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
399 /* Enable display power gate & LOCALMEM power gate*/
400 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
401 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
402 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
403 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
404 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
405 hibmc_set_current_gate(priv
, reg
);
407 /* We can add more initialization as needed. */
410 static void hibmc_crtc_atomic_flush(struct drm_crtc
*crtc
,
411 struct drm_crtc_state
*old_state
)
416 spin_lock_irqsave(&crtc
->dev
->event_lock
, flags
);
417 if (crtc
->state
->event
)
418 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
419 crtc
->state
->event
= NULL
;
420 spin_unlock_irqrestore(&crtc
->dev
->event_lock
, flags
);
423 static int hibmc_crtc_enable_vblank(struct drm_crtc
*crtc
)
425 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
427 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(1),
428 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
433 static void hibmc_crtc_disable_vblank(struct drm_crtc
*crtc
)
435 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
437 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(0),
438 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
441 static const struct drm_crtc_funcs hibmc_crtc_funcs
= {
442 .page_flip
= drm_atomic_helper_page_flip
,
443 .set_config
= drm_atomic_helper_set_config
,
444 .destroy
= drm_crtc_cleanup
,
445 .reset
= drm_atomic_helper_crtc_reset
,
446 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
447 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
448 .enable_vblank
= hibmc_crtc_enable_vblank
,
449 .disable_vblank
= hibmc_crtc_disable_vblank
,
452 static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs
= {
453 .mode_set_nofb
= hibmc_crtc_mode_set_nofb
,
454 .atomic_begin
= hibmc_crtc_atomic_begin
,
455 .atomic_flush
= hibmc_crtc_atomic_flush
,
456 .atomic_enable
= hibmc_crtc_atomic_enable
,
457 .atomic_disable
= hibmc_crtc_atomic_disable
,
460 int hibmc_de_init(struct hibmc_drm_private
*priv
)
462 struct drm_device
*dev
= priv
->dev
;
463 struct drm_crtc
*crtc
;
464 struct drm_plane
*plane
;
467 plane
= hibmc_plane_init(priv
);
469 DRM_ERROR("failed to create plane: %ld\n", PTR_ERR(plane
));
470 return PTR_ERR(plane
);
473 crtc
= devm_kzalloc(dev
->dev
, sizeof(*crtc
), GFP_KERNEL
);
475 DRM_ERROR("failed to alloc memory when init crtc\n");
479 ret
= drm_crtc_init_with_planes(dev
, crtc
, plane
,
480 NULL
, &hibmc_crtc_funcs
, NULL
);
482 DRM_ERROR("failed to init crtc: %d\n", ret
);
486 ret
= drm_mode_crtc_set_gamma_size(crtc
, 256);
488 DRM_ERROR("failed to set gamma size: %d\n", ret
);
491 drm_crtc_helper_add(crtc
, &hibmc_crtc_helper_funcs
);