1 #include <linux/module.h>
2 #include <linux/kernel.h>
3 #include <linux/errno.h>
4 #include <linux/string.h>
5 #include <linux/mm.h>
6 #include <linux/slab.h>
7 #include <linux/delay.h>
8 #include <linux/fb.h>
9 #include <linux/ioport.h>
10 #include <linux/init.h>
11 #include <linux/pci.h>
12 #include <linux/vmalloc.h>
13 #include <linux/pagemap.h>
14 #include <linux/console.h>
15 #ifdef CONFIG_MTRR
16 #include <asm/mtrr.h>
17 #endif
18 #include <linux/platform_device.h>
19 #include <linux/screen_info.h>
20 #include <linux/sizes.h>
21 
22 #include "sm750.h"
23 #include "ddk750.h"
24 #include "sm750_accel.h"
25 
26 int hw_sm750_map(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
27 {
28 	int ret;
29 
30 	ret = 0;
31 
32 	sm750_dev->vidreg_start  = pci_resource_start(pdev, 1);
33 	sm750_dev->vidreg_size = SZ_2M;
34 
35 	pr_info("mmio phyAddr = %lx\n", sm750_dev->vidreg_start);
36 
37 	/* reserve the vidreg space of smi adaptor
38 	 * if you do this, u need to add release region code
39 	 * in lynxfb_remove, or memory will not be mapped again
40 	 * successfully
41 	 * */
42 	ret = pci_request_region(pdev, 1, "sm750fb");
43 	if (ret) {
44 		pr_err("Can not request PCI regions.\n");
45 		goto exit;
46 	}
47 
48 	/* now map mmio and vidmem*/
49 	sm750_dev->pvReg = ioremap_nocache(sm750_dev->vidreg_start,
50 					   sm750_dev->vidreg_size);
51 	if (!sm750_dev->pvReg) {
52 		pr_err("mmio failed\n");
53 		ret = -EFAULT;
54 		goto exit;
55 	} else {
56 		pr_info("mmio virtual addr = %p\n", sm750_dev->pvReg);
57 	}
58 
59 
60 	sm750_dev->accel.dprBase = sm750_dev->pvReg + DE_BASE_ADDR_TYPE1;
61 	sm750_dev->accel.dpPortBase = sm750_dev->pvReg + DE_PORT_ADDR_TYPE1;
62 
63 	ddk750_set_mmio(sm750_dev->pvReg, sm750_dev->devid, sm750_dev->revid);
64 
65 	sm750_dev->vidmem_start = pci_resource_start(pdev, 0);
66 	/* don't use pdev_resource[x].end - resource[x].start to
67 	 * calculate the resource size,its only the maximum available
68 	 * size but not the actual size,use
69 	 * @ddk750_getVMSize function can be safe.
70 	 * */
71 	sm750_dev->vidmem_size = ddk750_getVMSize();
72 	pr_info("video memory phyAddr = %lx, size = %u bytes\n",
73 		sm750_dev->vidmem_start, sm750_dev->vidmem_size);
74 
75 	/* reserve the vidmem space of smi adaptor */
76 	sm750_dev->pvMem = ioremap_wc(sm750_dev->vidmem_start,
77 				      sm750_dev->vidmem_size);
78 	if (!sm750_dev->pvMem) {
79 		pr_err("Map video memory failed\n");
80 		ret = -EFAULT;
81 		goto exit;
82 	} else {
83 		pr_info("video memory vaddr = %p\n", sm750_dev->pvMem);
84 	}
85 exit:
86 	return ret;
87 }
88 
89 
90 
91 int hw_sm750_inithw(struct sm750_dev *sm750_dev, struct pci_dev *pdev)
92 {
93 	struct init_status *parm;
94 
95 	parm = &sm750_dev->initParm;
96 	if (parm->chip_clk == 0)
97 		parm->chip_clk = (getChipType() == SM750LE) ?
98 						DEFAULT_SM750LE_CHIP_CLOCK :
99 						DEFAULT_SM750_CHIP_CLOCK;
100 
101 	if (parm->mem_clk == 0)
102 		parm->mem_clk = parm->chip_clk;
103 	if (parm->master_clk == 0)
104 		parm->master_clk = parm->chip_clk/3;
105 
106 	ddk750_initHw((initchip_param_t *)&sm750_dev->initParm);
107 	/* for sm718,open pci burst */
108 	if (sm750_dev->devid == 0x718) {
109 		POKE32(SYSTEM_CTRL,
110 		       PEEK32(SYSTEM_CTRL) | SYSTEM_CTRL_PCI_BURST);
111 	}
112 
113 	if (getChipType() != SM750LE) {
114 		unsigned int val;
115 		/* does user need CRT ?*/
116 		if (sm750_dev->nocrt) {
117 			POKE32(MISC_CTRL,
118 			       PEEK32(MISC_CTRL) | MISC_CTRL_DAC_POWER_OFF);
119 			/* shut off dpms */
120 			val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK;
121 			val |= SYSTEM_CTRL_DPMS_VPHN;
122 			POKE32(SYSTEM_CTRL, val);
123 		} else {
124 			POKE32(MISC_CTRL,
125 			       PEEK32(MISC_CTRL) & ~MISC_CTRL_DAC_POWER_OFF);
126 			/* turn on dpms */
127 			val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK;
128 			val |= SYSTEM_CTRL_DPMS_VPHP;
129 			POKE32(SYSTEM_CTRL, val);
130 		}
131 
132 		val = PEEK32(PANEL_DISPLAY_CTRL) &
133 			~(PANEL_DISPLAY_CTRL_DUAL_DISPLAY |
134 			  PANEL_DISPLAY_CTRL_DOUBLE_PIXEL);
135 		switch (sm750_dev->pnltype) {
136 		case sm750_24TFT:
137 			break;
138 		case sm750_doubleTFT:
139 			val |= PANEL_DISPLAY_CTRL_DOUBLE_PIXEL;
140 			break;
141 		case sm750_dualTFT:
142 			val |= PANEL_DISPLAY_CTRL_DUAL_DISPLAY;
143 			break;
144 		}
145 		POKE32(PANEL_DISPLAY_CTRL, val);
146 	} else {
147 		/* for 750LE ,no DVI chip initialization makes Monitor no signal */
148 		/* Set up GPIO for software I2C to program DVI chip in the
149 		   Xilinx SP605 board, in order to have video signal.
150 		 */
151 		sm750_sw_i2c_init(0, 1);
152 
153 		/* Customer may NOT use CH7301 DVI chip, which has to be
154 		initialized differently.
155 		*/
156 		if (sm750_sw_i2c_read_reg(0xec, 0x4a) == 0x95) {
157 		/* The following register values for CH7301 are from
158 		   Chrontel app note and our experiment.
159 		*/
160 			pr_info("yes,CH7301 DVI chip found\n");
161 			sm750_sw_i2c_write_reg(0xec, 0x1d, 0x16);
162 			sm750_sw_i2c_write_reg(0xec, 0x21, 0x9);
163 			sm750_sw_i2c_write_reg(0xec, 0x49, 0xC0);
164 			pr_info("okay,CH7301 DVI chip setup done\n");
165 		}
166 	}
167 
168 	/* init 2d engine */
169 	if (!sm750_dev->accel_off)
170 		hw_sm750_initAccel(sm750_dev);
171 
172 	return 0;
173 }
174 
175 int hw_sm750_output_setMode(struct lynxfb_output *output,
176 									struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix)
177 {
178 	int ret;
179 	disp_output_t dispSet;
180 	int channel;
181 
182 	ret = 0;
183 	dispSet = 0;
184 	channel = *output->channel;
185 
186 
187 	if (getChipType() != SM750LE) {
188 		if (channel == sm750_primary) {
189 			pr_info("primary channel\n");
190 			if (output->paths & sm750_panel)
191 				dispSet |= do_LCD1_PRI;
192 			if (output->paths & sm750_crt)
193 				dispSet |= do_CRT_PRI;
194 
195 		} else {
196 			pr_info("secondary channel\n");
197 			if (output->paths & sm750_panel)
198 				dispSet |= do_LCD1_SEC;
199 			if (output->paths & sm750_crt)
200 				dispSet |= do_CRT_SEC;
201 
202 		}
203 		ddk750_setLogicalDispOut(dispSet);
204 	} else {
205 		/* just open DISPLAY_CONTROL_750LE register bit 3:0*/
206 		u32 reg;
207 
208 		reg = PEEK32(DISPLAY_CONTROL_750LE);
209 		reg |= 0xf;
210 		POKE32(DISPLAY_CONTROL_750LE, reg);
211 	}
212 
213 	pr_info("ddk setlogicdispout done\n");
214 	return ret;
215 }
216 
217 int hw_sm750_crtc_checkMode(struct lynxfb_crtc *crtc, struct fb_var_screeninfo *var)
218 {
219 	struct sm750_dev *sm750_dev;
220 	struct lynxfb_par *par = container_of(crtc, struct lynxfb_par, crtc);
221 
222 	sm750_dev = par->dev;
223 
224 	switch (var->bits_per_pixel) {
225 	case 8:
226 	case 16:
227 		break;
228 	case 32:
229 		if (sm750_dev->revid == SM750LE_REVISION_ID) {
230 			pr_debug("750le do not support 32bpp\n");
231 			return -EINVAL;
232 		}
233 		break;
234 	default:
235 		return -EINVAL;
236 
237 	}
238 
239 	return 0;
240 }
241 
242 
243 /*
244 	set the controller's mode for @crtc charged with @var and @fix parameters
245 */
246 int hw_sm750_crtc_setMode(struct lynxfb_crtc *crtc,
247 								struct fb_var_screeninfo *var,
248 								struct fb_fix_screeninfo *fix)
249 {
250 	int ret, fmt;
251 	u32 reg;
252 	mode_parameter_t modparm;
253 	clock_type_t clock;
254 	struct sm750_dev *sm750_dev;
255 	struct lynxfb_par *par;
256 
257 
258 	ret = 0;
259 	par = container_of(crtc, struct lynxfb_par, crtc);
260 	sm750_dev = par->dev;
261 
262 	if (!sm750_dev->accel_off) {
263 		/* set 2d engine pixel format according to mode bpp */
264 		switch (var->bits_per_pixel) {
265 		case 8:
266 			fmt = 0;
267 			break;
268 		case 16:
269 			fmt = 1;
270 			break;
271 		case 32:
272 		default:
273 			fmt = 2;
274 			break;
275 		}
276 		hw_set2dformat(&sm750_dev->accel, fmt);
277 	}
278 
279 	/* set timing */
280 	modparm.pixel_clock = ps_to_hz(var->pixclock);
281 	modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? POS:NEG;
282 	modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? POS:NEG;
283 	modparm.clock_phase_polarity = (var->sync & FB_SYNC_COMP_HIGH_ACT) ? POS:NEG;
284 	modparm.horizontal_display_end = var->xres;
285 	modparm.horizontal_sync_width = var->hsync_len;
286 	modparm.horizontal_sync_start = var->xres + var->right_margin;
287 	modparm.horizontal_total = var->xres + var->left_margin + var->right_margin + var->hsync_len;
288 	modparm.vertical_display_end = var->yres;
289 	modparm.vertical_sync_height = var->vsync_len;
290 	modparm.vertical_sync_start = var->yres + var->lower_margin;
291 	modparm.vertical_total = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
292 
293 	/* choose pll */
294 	if (crtc->channel != sm750_secondary)
295 		clock = PRIMARY_PLL;
296 	else
297 		clock = SECONDARY_PLL;
298 
299 	pr_debug("Request pixel clock = %lu\n", modparm.pixel_clock);
300 	ret = ddk750_setModeTiming(&modparm, clock);
301 	if (ret) {
302 		pr_err("Set mode timing failed\n");
303 		goto exit;
304 	}
305 
306 	if (crtc->channel != sm750_secondary) {
307 		/* set pitch, offset ,width,start address ,etc... */
308 		POKE32(PANEL_FB_ADDRESS,
309 		       crtc->oScreen & PANEL_FB_ADDRESS_ADDRESS_MASK);
310 
311 		reg = var->xres * (var->bits_per_pixel >> 3);
312 		/* crtc->channel is not equal to par->index on numeric,be aware of that */
313 		reg = ALIGN(reg, crtc->line_pad);
314 		reg = (reg << PANEL_FB_WIDTH_WIDTH_SHIFT) &
315 		       PANEL_FB_WIDTH_WIDTH_MASK;
316 		reg |= (fix->line_length & PANEL_FB_WIDTH_OFFSET_MASK);
317 		POKE32(PANEL_FB_WIDTH, reg);
318 
319 		reg = ((var->xres - 1) << PANEL_WINDOW_WIDTH_WIDTH_SHIFT) &
320 		       PANEL_WINDOW_WIDTH_WIDTH_MASK;
321 		reg |= (var->xoffset & PANEL_WINDOW_WIDTH_X_MASK);
322 		POKE32(PANEL_WINDOW_WIDTH, reg);
323 
324 		reg = ((var->yres_virtual - 1) <<
325 		       PANEL_WINDOW_HEIGHT_HEIGHT_SHIFT);
326 		reg &= PANEL_WINDOW_HEIGHT_HEIGHT_MASK;
327 		reg |= (var->yoffset & PANEL_WINDOW_HEIGHT_Y_MASK);
328 		POKE32(PANEL_WINDOW_HEIGHT, reg);
329 
330 		POKE32(PANEL_PLANE_TL, 0);
331 
332 		reg = ((var->yres - 1) << PANEL_PLANE_BR_BOTTOM_SHIFT) &
333 		       PANEL_PLANE_BR_BOTTOM_MASK;
334 		reg |= ((var->xres - 1) & PANEL_PLANE_BR_RIGHT_MASK);
335 		POKE32(PANEL_PLANE_BR, reg);
336 
337 		/* set pixel format */
338 		reg = PEEK32(PANEL_DISPLAY_CTRL);
339 		POKE32(PANEL_DISPLAY_CTRL, reg | (var->bits_per_pixel >> 4));
340 	} else {
341 		/* not implemented now */
342 		POKE32(CRT_FB_ADDRESS, crtc->oScreen);
343 		reg = var->xres * (var->bits_per_pixel >> 3);
344 		/* crtc->channel is not equal to par->index on numeric,be aware of that */
345 		reg = ALIGN(reg, crtc->line_pad) << CRT_FB_WIDTH_WIDTH_SHIFT;
346 		reg &= CRT_FB_WIDTH_WIDTH_MASK;
347 		reg |= (fix->line_length & CRT_FB_WIDTH_OFFSET_MASK);
348 		POKE32(CRT_FB_WIDTH, reg);
349 
350 		/* SET PIXEL FORMAT */
351 		reg = PEEK32(CRT_DISPLAY_CTRL);
352 		reg |= ((var->bits_per_pixel >> 4) &
353 			CRT_DISPLAY_CTRL_FORMAT_MASK);
354 		POKE32(CRT_DISPLAY_CTRL, reg);
355 
356 	}
357 
358 
359 exit:
360 	return ret;
361 }
362 
363 int hw_sm750_setColReg(struct lynxfb_crtc *crtc, ushort index,
364 								ushort red, ushort green, ushort blue)
365 {
366 	static unsigned int add[] = {PANEL_PALETTE_RAM, CRT_PALETTE_RAM};
367 
368 	POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
369 	return 0;
370 }
371 
372 int hw_sm750le_setBLANK(struct lynxfb_output *output, int blank)
373 {
374 	int dpms, crtdb;
375 
376 	switch (blank) {
377 	case FB_BLANK_UNBLANK:
378 		dpms = CRT_DISPLAY_CTRL_DPMS_0;
379 		crtdb = 0;
380 		break;
381 	case FB_BLANK_NORMAL:
382 		dpms = CRT_DISPLAY_CTRL_DPMS_0;
383 		crtdb = CRT_DISPLAY_CTRL_BLANK;
384 		break;
385 	case FB_BLANK_VSYNC_SUSPEND:
386 		dpms = CRT_DISPLAY_CTRL_DPMS_2;
387 		crtdb = CRT_DISPLAY_CTRL_BLANK;
388 		break;
389 	case FB_BLANK_HSYNC_SUSPEND:
390 		dpms = CRT_DISPLAY_CTRL_DPMS_1;
391 		crtdb = CRT_DISPLAY_CTRL_BLANK;
392 		break;
393 	case FB_BLANK_POWERDOWN:
394 		dpms = CRT_DISPLAY_CTRL_DPMS_3;
395 		crtdb = CRT_DISPLAY_CTRL_BLANK;
396 		break;
397 	default:
398 		return -EINVAL;
399 	}
400 
401 	if (output->paths & sm750_crt) {
402 		unsigned int val;
403 
404 		val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_DPMS_MASK;
405 		POKE32(CRT_DISPLAY_CTRL, val | dpms);
406 
407 		val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK;
408 		POKE32(CRT_DISPLAY_CTRL, val | crtdb);
409 	}
410 	return 0;
411 }
412 
413 int hw_sm750_setBLANK(struct lynxfb_output *output, int blank)
414 {
415 	unsigned int dpms, pps, crtdb;
416 
417 	dpms = pps = crtdb = 0;
418 
419 	switch (blank) {
420 	case FB_BLANK_UNBLANK:
421 		pr_debug("flag = FB_BLANK_UNBLANK\n");
422 		dpms = SYSTEM_CTRL_DPMS_VPHP;
423 		pps = PANEL_DISPLAY_CTRL_DATA;
424 		break;
425 	case FB_BLANK_NORMAL:
426 		pr_debug("flag = FB_BLANK_NORMAL\n");
427 		dpms = SYSTEM_CTRL_DPMS_VPHP;
428 		crtdb = CRT_DISPLAY_CTRL_BLANK;
429 		break;
430 	case FB_BLANK_VSYNC_SUSPEND:
431 		dpms = SYSTEM_CTRL_DPMS_VNHP;
432 		crtdb = CRT_DISPLAY_CTRL_BLANK;
433 		break;
434 	case FB_BLANK_HSYNC_SUSPEND:
435 		dpms = SYSTEM_CTRL_DPMS_VPHN;
436 		crtdb = CRT_DISPLAY_CTRL_BLANK;
437 		break;
438 	case FB_BLANK_POWERDOWN:
439 		dpms = SYSTEM_CTRL_DPMS_VNHN;
440 		crtdb = CRT_DISPLAY_CTRL_BLANK;
441 		break;
442 	}
443 
444 	if (output->paths & sm750_crt) {
445 		unsigned int val = PEEK32(SYSTEM_CTRL) & ~SYSTEM_CTRL_DPMS_MASK;
446 
447 		POKE32(SYSTEM_CTRL, val | dpms);
448 
449 		val = PEEK32(CRT_DISPLAY_CTRL) & ~CRT_DISPLAY_CTRL_BLANK;
450 		POKE32(CRT_DISPLAY_CTRL, val | crtdb);
451 	}
452 
453 	if (output->paths & sm750_panel) {
454 		unsigned int val = PEEK32(PANEL_DISPLAY_CTRL);
455 
456 		val &= ~PANEL_DISPLAY_CTRL_DATA;
457 		val |= pps;
458 		POKE32(PANEL_DISPLAY_CTRL, val);
459 	}
460 
461 	return 0;
462 }
463 
464 
465 void hw_sm750_initAccel(struct sm750_dev *sm750_dev)
466 {
467 	u32 reg;
468 
469 	enable2DEngine(1);
470 
471 	if (getChipType() == SM750LE) {
472 		reg = PEEK32(DE_STATE1);
473 		reg |= DE_STATE1_DE_ABORT;
474 		POKE32(DE_STATE1, reg);
475 
476 		reg = PEEK32(DE_STATE1);
477 		reg &= ~DE_STATE1_DE_ABORT;
478 		POKE32(DE_STATE1, reg);
479 
480 	} else {
481 		/* engine reset */
482 		reg = PEEK32(SYSTEM_CTRL);
483 		reg |= SYSTEM_CTRL_DE_ABORT;
484 		POKE32(SYSTEM_CTRL, reg);
485 
486 		reg = PEEK32(SYSTEM_CTRL);
487 		reg &= ~SYSTEM_CTRL_DE_ABORT;
488 		POKE32(SYSTEM_CTRL, reg);
489 	}
490 
491 	/* call 2d init */
492 	sm750_dev->accel.de_init(&sm750_dev->accel);
493 }
494 
495 int hw_sm750le_deWait(void)
496 {
497 	int i = 0x10000000;
498 	unsigned int mask = DE_STATE2_DE_STATUS_BUSY | DE_STATE2_DE_FIFO_EMPTY |
499 		DE_STATE2_DE_MEM_FIFO_EMPTY;
500 
501 	while (i--) {
502 		unsigned int val = PEEK32(DE_STATE2);
503 
504 		if ((val & mask) ==
505 		    (DE_STATE2_DE_FIFO_EMPTY | DE_STATE2_DE_MEM_FIFO_EMPTY))
506 			return 0;
507 	}
508 	/* timeout error */
509 	return -1;
510 }
511 
512 
513 int hw_sm750_deWait(void)
514 {
515 	int i = 0x10000000;
516 	unsigned int mask = SYSTEM_CTRL_DE_STATUS_BUSY |
517 		SYSTEM_CTRL_DE_FIFO_EMPTY |
518 		SYSTEM_CTRL_DE_MEM_FIFO_EMPTY;
519 
520 	while (i--) {
521 		unsigned int val = PEEK32(SYSTEM_CTRL);
522 
523 		if ((val & mask) ==
524 		    (SYSTEM_CTRL_DE_FIFO_EMPTY | SYSTEM_CTRL_DE_MEM_FIFO_EMPTY))
525 			return 0;
526 	}
527 	/* timeout error */
528 	return -1;
529 }
530 
531 int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
532 	const struct fb_var_screeninfo *var,
533 	const struct fb_info *info)
534 {
535 	uint32_t total;
536 	/* check params */
537 	if ((var->xoffset + var->xres > var->xres_virtual) ||
538 	    (var->yoffset + var->yres > var->yres_virtual)) {
539 		return -EINVAL;
540 	}
541 
542 	total = var->yoffset * info->fix.line_length +
543 		((var->xoffset * var->bits_per_pixel) >> 3);
544 	total += crtc->oScreen;
545 	if (crtc->channel == sm750_primary) {
546 		POKE32(PANEL_FB_ADDRESS,
547 		       PEEK32(PANEL_FB_ADDRESS) |
548 		       (total & PANEL_FB_ADDRESS_ADDRESS_MASK));
549 	} else {
550 		POKE32(CRT_FB_ADDRESS,
551 		       PEEK32(CRT_FB_ADDRESS) |
552 		       (total & CRT_FB_ADDRESS_ADDRESS_MASK));
553 	}
554 	return 0;
555 }
556