coreboot
coreboot is an Open Source project aimed at replacing the proprietary BIOS found in most computers.
dc.c
Go to the documentation of this file.
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <stdint.h>
6 #include <device/device.h>
7 #include <soc/nvidia/tegra/dc.h>
8 #include <soc/display.h>
9 #include <framebuffer_info.h>
10 
11 #include "chip.h"
12 
13 int dump = 0;
14 unsigned long READL(void *p)
15 {
16  unsigned long value;
17 
18  /*
19  * In case of hard hung on readl(p), we can set dump > 1 to print out
20  * the address accessed.
21  */
22  if (dump > 1)
23  printk(BIOS_SPEW, "readl %p\n", p);
24 
25  value = read32(p);
26  if (dump)
27  printk(BIOS_SPEW, "readl %p %08lx\n", p, value);
28  return value;
29 }
30 
31 void WRITEL(unsigned long value, void *p)
32 {
33  if (dump)
34  printk(BIOS_SPEW, "writel %p %08lx\n", p, value);
35  write32(p, value);
36 }
37 
38 /* return in 1000ths of a Hertz */
40 {
41  int refresh;
42  int h_total = htotal(config);
43  int v_total = vtotal(config);
44  int pclk = config->pixel_clock;
45 
46  if (!pclk || !h_total || !v_total)
47  return 0;
48  refresh = pclk / h_total;
49  refresh *= 1000;
50  refresh /= v_total;
51  return refresh;
52 }
53 
54 static void print_mode(const struct soc_nvidia_tegra210_config *config)
55 {
56  if (config) {
59  "Panel Mode: %dx%d@%d.%03uHz pclk=%d\n",
60  config->xres, config->yres,
61  refresh / 1000, refresh % 1000,
62  config->pixel_clock);
63  }
64 }
65 
68 {
70 
71  printk(BIOS_ERR, "config: xres:yres: %d x %d\n ",
72  config->xres, config->yres);
73  printk(BIOS_ERR, " href_sync:vref_sync: %d x %d\n ",
74  config->href_to_sync, config->vref_to_sync);
75  printk(BIOS_ERR, " hsyn_width:vsyn_width: %d x %d\n ",
76  config->hsync_width, config->vsync_width);
77  printk(BIOS_ERR, " hfnt_porch:vfnt_porch: %d x %d\n ",
78  config->hfront_porch, config->vfront_porch);
79  printk(BIOS_ERR, " hbk_porch:vbk_porch: %d x %d\n ",
80  config->hback_porch, config->vback_porch);
81 
82  WRITEL(0x0, &disp_ctrl->disp.disp_timing_opt);
83  WRITEL(0x0, &disp_ctrl->disp.disp_color_ctrl);
84 
85  /* select win opt */
86  WRITEL(config->win_opt, &disp_ctrl->disp.disp_win_opt);
87 
88  WRITEL(config->vref_to_sync << 16 | config->href_to_sync,
89  &disp_ctrl->disp.ref_to_sync);
90 
91  WRITEL(config->vsync_width << 16 | config->hsync_width,
92  &disp_ctrl->disp.sync_width);
93 
94  WRITEL((config->vback_porch << 16) | config->hback_porch,
95  &disp_ctrl->disp.back_porch);
96 
97  WRITEL((config->vfront_porch << 16) | config->hfront_porch,
98  &disp_ctrl->disp.front_porch);
99 
100  WRITEL(config->xres | (config->yres << 16),
101  &disp_ctrl->disp.disp_active);
102 
103  /*
104  * PixelClock = (PLLD / 2) / ShiftClockDiv / PixelClockDiv.
105  *
106  * default: Set both shift_clk_div and pixel_clock_div to 1
107  */
109 
110  return 0;
111 }
112 
114  u32 shift_clock_div)
115 {
117  (shift_clock_div & 0xff) << SHIFT_CLK_DIVIDER_SHIFT,
118  &disp_ctrl->disp.disp_clk_ctrl);
119  printk(BIOS_DEBUG, "%s: ShiftClockDiv=%u\n",
120  __func__, shift_clock_div);
121 }
122 
123 /*
124  * update_window:
125  * set up window registers and activate window except two:
126  * frame buffer base address register (WINBUF_START_ADDR) and
127  * display enable register (_DISP_DISP_WIN_OPTIONS). This is
128  * because framebuffer is not available until payload stage.
129  */
131 {
132  struct display_controller *disp_ctrl =
133  (void *)config->display_controller;
134  u32 val;
135 
137 
138  WRITEL(((config->yres << 16) | config->xres), &disp_ctrl->win.size);
139 
140  WRITEL(((config->display_yres << 16) |
141  (config->display_xres *
142  config->framebuffer_bits_per_pixel / 8)),
143  &disp_ctrl->win.prescaled_size);
144 
145  val = ALIGN_UP((config->display_xres *
146  config->framebuffer_bits_per_pixel / 8), 64);
147  WRITEL(val, &disp_ctrl->win.line_stride);
148 
149  WRITEL(config->color_depth, &disp_ctrl->win.color_depth);
151 
152  WRITEL(((DDA_INC(config->display_yres, config->yres) << 16) |
153  DDA_INC(config->display_xres, config->xres)),
154  &disp_ctrl->win.dda_increment);
155 
157 
158  WRITEL(WRITE_MUX_ACTIVE, &disp_ctrl->cmd.state_access);
159 
160  WRITEL(0, &disp_ctrl->win.buffer_addr_mode);
161 
164  WRITEL(val, &disp_ctrl->cmd.disp_pow_ctrl);
165 
167  WRITEL(val, &disp_ctrl->cmd.state_ctrl);
168 
170  WRITEL(val, &disp_ctrl->cmd.state_ctrl);
171 }
172 
173 int tegra_dc_init(struct display_controller *disp_ctrl)
174 {
175  /* do not accept interrupts during initialization */
176  WRITEL(0x00000000, &disp_ctrl->cmd.int_mask);
178  &disp_ctrl->cmd.state_access);
180  WRITEL(0x00000000, &disp_ctrl->win.win_opt);
181  WRITEL(0x00000000, &disp_ctrl->win.byte_swap);
182  WRITEL(0x00000000, &disp_ctrl->win.buffer_ctrl);
183 
184  WRITEL(0x00000000, &disp_ctrl->win.pos);
185  WRITEL(0x00000000, &disp_ctrl->win.h_initial_dda);
186  WRITEL(0x00000000, &disp_ctrl->win.v_initial_dda);
187  WRITEL(0x00000000, &disp_ctrl->win.dda_increment);
188  WRITEL(0x00000000, &disp_ctrl->win.dv_ctrl);
189 
190  WRITEL(0x01000000, &disp_ctrl->win.blend_layer_ctrl);
191  WRITEL(0x00000000, &disp_ctrl->win.blend_match_select);
192  WRITEL(0x00000000, &disp_ctrl->win.blend_nomatch_select);
193  WRITEL(0x00000000, &disp_ctrl->win.blend_alpha_1bit);
194 
195  WRITEL(0x00000000, &disp_ctrl->winbuf.start_addr_hi);
196  WRITEL(0x00000000, &disp_ctrl->winbuf.addr_h_offset);
197  WRITEL(0x00000000, &disp_ctrl->winbuf.addr_v_offset);
198 
199  WRITEL(0x00000000, &disp_ctrl->com.crc_checksum);
200  WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[0]);
201  WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[1]);
202  WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[2]);
203  WRITEL(0x00000000, &disp_ctrl->com.pin_output_enb[3]);
204  WRITEL(0x00000000, &disp_ctrl->disp.disp_signal_opt0);
205 
206  return 0;
207 }
208 
209 /*
210  * Save mode to cb tables
211  */
214 {
215  const uint32_t bytes_per_line = ALIGN_UP(config->display_xres *
216  DIV_ROUND_UP(config->framebuffer_bits_per_pixel, 8), 64);
217  /* The framebuffer address is zero to let the payload allocate it */
218  fb_add_framebuffer_info(0, config->display_xres, config->display_yres,
219  bytes_per_line, config->framebuffer_bits_per_pixel);
220 }
pte_t value
Definition: mmu.c:91
static void write32(void *addr, uint32_t val)
Definition: mmio.h:40
static uint32_t read32(const void *addr)
Definition: mmio.h:22
#define ALIGN_UP(x, a)
Definition: helpers.h:17
#define DIV_ROUND_UP(x, y)
Definition: helpers.h:60
#define printk(level,...)
Definition: stdlib.h:16
static int tegra_calc_refresh(const struct soc_nvidia_tegra210_config *config)
Definition: dc.c:39
int tegra_dc_init(struct display_controller *disp_ctrl)
Definition: dc.c:173
int dump
Definition: dc.c:13
void pass_mode_info_to_payload(struct soc_nvidia_tegra210_config *config)
Definition: dc.c:212
void update_window(const struct soc_nvidia_tegra210_config *config)
Definition: dc.c:130
void update_display_shift_clock_divider(struct display_controller *disp_ctrl, u32 shift_clock_div)
Definition: dc.c:113
int update_display_mode(struct display_controller *disp_ctrl, struct soc_nvidia_tegra210_config *config)
Definition: dc.c:66
unsigned long READL(void *p)
Definition: dc.c:14
static void print_mode(const struct soc_nvidia_tegra210_config *config)
Definition: dc.c:54
void WRITEL(unsigned long value, void *p)
Definition: dc.c:31
#define PW2_ENABLE
Definition: dc.h:362
#define SHIFT_CLK_DIVIDER(x)
Definition: dc.h:430
#define WINDOW_A_SELECT
Definition: dc.h:394
#define WIN_A_UPDATE
Definition: dc.h:385
#define PW4_ENABLE
Definition: dc.h:364
#define PW1_ENABLE
Definition: dc.h:361
#define READ_MUX_ASSEMBLY
Definition: dc.h:371
#define WIN_A_ACT_REQ
Definition: dc.h:378
#define PIXEL_CLK_DIVIDER_SHIFT
Definition: dc.h:413
#define PW3_ENABLE
Definition: dc.h:363
#define WRITE_MUX_ASSEMBLY
Definition: dc.h:373
#define GENERAL_ACT_REQ
Definition: dc.h:377
#define DDA_INC(prescaled_size, post_scaled_size)
Definition: dc.h:470
#define PM0_ENABLE
Definition: dc.h:365
#define DISP_CTRL_MODE_C_DISPLAY
Definition: dc.h:354
#define GENERAL_UPDATE
Definition: dc.h:384
#define PM1_ENABLE
Definition: dc.h:366
#define PW0_ENABLE
Definition: dc.h:360
@ PIXEL_CLK_DIVIDER_PCD1
Definition: dc.h:416
#define SHIFT_CLK_DIVIDER_SHIFT
Definition: dc.h:411
struct fb_info * fb_add_framebuffer_info(uintptr_t fb_addr, uint32_t x_resolution, uint32_t y_resolution, uint32_t bytes_per_line, uint8_t bits_per_pixel)
Definition: edid_fill_fb.c:89
int refresh
Definition: edid.c:994
#define BIOS_DEBUG
BIOS_DEBUG - Verbose output.
Definition: loglevel.h:128
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
Definition: loglevel.h:72
#define BIOS_SPEW
BIOS_SPEW - Excessively verbose output.
Definition: loglevel.h:142
enum board_config config
Definition: memory.c:448
#define vtotal(mode)
Definition: display.h:19
#define htotal(mode)
Definition: display.h:15
#define COLOR_BLACK
Definition: display.h:7
unsigned int uint32_t
Definition: stdint.h:14
uint32_t u32
Definition: stdint.h:51
u32 disp_cmd
Definition: dc.h:49
u32 state_ctrl
Definition: dc.h:69
u32 int_mask
Definition: dc.h:57
u32 disp_win_header
Definition: dc.h:70
u32 state_access
Definition: dc.h:68
u32 disp_pow_ctrl
Definition: dc.h:55
u32 pin_output_enb[PIN_REG_COUNT]
Definition: dc.h:87
u32 crc_checksum
Definition: dc.h:84
u32 disp_clk_ctrl
Definition: dc.h:203
u32 disp_color_ctrl
Definition: dc.h:205
u32 back_porch
Definition: dc.h:185
u32 disp_timing_opt
Definition: dc.h:182
u32 disp_win_opt
Definition: dc.h:180
u32 disp_active
Definition: dc.h:186
u32 front_porch
Definition: dc.h:187
u32 disp_signal_opt0
Definition: dc.h:178
u32 blend_background_color
Definition: dc.h:240
u32 ref_to_sync
Definition: dc.h:183
u32 sync_width
Definition: dc.h:184
u32 blend_alpha_1bit
Definition: dc.h:306
u32 blend_nomatch_select
Definition: dc.h:305
u32 line_stride
Definition: dc.h:291
u32 dv_ctrl
Definition: dc.h:295
u32 byte_swap
Definition: dc.h:282
u32 dda_increment
Definition: dc.h:290
u32 size
Definition: dc.h:286
u32 buffer_addr_mode
Definition: dc.h:294
u32 h_initial_dda
Definition: dc.h:288
u32 blend_layer_ctrl
Definition: dc.h:303
u32 color_depth
Definition: dc.h:284
u32 blend_match_select
Definition: dc.h:304
u32 prescaled_size
Definition: dc.h:287
u32 pos
Definition: dc.h:285
u32 buffer_ctrl
Definition: dc.h:283
u32 v_initial_dda
Definition: dc.h:289
u32 win_opt
Definition: dc.h:281
u32 addr_v_offset
Definition: dc.h:321
u32 addr_h_offset
Definition: dc.h:319
u32 start_addr_hi
Definition: dc.h:326
struct dc_cmd_reg cmd
Definition: dc.h:332
struct dc_winbuf_reg winbuf
Definition: dc.h:347
struct dc_disp_reg disp
Definition: dc.h:338
struct dc_com_reg com
Definition: dc.h:335
struct dc_win_reg win
Definition: dc.h:344
u8 val
Definition: sys.c:300
@ WRITE_MUX_ACTIVE
Definition: emc.h:50