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_plane_helper.h>
21 #include <drm/drm_print.h>
22 #include <drm/drm_probe_helper.h>
23 #include <drm/drm_vblank.h>
25 #include "hibmc_drm_drv.h"
26 #include "hibmc_drm_regs.h"
28 struct hibmc_display_panel_pll
{
35 struct hibmc_dislay_pll_config
{
36 unsigned long hdisplay
;
37 unsigned long vdisplay
;
38 u32 pll1_config_value
;
39 u32 pll2_config_value
;
42 static const struct hibmc_dislay_pll_config hibmc_pll_table
[] = {
43 {800, 600, CRT_PLL1_HS_40MHZ
, CRT_PLL2_HS_40MHZ
},
44 {1024, 768, CRT_PLL1_HS_65MHZ
, CRT_PLL2_HS_65MHZ
},
45 {1152, 864, CRT_PLL1_HS_80MHZ_1152
, CRT_PLL2_HS_80MHZ
},
46 {1280, 768, CRT_PLL1_HS_80MHZ
, CRT_PLL2_HS_80MHZ
},
47 {1280, 720, CRT_PLL1_HS_74MHZ
, CRT_PLL2_HS_74MHZ
},
48 {1280, 960, CRT_PLL1_HS_108MHZ
, CRT_PLL2_HS_108MHZ
},
49 {1280, 1024, 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 #define PADDING(align, data) (((data) + (align) - 1) & (~((align) - 1)))
57 static int hibmc_plane_atomic_check(struct drm_plane
*plane
,
58 struct drm_plane_state
*state
)
60 struct drm_framebuffer
*fb
= state
->fb
;
61 struct drm_crtc
*crtc
= state
->crtc
;
62 struct drm_crtc_state
*crtc_state
;
63 u32 src_w
= state
->src_w
>> 16;
64 u32 src_h
= state
->src_h
>> 16;
69 crtc_state
= drm_atomic_get_crtc_state(state
->state
, crtc
);
70 if (IS_ERR(crtc_state
))
71 return PTR_ERR(crtc_state
);
73 if (src_w
!= state
->crtc_w
|| src_h
!= state
->crtc_h
) {
74 DRM_DEBUG_ATOMIC("scale not support\n");
78 if (state
->crtc_x
< 0 || state
->crtc_y
< 0) {
79 DRM_DEBUG_ATOMIC("crtc_x/y of drm_plane state is invalid\n");
83 if (state
->crtc_x
+ state
->crtc_w
>
84 crtc_state
->adjusted_mode
.hdisplay
||
85 state
->crtc_y
+ state
->crtc_h
>
86 crtc_state
->adjusted_mode
.vdisplay
) {
87 DRM_DEBUG_ATOMIC("visible portion of plane is invalid\n");
94 static void hibmc_plane_atomic_update(struct drm_plane
*plane
,
95 struct drm_plane_state
*old_state
)
97 struct drm_plane_state
*state
= plane
->state
;
101 struct hibmc_drm_private
*priv
= plane
->dev
->dev_private
;
102 struct drm_gem_vram_object
*gbo
;
107 gbo
= drm_gem_vram_of_gem(state
->fb
->obj
[0]);
109 gpu_addr
= drm_gem_vram_offset(gbo
);
110 if (WARN_ON_ONCE(gpu_addr
< 0))
111 return; /* Bug: we didn't pin the BO to VRAM in prepare_fb. */
113 writel(gpu_addr
, priv
->mmio
+ HIBMC_CRT_FB_ADDRESS
);
115 reg
= state
->fb
->width
* (state
->fb
->format
->cpp
[0]);
116 /* now line_pad is 16 */
117 reg
= PADDING(16, reg
);
119 line_l
= state
->fb
->width
* state
->fb
->format
->cpp
[0];
120 line_l
= PADDING(16, line_l
);
121 writel(HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_WIDTH
, reg
) |
122 HIBMC_FIELD(HIBMC_CRT_FB_WIDTH_OFFS
, line_l
),
123 priv
->mmio
+ HIBMC_CRT_FB_WIDTH
);
125 /* SET PIXEL FORMAT */
126 reg
= readl(priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
127 reg
&= ~HIBMC_CRT_DISP_CTL_FORMAT_MASK
;
128 reg
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_FORMAT
,
129 state
->fb
->format
->cpp
[0] * 8 / 16);
130 writel(reg
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
133 static const u32 channel_formats1
[] = {
134 DRM_FORMAT_RGB565
, DRM_FORMAT_BGR565
, DRM_FORMAT_RGB888
,
135 DRM_FORMAT_BGR888
, DRM_FORMAT_XRGB8888
, DRM_FORMAT_XBGR8888
,
136 DRM_FORMAT_RGBA8888
, DRM_FORMAT_BGRA8888
, DRM_FORMAT_ARGB8888
,
140 static struct drm_plane_funcs hibmc_plane_funcs
= {
141 .update_plane
= drm_atomic_helper_update_plane
,
142 .disable_plane
= drm_atomic_helper_disable_plane
,
143 .destroy
= drm_plane_cleanup
,
144 .reset
= drm_atomic_helper_plane_reset
,
145 .atomic_duplicate_state
= drm_atomic_helper_plane_duplicate_state
,
146 .atomic_destroy_state
= drm_atomic_helper_plane_destroy_state
,
149 static const struct drm_plane_helper_funcs hibmc_plane_helper_funcs
= {
150 .prepare_fb
= drm_gem_vram_plane_helper_prepare_fb
,
151 .cleanup_fb
= drm_gem_vram_plane_helper_cleanup_fb
,
152 .atomic_check
= hibmc_plane_atomic_check
,
153 .atomic_update
= hibmc_plane_atomic_update
,
156 static struct drm_plane
*hibmc_plane_init(struct hibmc_drm_private
*priv
)
158 struct drm_device
*dev
= priv
->dev
;
159 struct drm_plane
*plane
;
162 plane
= devm_kzalloc(dev
->dev
, sizeof(*plane
), GFP_KERNEL
);
164 DRM_ERROR("failed to alloc memory when init plane\n");
165 return ERR_PTR(-ENOMEM
);
169 * TODO: Now only support primary plane, overlay planes
172 ret
= drm_universal_plane_init(dev
, plane
, 1, &hibmc_plane_funcs
,
174 ARRAY_SIZE(channel_formats1
),
176 DRM_PLANE_TYPE_PRIMARY
,
179 DRM_ERROR("failed to init plane: %d\n", ret
);
183 drm_plane_helper_add(plane
, &hibmc_plane_helper_funcs
);
187 static void hibmc_crtc_atomic_enable(struct drm_crtc
*crtc
,
188 struct drm_crtc_state
*old_state
)
191 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
193 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
195 /* Enable display power gate & LOCALMEM power gate*/
196 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
197 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
198 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
199 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
200 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
201 hibmc_set_current_gate(priv
, reg
);
202 drm_crtc_vblank_on(crtc
);
205 static void hibmc_crtc_atomic_disable(struct drm_crtc
*crtc
,
206 struct drm_crtc_state
*old_state
)
209 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
211 drm_crtc_vblank_off(crtc
);
213 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_SLEEP
);
215 /* Enable display power gate & LOCALMEM power gate*/
216 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
217 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
218 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
219 reg
|= HIBMC_CURR_GATE_LOCALMEM(0);
220 reg
|= HIBMC_CURR_GATE_DISPLAY(0);
221 hibmc_set_current_gate(priv
, reg
);
224 static unsigned int format_pll_reg(void)
226 unsigned int pllreg
= 0;
227 struct hibmc_display_panel_pll pll
= {0};
230 * Note that all PLL's have the same format. Here,
231 * we just use Panel PLL parameter to work out the bit
232 * fields in the register.On returning a 32 bit number, the value can
233 * be applied to any PLL in the calling function.
235 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_BYPASS
, 0);
236 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POWER
, 1);
237 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_INPUT
, 0);
238 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_POD
, pll
.POD
);
239 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_OD
, pll
.OD
);
240 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_N
, pll
.N
);
241 pllreg
|= HIBMC_FIELD(HIBMC_PLL_CTRL_M
, pll
.M
);
246 static void set_vclock_hisilicon(struct drm_device
*dev
, unsigned long pll
)
249 struct hibmc_drm_private
*priv
= dev
->dev_private
;
251 val
= readl(priv
->mmio
+ CRT_PLL1_HS
);
252 val
&= ~(CRT_PLL1_HS_OUTER_BYPASS(1));
253 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
255 val
= CRT_PLL1_HS_INTER_BYPASS(1) | CRT_PLL1_HS_POWERON(1);
256 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
258 writel(pll
, priv
->mmio
+ CRT_PLL1_HS
);
260 usleep_range(1000, 2000);
262 val
= pll
& ~(CRT_PLL1_HS_POWERON(1));
263 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
265 usleep_range(1000, 2000);
267 val
&= ~(CRT_PLL1_HS_INTER_BYPASS(1));
268 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
270 usleep_range(1000, 2000);
272 val
|= CRT_PLL1_HS_OUTER_BYPASS(1);
273 writel(val
, priv
->mmio
+ CRT_PLL1_HS
);
276 static void get_pll_config(unsigned long x
, unsigned long y
,
277 u32
*pll1
, u32
*pll2
)
280 int count
= ARRAY_SIZE(hibmc_pll_table
);
282 for (i
= 0; i
< count
; i
++) {
283 if (hibmc_pll_table
[i
].hdisplay
== x
&&
284 hibmc_pll_table
[i
].vdisplay
== y
) {
285 *pll1
= hibmc_pll_table
[i
].pll1_config_value
;
286 *pll2
= hibmc_pll_table
[i
].pll2_config_value
;
291 /* if found none, we use default value */
292 *pll1
= CRT_PLL1_HS_25MHZ
;
293 *pll2
= CRT_PLL2_HS_25MHZ
;
297 * This function takes care the extra registers and bit fields required to
298 * setup a mode in board.
299 * Explanation about Display Control register:
300 * FPGA only supports 7 predefined pixel clocks, and clock select is
301 * in bit 4:0 of new register 0x802a8.
303 static unsigned int display_ctrl_adjust(struct drm_device
*dev
,
304 struct drm_display_mode
*mode
,
308 u32 pll1
; /* bit[31:0] of PLL */
309 u32 pll2
; /* bit[63:32] of PLL */
310 struct hibmc_drm_private
*priv
= dev
->dev_private
;
315 get_pll_config(x
, y
, &pll1
, &pll2
);
316 writel(pll2
, priv
->mmio
+ CRT_PLL2_HS
);
317 set_vclock_hisilicon(dev
, pll1
);
320 * Hisilicon has to set up the top-left and bottom-right
322 * Note that normal chip only use those two register for
323 * auto-centering mode.
325 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_TOP
, 0) |
326 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_TL_LEFT
, 0),
327 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_TL
);
329 writel(HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_BOTTOM
, y
- 1) |
330 HIBMC_FIELD(HIBMC_CRT_AUTO_CENTERING_BR_RIGHT
, x
- 1),
331 priv
->mmio
+ HIBMC_CRT_AUTO_CENTERING_BR
);
334 * Assume common fields in ctrl have been properly set before
335 * calling this function.
336 * This function only sets the extra fields in ctrl.
339 /* Set bit 25 of display controller: Select CRT or VGA clock */
340 ctrl
&= ~HIBMC_CRT_DISP_CTL_CRTSELECT_MASK
;
341 ctrl
&= ~HIBMC_CRT_DISP_CTL_CLOCK_PHASE_MASK
;
343 ctrl
|= HIBMC_CRT_DISP_CTL_CRTSELECT(HIBMC_CRTSELECT_CRT
);
345 /* clock_phase_polarity is 0 */
346 ctrl
|= HIBMC_CRT_DISP_CTL_CLOCK_PHASE(0);
348 writel(ctrl
, priv
->mmio
+ HIBMC_CRT_DISP_CTL
);
353 static void hibmc_crtc_mode_set_nofb(struct drm_crtc
*crtc
)
356 struct drm_display_mode
*mode
= &crtc
->state
->mode
;
357 struct drm_device
*dev
= crtc
->dev
;
358 struct hibmc_drm_private
*priv
= dev
->dev_private
;
359 int width
= mode
->hsync_end
- mode
->hsync_start
;
360 int height
= mode
->vsync_end
- mode
->vsync_start
;
362 writel(format_pll_reg(), priv
->mmio
+ HIBMC_CRT_PLL_CTRL
);
363 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_TOTAL
, mode
->htotal
- 1) |
364 HIBMC_FIELD(HIBMC_CRT_HORZ_TOTAL_DISP_END
, mode
->hdisplay
- 1),
365 priv
->mmio
+ HIBMC_CRT_HORZ_TOTAL
);
367 writel(HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_WIDTH
, width
) |
368 HIBMC_FIELD(HIBMC_CRT_HORZ_SYNC_START
, mode
->hsync_start
- 1),
369 priv
->mmio
+ HIBMC_CRT_HORZ_SYNC
);
371 writel(HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_TOTAL
, mode
->vtotal
- 1) |
372 HIBMC_FIELD(HIBMC_CRT_VERT_TOTAL_DISP_END
, mode
->vdisplay
- 1),
373 priv
->mmio
+ HIBMC_CRT_VERT_TOTAL
);
375 writel(HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_HEIGHT
, height
) |
376 HIBMC_FIELD(HIBMC_CRT_VERT_SYNC_START
, mode
->vsync_start
- 1),
377 priv
->mmio
+ HIBMC_CRT_VERT_SYNC
);
379 val
= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_VSYNC_PHASE
, 0);
380 val
|= HIBMC_FIELD(HIBMC_CRT_DISP_CTL_HSYNC_PHASE
, 0);
381 val
|= HIBMC_CRT_DISP_CTL_TIMING(1);
382 val
|= HIBMC_CRT_DISP_CTL_PLANE(1);
384 display_ctrl_adjust(dev
, mode
, val
);
387 static void hibmc_crtc_atomic_begin(struct drm_crtc
*crtc
,
388 struct drm_crtc_state
*old_state
)
391 struct drm_device
*dev
= crtc
->dev
;
392 struct hibmc_drm_private
*priv
= dev
->dev_private
;
394 hibmc_set_power_mode(priv
, HIBMC_PW_MODE_CTL_MODE_MODE0
);
396 /* Enable display power gate & LOCALMEM power gate*/
397 reg
= readl(priv
->mmio
+ HIBMC_CURRENT_GATE
);
398 reg
&= ~HIBMC_CURR_GATE_DISPLAY_MASK
;
399 reg
&= ~HIBMC_CURR_GATE_LOCALMEM_MASK
;
400 reg
|= HIBMC_CURR_GATE_DISPLAY(1);
401 reg
|= HIBMC_CURR_GATE_LOCALMEM(1);
402 hibmc_set_current_gate(priv
, reg
);
404 /* We can add more initialization as needed. */
407 static void hibmc_crtc_atomic_flush(struct drm_crtc
*crtc
,
408 struct drm_crtc_state
*old_state
)
413 spin_lock_irqsave(&crtc
->dev
->event_lock
, flags
);
414 if (crtc
->state
->event
)
415 drm_crtc_send_vblank_event(crtc
, crtc
->state
->event
);
416 crtc
->state
->event
= NULL
;
417 spin_unlock_irqrestore(&crtc
->dev
->event_lock
, flags
);
420 static int hibmc_crtc_enable_vblank(struct drm_crtc
*crtc
)
422 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
424 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(1),
425 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
430 static void hibmc_crtc_disable_vblank(struct drm_crtc
*crtc
)
432 struct hibmc_drm_private
*priv
= crtc
->dev
->dev_private
;
434 writel(HIBMC_RAW_INTERRUPT_EN_VBLANK(0),
435 priv
->mmio
+ HIBMC_RAW_INTERRUPT_EN
);
438 static const struct drm_crtc_funcs hibmc_crtc_funcs
= {
439 .page_flip
= drm_atomic_helper_page_flip
,
440 .set_config
= drm_atomic_helper_set_config
,
441 .destroy
= drm_crtc_cleanup
,
442 .reset
= drm_atomic_helper_crtc_reset
,
443 .atomic_duplicate_state
= drm_atomic_helper_crtc_duplicate_state
,
444 .atomic_destroy_state
= drm_atomic_helper_crtc_destroy_state
,
445 .enable_vblank
= hibmc_crtc_enable_vblank
,
446 .disable_vblank
= hibmc_crtc_disable_vblank
,
449 static const struct drm_crtc_helper_funcs hibmc_crtc_helper_funcs
= {
450 .mode_set_nofb
= hibmc_crtc_mode_set_nofb
,
451 .atomic_begin
= hibmc_crtc_atomic_begin
,
452 .atomic_flush
= hibmc_crtc_atomic_flush
,
453 .atomic_enable
= hibmc_crtc_atomic_enable
,
454 .atomic_disable
= hibmc_crtc_atomic_disable
,
457 int hibmc_de_init(struct hibmc_drm_private
*priv
)
459 struct drm_device
*dev
= priv
->dev
;
460 struct drm_crtc
*crtc
;
461 struct drm_plane
*plane
;
464 plane
= hibmc_plane_init(priv
);
466 DRM_ERROR("failed to create plane: %ld\n", PTR_ERR(plane
));
467 return PTR_ERR(plane
);
470 crtc
= devm_kzalloc(dev
->dev
, sizeof(*crtc
), GFP_KERNEL
);
472 DRM_ERROR("failed to alloc memory when init crtc\n");
476 ret
= drm_crtc_init_with_planes(dev
, crtc
, plane
,
477 NULL
, &hibmc_crtc_funcs
, NULL
);
479 DRM_ERROR("failed to init crtc: %d\n", ret
);
483 ret
= drm_mode_crtc_set_gamma_size(crtc
, 256);
485 DRM_ERROR("failed to set gamma size: %d\n", ret
);
488 drm_crtc_helper_add(crtc
, &hibmc_crtc_helper_funcs
);