5 #include <asm/arch/dss.h>
6 #include <asm/arch/sys_proto.h>
11 #define TWL_INTBR_PMBR1 0x92
12 #define GPIODATADIR1 0x9b
13 #define SETGPIODATAOUT1 0xa4
15 static const struct panel_config panel_cfg = {
16 .timing_h = 0x0d504300, /* Horizantal timing */
17 .timing_v = 0x02202700, /* Vertical timing */
18 .pol_freq = 0x00007000, /* Pol Freq */
19 .divisor = 0x00010004, /* 36Mhz Pixel Clock */
20 .lcd_size = 0x01df031f, /* 800x480 */
21 .panel_type = 0x01, /* TFT */
22 .data_lines = 0x03, /* 24 Bit RGB */
23 .load_mode = 0x02, /* Frame Mode */
28 * Hacky DSS/LCD initialization code
31 static void dss_lcd_init(uint base_addr)
35 l = readl(0x48004d44);
36 dpll4 = 26 * ((l >> 8) & 0xfff) / ((l & 0x7f) + 1);
37 if (get_cpu_family() == CPU_OMAP36XX)
40 /* find and write dpll4 m4 divisor */
41 l = dpll4 / 4; /* / panel_cfg.divisor */
42 for (div = 2; l / div > 36; div++)
45 /* program CM_CLKSEL_DSS m4 divisor */
46 l = readl(0x48004e40);
47 writel((l & ~0x3f) | div, 0x48004e40);
49 omap3_dss_panel_config(&panel_cfg);
51 writel(base_addr, 0x48050480);
52 writel(base_addr, 0x48050484);
53 writel(0x01df031f, 0x4805048c); /* graphics window size */
54 writel(0x0000008d, 0x480504a0); /* graphics format */
56 /* omap3_dss_enable(); */
57 l = readl(0x48050440);
58 l |= LCD_ENABLE | GO_LCD | GP_OUT0 | GP_OUT1;
59 writel(l, 0x48050440);
62 /* SPI stuff to set correct clock polarity in the LCD */
63 static void lcd_spi_init(void)
65 /* Enable clock for SPI1 */
66 writel(readl(0x48004A00) | (1<<18), 0x48004A00);
67 writel(readl(0x48004A10) | (1<<18), 0x48004A10);
69 /* Reset module, wait for reset to complete */
70 writel(0x00000002, 0x48098010);
71 while ( !(readl(0x48098014) & 1) );
73 /* SPI1 base address = 0x48098000 for CS0,
74 * for CS1 add 0x14 to the offset where applicable */
75 *((volatile uint *) 0x48098034) = 0x00000000; /* CS0 +8 */
76 *((volatile uint *) 0x48098048) = 0x00000000; /* CS1 +8 */
77 *((volatile uint *) 0x4809801C) = 0x00000000;
78 *((volatile uint *) 0x48098018) = 0xFFFFFFFF;
79 *((volatile uint *) 0x48098024) = 0x00000000;
80 *((volatile uint *) 0x48098028) = 0x00000000;
81 *((volatile uint *) 0x48098010) = 0x00000308;
82 *((volatile uint *) 0x48098040) = 0x020127DC;
83 *((volatile uint *) 0x48098048) = 0x00000001; /* CS1 */
86 static void lcd_spi_write(uint addr, uint data)
89 data |= (addr << 10) | (1 << 8);
91 while ( !(readl(0x48098044) & (1<<1)) ); /* wait for TXS */
93 writel(data, 0x4809804C);
95 while ( !(readl(0x48098044) & (1<<1)) ); /* wait for TXS */
96 while ( !(readl(0x48098044) & (1<<2)) ); /* wait for EOT */
99 static void lcd_init(void)
101 DECLARE_GLOBAL_DATA_PTR;
104 /* make sure LCD nreset is driven low (GPIO157)
105 * (we are called before misc_init_r() which normally handles this stuff) */
106 writel(0x20000000, 0x49056090);
107 writel(readl(0x49056034) & ~0x20000000, 0x49056034);
108 /* also GPIO164 (some audible noise otherwise) */
109 writel(0x10, 0x49058094);
110 writel(readl(0x49058034) & ~0x10, 0x49058034);
114 /* set VPLL2 to 1.8V */
115 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x05,
116 TWL4030_PM_RECEIVER_VPLL2_DEDICATED);
117 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
118 TWL4030_PM_RECEIVER_VPLL2_DEV_GRP);
120 /* set VAUX1 to 3.0V (LCD) */
121 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x04,
122 TWL4030_PM_RECEIVER_VAUX1_DEDICATED);
123 twl4030_i2c_write_u8(TWL4030_CHIP_PM_RECEIVER, 0x20,
124 TWL4030_PM_RECEIVER_VAUX1_DEV_GRP);
126 /* Clear frame buffer */
127 memset((void *)gd->fb_base, 0, 800*480*2);
129 writel(0x20000000, 0x49056094); /* Bring LCD out of reset (157) */
130 udelay(2000); /* Need to wait at least 1ms after reset to start sending signals */
132 dss_lcd_init((uint)gd->fb_base);
134 lcd_spi_write(0x02, 0x0f);
135 writel(0, 0x48098048); /* Disable SPI1, CS1 */
137 /* Set GPIOs on T2 (Turn on LCD BL) */
138 twl4030_i2c_read_u8(TWL4030_CHIP_INTBR, &d, TWL_INTBR_PMBR1);
139 d &= ~0x0c; /* switch to GPIO function */
140 twl4030_i2c_write_u8(TWL4030_CHIP_INTBR, d, TWL_INTBR_PMBR1);
142 twl4030_i2c_read_u8(TWL4030_CHIP_GPIO, &d, GPIODATADIR1);
143 d |= 0x40; /* GPIO6 */
144 twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, d, GPIODATADIR1);
145 twl4030_i2c_write_u8(TWL4030_CHIP_GPIO, 0x40, SETGPIODATAOUT1);
148 static void draw_logo(void)
150 DECLARE_GLOBAL_DATA_PTR;
151 unsigned short *dest = (void *)gd->fb_base;
152 unsigned short *logo = (unsigned short *)logo_data;
155 dest += 800 * 480/2 + 800/2;
156 dest -= 800 * logo_height/2;
157 dest -= logo_width/2;
159 for (i = 0; i < logo_height; i++, dest += 800, logo += logo_width)
160 memcpy(dest, logo, logo_width * 2);
163 /* u-boot LCD driver support */
164 vidinfo_t panel_info = {
168 /* vars managed by lcd.c */
173 void *lcd_console_address;
177 void lcd_enable(void)
182 void lcd_ctrl_init(void *lcdbase)
187 /* Calculate fb size for VIDEOLFB_ATAG. */
188 ulong calc_fbsize(void)
190 return (panel_info.vl_col * panel_info.vl_row *
191 NBITS(panel_info.vl_bpix) / 8);
194 #endif /* CONFIG_LCD */