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 <linux/delay.h>
16 #include <drm/drm_atomic.h>
17 #include <drm/drm_atomic_helper.h>
18 #include <drm/drm_fourcc.h>
19 #include <drm/drm_gem_vram_helper.h>
20 #include <drm/drm_vblank.h>
22 #include "hibmc_drm_drv.h"
23 #include "hibmc_drm_regs.h"
25 struct hibmc_display_panel_pll
{
32 struct hibmc_dislay_pll_config
{
35 u32 pll1_config_value
;
36 u32 pll2_config_value
;
39 static const struct hibmc_dislay_pll_config hibmc_pll_table
[] = {
40 {640, 480, CRT_PLL1_HS_25MHZ
, CRT_PLL2_HS_25MHZ
},
41 {800, 600, CRT_PLL1_HS_40MHZ
, CRT_PLL2_HS_40MHZ
},
42 {1024, 768, CRT_PLL1_HS_65MHZ
, CRT_PLL2_HS_65MHZ
},
43 {1152, 864, CRT_PLL1_HS_80MHZ_1152
, CRT_PLL2_HS_80MHZ
},
44 {1280, 768, CRT_PLL1_HS_80MHZ
, CRT_PLL2_HS_80MHZ
},
45 {1280, 720, CRT_PLL1_HS_74MHZ
, CRT_PLL2_HS_74MHZ
},
46 {1280, 960, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
47 {1280, 1024, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
48 {1440, 900, CRT_PLL1_HS_106MHZ
, CRT_PLL2_HS_106MHZ
},
49 {1600, 900, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
50 {1600, 1200, CRT_PLL1_HS_162MHZ
, CRT_PLL2_HS_162MHZ
},
51 {1920, 1080, CRT_PLL1_HS_148MHZ
, CRT_PLL2_HS_148MHZ
},
52 {1920, 1200, CRT_PLL1_HS_193MHZ
, CRT_PLL2_HS_193MHZ
},
55 static int hibmc_plane_atomic_check(struct drm_plane
*plane
,
56 struct drm_plane_state
*state
)
58 struct drm_framebuffer
*fb
= state
->fb
;
59 struct drm_crtc
*crtc
= state
->crtc
;
60 struct drm_crtc_state
*crtc_state
;
61 u32 src_w
= state
->src_w
>> 16;
62 u32 src_h
= state
->src_h
>> 16;
67 crtc_state
= drm_atomic_get_crtc_state(state
->state
, crtc
);
68 if (IS_ERR(crtc_state
))
69 return PTR_ERR(crtc_state
);
71 if (src_w
!= state
->crtc_w
|| src_h
!= state
->crtc_h
) {
72 drm_dbg_atomic(plane
->dev
, "scale not support\n");
76 if (state
->crtc_x
< 0 || state
->crtc_y
< 0) {
77 drm_dbg_atomic(plane
->dev
, "crtc_x/y of drm_plane state is invalid\n");
81 if (!crtc_state
->enable
)
84 if (state
->crtc_x
+ state
->crtc_w
>
85 crtc_state
->adjusted_mode
.hdisplay
||
86 state
->crtc_y
+ state
->crtc_h
>
87 crtc_state
->adjusted_mode
.vdisplay
) {
88 drm_dbg_atomic(plane
->dev
, "visible portion of plane is invalid\n");
92 if (state
->fb
->pitches
[0] % 128 != 0) {
93 drm_dbg_atomic(plane
->dev
, "wrong stride with 128-byte aligned\n");
99 static void hibmc_plane_atomic_update(struct drm_plane
*plane
,
100 struct drm_plane_state
*old_state
)
102 struct drm_plane_state
*state
= plane
->state
;
106 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(plane
->dev
);
107 struct drm_gem_vram_object
*gbo
;
112 gbo
= drm_gem_vram_of_gem(state
->fb
->obj
[0]);
114 gpu_addr
= drm_gem_vram_offset(gbo
);
115 if (WARN_ON_ONCE(gpu_addr
< 0))
116 return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
118 writel(gpu_addr
, priv
->mmio
+ HIBMC_CRT_FB_ADDRESS
);
120 reg
= state
->fb
->width
* (state
->fb
->format
->cpp
[0]);
122 line_l
= state
->fb
->pitches
[0];
123 writel(HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_WIDTH
, reg
) |
124 HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_OFFS
, line_l
),
125 priv
->mmio
+ HIBMC_CRT_FB_WIDTH
);
127 /* SET PIXEL FORMAT */
128 reg
= readl(priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
129 reg
&= ~HIBMC_CRT_DISP_CTL_FORMAT_MASK
;
130 reg
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_FORMAT
,
131 state
->fb
->format
->cpp
[0] * 8 / 16);
132 writel(reg
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
135 static const u32 channel_formats1
[] = {
136 DRM_FORMAT_RGB565
, DRM_FORMAT_BGR565
, DRM_FORMAT_RGB888
,
137 DRM_FORMAT_BGR888
, DRM_FORMAT_XRGB8888
, DRM_FORMAT_XBGR8888
,
138 DRM_FORMAT_RGBA8888
, DRM_FORMAT_BGRA8888
, DRM_FORMAT_ARGB8888
,
142 static const struct drm_plane_funcs hibmc_plane_funcs
= {
143 .update_plane
= drm_atomic_helper_update_plane
,
144 .disable_plane
= drm_atomic_helper_disable_plane
,
145 .destroy
= drm_plane_cleanup
,
146 .reset
= drm_atomic_helper_plane_reset
,
147 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
148 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
151 static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs
= {
152 .prepare_fb
= drm_gem_vram_plane_helper_prepare_fb
,
153 .cleanup_fb
= drm_gem_vram_plane_helper_cleanup_fb
,
154 .atomic_check
= hibmc_plane_atomic_check
,
155 .atomic_update
= hibmc_plane_atomic_update
,
158 static void hibmc_crtc_dpms(struct drm_crtc
*crtc
, u32 dpms
)
160 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(crtc
->dev
);
163 reg
= readl(priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
164 reg
&= ~HIBMC_CRT_DISP_CTL_DPMS_MASK
;
165 reg
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_DPMS
, dpms
);
166 reg
&= ~HIBMC_CRT_DISP_CTL_TIMING_MASK
;
167 if (dpms
== HIBMC_CRT_DPMS_ON
)
168 reg
|= HIBMC_CRT_DISP_CTL_TIMING(1);
169 writel(reg
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
172 static void hibmc_crtc_atomic_enable(struct drm_crtc
*crtc
,
173 struct drm_atomic_state
*state
)
176 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(crtc
->dev
);
178 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
180 /* Enable display power gate & LOCALMEM power gate*/
181 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
182 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
183 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
184 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
185 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
186 hibmc_set_current_gate(priv
, reg
);
187 drm_crtc_vblank_on(crtc
);
188 hibmc_crtc_dpms(crtc
, HIBMC_CRT_DPMS_ON
);
191 static void hibmc_crtc_atomic_disable(struct drm_crtc
*crtc
,
192 struct drm_atomic_state
*state
)
195 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(crtc
->dev
);
197 hibmc_crtc_dpms(crtc
, HIBMC_CRT_DPMS_OFF
);
198 drm_crtc_vblank_off(crtc
);
200 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_SLEEP
);
202 /* Enable display power gate & LOCALMEM power gate*/
203 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
204 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
205 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
206 reg
|= HIBMC_CURR_GATE_LOCALMEM(0);
207 reg
|= HIBMC_CURR_GATE_DISPLAY(0);
208 hibmc_set_current_gate(priv
, reg
);
211 static enum drm_mode_status
212 hibmc_crtc_mode_valid(struct drm_crtc
*crtc
,
213 const struct drm_display_mode
*mode
)
216 int vrefresh
= drm_mode_vrefresh(mode
);
218 if (vrefresh
< 59 || vrefresh
> 61)
221 for (i
= 0; i
< ARRAY_SIZE(hibmc_pll_table
); i
++) {
222 if (hibmc_pll_table
[i
].hdisplay
== mode
->hdisplay
&&
223 hibmc_pll_table
[i
].vdisplay
== mode
->vdisplay
)
230 static u32
format_pll_reg(void)
233 struct hibmc_display_panel_pll pll
= {0};
236 * Note that all PLL's have the same format. Here,
237 * we just use Panel PLL parameter to work out the bit
238 * fields in the register.On returning a 32 bit number, the value can
239 * be applied to any PLL in the calling function.
241 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_BYPASS
, 0);
242 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POWER
, 1);
243 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_INPUT
, 0);
244 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POD
, pll
.POD
);
245 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_OD
, pll
.OD
);
246 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_N
, pll
.N
);
247 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_M
, pll
.M
);
252 static void set_vclock_hisilicon(struct drm_device
*dev
, u64 pll
)
255 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(dev
);
257 val
= readl(priv
->mmio
+ CRT_PLL1_HS
);
258 val
&= ~(CRT_PLL1_HS_OUTER_BYPASS(1));
259 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
261 val
= CRT_PLL1_HS_INTER_BYPASS(1) | CRT_PLL1_HS_POWERON(1);
262 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
264 writel(pll
, priv
->mmio
+ CRT_PLL1_HS
);
266 usleep_range(1000, 2000);
268 val
= pll
& ~(CRT_PLL1_HS_POWERON(1));
269 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
271 usleep_range(1000, 2000);
273 val
&= ~(CRT_PLL1_HS_INTER_BYPASS(1));
274 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
276 usleep_range(1000, 2000);
278 val
|= CRT_PLL1_HS_OUTER_BYPASS(1);
279 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
282 static void get_pll_config(u64 x
, u64 y
, u32
*pll1
, u32
*pll2
)
285 size_t count
= ARRAY_SIZE(hibmc_pll_table
);
287 for (i
= 0; i
< count
; i
++) {
288 if (hibmc_pll_table
[i
].hdisplay
== x
&&
289 hibmc_pll_table
[i
].vdisplay
== y
) {
290 *pll1
= hibmc_pll_table
[i
].pll1_config_value
;
291 *pll2
= hibmc_pll_table
[i
].pll2_config_value
;
296 /* if found none, we use default value */
297 *pll1
= CRT_PLL1_HS_25MHZ
;
298 *pll2
= CRT_PLL2_HS_25MHZ
;
302 * This function takes care the extra registers and bit fields required to
303 * setup a mode in board.
304 * Explanation about Display Control register:
305 * FPGA only supports 7 predefined pixel clocks, and clock select is
306 * in bit 4:0 of new register 0x802a8.
308 static u32
display_ctrl_adjust(struct drm_device
*dev
,
309 struct drm_display_mode
*mode
,
313 u32 pll1
; /* bit[31:0] of PLL */
314 u32 pll2
; /* bit[63:32] of PLL */
315 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(dev
);
320 get_pll_config(x
, y
, &pll1
, &pll2
);
321 writel(pll2
, priv
->mmio
+ CRT_PLL2_HS
);
322 set_vclock_hisilicon(dev
, pll1
);
325 * Hisilicon has to set up the top-left and bottom-right
327 * Note that normal chip only use those two register for
328 * auto-centering mode.
330 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_TOP
, 0) |
331 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_LEFT
, 0),
332 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_TL
);
334 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM
, y
- 1) |
335 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_RIGHT
, x
- 1),
336 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_BR
);
339 * Assume common fields in ctrl have been properly set before
340 * calling this function.
341 * This function only sets the extra fields in ctrl.
344 /* Set bit 25 of display controller: Select CRT or VGA clock */
345 ctrl
&= ~HIBMC_CRT_DISP_CTL_CRTSELECT_MASK
;
346 ctrl
&= ~HIBMC_CRT_DISP_CTL_CLOCK_PHASE_MASK
;
348 ctrl
|= HIBMC_CRT_DISP_CTL_CRTSELECT(HIBMC_CRTSELECT_CRT
);
350 /* clock_phase_polarity is 0 */
351 ctrl
|= HIBMC_CRT_DISP_CTL_CLOCK_PHASE(0);
353 writel(ctrl
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
358 static void hibmc_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
361 struct drm_display_mode
*mode
= &crtc
->state
->mode
;
362 struct drm_device
*dev
= crtc
->dev
;
363 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(dev
);
364 u32 width
= mode
->hsync_end
- mode
->hsync_start
;
365 u32 height
= mode
->vsync_end
- mode
->vsync_start
;
367 writel(format_pll_reg(), priv
->mmio
+ HIBMC_CRT_PLL_CTRL
);
368 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_TOTAL
, mode
->htotal
- 1) |
369 HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_DISP_END
, mode
->hdisplay
- 1),
370 priv
->mmio
+ HIBMC_CRT_HORZ_TOTAL
);
372 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_WIDTH
, width
) |
373 HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_START
, mode
->hsync_start
- 1),
374 priv
->mmio
+ HIBMC_CRT_HORZ_SYNC
);
376 writel(HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_TOTAL
, mode
->vtotal
- 1) |
377 HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_DISP_END
, mode
->vdisplay
- 1),
378 priv
->mmio
+ HIBMC_CRT_VERT_TOTAL
);
380 writel(HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_HEIGHT
, height
) |
381 HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_START
, mode
->vsync_start
- 1),
382 priv
->mmio
+ HIBMC_CRT_VERT_SYNC
);
384 val
= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_VSYNC_PHASE
, 0);
385 val
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_HSYNC_PHASE
, 0);
386 val
|= HIBMC_CRT_DISP_CTL_TIMING(1);
387 val
|= HIBMC_CRT_DISP_CTL_PLANE(1);
389 display_ctrl_adjust(dev
, mode
, val
);
392 static void hibmc_crtc_atomic_begin(struct drm_crtc
*crtc
,
393 struct drm_atomic_state
*state
)
396 struct drm_device
*dev
= crtc
->dev
;
397 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(dev
);
399 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
401 /* Enable display power gate & LOCALMEM power gate*/
402 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
403 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
404 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
405 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
406 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
407 hibmc_set_current_gate(priv
, reg
);
409 /* We can add more initialization as needed. */
412 static void hibmc_crtc_atomic_flush(struct drm_crtc
*crtc
,
413 struct drm_atomic_state
*state
)
418 spin_lock_irqsave(&crtc
->dev
->event_lock
, flags
);
419 if (crtc
->state
->event
)
420 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
421 crtc
->state
->event
= NULL
;
422 spin_unlock_irqrestore(&crtc
->dev
->event_lock
, flags
);
425 static int hibmc_crtc_enable_vblank(struct drm_crtc
*crtc
)
427 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(crtc
->dev
);
429 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(1),
430 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
435 static void hibmc_crtc_disable_vblank(struct drm_crtc
*crtc
)
437 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(crtc
->dev
);
439 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(0),
440 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
443 static void hibmc_crtc_load_lut(struct drm_crtc
*crtc
)
445 struct hibmc_drm_private
*priv
= to_hibmc_drm_private(crtc
->dev
);
446 void __iomem
*mmio
= priv
->mmio
;
451 r
= crtc
->gamma_store
;
452 g
= r
+ crtc
->gamma_size
;
453 b
= g
+ crtc
->gamma_size
;
455 for (i
= 0; i
< crtc
->gamma_size
; i
++) {
458 u8 green
= *g
++ >> 8;
460 u32 rgb
= (red
<< 16) | (green
<< 8) | blue
;
462 writel(rgb
, mmio
+ HIBMC_CRT_PALETTE
+ offset
);
465 reg
= readl(priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
466 reg
|= HIBMC_FIELD(HIBMC_CTL_DISP_CTL_GAMMA
, 1);
467 writel(reg
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
470 static int hibmc_crtc_gamma_set(struct drm_crtc
*crtc
, u16
*red
, u16
*green
,
471 u16
*blue
, uint32_t size
,
472 struct drm_modeset_acquire_ctx
*ctx
)
474 hibmc_crtc_load_lut(crtc
);
479 static const struct drm_crtc_funcs hibmc_crtc_funcs
= {
480 .page_flip
= drm_atomic_helper_page_flip
,
481 .set_config
= drm_atomic_helper_set_config
,
482 .destroy
= drm_crtc_cleanup
,
483 .reset
= drm_atomic_helper_crtc_reset
,
484 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
485 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
486 .enable_vblank
= hibmc_crtc_enable_vblank
,
487 .disable_vblank
= hibmc_crtc_disable_vblank
,
488 .gamma_set
= hibmc_crtc_gamma_set
,
491 static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs
= {
492 .mode_set_nofb
= hibmc_crtc_mode_set_nofb
,
493 .atomic_begin
= hibmc_crtc_atomic_begin
,
494 .atomic_flush
= hibmc_crtc_atomic_flush
,
495 .atomic_enable
= hibmc_crtc_atomic_enable
,
496 .atomic_disable
= hibmc_crtc_atomic_disable
,
497 .mode_valid
= hibmc_crtc_mode_valid
,
500 int hibmc_de_init(struct hibmc_drm_private
*priv
)
502 struct drm_device
*dev
= priv
->dev
;
503 struct drm_crtc
*crtc
= &priv
->crtc
;
504 struct drm_plane
*plane
= &priv
->primary_plane
;
507 ret
= drm_universal_plane_init(dev
, plane
, 1, &hibmc_plane_funcs
,
509 ARRAY_SIZE(channel_formats1
),
511 DRM_PLANE_TYPE_PRIMARY
,
515 drm_err(dev
, "failed to init plane: %d\n", ret
);
519 drm_plane_helper_add(plane
, &hibmc_plane_helper_funcs
);
521 ret
= drm_crtc_init_with_planes(dev
, crtc
, plane
,
522 NULL
, &hibmc_crtc_funcs
, NULL
);
524 drm_err(dev
, "failed to init crtc: %d\n", ret
);
528 ret
= drm_mode_crtc_set_gamma_size(crtc
, 256);
530 drm_err(dev
, "failed to set gamma size: %d\n", ret
);
533 drm_crtc_helper_add(crtc
, &hibmc_crtc_helper_funcs
);