1 /* Hisilicon Hibmc SoC drm driver
3 * Based on the bochs drm driver.
5 * Copyright (c) 2016 Huawei Limited.
8 * Rongrong Zou <zourongrong@huawei.com>
9 * Rongrong Zou <zourongrong@gmail.com>
10 * Jianhua Li <lijianhua@huawei.com>
12 * This program is free software; you can redistribute it and/or modify
13 * it under the terms of the GNU General Public License as published by
14 * the Free Software Foundation; either version 2 of the License, or
15 * (at your option) any later version.
19 #include <drm/drm_atomic.h>
20 #include <drm/drm_atomic_helper.h>
21 #include <drm/drm_plane_helper.h>
22 #include <drm/drm_probe_helper.h>
24 #include "hibmc_drm_drv.h"
25 #include "hibmc_drm_regs.h"
27 struct hibmc_display_panel_pll
{
34 struct hibmc_dislay_pll_config
{
35 unsigned long hdisplay
;
36 unsigned long vdisplay
;
37 u32 pll1_config_value
;
38 u32 pll2_config_value
;
41 static const struct hibmc_dislay_pll_config hibmc_pll_table
[] = {
42 {800, 600, CRT_PLL1_HS_40MHZ
, CRT_PLL2_HS_40MHZ
},
43 {1024, 768, CRT_PLL1_HS_65MHZ
, CRT_PLL2_HS_65MHZ
},
44 {1152, 864, CRT_PLL1_HS_80MHZ_1152
, CRT_PLL2_HS_80MHZ
},
45 {1280, 768, CRT_PLL1_HS_80MHZ
, CRT_PLL2_HS_80MHZ
},
46 {1280, 720, CRT_PLL1_HS_74MHZ
, CRT_PLL2_HS_74MHZ
},
47 {1280, 960, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
48 {1280, 1024, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
49 {1600, 1200, CRT_PLL1_HS_162MHZ
, CRT_PLL2_HS_162MHZ
},
50 {1920, 1080, CRT_PLL1_HS_148MHZ
, CRT_PLL2_HS_148MHZ
},
51 {1920, 1200, CRT_PLL1_HS_193MHZ
, CRT_PLL2_HS_193MHZ
},
54 #define PADDING(align, data) (((data) + (align) - 1) & (~((align) - 1)))
56 static int hibmc_plane_atomic_check(struct drm_plane
*plane
,
57 struct drm_plane_state
*state
)
59 struct drm_framebuffer
*fb
= state
->fb
;
60 struct drm_crtc
*crtc
= state
->crtc
;
61 struct drm_crtc_state
*crtc_state
;
62 u32 src_w
= state
->src_w
>> 16;
63 u32 src_h
= state
->src_h
>> 16;
68 crtc_state
= drm_atomic_get_crtc_state(state
->state
, crtc
);
69 if (IS_ERR(crtc_state
))
70 return PTR_ERR(crtc_state
);
72 if (src_w
!= state
->crtc_w
|| src_h
!= state
->crtc_h
) {
73 DRM_DEBUG_ATOMIC("scale not support\n");
77 if (state
->crtc_x
< 0 || state
->crtc_y
< 0) {
78 DRM_DEBUG_ATOMIC("crtc_x/y of drm_plane state is invalid\n");
82 if (state
->crtc_x
+ state
->crtc_w
>
83 crtc_state
->adjusted_mode
.hdisplay
||
84 state
->crtc_y
+ state
->crtc_h
>
85 crtc_state
->adjusted_mode
.vdisplay
) {
86 DRM_DEBUG_ATOMIC("visible portion of plane is invalid\n");
93 static void hibmc_plane_atomic_update(struct drm_plane
*plane
,
94 struct drm_plane_state
*old_state
)
96 struct drm_plane_state
*state
= plane
->state
;
101 struct hibmc_drm_private
*priv
= plane
->dev
->dev_private
;
102 struct hibmc_framebuffer
*hibmc_fb
;
108 hibmc_fb
= to_hibmc_framebuffer(state
->fb
);
109 bo
= gem_to_hibmc_bo(hibmc_fb
->obj
);
110 ret
= ttm_bo_reserve(&bo
->bo
, true, false, NULL
);
112 DRM_ERROR("failed to reserve ttm_bo: %d", ret
);
116 ret
= hibmc_bo_pin(bo
, TTM_PL_FLAG_VRAM
, &gpu_addr
);
117 ttm_bo_unreserve(&bo
->bo
);
119 DRM_ERROR("failed to pin hibmc_bo: %d", ret
);
123 writel(gpu_addr
, priv
->mmio
+ HIBMC_CRT_FB_ADDRESS
);
125 reg
= state
->fb
->width
* (state
->fb
->format
->cpp
[0]);
126 /* now line_pad is 16 */
127 reg
= PADDING(16, reg
);
129 line_l
= state
->fb
->width
* state
->fb
->format
->cpp
[0];
130 line_l
= PADDING(16, line_l
);
131 writel(HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_WIDTH
, reg
) |
132 HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_OFFS
, line_l
),
133 priv
->mmio
+ HIBMC_CRT_FB_WIDTH
);
135 /* SET PIXEL FORMAT */
136 reg
= readl(priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
137 reg
&= ~HIBMC_CRT_DISP_CTL_FORMAT_MASK
;
138 reg
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_FORMAT
,
139 state
->fb
->format
->cpp
[0] * 8 / 16);
140 writel(reg
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
143 static const u32 channel_formats1
[] = {
144 DRM_FORMAT_RGB565
, DRM_FORMAT_BGR565
, DRM_FORMAT_RGB888
,
145 DRM_FORMAT_BGR888
, DRM_FORMAT_XRGB8888
, DRM_FORMAT_XBGR8888
,
146 DRM_FORMAT_RGBA8888
, DRM_FORMAT_BGRA8888
, DRM_FORMAT_ARGB8888
,
150 static struct drm_plane_funcs hibmc_plane_funcs
= {
151 .update_plane
= drm_atomic_helper_update_plane
,
152 .disable_plane
= drm_atomic_helper_disable_plane
,
153 .destroy
= drm_plane_cleanup
,
154 .reset
= drm_atomic_helper_plane_reset
,
155 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
156 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
159 static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs
= {
160 .atomic_check
= hibmc_plane_atomic_check
,
161 .atomic_update
= hibmc_plane_atomic_update
,
164 static struct drm_plane
*hibmc_plane_init(struct hibmc_drm_private
*priv
)
166 struct drm_device
*dev
= priv
->dev
;
167 struct drm_plane
*plane
;
170 plane
= devm_kzalloc(dev
->dev
, sizeof(*plane
), GFP_KERNEL
);
172 DRM_ERROR("failed to alloc memory when init plane\n");
173 return ERR_PTR(-ENOMEM
);
177 * TODO: Now only support primary plane, overlay planes
180 ret
= drm_universal_plane_init(dev
, plane
, 1, &hibmc_plane_funcs
,
182 ARRAY_SIZE(channel_formats1
),
184 DRM_PLANE_TYPE_PRIMARY
,
187 DRM_ERROR("failed to init plane: %d\n", ret
);
191 drm_plane_helper_add(plane
, &hibmc_plane_helper_funcs
);
195 static void hibmc_crtc_atomic_enable(struct drm_crtc
*crtc
,
196 struct drm_crtc_state
*old_state
)
199 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
201 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
203 /* Enable display power gate & LOCALMEM power gate*/
204 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
205 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
206 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
207 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
208 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
209 hibmc_set_current_gate(priv
, reg
);
210 drm_crtc_vblank_on(crtc
);
213 static void hibmc_crtc_atomic_disable(struct drm_crtc
*crtc
,
214 struct drm_crtc_state
*old_state
)
217 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
219 drm_crtc_vblank_off(crtc
);
221 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_SLEEP
);
223 /* Enable display power gate & LOCALMEM power gate*/
224 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
225 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
226 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
227 reg
|= HIBMC_CURR_GATE_LOCALMEM(0);
228 reg
|= HIBMC_CURR_GATE_DISPLAY(0);
229 hibmc_set_current_gate(priv
, reg
);
232 static unsigned int format_pll_reg(void)
234 unsigned int pllreg
= 0;
235 struct hibmc_display_panel_pll pll
= {0};
238 * Note that all PLL's have the same format. Here,
239 * we just use Panel PLL parameter to work out the bit
240 * fields in the register.On returning a 32 bit number, the value can
241 * be applied to any PLL in the calling function.
243 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_BYPASS
, 0);
244 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POWER
, 1);
245 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_INPUT
, 0);
246 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POD
, pll
.POD
);
247 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_OD
, pll
.OD
);
248 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_N
, pll
.N
);
249 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_M
, pll
.M
);
254 static void set_vclock_hisilicon(struct drm_device
*dev
, unsigned long pll
)
257 struct hibmc_drm_private
*priv
= dev
->dev_private
;
259 val
= readl(priv
->mmio
+ CRT_PLL1_HS
);
260 val
&= ~(CRT_PLL1_HS_OUTER_BYPASS(1));
261 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
263 val
= CRT_PLL1_HS_INTER_BYPASS(1) | CRT_PLL1_HS_POWERON(1);
264 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
266 writel(pll
, priv
->mmio
+ CRT_PLL1_HS
);
268 usleep_range(1000, 2000);
270 val
= pll
& ~(CRT_PLL1_HS_POWERON(1));
271 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
273 usleep_range(1000, 2000);
275 val
&= ~(CRT_PLL1_HS_INTER_BYPASS(1));
276 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
278 usleep_range(1000, 2000);
280 val
|= CRT_PLL1_HS_OUTER_BYPASS(1);
281 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
284 static void get_pll_config(unsigned long x
, unsigned long y
,
285 u32
*pll1
, u32
*pll2
)
288 int count
= ARRAY_SIZE(hibmc_pll_table
);
290 for (i
= 0; i
< count
; i
++) {
291 if (hibmc_pll_table
[i
].hdisplay
== x
&&
292 hibmc_pll_table
[i
].vdisplay
== y
) {
293 *pll1
= hibmc_pll_table
[i
].pll1_config_value
;
294 *pll2
= hibmc_pll_table
[i
].pll2_config_value
;
299 /* if found none, we use default value */
300 *pll1
= CRT_PLL1_HS_25MHZ
;
301 *pll2
= CRT_PLL2_HS_25MHZ
;
305 * This function takes care the extra registers and bit fields required to
306 * setup a mode in board.
307 * Explanation about Display Control register:
308 * FPGA only supports 7 predefined pixel clocks, and clock select is
309 * in bit 4:0 of new register 0x802a8.
311 static unsigned int display_ctrl_adjust(struct drm_device
*dev
,
312 struct drm_display_mode
*mode
,
316 u32 pll1
; /* bit[31:0] of PLL */
317 u32 pll2
; /* bit[63:32] of PLL */
318 struct hibmc_drm_private
*priv
= dev
->dev_private
;
323 get_pll_config(x
, y
, &pll1
, &pll2
);
324 writel(pll2
, priv
->mmio
+ CRT_PLL2_HS
);
325 set_vclock_hisilicon(dev
, pll1
);
328 * Hisilicon has to set up the top-left and bottom-right
330 * Note that normal chip only use those two register for
331 * auto-centering mode.
333 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_TOP
, 0) |
334 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_LEFT
, 0),
335 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_TL
);
337 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM
, y
- 1) |
338 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_RIGHT
, x
- 1),
339 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_BR
);
342 * Assume common fields in ctrl have been properly set before
343 * calling this function.
344 * This function only sets the extra fields in ctrl.
347 /* Set bit 25 of display controller: Select CRT or VGA clock */
348 ctrl
&= ~HIBMC_CRT_DISP_CTL_CRTSELECT_MASK
;
349 ctrl
&= ~HIBMC_CRT_DISP_CTL_CLOCK_PHASE_MASK
;
351 ctrl
|= HIBMC_CRT_DISP_CTL_CRTSELECT(HIBMC_CRTSELECT_CRT
);
353 /* clock_phase_polarity is 0 */
354 ctrl
|= HIBMC_CRT_DISP_CTL_CLOCK_PHASE(0);
356 writel(ctrl
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
361 static void hibmc_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
364 struct drm_display_mode
*mode
= &crtc
->state
->mode
;
365 struct drm_device
*dev
= crtc
->dev
;
366 struct hibmc_drm_private
*priv
= dev
->dev_private
;
367 int width
= mode
->hsync_end
- mode
->hsync_start
;
368 int height
= mode
->vsync_end
- mode
->vsync_start
;
370 writel(format_pll_reg(), priv
->mmio
+ HIBMC_CRT_PLL_CTRL
);
371 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_TOTAL
, mode
->htotal
- 1) |
372 HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_DISP_END
, mode
->hdisplay
- 1),
373 priv
->mmio
+ HIBMC_CRT_HORZ_TOTAL
);
375 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_WIDTH
, width
) |
376 HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_START
, mode
->hsync_start
- 1),
377 priv
->mmio
+ HIBMC_CRT_HORZ_SYNC
);
379 writel(HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_TOTAL
, mode
->vtotal
- 1) |
380 HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_DISP_END
, mode
->vdisplay
- 1),
381 priv
->mmio
+ HIBMC_CRT_VERT_TOTAL
);
383 writel(HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_HEIGHT
, height
) |
384 HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_START
, mode
->vsync_start
- 1),
385 priv
->mmio
+ HIBMC_CRT_VERT_SYNC
);
387 val
= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_VSYNC_PHASE
, 0);
388 val
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_HSYNC_PHASE
, 0);
389 val
|= HIBMC_CRT_DISP_CTL_TIMING(1);
390 val
|= HIBMC_CRT_DISP_CTL_PLANE(1);
392 display_ctrl_adjust(dev
, mode
, val
);
395 static void hibmc_crtc_atomic_begin(struct drm_crtc
*crtc
,
396 struct drm_crtc_state
*old_state
)
399 struct drm_device
*dev
= crtc
->dev
;
400 struct hibmc_drm_private
*priv
= dev
->dev_private
;
402 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
404 /* Enable display power gate & LOCALMEM power gate*/
405 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
406 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
407 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
408 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
409 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
410 hibmc_set_current_gate(priv
, reg
);
412 /* We can add more initialization as needed. */
415 static void hibmc_crtc_atomic_flush(struct drm_crtc
*crtc
,
416 struct drm_crtc_state
*old_state
)
421 spin_lock_irqsave(&crtc
->dev
->event_lock
, flags
);
422 if (crtc
->state
->event
)
423 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
424 crtc
->state
->event
= NULL
;
425 spin_unlock_irqrestore(&crtc
->dev
->event_lock
, flags
);
428 static int hibmc_crtc_enable_vblank(struct drm_crtc
*crtc
)
430 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
432 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(1),
433 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
438 static void hibmc_crtc_disable_vblank(struct drm_crtc
*crtc
)
440 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
442 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(0),
443 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
446 static const struct drm_crtc_funcs hibmc_crtc_funcs
= {
447 .page_flip
= drm_atomic_helper_page_flip
,
448 .set_config
= drm_atomic_helper_set_config
,
449 .destroy
= drm_crtc_cleanup
,
450 .reset
= drm_atomic_helper_crtc_reset
,
451 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
452 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
453 .enable_vblank
= hibmc_crtc_enable_vblank
,
454 .disable_vblank
= hibmc_crtc_disable_vblank
,
457 static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs
= {
458 .mode_set_nofb
= hibmc_crtc_mode_set_nofb
,
459 .atomic_begin
= hibmc_crtc_atomic_begin
,
460 .atomic_flush
= hibmc_crtc_atomic_flush
,
461 .atomic_enable
= hibmc_crtc_atomic_enable
,
462 .atomic_disable
= hibmc_crtc_atomic_disable
,
465 int hibmc_de_init(struct hibmc_drm_private
*priv
)
467 struct drm_device
*dev
= priv
->dev
;
468 struct drm_crtc
*crtc
;
469 struct drm_plane
*plane
;
472 plane
= hibmc_plane_init(priv
);
474 DRM_ERROR("failed to create plane: %ld\n", PTR_ERR(plane
));
475 return PTR_ERR(plane
);
478 crtc
= devm_kzalloc(dev
->dev
, sizeof(*crtc
), GFP_KERNEL
);
480 DRM_ERROR("failed to alloc memory when init crtc\n");
484 ret
= drm_crtc_init_with_planes(dev
, crtc
, plane
,
485 NULL
, &hibmc_crtc_funcs
, NULL
);
487 DRM_ERROR("failed to init crtc: %d\n", ret
);
491 ret
= drm_mode_crtc_set_gamma_size(crtc
, 256);
493 DRM_ERROR("failed to set gamma size: %d\n", ret
);
496 drm_crtc_helper_add(crtc
, &hibmc_crtc_helper_funcs
);