forked from ~ljy/RK356X_SDK_RELEASE

hc
2024-10-09 244b2c5ca8b14627e4a17755e5922221e121c771
kernel/drivers/video/fbdev/controlfb.c
....@@ -31,7 +31,6 @@
3131 * more details.
3232 */
3333
34
-#include <linux/module.h>
3534 #include <linux/kernel.h>
3635 #include <linux/errno.h>
3736 #include <linux/string.h>
....@@ -48,13 +47,40 @@
4847 #include <linux/nvram.h>
4948 #include <linux/adb.h>
5049 #include <linux/cuda.h>
51
-#include <asm/io.h>
50
+#ifdef CONFIG_PPC_PMAC
5251 #include <asm/prom.h>
53
-#include <asm/pgtable.h>
52
+#endif
53
+#ifdef CONFIG_BOOTX_TEXT
5454 #include <asm/btext.h>
55
+#endif
5556
5657 #include "macmodes.h"
5758 #include "controlfb.h"
59
+
60
+#if !defined(CONFIG_PPC_PMAC) || !defined(CONFIG_PPC32)
61
+#define invalid_vram_cache(addr)
62
+#undef in_8
63
+#undef out_8
64
+#undef in_le32
65
+#undef out_le32
66
+#define in_8(addr) 0
67
+#define out_8(addr, val) (void)(val)
68
+#define in_le32(addr) 0
69
+#define out_le32(addr, val) (void)(val)
70
+#ifndef pgprot_cached_wthru
71
+#define pgprot_cached_wthru(prot) (prot)
72
+#endif
73
+#else
74
+static void invalid_vram_cache(void __force *addr)
75
+{
76
+ eieio();
77
+ dcbf(addr);
78
+ mb();
79
+ eieio();
80
+ dcbf(addr);
81
+ mb();
82
+}
83
+#endif
5884
5985 struct fb_par_control {
6086 int vmode, cmode;
....@@ -119,38 +145,6 @@
119145 #define CNTRL_REG(INFO,REG) (&(((INFO)->control_regs->REG).r))
120146
121147
122
-/******************** Prototypes for exported functions ********************/
123
-/*
124
- * struct fb_ops
125
- */
126
-static int controlfb_pan_display(struct fb_var_screeninfo *var,
127
- struct fb_info *info);
128
-static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
129
- u_int transp, struct fb_info *info);
130
-static int controlfb_blank(int blank_mode, struct fb_info *info);
131
-static int controlfb_mmap(struct fb_info *info,
132
- struct vm_area_struct *vma);
133
-static int controlfb_set_par (struct fb_info *info);
134
-static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info);
135
-
136
-/******************** Prototypes for internal functions **********************/
137
-
138
-static void set_control_clock(unsigned char *params);
139
-static int init_control(struct fb_info_control *p);
140
-static void control_set_hardware(struct fb_info_control *p,
141
- struct fb_par_control *par);
142
-static int control_of_init(struct device_node *dp);
143
-static void find_vram_size(struct fb_info_control *p);
144
-static int read_control_sense(struct fb_info_control *p);
145
-static int calc_clock_params(unsigned long clk, unsigned char *param);
146
-static int control_var_to_par(struct fb_var_screeninfo *var,
147
- struct fb_par_control *par, const struct fb_info *fb_info);
148
-static inline void control_par_to_var(struct fb_par_control *par,
149
- struct fb_var_screeninfo *var);
150
-static void control_init_info(struct fb_info *info, struct fb_info_control *p);
151
-static void control_cleanup(void);
152
-
153
-
154148 /************************** Internal variables *******************************/
155149
156150 static struct fb_info_control *control_fb;
....@@ -158,189 +152,6 @@
158152 static int default_vmode __initdata = VMODE_NVRAM;
159153 static int default_cmode __initdata = CMODE_NVRAM;
160154
161
-
162
-static struct fb_ops controlfb_ops = {
163
- .owner = THIS_MODULE,
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,
170
- .fb_fillrect = cfb_fillrect,
171
- .fb_copyarea = cfb_copyarea,
172
- .fb_imageblit = cfb_imageblit,
173
-};
174
-
175
-
176
-/******************** The functions for controlfb_ops ********************/
177
-
178
-#ifdef MODULE
179
-MODULE_LICENSE("GPL");
180
-
181
-int init_module(void)
182
-{
183
- struct device_node *dp;
184
- int ret = -ENXIO;
185
-
186
- dp = of_find_node_by_name(NULL, "control");
187
- if (dp != 0 && !control_of_init(dp))
188
- ret = 0;
189
- of_node_put(dp);
190
-
191
- return ret;
192
-}
193
-
194
-void cleanup_module(void)
195
-{
196
- control_cleanup();
197
-}
198
-#endif
199
-
200
-/*
201
- * Checks a var structure
202
- */
203
-static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
204
-{
205
- struct fb_par_control par;
206
- int err;
207
-
208
- err = control_var_to_par(var, &par, info);
209
- if (err)
210
- return err;
211
- control_par_to_var(&par, var);
212
-
213
- return 0;
214
-}
215
-
216
-/*
217
- * Applies current var to display
218
- */
219
-static int controlfb_set_par (struct fb_info *info)
220
-{
221
- struct fb_info_control *p =
222
- container_of(info, struct fb_info_control, info);
223
- struct fb_par_control par;
224
- int err;
225
-
226
- if((err = control_var_to_par(&info->var, &par, info))) {
227
- printk (KERN_ERR "controlfb_set_par: error calling"
228
- " control_var_to_par: %d.\n", err);
229
- return err;
230
- }
231
-
232
- control_set_hardware(p, &par);
233
-
234
- info->fix.visual = (p->par.cmode == CMODE_8) ?
235
- FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
236
- info->fix.line_length = p->par.pitch;
237
- info->fix.xpanstep = 32 >> p->par.cmode;
238
- info->fix.ypanstep = 1;
239
-
240
- return 0;
241
-}
242
-
243
-/*
244
- * Set screen start address according to var offset values
245
- */
246
-static inline void set_screen_start(int xoffset, int yoffset,
247
- struct fb_info_control *p)
248
-{
249
- struct fb_par_control *par = &p->par;
250
-
251
- par->xoffset = xoffset;
252
- par->yoffset = yoffset;
253
- out_le32(CNTRL_REG(p,start_addr),
254
- par->yoffset * par->pitch + (par->xoffset << par->cmode));
255
-}
256
-
257
-
258
-static int controlfb_pan_display(struct fb_var_screeninfo *var,
259
- struct fb_info *info)
260
-{
261
- unsigned int xoffset, hstep;
262
- struct fb_info_control *p =
263
- container_of(info, struct fb_info_control, info);
264
- struct fb_par_control *par = &p->par;
265
-
266
- /*
267
- * make sure start addr will be 32-byte aligned
268
- */
269
- hstep = 0x1f >> par->cmode;
270
- xoffset = (var->xoffset + hstep) & ~hstep;
271
-
272
- if (xoffset+par->xres > par->vxres ||
273
- var->yoffset+par->yres > par->vyres)
274
- return -EINVAL;
275
-
276
- set_screen_start(xoffset, var->yoffset, p);
277
-
278
- return 0;
279
-}
280
-
281
-
282
-/*
283
- * Private mmap since we want to have a different caching on the framebuffer
284
- * for controlfb.
285
- * Note there's no locking in here; it's done in fb_mmap() in fbmem.c.
286
- */
287
-static int controlfb_mmap(struct fb_info *info,
288
- struct vm_area_struct *vma)
289
-{
290
- unsigned long mmio_pgoff;
291
- unsigned long start;
292
- u32 len;
293
-
294
- start = info->fix.smem_start;
295
- len = info->fix.smem_len;
296
- mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
297
- if (vma->vm_pgoff >= mmio_pgoff) {
298
- if (info->var.accel_flags)
299
- return -EINVAL;
300
- vma->vm_pgoff -= mmio_pgoff;
301
- start = info->fix.mmio_start;
302
- len = info->fix.mmio_len;
303
- vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
304
- } else {
305
- /* framebuffer */
306
- vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot);
307
- }
308
-
309
- return vm_iomap_memory(vma, start, len);
310
-}
311
-
312
-static int controlfb_blank(int blank_mode, struct fb_info *info)
313
-{
314
- struct fb_info_control *p =
315
- container_of(info, struct fb_info_control, info);
316
- unsigned ctrl;
317
-
318
- ctrl = le32_to_cpup(CNTRL_REG(p,ctrl));
319
- if (blank_mode > 0)
320
- switch (blank_mode) {
321
- case FB_BLANK_VSYNC_SUSPEND:
322
- ctrl &= ~3;
323
- break;
324
- case FB_BLANK_HSYNC_SUSPEND:
325
- ctrl &= ~0x30;
326
- break;
327
- case FB_BLANK_POWERDOWN:
328
- ctrl &= ~0x33;
329
- /* fall through */
330
- case FB_BLANK_NORMAL:
331
- ctrl |= 0x400;
332
- break;
333
- default:
334
- break;
335
- }
336
- else {
337
- ctrl &= ~0x400;
338
- ctrl |= 0x33;
339
- }
340
- out_le32(CNTRL_REG(p,ctrl), ctrl);
341
-
342
- return 0;
343
-}
344155
345156 static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
346157 u_int transp, struct fb_info *info)
....@@ -398,87 +209,18 @@
398209 #endif
399210 }
400211
401
-
402212 /*
403
- * finish off the driver initialization and register
213
+ * Set screen start address according to var offset values
404214 */
405
-static int __init init_control(struct fb_info_control *p)
215
+static inline void set_screen_start(int xoffset, int yoffset,
216
+ struct fb_info_control *p)
406217 {
407
- int full, sense, vmode, cmode, vyres;
408
- struct fb_var_screeninfo var;
409
- int rc;
410
-
411
- printk(KERN_INFO "controlfb: ");
218
+ struct fb_par_control *par = &p->par;
412219
413
- full = p->total_vram == 0x400000;
414
-
415
- /* Try to pick a video mode out of NVRAM if we have one. */
416
-#ifdef CONFIG_NVRAM
417
- if (default_cmode == CMODE_NVRAM) {
418
- cmode = nvram_read_byte(NV_CMODE);
419
- if(cmode < CMODE_8 || cmode > CMODE_32)
420
- cmode = CMODE_8;
421
- } else
422
-#endif
423
- cmode=default_cmode;
424
-#ifdef CONFIG_NVRAM
425
- if (default_vmode == VMODE_NVRAM) {
426
- vmode = nvram_read_byte(NV_VMODE);
427
- if (vmode < 1 || vmode > VMODE_MAX ||
428
- control_mac_modes[vmode - 1].m[full] < cmode) {
429
- sense = read_control_sense(p);
430
- printk("Monitor sense value = 0x%x, ", sense);
431
- vmode = mac_map_monitor_sense(sense);
432
- if (control_mac_modes[vmode - 1].m[full] < cmode)
433
- vmode = VMODE_640_480_60;
434
- }
435
- } else
436
-#endif
437
- {
438
- vmode=default_vmode;
439
- if (control_mac_modes[vmode - 1].m[full] < cmode) {
440
- if (cmode > CMODE_8)
441
- cmode--;
442
- else
443
- vmode = VMODE_640_480_60;
444
- }
445
- }
446
-
447
- /* Initialize info structure */
448
- control_init_info(&p->info, p);
449
-
450
- /* Setup default var */
451
- if (mac_vmode_to_var(vmode, cmode, &var) < 0) {
452
- /* This shouldn't happen! */
453
- printk("mac_vmode_to_var(%d, %d,) failed\n", vmode, cmode);
454
-try_again:
455
- vmode = VMODE_640_480_60;
456
- cmode = CMODE_8;
457
- if (mac_vmode_to_var(vmode, cmode, &var) < 0) {
458
- printk(KERN_ERR "controlfb: mac_vmode_to_var() failed\n");
459
- return -ENXIO;
460
- }
461
- printk(KERN_INFO "controlfb: ");
462
- }
463
- printk("using video mode %d and color mode %d.\n", vmode, cmode);
464
-
465
- vyres = (p->total_vram - CTRLFB_OFF) / (var.xres << cmode);
466
- if (vyres > var.yres)
467
- var.yres_virtual = vyres;
468
-
469
- /* Apply default var */
470
- var.activate = FB_ACTIVATE_NOW;
471
- rc = fb_set_var(&p->info, &var);
472
- if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8))
473
- goto try_again;
474
-
475
- /* Register with fbdev layer */
476
- if (register_framebuffer(&p->info) < 0)
477
- return -ENXIO;
478
-
479
- fb_info(&p->info, "control display adapter\n");
480
-
481
- return 0;
220
+ par->xoffset = xoffset;
221
+ par->yoffset = yoffset;
222
+ out_le32(CNTRL_REG(p,start_addr),
223
+ par->yoffset * par->pitch + (par->xoffset << par->cmode));
482224 }
483225
484226 #define RADACAL_WRITE(a,d) \
....@@ -542,67 +284,6 @@
542284 #endif /* CONFIG_BOOTX_TEXT */
543285 }
544286
545
-
546
-/*
547
- * Parse user specified options (`video=controlfb:')
548
- */
549
-static void __init control_setup(char *options)
550
-{
551
- char *this_opt;
552
-
553
- if (!options || !*options)
554
- return;
555
-
556
- while ((this_opt = strsep(&options, ",")) != NULL) {
557
- if (!strncmp(this_opt, "vmode:", 6)) {
558
- int vmode = simple_strtoul(this_opt+6, NULL, 0);
559
- if (vmode > 0 && vmode <= VMODE_MAX &&
560
- control_mac_modes[vmode - 1].m[1] >= 0)
561
- default_vmode = vmode;
562
- } else if (!strncmp(this_opt, "cmode:", 6)) {
563
- int depth = simple_strtoul(this_opt+6, NULL, 0);
564
- switch (depth) {
565
- case CMODE_8:
566
- case CMODE_16:
567
- case CMODE_32:
568
- default_cmode = depth;
569
- break;
570
- case 8:
571
- default_cmode = CMODE_8;
572
- break;
573
- case 15:
574
- case 16:
575
- default_cmode = CMODE_16;
576
- break;
577
- case 24:
578
- case 32:
579
- default_cmode = CMODE_32;
580
- break;
581
- }
582
- }
583
- }
584
-}
585
-
586
-static int __init control_init(void)
587
-{
588
- struct device_node *dp;
589
- char *option = NULL;
590
- int ret = -ENXIO;
591
-
592
- if (fb_get_options("controlfb", &option))
593
- return -ENODEV;
594
- control_setup(option);
595
-
596
- dp = of_find_node_by_name(NULL, "control");
597
- if (dp != 0 && !control_of_init(dp))
598
- ret = 0;
599
- of_node_put(dp);
600
-
601
- return ret;
602
-}
603
-
604
-module_init(control_init);
605
-
606287 /* Work out which banks of VRAM we have installed. */
607288 /* danj: I guess the card just ignores writes to nonexistant VRAM... */
608289
....@@ -619,12 +300,7 @@
619300
620301 out_8(&p->frame_buffer[0x600000], 0xb3);
621302 out_8(&p->frame_buffer[0x600001], 0x71);
622
- asm volatile("eieio; dcbf 0,%0" : : "r" (&p->frame_buffer[0x600000])
623
- : "memory" );
624
- mb();
625
- asm volatile("eieio; dcbi 0,%0" : : "r" (&p->frame_buffer[0x600000])
626
- : "memory" );
627
- mb();
303
+ invalid_vram_cache(&p->frame_buffer[0x600000]);
628304
629305 bank2 = (in_8(&p->frame_buffer[0x600000]) == 0xb3)
630306 && (in_8(&p->frame_buffer[0x600001]) == 0x71);
....@@ -638,12 +314,7 @@
638314
639315 out_8(&p->frame_buffer[0], 0x5a);
640316 out_8(&p->frame_buffer[1], 0xc7);
641
- asm volatile("eieio; dcbf 0,%0" : : "r" (&p->frame_buffer[0])
642
- : "memory" );
643
- mb();
644
- asm volatile("eieio; dcbi 0,%0" : : "r" (&p->frame_buffer[0])
645
- : "memory" );
646
- mb();
317
+ invalid_vram_cache(&p->frame_buffer[0]);
647318
648319 bank1 = (in_8(&p->frame_buffer[0]) == 0x5a)
649320 && (in_8(&p->frame_buffer[1]) == 0xc7);
....@@ -675,79 +346,6 @@
675346 printk(KERN_INFO "controlfb: VRAM Total = %dMB "
676347 "(%dMB @ bank 1, %dMB @ bank 2)\n",
677348 (bank1 + bank2) << 1, bank1 << 1, bank2 << 1);
678
-}
679
-
680
-
681
-/*
682
- * find "control" and initialize
683
- */
684
-static int __init control_of_init(struct device_node *dp)
685
-{
686
- struct fb_info_control *p;
687
- struct resource fb_res, reg_res;
688
-
689
- if (control_fb) {
690
- printk(KERN_ERR "controlfb: only one control is supported\n");
691
- return -ENXIO;
692
- }
693
-
694
- if (of_pci_address_to_resource(dp, 2, &fb_res) ||
695
- of_pci_address_to_resource(dp, 1, &reg_res)) {
696
- printk(KERN_ERR "can't get 2 addresses for control\n");
697
- return -ENXIO;
698
- }
699
- p = kzalloc(sizeof(*p), GFP_KERNEL);
700
- if (p == 0)
701
- return -ENXIO;
702
- control_fb = p; /* save it for cleanups */
703
-
704
- /* Map in frame buffer and registers */
705
- p->fb_orig_base = fb_res.start;
706
- p->fb_orig_size = resource_size(&fb_res);
707
- /* use the big-endian aperture (??) */
708
- p->frame_buffer_phys = fb_res.start + 0x800000;
709
- p->control_regs_phys = reg_res.start;
710
- p->control_regs_size = resource_size(&reg_res);
711
-
712
- if (!p->fb_orig_base ||
713
- !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) {
714
- p->fb_orig_base = 0;
715
- goto error_out;
716
- }
717
- /* map at most 8MB for the frame buffer */
718
- p->frame_buffer = __ioremap(p->frame_buffer_phys, 0x800000,
719
- _PAGE_WRITETHRU);
720
-
721
- if (!p->control_regs_phys ||
722
- !request_mem_region(p->control_regs_phys, p->control_regs_size,
723
- "controlfb regs")) {
724
- p->control_regs_phys = 0;
725
- goto error_out;
726
- }
727
- p->control_regs = ioremap(p->control_regs_phys, p->control_regs_size);
728
-
729
- p->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */
730
- if (!request_mem_region(p->cmap_regs_phys, 0x1000, "controlfb cmap")) {
731
- p->cmap_regs_phys = 0;
732
- goto error_out;
733
- }
734
- p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
735
-
736
- if (!p->cmap_regs || !p->control_regs || !p->frame_buffer)
737
- goto error_out;
738
-
739
- find_vram_size(p);
740
- if (!p->total_vram)
741
- goto error_out;
742
-
743
- if (init_control(p) < 0)
744
- goto error_out;
745
-
746
- return 0;
747
-
748
-error_out:
749
- control_cleanup();
750
- return -ENXIO;
751349 }
752350
753351 /*
....@@ -1034,6 +632,150 @@
1034632 var->pixclock >>= par->regvals.clock_params[2];
1035633 }
1036634
635
+/******************** The functions for controlfb_ops ********************/
636
+
637
+/*
638
+ * Checks a var structure
639
+ */
640
+static int controlfb_check_var (struct fb_var_screeninfo *var, struct fb_info *info)
641
+{
642
+ struct fb_par_control par;
643
+ int err;
644
+
645
+ err = control_var_to_par(var, &par, info);
646
+ if (err)
647
+ return err;
648
+ control_par_to_var(&par, var);
649
+
650
+ return 0;
651
+}
652
+
653
+/*
654
+ * Applies current var to display
655
+ */
656
+static int controlfb_set_par (struct fb_info *info)
657
+{
658
+ struct fb_info_control *p =
659
+ container_of(info, struct fb_info_control, info);
660
+ struct fb_par_control par;
661
+ int err;
662
+
663
+ if((err = control_var_to_par(&info->var, &par, info))) {
664
+ printk (KERN_ERR "controlfb_set_par: error calling"
665
+ " control_var_to_par: %d.\n", err);
666
+ return err;
667
+ }
668
+
669
+ control_set_hardware(p, &par);
670
+
671
+ info->fix.visual = (p->par.cmode == CMODE_8) ?
672
+ FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_DIRECTCOLOR;
673
+ info->fix.line_length = p->par.pitch;
674
+ info->fix.xpanstep = 32 >> p->par.cmode;
675
+ info->fix.ypanstep = 1;
676
+
677
+ return 0;
678
+}
679
+
680
+static int controlfb_pan_display(struct fb_var_screeninfo *var,
681
+ struct fb_info *info)
682
+{
683
+ unsigned int xoffset, hstep;
684
+ struct fb_info_control *p =
685
+ container_of(info, struct fb_info_control, info);
686
+ struct fb_par_control *par = &p->par;
687
+
688
+ /*
689
+ * make sure start addr will be 32-byte aligned
690
+ */
691
+ hstep = 0x1f >> par->cmode;
692
+ xoffset = (var->xoffset + hstep) & ~hstep;
693
+
694
+ if (xoffset+par->xres > par->vxres ||
695
+ var->yoffset+par->yres > par->vyres)
696
+ return -EINVAL;
697
+
698
+ set_screen_start(xoffset, var->yoffset, p);
699
+
700
+ return 0;
701
+}
702
+
703
+static int controlfb_blank(int blank_mode, struct fb_info *info)
704
+{
705
+ struct fb_info_control __maybe_unused *p =
706
+ container_of(info, struct fb_info_control, info);
707
+ unsigned ctrl;
708
+
709
+ ctrl = in_le32(CNTRL_REG(p, ctrl));
710
+ if (blank_mode > 0)
711
+ switch (blank_mode) {
712
+ case FB_BLANK_VSYNC_SUSPEND:
713
+ ctrl &= ~3;
714
+ break;
715
+ case FB_BLANK_HSYNC_SUSPEND:
716
+ ctrl &= ~0x30;
717
+ break;
718
+ case FB_BLANK_POWERDOWN:
719
+ ctrl &= ~0x33;
720
+ fallthrough;
721
+ case FB_BLANK_NORMAL:
722
+ ctrl |= 0x400;
723
+ break;
724
+ default:
725
+ break;
726
+ }
727
+ else {
728
+ ctrl &= ~0x400;
729
+ ctrl |= 0x33;
730
+ }
731
+ out_le32(CNTRL_REG(p,ctrl), ctrl);
732
+
733
+ return 0;
734
+}
735
+
736
+/*
737
+ * Private mmap since we want to have a different caching on the framebuffer
738
+ * for controlfb.
739
+ * Note there's no locking in here; it's done in fb_mmap() in fbmem.c.
740
+ */
741
+static int controlfb_mmap(struct fb_info *info,
742
+ struct vm_area_struct *vma)
743
+{
744
+ unsigned long mmio_pgoff;
745
+ unsigned long start;
746
+ u32 len;
747
+
748
+ start = info->fix.smem_start;
749
+ len = info->fix.smem_len;
750
+ mmio_pgoff = PAGE_ALIGN((start & ~PAGE_MASK) + len) >> PAGE_SHIFT;
751
+ if (vma->vm_pgoff >= mmio_pgoff) {
752
+ if (info->var.accel_flags)
753
+ return -EINVAL;
754
+ vma->vm_pgoff -= mmio_pgoff;
755
+ start = info->fix.mmio_start;
756
+ len = info->fix.mmio_len;
757
+ vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
758
+ } else {
759
+ /* framebuffer */
760
+ vma->vm_page_prot = pgprot_cached_wthru(vma->vm_page_prot);
761
+ }
762
+
763
+ return vm_iomap_memory(vma, start, len);
764
+}
765
+
766
+static const struct fb_ops controlfb_ops = {
767
+ .owner = THIS_MODULE,
768
+ .fb_check_var = controlfb_check_var,
769
+ .fb_set_par = controlfb_set_par,
770
+ .fb_setcolreg = controlfb_setcolreg,
771
+ .fb_pan_display = controlfb_pan_display,
772
+ .fb_blank = controlfb_blank,
773
+ .fb_mmap = controlfb_mmap,
774
+ .fb_fillrect = cfb_fillrect,
775
+ .fb_copyarea = cfb_copyarea,
776
+ .fb_imageblit = cfb_imageblit,
777
+};
778
+
1037779 /*
1038780 * Set misc info vars for this driver
1039781 */
....@@ -1060,6 +802,115 @@
1060802 info->fix.accel = FB_ACCEL_NONE;
1061803 }
1062804
805
+/*
806
+ * Parse user specified options (`video=controlfb:')
807
+ */
808
+static void __init control_setup(char *options)
809
+{
810
+ char *this_opt;
811
+
812
+ if (!options || !*options)
813
+ return;
814
+
815
+ while ((this_opt = strsep(&options, ",")) != NULL) {
816
+ if (!strncmp(this_opt, "vmode:", 6)) {
817
+ int vmode = simple_strtoul(this_opt+6, NULL, 0);
818
+ if (vmode > 0 && vmode <= VMODE_MAX &&
819
+ control_mac_modes[vmode - 1].m[1] >= 0)
820
+ default_vmode = vmode;
821
+ } else if (!strncmp(this_opt, "cmode:", 6)) {
822
+ int depth = simple_strtoul(this_opt+6, NULL, 0);
823
+ switch (depth) {
824
+ case CMODE_8:
825
+ case CMODE_16:
826
+ case CMODE_32:
827
+ default_cmode = depth;
828
+ break;
829
+ case 8:
830
+ default_cmode = CMODE_8;
831
+ break;
832
+ case 15:
833
+ case 16:
834
+ default_cmode = CMODE_16;
835
+ break;
836
+ case 24:
837
+ case 32:
838
+ default_cmode = CMODE_32;
839
+ break;
840
+ }
841
+ }
842
+ }
843
+}
844
+
845
+/*
846
+ * finish off the driver initialization and register
847
+ */
848
+static int __init init_control(struct fb_info_control *p)
849
+{
850
+ int full, sense, vmode, cmode, vyres;
851
+ struct fb_var_screeninfo var;
852
+ int rc;
853
+
854
+ printk(KERN_INFO "controlfb: ");
855
+
856
+ full = p->total_vram == 0x400000;
857
+
858
+ /* Try to pick a video mode out of NVRAM if we have one. */
859
+ cmode = default_cmode;
860
+ if (IS_REACHABLE(CONFIG_NVRAM) && cmode == CMODE_NVRAM)
861
+ cmode = nvram_read_byte(NV_CMODE);
862
+ if (cmode < CMODE_8 || cmode > CMODE_32)
863
+ cmode = CMODE_8;
864
+
865
+ vmode = default_vmode;
866
+ if (IS_REACHABLE(CONFIG_NVRAM) && vmode == VMODE_NVRAM)
867
+ vmode = nvram_read_byte(NV_VMODE);
868
+ if (vmode < 1 || vmode > VMODE_MAX ||
869
+ control_mac_modes[vmode - 1].m[full] < cmode) {
870
+ sense = read_control_sense(p);
871
+ printk(KERN_CONT "Monitor sense value = 0x%x, ", sense);
872
+ vmode = mac_map_monitor_sense(sense);
873
+ if (control_mac_modes[vmode - 1].m[full] < 0)
874
+ vmode = VMODE_640_480_60;
875
+ cmode = min(cmode, control_mac_modes[vmode - 1].m[full]);
876
+ }
877
+
878
+ /* Initialize info structure */
879
+ control_init_info(&p->info, p);
880
+
881
+ /* Setup default var */
882
+ if (mac_vmode_to_var(vmode, cmode, &var) < 0) {
883
+ /* This shouldn't happen! */
884
+ printk("mac_vmode_to_var(%d, %d,) failed\n", vmode, cmode);
885
+try_again:
886
+ vmode = VMODE_640_480_60;
887
+ cmode = CMODE_8;
888
+ if (mac_vmode_to_var(vmode, cmode, &var) < 0) {
889
+ printk(KERN_ERR "controlfb: mac_vmode_to_var() failed\n");
890
+ return -ENXIO;
891
+ }
892
+ printk(KERN_INFO "controlfb: ");
893
+ }
894
+ printk("using video mode %d and color mode %d.\n", vmode, cmode);
895
+
896
+ vyres = (p->total_vram - CTRLFB_OFF) / (var.xres << cmode);
897
+ if (vyres > var.yres)
898
+ var.yres_virtual = vyres;
899
+
900
+ /* Apply default var */
901
+ var.activate = FB_ACTIVATE_NOW;
902
+ rc = fb_set_var(&p->info, &var);
903
+ if (rc && (vmode != VMODE_640_480_60 || cmode != CMODE_8))
904
+ goto try_again;
905
+
906
+ /* Register with fbdev layer */
907
+ if (register_framebuffer(&p->info) < 0)
908
+ return -ENXIO;
909
+
910
+ fb_info(&p->info, "control display adapter\n");
911
+
912
+ return 0;
913
+}
1063914
1064915 static void control_cleanup(void)
1065916 {
....@@ -1086,4 +937,93 @@
1086937 kfree(p);
1087938 }
1088939
940
+/*
941
+ * find "control" and initialize
942
+ */
943
+static int __init control_of_init(struct device_node *dp)
944
+{
945
+ struct fb_info_control *p;
946
+ struct resource fb_res, reg_res;
1089947
948
+ if (control_fb) {
949
+ printk(KERN_ERR "controlfb: only one control is supported\n");
950
+ return -ENXIO;
951
+ }
952
+
953
+ if (of_pci_address_to_resource(dp, 2, &fb_res) ||
954
+ of_pci_address_to_resource(dp, 1, &reg_res)) {
955
+ printk(KERN_ERR "can't get 2 addresses for control\n");
956
+ return -ENXIO;
957
+ }
958
+ p = kzalloc(sizeof(*p), GFP_KERNEL);
959
+ if (!p)
960
+ return -ENOMEM;
961
+ control_fb = p; /* save it for cleanups */
962
+
963
+ /* Map in frame buffer and registers */
964
+ p->fb_orig_base = fb_res.start;
965
+ p->fb_orig_size = resource_size(&fb_res);
966
+ /* use the big-endian aperture (??) */
967
+ p->frame_buffer_phys = fb_res.start + 0x800000;
968
+ p->control_regs_phys = reg_res.start;
969
+ p->control_regs_size = resource_size(&reg_res);
970
+
971
+ if (!p->fb_orig_base ||
972
+ !request_mem_region(p->fb_orig_base,p->fb_orig_size,"controlfb")) {
973
+ p->fb_orig_base = 0;
974
+ goto error_out;
975
+ }
976
+ /* map at most 8MB for the frame buffer */
977
+ p->frame_buffer = ioremap_wt(p->frame_buffer_phys, 0x800000);
978
+
979
+ if (!p->control_regs_phys ||
980
+ !request_mem_region(p->control_regs_phys, p->control_regs_size,
981
+ "controlfb regs")) {
982
+ p->control_regs_phys = 0;
983
+ goto error_out;
984
+ }
985
+ p->control_regs = ioremap(p->control_regs_phys, p->control_regs_size);
986
+
987
+ p->cmap_regs_phys = 0xf301b000; /* XXX not in prom? */
988
+ if (!request_mem_region(p->cmap_regs_phys, 0x1000, "controlfb cmap")) {
989
+ p->cmap_regs_phys = 0;
990
+ goto error_out;
991
+ }
992
+ p->cmap_regs = ioremap(p->cmap_regs_phys, 0x1000);
993
+
994
+ if (!p->cmap_regs || !p->control_regs || !p->frame_buffer)
995
+ goto error_out;
996
+
997
+ find_vram_size(p);
998
+ if (!p->total_vram)
999
+ goto error_out;
1000
+
1001
+ if (init_control(p) < 0)
1002
+ goto error_out;
1003
+
1004
+ return 0;
1005
+
1006
+error_out:
1007
+ control_cleanup();
1008
+ return -ENXIO;
1009
+}
1010
+
1011
+static int __init control_init(void)
1012
+{
1013
+ struct device_node *dp;
1014
+ char *option = NULL;
1015
+ int ret = -ENXIO;
1016
+
1017
+ if (fb_get_options("controlfb", &option))
1018
+ return -ENODEV;
1019
+ control_setup(option);
1020
+
1021
+ dp = of_find_node_by_name(NULL, "control");
1022
+ if (dp && !control_of_init(dp))
1023
+ ret = 0;
1024
+ of_node_put(dp);
1025
+
1026
+ return ret;
1027
+}
1028
+
1029
+device_initcall(control_init);