1/*
2 *  controlfb.c -- frame buffer device for the PowerMac 'control' display
3 *
4 *  Created 12 July 1998 by Dan Jacobowitz <dan@debian.org>
5 *  Copyright (C) 1998 Dan Jacobowitz
6 *  Copyright (C) 2001 Takashi Oe
7 *
8 *  Mmap code by Michel Lanners <mlan@cpu.lu>
9 *
10 *  Frame buffer structure from:
11 *    drivers/video/chipsfb.c -- frame buffer device for
12 *    Chips & Technologies 65550 chip.
13 *
14 *    Copyright (C) 1998 Paul Mackerras
15 *
16 *    This file is derived from the Powermac "chips" driver:
17 *    Copyright (C) 1997 Fabio Riccardi.
18 *    And from the frame buffer device for Open Firmware-initialized devices:
19 *    Copyright (C) 1997 Geert Uytterhoeven.
20 *
21 *  Hardware information from:
22 *    control.c: Console support for PowerMac "control" display adaptor.
23 *    Copyright (C) 1996 Paul Mackerras
24 *
25 *  Updated to 2.5 framebuffer API by Ben Herrenschmidt
26 *  <benh@kernel.crashing.org>, Paul Mackerras <paulus@samba.org>,
27 *  and James Simmons <jsimmons@infradead.org>.
28 *
29 *  This file is subject to the terms and conditions of the GNU General Public
30 *  License. See the file COPYING in the main directory of this archive for
31 *  more details.
32 */
33
34#include <linux/kernel.h>
35#include <linux/errno.h>
36#include <linux/string.h>
37#include <linux/mm.h>
38#include <linux/slab.h>
39#include <linux/vmalloc.h>
40#include <linux/delay.h>
41#include <linux/interrupt.h>
42#include <linux/of.h>
43#include <linux/of_address.h>
44#include <linux/fb.h>
45#include <linux/init.h>
46#include <linux/pci.h>
47#include <linux/nvram.h>
48#include <linux/adb.h>
49#include <linux/cuda.h>
50#ifdef CONFIG_PPC_PMAC
51#include <asm/prom.h>
52#endif
53#ifdef CONFIG_BOOTX_TEXT
54#include <asm/btext.h>
55#endif
56
57#include "macmodes.h"
58#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
74static 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
84
85struct fb_par_control {
86	int	vmode, cmode;
87	int	xres, yres;
88	int	vxres, vyres;
89	int	xoffset, yoffset;
90	int	pitch;
91	struct control_regvals	regvals;
92	unsigned long sync;
93	unsigned char ctrl;
94};
95
96#define DIRTY(z) ((x)->z != (y)->z)
97#define DIRTY_CMAP(z) (memcmp(&((x)->z), &((y)->z), sizeof((y)->z)))
98static inline int PAR_EQUAL(struct fb_par_control *x, struct fb_par_control *y)
99{
100	int i, results;
101
102	results = 1;
103	for (i = 0; i < 3; i++)
104		results &= !DIRTY(regvals.clock_params[i]);
105	if (!results)
106		return 0;
107	for (i = 0; i < 16; i++)
108		results &= !DIRTY(regvals.regs[i]);
109	if (!results)
110		return 0;
111	return (!DIRTY(cmode) && !DIRTY(xres) && !DIRTY(yres)
112		&& !DIRTY(vxres) && !DIRTY(vyres));
113}
114static inline int VAR_MATCH(struct fb_var_screeninfo *x, struct fb_var_screeninfo *y)
115{
116	return (!DIRTY(bits_per_pixel) && !DIRTY(xres)
117		&& !DIRTY(yres) && !DIRTY(xres_virtual)
118		&& !DIRTY(yres_virtual)
119		&& !DIRTY_CMAP(red) && !DIRTY_CMAP(green) && !DIRTY_CMAP(blue));
120}
121
122struct fb_info_control {
123	struct fb_info		info;
124	struct fb_par_control	par;
125	u32			pseudo_palette[16];
126
127	struct cmap_regs	__iomem *cmap_regs;
128	unsigned long		cmap_regs_phys;
129
130	struct control_regs	__iomem *control_regs;
131	unsigned long		control_regs_phys;
132	unsigned long		control_regs_size;
133
134	__u8			__iomem *frame_buffer;
135	unsigned long		frame_buffer_phys;
136	unsigned long		fb_orig_base;
137	unsigned long		fb_orig_size;
138
139	int			control_use_bank2;
140	unsigned long		total_vram;
141	unsigned char		vram_attr;
142};
143
144/* control register access macro */
145#define CNTRL_REG(INFO,REG) (&(((INFO)->control_regs->REG).r))
146
147
148/************************** Internal variables *******************************/
149
150static struct fb_info_control *control_fb;
151
152static int default_vmode __initdata = VMODE_NVRAM;
153static int default_cmode __initdata = CMODE_NVRAM;
154
155
156static int controlfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue,
157			     u_int transp, struct fb_info *info)
158{
159	struct fb_info_control *p =
160		container_of(info, struct fb_info_control, info);
161	__u8 r, g, b;
162
163	if (regno > 255)
164		return 1;
165
166	r = red >> 8;
167	g = green >> 8;
168	b = blue >> 8;
169
170	out_8(&p->cmap_regs->addr, regno);	/* tell clut what addr to fill	*/
171	out_8(&p->cmap_regs->lut, r);		/* send one color channel at	*/
172	out_8(&p->cmap_regs->lut, g);		/* a time...			*/
173	out_8(&p->cmap_regs->lut, b);
174
175	if (regno < 16) {
176		int i;
177		switch (p->par.cmode) {
178		case CMODE_16:
179			p->pseudo_palette[regno] =
180			    (regno << 10) | (regno << 5) | regno;
181			break;
182		case CMODE_32:
183			i = (regno << 8) | regno;
184			p->pseudo_palette[regno] = (i << 16) | i;
185			break;
186		}
187	}
188
189	return 0;
190}
191
192
193/********************  End of controlfb_ops implementation  ******************/
194
195
196
197static void set_control_clock(unsigned char *params)
198{
199#ifdef CONFIG_ADB_CUDA
200	struct adb_request req;
201	int i;
202
203	for (i = 0; i < 3; ++i) {
204		cuda_request(&req, NULL, 5, CUDA_PACKET, CUDA_GET_SET_IIC,
205			     0x50, i + 1, params[i]);
206		while (!req.complete)
207			cuda_poll();
208	}
209#endif
210}
211
212/*
213 * Set screen start address according to var offset values
214 */
215static inline void set_screen_start(int xoffset, int yoffset,
216	struct fb_info_control *p)
217{
218	struct fb_par_control *par = &p->par;
219
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));
224}
225
226#define RADACAL_WRITE(a,d) \
227	out_8(&p->cmap_regs->addr, (a)); \
228	out_8(&p->cmap_regs->dat,   (d))
229
230/* Now how about actually saying, Make it so! */
231/* Some things in here probably don't need to be done each time. */
232static void control_set_hardware(struct fb_info_control *p, struct fb_par_control *par)
233{
234	struct control_regvals	*r;
235	volatile struct preg	__iomem *rp;
236	int			i, cmode;
237
238	if (PAR_EQUAL(&p->par, par)) {
239		/*
240		 * check if only xoffset or yoffset differs.
241		 * this prevents flickers in typical VT switch case.
242		 */
243		if (p->par.xoffset != par->xoffset ||
244		    p->par.yoffset != par->yoffset)
245			set_screen_start(par->xoffset, par->yoffset, p);
246
247		return;
248	}
249
250	p->par = *par;
251	cmode = p->par.cmode;
252	r = &par->regvals;
253
254	/* Turn off display */
255	out_le32(CNTRL_REG(p,ctrl), 0x400 | par->ctrl);
256
257	set_control_clock(r->clock_params);
258
259	RADACAL_WRITE(0x20, r->radacal_ctrl);
260	RADACAL_WRITE(0x21, p->control_use_bank2 ? 0 : 1);
261	RADACAL_WRITE(0x10, 0);
262	RADACAL_WRITE(0x11, 0);
263
264	rp = &p->control_regs->vswin;
265	for (i = 0; i < 16; ++i, ++rp)
266		out_le32(&rp->r, r->regs[i]);
267
268	out_le32(CNTRL_REG(p,pitch), par->pitch);
269	out_le32(CNTRL_REG(p,mode), r->mode);
270	out_le32(CNTRL_REG(p,vram_attr), p->vram_attr);
271	out_le32(CNTRL_REG(p,start_addr), par->yoffset * par->pitch
272		 + (par->xoffset << cmode));
273	out_le32(CNTRL_REG(p,rfrcnt), 0x1e5);
274	out_le32(CNTRL_REG(p,intr_ena), 0);
275
276	/* Turn on display */
277	out_le32(CNTRL_REG(p,ctrl), par->ctrl);
278
279#ifdef CONFIG_BOOTX_TEXT
280	btext_update_display(p->frame_buffer_phys + CTRLFB_OFF,
281			     p->par.xres, p->par.yres,
282			     (cmode == CMODE_32? 32: cmode == CMODE_16? 16: 8),
283			     p->par.pitch);
284#endif /* CONFIG_BOOTX_TEXT */
285}
286
287/* Work out which banks of VRAM we have installed. */
288/* danj: I guess the card just ignores writes to nonexistant VRAM... */
289
290static void __init find_vram_size(struct fb_info_control *p)
291{
292	int bank1, bank2;
293
294	/*
295	 * Set VRAM in 2MB (bank 1) mode
296	 * VRAM Bank 2 will be accessible through offset 0x600000 if present
297	 * and VRAM Bank 1 will not respond at that offset even if present
298	 */
299	out_le32(CNTRL_REG(p,vram_attr), 0x31);
300
301	out_8(&p->frame_buffer[0x600000], 0xb3);
302	out_8(&p->frame_buffer[0x600001], 0x71);
303	invalid_vram_cache(&p->frame_buffer[0x600000]);
304
305	bank2 = (in_8(&p->frame_buffer[0x600000]) == 0xb3)
306		&& (in_8(&p->frame_buffer[0x600001]) == 0x71);
307
308	/*
309	 * Set VRAM in 2MB (bank 2) mode
310	 * VRAM Bank 1 will be accessible through offset 0x000000 if present
311	 * and VRAM Bank 2 will not respond at that offset even if present
312	 */
313	out_le32(CNTRL_REG(p,vram_attr), 0x39);
314
315	out_8(&p->frame_buffer[0], 0x5a);
316	out_8(&p->frame_buffer[1], 0xc7);
317	invalid_vram_cache(&p->frame_buffer[0]);
318
319	bank1 = (in_8(&p->frame_buffer[0]) == 0x5a)
320		&& (in_8(&p->frame_buffer[1]) == 0xc7);
321
322	if (bank2) {
323		if (!bank1) {
324			/*
325			 * vram bank 2 only
326			 */
327			p->control_use_bank2 = 1;
328			p->vram_attr = 0x39;
329			p->frame_buffer += 0x600000;
330			p->frame_buffer_phys += 0x600000;
331		} else {
332			/*
333			 * 4 MB vram
334			 */
335			p->vram_attr = 0x51;
336		}
337	} else {
338		/*
339		 * vram bank 1 only
340		 */
341		p->vram_attr = 0x31;
342	}
343
344        p->total_vram = (bank1 + bank2) * 0x200000;
345
346	printk(KERN_INFO "controlfb: VRAM Total = %dMB "
347			"(%dMB @ bank 1, %dMB @ bank 2)\n",
348			(bank1 + bank2) << 1, bank1 << 1, bank2 << 1);
349}
350
351/*
352 * Get the monitor sense value.
353 * Note that this can be called before calibrate_delay,
354 * so we can't use udelay.
355 */
356static int read_control_sense(struct fb_info_control *p)
357{
358	int sense;
359
360	out_le32(CNTRL_REG(p,mon_sense), 7);	/* drive all lines high */
361	__delay(200);
362	out_le32(CNTRL_REG(p,mon_sense), 077);	/* turn off drivers */
363	__delay(2000);
364	sense = (in_le32(CNTRL_REG(p,mon_sense)) & 0x1c0) << 2;
365
366	/* drive each sense line low in turn and collect the other 2 */
367	out_le32(CNTRL_REG(p,mon_sense), 033);	/* drive A low */
368	__delay(2000);
369	sense |= (in_le32(CNTRL_REG(p,mon_sense)) & 0xc0) >> 2;
370	out_le32(CNTRL_REG(p,mon_sense), 055);	/* drive B low */
371	__delay(2000);
372	sense |= ((in_le32(CNTRL_REG(p,mon_sense)) & 0x100) >> 5)
373		| ((in_le32(CNTRL_REG(p,mon_sense)) & 0x40) >> 4);
374	out_le32(CNTRL_REG(p,mon_sense), 066);	/* drive C low */
375	__delay(2000);
376	sense |= (in_le32(CNTRL_REG(p,mon_sense)) & 0x180) >> 7;
377
378	out_le32(CNTRL_REG(p,mon_sense), 077);	/* turn off drivers */
379
380	return sense;
381}
382
383/**********************  Various translation functions  **********************/
384
385#define CONTROL_PIXCLOCK_BASE	256016
386#define CONTROL_PIXCLOCK_MIN	5000	/* ~ 200 MHz dot clock */
387
388/*
389 * calculate the clock paramaters to be sent to CUDA according to given
390 * pixclock in pico second.
391 */
392static int calc_clock_params(unsigned long clk, unsigned char *param)
393{
394	unsigned long p0, p1, p2, k, l, m, n, min;
395
396	if (clk > (CONTROL_PIXCLOCK_BASE << 3))
397		return 1;
398
399	p2 = ((clk << 4) < CONTROL_PIXCLOCK_BASE)? 3: 2;
400	l = clk << p2;
401	p0 = 0;
402	p1 = 0;
403	for (k = 1, min = l; k < 32; k++) {
404		unsigned long rem;
405
406		m = CONTROL_PIXCLOCK_BASE * k;
407		n = m / l;
408		rem = m % l;
409		if (n && (n < 128) && rem < min) {
410			p0 = k;
411			p1 = n;
412			min = rem;
413		}
414	}
415	if (!p0 || !p1)
416		return 1;
417
418	param[0] = p0;
419	param[1] = p1;
420	param[2] = p2;
421
422	return 0;
423}
424
425
426/*
427 * This routine takes a user-supplied var, and picks the best vmode/cmode
428 * from it.
429 */
430
431static int control_var_to_par(struct fb_var_screeninfo *var,
432	struct fb_par_control *par, const struct fb_info *fb_info)
433{
434	int cmode, piped_diff, hstep;
435	unsigned hperiod, hssync, hsblank, hesync, heblank, piped, heq, hlfln,
436		 hserr, vperiod, vssync, vesync, veblank, vsblank, vswin, vewin;
437	unsigned long pixclock;
438	struct fb_info_control *p =
439		container_of(fb_info, struct fb_info_control, info);
440	struct control_regvals *r = &par->regvals;
441
442	switch (var->bits_per_pixel) {
443	case 8:
444		par->cmode = CMODE_8;
445		if (p->total_vram > 0x200000) {
446			r->mode = 3;
447			r->radacal_ctrl = 0x20;
448			piped_diff = 13;
449		} else {
450			r->mode = 2;
451			r->radacal_ctrl = 0x10;
452			piped_diff = 9;
453		}
454		break;
455	case 15:
456	case 16:
457		par->cmode = CMODE_16;
458		if (p->total_vram > 0x200000) {
459			r->mode = 2;
460			r->radacal_ctrl = 0x24;
461			piped_diff = 5;
462		} else {
463			r->mode = 1;
464			r->radacal_ctrl = 0x14;
465			piped_diff = 3;
466		}
467		break;
468	case 32:
469		par->cmode = CMODE_32;
470		if (p->total_vram > 0x200000) {
471			r->mode = 1;
472			r->radacal_ctrl = 0x28;
473		} else {
474			r->mode = 0;
475			r->radacal_ctrl = 0x18;
476		}
477		piped_diff = 1;
478		break;
479	default:
480		return -EINVAL;
481	}
482
483	/*
484	 * adjust xres and vxres so that the corresponding memory widths are
485	 * 32-byte aligned
486	 */
487	hstep = 31 >> par->cmode;
488	par->xres = (var->xres + hstep) & ~hstep;
489	par->vxres = (var->xres_virtual + hstep) & ~hstep;
490	par->xoffset = (var->xoffset + hstep) & ~hstep;
491	if (par->vxres < par->xres)
492		par->vxres = par->xres;
493	par->pitch = par->vxres << par->cmode;
494
495	par->yres = var->yres;
496	par->vyres = var->yres_virtual;
497	par->yoffset = var->yoffset;
498	if (par->vyres < par->yres)
499		par->vyres = par->yres;
500
501	par->sync = var->sync;
502
503	if (par->pitch * par->vyres + CTRLFB_OFF > p->total_vram)
504		return -EINVAL;
505
506	if (par->xoffset + par->xres > par->vxres)
507		par->xoffset = par->vxres - par->xres;
508	if (par->yoffset + par->yres > par->vyres)
509		par->yoffset = par->vyres - par->yres;
510
511	pixclock = (var->pixclock < CONTROL_PIXCLOCK_MIN)? CONTROL_PIXCLOCK_MIN:
512		   var->pixclock;
513	if (calc_clock_params(pixclock, r->clock_params))
514		return -EINVAL;
515
516	hperiod = ((var->left_margin + par->xres + var->right_margin
517		    + var->hsync_len) >> 1) - 2;
518	hssync = hperiod + 1;
519	hsblank = hssync - (var->right_margin >> 1);
520	hesync = (var->hsync_len >> 1) - 1;
521	heblank = (var->left_margin >> 1) + hesync;
522	piped = heblank - piped_diff;
523	heq = var->hsync_len >> 2;
524	hlfln = (hperiod+2) >> 1;
525	hserr = hssync-hesync;
526	vperiod = (var->vsync_len + var->lower_margin + par->yres
527		   + var->upper_margin) << 1;
528	vssync = vperiod - 2;
529	vesync = (var->vsync_len << 1) - vperiod + vssync;
530	veblank = (var->upper_margin << 1) + vesync;
531	vsblank = vssync - (var->lower_margin << 1);
532	vswin = (vsblank+vssync) >> 1;
533	vewin = (vesync+veblank) >> 1;
534
535	r->regs[0] = vswin;
536	r->regs[1] = vsblank;
537	r->regs[2] = veblank;
538	r->regs[3] = vewin;
539	r->regs[4] = vesync;
540	r->regs[5] = vssync;
541	r->regs[6] = vperiod;
542	r->regs[7] = piped;
543	r->regs[8] = hperiod;
544	r->regs[9] = hsblank;
545	r->regs[10] = heblank;
546	r->regs[11] = hesync;
547	r->regs[12] = hssync;
548	r->regs[13] = heq;
549	r->regs[14] = hlfln;
550	r->regs[15] = hserr;
551
552	if (par->xres >= 1280 && par->cmode >= CMODE_16)
553		par->ctrl = 0x7f;
554	else
555		par->ctrl = 0x3b;
556
557	if (mac_var_to_vmode(var, &par->vmode, &cmode))
558		par->vmode = 0;
559
560	return 0;
561}
562
563
564/*
565 * Convert hardware data in par to an fb_var_screeninfo
566 */
567
568static void control_par_to_var(struct fb_par_control *par, struct fb_var_screeninfo *var)
569{
570	struct control_regints *rv;
571
572	rv = (struct control_regints *) par->regvals.regs;
573
574	memset(var, 0, sizeof(*var));
575	var->xres = par->xres;
576	var->yres = par->yres;
577	var->xres_virtual = par->vxres;
578	var->yres_virtual = par->vyres;
579	var->xoffset = par->xoffset;
580	var->yoffset = par->yoffset;
581
582	switch(par->cmode) {
583	default:
584	case CMODE_8:
585		var->bits_per_pixel = 8;
586		var->red.length = 8;
587		var->green.length = 8;
588		var->blue.length = 8;
589		break;
590	case CMODE_16:	/* RGB 555 */
591		var->bits_per_pixel = 16;
592		var->red.offset = 10;
593		var->red.length = 5;
594		var->green.offset = 5;
595		var->green.length = 5;
596		var->blue.length = 5;
597		break;
598	case CMODE_32:	/* RGB 888 */
599		var->bits_per_pixel = 32;
600		var->red.offset = 16;
601		var->red.length = 8;
602		var->green.offset = 8;
603		var->green.length = 8;
604		var->blue.length = 8;
605		var->transp.offset = 24;
606		var->transp.length = 8;
607		break;
608	}
609	var->height = -1;
610	var->width = -1;
611	var->vmode = FB_VMODE_NONINTERLACED;
612
613	var->left_margin = (rv->heblank - rv->hesync) << 1;
614	var->right_margin = (rv->hssync - rv->hsblank) << 1;
615	var->hsync_len = (rv->hperiod + 2 - rv->hssync + rv->hesync) << 1;
616
617	var->upper_margin = (rv->veblank - rv->vesync) >> 1;
618	var->lower_margin = (rv->vssync - rv->vsblank) >> 1;
619	var->vsync_len = (rv->vperiod - rv->vssync + rv->vesync) >> 1;
620
621	var->sync = par->sync;
622
623	/*
624	 * 10^12 * clock_params[0] / (3906400 * clock_params[1]
625	 *			      * 2^clock_params[2])
626	 * (10^12 * clock_params[0] / (3906400 * clock_params[1]))
627	 * >> clock_params[2]
628	 */
629	/* (255990.17 * clock_params[0] / clock_params[1]) >> clock_params[2] */
630	var->pixclock = CONTROL_PIXCLOCK_BASE * par->regvals.clock_params[0];
631	var->pixclock /= par->regvals.clock_params[1];
632	var->pixclock >>= par->regvals.clock_params[2];
633}
634
635/********************  The functions for controlfb_ops ********************/
636
637/*
638 * Checks a var structure
639 */
640static 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 */
656static 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
680static 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
703static 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 */
741static 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
766static 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
779/*
780 * Set misc info vars for this driver
781 */
782static void __init control_init_info(struct fb_info *info, struct fb_info_control *p)
783{
784	/* Fill fb_info */
785	info->par = &p->par;
786	info->fbops = &controlfb_ops;
787	info->pseudo_palette = p->pseudo_palette;
788        info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
789	info->screen_base = p->frame_buffer + CTRLFB_OFF;
790
791	fb_alloc_cmap(&info->cmap, 256, 0);
792
793	/* Fill fix common fields */
794	strcpy(info->fix.id, "control");
795	info->fix.mmio_start = p->control_regs_phys;
796	info->fix.mmio_len = sizeof(struct control_regs);
797	info->fix.type = FB_TYPE_PACKED_PIXELS;
798	info->fix.smem_start = p->frame_buffer_phys + CTRLFB_OFF;
799	info->fix.smem_len = p->total_vram - CTRLFB_OFF;
800        info->fix.ywrapstep = 0;
801        info->fix.type_aux = 0;
802        info->fix.accel = FB_ACCEL_NONE;
803}
804
805/*
806 * Parse user specified options (`video=controlfb:')
807 */
808static 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 */
848static 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);
885try_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}
914
915static void control_cleanup(void)
916{
917	struct fb_info_control	*p = control_fb;
918
919	if (!p)
920		return;
921
922	if (p->cmap_regs)
923		iounmap(p->cmap_regs);
924	if (p->control_regs)
925		iounmap(p->control_regs);
926	if (p->frame_buffer) {
927		if (p->control_use_bank2)
928			p->frame_buffer -= 0x600000;
929		iounmap(p->frame_buffer);
930	}
931	if (p->cmap_regs_phys)
932		release_mem_region(p->cmap_regs_phys, 0x1000);
933	if (p->control_regs_phys)
934		release_mem_region(p->control_regs_phys, p->control_regs_size);
935	if (p->fb_orig_base)
936		release_mem_region(p->fb_orig_base, p->fb_orig_size);
937	kfree(p);
938}
939
940/*
941 * find "control" and initialize
942 */
943static int __init control_of_init(struct device_node *dp)
944{
945	struct fb_info_control	*p;
946	struct resource		fb_res, reg_res;
947
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
1006error_out:
1007	control_cleanup();
1008	return -ENXIO;
1009}
1010
1011static 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
1029device_initcall(control_init);
1030