34 #include <linux/module.h>
35 #include <linux/kernel.h>
36 #include <linux/errno.h>
37 #include <linux/string.h>
39 #include <linux/slab.h>
47 #include <linux/pci.h>
48 #include <linux/nvram.h>
49 #include <linux/adb.h>
50 #include <linux/cuda.h>
53 #include <asm/pgtable.h>
54 #include <asm/btext.h>
70 #define DIRTY(z) ((x)->z != (y)->z)
71 #define DIRTY_CMAP(z) (memcmp(&((x)->z), &((y)->z), sizeof((y)->z)))
77 for (i = 0; i < 3; i++)
78 results &= !
DIRTY(regvals.clock_params[i]);
81 for (i = 0; i < 16; i++)
82 results &= !
DIRTY(regvals.regs[i]);
92 && !
DIRTY(yres_virtual)
119 #define CNTRL_REG(INFO,REG) (&(((INFO)->control_regs->REG).r))
130 static int controlfb_blank(
int blank_mode,
struct fb_info *
info);
133 static int controlfb_set_par (
struct fb_info *
info);
138 static void set_control_clock(
unsigned char *
params);
145 static int calc_clock_params(
unsigned long clk,
unsigned char *
param);
151 static void control_cleanup(
void);
162 static struct fb_ops controlfb_ops = {
164 .fb_check_var = controlfb_check_var,
165 .fb_set_par = controlfb_set_par,
166 .fb_setcolreg = controlfb_setcolreg,
167 .fb_pan_display = controlfb_pan_display,
168 .fb_blank = controlfb_blank,
169 .fb_mmap = controlfb_mmap,
187 if (dp != 0 && !control_of_init(dp))
208 err = control_var_to_par(var, &par, info);
211 control_par_to_var(&par, var);
219 static int controlfb_set_par (
struct fb_info *info)
225 if((err = control_var_to_par(&info->
var, &par, info))) {
227 " control_var_to_par: %d.\n", err);
231 control_set_hardware(p, &par);
235 info->
fix.line_length = p->
par.pitch;
236 info->
fix.xpanstep = 32 >> p->
par.cmode;
237 info->
fix.ypanstep = 1;
267 hstep = 0x1f >> par->
cmode;
268 xoffset = (var->
xoffset + hstep) & ~hstep;
274 set_screen_start(xoffset, var->
yoffset, p);
285 static int controlfb_mmap(
struct fb_info *info,
288 unsigned long off,
start;
294 start = info->
fix.smem_start;
299 if (info->
var.accel_flags)
301 start = info->
fix.mmio_start;
320 static int controlfb_blank(
int blank_mode,
struct fb_info *info)
327 switch (blank_mode) {
372 switch (p->
par.cmode) {
375 (regno << 10) | (regno << 5) | regno;
378 i = (regno << 8) | regno;
392 static void set_control_clock(
unsigned char *
params)
394 #ifdef CONFIG_ADB_CUDA
398 for (i = 0; i < 3; ++
i) {
400 0x50, i + 1, params[i]);
401 while (!
req.complete)
425 if(cmode < CMODE_8 || cmode >
CMODE_32)
434 control_mac_modes[vmode - 1].
m[full] < cmode) {
435 sense = read_control_sense(p);
436 printk(
"Monitor sense value = 0x%x, ", sense);
438 if (control_mac_modes[vmode - 1].
m[full] < cmode)
445 if (control_mac_modes[vmode - 1].
m[full] < cmode) {
454 control_init_info(&p->
info, p);
459 printk(
"mac_vmode_to_var(%d, %d,) failed\n", vmode, cmode);
469 printk(
"using video mode %d and color mode %d.\n", vmode, cmode);
472 if (vyres > var.
yres)
490 #define RADACAL_WRITE(a,d) \
491 out_8(&p->cmap_regs->addr, (a)); \
492 out_8(&p->cmap_regs->dat, (d))
499 volatile struct preg __iomem *
rp;
502 if (PAR_EQUAL(&p->
par, par)) {
515 cmode = p->
par.cmode;
529 for (i = 0; i < 16; ++
i, ++
rp)
543 #ifdef CONFIG_BOOTX_TEXT
559 if (!options || !*options)
562 while ((this_opt =
strsep(&options,
",")) !=
NULL) {
563 if (!
strncmp(this_opt,
"vmode:", 6)) {
566 control_mac_modes[vmode - 1].
m[1] >= 0)
567 default_vmode = vmode;
568 }
else if (!
strncmp(this_opt,
"cmode:", 6)) {
574 default_cmode =
depth;
592 static int __init control_init(
void)
600 control_setup(option);
603 if (dp != 0 && !control_of_init(dp))
628 asm volatile(
"eieio; dcbf 0,%0" : :
"r" (&p->
frame_buffer[0x600000])
631 asm volatile(
"eieio; dcbi 0,%0" : :
"r" (&p->
frame_buffer[0x600000])
647 asm volatile(
"eieio; dcbf 0,%0" : :
"r" (&p->
frame_buffer[0])
650 asm volatile(
"eieio; dcbi 0,%0" : :
"r" (&p->
frame_buffer[0])
682 "(%dMB @ bank 1, %dMB @ bank 2)\n",
683 (bank1 + bank2) << 1, bank1 << 1, bank2 << 1);
700 if (of_pci_address_to_resource(dp, 2, &fb_res) ||
701 of_pci_address_to_resource(dp, 1, ®_res)) {
749 if (init_control(p) < 0)
793 #define CONTROL_PIXCLOCK_BASE 256016
794 #define CONTROL_PIXCLOCK_MIN 5000
800 static int calc_clock_params(
unsigned long clk,
unsigned char *
param)
811 for (k = 1, min = l; k < 32; k++) {
817 if (n && (n < 128) && rem <
min) {
842 int cmode, piped_diff, hstep;
843 unsigned hperiod, hssync, hsblank, hesync, heblank, piped,
heq, hlfln,
844 hserr, vperiod, vssync, vesync, veblank, vsblank, vswin, vewin;
845 unsigned long pixclock;
894 hstep = 31 >> par->
cmode;
895 par->
xres = (var->
xres + hstep) & ~hstep;
925 hssync = hperiod + 1;
929 piped = heblank - piped_diff;
931 hlfln = (hperiod+2) >> 1;
932 hserr = hssync-hesync;
935 vssync = vperiod - 2;
936 vesync = (var->
vsync_len << 1) - vperiod + vssync;
939 vswin = (vsblank+vssync) >> 1;
940 vewin = (vesync+veblank) >> 1;
943 r->
regs[1] = vsblank;
944 r->
regs[2] = veblank;
948 r->
regs[6] = vperiod;
950 r->
regs[8] = hperiod;
951 r->
regs[9] = hsblank;
952 r->
regs[10] = heblank;
953 r->
regs[11] = hesync;
954 r->
regs[12] = hssync;
981 memset(var, 0,
sizeof(*var));
994 var->
green.length = 8;
995 var->
blue.length = 8;
999 var->
red.offset = 10;
1000 var->
red.length = 5;
1001 var->
green.offset = 5;
1002 var->
green.length = 5;
1003 var->
blue.length = 5;
1007 var->
red.offset = 16;
1008 var->
red.length = 8;
1009 var->
green.offset = 8;
1010 var->
green.length = 8;
1011 var->
blue.length = 8;
1049 info->
fbops = &controlfb_ops;
1063 info->
fix.ywrapstep = 0;
1064 info->
fix.type_aux = 0;
1069 static void control_cleanup(
void)