diff options
Diffstat (limited to 'drivers/video/w100fb.c')
-rw-r--r-- | drivers/video/w100fb.c | 1912 |
1 files changed, 758 insertions, 1154 deletions
diff --git a/drivers/video/w100fb.c b/drivers/video/w100fb.c index adcda697ea60..0030c071da8f 100644 --- a/drivers/video/w100fb.c +++ b/drivers/video/w100fb.c | |||
@@ -5,9 +5,15 @@ | |||
5 | * | 5 | * |
6 | * Copyright (C) 2002, ATI Corp. | 6 | * Copyright (C) 2002, ATI Corp. |
7 | * Copyright (C) 2004-2005 Richard Purdie | 7 | * Copyright (C) 2004-2005 Richard Purdie |
8 | * Copyright (c) 2005 Ian Molton | ||
8 | * | 9 | * |
9 | * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net> | 10 | * Rewritten for 2.6 by Richard Purdie <rpurdie@rpsys.net> |
10 | * | 11 | * |
12 | * Generic platform support by Ian Molton <spyro@f2s.com> | ||
13 | * and Richard Purdie <rpurdie@rpsys.net> | ||
14 | * | ||
15 | * w32xx support by Ian Molton | ||
16 | * | ||
11 | * This program is free software; you can redistribute it and/or modify | 17 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License version 2 as | 18 | * it under the terms of the GNU General Public License version 2 as |
13 | * published by the Free Software Foundation. | 19 | * published by the Free Software Foundation. |
@@ -21,7 +27,7 @@ | |||
21 | #include <linux/mm.h> | 27 | #include <linux/mm.h> |
22 | #include <linux/device.h> | 28 | #include <linux/device.h> |
23 | #include <linux/string.h> | 29 | #include <linux/string.h> |
24 | #include <linux/proc_fs.h> | 30 | #include <linux/vmalloc.h> |
25 | #include <asm/io.h> | 31 | #include <asm/io.h> |
26 | #include <asm/uaccess.h> | 32 | #include <asm/uaccess.h> |
27 | #include <video/w100fb.h> | 33 | #include <video/w100fb.h> |
@@ -30,114 +36,78 @@ | |||
30 | /* | 36 | /* |
31 | * Prototypes | 37 | * Prototypes |
32 | */ | 38 | */ |
33 | static void w100fb_save_buffer(void); | ||
34 | static void w100fb_clear_buffer(void); | ||
35 | static void w100fb_restore_buffer(void); | ||
36 | static void w100fb_clear_screen(u32 mode, long int offset); | ||
37 | static void w100_resume(void); | ||
38 | static void w100_suspend(u32 mode); | 39 | static void w100_suspend(u32 mode); |
39 | static void w100_init_qvga_rotation(u16 deg); | ||
40 | static void w100_init_vga_rotation(u16 deg); | ||
41 | static void w100_vsync(void); | 40 | static void w100_vsync(void); |
42 | static void w100_init_sharp_lcd(u32 mode); | 41 | static void w100_hw_init(struct w100fb_par*); |
43 | static void w100_pwm_setup(void); | 42 | static void w100_pwm_setup(struct w100fb_par*); |
44 | static void w100_InitExtMem(u32 mode); | 43 | static void w100_init_clocks(struct w100fb_par*); |
45 | static void w100_hw_init(void); | 44 | static void w100_setup_memory(struct w100fb_par*); |
46 | static u16 w100_set_fastsysclk(u16 Freq); | 45 | static void w100_init_lcd(struct w100fb_par*); |
47 | 46 | static void w100_set_dispregs(struct w100fb_par*); | |
48 | static void lcdtg_hw_init(u32 mode); | 47 | static void w100_update_enable(void); |
49 | static void lcdtg_lcd_change(u32 mode); | 48 | static void w100_update_disable(void); |
50 | static void lcdtg_resume(void); | 49 | static void calc_hsync(struct w100fb_par *par); |
51 | static void lcdtg_suspend(void); | 50 | struct w100_pll_info *w100_get_xtal_table(unsigned int freq); |
52 | |||
53 | |||
54 | /* Register offsets & lengths */ | ||
55 | #define REMAPPED_FB_LEN 0x15ffff | ||
56 | |||
57 | #define BITS_PER_PIXEL 16 | ||
58 | 51 | ||
59 | /* Pseudo palette size */ | 52 | /* Pseudo palette size */ |
60 | #define MAX_PALETTES 16 | 53 | #define MAX_PALETTES 16 |
61 | 54 | ||
62 | /* for resolution change */ | ||
63 | #define LCD_MODE_INIT (-1) | ||
64 | #define LCD_MODE_480 0 | ||
65 | #define LCD_MODE_320 1 | ||
66 | #define LCD_MODE_240 2 | ||
67 | #define LCD_MODE_640 3 | ||
68 | |||
69 | #define LCD_SHARP_QVGA 0 | ||
70 | #define LCD_SHARP_VGA 1 | ||
71 | |||
72 | #define LCD_MODE_PORTRAIT 0 | ||
73 | #define LCD_MODE_LANDSCAPE 1 | ||
74 | |||
75 | #define W100_SUSPEND_EXTMEM 0 | 55 | #define W100_SUSPEND_EXTMEM 0 |
76 | #define W100_SUSPEND_ALL 1 | 56 | #define W100_SUSPEND_ALL 1 |
77 | 57 | ||
78 | /* General frame buffer data structures */ | 58 | #define BITS_PER_PIXEL 16 |
79 | struct w100fb_par { | ||
80 | u32 xres; | ||
81 | u32 yres; | ||
82 | int fastsysclk_mode; | ||
83 | int lcdMode; | ||
84 | int rotation_flag; | ||
85 | int blanking_flag; | ||
86 | int comadj; | ||
87 | int phadadj; | ||
88 | }; | ||
89 | |||
90 | static struct w100fb_par *current_par; | ||
91 | 59 | ||
92 | /* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */ | 60 | /* Remapped addresses for base cfg, memmapped regs and the frame buffer itself */ |
93 | static void *remapped_base; | 61 | static void *remapped_base; |
94 | static void *remapped_regs; | 62 | static void *remapped_regs; |
95 | static void *remapped_fbuf; | 63 | static void *remapped_fbuf; |
96 | 64 | ||
97 | /* External Function */ | 65 | #define REMAPPED_FB_LEN 0x15ffff |
98 | static void(*w100fb_ssp_send)(u8 adrs, u8 data); | 66 | |
67 | /* This is the offset in the w100's address space we map the current | ||
68 | framebuffer memory to. We use the position of external memory as | ||
69 | we can remap internal memory to there if external isn't present. */ | ||
70 | #define W100_FB_BASE MEM_EXT_BASE_VALUE | ||
71 | |||
99 | 72 | ||
100 | /* | 73 | /* |
101 | * Sysfs functions | 74 | * Sysfs functions |
102 | */ | 75 | */ |
103 | 76 | static ssize_t flip_show(struct device *dev, struct device_attribute *attr, char *buf) | |
104 | static ssize_t rotation_show(struct device *dev, struct device_attribute *attr, char *buf) | ||
105 | { | 77 | { |
106 | struct fb_info *info = dev_get_drvdata(dev); | 78 | struct fb_info *info = dev_get_drvdata(dev); |
107 | struct w100fb_par *par=info->par; | 79 | struct w100fb_par *par=info->par; |
108 | 80 | ||
109 | return sprintf(buf, "%d\n",par->rotation_flag); | 81 | return sprintf(buf, "%d\n",par->flip); |
110 | } | 82 | } |
111 | 83 | ||
112 | static ssize_t rotation_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 84 | static ssize_t flip_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
113 | { | 85 | { |
114 | unsigned int rotate; | 86 | unsigned int flip; |
115 | struct fb_info *info = dev_get_drvdata(dev); | 87 | struct fb_info *info = dev_get_drvdata(dev); |
116 | struct w100fb_par *par=info->par; | 88 | struct w100fb_par *par=info->par; |
117 | 89 | ||
118 | rotate = simple_strtoul(buf, NULL, 10); | 90 | flip = simple_strtoul(buf, NULL, 10); |
91 | |||
92 | if (flip > 0) | ||
93 | par->flip = 1; | ||
94 | else | ||
95 | par->flip = 0; | ||
119 | 96 | ||
120 | if (rotate > 0) par->rotation_flag = 1; | 97 | w100_update_disable(); |
121 | else par->rotation_flag = 0; | 98 | w100_set_dispregs(par); |
99 | w100_update_enable(); | ||
122 | 100 | ||
123 | if (par->lcdMode == LCD_MODE_320) | 101 | calc_hsync(par); |
124 | w100_init_qvga_rotation(par->rotation_flag ? 270 : 90); | ||
125 | else if (par->lcdMode == LCD_MODE_240) | ||
126 | w100_init_qvga_rotation(par->rotation_flag ? 180 : 0); | ||
127 | else if (par->lcdMode == LCD_MODE_640) | ||
128 | w100_init_vga_rotation(par->rotation_flag ? 270 : 90); | ||
129 | else if (par->lcdMode == LCD_MODE_480) | ||
130 | w100_init_vga_rotation(par->rotation_flag ? 180 : 0); | ||
131 | 102 | ||
132 | return count; | 103 | return count; |
133 | } | 104 | } |
134 | 105 | ||
135 | static DEVICE_ATTR(rotation, 0644, rotation_show, rotation_store); | 106 | static DEVICE_ATTR(flip, 0644, flip_show, flip_store); |
136 | 107 | ||
137 | static ssize_t w100fb_reg_read(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 108 | static ssize_t w100fb_reg_read(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
138 | { | 109 | { |
139 | unsigned long param; | 110 | unsigned long regs, param; |
140 | unsigned long regs; | ||
141 | regs = simple_strtoul(buf, NULL, 16); | 111 | regs = simple_strtoul(buf, NULL, 16); |
142 | param = readl(remapped_regs + regs); | 112 | param = readl(remapped_regs + regs); |
143 | printk("Read Register 0x%08lX: 0x%08lX\n", regs, param); | 113 | printk("Read Register 0x%08lX: 0x%08lX\n", regs, param); |
@@ -148,8 +118,7 @@ static DEVICE_ATTR(reg_read, 0200, NULL, w100fb_reg_read); | |||
148 | 118 | ||
149 | static ssize_t w100fb_reg_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 119 | static ssize_t w100fb_reg_write(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
150 | { | 120 | { |
151 | unsigned long regs; | 121 | unsigned long regs, param; |
152 | unsigned long param; | ||
153 | sscanf(buf, "%lx %lx", ®s, ¶m); | 122 | sscanf(buf, "%lx %lx", ®s, ¶m); |
154 | 123 | ||
155 | if (regs <= 0x2000) { | 124 | if (regs <= 0x2000) { |
@@ -163,54 +132,56 @@ static ssize_t w100fb_reg_write(struct device *dev, struct device_attribute *att | |||
163 | static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write); | 132 | static DEVICE_ATTR(reg_write, 0200, NULL, w100fb_reg_write); |
164 | 133 | ||
165 | 134 | ||
166 | static ssize_t fastsysclk_show(struct device *dev, struct device_attribute *attr, char *buf) | 135 | static ssize_t fastpllclk_show(struct device *dev, struct device_attribute *attr, char *buf) |
167 | { | 136 | { |
168 | struct fb_info *info = dev_get_drvdata(dev); | 137 | struct fb_info *info = dev_get_drvdata(dev); |
169 | struct w100fb_par *par=info->par; | 138 | struct w100fb_par *par=info->par; |
170 | 139 | ||
171 | return sprintf(buf, "%d\n",par->fastsysclk_mode); | 140 | return sprintf(buf, "%d\n",par->fastpll_mode); |
172 | } | 141 | } |
173 | 142 | ||
174 | static ssize_t fastsysclk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) | 143 | static ssize_t fastpllclk_store(struct device *dev, struct device_attribute *attr, const char *buf, size_t count) |
175 | { | 144 | { |
176 | int param; | ||
177 | struct fb_info *info = dev_get_drvdata(dev); | 145 | struct fb_info *info = dev_get_drvdata(dev); |
178 | struct w100fb_par *par=info->par; | 146 | struct w100fb_par *par=info->par; |
179 | 147 | ||
180 | param = simple_strtoul(buf, NULL, 10); | 148 | if (simple_strtoul(buf, NULL, 10) > 0) { |
181 | 149 | par->fastpll_mode=1; | |
182 | if (param == 75) { | 150 | printk("w100fb: Using fast system clock (if possible)\n"); |
183 | printk("Set fastsysclk %d\n", param); | 151 | } else { |
184 | par->fastsysclk_mode = param; | 152 | par->fastpll_mode=0; |
185 | w100_set_fastsysclk(par->fastsysclk_mode); | 153 | printk("w100fb: Using normal system clock\n"); |
186 | } else if (param == 100) { | ||
187 | printk("Set fastsysclk %d\n", param); | ||
188 | par->fastsysclk_mode = param; | ||
189 | w100_set_fastsysclk(par->fastsysclk_mode); | ||
190 | } | 154 | } |
155 | |||
156 | w100_init_clocks(par); | ||
157 | calc_hsync(par); | ||
158 | |||
191 | return count; | 159 | return count; |
192 | } | 160 | } |
193 | 161 | ||
194 | static DEVICE_ATTR(fastsysclk, 0644, fastsysclk_show, fastsysclk_store); | 162 | static DEVICE_ATTR(fastpllclk, 0644, fastpllclk_show, fastpllclk_store); |
195 | 163 | ||
196 | /* | 164 | /* |
197 | * The touchscreen on this device needs certain information | 165 | * Some touchscreens need hsync information from the video driver to |
198 | * from the video driver to function correctly. We export it here. | 166 | * function correctly. We export it here. |
199 | */ | 167 | */ |
200 | int w100fb_get_xres(void) { | 168 | unsigned long w100fb_get_hsynclen(struct device *dev) |
201 | return current_par->xres; | 169 | { |
202 | } | 170 | struct fb_info *info = dev_get_drvdata(dev); |
171 | struct w100fb_par *par=info->par; | ||
203 | 172 | ||
204 | int w100fb_get_blanking(void) { | 173 | /* If display is blanked/suspended, hsync isn't active */ |
205 | return current_par->blanking_flag; | 174 | if (par->blanked) |
175 | return 0; | ||
176 | else | ||
177 | return par->hsync_len; | ||
206 | } | 178 | } |
179 | EXPORT_SYMBOL(w100fb_get_hsynclen); | ||
207 | 180 | ||
208 | int w100fb_get_fastsysclk(void) { | 181 | static void w100fb_clear_screen(struct w100fb_par *par) |
209 | return current_par->fastsysclk_mode; | 182 | { |
183 | memset_io(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), 0, (par->xres * par->yres * BITS_PER_PIXEL/8)); | ||
210 | } | 184 | } |
211 | EXPORT_SYMBOL(w100fb_get_xres); | ||
212 | EXPORT_SYMBOL(w100fb_get_blanking); | ||
213 | EXPORT_SYMBOL(w100fb_get_fastsysclk); | ||
214 | 185 | ||
215 | 186 | ||
216 | /* | 187 | /* |
@@ -234,7 +205,6 @@ static int w100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
234 | * according to the RGB bitfield information. | 205 | * according to the RGB bitfield information. |
235 | */ | 206 | */ |
236 | if (regno < MAX_PALETTES) { | 207 | if (regno < MAX_PALETTES) { |
237 | |||
238 | u32 *pal = info->pseudo_palette; | 208 | u32 *pal = info->pseudo_palette; |
239 | 209 | ||
240 | val = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); | 210 | val = (red & 0xf800) | ((green & 0xfc00) >> 5) | ((blue & 0xf800) >> 11); |
@@ -250,115 +220,90 @@ static int w100fb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, | |||
250 | */ | 220 | */ |
251 | static int w100fb_blank(int blank_mode, struct fb_info *info) | 221 | static int w100fb_blank(int blank_mode, struct fb_info *info) |
252 | { | 222 | { |
253 | struct w100fb_par *par; | 223 | struct w100fb_par *par = info->par; |
254 | par=info->par; | 224 | struct w100_tg_info *tg = par->mach->tg; |
255 | 225 | ||
256 | switch(blank_mode) { | 226 | switch(blank_mode) { |
257 | 227 | ||
258 | case FB_BLANK_NORMAL: /* Normal blanking */ | 228 | case FB_BLANK_NORMAL: /* Normal blanking */ |
259 | case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */ | 229 | case FB_BLANK_VSYNC_SUSPEND: /* VESA blank (vsync off) */ |
260 | case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */ | 230 | case FB_BLANK_HSYNC_SUSPEND: /* VESA blank (hsync off) */ |
261 | case FB_BLANK_POWERDOWN: /* Poweroff */ | 231 | case FB_BLANK_POWERDOWN: /* Poweroff */ |
262 | if (par->blanking_flag == 0) { | 232 | if (par->blanked == 0) { |
263 | w100fb_save_buffer(); | 233 | if(tg && tg->suspend) |
264 | lcdtg_suspend(); | 234 | tg->suspend(par); |
265 | par->blanking_flag = 1; | 235 | par->blanked = 1; |
266 | } | 236 | } |
267 | break; | 237 | break; |
268 | 238 | ||
269 | case FB_BLANK_UNBLANK: /* Unblanking */ | 239 | case FB_BLANK_UNBLANK: /* Unblanking */ |
270 | if (par->blanking_flag != 0) { | 240 | if (par->blanked != 0) { |
271 | w100fb_restore_buffer(); | 241 | if(tg && tg->resume) |
272 | lcdtg_resume(); | 242 | tg->resume(par); |
273 | par->blanking_flag = 0; | 243 | par->blanked = 0; |
274 | } | 244 | } |
275 | break; | 245 | break; |
276 | } | 246 | } |
277 | return 0; | 247 | return 0; |
278 | } | 248 | } |
279 | 249 | ||
250 | |||
280 | /* | 251 | /* |
281 | * Change the resolution by calling the appropriate hardware functions | 252 | * Change the resolution by calling the appropriate hardware functions |
282 | */ | 253 | */ |
283 | static void w100fb_changeres(int rotate_mode, u32 mode) | 254 | static void w100fb_activate_var(struct w100fb_par *par) |
284 | { | 255 | { |
285 | u16 rotation=0; | 256 | struct w100_tg_info *tg = par->mach->tg; |
286 | |||
287 | switch(rotate_mode) { | ||
288 | case LCD_MODE_LANDSCAPE: | ||
289 | rotation=(current_par->rotation_flag ? 270 : 90); | ||
290 | break; | ||
291 | case LCD_MODE_PORTRAIT: | ||
292 | rotation=(current_par->rotation_flag ? 180 : 0); | ||
293 | break; | ||
294 | } | ||
295 | 257 | ||
296 | w100_pwm_setup(); | 258 | w100_pwm_setup(par); |
297 | switch(mode) { | 259 | w100_setup_memory(par); |
298 | case LCD_SHARP_QVGA: | 260 | w100_init_clocks(par); |
299 | w100_vsync(); | 261 | w100fb_clear_screen(par); |
300 | w100_suspend(W100_SUSPEND_EXTMEM); | 262 | w100_vsync(); |
301 | w100_init_sharp_lcd(LCD_SHARP_QVGA); | 263 | |
302 | w100_init_qvga_rotation(rotation); | 264 | w100_update_disable(); |
303 | w100_InitExtMem(LCD_SHARP_QVGA); | 265 | w100_init_lcd(par); |
304 | w100fb_clear_screen(LCD_SHARP_QVGA, 0); | 266 | w100_set_dispregs(par); |
305 | lcdtg_lcd_change(LCD_SHARP_QVGA); | 267 | w100_update_enable(); |
306 | break; | 268 | |
307 | case LCD_SHARP_VGA: | 269 | calc_hsync(par); |
308 | w100fb_clear_screen(LCD_SHARP_QVGA, 0); | 270 | |
309 | writel(0xBFFFA000, remapped_regs + mmMC_EXT_MEM_LOCATION); | 271 | if (!par->blanked && tg && tg->change) |
310 | w100_InitExtMem(LCD_SHARP_VGA); | 272 | tg->change(par); |
311 | w100fb_clear_screen(LCD_SHARP_VGA, 0x200000); | ||
312 | w100_vsync(); | ||
313 | w100_init_sharp_lcd(LCD_SHARP_VGA); | ||
314 | if (rotation != 0) | ||
315 | w100_init_vga_rotation(rotation); | ||
316 | lcdtg_lcd_change(LCD_SHARP_VGA); | ||
317 | break; | ||
318 | } | ||
319 | } | 273 | } |
320 | 274 | ||
321 | /* | 275 | |
322 | * Set up the display for the fb subsystem | 276 | /* Select the smallest mode that allows the desired resolution to be |
277 | * displayed. If desired, the x and y parameters can be rounded up to | ||
278 | * match the selected mode. | ||
323 | */ | 279 | */ |
324 | static void w100fb_activate_var(struct fb_info *info) | 280 | static struct w100_mode *w100fb_get_mode(struct w100fb_par *par, unsigned int *x, unsigned int *y, int saveval) |
325 | { | 281 | { |
326 | u32 temp32; | 282 | struct w100_mode *mode = NULL; |
327 | struct w100fb_par *par=info->par; | 283 | struct w100_mode *modelist = par->mach->modelist; |
328 | struct fb_var_screeninfo *var = &info->var; | 284 | unsigned int best_x = 0xffffffff, best_y = 0xffffffff; |
285 | unsigned int i; | ||
286 | |||
287 | for (i = 0 ; i < par->mach->num_modes ; i++) { | ||
288 | if (modelist[i].xres >= *x && modelist[i].yres >= *y && | ||
289 | modelist[i].xres < best_x && modelist[i].yres < best_y) { | ||
290 | best_x = modelist[i].xres; | ||
291 | best_y = modelist[i].yres; | ||
292 | mode = &modelist[i]; | ||
293 | } else if(modelist[i].xres >= *y && modelist[i].yres >= *x && | ||
294 | modelist[i].xres < best_y && modelist[i].yres < best_x) { | ||
295 | best_x = modelist[i].yres; | ||
296 | best_y = modelist[i].xres; | ||
297 | mode = &modelist[i]; | ||
298 | } | ||
299 | } | ||
329 | 300 | ||
330 | /* Set the hardware to 565 */ | 301 | if (mode && saveval) { |
331 | temp32 = readl(remapped_regs + mmDISP_DEBUG2); | 302 | *x = best_x; |
332 | temp32 &= 0xff7fffff; | 303 | *y = best_y; |
333 | temp32 |= 0x00800000; | 304 | } |
334 | writel(temp32, remapped_regs + mmDISP_DEBUG2); | ||
335 | 305 | ||
336 | if (par->lcdMode == LCD_MODE_INIT) { | 306 | return mode; |
337 | w100_init_sharp_lcd(LCD_SHARP_VGA); | ||
338 | w100_init_vga_rotation(par->rotation_flag ? 270 : 90); | ||
339 | par->lcdMode = LCD_MODE_640; | ||
340 | lcdtg_hw_init(LCD_SHARP_VGA); | ||
341 | } else if (var->xres == 320 && var->yres == 240) { | ||
342 | if (par->lcdMode != LCD_MODE_320) { | ||
343 | w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_QVGA); | ||
344 | par->lcdMode = LCD_MODE_320; | ||
345 | } | ||
346 | } else if (var->xres == 240 && var->yres == 320) { | ||
347 | if (par->lcdMode != LCD_MODE_240) { | ||
348 | w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_QVGA); | ||
349 | par->lcdMode = LCD_MODE_240; | ||
350 | } | ||
351 | } else if (var->xres == 640 && var->yres == 480) { | ||
352 | if (par->lcdMode != LCD_MODE_640) { | ||
353 | w100fb_changeres(LCD_MODE_LANDSCAPE, LCD_SHARP_VGA); | ||
354 | par->lcdMode = LCD_MODE_640; | ||
355 | } | ||
356 | } else if (var->xres == 480 && var->yres == 640) { | ||
357 | if (par->lcdMode != LCD_MODE_480) { | ||
358 | w100fb_changeres(LCD_MODE_PORTRAIT, LCD_SHARP_VGA); | ||
359 | par->lcdMode = LCD_MODE_480; | ||
360 | } | ||
361 | } else printk(KERN_ERR "W100FB: Resolution error!\n"); | ||
362 | } | 307 | } |
363 | 308 | ||
364 | 309 | ||
@@ -366,31 +311,19 @@ static void w100fb_activate_var(struct fb_info *info) | |||
366 | * w100fb_check_var(): | 311 | * w100fb_check_var(): |
367 | * Get the video params out of 'var'. If a value doesn't fit, round it up, | 312 | * Get the video params out of 'var'. If a value doesn't fit, round it up, |
368 | * if it's too big, return -EINVAL. | 313 | * if it's too big, return -EINVAL. |
369 | * | ||
370 | */ | 314 | */ |
371 | static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | 315 | static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) |
372 | { | 316 | { |
373 | if (var->xres < var->yres) { /* Portrait mode */ | 317 | struct w100fb_par *par=info->par; |
374 | if ((var->xres > 480) || (var->yres > 640)) { | 318 | |
375 | return -EINVAL; | 319 | if(!w100fb_get_mode(par, &var->xres, &var->yres, 1)) |
376 | } else if ((var->xres > 240) || (var->yres > 320)) { | 320 | return -EINVAL; |
377 | var->xres = 480; | 321 | |
378 | var->yres = 640; | 322 | if (par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (par->mach->mem->size+1))) |
379 | } else { | 323 | return -EINVAL; |
380 | var->xres = 240; | 324 | |
381 | var->yres = 320; | 325 | if (!par->mach->mem && ((var->xres*var->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1))) |
382 | } | 326 | return -EINVAL; |
383 | } else { /* Landscape mode */ | ||
384 | if ((var->xres > 640) || (var->yres > 480)) { | ||
385 | return -EINVAL; | ||
386 | } else if ((var->xres > 320) || (var->yres > 240)) { | ||
387 | var->xres = 640; | ||
388 | var->yres = 480; | ||
389 | } else { | ||
390 | var->xres = 320; | ||
391 | var->yres = 240; | ||
392 | } | ||
393 | } | ||
394 | 327 | ||
395 | var->xres_virtual = max(var->xres_virtual, var->xres); | 328 | var->xres_virtual = max(var->xres_virtual, var->xres); |
396 | var->yres_virtual = max(var->yres_virtual, var->yres); | 329 | var->yres_virtual = max(var->yres_virtual, var->yres); |
@@ -409,13 +342,11 @@ static int w100fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) | |||
409 | var->transp.offset = var->transp.length = 0; | 342 | var->transp.offset = var->transp.length = 0; |
410 | 343 | ||
411 | var->nonstd = 0; | 344 | var->nonstd = 0; |
412 | |||
413 | var->height = -1; | 345 | var->height = -1; |
414 | var->width = -1; | 346 | var->width = -1; |
415 | var->vmode = FB_VMODE_NONINTERLACED; | 347 | var->vmode = FB_VMODE_NONINTERLACED; |
416 | |||
417 | var->sync = 0; | 348 | var->sync = 0; |
418 | var->pixclock = 0x04; /* 171521; */ | 349 | var->pixclock = 0x04; /* 171521; */ |
419 | 350 | ||
420 | return 0; | 351 | return 0; |
421 | } | 352 | } |
@@ -430,274 +361,286 @@ static int w100fb_set_par(struct fb_info *info) | |||
430 | { | 361 | { |
431 | struct w100fb_par *par=info->par; | 362 | struct w100fb_par *par=info->par; |
432 | 363 | ||
433 | par->xres = info->var.xres; | 364 | if (par->xres != info->var.xres || par->yres != info->var.yres) { |
434 | par->yres = info->var.yres; | 365 | par->xres = info->var.xres; |
435 | 366 | par->yres = info->var.yres; | |
436 | info->fix.visual = FB_VISUAL_TRUECOLOR; | 367 | par->mode = w100fb_get_mode(par, &par->xres, &par->yres, 0); |
437 | |||
438 | info->fix.ypanstep = 0; | ||
439 | info->fix.ywrapstep = 0; | ||
440 | 368 | ||
441 | if (par->blanking_flag) | 369 | info->fix.visual = FB_VISUAL_TRUECOLOR; |
442 | w100fb_clear_buffer(); | 370 | info->fix.ypanstep = 0; |
371 | info->fix.ywrapstep = 0; | ||
372 | info->fix.line_length = par->xres * BITS_PER_PIXEL / 8; | ||
443 | 373 | ||
444 | w100fb_activate_var(info); | 374 | if ((par->xres*par->yres*BITS_PER_PIXEL/8) > (MEM_INT_SIZE+1)) { |
375 | par->extmem_active = 1; | ||
376 | info->fix.smem_len = par->mach->mem->size+1; | ||
377 | } else { | ||
378 | par->extmem_active = 0; | ||
379 | info->fix.smem_len = MEM_INT_SIZE+1; | ||
380 | } | ||
445 | 381 | ||
446 | if (par->lcdMode == LCD_MODE_480) { | 382 | w100fb_activate_var(par); |
447 | info->fix.line_length = (480 * BITS_PER_PIXEL) / 8; | ||
448 | info->fix.smem_len = 0x200000; | ||
449 | } else if (par->lcdMode == LCD_MODE_320) { | ||
450 | info->fix.line_length = (320 * BITS_PER_PIXEL) / 8; | ||
451 | info->fix.smem_len = 0x60000; | ||
452 | } else if (par->lcdMode == LCD_MODE_240) { | ||
453 | info->fix.line_length = (240 * BITS_PER_PIXEL) / 8; | ||
454 | info->fix.smem_len = 0x60000; | ||
455 | } else if (par->lcdMode == LCD_MODE_INIT || par->lcdMode == LCD_MODE_640) { | ||
456 | info->fix.line_length = (640 * BITS_PER_PIXEL) / 8; | ||
457 | info->fix.smem_len = 0x200000; | ||
458 | } | 383 | } |
459 | |||
460 | return 0; | 384 | return 0; |
461 | } | 385 | } |
462 | 386 | ||
463 | 387 | ||
464 | /* | 388 | /* |
465 | * Frame buffer operations | 389 | * Frame buffer operations |
466 | */ | 390 | */ |
467 | static struct fb_ops w100fb_ops = { | 391 | static struct fb_ops w100fb_ops = { |
468 | .owner = THIS_MODULE, | 392 | .owner = THIS_MODULE, |
469 | .fb_check_var = w100fb_check_var, | 393 | .fb_check_var = w100fb_check_var, |
470 | .fb_set_par = w100fb_set_par, | 394 | .fb_set_par = w100fb_set_par, |
471 | .fb_setcolreg = w100fb_setcolreg, | 395 | .fb_setcolreg = w100fb_setcolreg, |
472 | .fb_blank = w100fb_blank, | 396 | .fb_blank = w100fb_blank, |
473 | .fb_fillrect = cfb_fillrect, | 397 | .fb_fillrect = cfb_fillrect, |
474 | .fb_copyarea = cfb_copyarea, | 398 | .fb_copyarea = cfb_copyarea, |
475 | .fb_imageblit = cfb_imageblit, | 399 | .fb_imageblit = cfb_imageblit, |
476 | .fb_cursor = soft_cursor, | 400 | .fb_cursor = soft_cursor, |
477 | }; | 401 | }; |
478 | 402 | ||
479 | 403 | #ifdef CONFIG_PM | |
480 | static void w100fb_clear_screen(u32 mode, long int offset) | 404 | static void w100fb_save_vidmem(struct w100fb_par *par) |
481 | { | 405 | { |
482 | int i, numPix = 0; | 406 | int memsize; |
483 | |||
484 | if (mode == LCD_SHARP_VGA) | ||
485 | numPix = 640 * 480; | ||
486 | else if (mode == LCD_SHARP_QVGA) | ||
487 | numPix = 320 * 240; | ||
488 | 407 | ||
489 | for (i = 0; i < numPix; i++) | 408 | if (par->extmem_active) { |
490 | writew(0xffff, remapped_fbuf + offset + (2*i)); | 409 | memsize=par->mach->mem->size; |
491 | } | 410 | par->saved_extmem = vmalloc(memsize); |
492 | 411 | if (par->saved_extmem) | |
493 | 412 | memcpy_fromio(par->saved_extmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize); | |
494 | /* Need to split up the buffers to stay within the limits of kmalloc */ | ||
495 | #define W100_BUF_NUM 6 | ||
496 | static uint32_t *gSaveImagePtr[W100_BUF_NUM] = { NULL }; | ||
497 | |||
498 | static void w100fb_save_buffer(void) | ||
499 | { | ||
500 | int i, j, bufsize; | ||
501 | |||
502 | bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM; | ||
503 | for (i = 0; i < W100_BUF_NUM; i++) { | ||
504 | if (gSaveImagePtr[i] == NULL) | ||
505 | gSaveImagePtr[i] = kmalloc(bufsize, GFP_KERNEL); | ||
506 | if (gSaveImagePtr[i] == NULL) { | ||
507 | w100fb_clear_buffer(); | ||
508 | printk(KERN_WARNING "can't alloc pre-off image buffer %d\n", i); | ||
509 | break; | ||
510 | } | ||
511 | for (j = 0; j < bufsize/4; j++) | ||
512 | *(gSaveImagePtr[i] + j) = readl(remapped_fbuf + (bufsize*i) + j*4); | ||
513 | } | 413 | } |
414 | memsize=MEM_INT_SIZE; | ||
415 | par->saved_intmem = vmalloc(memsize); | ||
416 | if (par->saved_intmem && par->extmem_active) | ||
417 | memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), memsize); | ||
418 | else if (par->saved_intmem) | ||
419 | memcpy_fromio(par->saved_intmem, remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), memsize); | ||
514 | } | 420 | } |
515 | 421 | ||
516 | 422 | static void w100fb_restore_vidmem(struct w100fb_par *par) | |
517 | static void w100fb_restore_buffer(void) | ||
518 | { | 423 | { |
519 | int i, j, bufsize; | 424 | int memsize; |
520 | 425 | ||
521 | bufsize=(current_par->xres * current_par->yres * BITS_PER_PIXEL / 8) / W100_BUF_NUM; | 426 | if (par->extmem_active && par->saved_extmem) { |
522 | for (i = 0; i < W100_BUF_NUM; i++) { | 427 | memsize=par->mach->mem->size; |
523 | if (gSaveImagePtr[i] == NULL) { | 428 | memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_extmem, memsize); |
524 | printk(KERN_WARNING "can't find pre-off image buffer %d\n", i); | 429 | vfree(par->saved_extmem); |
525 | w100fb_clear_buffer(); | ||
526 | break; | ||
527 | } | ||
528 | for (j = 0; j < (bufsize/4); j++) | ||
529 | writel(*(gSaveImagePtr[i] + j),remapped_fbuf + (bufsize*i) + (j*4)); | ||
530 | kfree(gSaveImagePtr[i]); | ||
531 | gSaveImagePtr[i] = NULL; | ||
532 | } | 430 | } |
533 | } | 431 | if (par->saved_intmem) { |
534 | 432 | memsize=MEM_INT_SIZE; | |
535 | 433 | if (par->extmem_active) | |
536 | static void w100fb_clear_buffer(void) | 434 | memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_INT_BASE_VALUE), par->saved_intmem, memsize); |
537 | { | 435 | else |
538 | int i; | 436 | memcpy_toio(remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE), par->saved_intmem, memsize); |
539 | for (i = 0; i < W100_BUF_NUM; i++) { | 437 | vfree(par->saved_intmem); |
540 | kfree(gSaveImagePtr[i]); | ||
541 | gSaveImagePtr[i] = NULL; | ||
542 | } | 438 | } |
543 | } | 439 | } |
544 | 440 | ||
545 | 441 | static int w100fb_suspend(struct device *dev, pm_message_t state, uint32_t level) | |
546 | #ifdef CONFIG_PM | ||
547 | static int w100fb_suspend(struct device *dev, pm_message_t state, u32 level) | ||
548 | { | 442 | { |
549 | if (level == SUSPEND_POWER_DOWN) { | 443 | if (level == SUSPEND_POWER_DOWN) { |
550 | struct fb_info *info = dev_get_drvdata(dev); | 444 | struct fb_info *info = dev_get_drvdata(dev); |
551 | struct w100fb_par *par=info->par; | 445 | struct w100fb_par *par=info->par; |
446 | struct w100_tg_info *tg = par->mach->tg; | ||
552 | 447 | ||
553 | w100fb_save_buffer(); | 448 | w100fb_save_vidmem(par); |
554 | lcdtg_suspend(); | 449 | if(tg && tg->suspend) |
450 | tg->suspend(par); | ||
555 | w100_suspend(W100_SUSPEND_ALL); | 451 | w100_suspend(W100_SUSPEND_ALL); |
556 | par->blanking_flag = 1; | 452 | par->blanked = 1; |
557 | } | 453 | } |
558 | return 0; | 454 | return 0; |
559 | } | 455 | } |
560 | 456 | ||
561 | static int w100fb_resume(struct device *dev, u32 level) | 457 | static int w100fb_resume(struct device *dev, uint32_t level) |
562 | { | 458 | { |
563 | if (level == RESUME_POWER_ON) { | 459 | if (level == RESUME_POWER_ON) { |
564 | struct fb_info *info = dev_get_drvdata(dev); | 460 | struct fb_info *info = dev_get_drvdata(dev); |
565 | struct w100fb_par *par=info->par; | 461 | struct w100fb_par *par=info->par; |
566 | 462 | struct w100_tg_info *tg = par->mach->tg; | |
567 | w100_resume(); | 463 | |
568 | w100fb_restore_buffer(); | 464 | w100_hw_init(par); |
569 | lcdtg_resume(); | 465 | w100fb_activate_var(par); |
570 | par->blanking_flag = 0; | 466 | w100fb_restore_vidmem(par); |
467 | if(tg && tg->resume) | ||
468 | tg->resume(par); | ||
469 | par->blanked = 0; | ||
571 | } | 470 | } |
572 | return 0; | 471 | return 0; |
573 | } | 472 | } |
574 | #else | 473 | #else |
575 | #define w100fb_suspend NULL | 474 | #define w100fb_suspend NULL |
576 | #define w100fb_resume NULL | 475 | #define w100fb_resume NULL |
577 | #endif | 476 | #endif |
578 | 477 | ||
579 | 478 | ||
580 | int __init w100fb_probe(struct device *dev) | 479 | int __init w100fb_probe(struct device *dev) |
581 | { | 480 | { |
481 | int err = -EIO; | ||
582 | struct w100fb_mach_info *inf; | 482 | struct w100fb_mach_info *inf; |
583 | struct fb_info *info; | 483 | struct fb_info *info = NULL; |
584 | struct w100fb_par *par; | 484 | struct w100fb_par *par; |
585 | struct platform_device *pdev = to_platform_device(dev); | 485 | struct platform_device *pdev = to_platform_device(dev); |
586 | struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 486 | struct resource *mem = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
487 | unsigned int chip_id; | ||
587 | 488 | ||
588 | if (!mem) | 489 | if (!mem) |
589 | return -EINVAL; | 490 | return -EINVAL; |
590 | 491 | ||
591 | /* remap the areas we're going to use */ | 492 | /* Remap the chip base address */ |
592 | remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN); | 493 | remapped_base = ioremap_nocache(mem->start+W100_CFG_BASE, W100_CFG_LEN); |
593 | if (remapped_base == NULL) | 494 | if (remapped_base == NULL) |
594 | return -EIO; | 495 | goto out; |
595 | 496 | ||
497 | /* Map the register space */ | ||
596 | remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN); | 498 | remapped_regs = ioremap_nocache(mem->start+W100_REG_BASE, W100_REG_LEN); |
597 | if (remapped_regs == NULL) { | 499 | if (remapped_regs == NULL) |
598 | iounmap(remapped_base); | 500 | goto out; |
599 | return -EIO; | 501 | |
502 | /* Identify the chip */ | ||
503 | printk("Found "); | ||
504 | chip_id = readl(remapped_regs + mmCHIP_ID); | ||
505 | switch(chip_id) { | ||
506 | case CHIP_ID_W100: printk("w100"); break; | ||
507 | case CHIP_ID_W3200: printk("w3200"); break; | ||
508 | case CHIP_ID_W3220: printk("w3220"); break; | ||
509 | default: | ||
510 | printk("Unknown imageon chip ID\n"); | ||
511 | err = -ENODEV; | ||
512 | goto out; | ||
600 | } | 513 | } |
514 | printk(" at 0x%08lx.\n", mem->start+W100_CFG_BASE); | ||
601 | 515 | ||
602 | remapped_fbuf = ioremap_nocache(mem->start+MEM_EXT_BASE_VALUE, REMAPPED_FB_LEN); | 516 | /* Remap the framebuffer */ |
603 | if (remapped_fbuf == NULL) { | 517 | remapped_fbuf = ioremap_nocache(mem->start+MEM_WINDOW_BASE, MEM_WINDOW_SIZE); |
604 | iounmap(remapped_base); | 518 | if (remapped_fbuf == NULL) |
605 | iounmap(remapped_regs); | 519 | goto out; |
606 | return -EIO; | ||
607 | } | ||
608 | 520 | ||
609 | info=framebuffer_alloc(sizeof(struct w100fb_par), dev); | 521 | info=framebuffer_alloc(sizeof(struct w100fb_par), dev); |
610 | if (!info) { | 522 | if (!info) { |
611 | iounmap(remapped_base); | 523 | err = -ENOMEM; |
612 | iounmap(remapped_regs); | 524 | goto out; |
613 | iounmap(remapped_fbuf); | ||
614 | return -ENOMEM; | ||
615 | } | 525 | } |
616 | 526 | ||
617 | info->device=dev; | ||
618 | par = info->par; | 527 | par = info->par; |
619 | current_par=info->par; | ||
620 | dev_set_drvdata(dev, info); | 528 | dev_set_drvdata(dev, info); |
621 | 529 | ||
622 | inf = dev->platform_data; | 530 | inf = dev->platform_data; |
623 | par->phadadj = inf->phadadj; | 531 | par->chip_id = chip_id; |
624 | par->comadj = inf->comadj; | 532 | par->mach = inf; |
625 | par->fastsysclk_mode = 75; | 533 | par->fastpll_mode = 0; |
626 | par->lcdMode = LCD_MODE_INIT; | 534 | par->blanked = 0; |
627 | par->rotation_flag=0; | 535 | |
628 | par->blanking_flag=0; | 536 | par->pll_table=w100_get_xtal_table(inf->xtal_freq); |
629 | w100fb_ssp_send = inf->w100fb_ssp_send; | 537 | if (!par->pll_table) { |
630 | 538 | printk(KERN_ERR "No matching Xtal definition found\n"); | |
631 | w100_hw_init(); | 539 | err = -EINVAL; |
632 | w100_pwm_setup(); | 540 | goto out; |
541 | } | ||
633 | 542 | ||
634 | info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL); | 543 | info->pseudo_palette = kmalloc(sizeof (u32) * MAX_PALETTES, GFP_KERNEL); |
635 | if (!info->pseudo_palette) { | 544 | if (!info->pseudo_palette) { |
636 | iounmap(remapped_base); | 545 | err = -ENOMEM; |
637 | iounmap(remapped_regs); | 546 | goto out; |
638 | iounmap(remapped_fbuf); | ||
639 | return -ENOMEM; | ||
640 | } | 547 | } |
641 | 548 | ||
642 | info->fbops = &w100fb_ops; | 549 | info->fbops = &w100fb_ops; |
643 | info->flags = FBINFO_DEFAULT; | 550 | info->flags = FBINFO_DEFAULT; |
644 | info->node = -1; | 551 | info->node = -1; |
645 | info->screen_base = remapped_fbuf; | 552 | info->screen_base = remapped_fbuf + (W100_FB_BASE-MEM_WINDOW_BASE); |
646 | info->screen_size = REMAPPED_FB_LEN; | 553 | info->screen_size = REMAPPED_FB_LEN; |
647 | 554 | ||
648 | info->var.xres = 640; | 555 | strcpy(info->fix.id, "w100fb"); |
556 | info->fix.type = FB_TYPE_PACKED_PIXELS; | ||
557 | info->fix.type_aux = 0; | ||
558 | info->fix.accel = FB_ACCEL_NONE; | ||
559 | info->fix.smem_start = mem->start+W100_FB_BASE; | ||
560 | info->fix.mmio_start = mem->start+W100_REG_BASE; | ||
561 | info->fix.mmio_len = W100_REG_LEN; | ||
562 | |||
563 | if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { | ||
564 | err = -ENOMEM; | ||
565 | goto out; | ||
566 | } | ||
567 | |||
568 | par->mode = &inf->modelist[0]; | ||
569 | if(inf->init_mode & INIT_MODE_ROTATED) { | ||
570 | info->var.xres = par->mode->yres; | ||
571 | info->var.yres = par->mode->xres; | ||
572 | } | ||
573 | else { | ||
574 | info->var.xres = par->mode->xres; | ||
575 | info->var.yres = par->mode->yres; | ||
576 | } | ||
577 | |||
578 | if(inf->init_mode &= INIT_MODE_FLIPPED) | ||
579 | par->flip = 1; | ||
580 | else | ||
581 | par->flip = 0; | ||
582 | |||
649 | info->var.xres_virtual = info->var.xres; | 583 | info->var.xres_virtual = info->var.xres; |
650 | info->var.yres = 480; | ||
651 | info->var.yres_virtual = info->var.yres; | 584 | info->var.yres_virtual = info->var.yres; |
652 | info->var.pixclock = 0x04; /* 171521; */ | 585 | info->var.pixclock = 0x04; /* 171521; */ |
653 | info->var.sync = 0; | 586 | info->var.sync = 0; |
654 | info->var.grayscale = 0; | 587 | info->var.grayscale = 0; |
655 | info->var.xoffset = info->var.yoffset = 0; | 588 | info->var.xoffset = info->var.yoffset = 0; |
656 | info->var.accel_flags = 0; | 589 | info->var.accel_flags = 0; |
657 | info->var.activate = FB_ACTIVATE_NOW; | 590 | info->var.activate = FB_ACTIVATE_NOW; |
658 | 591 | ||
659 | strcpy(info->fix.id, "w100fb"); | 592 | w100_hw_init(par); |
660 | info->fix.type = FB_TYPE_PACKED_PIXELS; | 593 | |
661 | info->fix.type_aux = 0; | 594 | if (w100fb_check_var(&info->var, info) < 0) { |
662 | info->fix.accel = FB_ACCEL_NONE; | 595 | err = -EINVAL; |
663 | info->fix.smem_start = mem->start+MEM_EXT_BASE_VALUE; | 596 | goto out; |
664 | info->fix.mmio_start = mem->start+W100_REG_BASE; | 597 | } |
665 | info->fix.mmio_len = W100_REG_LEN; | ||
666 | 598 | ||
667 | w100fb_check_var(&info->var, info); | ||
668 | w100fb_set_par(info); | 599 | w100fb_set_par(info); |
669 | 600 | ||
670 | if (register_framebuffer(info) < 0) { | 601 | if (register_framebuffer(info) < 0) { |
671 | kfree(info->pseudo_palette); | 602 | err = -EINVAL; |
672 | iounmap(remapped_base); | 603 | goto out; |
673 | iounmap(remapped_regs); | ||
674 | iounmap(remapped_fbuf); | ||
675 | return -EINVAL; | ||
676 | } | 604 | } |
677 | 605 | ||
678 | device_create_file(dev, &dev_attr_fastsysclk); | 606 | device_create_file(dev, &dev_attr_fastpllclk); |
679 | device_create_file(dev, &dev_attr_reg_read); | 607 | device_create_file(dev, &dev_attr_reg_read); |
680 | device_create_file(dev, &dev_attr_reg_write); | 608 | device_create_file(dev, &dev_attr_reg_write); |
681 | device_create_file(dev, &dev_attr_rotation); | 609 | device_create_file(dev, &dev_attr_flip); |
682 | 610 | ||
683 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); | 611 | printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); |
684 | return 0; | 612 | return 0; |
613 | out: | ||
614 | fb_dealloc_cmap(&info->cmap); | ||
615 | kfree(info->pseudo_palette); | ||
616 | if (remapped_fbuf != NULL) | ||
617 | iounmap(remapped_fbuf); | ||
618 | if (remapped_regs != NULL) | ||
619 | iounmap(remapped_regs); | ||
620 | if (remapped_base != NULL) | ||
621 | iounmap(remapped_base); | ||
622 | if (info) | ||
623 | framebuffer_release(info); | ||
624 | return err; | ||
685 | } | 625 | } |
686 | 626 | ||
687 | 627 | ||
688 | static int w100fb_remove(struct device *dev) | 628 | static int w100fb_remove(struct device *dev) |
689 | { | 629 | { |
690 | struct fb_info *info = dev_get_drvdata(dev); | 630 | struct fb_info *info = dev_get_drvdata(dev); |
631 | struct w100fb_par *par=info->par; | ||
691 | 632 | ||
692 | device_remove_file(dev, &dev_attr_fastsysclk); | 633 | device_remove_file(dev, &dev_attr_fastpllclk); |
693 | device_remove_file(dev, &dev_attr_reg_read); | 634 | device_remove_file(dev, &dev_attr_reg_read); |
694 | device_remove_file(dev, &dev_attr_reg_write); | 635 | device_remove_file(dev, &dev_attr_reg_write); |
695 | device_remove_file(dev, &dev_attr_rotation); | 636 | device_remove_file(dev, &dev_attr_flip); |
696 | 637 | ||
697 | unregister_framebuffer(info); | 638 | unregister_framebuffer(info); |
698 | 639 | ||
699 | w100fb_clear_buffer(); | 640 | vfree(par->saved_intmem); |
641 | vfree(par->saved_extmem); | ||
700 | kfree(info->pseudo_palette); | 642 | kfree(info->pseudo_palette); |
643 | fb_dealloc_cmap(&info->cmap); | ||
701 | 644 | ||
702 | iounmap(remapped_base); | 645 | iounmap(remapped_base); |
703 | iounmap(remapped_regs); | 646 | iounmap(remapped_regs); |
@@ -721,10 +664,54 @@ static void w100_soft_reset(void) | |||
721 | udelay(100); | 664 | udelay(100); |
722 | } | 665 | } |
723 | 666 | ||
667 | static void w100_update_disable(void) | ||
668 | { | ||
669 | union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl; | ||
670 | |||
671 | /* Prevent display updates */ | ||
672 | disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e; | ||
673 | disp_db_buf_wr_cntl.f.update_db_buf = 0; | ||
674 | disp_db_buf_wr_cntl.f.en_db_buf = 0; | ||
675 | writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL); | ||
676 | } | ||
677 | |||
678 | static void w100_update_enable(void) | ||
679 | { | ||
680 | union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl; | ||
681 | |||
682 | /* Enable display updates */ | ||
683 | disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e; | ||
684 | disp_db_buf_wr_cntl.f.update_db_buf = 1; | ||
685 | disp_db_buf_wr_cntl.f.en_db_buf = 1; | ||
686 | writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL); | ||
687 | } | ||
688 | |||
689 | unsigned long w100fb_gpio_read(int port) | ||
690 | { | ||
691 | unsigned long value; | ||
692 | |||
693 | if (port==W100_GPIO_PORT_A) | ||
694 | value = readl(remapped_regs + mmGPIO_DATA); | ||
695 | else | ||
696 | value = readl(remapped_regs + mmGPIO_DATA2); | ||
697 | |||
698 | return value; | ||
699 | } | ||
700 | |||
701 | void w100fb_gpio_write(int port, unsigned long value) | ||
702 | { | ||
703 | if (port==W100_GPIO_PORT_A) | ||
704 | value = writel(value, remapped_regs + mmGPIO_DATA); | ||
705 | else | ||
706 | value = writel(value, remapped_regs + mmGPIO_DATA2); | ||
707 | } | ||
708 | EXPORT_SYMBOL(w100fb_gpio_read); | ||
709 | EXPORT_SYMBOL(w100fb_gpio_write); | ||
710 | |||
724 | /* | 711 | /* |
725 | * Initialization of critical w100 hardware | 712 | * Initialization of critical w100 hardware |
726 | */ | 713 | */ |
727 | static void w100_hw_init(void) | 714 | static void w100_hw_init(struct w100fb_par *par) |
728 | { | 715 | { |
729 | u32 temp32; | 716 | u32 temp32; |
730 | union cif_cntl_u cif_cntl; | 717 | union cif_cntl_u cif_cntl; |
@@ -735,8 +722,8 @@ static void w100_hw_init(void) | |||
735 | union cpu_defaults_u cpu_default; | 722 | union cpu_defaults_u cpu_default; |
736 | union cif_write_dbg_u cif_write_dbg; | 723 | union cif_write_dbg_u cif_write_dbg; |
737 | union wrap_start_dir_u wrap_start_dir; | 724 | union wrap_start_dir_u wrap_start_dir; |
738 | union mc_ext_mem_location_u mc_ext_mem_loc; | ||
739 | union cif_io_u cif_io; | 725 | union cif_io_u cif_io; |
726 | struct w100_gpio_regs *gpio = par->mach->gpio; | ||
740 | 727 | ||
741 | w100_soft_reset(); | 728 | w100_soft_reset(); |
742 | 729 | ||
@@ -791,19 +778,6 @@ static void w100_hw_init(void) | |||
791 | cfgreg_base.f.cfgreg_base = W100_CFG_BASE; | 778 | cfgreg_base.f.cfgreg_base = W100_CFG_BASE; |
792 | writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE); | 779 | writel((u32) (cfgreg_base.val), remapped_regs + mmCFGREG_BASE); |
793 | 780 | ||
794 | /* This location is relative to internal w100 addresses */ | ||
795 | writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION); | ||
796 | |||
797 | mc_ext_mem_loc.val = defMC_EXT_MEM_LOCATION; | ||
798 | mc_ext_mem_loc.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8; | ||
799 | mc_ext_mem_loc.f.mc_ext_mem_top = MEM_EXT_TOP_VALUE >> 8; | ||
800 | writel((u32) (mc_ext_mem_loc.val), remapped_regs + mmMC_EXT_MEM_LOCATION); | ||
801 | |||
802 | if ((current_par->lcdMode == LCD_MODE_240) || (current_par->lcdMode == LCD_MODE_320)) | ||
803 | w100_InitExtMem(LCD_SHARP_QVGA); | ||
804 | else | ||
805 | w100_InitExtMem(LCD_SHARP_VGA); | ||
806 | |||
807 | wrap_start_dir.val = defWRAP_START_DIR; | 781 | wrap_start_dir.val = defWRAP_START_DIR; |
808 | wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1; | 782 | wrap_start_dir.f.start_addr = WRAP_BUF_BASE_VALUE >> 1; |
809 | writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR); | 783 | writel((u32) (wrap_start_dir.val), remapped_regs + mmWRAP_START_DIR); |
@@ -813,21 +787,24 @@ static void w100_hw_init(void) | |||
813 | writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR); | 787 | writel((u32) (wrap_top_dir.val), remapped_regs + mmWRAP_TOP_DIR); |
814 | 788 | ||
815 | writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL); | 789 | writel((u32) 0x2440, remapped_regs + mmRBBM_CNTL); |
816 | } | ||
817 | 790 | ||
791 | /* Set the hardware to 565 colour */ | ||
792 | temp32 = readl(remapped_regs + mmDISP_DEBUG2); | ||
793 | temp32 &= 0xff7fffff; | ||
794 | temp32 |= 0x00800000; | ||
795 | writel(temp32, remapped_regs + mmDISP_DEBUG2); | ||
818 | 796 | ||
819 | /* | 797 | /* Initialise the GPIO lines */ |
820 | * Types | 798 | if (gpio) { |
821 | */ | 799 | writel(gpio->init_data1, remapped_regs + mmGPIO_DATA); |
800 | writel(gpio->init_data2, remapped_regs + mmGPIO_DATA2); | ||
801 | writel(gpio->gpio_dir1, remapped_regs + mmGPIO_CNTL1); | ||
802 | writel(gpio->gpio_oe1, remapped_regs + mmGPIO_CNTL2); | ||
803 | writel(gpio->gpio_dir2, remapped_regs + mmGPIO_CNTL3); | ||
804 | writel(gpio->gpio_oe2, remapped_regs + mmGPIO_CNTL4); | ||
805 | } | ||
806 | } | ||
822 | 807 | ||
823 | struct pll_parm { | ||
824 | u16 freq; /* desired Fout for PLL */ | ||
825 | u8 M; | ||
826 | u8 N_int; | ||
827 | u8 N_fac; | ||
828 | u8 tfgoal; | ||
829 | u8 lock_time; | ||
830 | }; | ||
831 | 808 | ||
832 | struct power_state { | 809 | struct power_state { |
833 | union clk_pin_cntl_u clk_pin_cntl; | 810 | union clk_pin_cntl_u clk_pin_cntl; |
@@ -835,317 +812,275 @@ struct power_state { | |||
835 | union pll_cntl_u pll_cntl; | 812 | union pll_cntl_u pll_cntl; |
836 | union sclk_cntl_u sclk_cntl; | 813 | union sclk_cntl_u sclk_cntl; |
837 | union pclk_cntl_u pclk_cntl; | 814 | union pclk_cntl_u pclk_cntl; |
838 | union clk_test_cntl_u clk_test_cntl; | ||
839 | union pwrmgt_cntl_u pwrmgt_cntl; | 815 | union pwrmgt_cntl_u pwrmgt_cntl; |
840 | u32 freq; /* Fout for PLL calibration */ | 816 | int auto_mode; /* system clock auto changing? */ |
841 | u8 tf100; /* for pll calibration */ | ||
842 | u8 tf80; /* for pll calibration */ | ||
843 | u8 tf20; /* for pll calibration */ | ||
844 | u8 M; /* for pll calibration */ | ||
845 | u8 N_int; /* for pll calibration */ | ||
846 | u8 N_fac; /* for pll calibration */ | ||
847 | u8 lock_time; /* for pll calibration */ | ||
848 | u8 tfgoal; /* for pll calibration */ | ||
849 | u8 auto_mode; /* hardware auto switch? */ | ||
850 | u8 pwm_mode; /* 0 fast, 1 normal/slow */ | ||
851 | u16 fast_sclk; /* fast clk freq */ | ||
852 | u16 norm_sclk; /* slow clk freq */ | ||
853 | }; | 817 | }; |
854 | 818 | ||
855 | 819 | ||
856 | /* | ||
857 | * Global state variables | ||
858 | */ | ||
859 | |||
860 | static struct power_state w100_pwr_state; | 820 | static struct power_state w100_pwr_state; |
861 | 821 | ||
862 | /* This table is specific for 12.5MHz ref crystal. */ | 822 | /* The PLL Fout is determined by (XtalFreq/(M+1)) * ((N_int+1) + (N_fac/8)) */ |
863 | static struct pll_parm gPLLTable[] = { | 823 | |
864 | /*freq M N_int N_fac tfgoal lock_time */ | 824 | /* 12.5MHz Crystal PLL Table */ |
865 | { 50, 0, 1, 0, 0xE0, 56}, /* 50.00 MHz */ | 825 | static struct w100_pll_info xtal_12500000[] = { |
866 | { 75, 0, 5, 0, 0xDE, 37}, /* 75.00 MHz */ | 826 | /*freq M N_int N_fac tfgoal lock_time */ |
867 | {100, 0, 7, 0, 0xE0, 28}, /* 100.00 MHz */ | 827 | { 50, 0, 1, 0, 0xe0, 56}, /* 50.00 MHz */ |
868 | {125, 0, 9, 0, 0xE0, 22}, /* 125.00 MHz */ | 828 | { 75, 0, 5, 0, 0xde, 37}, /* 75.00 MHz */ |
869 | {150, 0, 11, 0, 0xE0, 17}, /* 150.00 MHz */ | 829 | {100, 0, 7, 0, 0xe0, 28}, /* 100.00 MHz */ |
870 | { 0, 0, 0, 0, 0, 0} /* Terminator */ | 830 | {125, 0, 9, 0, 0xe0, 22}, /* 125.00 MHz */ |
831 | {150, 0, 11, 0, 0xe0, 17}, /* 150.00 MHz */ | ||
832 | { 0, 0, 0, 0, 0, 0}, /* Terminator */ | ||
871 | }; | 833 | }; |
872 | 834 | ||
835 | /* 14.318MHz Crystal PLL Table */ | ||
836 | static struct w100_pll_info xtal_14318000[] = { | ||
837 | /*freq M N_int N_fac tfgoal lock_time */ | ||
838 | { 40, 4, 13, 0, 0xe0, 80}, /* tfgoal guessed */ | ||
839 | { 50, 1, 6, 0, 0xe0, 64}, /* 50.05 MHz */ | ||
840 | { 57, 2, 11, 0, 0xe0, 53}, /* tfgoal guessed */ | ||
841 | { 75, 0, 4, 3, 0xe0, 43}, /* 75.08 MHz */ | ||
842 | {100, 0, 6, 0, 0xe0, 32}, /* 100.10 MHz */ | ||
843 | { 0, 0, 0, 0, 0, 0}, | ||
844 | }; | ||
873 | 845 | ||
874 | static u8 w100_pll_get_testcount(u8 testclk_sel) | 846 | /* 16MHz Crystal PLL Table */ |
847 | static struct w100_pll_info xtal_16000000[] = { | ||
848 | /*freq M N_int N_fac tfgoal lock_time */ | ||
849 | { 72, 1, 8, 0, 0xe0, 48}, /* tfgoal guessed */ | ||
850 | { 95, 1, 10, 7, 0xe0, 38}, /* tfgoal guessed */ | ||
851 | { 96, 1, 11, 0, 0xe0, 36}, /* tfgoal guessed */ | ||
852 | { 0, 0, 0, 0, 0, 0}, | ||
853 | }; | ||
854 | |||
855 | static struct pll_entries { | ||
856 | int xtal_freq; | ||
857 | struct w100_pll_info *pll_table; | ||
858 | } w100_pll_tables[] = { | ||
859 | { 12500000, &xtal_12500000[0] }, | ||
860 | { 14318000, &xtal_14318000[0] }, | ||
861 | { 16000000, &xtal_16000000[0] }, | ||
862 | { 0 }, | ||
863 | }; | ||
864 | |||
865 | struct w100_pll_info *w100_get_xtal_table(unsigned int freq) | ||
875 | { | 866 | { |
867 | struct pll_entries *pll_entry = w100_pll_tables; | ||
868 | |||
869 | do { | ||
870 | if (freq == pll_entry->xtal_freq) | ||
871 | return pll_entry->pll_table; | ||
872 | pll_entry++; | ||
873 | } while (pll_entry->xtal_freq); | ||
874 | return 0; | ||
875 | } | ||
876 | |||
877 | |||
878 | static unsigned int w100_get_testcount(unsigned int testclk_sel) | ||
879 | { | ||
880 | union clk_test_cntl_u clk_test_cntl; | ||
881 | |||
876 | udelay(5); | 882 | udelay(5); |
877 | 883 | ||
878 | w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0; | 884 | /* Select the test clock source and reset */ |
879 | w100_pwr_state.clk_test_cntl.f.testclk_sel = testclk_sel; | 885 | clk_test_cntl.f.start_check_freq = 0x0; |
880 | w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x1; /*reset test count */ | 886 | clk_test_cntl.f.testclk_sel = testclk_sel; |
881 | writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); | 887 | clk_test_cntl.f.tstcount_rst = 0x1; /* set reset */ |
882 | w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0; | 888 | writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); |
883 | writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); | ||
884 | 889 | ||
885 | w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x1; | 890 | clk_test_cntl.f.tstcount_rst = 0x0; /* clear reset */ |
886 | writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); | 891 | writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); |
887 | 892 | ||
893 | /* Run clock test */ | ||
894 | clk_test_cntl.f.start_check_freq = 0x1; | ||
895 | writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); | ||
896 | |||
897 | /* Give the test time to complete */ | ||
888 | udelay(20); | 898 | udelay(20); |
889 | 899 | ||
890 | w100_pwr_state.clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL); | 900 | /* Return the result */ |
891 | w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0; | 901 | clk_test_cntl.val = readl(remapped_regs + mmCLK_TEST_CNTL); |
892 | writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); | 902 | clk_test_cntl.f.start_check_freq = 0x0; |
903 | writel((u32) (clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); | ||
893 | 904 | ||
894 | return w100_pwr_state.clk_test_cntl.f.test_count; | 905 | return clk_test_cntl.f.test_count; |
895 | } | 906 | } |
896 | 907 | ||
897 | 908 | ||
898 | static u8 w100_pll_adjust(void) | 909 | static int w100_pll_adjust(struct w100_pll_info *pll) |
899 | { | 910 | { |
911 | unsigned int tf80; | ||
912 | unsigned int tf20; | ||
913 | |||
914 | /* Initial Settings */ | ||
915 | w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0; /* power down */ | ||
916 | w100_pwr_state.pll_cntl.f.pll_reset = 0x0; /* not reset */ | ||
917 | w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1; /* Hi-Z */ | ||
918 | w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; /* VCO gain = 0 */ | ||
919 | w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0; /* VCO frequency range control = off */ | ||
920 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; /* current offset inside VCO = 0 */ | ||
921 | w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0; | ||
922 | |||
923 | /* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V | ||
924 | * therefore, commented out the following lines | ||
925 | * tf80 meant tf100 | ||
926 | */ | ||
900 | do { | 927 | do { |
901 | /* Wai Ming 80 percent of VDD 1.3V gives 1.04V, minimum operating voltage is 1.08V | 928 | /* set VCO input = 0.8 * VDD */ |
902 | * therefore, commented out the following lines | ||
903 | * tf80 meant tf100 | ||
904 | * set VCO input = 0.8 * VDD | ||
905 | */ | ||
906 | w100_pwr_state.pll_cntl.f.pll_dactal = 0xd; | 929 | w100_pwr_state.pll_cntl.f.pll_dactal = 0xd; |
907 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 930 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); |
908 | 931 | ||
909 | w100_pwr_state.tf80 = w100_pll_get_testcount(0x1); /* PLLCLK */ | 932 | tf80 = w100_get_testcount(TESTCLK_SRC_PLL); |
910 | if (w100_pwr_state.tf80 >= (w100_pwr_state.tfgoal)) { | 933 | if (tf80 >= (pll->tfgoal)) { |
911 | /* set VCO input = 0.2 * VDD */ | 934 | /* set VCO input = 0.2 * VDD */ |
912 | w100_pwr_state.pll_cntl.f.pll_dactal = 0x7; | 935 | w100_pwr_state.pll_cntl.f.pll_dactal = 0x7; |
913 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 936 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); |
914 | 937 | ||
915 | w100_pwr_state.tf20 = w100_pll_get_testcount(0x1); /* PLLCLK */ | 938 | tf20 = w100_get_testcount(TESTCLK_SRC_PLL); |
916 | if (w100_pwr_state.tf20 <= (w100_pwr_state.tfgoal)) | 939 | if (tf20 <= (pll->tfgoal)) |
917 | return 1; // Success | 940 | return 1; /* Success */ |
918 | 941 | ||
919 | if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) && | 942 | if ((w100_pwr_state.pll_cntl.f.pll_vcofr == 0x0) && |
920 | ((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) || | 943 | ((w100_pwr_state.pll_cntl.f.pll_pvg == 0x7) || |
921 | (w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) { | 944 | (w100_pwr_state.pll_cntl.f.pll_ioffset == 0x0))) { |
922 | /* slow VCO config */ | 945 | /* slow VCO config */ |
923 | w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1; | 946 | w100_pwr_state.pll_cntl.f.pll_vcofr = 0x1; |
924 | w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; | 947 | w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; |
925 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; | 948 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; |
926 | writel((u32) (w100_pwr_state.pll_cntl.val), | ||
927 | remapped_regs + mmPLL_CNTL); | ||
928 | continue; | 949 | continue; |
929 | } | 950 | } |
930 | } | 951 | } |
931 | if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) { | 952 | if ((w100_pwr_state.pll_cntl.f.pll_ioffset) < 0x3) { |
932 | w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1; | 953 | w100_pwr_state.pll_cntl.f.pll_ioffset += 0x1; |
933 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 954 | } else if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) { |
934 | continue; | ||
935 | } | ||
936 | if ((w100_pwr_state.pll_cntl.f.pll_pvg) < 0x7) { | ||
937 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; | 955 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; |
938 | w100_pwr_state.pll_cntl.f.pll_pvg += 0x1; | 956 | w100_pwr_state.pll_cntl.f.pll_pvg += 0x1; |
939 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 957 | } else { |
940 | continue; | 958 | return 0; /* Error */ |
941 | } | 959 | } |
942 | return 0; // error | ||
943 | } while(1); | 960 | } while(1); |
944 | } | 961 | } |
945 | 962 | ||
946 | 963 | ||
947 | /* | 964 | /* |
948 | * w100_pll_calibration | 965 | * w100_pll_calibration |
949 | * freq = target frequency of the PLL | ||
950 | * (note: crystal = 14.3MHz) | ||
951 | */ | 966 | */ |
952 | static u8 w100_pll_calibration(u32 freq) | 967 | static int w100_pll_calibration(struct w100_pll_info *pll) |
953 | { | 968 | { |
954 | u8 status; | 969 | int status; |
955 | |||
956 | /* initial setting */ | ||
957 | w100_pwr_state.pll_cntl.f.pll_pwdn = 0x0; /* power down */ | ||
958 | w100_pwr_state.pll_cntl.f.pll_reset = 0x0; /* not reset */ | ||
959 | w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x1; /* Hi-Z */ | ||
960 | w100_pwr_state.pll_cntl.f.pll_pvg = 0x0; /* VCO gain = 0 */ | ||
961 | w100_pwr_state.pll_cntl.f.pll_vcofr = 0x0; /* VCO frequency range control = off */ | ||
962 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; /* current offset inside VCO = 0 */ | ||
963 | w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0; | ||
964 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | ||
965 | 970 | ||
966 | /* check for (tf80 >= tfgoal) && (tf20 =< tfgoal) */ | 971 | status = w100_pll_adjust(pll); |
967 | if ((w100_pwr_state.tf80 < w100_pwr_state.tfgoal) || (w100_pwr_state.tf20 > w100_pwr_state.tfgoal)) { | ||
968 | status=w100_pll_adjust(); | ||
969 | } | ||
970 | /* PLL Reset And Lock */ | ||
971 | 972 | ||
973 | /* PLL Reset And Lock */ | ||
972 | /* set VCO input = 0.5 * VDD */ | 974 | /* set VCO input = 0.5 * VDD */ |
973 | w100_pwr_state.pll_cntl.f.pll_dactal = 0xa; | 975 | w100_pwr_state.pll_cntl.f.pll_dactal = 0xa; |
974 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 976 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); |
975 | 977 | ||
976 | /* reset time */ | 978 | udelay(1); /* reset time */ |
977 | udelay(1); | ||
978 | 979 | ||
979 | /* enable charge pump */ | 980 | /* enable charge pump */ |
980 | w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; /* normal */ | 981 | w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; /* normal */ |
981 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 982 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); |
982 | 983 | ||
983 | /* set VCO input = Hi-Z */ | 984 | /* set VCO input = Hi-Z, disable DAC */ |
984 | /* disable DAC */ | ||
985 | w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; | 985 | w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; |
986 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 986 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); |
987 | 987 | ||
988 | /* lock time */ | 988 | udelay(400); /* lock time */ |
989 | udelay(400); /* delay 400 us */ | ||
990 | 989 | ||
991 | /* PLL locked */ | 990 | /* PLL locked */ |
992 | 991 | ||
993 | w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x1; /* PLL clock */ | ||
994 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); | ||
995 | |||
996 | w100_pwr_state.tf100 = w100_pll_get_testcount(0x1); /* PLLCLK */ | ||
997 | |||
998 | return status; | 992 | return status; |
999 | } | 993 | } |
1000 | 994 | ||
1001 | 995 | ||
1002 | static u8 w100_pll_set_clk(void) | 996 | static int w100_pll_set_clk(struct w100_pll_info *pll) |
1003 | { | 997 | { |
1004 | u8 status; | 998 | int status; |
1005 | 999 | ||
1006 | if (w100_pwr_state.auto_mode == 1) /* auto mode */ | 1000 | if (w100_pwr_state.auto_mode == 1) /* auto mode */ |
1007 | { | 1001 | { |
1008 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; /* disable fast to normal */ | 1002 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; /* disable fast to normal */ |
1009 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; /* disable normal to fast */ | 1003 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; /* disable normal to fast */ |
1010 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); | 1004 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); |
1011 | } | 1005 | } |
1012 | 1006 | ||
1013 | w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* crystal clock */ | 1007 | /* Set system clock source to XTAL whilst adjusting the PLL! */ |
1008 | w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL; | ||
1014 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); | 1009 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); |
1015 | 1010 | ||
1016 | w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = w100_pwr_state.M; | 1011 | w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = pll->M; |
1017 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = w100_pwr_state.N_int; | 1012 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = pll->N_int; |
1018 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = w100_pwr_state.N_fac; | 1013 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = pll->N_fac; |
1019 | w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = w100_pwr_state.lock_time; | 1014 | w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = pll->lock_time; |
1020 | writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV); | 1015 | writel((u32) (w100_pwr_state.pll_ref_fb_div.val), remapped_regs + mmPLL_REF_FB_DIV); |
1021 | 1016 | ||
1022 | w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0; | 1017 | w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0; |
1023 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); | 1018 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); |
1024 | 1019 | ||
1025 | status = w100_pll_calibration (w100_pwr_state.freq); | 1020 | status = w100_pll_calibration(pll); |
1026 | 1021 | ||
1027 | if (w100_pwr_state.auto_mode == 1) /* auto mode */ | 1022 | if (w100_pwr_state.auto_mode == 1) /* auto mode */ |
1028 | { | 1023 | { |
1029 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1; /* reenable fast to normal */ | 1024 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x1; /* reenable fast to normal */ |
1030 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1; /* reenable normal to fast */ | 1025 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x1; /* reenable normal to fast */ |
1031 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); | 1026 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); |
1032 | } | 1027 | } |
1033 | return status; | 1028 | return status; |
1034 | } | 1029 | } |
1035 | 1030 | ||
1036 | 1031 | /* freq = target frequency of the PLL */ | |
1037 | /* assume reference crystal clk is 12.5MHz, | 1032 | static int w100_set_pll_freq(struct w100fb_par *par, unsigned int freq) |
1038 | * and that doubling is not enabled. | ||
1039 | * | ||
1040 | * Freq = 12 == 12.5MHz. | ||
1041 | */ | ||
1042 | static u16 w100_set_slowsysclk(u16 freq) | ||
1043 | { | ||
1044 | if (w100_pwr_state.norm_sclk == freq) | ||
1045 | return freq; | ||
1046 | |||
1047 | if (w100_pwr_state.auto_mode == 1) /* auto mode */ | ||
1048 | return 0; | ||
1049 | |||
1050 | if (freq == 12) { | ||
1051 | w100_pwr_state.norm_sclk = freq; | ||
1052 | w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */ | ||
1053 | w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* crystal src */ | ||
1054 | |||
1055 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); | ||
1056 | |||
1057 | w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x1; | ||
1058 | writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL); | ||
1059 | |||
1060 | w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x1; | ||
1061 | w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1; | ||
1062 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); | ||
1063 | w100_pwr_state.pwm_mode = 1; /* normal mode */ | ||
1064 | return freq; | ||
1065 | } else | ||
1066 | return 0; | ||
1067 | } | ||
1068 | |||
1069 | |||
1070 | static u16 w100_set_fastsysclk(u16 freq) | ||
1071 | { | 1033 | { |
1072 | u16 pll_freq; | 1034 | struct w100_pll_info *pll = par->pll_table; |
1073 | int i; | ||
1074 | |||
1075 | while(1) { | ||
1076 | pll_freq = (u16) (freq * (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast + 1)); | ||
1077 | i = 0; | ||
1078 | do { | ||
1079 | if (pll_freq == gPLLTable[i].freq) { | ||
1080 | w100_pwr_state.freq = gPLLTable[i].freq * 1000000; | ||
1081 | w100_pwr_state.M = gPLLTable[i].M; | ||
1082 | w100_pwr_state.N_int = gPLLTable[i].N_int; | ||
1083 | w100_pwr_state.N_fac = gPLLTable[i].N_fac; | ||
1084 | w100_pwr_state.tfgoal = gPLLTable[i].tfgoal; | ||
1085 | w100_pwr_state.lock_time = gPLLTable[i].lock_time; | ||
1086 | w100_pwr_state.tf20 = 0xff; /* set highest */ | ||
1087 | w100_pwr_state.tf80 = 0x00; /* set lowest */ | ||
1088 | |||
1089 | w100_pll_set_clk(); | ||
1090 | w100_pwr_state.pwm_mode = 0; /* fast mode */ | ||
1091 | w100_pwr_state.fast_sclk = freq; | ||
1092 | return freq; | ||
1093 | } | ||
1094 | i++; | ||
1095 | } while(gPLLTable[i].freq); | ||
1096 | 1035 | ||
1097 | if (w100_pwr_state.auto_mode == 1) | 1036 | do { |
1098 | break; | 1037 | if (freq == pll->freq) { |
1099 | 1038 | return w100_pll_set_clk(pll); | |
1100 | if (w100_pwr_state.sclk_cntl.f.sclk_post_div_fast == 0) | 1039 | } |
1101 | break; | 1040 | pll++; |
1102 | 1041 | } while(pll->freq); | |
1103 | w100_pwr_state.sclk_cntl.f.sclk_post_div_fast -= 1; | ||
1104 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); | ||
1105 | } | ||
1106 | return 0; | 1042 | return 0; |
1107 | } | 1043 | } |
1108 | 1044 | ||
1109 | |||
1110 | /* Set up an initial state. Some values/fields set | 1045 | /* Set up an initial state. Some values/fields set |
1111 | here will be overwritten. */ | 1046 | here will be overwritten. */ |
1112 | static void w100_pwm_setup(void) | 1047 | static void w100_pwm_setup(struct w100fb_par *par) |
1113 | { | 1048 | { |
1114 | w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1; | 1049 | w100_pwr_state.clk_pin_cntl.f.osc_en = 0x1; |
1115 | w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f; | 1050 | w100_pwr_state.clk_pin_cntl.f.osc_gain = 0x1f; |
1116 | w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0; | 1051 | w100_pwr_state.clk_pin_cntl.f.dont_use_xtalin = 0x0; |
1117 | w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0; | 1052 | w100_pwr_state.clk_pin_cntl.f.xtalin_pm_en = 0x0; |
1118 | w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = 0x0; /* no freq doubling */ | 1053 | w100_pwr_state.clk_pin_cntl.f.xtalin_dbl_en = par->mach->xtal_dbl ? 1 : 0; |
1119 | w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0; | 1054 | w100_pwr_state.clk_pin_cntl.f.cg_debug = 0x0; |
1120 | writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL); | 1055 | writel((u32) (w100_pwr_state.clk_pin_cntl.val), remapped_regs + mmCLK_PIN_CNTL); |
1121 | 1056 | ||
1122 | w100_pwr_state.sclk_cntl.f.sclk_src_sel = 0x0; /* Crystal Clk */ | 1057 | w100_pwr_state.sclk_cntl.f.sclk_src_sel = CLK_SRC_XTAL; |
1123 | w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0; /* Pfast = 1 */ | 1058 | w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = 0x0; /* Pfast = 1 */ |
1124 | w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3; | 1059 | w100_pwr_state.sclk_cntl.f.sclk_clkon_hys = 0x3; |
1125 | w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */ | 1060 | w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = 0x0; /* Pslow = 1 */ |
1126 | w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0; | 1061 | w100_pwr_state.sclk_cntl.f.disp_cg_ok2switch_en = 0x0; |
1127 | w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0; /* Dynamic */ | 1062 | w100_pwr_state.sclk_cntl.f.sclk_force_reg = 0x0; /* Dynamic */ |
1128 | w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0; /* Dynamic */ | 1063 | w100_pwr_state.sclk_cntl.f.sclk_force_disp = 0x0; /* Dynamic */ |
1129 | w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0; /* Dynamic */ | 1064 | w100_pwr_state.sclk_cntl.f.sclk_force_mc = 0x0; /* Dynamic */ |
1130 | w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0; /* Dynamic */ | 1065 | w100_pwr_state.sclk_cntl.f.sclk_force_extmc = 0x0; /* Dynamic */ |
1131 | w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0; /* Dynamic */ | 1066 | w100_pwr_state.sclk_cntl.f.sclk_force_cp = 0x0; /* Dynamic */ |
1132 | w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0; /* Dynamic */ | 1067 | w100_pwr_state.sclk_cntl.f.sclk_force_e2 = 0x0; /* Dynamic */ |
1133 | w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0; /* Dynamic */ | 1068 | w100_pwr_state.sclk_cntl.f.sclk_force_e3 = 0x0; /* Dynamic */ |
1134 | w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0; /* Dynamic */ | 1069 | w100_pwr_state.sclk_cntl.f.sclk_force_idct = 0x0; /* Dynamic */ |
1135 | w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0; /* Dynamic */ | 1070 | w100_pwr_state.sclk_cntl.f.sclk_force_bist = 0x0; /* Dynamic */ |
1136 | w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0; | 1071 | w100_pwr_state.sclk_cntl.f.busy_extend_cp = 0x0; |
1137 | w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0; | 1072 | w100_pwr_state.sclk_cntl.f.busy_extend_e2 = 0x0; |
1138 | w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0; | 1073 | w100_pwr_state.sclk_cntl.f.busy_extend_e3 = 0x0; |
1139 | w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0; | 1074 | w100_pwr_state.sclk_cntl.f.busy_extend_idct = 0x0; |
1140 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); | 1075 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); |
1141 | 1076 | ||
1142 | w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x0; /* Crystal Clk */ | 1077 | w100_pwr_state.pclk_cntl.f.pclk_src_sel = CLK_SRC_XTAL; |
1143 | w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1; /* P = 2 */ | 1078 | w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x1; /* P = 2 */ |
1144 | w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0; /* Dynamic */ | 1079 | w100_pwr_state.pclk_cntl.f.pclk_force_disp = 0x0; /* Dynamic */ |
1145 | writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL); | 1080 | writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL); |
1146 | 1081 | ||
1147 | w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0; /* M = 1 */ | 1082 | w100_pwr_state.pll_ref_fb_div.f.pll_ref_div = 0x0; /* M = 1 */ |
1148 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0; /* N = 1.0 */ | 1083 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_int = 0x0; /* N = 1.0 */ |
1149 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0; | 1084 | w100_pwr_state.pll_ref_fb_div.f.pll_fb_div_frac = 0x0; |
1150 | w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5; | 1085 | w100_pwr_state.pll_ref_fb_div.f.pll_reset_time = 0x5; |
1151 | w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff; | 1086 | w100_pwr_state.pll_ref_fb_div.f.pll_lock_time = 0xff; |
@@ -1154,7 +1089,7 @@ static void w100_pwm_setup(void) | |||
1154 | w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1; | 1089 | w100_pwr_state.pll_cntl.f.pll_pwdn = 0x1; |
1155 | w100_pwr_state.pll_cntl.f.pll_reset = 0x1; | 1090 | w100_pwr_state.pll_cntl.f.pll_reset = 0x1; |
1156 | w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0; | 1091 | w100_pwr_state.pll_cntl.f.pll_pm_en = 0x0; |
1157 | w100_pwr_state.pll_cntl.f.pll_mode = 0x0; /* uses VCO clock */ | 1092 | w100_pwr_state.pll_cntl.f.pll_mode = 0x0; /* uses VCO clock */ |
1158 | w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0; | 1093 | w100_pwr_state.pll_cntl.f.pll_refclk_sel = 0x0; |
1159 | w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0; | 1094 | w100_pwr_state.pll_cntl.f.pll_fbclk_sel = 0x0; |
1160 | w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; | 1095 | w100_pwr_state.pll_cntl.f.pll_tcpoff = 0x0; |
@@ -1164,220 +1099,275 @@ static void w100_pwm_setup(void) | |||
1164 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; | 1099 | w100_pwr_state.pll_cntl.f.pll_ioffset = 0x0; |
1165 | w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0; | 1100 | w100_pwr_state.pll_cntl.f.pll_pecc_mode = 0x0; |
1166 | w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0; | 1101 | w100_pwr_state.pll_cntl.f.pll_pecc_scon = 0x0; |
1167 | w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; /* Hi-Z */ | 1102 | w100_pwr_state.pll_cntl.f.pll_dactal = 0x0; /* Hi-Z */ |
1168 | w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3; | 1103 | w100_pwr_state.pll_cntl.f.pll_cp_clip = 0x3; |
1169 | w100_pwr_state.pll_cntl.f.pll_conf = 0x2; | 1104 | w100_pwr_state.pll_cntl.f.pll_conf = 0x2; |
1170 | w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2; | 1105 | w100_pwr_state.pll_cntl.f.pll_mbctrl = 0x2; |
1171 | w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0; | 1106 | w100_pwr_state.pll_cntl.f.pll_ring_off = 0x0; |
1172 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); | 1107 | writel((u32) (w100_pwr_state.pll_cntl.val), remapped_regs + mmPLL_CNTL); |
1173 | 1108 | ||
1174 | w100_pwr_state.clk_test_cntl.f.testclk_sel = 0x1; /* PLLCLK (for testing) */ | ||
1175 | w100_pwr_state.clk_test_cntl.f.start_check_freq = 0x0; | ||
1176 | w100_pwr_state.clk_test_cntl.f.tstcount_rst = 0x0; | ||
1177 | writel((u32) (w100_pwr_state.clk_test_cntl.val), remapped_regs + mmCLK_TEST_CNTL); | ||
1178 | |||
1179 | w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0; | 1109 | w100_pwr_state.pwrmgt_cntl.f.pwm_enable = 0x0; |
1180 | w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1; /* normal mode (0, 1, 3) */ | 1110 | w100_pwr_state.pwrmgt_cntl.f.pwm_mode_req = 0x1; /* normal mode (0, 1, 3) */ |
1181 | w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0; | 1111 | w100_pwr_state.pwrmgt_cntl.f.pwm_wakeup_cond = 0x0; |
1182 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; | 1112 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_hw_en = 0x0; |
1183 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; | 1113 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_hw_en = 0x0; |
1184 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1; /* PM4,ENG */ | 1114 | w100_pwr_state.pwrmgt_cntl.f.pwm_fast_noml_cond = 0x1; /* PM4,ENG */ |
1185 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1; /* PM4,ENG */ | 1115 | w100_pwr_state.pwrmgt_cntl.f.pwm_noml_fast_cond = 0x1; /* PM4,ENG */ |
1186 | w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF; | 1116 | w100_pwr_state.pwrmgt_cntl.f.pwm_idle_timer = 0xFF; |
1187 | w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF; | 1117 | w100_pwr_state.pwrmgt_cntl.f.pwm_busy_timer = 0xFF; |
1188 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); | 1118 | writel((u32) (w100_pwr_state.pwrmgt_cntl.val), remapped_regs + mmPWRMGT_CNTL); |
1189 | 1119 | ||
1190 | w100_pwr_state.auto_mode = 0; /* manual mode */ | 1120 | w100_pwr_state.auto_mode = 0; /* manual mode */ |
1191 | w100_pwr_state.pwm_mode = 1; /* normal mode (0, 1, 2) */ | ||
1192 | w100_pwr_state.freq = 50000000; /* 50 MHz */ | ||
1193 | w100_pwr_state.M = 3; /* M = 4 */ | ||
1194 | w100_pwr_state.N_int = 6; /* N = 7.0 */ | ||
1195 | w100_pwr_state.N_fac = 0; | ||
1196 | w100_pwr_state.tfgoal = 0xE0; | ||
1197 | w100_pwr_state.lock_time = 56; | ||
1198 | w100_pwr_state.tf20 = 0xff; /* set highest */ | ||
1199 | w100_pwr_state.tf80 = 0x00; /* set lowest */ | ||
1200 | w100_pwr_state.tf100 = 0x00; /* set lowest */ | ||
1201 | w100_pwr_state.fast_sclk = 50; /* 50.0 MHz */ | ||
1202 | w100_pwr_state.norm_sclk = 12; /* 12.5 MHz */ | ||
1203 | } | 1121 | } |
1204 | 1122 | ||
1205 | 1123 | ||
1206 | static void w100_init_sharp_lcd(u32 mode) | 1124 | /* |
1125 | * Setup the w100 clocks for the specified mode | ||
1126 | */ | ||
1127 | static void w100_init_clocks(struct w100fb_par *par) | ||
1207 | { | 1128 | { |
1208 | u32 temp32; | 1129 | struct w100_mode *mode = par->mode; |
1209 | union disp_db_buf_cntl_wr_u disp_db_buf_wr_cntl; | ||
1210 | 1130 | ||
1211 | /* Prevent display updates */ | 1131 | if (mode->pixclk_src == CLK_SRC_PLL || mode->sysclk_src == CLK_SRC_PLL) |
1212 | disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e; | 1132 | w100_set_pll_freq(par, (par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq); |
1213 | disp_db_buf_wr_cntl.f.update_db_buf = 0; | ||
1214 | disp_db_buf_wr_cntl.f.en_db_buf = 0; | ||
1215 | writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL); | ||
1216 | 1133 | ||
1217 | switch(mode) { | 1134 | w100_pwr_state.sclk_cntl.f.sclk_src_sel = mode->sysclk_src; |
1218 | case LCD_SHARP_QVGA: | 1135 | w100_pwr_state.sclk_cntl.f.sclk_post_div_fast = mode->sysclk_divider; |
1219 | w100_set_slowsysclk(12); /* use crystal -- 12.5MHz */ | 1136 | w100_pwr_state.sclk_cntl.f.sclk_post_div_slow = mode->sysclk_divider; |
1220 | /* not use PLL */ | 1137 | writel((u32) (w100_pwr_state.sclk_cntl.val), remapped_regs + mmSCLK_CNTL); |
1221 | 1138 | } | |
1222 | writel(0x7FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION); | 1139 | |
1223 | writel(0x85FF8000, remapped_regs + mmMC_FB_LOCATION); | 1140 | static void w100_init_lcd(struct w100fb_par *par) |
1224 | writel(0x00000003, remapped_regs + mmLCD_FORMAT); | 1141 | { |
1225 | writel(0x00CF1C06, remapped_regs + mmGRAPHIC_CTRL); | 1142 | u32 temp32; |
1226 | writel(0x01410145, remapped_regs + mmCRTC_TOTAL); | 1143 | struct w100_mode *mode = par->mode; |
1227 | writel(0x01170027, remapped_regs + mmACTIVE_H_DISP); | 1144 | struct w100_gen_regs *regs = par->mach->regs; |
1228 | writel(0x01410001, remapped_regs + mmACTIVE_V_DISP); | 1145 | union active_h_disp_u active_h_disp; |
1229 | writel(0x01170027, remapped_regs + mmGRAPHIC_H_DISP); | 1146 | union active_v_disp_u active_v_disp; |
1230 | writel(0x01410001, remapped_regs + mmGRAPHIC_V_DISP); | 1147 | union graphic_h_disp_u graphic_h_disp; |
1231 | writel(0x81170027, remapped_regs + mmCRTC_SS); | 1148 | union graphic_v_disp_u graphic_v_disp; |
1232 | writel(0xA0140000, remapped_regs + mmCRTC_LS); | 1149 | union crtc_total_u crtc_total; |
1233 | writel(0x00400008, remapped_regs + mmCRTC_REV); | 1150 | |
1234 | writel(0xA0000000, remapped_regs + mmCRTC_DCLK); | 1151 | /* w3200 doesnt like undefined bits being set so zero register values first */ |
1235 | writel(0xC0140014, remapped_regs + mmCRTC_GS); | 1152 | |
1236 | writel(0x00010141, remapped_regs + mmCRTC_VPOS_GS); | 1153 | active_h_disp.val = 0; |
1237 | writel(0x8015010F, remapped_regs + mmCRTC_GCLK); | 1154 | active_h_disp.f.active_h_start=mode->left_margin; |
1238 | writel(0x80100110, remapped_regs + mmCRTC_GOE); | 1155 | active_h_disp.f.active_h_end=mode->left_margin + mode->xres; |
1239 | writel(0x00000000, remapped_regs + mmCRTC_FRAME); | 1156 | writel(active_h_disp.val, remapped_regs + mmACTIVE_H_DISP); |
1240 | writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS); | 1157 | |
1241 | writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1); | 1158 | active_v_disp.val = 0; |
1242 | writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2); | 1159 | active_v_disp.f.active_v_start=mode->upper_margin; |
1243 | writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1); | 1160 | active_v_disp.f.active_v_end=mode->upper_margin + mode->yres; |
1244 | writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2); | 1161 | writel(active_v_disp.val, remapped_regs + mmACTIVE_V_DISP); |
1245 | writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT); | 1162 | |
1246 | writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR); | 1163 | graphic_h_disp.val = 0; |
1247 | writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3); | 1164 | graphic_h_disp.f.graphic_h_start=mode->left_margin; |
1248 | writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET); | 1165 | graphic_h_disp.f.graphic_h_end=mode->left_margin + mode->xres; |
1249 | writel(0x000001e0, remapped_regs + mmGRAPHIC_PITCH); | 1166 | writel(graphic_h_disp.val, remapped_regs + mmGRAPHIC_H_DISP); |
1250 | writel(0x000000bf, remapped_regs + mmGPIO_DATA); | 1167 | |
1251 | writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2); | 1168 | graphic_v_disp.val = 0; |
1252 | writel(0x00000000, remapped_regs + mmGPIO_CNTL1); | 1169 | graphic_v_disp.f.graphic_v_start=mode->upper_margin; |
1253 | writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE); | 1170 | graphic_v_disp.f.graphic_v_end=mode->upper_margin + mode->yres; |
1254 | break; | 1171 | writel(graphic_v_disp.val, remapped_regs + mmGRAPHIC_V_DISP); |
1255 | case LCD_SHARP_VGA: | 1172 | |
1256 | w100_set_slowsysclk(12); /* use crystal -- 12.5MHz */ | 1173 | crtc_total.val = 0; |
1257 | w100_set_fastsysclk(current_par->fastsysclk_mode); /* use PLL -- 75.0MHz */ | 1174 | crtc_total.f.crtc_h_total=mode->left_margin + mode->xres + mode->right_margin; |
1258 | w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1; | 1175 | crtc_total.f.crtc_v_total=mode->upper_margin + mode->yres + mode->lower_margin; |
1259 | w100_pwr_state.pclk_cntl.f.pclk_post_div = 0x2; | 1176 | writel(crtc_total.val, remapped_regs + mmCRTC_TOTAL); |
1260 | writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL); | 1177 | |
1261 | writel(0x15FF1000, remapped_regs + mmMC_FB_LOCATION); | 1178 | writel(mode->crtc_ss, remapped_regs + mmCRTC_SS); |
1262 | writel(0x9FFF8000, remapped_regs + mmMC_EXT_MEM_LOCATION); | 1179 | writel(mode->crtc_ls, remapped_regs + mmCRTC_LS); |
1263 | writel(0x00000003, remapped_regs + mmLCD_FORMAT); | 1180 | writel(mode->crtc_gs, remapped_regs + mmCRTC_GS); |
1264 | writel(0x00DE1D66, remapped_regs + mmGRAPHIC_CTRL); | 1181 | writel(mode->crtc_vpos_gs, remapped_regs + mmCRTC_VPOS_GS); |
1265 | 1182 | writel(mode->crtc_rev, remapped_regs + mmCRTC_REV); | |
1266 | writel(0x0283028B, remapped_regs + mmCRTC_TOTAL); | 1183 | writel(mode->crtc_dclk, remapped_regs + mmCRTC_DCLK); |
1267 | writel(0x02360056, remapped_regs + mmACTIVE_H_DISP); | 1184 | writel(mode->crtc_gclk, remapped_regs + mmCRTC_GCLK); |
1268 | writel(0x02830003, remapped_regs + mmACTIVE_V_DISP); | 1185 | writel(mode->crtc_goe, remapped_regs + mmCRTC_GOE); |
1269 | writel(0x02360056, remapped_regs + mmGRAPHIC_H_DISP); | 1186 | writel(mode->crtc_ps1_active, remapped_regs + mmCRTC_PS1_ACTIVE); |
1270 | writel(0x02830003, remapped_regs + mmGRAPHIC_V_DISP); | 1187 | |
1271 | writel(0x82360056, remapped_regs + mmCRTC_SS); | 1188 | writel(regs->lcd_format, remapped_regs + mmLCD_FORMAT); |
1272 | writel(0xA0280000, remapped_regs + mmCRTC_LS); | 1189 | writel(regs->lcdd_cntl1, remapped_regs + mmLCDD_CNTL1); |
1273 | writel(0x00400008, remapped_regs + mmCRTC_REV); | 1190 | writel(regs->lcdd_cntl2, remapped_regs + mmLCDD_CNTL2); |
1274 | writel(0xA0000000, remapped_regs + mmCRTC_DCLK); | 1191 | writel(regs->genlcd_cntl1, remapped_regs + mmGENLCD_CNTL1); |
1275 | writel(0x80280028, remapped_regs + mmCRTC_GS); | 1192 | writel(regs->genlcd_cntl2, remapped_regs + mmGENLCD_CNTL2); |
1276 | writel(0x02830002, remapped_regs + mmCRTC_VPOS_GS); | 1193 | writel(regs->genlcd_cntl3, remapped_regs + mmGENLCD_CNTL3); |
1277 | writel(0x8015010F, remapped_regs + mmCRTC_GCLK); | 1194 | |
1278 | writel(0x80100110, remapped_regs + mmCRTC_GOE); | 1195 | writel(0x00000000, remapped_regs + mmCRTC_FRAME); |
1279 | writel(0x00000000, remapped_regs + mmCRTC_FRAME); | 1196 | writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS); |
1280 | writel(0x00000000, remapped_regs + mmCRTC_FRAME_VPOS); | 1197 | writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT); |
1281 | writel(0x01CC0000, remapped_regs + mmLCDD_CNTL1); | 1198 | writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR); |
1282 | writel(0x0003FFFF, remapped_regs + mmLCDD_CNTL2); | ||
1283 | writel(0x00FFFF0D, remapped_regs + mmGENLCD_CNTL1); | ||
1284 | writel(0x003F3003, remapped_regs + mmGENLCD_CNTL2); | ||
1285 | writel(0x00000000, remapped_regs + mmCRTC_DEFAULT_COUNT); | ||
1286 | writel(0x0000FF00, remapped_regs + mmLCD_BACKGROUND_COLOR); | ||
1287 | writel(0x000102aa, remapped_regs + mmGENLCD_CNTL3); | ||
1288 | writel(0x00800000, remapped_regs + mmGRAPHIC_OFFSET); | ||
1289 | writel(0x000003C0, remapped_regs + mmGRAPHIC_PITCH); | ||
1290 | writel(0x000000bf, remapped_regs + mmGPIO_DATA); | ||
1291 | writel(0x03c0feff, remapped_regs + mmGPIO_CNTL2); | ||
1292 | writel(0x00000000, remapped_regs + mmGPIO_CNTL1); | ||
1293 | writel(0x41060010, remapped_regs + mmCRTC_PS1_ACTIVE); | ||
1294 | break; | ||
1295 | default: | ||
1296 | break; | ||
1297 | } | ||
1298 | 1199 | ||
1299 | /* Hack for overlay in ext memory */ | 1200 | /* Hack for overlay in ext memory */ |
1300 | temp32 = readl(remapped_regs + mmDISP_DEBUG2); | 1201 | temp32 = readl(remapped_regs + mmDISP_DEBUG2); |
1301 | temp32 |= 0xc0000000; | 1202 | temp32 |= 0xc0000000; |
1302 | writel(temp32, remapped_regs + mmDISP_DEBUG2); | 1203 | writel(temp32, remapped_regs + mmDISP_DEBUG2); |
1303 | |||
1304 | /* Re-enable display updates */ | ||
1305 | disp_db_buf_wr_cntl.f.db_buf_cntl = 0x1e; | ||
1306 | disp_db_buf_wr_cntl.f.update_db_buf = 1; | ||
1307 | disp_db_buf_wr_cntl.f.en_db_buf = 1; | ||
1308 | writel((u32) (disp_db_buf_wr_cntl.val), remapped_regs + mmDISP_DB_BUF_CNTL); | ||
1309 | } | 1204 | } |
1310 | 1205 | ||
1311 | 1206 | ||
1312 | static void w100_set_vga_rotation_regs(u16 divider, unsigned long ctrl, unsigned long offset, unsigned long pitch) | 1207 | static void w100_setup_memory(struct w100fb_par *par) |
1313 | { | 1208 | { |
1314 | w100_pwr_state.pclk_cntl.f.pclk_src_sel = 0x1; | 1209 | union mc_ext_mem_location_u extmem_location; |
1315 | w100_pwr_state.pclk_cntl.f.pclk_post_div = divider; | 1210 | union mc_fb_location_u intmem_location; |
1316 | writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL); | 1211 | struct w100_mem_info *mem = par->mach->mem; |
1212 | struct w100_bm_mem_info *bm_mem = par->mach->bm_mem; | ||
1317 | 1213 | ||
1318 | writel(ctrl, remapped_regs + mmGRAPHIC_CTRL); | 1214 | if (!par->extmem_active) { |
1319 | writel(offset, remapped_regs + mmGRAPHIC_OFFSET); | 1215 | w100_suspend(W100_SUSPEND_EXTMEM); |
1320 | writel(pitch, remapped_regs + mmGRAPHIC_PITCH); | ||
1321 | 1216 | ||
1322 | /* Re-enable display updates */ | 1217 | /* Map Internal Memory at FB Base */ |
1323 | writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL); | 1218 | intmem_location.f.mc_fb_start = W100_FB_BASE >> 8; |
1324 | } | 1219 | intmem_location.f.mc_fb_top = (W100_FB_BASE+MEM_INT_SIZE) >> 8; |
1220 | writel((u32) (intmem_location.val), remapped_regs + mmMC_FB_LOCATION); | ||
1325 | 1221 | ||
1222 | /* Unmap External Memory - value is *probably* irrelevant but may have meaning | ||
1223 | to acceleration libraries */ | ||
1224 | extmem_location.f.mc_ext_mem_start = MEM_EXT_BASE_VALUE >> 8; | ||
1225 | extmem_location.f.mc_ext_mem_top = (MEM_EXT_BASE_VALUE-1) >> 8; | ||
1226 | writel((u32) (extmem_location.val), remapped_regs + mmMC_EXT_MEM_LOCATION); | ||
1227 | } else { | ||
1228 | /* Map Internal Memory to its default location */ | ||
1229 | intmem_location.f.mc_fb_start = MEM_INT_BASE_VALUE >> 8; | ||
1230 | intmem_location.f.mc_fb_top = (MEM_INT_BASE_VALUE+MEM_INT_SIZE) >> 8; | ||
1231 | writel((u32) (intmem_location.val), remapped_regs + mmMC_FB_LOCATION); | ||
1326 | 1232 | ||
1327 | static void w100_init_vga_rotation(u16 deg) | 1233 | /* Map External Memory at FB Base */ |
1328 | { | 1234 | extmem_location.f.mc_ext_mem_start = W100_FB_BASE >> 8; |
1329 | switch(deg) { | 1235 | extmem_location.f.mc_ext_mem_top = (W100_FB_BASE+par->mach->mem->size) >> 8; |
1330 | case 0: | 1236 | writel((u32) (extmem_location.val), remapped_regs + mmMC_EXT_MEM_LOCATION); |
1331 | w100_set_vga_rotation_regs(0x02, 0x00DE1D66, 0x00800000, 0x000003c0); | 1237 | |
1332 | break; | 1238 | writel(0x00007800, remapped_regs + mmMC_BIST_CTRL); |
1333 | case 90: | 1239 | writel(mem->ext_cntl, remapped_regs + mmMEM_EXT_CNTL); |
1334 | w100_set_vga_rotation_regs(0x06, 0x00DE1D0e, 0x00895b00, 0x00000500); | 1240 | writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG); |
1335 | break; | 1241 | udelay(100); |
1336 | case 180: | 1242 | writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG); |
1337 | w100_set_vga_rotation_regs(0x02, 0x00DE1D7e, 0x00895ffc, 0x000003c0); | 1243 | udelay(100); |
1338 | break; | 1244 | writel(mem->sdram_mode_reg, remapped_regs + mmMEM_SDRAM_MODE_REG); |
1339 | case 270: | 1245 | udelay(100); |
1340 | w100_set_vga_rotation_regs(0x06, 0x00DE1D16, 0x008004fc, 0x00000500); | 1246 | writel(mem->ext_timing_cntl, remapped_regs + mmMEM_EXT_TIMING_CNTL); |
1341 | break; | 1247 | writel(mem->io_cntl, remapped_regs + mmMEM_IO_CNTL); |
1342 | default: | 1248 | if (bm_mem) { |
1343 | /* not-support */ | 1249 | writel(bm_mem->ext_mem_bw, remapped_regs + mmBM_EXT_MEM_BANDWIDTH); |
1344 | break; | 1250 | writel(bm_mem->offset, remapped_regs + mmBM_OFFSET); |
1251 | writel(bm_mem->ext_timing_ctl, remapped_regs + mmBM_MEM_EXT_TIMING_CNTL); | ||
1252 | writel(bm_mem->ext_cntl, remapped_regs + mmBM_MEM_EXT_CNTL); | ||
1253 | writel(bm_mem->mode_reg, remapped_regs + mmBM_MEM_MODE_REG); | ||
1254 | writel(bm_mem->io_cntl, remapped_regs + mmBM_MEM_IO_CNTL); | ||
1255 | writel(bm_mem->config, remapped_regs + mmBM_CONFIG); | ||
1256 | } | ||
1345 | } | 1257 | } |
1346 | } | 1258 | } |
1347 | 1259 | ||
1348 | 1260 | static void w100_set_dispregs(struct w100fb_par *par) | |
1349 | static void w100_set_qvga_rotation_regs(unsigned long ctrl, unsigned long offset, unsigned long pitch) | ||
1350 | { | 1261 | { |
1351 | writel(ctrl, remapped_regs + mmGRAPHIC_CTRL); | 1262 | unsigned long rot=0, divider, offset=0; |
1352 | writel(offset, remapped_regs + mmGRAPHIC_OFFSET); | 1263 | union graphic_ctrl_u graphic_ctrl; |
1353 | writel(pitch, remapped_regs + mmGRAPHIC_PITCH); | 1264 | |
1265 | /* See if the mode has been rotated */ | ||
1266 | if (par->xres == par->mode->xres) { | ||
1267 | if (par->flip) { | ||
1268 | rot=3; /* 180 degree */ | ||
1269 | offset=(par->xres * par->yres) - 1; | ||
1270 | } /* else 0 degree */ | ||
1271 | divider = par->mode->pixclk_divider; | ||
1272 | } else { | ||
1273 | if (par->flip) { | ||
1274 | rot=2; /* 270 degree */ | ||
1275 | offset=par->xres - 1; | ||
1276 | } else { | ||
1277 | rot=1; /* 90 degree */ | ||
1278 | offset=par->xres * (par->yres - 1); | ||
1279 | } | ||
1280 | divider = par->mode->pixclk_divider_rotated; | ||
1281 | } | ||
1354 | 1282 | ||
1355 | /* Re-enable display updates */ | 1283 | graphic_ctrl.val = 0; /* w32xx doesn't like undefined bits */ |
1356 | writel(0x0000007b, remapped_regs + mmDISP_DB_BUF_CNTL); | 1284 | switch (par->chip_id) { |
1285 | case CHIP_ID_W100: | ||
1286 | graphic_ctrl.f_w100.color_depth=6; | ||
1287 | graphic_ctrl.f_w100.en_crtc=1; | ||
1288 | graphic_ctrl.f_w100.en_graphic_req=1; | ||
1289 | graphic_ctrl.f_w100.en_graphic_crtc=1; | ||
1290 | graphic_ctrl.f_w100.lcd_pclk_on=1; | ||
1291 | graphic_ctrl.f_w100.lcd_sclk_on=1; | ||
1292 | graphic_ctrl.f_w100.low_power_on=0; | ||
1293 | graphic_ctrl.f_w100.req_freq=0; | ||
1294 | graphic_ctrl.f_w100.portrait_mode=rot; | ||
1295 | |||
1296 | /* Zaurus needs this */ | ||
1297 | switch(par->xres) { | ||
1298 | case 240: | ||
1299 | case 320: | ||
1300 | default: | ||
1301 | graphic_ctrl.f_w100.total_req_graphic=0xa0; | ||
1302 | break; | ||
1303 | case 480: | ||
1304 | case 640: | ||
1305 | switch(rot) { | ||
1306 | case 0: /* 0 */ | ||
1307 | case 3: /* 180 */ | ||
1308 | graphic_ctrl.f_w100.low_power_on=1; | ||
1309 | graphic_ctrl.f_w100.req_freq=5; | ||
1310 | break; | ||
1311 | case 1: /* 90 */ | ||
1312 | case 2: /* 270 */ | ||
1313 | graphic_ctrl.f_w100.req_freq=4; | ||
1314 | break; | ||
1315 | default: | ||
1316 | break; | ||
1317 | } | ||
1318 | graphic_ctrl.f_w100.total_req_graphic=0xf0; | ||
1319 | break; | ||
1320 | } | ||
1321 | break; | ||
1322 | case CHIP_ID_W3200: | ||
1323 | case CHIP_ID_W3220: | ||
1324 | graphic_ctrl.f_w32xx.color_depth=6; | ||
1325 | graphic_ctrl.f_w32xx.en_crtc=1; | ||
1326 | graphic_ctrl.f_w32xx.en_graphic_req=1; | ||
1327 | graphic_ctrl.f_w32xx.en_graphic_crtc=1; | ||
1328 | graphic_ctrl.f_w32xx.lcd_pclk_on=1; | ||
1329 | graphic_ctrl.f_w32xx.lcd_sclk_on=1; | ||
1330 | graphic_ctrl.f_w32xx.low_power_on=0; | ||
1331 | graphic_ctrl.f_w32xx.req_freq=0; | ||
1332 | graphic_ctrl.f_w32xx.total_req_graphic=par->mode->xres >> 1; /* panel xres, not mode */ | ||
1333 | graphic_ctrl.f_w32xx.portrait_mode=rot; | ||
1334 | break; | ||
1335 | } | ||
1336 | |||
1337 | /* Set the pixel clock source and divider */ | ||
1338 | w100_pwr_state.pclk_cntl.f.pclk_src_sel = par->mode->pixclk_src; | ||
1339 | w100_pwr_state.pclk_cntl.f.pclk_post_div = divider; | ||
1340 | writel((u32) (w100_pwr_state.pclk_cntl.val), remapped_regs + mmPCLK_CNTL); | ||
1341 | |||
1342 | writel(graphic_ctrl.val, remapped_regs + mmGRAPHIC_CTRL); | ||
1343 | writel(W100_FB_BASE + ((offset * BITS_PER_PIXEL/8)&~0x03UL), remapped_regs + mmGRAPHIC_OFFSET); | ||
1344 | writel((par->xres*BITS_PER_PIXEL/8), remapped_regs + mmGRAPHIC_PITCH); | ||
1357 | } | 1345 | } |
1358 | 1346 | ||
1359 | 1347 | ||
1360 | static void w100_init_qvga_rotation(u16 deg) | 1348 | /* |
1349 | * Work out how long the sync pulse lasts | ||
1350 | * Value is 1/(time in seconds) | ||
1351 | */ | ||
1352 | static void calc_hsync(struct w100fb_par *par) | ||
1361 | { | 1353 | { |
1362 | switch(deg) { | 1354 | unsigned long hsync; |
1363 | case 0: | 1355 | struct w100_mode *mode = par->mode; |
1364 | w100_set_qvga_rotation_regs(0x00d41c06, 0x00800000, 0x000001e0); | 1356 | union crtc_ss_u crtc_ss; |
1365 | break; | 1357 | |
1366 | case 90: | 1358 | if (mode->pixclk_src == CLK_SRC_XTAL) |
1367 | w100_set_qvga_rotation_regs(0x00d41c0E, 0x00825580, 0x00000280); | 1359 | hsync=par->mach->xtal_freq; |
1368 | break; | 1360 | else |
1369 | case 180: | 1361 | hsync=((par->fastpll_mode && mode->fast_pll_freq) ? mode->fast_pll_freq : mode->pll_freq)*100000; |
1370 | w100_set_qvga_rotation_regs(0x00d41c1e, 0x008257fc, 0x000001e0); | ||
1371 | break; | ||
1372 | case 270: | ||
1373 | w100_set_qvga_rotation_regs(0x00d41c16, 0x0080027c, 0x00000280); | ||
1374 | break; | ||
1375 | default: | ||
1376 | /* not-support */ | ||
1377 | break; | ||
1378 | } | ||
1379 | } | ||
1380 | 1362 | ||
1363 | hsync /= (w100_pwr_state.pclk_cntl.f.pclk_post_div + 1); | ||
1364 | |||
1365 | crtc_ss.val = readl(remapped_regs + mmCRTC_SS); | ||
1366 | if (crtc_ss.val) | ||
1367 | par->hsync_len = hsync / (crtc_ss.f.ss_end-crtc_ss.f.ss_start); | ||
1368 | else | ||
1369 | par->hsync_len = 0; | ||
1370 | } | ||
1381 | 1371 | ||
1382 | static void w100_suspend(u32 mode) | 1372 | static void w100_suspend(u32 mode) |
1383 | { | 1373 | { |
@@ -1387,30 +1377,28 @@ static void w100_suspend(u32 mode) | |||
1387 | writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL); | 1377 | writel(0x00FF0000, remapped_regs + mmMC_PERF_MON_CNTL); |
1388 | 1378 | ||
1389 | val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL); | 1379 | val = readl(remapped_regs + mmMEM_EXT_TIMING_CNTL); |
1390 | val &= ~(0x00100000); /* bit20=0 */ | 1380 | val &= ~(0x00100000); /* bit20=0 */ |
1391 | val |= 0xFF000000; /* bit31:24=0xff */ | 1381 | val |= 0xFF000000; /* bit31:24=0xff */ |
1392 | writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL); | 1382 | writel(val, remapped_regs + mmMEM_EXT_TIMING_CNTL); |
1393 | 1383 | ||
1394 | val = readl(remapped_regs + mmMEM_EXT_CNTL); | 1384 | val = readl(remapped_regs + mmMEM_EXT_CNTL); |
1395 | val &= ~(0x00040000); /* bit18=0 */ | 1385 | val &= ~(0x00040000); /* bit18=0 */ |
1396 | val |= 0x00080000; /* bit19=1 */ | 1386 | val |= 0x00080000; /* bit19=1 */ |
1397 | writel(val, remapped_regs + mmMEM_EXT_CNTL); | 1387 | writel(val, remapped_regs + mmMEM_EXT_CNTL); |
1398 | 1388 | ||
1399 | udelay(1); /* wait 1us */ | 1389 | udelay(1); /* wait 1us */ |
1400 | 1390 | ||
1401 | if (mode == W100_SUSPEND_EXTMEM) { | 1391 | if (mode == W100_SUSPEND_EXTMEM) { |
1402 | |||
1403 | /* CKE: Tri-State */ | 1392 | /* CKE: Tri-State */ |
1404 | val = readl(remapped_regs + mmMEM_EXT_CNTL); | 1393 | val = readl(remapped_regs + mmMEM_EXT_CNTL); |
1405 | val |= 0x40000000; /* bit30=1 */ | 1394 | val |= 0x40000000; /* bit30=1 */ |
1406 | writel(val, remapped_regs + mmMEM_EXT_CNTL); | 1395 | writel(val, remapped_regs + mmMEM_EXT_CNTL); |
1407 | 1396 | ||
1408 | /* CLK: Stop */ | 1397 | /* CLK: Stop */ |
1409 | val = readl(remapped_regs + mmMEM_EXT_CNTL); | 1398 | val = readl(remapped_regs + mmMEM_EXT_CNTL); |
1410 | val &= ~(0x00000001); /* bit0=0 */ | 1399 | val &= ~(0x00000001); /* bit0=0 */ |
1411 | writel(val, remapped_regs + mmMEM_EXT_CNTL); | 1400 | writel(val, remapped_regs + mmMEM_EXT_CNTL); |
1412 | } else { | 1401 | } else { |
1413 | |||
1414 | writel(0x00000000, remapped_regs + mmSCLK_CNTL); | 1402 | writel(0x00000000, remapped_regs + mmSCLK_CNTL); |
1415 | writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL); | 1403 | writel(0x000000BF, remapped_regs + mmCLK_PIN_CNTL); |
1416 | writel(0x00000015, remapped_regs + mmPWRMGT_CNTL); | 1404 | writel(0x00000015, remapped_regs + mmPWRMGT_CNTL); |
@@ -1418,43 +1406,16 @@ static void w100_suspend(u32 mode) | |||
1418 | udelay(5); | 1406 | udelay(5); |
1419 | 1407 | ||
1420 | val = readl(remapped_regs + mmPLL_CNTL); | 1408 | val = readl(remapped_regs + mmPLL_CNTL); |
1421 | val |= 0x00000004; /* bit2=1 */ | 1409 | val |= 0x00000004; /* bit2=1 */ |
1422 | writel(val, remapped_regs + mmPLL_CNTL); | 1410 | writel(val, remapped_regs + mmPLL_CNTL); |
1423 | writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL); | 1411 | writel(0x0000001d, remapped_regs + mmPWRMGT_CNTL); |
1424 | } | 1412 | } |
1425 | } | 1413 | } |
1426 | 1414 | ||
1427 | |||
1428 | static void w100_resume(void) | ||
1429 | { | ||
1430 | u32 temp32; | ||
1431 | |||
1432 | w100_hw_init(); | ||
1433 | w100_pwm_setup(); | ||
1434 | |||
1435 | temp32 = readl(remapped_regs + mmDISP_DEBUG2); | ||
1436 | temp32 &= 0xff7fffff; | ||
1437 | temp32 |= 0x00800000; | ||
1438 | writel(temp32, remapped_regs + mmDISP_DEBUG2); | ||
1439 | |||
1440 | if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) { | ||
1441 | w100_init_sharp_lcd(LCD_SHARP_VGA); | ||
1442 | if (current_par->lcdMode == LCD_MODE_640) { | ||
1443 | w100_init_vga_rotation(current_par->rotation_flag ? 270 : 90); | ||
1444 | } | ||
1445 | } else { | ||
1446 | w100_init_sharp_lcd(LCD_SHARP_QVGA); | ||
1447 | if (current_par->lcdMode == LCD_MODE_320) { | ||
1448 | w100_init_qvga_rotation(current_par->rotation_flag ? 270 : 90); | ||
1449 | } | ||
1450 | } | ||
1451 | } | ||
1452 | |||
1453 | |||
1454 | static void w100_vsync(void) | 1415 | static void w100_vsync(void) |
1455 | { | 1416 | { |
1456 | u32 tmp; | 1417 | u32 tmp; |
1457 | int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */ | 1418 | int timeout = 30000; /* VSync timeout = 30[ms] > 16.8[ms] */ |
1458 | 1419 | ||
1459 | tmp = readl(remapped_regs + mmACTIVE_V_DISP); | 1420 | tmp = readl(remapped_regs + mmACTIVE_V_DISP); |
1460 | 1421 | ||
@@ -1490,363 +1451,6 @@ static void w100_vsync(void) | |||
1490 | writel(0x00000002, remapped_regs + mmGEN_INT_STATUS); | 1451 | writel(0x00000002, remapped_regs + mmGEN_INT_STATUS); |
1491 | } | 1452 | } |
1492 | 1453 | ||
1493 | |||
1494 | static void w100_InitExtMem(u32 mode) | ||
1495 | { | ||
1496 | switch(mode) { | ||
1497 | case LCD_SHARP_QVGA: | ||
1498 | /* QVGA doesn't use external memory | ||
1499 | nothing to do, really. */ | ||
1500 | break; | ||
1501 | case LCD_SHARP_VGA: | ||
1502 | writel(0x00007800, remapped_regs + mmMC_BIST_CTRL); | ||
1503 | writel(0x00040003, remapped_regs + mmMEM_EXT_CNTL); | ||
1504 | writel(0x00200021, remapped_regs + mmMEM_SDRAM_MODE_REG); | ||
1505 | udelay(100); | ||
1506 | writel(0x80200021, remapped_regs + mmMEM_SDRAM_MODE_REG); | ||
1507 | udelay(100); | ||
1508 | writel(0x00650021, remapped_regs + mmMEM_SDRAM_MODE_REG); | ||
1509 | udelay(100); | ||
1510 | writel(0x10002a4a, remapped_regs + mmMEM_EXT_TIMING_CNTL); | ||
1511 | writel(0x7ff87012, remapped_regs + mmMEM_IO_CNTL); | ||
1512 | break; | ||
1513 | default: | ||
1514 | break; | ||
1515 | } | ||
1516 | } | ||
1517 | |||
1518 | |||
1519 | #define RESCTL_ADRS 0x00 | ||
1520 | #define PHACTRL_ADRS 0x01 | ||
1521 | #define DUTYCTRL_ADRS 0x02 | ||
1522 | #define POWERREG0_ADRS 0x03 | ||
1523 | #define POWERREG1_ADRS 0x04 | ||
1524 | #define GPOR3_ADRS 0x05 | ||
1525 | #define PICTRL_ADRS 0x06 | ||
1526 | #define POLCTRL_ADRS 0x07 | ||
1527 | |||
1528 | #define RESCTL_QVGA 0x01 | ||
1529 | #define RESCTL_VGA 0x00 | ||
1530 | |||
1531 | #define POWER1_VW_ON 0x01 /* VW Supply FET ON */ | ||
1532 | #define POWER1_GVSS_ON 0x02 /* GVSS(-8V) Power Supply ON */ | ||
1533 | #define POWER1_VDD_ON 0x04 /* VDD(8V),SVSS(-4V) Power Supply ON */ | ||
1534 | |||
1535 | #define POWER1_VW_OFF 0x00 /* VW Supply FET OFF */ | ||
1536 | #define POWER1_GVSS_OFF 0x00 /* GVSS(-8V) Power Supply OFF */ | ||
1537 | #define POWER1_VDD_OFF 0x00 /* VDD(8V),SVSS(-4V) Power Supply OFF */ | ||
1538 | |||
1539 | #define POWER0_COM_DCLK 0x01 /* COM Voltage DC Bias DAC Serial Data Clock */ | ||
1540 | #define POWER0_COM_DOUT 0x02 /* COM Voltage DC Bias DAC Serial Data Out */ | ||
1541 | #define POWER0_DAC_ON 0x04 /* DAC Power Supply ON */ | ||
1542 | #define POWER0_COM_ON 0x08 /* COM Powewr Supply ON */ | ||
1543 | #define POWER0_VCC5_ON 0x10 /* VCC5 Power Supply ON */ | ||
1544 | |||
1545 | #define POWER0_DAC_OFF 0x00 /* DAC Power Supply OFF */ | ||
1546 | #define POWER0_COM_OFF 0x00 /* COM Powewr Supply OFF */ | ||
1547 | #define POWER0_VCC5_OFF 0x00 /* VCC5 Power Supply OFF */ | ||
1548 | |||
1549 | #define PICTRL_INIT_STATE 0x01 | ||
1550 | #define PICTRL_INIOFF 0x02 | ||
1551 | #define PICTRL_POWER_DOWN 0x04 | ||
1552 | #define PICTRL_COM_SIGNAL_OFF 0x08 | ||
1553 | #define PICTRL_DAC_SIGNAL_OFF 0x10 | ||
1554 | |||
1555 | #define PICTRL_POWER_ACTIVE (0) | ||
1556 | |||
1557 | #define POLCTRL_SYNC_POL_FALL 0x01 | ||
1558 | #define POLCTRL_EN_POL_FALL 0x02 | ||
1559 | #define POLCTRL_DATA_POL_FALL 0x04 | ||
1560 | #define POLCTRL_SYNC_ACT_H 0x08 | ||
1561 | #define POLCTRL_EN_ACT_L 0x10 | ||
1562 | |||
1563 | #define POLCTRL_SYNC_POL_RISE 0x00 | ||
1564 | #define POLCTRL_EN_POL_RISE 0x00 | ||
1565 | #define POLCTRL_DATA_POL_RISE 0x00 | ||
1566 | #define POLCTRL_SYNC_ACT_L 0x00 | ||
1567 | #define POLCTRL_EN_ACT_H 0x00 | ||
1568 | |||
1569 | #define PHACTRL_PHASE_MANUAL 0x01 | ||
1570 | |||
1571 | #define PHAD_QVGA_DEFAULT_VAL (9) | ||
1572 | #define COMADJ_DEFAULT (125) | ||
1573 | |||
1574 | static void lcdtg_ssp_send(u8 adrs, u8 data) | ||
1575 | { | ||
1576 | w100fb_ssp_send(adrs,data); | ||
1577 | } | ||
1578 | |||
1579 | /* | ||
1580 | * This is only a psuedo I2C interface. We can't use the standard kernel | ||
1581 | * routines as the interface is write only. We just assume the data is acked... | ||
1582 | */ | ||
1583 | static void lcdtg_ssp_i2c_send(u8 data) | ||
1584 | { | ||
1585 | lcdtg_ssp_send(POWERREG0_ADRS, data); | ||
1586 | udelay(10); | ||
1587 | } | ||
1588 | |||
1589 | static void lcdtg_i2c_send_bit(u8 data) | ||
1590 | { | ||
1591 | lcdtg_ssp_i2c_send(data); | ||
1592 | lcdtg_ssp_i2c_send(data | POWER0_COM_DCLK); | ||
1593 | lcdtg_ssp_i2c_send(data); | ||
1594 | } | ||
1595 | |||
1596 | static void lcdtg_i2c_send_start(u8 base) | ||
1597 | { | ||
1598 | lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT); | ||
1599 | lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK); | ||
1600 | lcdtg_ssp_i2c_send(base); | ||
1601 | } | ||
1602 | |||
1603 | static void lcdtg_i2c_send_stop(u8 base) | ||
1604 | { | ||
1605 | lcdtg_ssp_i2c_send(base); | ||
1606 | lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK); | ||
1607 | lcdtg_ssp_i2c_send(base | POWER0_COM_DCLK | POWER0_COM_DOUT); | ||
1608 | } | ||
1609 | |||
1610 | static void lcdtg_i2c_send_byte(u8 base, u8 data) | ||
1611 | { | ||
1612 | int i; | ||
1613 | for (i = 0; i < 8; i++) { | ||
1614 | if (data & 0x80) | ||
1615 | lcdtg_i2c_send_bit(base | POWER0_COM_DOUT); | ||
1616 | else | ||
1617 | lcdtg_i2c_send_bit(base); | ||
1618 | data <<= 1; | ||
1619 | } | ||
1620 | } | ||
1621 | |||
1622 | static void lcdtg_i2c_wait_ack(u8 base) | ||
1623 | { | ||
1624 | lcdtg_i2c_send_bit(base); | ||
1625 | } | ||
1626 | |||
1627 | static void lcdtg_set_common_voltage(u8 base_data, u8 data) | ||
1628 | { | ||
1629 | /* Set Common Voltage to M62332FP via I2C */ | ||
1630 | lcdtg_i2c_send_start(base_data); | ||
1631 | lcdtg_i2c_send_byte(base_data, 0x9c); | ||
1632 | lcdtg_i2c_wait_ack(base_data); | ||
1633 | lcdtg_i2c_send_byte(base_data, 0x00); | ||
1634 | lcdtg_i2c_wait_ack(base_data); | ||
1635 | lcdtg_i2c_send_byte(base_data, data); | ||
1636 | lcdtg_i2c_wait_ack(base_data); | ||
1637 | lcdtg_i2c_send_stop(base_data); | ||
1638 | } | ||
1639 | |||
1640 | static struct lcdtg_register_setting { | ||
1641 | u8 adrs; | ||
1642 | u8 data; | ||
1643 | u32 wait; | ||
1644 | } lcdtg_power_on_table[] = { | ||
1645 | |||
1646 | /* Initialize Internal Logic & Port */ | ||
1647 | { PICTRL_ADRS, | ||
1648 | PICTRL_POWER_DOWN | PICTRL_INIOFF | PICTRL_INIT_STATE | | ||
1649 | PICTRL_COM_SIGNAL_OFF | PICTRL_DAC_SIGNAL_OFF, | ||
1650 | 0 }, | ||
1651 | |||
1652 | { POWERREG0_ADRS, | ||
1653 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_OFF | POWER0_COM_OFF | | ||
1654 | POWER0_VCC5_OFF, | ||
1655 | 0 }, | ||
1656 | |||
1657 | { POWERREG1_ADRS, | ||
1658 | POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF, | ||
1659 | 0 }, | ||
1660 | |||
1661 | /* VDD(+8V),SVSS(-4V) ON */ | ||
1662 | { POWERREG1_ADRS, | ||
1663 | POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON /* VDD ON */, | ||
1664 | 3000 }, | ||
1665 | |||
1666 | /* DAC ON */ | ||
1667 | { POWERREG0_ADRS, | ||
1668 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ | | ||
1669 | POWER0_COM_OFF | POWER0_VCC5_OFF, | ||
1670 | 0 }, | ||
1671 | |||
1672 | /* INIB = H, INI = L */ | ||
1673 | { PICTRL_ADRS, | ||
1674 | /* PICTL[0] = H , PICTL[1] = PICTL[2] = PICTL[4] = L */ | ||
1675 | PICTRL_INIT_STATE | PICTRL_COM_SIGNAL_OFF, | ||
1676 | 0 }, | ||
1677 | |||
1678 | /* Set Common Voltage */ | ||
1679 | { 0xfe, 0, 0 }, | ||
1680 | |||
1681 | /* VCC5 ON */ | ||
1682 | { POWERREG0_ADRS, | ||
1683 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ | | ||
1684 | POWER0_COM_OFF | POWER0_VCC5_ON /* VCC5 ON */, | ||
1685 | 0 }, | ||
1686 | |||
1687 | /* GVSS(-8V) ON */ | ||
1688 | { POWERREG1_ADRS, | ||
1689 | POWER1_VW_OFF | POWER1_GVSS_ON /* GVSS ON */ | | ||
1690 | POWER1_VDD_ON /* VDD ON */, | ||
1691 | 2000 }, | ||
1692 | |||
1693 | /* COM SIGNAL ON (PICTL[3] = L) */ | ||
1694 | { PICTRL_ADRS, | ||
1695 | PICTRL_INIT_STATE, | ||
1696 | 0 }, | ||
1697 | |||
1698 | /* COM ON */ | ||
1699 | { POWERREG0_ADRS, | ||
1700 | POWER0_COM_DCLK | POWER0_COM_DOUT | POWER0_DAC_ON /* DAC ON */ | | ||
1701 | POWER0_COM_ON /* COM ON */ | POWER0_VCC5_ON /* VCC5_ON */, | ||
1702 | 0 }, | ||
1703 | |||
1704 | /* VW ON */ | ||
1705 | { POWERREG1_ADRS, | ||
1706 | POWER1_VW_ON /* VW ON */ | POWER1_GVSS_ON /* GVSS ON */ | | ||
1707 | POWER1_VDD_ON /* VDD ON */, | ||
1708 | 0 /* Wait 100ms */ }, | ||
1709 | |||
1710 | /* Signals output enable */ | ||
1711 | { PICTRL_ADRS, | ||
1712 | 0 /* Signals output enable */, | ||
1713 | 0 }, | ||
1714 | |||
1715 | { PHACTRL_ADRS, | ||
1716 | PHACTRL_PHASE_MANUAL, | ||
1717 | 0 }, | ||
1718 | |||
1719 | /* Initialize for Input Signals from ATI */ | ||
1720 | { POLCTRL_ADRS, | ||
1721 | POLCTRL_SYNC_POL_RISE | POLCTRL_EN_POL_RISE | POLCTRL_DATA_POL_RISE | | ||
1722 | POLCTRL_SYNC_ACT_L | POLCTRL_EN_ACT_H, | ||
1723 | 1000 /*100000*/ /* Wait 100ms */ }, | ||
1724 | |||
1725 | /* end mark */ | ||
1726 | { 0xff, 0, 0 } | ||
1727 | }; | ||
1728 | |||
1729 | static void lcdtg_resume(void) | ||
1730 | { | ||
1731 | if (current_par->lcdMode == LCD_MODE_480 || current_par->lcdMode == LCD_MODE_640) { | ||
1732 | lcdtg_hw_init(LCD_SHARP_VGA); | ||
1733 | } else { | ||
1734 | lcdtg_hw_init(LCD_SHARP_QVGA); | ||
1735 | } | ||
1736 | } | ||
1737 | |||
1738 | static void lcdtg_suspend(void) | ||
1739 | { | ||
1740 | int i; | ||
1741 | |||
1742 | for (i = 0; i < (current_par->xres * current_par->yres); i++) { | ||
1743 | writew(0xffff, remapped_fbuf + (2*i)); | ||
1744 | } | ||
1745 | |||
1746 | /* 60Hz x 2 frame = 16.7msec x 2 = 33.4 msec */ | ||
1747 | mdelay(34); | ||
1748 | |||
1749 | /* (1)VW OFF */ | ||
1750 | lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_ON | POWER1_VDD_ON); | ||
1751 | |||
1752 | /* (2)COM OFF */ | ||
1753 | lcdtg_ssp_send(PICTRL_ADRS, PICTRL_COM_SIGNAL_OFF); | ||
1754 | lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON); | ||
1755 | |||
1756 | /* (3)Set Common Voltage Bias 0V */ | ||
1757 | lcdtg_set_common_voltage(POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_ON, 0); | ||
1758 | |||
1759 | /* (4)GVSS OFF */ | ||
1760 | lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_ON); | ||
1761 | |||
1762 | /* (5)VCC5 OFF */ | ||
1763 | lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF); | ||
1764 | |||
1765 | /* (6)Set PDWN, INIOFF, DACOFF */ | ||
1766 | lcdtg_ssp_send(PICTRL_ADRS, PICTRL_INIOFF | PICTRL_DAC_SIGNAL_OFF | | ||
1767 | PICTRL_POWER_DOWN | PICTRL_COM_SIGNAL_OFF); | ||
1768 | |||
1769 | /* (7)DAC OFF */ | ||
1770 | lcdtg_ssp_send(POWERREG0_ADRS, POWER0_DAC_OFF | POWER0_COM_OFF | POWER0_VCC5_OFF); | ||
1771 | |||
1772 | /* (8)VDD OFF */ | ||
1773 | lcdtg_ssp_send(POWERREG1_ADRS, POWER1_VW_OFF | POWER1_GVSS_OFF | POWER1_VDD_OFF); | ||
1774 | |||
1775 | } | ||
1776 | |||
1777 | static void lcdtg_set_phadadj(u32 mode) | ||
1778 | { | ||
1779 | int adj; | ||
1780 | |||
1781 | if (mode == LCD_SHARP_VGA) { | ||
1782 | /* Setting for VGA */ | ||
1783 | adj = current_par->phadadj; | ||
1784 | if (adj < 0) { | ||
1785 | adj = PHACTRL_PHASE_MANUAL; | ||
1786 | } else { | ||
1787 | adj = ((adj & 0x0f) << 1) | PHACTRL_PHASE_MANUAL; | ||
1788 | } | ||
1789 | } else { | ||
1790 | /* Setting for QVGA */ | ||
1791 | adj = (PHAD_QVGA_DEFAULT_VAL << 1) | PHACTRL_PHASE_MANUAL; | ||
1792 | } | ||
1793 | lcdtg_ssp_send(PHACTRL_ADRS, adj); | ||
1794 | } | ||
1795 | |||
1796 | static void lcdtg_hw_init(u32 mode) | ||
1797 | { | ||
1798 | int i; | ||
1799 | int comadj; | ||
1800 | |||
1801 | i = 0; | ||
1802 | while(lcdtg_power_on_table[i].adrs != 0xff) { | ||
1803 | if (lcdtg_power_on_table[i].adrs == 0xfe) { | ||
1804 | /* Set Common Voltage */ | ||
1805 | comadj = current_par->comadj; | ||
1806 | if (comadj < 0) { | ||
1807 | comadj = COMADJ_DEFAULT; | ||
1808 | } | ||
1809 | lcdtg_set_common_voltage((POWER0_DAC_ON | POWER0_COM_OFF | POWER0_VCC5_OFF), comadj); | ||
1810 | } else if (lcdtg_power_on_table[i].adrs == PHACTRL_ADRS) { | ||
1811 | /* Set Phase Adjuct */ | ||
1812 | lcdtg_set_phadadj(mode); | ||
1813 | } else { | ||
1814 | /* Other */ | ||
1815 | lcdtg_ssp_send(lcdtg_power_on_table[i].adrs, lcdtg_power_on_table[i].data); | ||
1816 | } | ||
1817 | if (lcdtg_power_on_table[i].wait != 0) | ||
1818 | udelay(lcdtg_power_on_table[i].wait); | ||
1819 | i++; | ||
1820 | } | ||
1821 | |||
1822 | switch(mode) { | ||
1823 | case LCD_SHARP_QVGA: | ||
1824 | /* Set Lcd Resolution (QVGA) */ | ||
1825 | lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA); | ||
1826 | break; | ||
1827 | case LCD_SHARP_VGA: | ||
1828 | /* Set Lcd Resolution (VGA) */ | ||
1829 | lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA); | ||
1830 | break; | ||
1831 | default: | ||
1832 | break; | ||
1833 | } | ||
1834 | } | ||
1835 | |||
1836 | static void lcdtg_lcd_change(u32 mode) | ||
1837 | { | ||
1838 | /* Set Phase Adjuct */ | ||
1839 | lcdtg_set_phadadj(mode); | ||
1840 | |||
1841 | if (mode == LCD_SHARP_VGA) | ||
1842 | /* Set Lcd Resolution (VGA) */ | ||
1843 | lcdtg_ssp_send(RESCTL_ADRS, RESCTL_VGA); | ||
1844 | else if (mode == LCD_SHARP_QVGA) | ||
1845 | /* Set Lcd Resolution (QVGA) */ | ||
1846 | lcdtg_ssp_send(RESCTL_ADRS, RESCTL_QVGA); | ||
1847 | } | ||
1848 | |||
1849 | |||
1850 | static struct device_driver w100fb_driver = { | 1454 | static struct device_driver w100fb_driver = { |
1851 | .name = "w100fb", | 1455 | .name = "w100fb", |
1852 | .bus = &platform_bus_type, | 1456 | .bus = &platform_bus_type, |
@@ -1870,4 +1474,4 @@ module_init(w100fb_init); | |||
1870 | module_exit(w100fb_cleanup); | 1474 | module_exit(w100fb_cleanup); |
1871 | 1475 | ||
1872 | MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver"); | 1476 | MODULE_DESCRIPTION("ATI Imageon w100 framebuffer driver"); |
1873 | MODULE_LICENSE("GPLv2"); | 1477 | MODULE_LICENSE("GPL"); |