MINI2440: Temporary reset of base board init
[u-boot-openmoko/mini2440.git] / drivers / video / smedia3362.c
blobd88568b7879deba39ba350e26602aaabcf4dd8d6
1 /*
2 * (C) Copyright 2007 by OpenMoko, Inc.
3 * Author: Harald Welte <laforge@openmoko.org>
5 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public License as
7 * published by the Free Software Foundation; either version 2 of
8 * the License, or (at your option) any later version.
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.
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., 59 Temple Place, Suite 330, Boston,
18 * MA 02111-1307 USA
21 #include <common.h>
23 #if defined(CONFIG_VIDEO_GLAMO3362)
25 #include <video_fb.h>
26 #include "videomodes.h"
27 #include <s3c2410.h>
28 #include "smedia3362.h"
29 #ifdef CONFIG_GTA02_REVISION
30 #include "../../board/neo1973/common/jbt6k74.h"
31 #endif
33 #define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
35 /* Export Graphic Device */
36 GraphicDevice smi;
38 #define GLAMO_REG(x) (*(volatile unsigned short *)(CONFIG_GLAMO_BASE + x))
40 static inline void
41 glamo_reg_write(u_int16_t reg, u_int16_t val)
43 GLAMO_REG(reg) = val;
46 static inline u_int16_t
47 glamo_reg_read(u_int16_t reg)
49 return GLAMO_REG(reg);
52 /* these are called by jbt6k74 driver to do LCM bitbang SPI via Glamo */
54 void smedia3362_spi_cs(int b)
56 glamo_reg_write(GLAMO_REG_GPIO_GEN4,
57 (glamo_reg_read(GLAMO_REG_GPIO_GEN4) & 0xffef) | (b << 4));
60 void smedia3362_spi_sda(int b)
62 glamo_reg_write(GLAMO_REG_GPIO_GEN3,
63 (glamo_reg_read(GLAMO_REG_GPIO_GEN3) & 0xff7f) | (b << 7));
66 void smedia3362_spi_scl(int b)
68 glamo_reg_write(GLAMO_REG_GPIO_GEN3,
69 (glamo_reg_read(GLAMO_REG_GPIO_GEN3) & 0xffbf) | (b << 6));
72 void smedia3362_lcm_reset(int b)
74 glamo_reg_write(GLAMO_REG_GPIO_GEN2,
75 (glamo_reg_read(GLAMO_REG_GPIO_GEN2) & 0xffef) | (b << 4));
79 * these are dumps of Glamo register ranges from working Linux
80 * framebuffer
82 static u16 u16a_lcd_init[] = {
83 0x0020, 0x1020, 0x0B40, 0x01E0, 0x0280, 0x440C, 0x0000, 0x0000,
84 0x0000, 0x0000, 0x0000, 0x0000, 0x03C0, 0x0000, 0x0258, 0x0000,
85 0x0000, 0x0000, 0x0008, 0x0000, 0x0010, 0x0000, 0x01F0, 0x0000,
86 0x0294, 0x0000, 0x0000, 0x0000, 0x0002, 0x0000, 0x0004, 0x0000,
87 0x0284, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
88 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
89 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
90 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
91 0x8023, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
94 static u16 u16a_gen_init_0x0000[] = {
95 0x2020, 0x3650, 0x0002, 0x01FF, 0x0000, 0x0000, 0x0000, 0x0000,
96 0x000D, 0x000B, 0x00EE, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
97 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
98 0x1839, 0x0000, 0x2000, 0x0001, 0x0100, 0x0000, 0x0000, 0x0000,
99 0x05DB, 0x5231, 0x09C3, 0x8261, 0x0003, 0x0000, 0x0000, 0x0000,
100 0x000F, 0x101E, 0xC0C3, 0x101E, 0x000F, 0x0001, 0x030F, 0x020F,
101 0x080F, 0x0F0F
104 static u16 u16a_gen_init_0x0200[] = {
105 0x0EF0, 0x07FF, 0x0000, 0x0080, 0x0344, 0x0600, 0x0000, 0x0000,
106 0x0000, 0x0000, 0x4000, 0xF00E, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
107 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
108 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
109 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
110 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
111 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
112 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
113 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
114 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
115 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
116 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
117 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
118 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
119 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
120 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0, 0x00C0,
121 0x0873, 0xAFAF, 0x0108, 0x0010, 0x0000, 0x0000, 0x0000, 0x0000,
122 0x0000, 0x1002, 0x6006, 0x00FF, 0x0001, 0x0020, 0x0000, 0x0000,
123 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000,
124 0x3210, 0x5432, 0xE100, 0x01D6
127 #define glamofb_cmdq_empty() (glamo_reg_read(GLAMO_REGOFS_LCD + \
128 GLAMO_REG_LCD_STATUS1) & (1 << 15))
130 void glamofb_cmd_mode(int on)
132 if (on) {
133 while (!glamofb_cmdq_empty())
135 /* display the entire frame then switch to command */
136 glamo_reg_write(GLAMO_REGOFS_LCD + GLAMO_REG_LCD_COMMAND1,
137 GLAMO_LCD_CMD_TYPE_DISP |
138 GLAMO_LCD_CMD_DATA_FIRE_VSYNC);
140 while (!(glamo_reg_read(GLAMO_REGOFS_LCD +
141 GLAMO_REG_LCD_STATUS2) & (1 << 12)))
143 udelay(5000); /* you really need this ;-) */
144 } else {
145 /* RGB interface needs vsync/hsync */
146 if (glamo_reg_read(GLAMO_REGOFS_LCD + GLAMO_REG_LCD_MODE3) &
147 GLAMO_LCD_MODE3_RGB)
148 glamo_reg_write(GLAMO_REGOFS_LCD +
149 GLAMO_REG_LCD_COMMAND1,
150 GLAMO_LCD_CMD_TYPE_DISP |
151 GLAMO_LCD_CMD_DATA_DISP_SYNC);
153 glamo_reg_write(GLAMO_REGOFS_LCD + GLAMO_REG_LCD_COMMAND1,
154 GLAMO_LCD_CMD_TYPE_DISP |
155 GLAMO_LCD_CMD_DATA_DISP_FIRE);
159 void glamofb_cmd_write(u_int16_t val)
161 while (!glamofb_cmdq_empty())
163 glamo_reg_write(GLAMO_REGOFS_LCD + GLAMO_REG_LCD_COMMAND1, val);
166 void glamo_core_init(void)
168 int bp;
170 /* power up PLL1 and PLL2 */
171 glamo_reg_write(GLAMO_REG_PLL_GEN7, 0x0000);
172 glamo_reg_write(GLAMO_REG_PLL_GEN3, 0x0400);
174 /* enable memory clock and get it out of deep pwrdown */
175 glamo_reg_write(GLAMO_REG_CLOCK_MEMORY,
176 glamo_reg_read(GLAMO_REG_CLOCK_MEMORY) |
177 GLAMO_CLOCK_MEM_EN_MOCACLK);
178 glamo_reg_write(GLAMO_REG_MEM_DRAM2,
179 glamo_reg_read(GLAMO_REG_MEM_DRAM2) &
180 (~GLAMO_MEM_DRAM2_DEEP_PWRDOWN));
181 glamo_reg_write(GLAMO_REG_MEM_DRAM1,
182 glamo_reg_read(GLAMO_REG_MEM_DRAM1) &
183 (~GLAMO_MEM_DRAM1_SELF_REFRESH));
185 * we just fill up the general hostbus and LCD register sets
186 * with magic values taken from the Linux framebuffer init action
188 for (bp = 0; bp < ARRAY_SIZE(u16a_gen_init_0x0000); bp++)
189 glamo_reg_write(GLAMO_REGOFS_GENERIC | (bp << 1),
190 u16a_gen_init_0x0000[bp]);
192 for (bp = 0; bp < ARRAY_SIZE(u16a_gen_init_0x0200); bp++)
193 glamo_reg_write(GLAMO_REGOFS_HOSTBUS | (bp << 1),
194 u16a_gen_init_0x0200[bp]);
196 /* spin until PLL1 lock */
197 while (!(glamo_reg_read(GLAMO_REG_PLL_GEN5) & 1))
200 glamofb_cmd_mode(1);
201 /* LCD registers */
202 for (bp = 0; bp < ARRAY_SIZE(u16a_lcd_init); bp++)
203 glamo_reg_write(GLAMO_REGOFS_LCD + (bp << 1),
204 u16a_lcd_init[bp]);
205 glamofb_cmd_mode(0);
208 void * video_hw_init(void)
210 GraphicDevice *pGD = (GraphicDevice *)&smi;
212 printf("Glamo core device ID: 0x%04x, Revision 0x%04x\n",
213 glamo_reg_read(GLAMO_REG_DEVICE_ID),
214 glamo_reg_read(GLAMO_REG_REVISION_ID));
216 pGD->winSizeX = pGD->plnSizeX = 480;
217 pGD->winSizeY = pGD->plnSizeY = 640;
218 pGD->gdfBytesPP = 2;
219 pGD->gdfIndex = GDF_16BIT_565RGB;
221 pGD->frameAdrs = CONFIG_GLAMO_BASE + 0x00800000;
222 pGD->memSize = 0x200000; /* 480x640x16bit = 614400 bytes */
224 return &smi;
227 void video_set_lut(unsigned int index, unsigned char r,
228 unsigned char g, unsigned char b)
230 /* FIXME: we don't support any palletized formats */
233 #endif /* CONFIG_VIDEO_GLAMO3362 */