2 * Copyright (c) 2011 The Chromium OS Authors.
3 * SPDX-License-Identifier: GPL-2.0+
11 #include <asm/system.h>
15 #include <asm/arch/clock.h>
16 #include <asm/arch/funcmux.h>
17 #include <asm/arch/pinmux.h>
18 #include <asm/arch/pwm.h>
19 #include <asm/arch/display.h>
20 #include <asm/arch-tegra/timer.h>
22 DECLARE_GLOBAL_DATA_PTR
;
24 /* These are the stages we go throuh in enabling the LCD */
35 #define FDT_LCD_TIMINGS 4
38 FDT_LCD_TIMING_REF_TO_SYNC
,
39 FDT_LCD_TIMING_SYNC_WIDTH
,
40 FDT_LCD_TIMING_BACK_PORCH
,
41 FDT_LCD_TIMING_FRONT_PORCH
,
47 FDT_LCD_CACHE_OFF
= 0,
48 FDT_LCD_CACHE_WRITE_THROUGH
= 1 << 0,
49 FDT_LCD_CACHE_WRITE_BACK
= 1 << 1,
50 FDT_LCD_CACHE_FLUSH
= 1 << 2,
51 FDT_LCD_CACHE_WRITE_BACK_FLUSH
= FDT_LCD_CACHE_WRITE_BACK
|
55 /* Information about the display controller */
56 struct tegra_lcd_priv
{
57 enum stage_t stage
; /* Current stage we are at */
58 unsigned long timer_next
; /* Time we can move onto next stage */
59 int width
; /* width in pixels */
60 int height
; /* height in pixels */
63 * log2 of number of bpp, in general, unless it bpp is 24 in which
64 * case this field holds 24 also! This is a U-Boot thing.
67 struct disp_ctlr
*disp
; /* Display controller to use */
68 fdt_addr_t frame_buffer
; /* Address of frame buffer */
69 unsigned pixel_clock
; /* Pixel clock in Hz */
70 uint horiz_timing
[FDT_LCD_TIMING_COUNT
]; /* Horizontal timing */
71 uint vert_timing
[FDT_LCD_TIMING_COUNT
]; /* Vertical timing */
73 int pwm_channel
; /* PWM channel to use for backlight */
74 enum lcd_cache_t cache_type
;
76 struct gpio_desc backlight_en
; /* GPIO for backlight enable */
77 struct gpio_desc lvds_shutdown
; /* GPIO for lvds shutdown */
78 struct gpio_desc backlight_vdd
; /* GPIO for backlight vdd */
79 struct gpio_desc panel_vdd
; /* GPIO for panel vdd */
81 * Panel required timings
82 * Timing 1: delay between panel_vdd-rise and data-rise
83 * Timing 2: delay between data-rise and backlight_vdd-rise
84 * Timing 3: delay between backlight_vdd and pwm-rise
85 * Timing 4: delay between pwm-rise and backlight_en-rise
87 uint panel_timings
[FDT_LCD_TIMINGS
];
91 /* Maximum LCD size we support */
94 LCD_MAX_LOG2_BPP
= VIDEO_BPP16
,
97 static void update_window(struct dc_ctlr
*dc
, struct disp_ctl_win
*win
)
99 unsigned h_dda
, v_dda
;
102 val
= readl(&dc
->cmd
.disp_win_header
);
103 val
|= WINDOW_A_SELECT
;
104 writel(val
, &dc
->cmd
.disp_win_header
);
106 writel(win
->fmt
, &dc
->win
.color_depth
);
108 clrsetbits_le32(&dc
->win
.byte_swap
, BYTE_SWAP_MASK
,
109 BYTE_SWAP_NOSWAP
<< BYTE_SWAP_SHIFT
);
111 val
= win
->out_x
<< H_POSITION_SHIFT
;
112 val
|= win
->out_y
<< V_POSITION_SHIFT
;
113 writel(val
, &dc
->win
.pos
);
115 val
= win
->out_w
<< H_SIZE_SHIFT
;
116 val
|= win
->out_h
<< V_SIZE_SHIFT
;
117 writel(val
, &dc
->win
.size
);
119 val
= (win
->w
* win
->bpp
/ 8) << H_PRESCALED_SIZE_SHIFT
;
120 val
|= win
->h
<< V_PRESCALED_SIZE_SHIFT
;
121 writel(val
, &dc
->win
.prescaled_size
);
123 writel(0, &dc
->win
.h_initial_dda
);
124 writel(0, &dc
->win
.v_initial_dda
);
126 h_dda
= (win
->w
* 0x1000) / max(win
->out_w
- 1, 1U);
127 v_dda
= (win
->h
* 0x1000) / max(win
->out_h
- 1, 1U);
129 val
= h_dda
<< H_DDA_INC_SHIFT
;
130 val
|= v_dda
<< V_DDA_INC_SHIFT
;
131 writel(val
, &dc
->win
.dda_increment
);
133 writel(win
->stride
, &dc
->win
.line_stride
);
134 writel(0, &dc
->win
.buf_stride
);
139 writel(val
, &dc
->win
.win_opt
);
141 writel((unsigned long)win
->phys_addr
, &dc
->winbuf
.start_addr
);
142 writel(win
->x
, &dc
->winbuf
.addr_h_offset
);
143 writel(win
->y
, &dc
->winbuf
.addr_v_offset
);
145 writel(0xff00, &dc
->win
.blend_nokey
);
146 writel(0xff00, &dc
->win
.blend_1win
);
148 val
= GENERAL_ACT_REQ
| WIN_A_ACT_REQ
;
149 val
|= GENERAL_UPDATE
| WIN_A_UPDATE
;
150 writel(val
, &dc
->cmd
.state_ctrl
);
153 static void write_pair(struct tegra_lcd_priv
*priv
, int item
, u32
*reg
)
155 writel(priv
->horiz_timing
[item
] |
156 (priv
->vert_timing
[item
] << 16), reg
);
159 static int update_display_mode(struct dc_disp_reg
*disp
,
160 struct tegra_lcd_priv
*priv
)
166 writel(0x0, &disp
->disp_timing_opt
);
167 write_pair(priv
, FDT_LCD_TIMING_REF_TO_SYNC
, &disp
->ref_to_sync
);
168 write_pair(priv
, FDT_LCD_TIMING_SYNC_WIDTH
, &disp
->sync_width
);
169 write_pair(priv
, FDT_LCD_TIMING_BACK_PORCH
, &disp
->back_porch
);
170 write_pair(priv
, FDT_LCD_TIMING_FRONT_PORCH
, &disp
->front_porch
);
172 writel(priv
->width
| (priv
->height
<< 16), &disp
->disp_active
);
174 val
= DE_SELECT_ACTIVE
<< DE_SELECT_SHIFT
;
175 val
|= DE_CONTROL_NORMAL
<< DE_CONTROL_SHIFT
;
176 writel(val
, &disp
->data_enable_opt
);
178 val
= DATA_FORMAT_DF1P1C
<< DATA_FORMAT_SHIFT
;
179 val
|= DATA_ALIGNMENT_MSB
<< DATA_ALIGNMENT_SHIFT
;
180 val
|= DATA_ORDER_RED_BLUE
<< DATA_ORDER_SHIFT
;
181 writel(val
, &disp
->disp_interface_ctrl
);
184 * The pixel clock divider is in 7.1 format (where the bottom bit
185 * represents 0.5). Here we calculate the divider needed to get from
186 * the display clock (typically 600MHz) to the pixel clock. We round
187 * up or down as requried.
189 rate
= clock_get_periph_rate(PERIPH_ID_DISP1
, CLOCK_ID_CGENERAL
);
190 div
= ((rate
* 2 + priv
->pixel_clock
/ 2) / priv
->pixel_clock
) - 2;
191 debug("Display clock %lu, divider %lu\n", rate
, div
);
193 writel(0x00010001, &disp
->shift_clk_opt
);
195 val
= PIXEL_CLK_DIVIDER_PCD1
<< PIXEL_CLK_DIVIDER_SHIFT
;
196 val
|= div
<< SHIFT_CLK_DIVIDER_SHIFT
;
197 writel(val
, &disp
->disp_clk_ctrl
);
202 /* Start up the display and turn on power to PWMs */
203 static void basic_init(struct dc_cmd_reg
*cmd
)
207 writel(0x00000100, &cmd
->gen_incr_syncpt_ctrl
);
208 writel(0x0000011a, &cmd
->cont_syncpt_vsync
);
209 writel(0x00000000, &cmd
->int_type
);
210 writel(0x00000000, &cmd
->int_polarity
);
211 writel(0x00000000, &cmd
->int_mask
);
212 writel(0x00000000, &cmd
->int_enb
);
214 val
= PW0_ENABLE
| PW1_ENABLE
| PW2_ENABLE
;
215 val
|= PW3_ENABLE
| PW4_ENABLE
| PM0_ENABLE
;
217 writel(val
, &cmd
->disp_pow_ctrl
);
219 val
= readl(&cmd
->disp_cmd
);
220 val
|= CTRL_MODE_C_DISPLAY
<< CTRL_MODE_SHIFT
;
221 writel(val
, &cmd
->disp_cmd
);
224 static void basic_init_timer(struct dc_disp_reg
*disp
)
226 writel(0x00000020, &disp
->mem_high_pri
);
227 writel(0x00000001, &disp
->mem_high_pri_timer
);
230 static const u32 rgb_enb_tab
[PIN_REG_COUNT
] = {
237 static const u32 rgb_polarity_tab
[PIN_REG_COUNT
] = {
244 static const u32 rgb_data_tab
[PIN_REG_COUNT
] = {
251 static const u32 rgb_sel_tab
[PIN_OUTPUT_SEL_COUNT
] = {
261 static void rgb_enable(struct dc_com_reg
*com
)
265 for (i
= 0; i
< PIN_REG_COUNT
; i
++) {
266 writel(rgb_enb_tab
[i
], &com
->pin_output_enb
[i
]);
267 writel(rgb_polarity_tab
[i
], &com
->pin_output_polarity
[i
]);
268 writel(rgb_data_tab
[i
], &com
->pin_output_data
[i
]);
271 for (i
= 0; i
< PIN_OUTPUT_SEL_COUNT
; i
++)
272 writel(rgb_sel_tab
[i
], &com
->pin_output_sel
[i
]);
275 static int setup_window(struct disp_ctl_win
*win
,
276 struct tegra_lcd_priv
*priv
)
280 win
->w
= priv
->width
;
281 win
->h
= priv
->height
;
284 win
->out_w
= priv
->width
;
285 win
->out_h
= priv
->height
;
286 win
->phys_addr
= priv
->frame_buffer
;
287 win
->stride
= priv
->width
* (1 << priv
->log2_bpp
) / 8;
288 debug("%s: depth = %d\n", __func__
, priv
->log2_bpp
);
289 switch (priv
->log2_bpp
) {
292 win
->fmt
= COLOR_DEPTH_R8G8B8A8
;
296 win
->fmt
= COLOR_DEPTH_B5G6R5
;
301 debug("Unsupported LCD bit depth");
308 static void debug_timing(const char *name
, unsigned int timing
[])
313 debug("%s timing: ", name
);
314 for (i
= 0; i
< FDT_LCD_TIMING_COUNT
; i
++)
315 debug("%d ", timing
[i
]);
321 * Register a new display based on device tree configuration.
323 * The frame buffer can be positioned by U-Boot or overriden by the fdt.
324 * You should pass in the U-Boot address here, and check the contents of
325 * struct tegra_lcd_priv to see what was actually chosen.
327 * @param blob Device tree blob
328 * @param priv Driver's private data
329 * @param default_lcd_base Default address of LCD frame buffer
330 * @return 0 if ok, -1 on error (unsupported bits per pixel)
332 static int tegra_display_probe(const void *blob
, struct tegra_lcd_priv
*priv
,
333 void *default_lcd_base
)
335 struct disp_ctl_win window
;
338 priv
->frame_buffer
= (u32
)default_lcd_base
;
340 dc
= (struct dc_ctlr
*)priv
->disp
;
343 * A header file for clock constants was NAKed upstream.
344 * TODO: Put this into the FDT and fdt_lcd struct when we have clock
347 clock_start_periph_pll(PERIPH_ID_HOST1X
, CLOCK_ID_PERIPH
,
349 clock_start_periph_pll(PERIPH_ID_DISP1
, CLOCK_ID_CGENERAL
,
351 basic_init(&dc
->cmd
);
352 basic_init_timer(&dc
->disp
);
353 rgb_enable(&dc
->com
);
355 if (priv
->pixel_clock
)
356 update_display_mode(&dc
->disp
, priv
);
358 if (setup_window(&window
, priv
))
361 update_window(dc
, &window
);
367 * Handle the next stage of device init
369 static int handle_stage(const void *blob
, struct tegra_lcd_priv
*priv
)
371 debug("%s: stage %d\n", __func__
, priv
->stage
);
373 /* do the things for this stage */
374 switch (priv
->stage
) {
377 * It is possible that the FDT has requested that the LCD be
378 * disabled. We currently don't support this. It would require
379 * changes to U-Boot LCD subsystem to have LCD support
380 * compiled in but not used. An easier option might be to
381 * still have a frame buffer, but leave the backlight off and
382 * remove all mention of lcd in the stdout environment
386 funcmux_select(PERIPH_ID_DISP1
, FUNCMUX_DEFAULT
);
388 case STAGE_PANEL_VDD
:
389 if (dm_gpio_is_valid(&priv
->panel_vdd
))
390 dm_gpio_set_value(&priv
->panel_vdd
, 1);
393 if (dm_gpio_is_valid(&priv
->lvds_shutdown
))
394 dm_gpio_set_value(&priv
->lvds_shutdown
, 1);
396 case STAGE_BACKLIGHT_VDD
:
397 if (dm_gpio_is_valid(&priv
->backlight_vdd
))
398 dm_gpio_set_value(&priv
->backlight_vdd
, 1);
401 /* Enable PWM at 15/16 high, 32768 Hz with divider 1 */
402 pinmux_set_func(PMUX_PINGRP_GPU
, PMUX_FUNC_PWM
);
403 pinmux_tristate_disable(PMUX_PINGRP_GPU
);
405 pwm_set_config(priv
->pwm
, priv
->pwm_channel
, 0xdf, 0xff);
406 pwm_set_enable(priv
->pwm
, priv
->pwm_channel
, true);
408 case STAGE_BACKLIGHT_EN
:
409 if (dm_gpio_is_valid(&priv
->backlight_en
))
410 dm_gpio_set_value(&priv
->backlight_en
, 1);
416 /* set up timer for next stage */
417 priv
->timer_next
= timer_get_us();
418 if (priv
->stage
< FDT_LCD_TIMINGS
)
419 priv
->timer_next
+= priv
->panel_timings
[priv
->stage
] * 1000;
421 /* move to next stage */
427 * Perform the next stage of the LCD init if it is time to do so.
429 * LCD init can be time-consuming because of the number of delays we need
430 * while waiting for the backlight power supply, etc. This function can
431 * be called at various times during U-Boot operation to advance the
432 * initialization of the LCD to the next stage if sufficient time has
433 * passed since the last stage. It keeps track of what stage it is up to
434 * and the time that it is permitted to move to the next stage.
436 * The final call should have wait=1 to complete the init.
438 * @param blob fdt blob containing LCD information
439 * @param wait 1 to wait until all init is complete, and then return
440 * 0 to return immediately, potentially doing nothing if it is
441 * not yet time for the next init.
443 static int tegra_lcd_check_next_stage(const void *blob
,
444 struct tegra_lcd_priv
*priv
, int wait
)
446 if (priv
->stage
== STAGE_DONE
)
450 /* wait if we need to */
451 debug("%s: stage %d\n", __func__
, priv
->stage
);
452 if (priv
->stage
!= STAGE_START
) {
453 int delay
= priv
->timer_next
- timer_get_us();
463 if (handle_stage(blob
, priv
))
465 } while (wait
&& priv
->stage
!= STAGE_DONE
);
466 if (priv
->stage
== STAGE_DONE
)
467 debug("%s: LCD init complete\n", __func__
);
472 static int tegra_lcd_probe(struct udevice
*dev
)
474 struct video_uc_platdata
*plat
= dev_get_uclass_platdata(dev
);
475 struct video_priv
*uc_priv
= dev_get_uclass_priv(dev
);
476 struct tegra_lcd_priv
*priv
= dev_get_priv(dev
);
477 const void *blob
= gd
->fdt_blob
;
478 int type
= DCACHE_OFF
;
480 /* Initialize the Tegra display controller */
481 if (tegra_display_probe(blob
, priv
, (void *)plat
->base
)) {
482 printf("%s: Failed to probe display driver\n", __func__
);
486 tegra_lcd_check_next_stage(blob
, priv
, 1);
488 /* Set up the LCD caching as requested */
489 if (priv
->cache_type
& FDT_LCD_CACHE_WRITE_THROUGH
)
490 type
= DCACHE_WRITETHROUGH
;
491 else if (priv
->cache_type
& FDT_LCD_CACHE_WRITE_BACK
)
492 type
= DCACHE_WRITEBACK
;
493 mmu_set_region_dcache_behaviour(priv
->frame_buffer
, plat
->size
, type
);
495 /* Enable flushing after LCD writes if requested */
496 video_set_flush_dcache(dev
, priv
->cache_type
& FDT_LCD_CACHE_FLUSH
);
498 uc_priv
->xsize
= priv
->width
;
499 uc_priv
->ysize
= priv
->height
;
500 uc_priv
->bpix
= priv
->log2_bpp
;
501 debug("LCD frame buffer at %pa, size %x\n", &priv
->frame_buffer
,
507 static int tegra_lcd_ofdata_to_platdata(struct udevice
*dev
)
509 struct tegra_lcd_priv
*priv
= dev_get_priv(dev
);
510 struct fdtdec_phandle_args args
;
511 const void *blob
= gd
->fdt_blob
;
512 int node
= dev
->of_offset
;
513 int front
, back
, ref
;
519 priv
->disp
= (struct disp_ctlr
*)dev_get_addr(dev
);
521 debug("%s: No display controller address\n", __func__
);
525 rgb
= fdt_subnode_offset(blob
, node
, "rgb");
527 panel_node
= fdtdec_lookup_phandle(blob
, rgb
, "nvidia,panel");
528 if (panel_node
< 0) {
529 debug("%s: Cannot find panel information\n", __func__
);
533 priv
->width
= fdtdec_get_int(blob
, panel_node
, "xres", -1);
534 priv
->height
= fdtdec_get_int(blob
, panel_node
, "yres", -1);
535 priv
->pixel_clock
= fdtdec_get_int(blob
, panel_node
, "clock", 0);
536 if (!priv
->pixel_clock
|| priv
->width
== -1 || priv
->height
== -1) {
537 debug("%s: Pixel parameters missing\n", __func__
);
541 back
= fdtdec_get_int(blob
, panel_node
, "left-margin", -1);
542 front
= fdtdec_get_int(blob
, panel_node
, "right-margin", -1);
543 ref
= fdtdec_get_int(blob
, panel_node
, "hsync-len", -1);
544 if ((back
| front
| ref
) == -1) {
545 debug("%s: Horizontal parameters missing\n", __func__
);
549 /* Use a ref-to-sync of 1 always, and take this from the front porch */
550 priv
->horiz_timing
[FDT_LCD_TIMING_REF_TO_SYNC
] = 1;
551 priv
->horiz_timing
[FDT_LCD_TIMING_SYNC_WIDTH
] = ref
;
552 priv
->horiz_timing
[FDT_LCD_TIMING_BACK_PORCH
] = back
;
553 priv
->horiz_timing
[FDT_LCD_TIMING_FRONT_PORCH
] = front
-
554 priv
->horiz_timing
[FDT_LCD_TIMING_REF_TO_SYNC
];
555 debug_timing("horiz", priv
->horiz_timing
);
557 back
= fdtdec_get_int(blob
, panel_node
, "upper-margin", -1);
558 front
= fdtdec_get_int(blob
, panel_node
, "lower-margin", -1);
559 ref
= fdtdec_get_int(blob
, panel_node
, "vsync-len", -1);
560 if ((back
| front
| ref
) == -1) {
561 debug("%s: Vertical parameters missing\n", __func__
);
565 priv
->vert_timing
[FDT_LCD_TIMING_REF_TO_SYNC
] = 1;
566 priv
->vert_timing
[FDT_LCD_TIMING_SYNC_WIDTH
] = ref
;
567 priv
->vert_timing
[FDT_LCD_TIMING_BACK_PORCH
] = back
;
568 priv
->vert_timing
[FDT_LCD_TIMING_FRONT_PORCH
] = front
-
569 priv
->vert_timing
[FDT_LCD_TIMING_REF_TO_SYNC
];
570 debug_timing("vert", priv
->vert_timing
);
572 bpp
= fdtdec_get_int(blob
, panel_node
, "nvidia,bits-per-pixel", -1);
574 if (bpp
== (1 << bit
))
575 priv
->log2_bpp
= bit
;
577 priv
->log2_bpp
= bpp
;
579 debug("%s: Pixel bpp parameters missing\n", __func__
);
583 if (fdtdec_parse_phandle_with_args(blob
, panel_node
, "nvidia,pwm",
584 "#pwm-cells", 0, 0, &args
)) {
585 debug("%s: Unable to decode PWM\n", __func__
);
589 ret
= uclass_get_device_by_of_offset(UCLASS_PWM
, args
.node
, &priv
->pwm
);
591 debug("%s: Unable to find PWM\n", __func__
);
594 priv
->pwm_channel
= args
.args
[0];
596 priv
->cache_type
= fdtdec_get_int(blob
, panel_node
, "nvidia,cache-type",
597 FDT_LCD_CACHE_WRITE_BACK_FLUSH
);
599 /* These GPIOs are all optional */
600 gpio_request_by_name_nodev(blob
, panel_node
,
601 "nvidia,backlight-enable-gpios", 0,
602 &priv
->backlight_en
, GPIOD_IS_OUT
);
603 gpio_request_by_name_nodev(blob
, panel_node
,
604 "nvidia,lvds-shutdown-gpios", 0,
605 &priv
->lvds_shutdown
, GPIOD_IS_OUT
);
606 gpio_request_by_name_nodev(blob
, panel_node
,
607 "nvidia,backlight-vdd-gpios", 0,
608 &priv
->backlight_vdd
, GPIOD_IS_OUT
);
609 gpio_request_by_name_nodev(blob
, panel_node
,
610 "nvidia,panel-vdd-gpios", 0,
611 &priv
->panel_vdd
, GPIOD_IS_OUT
);
613 if (fdtdec_get_int_array(blob
, panel_node
, "nvidia,panel-timings",
614 priv
->panel_timings
, FDT_LCD_TIMINGS
))
620 static int tegra_lcd_bind(struct udevice
*dev
)
622 struct video_uc_platdata
*plat
= dev_get_uclass_platdata(dev
);
624 plat
->size
= LCD_MAX_WIDTH
* LCD_MAX_HEIGHT
*
625 (1 << LCD_MAX_LOG2_BPP
) / 8;
630 static const struct video_ops tegra_lcd_ops
= {
633 static const struct udevice_id tegra_lcd_ids
[] = {
634 { .compatible
= "nvidia,tegra20-dc" },
638 U_BOOT_DRIVER(tegra_lcd
) = {
641 .of_match
= tegra_lcd_ids
,
642 .ops
= &tegra_lcd_ops
,
643 .bind
= tegra_lcd_bind
,
644 .probe
= tegra_lcd_probe
,
645 .ofdata_to_platdata
= tegra_lcd_ofdata_to_platdata
,
646 .priv_auto_alloc_size
= sizeof(struct tegra_lcd_priv
),