5 #include <asm/arch/dss.h>
6 #include <asm/arch/sys_proto.h>
12 #define TWL_INTBR_PMBR1 0x92
13 #define GPIODATADIR1 0x9b
14 #define SETGPIODATAOUT1 0xa4
16 static const struct panel_config panel_cfg = {
17 .timing_h = 0x0d504300, /* Horizantal timing */
18 .timing_v = 0x02202700, /* Vertical timing */
19 .pol_freq = 0x00007000, /* Pol Freq */
20 .divisor = 0x00010004, /* 36Mhz Pixel Clock */
21 .lcd_size = 0x01df031f, /* 800x480 */
22 .panel_type = 0x01, /* TFT */
23 .data_lines = 0x03, /* 24 Bit RGB */
24 .load_mode = 0x02, /* Frame Mode */
29 * Hacky DSS/LCD initialization code
32 static void dss_lcd_init(uint base_addr)
36 l = readl(0x48004d44);
37 dpll4 = 26 * ((l >> 8) & 0xfff) / ((l & 0x7f) + 1);
38 if (get_cpu_family() == CPU_OMAP36XX)
41 /* find and write dpll4 m4 divisor */
42 l = dpll4 / 4; /* / panel_cfg.divisor */
43 for (div = 2; l / div > 36; div++)
46 /* program CM_CLKSEL_DSS m4 divisor */
47 l = readl(0x48004e40);
48 writel((l & ~0x3f) | div, 0x48004e40);
50 omap3_dss_panel_config(&panel_cfg);
52 writel(base_addr, 0x48050480);
53 writel(base_addr, 0x48050484);
54 writel(0x01df031f, 0x4805048c); /* graphics window size */
55 writel(0x0000008d, 0x480504a0); /* graphics format */
57 /* omap3_dss_enable(); */
58 l = readl(0x48050440);
59 l |= LCD_ENABLE | GO_LCD | GP_OUT0 | GP_OUT1;
60 writel(l, 0x48050440);
63 /* SPI stuff to set correct clock polarity in the LCD */
64 static void lcd_spi_init(void)
66 /* Enable clock for SPI1 */
67 writel(readl(0x48004A00) | (1<<18), 0x48004A00);
68 writel(readl(0x48004A10) | (1<<18), 0x48004A10);
70 /* Reset module, wait for reset to complete */
71 writel(0x00000002, 0x48098010);
72 while ( !(readl(0x48098014) & 1) );
74 /* SPI1 base address = 0x48098000 for CS0,
75 * for CS1 add 0x14 to the offset where applicable */
76 *((volatile uint *) 0x48098034) = 0x00000000; /* CS0 +8 */
77 *((volatile uint *) 0x48098048) = 0x00000000; /* CS1 +8 */
78 *((volatile uint *) 0x4809801C) = 0x00000000;
79 *((volatile uint *) 0x48098018) = 0xFFFFFFFF;
80 *((volatile uint *) 0x48098024) = 0x00000000;
81 *((volatile uint *) 0x48098028) = 0x00000000;
82 *((volatile uint *) 0x48098010) = 0x00000308;
83 *((volatile uint *) 0x48098040) = 0x020127DC;
84 *((volatile uint *) 0x48098048) = 0x00000001; /* CS1 */
87 static void lcd_spi_write(uint addr, uint data)
90 data |= (addr << 10) | (1 << 8);
92 while ( !(readl(0x48098044) & (1<<1)) ); /* wait for TXS */
94 writel(data, 0x4809804C);
96 while ( !(readl(0x48098044) & (1<<1)) ); /* wait for TXS */
97 while ( !(readl(0x48098044) & (1<<2)) ); /* wait for EOT */
100 static void lcd_init(void)
102 DECLARE_GLOBAL_DATA_PTR;
105 /* make sure LCD nreset is driven low (GPIO157)
106 * (we are called before misc_init_r() which normally handles this stuff) */
107 gpio_direction_output(157, 0);
108 /* also GPIO164 should be high (some audible noise otherwise) */
109 gpio_direction_output(164, 1);
113 /* some kernels can now disable REGEN which controls the main 5V supply,
114 * LCD is connected to it on CC units. Also enable it on Rebirth as the
115 * user may want to boot the 2.6 kernel that doesn't control REGEN */
116 if (get_cpu_family() != CPU_OMAP36XX)
117 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x2e,
118 TWL4030_PM_RECEIVER_REGEN_DEV_GRP);
120 /* set VPLL2 to 1.8V */
121 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x05,
122 TWL4030_PM_RECEIVER_VPLL2_DEDICATED);
123 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
124 TWL4030_PM_RECEIVER_VPLL2_DEV_GRP);
126 /* set VAUX1 to 3.0V (LCD) */
127 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x04,
128 TWL4030_PM_RECEIVER_VAUX1_DEDICATED);
129 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
130 TWL4030_PM_RECEIVER_VAUX1_DEV_GRP);
132 /* Clear frame buffer */
133 memset((void *)gd->fb_base, 0, 800*480*2);
135 gpio_direction_output(157, 1);
136 udelay(2000); /* Need to wait at least 1ms after reset to start sending signals */
138 dss_lcd_init((uint)gd->fb_base);
140 lcd_spi_write(0x02, 0x0f);
141 writel(0, 0x48098048); /* Disable SPI1, CS1 */
143 /* Set GPIOs on T2 (Turn on LCD BL) */
144 twl4030_i2c_read_u8(TWL4030_CHIP_INTBR, &d, TWL_INTBR_PMBR1);
145 d &= ~0x0c; /* switch to GPIO function */
146 twl4030_i2c_write_u8(TWL4030_CHIP_INTBR, d, TWL_INTBR_PMBR1);
148 twl4030_i2c_read_u8(TWL4030_CHIP_GPIO, &d, GPIODATADIR1);
149 d |= 0x40; /* GPIO6 */
150 twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, d, GPIODATADIR1);
151 twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, 0x40, SETGPIODATAOUT1);
154 static void draw_logo(void)
156 DECLARE_GLOBAL_DATA_PTR;
157 unsigned short *dest = (void *)gd->fb_base;
158 unsigned short *logo = (unsigned short *)logo_data;
161 dest += 800 * 480/2 + 800/2;
162 dest -= 800 * logo_height/2;
163 dest -= logo_width/2;
165 for (i = 0; i < logo_height; i++, dest += 800, logo += logo_width)
166 memcpy(dest, logo, logo_width * 2);
169 /* u-boot LCD driver support */
170 vidinfo_t panel_info = {
174 /* vars managed by lcd.c */
179 void *lcd_console_address;
183 void lcd_enable(void)
188 void lcd_ctrl_init(void *lcdbase)
191 lcd_set_flush_dcache(1);
194 /* Calculate fb size for VIDEOLFB_ATAG. */
195 ulong calc_fbsize(void)
197 return (panel_info.vl_col * panel_info.vl_row *
198 NBITS(panel_info.vl_bpix) / 8);
201 #endif /* CONFIG_LCD */