16 #include <linux/module.h>
17 #include <linux/kernel.h>
19 #include <linux/errno.h>
20 #include <linux/string.h>
22 #include <linux/tty.h>
23 #include <linux/slab.h>
30 #include <linux/wait.h>
36 #include <linux/device.h>
39 #include <mach/regs-clock.h>
49 static void nuc900fb_set_lcdaddr(
struct fb_info *
info)
53 unsigned long vbaddr1, vbaddr2;
55 vbaddr1 = info->
fix.smem_start;
56 vbaddr2 = info->
fix.smem_start;
57 vbaddr2 += info->
fix.line_length * info->
var.yres;
70 static unsigned int nuc900fb_calc_pixclk(
struct nuc900fb_info *fbi,
74 unsigned long long div;
78 div = (
unsigned long long)clk * pixclk;
82 dev_dbg(fbi->
dev,
"pixclk %ld, divisor is %lld\n", pixclk, div);
100 dev_dbg(fbi->
dev,
"check_var(var=%p, info=%p)\n", var, info);
104 if (var->
xres == default_display->
xres &&
105 var->
yres == default_display->
yres &&
107 display = default_display;
117 if (display ==
NULL) {
118 printk(
KERN_ERR "wrong resolution or depth %dx%d at %d bit per pixel\n",
160 var->
green.length = 4;
161 var->
blue.length = 4;
163 var->
green.offset = 4;
164 var->
blue.offset = 0;
168 var->
green.length = 6;
169 var->
blue.length = 5;
170 var->
red.offset = 11;
171 var->
green.offset = 5;
172 var->
blue.offset = 0;
176 var->
green.length = 6;
177 var->
blue.length = 6;
178 var->
red.offset = 12;
179 var->
green.offset = 6;
180 var->
blue.offset = 0;
184 var->
green.length = 8;
185 var->
blue.length = 8;
186 var->
red.offset = 16;
187 var->
green.offset = 8;
188 var->
blue.offset = 0;
198 static void nuc900fb_calculate_lcd_regs(
const struct fb_info *info,
224 static void nuc900fb_activate_var(
struct fb_info *info)
231 clkdiv = nuc900fb_calc_pixclk(fbi, var->
pixclock) - 1;
235 nuc900fb_calculate_lcd_regs(info, &fbi->
regs);
241 dev_dbg(fbi->
dev,
"dev_ctl = 0x%08x\n", fbi->
regs.lcd_device_ctrl);
242 dev_dbg(fbi->
dev,
"crtc_size = 0x%08x\n", fbi->
regs.lcd_crtc_size);
243 dev_dbg(fbi->
dev,
"crtc_dend = 0x%08x\n", fbi->
regs.lcd_crtc_dend);
245 dev_dbg(fbi->
dev,
"crtc_hsync = 0x%08x\n", fbi->
regs.lcd_crtc_hsync);
256 nuc900fb_set_lcdaddr(info);
265 static int nuc900fb_set_par(
struct fb_info *info)
288 nuc900fb_activate_var(info);
292 static inline unsigned int chan_to_field(
unsigned int chan,
297 return chan << bf->
offset;
300 static int nuc900fb_setcolreg(
unsigned regno,
306 switch (info->
fix.visual) {
312 val = chan_to_field(red, &info->
var.red);
313 val |= chan_to_field(green, &info->
var.green);
314 val |= chan_to_field(blue, &info->
var.blue);
329 static int nuc900fb_blank(
int blank_mode,
struct fb_info *info)
335 static struct fb_ops nuc900fb_ops = {
337 .fb_check_var = nuc900fb_check_var,
338 .fb_set_par = nuc900fb_set_par,
339 .fb_blank = nuc900fb_blank,
340 .fb_setcolreg = nuc900fb_setcolreg,
347 static inline void modify_gpio(
void __iomem *
reg,
348 unsigned long set,
unsigned long mask)
351 tmp =
readl(reg) & ~mask;
358 static int nuc900fb_init_registers(
struct fb_info *info)
396 dev_dbg(fbi->
dev,
"nuc900fb_map_video_memory(fbi=%p) map_size %lu\n",
406 info->
fix.smem_start = map_dma;
411 static inline void nuc900fb_unmap_video_memory(
struct fb_info *info)
441 writel(
readl(irq_base) | LCM_INT_CS_UNDERRUN_INT, irq_base);
443 writel(
readl(irq_base) | LCM_INT_CS_BUS_ERROR_INT, irq_base);
449 #ifdef CONFIG_CPU_FREQ
452 unsigned long val,
void *
data)
465 nuc900fb_activate_var(fbinfo);
471 static inline int nuc900fb_cpufreq_register(
struct nuc900fb_info *fbi)
473 fbi->freq_transition.notifier_call = nuc900fb_cpufreq_transition;
478 static inline void nuc900fb_cpufreq_deregister(
struct nuc900fb_info *fbi)
484 static inline int nuc900fb_cpufreq_transition(
struct notifier_block *nb,
485 unsigned long val,
void *data)
490 static inline int nuc900fb_cpufreq_register(
struct nuc900fb_info *fbi)
495 static inline void nuc900fb_cpufreq_deregister(
struct nuc900fb_info *info)
515 mach_info = pdev->
dev.platform_data;
516 if (mach_info ==
NULL) {
518 "no platform data for lcd, cannot attach\n");
524 "default display No. is %d but only %d displays \n",
542 platform_set_drvdata(pdev, fbinfo);
547 #ifdef CONFIG_CPU_NUC950
553 size = resource_size(res);
556 dev_err(&pdev->
dev,
"failed to alloc memory region\n");
563 dev_err(&pdev->
dev,
"ioremap() of lcd registers failed\n");
577 fbinfo->
fix.type_aux = 0;
578 fbinfo->
fix.xpanstep = 0;
579 fbinfo->
fix.ypanstep = 0;
580 fbinfo->
fix.ywrapstep = 0;
582 fbinfo->
var.nonstd = 0;
584 fbinfo->
var.accel_flags = 0;
586 fbinfo->
fbops = &nuc900fb_ops;
593 dev_err(&pdev->
dev,
"cannot register irq handler %d -err %d\n",
600 if (IS_ERR(fbi->
clk)) {
602 ret = PTR_ERR(fbi->
clk);
607 dev_dbg(&pdev->
dev,
"got and enabled clock\n");
613 unsigned long smem_len = mach_info->
displays[
i].xres;
617 if (fbinfo->
fix.smem_len < smem_len)
618 fbinfo->
fix.smem_len = smem_len;
622 ret = nuc900fb_map_video_memory(fbinfo);
630 fbinfo->
var.xres = display->
xres;
631 fbinfo->
var.yres = display->
yres;
632 fbinfo->
var.bits_per_pixel = display->
bpp;
634 nuc900fb_init_registers(fbinfo);
636 nuc900fb_check_var(&fbinfo->
var, fbinfo);
638 ret = nuc900fb_cpufreq_register(fbi);
640 dev_err(&pdev->
dev,
"Failed to register cpufreq\n");
641 goto free_video_memory;
657 nuc900fb_cpufreq_deregister(fbi);
659 nuc900fb_unmap_video_memory(fbinfo);
677 static void nuc900fb_stop_lcd(
struct fb_info *info)
691 struct fb_info *fbinfo = platform_get_drvdata(pdev);
695 nuc900fb_stop_lcd(fbinfo);
699 nuc900fb_cpufreq_deregister(fbi);
700 nuc900fb_unmap_video_memory(fbinfo);
710 platform_set_drvdata(pdev,
NULL);
724 struct fb_info *fbinfo = platform_get_drvdata(dev);
727 nuc900fb_stop_lcd(fbinfo);
735 struct fb_info *fbinfo = platform_get_drvdata(dev);
743 nuc900fb_init_registers(fbinfo);
744 nuc900fb_activate_var(fbinfo);
750 #define nuc900fb_suspend NULL
751 #define nuc900fb_resume NULL
755 .probe = nuc900fb_probe,
756 .remove = nuc900fb_remove,
760 .name =
"nuc900-lcd",