163 #include <linux/module.h>
164 #include <linux/kernel.h>
165 #include <linux/sched.h>
166 #include <linux/errno.h>
167 #include <linux/string.h>
169 #include <linux/slab.h>
171 #include <linux/fb.h>
182 #include <video/sa1100fb.h>
184 #include <mach/hardware.h>
196 .red = { .offset = 0, .length = 4, },
197 .green = { .offset = 0, .length = 4, },
198 .blue = { .offset = 0, .length = 4, },
199 .transp = { .offset = 0, .length = 0, },
203 .red = { .offset = 0, .length = 8, },
204 .green = { .offset = 0, .length = 8, },
205 .blue = { .offset = 0, .length = 8, },
206 .transp = { .offset = 0, .length = 0, },
210 .red = { .offset = 11, .length = 5, },
211 .green = { .offset = 5, .length = 6, },
212 .blue = { .offset = 0, .length = 5, },
213 .transp = { .offset = 0, .length = 0, },
239 if (state != (
u_int)-1) {
250 return chan << bf->
offset;
260 case 4: ret = 0 << 12;
break;
261 case 8: ret = 1 << 12;
break;
262 case 16: ret = 2 << 12;
break;
275 val = ((red >> 4) & 0xf00);
276 val |= ((green >> 8) & 0x0f0);
277 val |= ((blue >> 12) & 0x00f);
280 val |= palette_pbs(&fbi->
fb.var);
302 if (fbi->
inf->cmap_inverse) {
304 green = 0xffff -
green;
305 blue = 0xffff -
blue;
312 if (fbi->
fb.var.grayscale)
313 red = green = blue = (19595 * red + 38470 * green +
316 switch (fbi->
fb.fix.visual) {
325 val = chan_to_field(red, &fbi->
fb.var.red);
326 val |= chan_to_field(green, &fbi->
fb.var.green);
327 val |= chan_to_field(blue, &fbi->
fb.var.blue);
336 ret = sa1100fb_setpalettereg(regno, red, green, blue, trans, info);
343 #ifdef CONFIG_CPU_FREQ
350 static inline unsigned int sa1100fb_display_dma_period(
struct fb_var_screeninfo *var)
376 if (var->
xres > fbi->
inf->xres)
378 if (var->
yres > fbi->
inf->yres)
402 var->
red = fbi->
rgb[rgbidx]->red;
403 var->
green = fbi->
rgb[rgbidx]->green;
404 var->
blue = fbi->
rgb[rgbidx]->blue;
407 dev_dbg(fbi->
dev,
"RGBT length = %d:%d:%d:%d\n",
411 dev_dbg(fbi->
dev,
"RGBT offset = %d:%d:%d:%d\n",
415 #ifdef CONFIG_CPU_FREQ
416 dev_dbg(fbi->
dev,
"dma period = %d ps, clock = %d kHz\n",
417 sa1100fb_display_dma_period(var),
426 if (fbi->
inf->set_visual)
427 fbi->
inf->set_visual(visual);
434 static int sa1100fb_set_par(
struct fb_info *info)
438 unsigned long palette_mem_size;
444 else if (!fbi->
inf->cmap_static)
461 dev_dbg(fbi->
dev,
"palette_mem_size = 0x%08lx\n", palette_mem_size);
469 sa1100fb_set_visual(fbi, fbi->
fb.fix.visual);
470 sa1100fb_activate_var(var, fbi);
477 sa1100fb_set_cmap(
struct fb_cmap *cmap,
int kspc,
int con,
485 if (!kspc && (fbi->
fb.var.bits_per_pixel == 16 || fbi->
inf->cmap_static))
488 return gen_set_cmap(cmap, kspc, con, info);
527 static int sa1100fb_blank(
int blank,
struct fb_info *info)
532 dev_dbg(fbi->
dev,
"sa1100fb_blank: blank=%d\n", blank);
542 sa1100fb_setpalettereg(i, 0, 0, 0, 0, info);
550 sa1100fb_schedule_work(fbi,
C_ENABLE);
555 static int sa1100fb_mmap(
struct fb_info *info,
561 if (off < info->fix.smem_len) {
563 return dma_mmap_writecombine(fbi->
dev, vma, fbi->
map_cpu,
567 start = info->
fix.mmio_start;
582 static struct fb_ops sa1100fb_ops = {
584 .fb_check_var = sa1100fb_check_var,
585 .fb_set_par = sa1100fb_set_par,
587 .fb_setcolreg = sa1100fb_setcolreg,
591 .fb_blank = sa1100fb_blank,
592 .fb_mmap = sa1100fb_mmap,
599 static inline unsigned int get_pcd(
unsigned int pixclock,
unsigned int cpuclock)
601 unsigned int pcd = cpuclock / 100;
617 u_int half_screen_size, yres, pcd;
620 dev_dbg(fbi->
dev,
"Configuring SA1100 LCD\n");
622 dev_dbg(fbi->
dev,
"var: xres=%d hslen=%d lm=%d rm=%d\n",
625 dev_dbg(fbi->
dev,
"var: yres=%d vslen=%d um=%d bm=%d\n",
630 if (var->
xres < 16 || var->
xres > 1024)
632 fbi->
fb.fix.id, var->
xres);
634 dev_err(fbi->
dev,
"%s: invalid hsync_len %d\n",
637 dev_err(fbi->
dev,
"%s: invalid left_margin %d\n",
640 dev_err(fbi->
dev,
"%s: invalid right_margin %d\n",
642 if (var->
yres < 1 || var->
yres > 1024)
644 fbi->
fb.fix.id, var->
yres);
646 dev_err(fbi->
dev,
"%s: invalid vsync_len %d\n",
649 dev_err(fbi->
dev,
"%s: invalid upper_margin %d\n",
652 dev_err(fbi->
dev,
"%s: invalid lower_margin %d\n",
656 new_regs.lccr0 = fbi->
inf->lccr0 |
685 dev_dbg(fbi->
dev,
"nlccr0 = 0x%08lx\n", new_regs.lccr0);
686 dev_dbg(fbi->
dev,
"nlccr1 = 0x%08lx\n", new_regs.lccr1);
687 dev_dbg(fbi->
dev,
"nlccr2 = 0x%08lx\n", new_regs.lccr2);
688 dev_dbg(fbi->
dev,
"nlccr3 = 0x%08lx\n", new_regs.lccr3);
691 half_screen_size = half_screen_size * var->
xres * var->
yres / 16;
725 static inline void __sa1100fb_backlight_power(
struct sa1100fb_info *fbi,
int on)
727 dev_dbg(fbi->
dev,
"backlight o%s\n", on ?
"n" :
"ff");
729 if (fbi->
inf->backlight_power)
730 fbi->
inf->backlight_power(on);
733 static inline void __sa1100fb_lcd_power(
struct sa1100fb_info *fbi,
int on)
735 dev_dbg(fbi->
dev,
"LCD power o%s\n", on ?
"n" :
"ff");
737 if (fbi->
inf->lcd_power)
738 fbi->
inf->lcd_power(on);
761 if (fbi->
fb.var.bits_per_pixel > 8 ||
784 static void sa1100fb_enable_controller(
struct sa1100fb_info *fbi)
786 dev_dbg(fbi->
dev,
"Enabling LCD controller\n");
803 if (machine_is_shannon())
814 static void sa1100fb_disable_controller(
struct sa1100fb_info *fbi)
819 dev_dbg(fbi->
dev,
"Disabling LCD controller\n");
821 if (machine_is_shannon())
828 writel_relaxed(~0, fbi->
base +
LCSR);
832 writel_relaxed(lccr0, fbi->
base +
LCCR0);
834 writel_relaxed(lccr0, fbi->
base +
LCCR0);
850 writel_relaxed(lccr0, fbi->
base +
LCCR0);
854 writel_relaxed(lcsr, fbi->
base +
LCSR);
869 old_state = fbi->
state;
885 sa1100fb_disable_controller(fbi);
897 __sa1100fb_backlight_power(fbi, 0);
899 sa1100fb_disable_controller(fbi);
900 __sa1100fb_lcd_power(fbi, 0);
911 sa1100fb_enable_controller(fbi);
922 sa1100fb_disable_controller(fbi);
923 sa1100fb_setup_gpio(fbi);
924 sa1100fb_enable_controller(fbi);
945 sa1100fb_setup_gpio(fbi);
946 __sa1100fb_lcd_power(fbi, 1);
947 sa1100fb_enable_controller(fbi);
948 __sa1100fb_backlight_power(fbi, 1);
964 set_ctrlr_state(fbi, state);
967 #ifdef CONFIG_CPU_FREQ
973 static unsigned int sa1100fb_min_dma_period(
struct sa1100fb_info *fbi)
976 unsigned int min_period = (
unsigned int)-1;
980 struct display *disp = &fb_display[
i];
986 if (disp->fb_info != &fbi->
fb)
992 period = sa1100fb_display_dma_period(&disp->var);
993 if (period < min_period)
1002 return sa1100fb_display_dma_period(&fbi->
fb.var);
1012 sa1100fb_freq_transition(
struct notifier_block *nb,
unsigned long val,
1025 pcd = get_pcd(fbi->
fb.var.pixclock, f->
new);
1034 sa1100fb_freq_policy(
struct notifier_block *nb,
unsigned long val,
1044 "new clock %d kHz\n", sa1100fb_min_dma_period(fbi),
1081 #define sa1100fb_suspend NULL
1082 #define sa1100fb_resume NULL
1144 fbi->
fb.fix.type_aux = 0;
1145 fbi->
fb.fix.xpanstep = 0;
1146 fbi->
fb.fix.ypanstep = 0;
1147 fbi->
fb.fix.ywrapstep = 0;
1150 fbi->
fb.var.nonstd = 0;
1152 fbi->
fb.var.height = -1;
1153 fbi->
fb.var.width = -1;
1154 fbi->
fb.var.accel_flags = 0;
1157 fbi->
fb.fbops = &sa1100fb_ops;
1159 fbi->
fb.monspecs = monspecs;
1160 fbi->
fb.pseudo_palette = (fbi + 1);
1173 panic(
"sa1100fb error: invalid LCCR3 fields set or zero "
1176 fbi->
fb.var.xres = inf->
xres;
1177 fbi->
fb.var.xres_virtual = inf->
xres;
1178 fbi->
fb.var.yres = inf->
yres;
1179 fbi->
fb.var.yres_virtual = inf->
yres;
1180 fbi->
fb.var.bits_per_pixel = inf->
bpp;
1188 fbi->
fb.var.sync = inf->
sync;
1192 fbi->
fb.fix.smem_len = inf->
xres * inf->
yres *
1197 for (i = 0; i <
NR_RGB; i++)
1214 if (!pdev->
dev.platform_data) {
1215 dev_err(&pdev->
dev,
"no platform LCD data\n");
1221 if (irq < 0 || !res)
1227 fbi = sa1100fb_init_fbinfo(&pdev->
dev);
1237 ret = sa1100fb_map_video_memory(fbi);
1241 ret =
request_irq(irq, sa1100fb_handle_irq, 0,
"LCD", fbi);
1243 dev_err(&pdev->
dev,
"request_irq failed: %d\n", ret);
1247 if (machine_is_shannon()) {
1258 sa1100fb_check_var(&fbi->
fb.var, &fbi->
fb);
1260 platform_set_drvdata(pdev, fbi);
1266 #ifdef CONFIG_CPU_FREQ
1267 fbi->freq_transition.notifier_call = sa1100fb_freq_transition;
1268 fbi->freq_policy.notifier_call = sa1100fb_freq_policy;
1277 if (machine_is_shannon())
1284 platform_set_drvdata(pdev,
NULL);
1291 .probe = sa1100fb_probe,
1295 .name =
"sa11x0-fb",
1313 if (!options || !*options)
1316 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
1318 if (!
strncmp(this_opt,
"bpp:", 4))
1319 current_par.max_bpp =
1322 if (!
strncmp(this_opt,
"lccr0:", 6))
1325 if (!
strncmp(this_opt,
"lccr1:", 6)) {
1328 current_par.max_xres =
1329 (lcd_shadow.lccr1 & 0x3ff) + 16;
1331 if (!
strncmp(this_opt,
"lccr2:", 6)) {
1334 current_par.max_yres =
1339 2 : ((lcd_shadow.lccr2 & 0x3ff) + 1);
1341 if (!
strncmp(this_opt,
"lccr3:", 6))