Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 1 | /* |
| 2 | * This file is part of the coreboot project. |
| 3 | * |
| 4 | * Copyright 2013 Google Inc. |
| 5 | * |
| 6 | * This program is free software; you can redistribute it and/or modify |
| 7 | * it under the terms of the GNU General Public License as published by |
| 8 | * the Free Software Foundation; version 2 of the License. |
| 9 | * |
| 10 | * This program is distributed in the hope that it will be useful, |
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 13 | * GNU General Public License for more details. |
| 14 | * |
| 15 | * You should have received a copy of the GNU General Public License |
| 16 | * along with this program; if not, write to the Free Software |
| 17 | * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
| 18 | */ |
| 19 | |
| 20 | #include <console/console.h> |
| 21 | #include <arch/io.h> |
| 22 | #include <stdint.h> |
| 23 | #include <lib.h> |
| 24 | #include <stdlib.h> |
| 25 | #include <delay.h> |
| 26 | #include <soc/addressmap.h> |
| 27 | #include <device/device.h> |
| 28 | #include <stdlib.h> |
| 29 | #include <string.h> |
| 30 | #include <cpu/cpu.h> |
| 31 | #include <boot/tables.h> |
| 32 | #include <cbmem.h> |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 33 | #include <edid.h> |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 34 | #include <soc/clock.h> |
| 35 | #include <soc/nvidia/tegra/dc.h> |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 36 | #include "chip.h" |
| 37 | #include <soc/display.h> |
| 38 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 39 | int dump = 0; |
| 40 | unsigned long READL(void * p); |
| 41 | void WRITEL(unsigned long value, void * p); |
| 42 | unsigned long READL(void * p) |
| 43 | { |
| 44 | unsigned long value = readl(p); |
| 45 | if (dump) |
| 46 | printk(BIOS_SPEW, "readl %p %08lx\n", p, value); |
| 47 | return value; |
| 48 | } |
| 49 | |
| 50 | |
| 51 | void WRITEL(unsigned long value, void * p) |
| 52 | { |
| 53 | if (dump) |
| 54 | printk(BIOS_SPEW, "writel %p %08lx\n", p, value); |
| 55 | writel(value, p); |
| 56 | } |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 57 | |
| 58 | static const u32 rgb_enb_tab[PIN_REG_COUNT] = { |
| 59 | 0x00000000, |
| 60 | 0x00000000, |
| 61 | 0x00000000, |
| 62 | 0x00000000, |
| 63 | }; |
| 64 | |
| 65 | static const u32 rgb_polarity_tab[PIN_REG_COUNT] = { |
| 66 | 0x00000000, |
| 67 | 0x01000000, |
| 68 | 0x00000000, |
| 69 | 0x00000000, |
| 70 | }; |
| 71 | |
| 72 | static const u32 rgb_data_tab[PIN_REG_COUNT] = { |
| 73 | 0x00000000, |
| 74 | 0x00000000, |
| 75 | 0x00000000, |
| 76 | 0x00000000, |
| 77 | }; |
| 78 | |
| 79 | static const u32 rgb_sel_tab[PIN_OUTPUT_SEL_COUNT] = { |
| 80 | 0x00000000, |
| 81 | 0x00000000, |
| 82 | 0x00000000, |
| 83 | 0x00000000, |
| 84 | 0x00210222, |
| 85 | 0x00002200, |
| 86 | 0x00020000, |
| 87 | }; |
| 88 | |
| 89 | static int update_display_mode(struct dc_disp_reg *disp, |
Julius Werner | edf6b57 | 2013-10-25 17:49:26 -0700 | [diff] [blame] | 90 | struct soc_nvidia_tegra124_config *config) |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 91 | { |
| 92 | u32 val; |
| 93 | u32 rate; |
| 94 | u32 div; |
| 95 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 96 | WRITEL(0x0, &disp->disp_timing_opt); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 97 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 98 | WRITEL(config->vref_to_sync << 16 | config->href_to_sync, |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 99 | &disp->ref_to_sync); |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 100 | WRITEL(config->vsync_width << 16 | config->hsync_width, &disp->sync_width); |
| 101 | WRITEL(config->vback_porch << 16 | config->hback_porch, &disp->back_porch); |
| 102 | WRITEL(config->vfront_porch << 16 | config->hfront_porch, |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 103 | &disp->front_porch); |
| 104 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 105 | WRITEL(config->xres | (config->yres << 16), &disp->disp_active); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 106 | |
| 107 | val = DE_SELECT_ACTIVE << DE_SELECT_SHIFT; |
| 108 | val |= DE_CONTROL_NORMAL << DE_CONTROL_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 109 | WRITEL(val, &disp->data_enable_opt); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 110 | |
| 111 | val = DATA_FORMAT_DF1P1C << DATA_FORMAT_SHIFT; |
| 112 | val |= DATA_ALIGNMENT_MSB << DATA_ALIGNMENT_SHIFT; |
| 113 | val |= DATA_ORDER_RED_BLUE << DATA_ORDER_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 114 | WRITEL(val, &disp->disp_interface_ctrl); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 115 | |
| 116 | /* |
| 117 | * The pixel clock divider is in 7.1 format (where the bottom bit |
| 118 | * represents 0.5). Here we calculate the divider needed to get from |
| 119 | * the display clock (typically 600MHz) to the pixel clock. We round |
| 120 | * up or down as requried. |
| 121 | * We use pllp for now. |
| 122 | */ |
| 123 | rate = 600 * 1000000; |
| 124 | div = ((rate * 2 + config->pixel_clock / 2) / config->pixel_clock) - 2; |
| 125 | printk(BIOS_SPEW, "Display clock %d, divider %d\n", rate, div); |
| 126 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 127 | WRITEL(0x00010001, &disp->shift_clk_opt); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 128 | |
| 129 | val = PIXEL_CLK_DIVIDER_PCD1 << PIXEL_CLK_DIVIDER_SHIFT; |
| 130 | val |= div << SHIFT_CLK_DIVIDER_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 131 | WRITEL(val, &disp->disp_clk_ctrl); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 132 | |
| 133 | return 0; |
| 134 | } |
| 135 | |
| 136 | static int setup_window(struct disp_ctl_win *win, |
| 137 | struct soc_nvidia_tegra124_config *config) |
| 138 | { |
| 139 | int log2_bpp = log2(config->framebuffer_bits_per_pixel); |
| 140 | win->x = 0; |
| 141 | win->y = 0; |
| 142 | win->w = config->xres; |
| 143 | win->h = config->yres; |
| 144 | win->out_x = 0; |
| 145 | win->out_y = 0; |
| 146 | win->out_w = config->xres; |
| 147 | win->out_h = config->yres; |
| 148 | win->phys_addr = config->framebuffer_base; |
| 149 | win->stride = config->xres * (1 << log2_bpp) / 8; |
| 150 | printk(BIOS_SPEW, "%s: depth = %d\n", __func__, log2_bpp); |
| 151 | switch (log2_bpp) { |
| 152 | case 5: |
| 153 | case 24: |
| 154 | win->fmt = COLOR_DEPTH_R8G8B8A8; |
| 155 | win->bpp = 32; |
| 156 | break; |
| 157 | case 4: |
| 158 | win->fmt = COLOR_DEPTH_B5G6R5; |
| 159 | win->bpp = 16; |
| 160 | break; |
| 161 | |
| 162 | default: |
| 163 | printk(BIOS_SPEW, "Unsupported LCD bit depth"); |
| 164 | return -1; |
| 165 | } |
| 166 | |
| 167 | return 0; |
| 168 | } |
| 169 | |
| 170 | static void update_window(struct display_controller *dc, |
| 171 | struct disp_ctl_win *win, |
| 172 | struct soc_nvidia_tegra124_config *config) |
| 173 | { |
| 174 | u32 h_dda, v_dda; |
| 175 | u32 val; |
| 176 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 177 | val = READL(&dc->cmd.disp_win_header); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 178 | val |= WINDOW_A_SELECT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 179 | WRITEL(val, &dc->cmd.disp_win_header); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 180 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 181 | WRITEL(win->fmt, &dc->win.color_depth); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 182 | |
| 183 | clrsetbits_le32(&dc->win.byte_swap, BYTE_SWAP_MASK, |
| 184 | BYTE_SWAP_NOSWAP << BYTE_SWAP_SHIFT); |
| 185 | |
| 186 | val = win->out_x << H_POSITION_SHIFT; |
| 187 | val |= win->out_y << V_POSITION_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 188 | WRITEL(val, &dc->win.pos); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 189 | |
| 190 | val = win->out_w << H_SIZE_SHIFT; |
| 191 | val |= win->out_h << V_SIZE_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 192 | WRITEL(val, &dc->win.size); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 193 | |
| 194 | val = (win->w * win->bpp / 8) << H_PRESCALED_SIZE_SHIFT; |
| 195 | val |= win->h << V_PRESCALED_SIZE_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 196 | WRITEL(val, &dc->win.prescaled_size); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 197 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 198 | WRITEL(0, &dc->win.h_initial_dda); |
| 199 | WRITEL(0, &dc->win.v_initial_dda); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 200 | |
| 201 | h_dda = (win->w * 0x1000) / MAX(win->out_w - 1, 1); |
| 202 | v_dda = (win->h * 0x1000) / MAX(win->out_h - 1, 1); |
| 203 | |
| 204 | val = h_dda << H_DDA_INC_SHIFT; |
| 205 | val |= v_dda << V_DDA_INC_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 206 | WRITEL(val, &dc->win.dda_increment); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 207 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 208 | WRITEL(win->stride, &dc->win.line_stride); |
| 209 | WRITEL(0, &dc->win.buf_stride); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 210 | |
| 211 | val = WIN_ENABLE; |
| 212 | if (win->bpp < 24) |
| 213 | val |= COLOR_EXPAND; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 214 | WRITEL(val, &dc->win.win_opt); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 215 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 216 | WRITEL((u32) win->phys_addr, &dc->winbuf.start_addr); |
| 217 | WRITEL(win->x, &dc->winbuf.addr_h_offset); |
| 218 | WRITEL(win->y, &dc->winbuf.addr_v_offset); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 219 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 220 | WRITEL(0xff00, &dc->win.blend_nokey); |
| 221 | WRITEL(0xff00, &dc->win.blend_1win); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 222 | |
| 223 | val = GENERAL_ACT_REQ | WIN_A_ACT_REQ; |
| 224 | val |= GENERAL_UPDATE | WIN_A_UPDATE; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 225 | WRITEL(val, &dc->cmd.state_ctrl); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 226 | } |
| 227 | |
| 228 | /* this is really aimed at the lcd panel. That said, there are two display |
| 229 | * devices on this part and we may someday want to extend it for other boards. |
| 230 | */ |
| 231 | void display_startup(device_t dev) |
| 232 | { |
| 233 | u32 val; |
| 234 | int i; |
| 235 | struct soc_nvidia_tegra124_config *config = dev->chip_info; |
| 236 | struct display_controller *dc = (void *)config->display_controller; |
| 237 | struct disp_ctl_win window; |
| 238 | |
| 239 | /* should probably just make it all MiB ... in future */ |
| 240 | u32 framebuffer_size_mb = config->framebuffer_size / MiB; |
| 241 | u32 framebuffer_base_mb= config->framebuffer_base / MiB; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 242 | /* light it all up */ |
| 243 | /* This one may have been done in romstage but that's ok for now. */ |
| 244 | if (config->panel_vdd_gpio){ |
| 245 | gpio_output(config->panel_vdd_gpio, 1); |
| 246 | printk(BIOS_SPEW,"%s: panel_vdd setting gpio %08x to %d\n", |
| 247 | __func__, config->panel_vdd_gpio, 1); |
| 248 | } |
| 249 | delay(1); |
| 250 | if (config->backlight_vdd_gpio){ |
| 251 | gpio_output(config->backlight_vdd_gpio, 1); |
| 252 | printk(BIOS_SPEW,"%s: backlight vdd setting gpio %08x to %d\n", |
| 253 | __func__, config->backlight_vdd_gpio, 1); |
| 254 | } |
| 255 | delay(1); |
| 256 | if (config->lvds_shutdown_gpio){ |
| 257 | gpio_output(config->lvds_shutdown_gpio, 0); |
| 258 | printk(BIOS_SPEW,"%s: lvds shutdown setting gpio %08x to %d\n", |
| 259 | __func__, config->lvds_shutdown_gpio, 0); |
| 260 | } |
| 261 | if (config->backlight_en_gpio){ |
| 262 | gpio_output(config->backlight_en_gpio, 1); |
| 263 | printk(BIOS_SPEW,"%s: backlight enable setting gpio %08x to %d\n", |
| 264 | __func__, config->backlight_en_gpio, 1); |
| 265 | } |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 266 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 267 | if (config->pwm){ |
| 268 | gpio_output(config->pwm, 1); |
| 269 | printk(BIOS_SPEW,"%s: pwm setting gpio %08x to %d\n", |
| 270 | __func__, config->pwm, 1); |
| 271 | } |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 272 | printk(BIOS_SPEW, |
| 273 | "%s: xres %d yres %d framebuffer_bits_per_pixel %d\n", |
| 274 | __func__, |
| 275 | config->xres, config->yres, config->framebuffer_bits_per_pixel); |
| 276 | if (framebuffer_size_mb == 0){ |
| 277 | framebuffer_size_mb = ALIGN_UP(config->xres * config->yres * |
| 278 | (config->framebuffer_bits_per_pixel / 8), MiB)/MiB; |
| 279 | } |
| 280 | |
| 281 | if (! framebuffer_base_mb) |
| 282 | framebuffer_base_mb = FB_BASE_MB; |
| 283 | |
| 284 | mmu_config_range(framebuffer_base_mb, framebuffer_size_mb, |
| 285 | config->cache_policy); |
| 286 | |
| 287 | /* Enable flushing after LCD writes if requested */ |
| 288 | /* I don't understand this part yet. |
| 289 | lcd_set_flush_dcache(config.cache_type & FDT_LCD_CACHE_FLUSH); |
| 290 | */ |
| 291 | printk(BIOS_SPEW, "LCD frame buffer at %dMiB to %dMiB\n", framebuffer_base_mb, |
| 292 | framebuffer_base_mb + framebuffer_size_mb); |
| 293 | |
| 294 | /* GPIO magic here if needed to start powering up things. You |
| 295 | * really only want to enable vdd, wait a bit, and then enable |
| 296 | * the panel. However ... the timings in the tegra20 dts make |
| 297 | * no sense to me. I'm pretty sure they're wrong. |
| 298 | * The panel_vdd is done in the romstage, so we need only |
| 299 | * light things up here once we're sure it's all working. |
| 300 | */ |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 301 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 302 | /* init dc_a */ |
| 303 | init_dca_regs(); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 304 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 305 | /* power up perip */ |
| 306 | dp_io_powerup(); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 307 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 308 | /* bringup dp */ |
| 309 | dp_bringup(framebuffer_base_mb*MiB); |
| 310 | |
Andrew Bresticker | 24d4f7f | 2013-12-18 22:41:34 -0800 | [diff] [blame^] | 311 | /* init frame buffer */ |
| 312 | memset((void *)(framebuffer_base_mb*MiB), 0x00, |
| 313 | framebuffer_size_mb*MiB); |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 314 | |
| 315 | /* tell depthcharge ... |
| 316 | */ |
| 317 | struct edid edid; |
Julius Werner | edf6b57 | 2013-10-25 17:49:26 -0700 | [diff] [blame] | 318 | edid.x_resolution = 1376; |
| 319 | edid.y_resolution = 768; |
| 320 | edid.bytes_per_line = 1376 * 2; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 321 | edid.framebuffer_bits_per_pixel = 16; |
| 322 | set_vbe_mode_info_valid(&edid, (uintptr_t)(framebuffer_base_mb*MiB)); |
| 323 | |
| 324 | if (0){ |
| 325 | /* do we still need these? */ |
| 326 | WRITEL(0x00000100, &dc->cmd.gen_incr_syncpt_ctrl); |
| 327 | WRITEL(0x0000011a, &dc->cmd.cont_syncpt_vsync); |
| 328 | WRITEL(0x00000000, &dc->cmd.int_type); |
| 329 | WRITEL(0x00000000, &dc->cmd.int_polarity); |
| 330 | WRITEL(0x00000000, &dc->cmd.int_mask); |
| 331 | WRITEL(0x00000000, &dc->cmd.int_enb); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 332 | |
| 333 | val = PW0_ENABLE | PW1_ENABLE | PW2_ENABLE; |
| 334 | val |= PW3_ENABLE | PW4_ENABLE | PM0_ENABLE; |
| 335 | val |= PM1_ENABLE; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 336 | WRITEL(val, &dc->cmd.disp_pow_ctrl); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 337 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 338 | val = READL(&dc->cmd.disp_cmd); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 339 | val |= CTRL_MODE_C_DISPLAY << CTRL_MODE_SHIFT; |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 340 | WRITEL(val, &dc->cmd.disp_cmd); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 341 | |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 342 | WRITEL(0x00000020, &dc->disp.mem_high_pri); |
| 343 | WRITEL(0x00000001, &dc->disp.mem_high_pri_timer); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 344 | |
| 345 | for (i = 0; i < PIN_REG_COUNT; i++) { |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 346 | WRITEL(rgb_enb_tab[i], &dc->com.pin_output_enb[i]); |
| 347 | WRITEL(rgb_polarity_tab[i], &dc->com.pin_output_polarity[i]); |
| 348 | WRITEL(rgb_data_tab[i], &dc->com.pin_output_data[i]); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 349 | } |
| 350 | |
| 351 | for (i = 0; i < PIN_OUTPUT_SEL_COUNT; i++) |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 352 | WRITEL(rgb_sel_tab[i], &dc->com.pin_output_sel[i]); |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 353 | |
| 354 | if (config->pixel_clock) |
| 355 | update_display_mode(&dc->disp, config); |
| 356 | |
| 357 | if (!setup_window(&window, config)) |
| 358 | update_window(dc, &window, config); |
Hung-Te Lin | 2fc3b62 | 2013-10-21 21:43:03 +0800 | [diff] [blame] | 359 | } |
Gabe Black | d40be11 | 2013-10-09 23:45:07 -0700 | [diff] [blame] | 360 | } |
| 361 | |