blob: 131125ca57373b6cb58d9781e34b230e275c3a77 [file] [log] [blame]
Sudip Mukherjee81dee672015-03-03 16:21:06 +05301#include <linux/version.h>
2#include<linux/module.h>
3#include<linux/kernel.h>
4#include<linux/errno.h>
5#include<linux/string.h>
6#include<linux/mm.h>
7#include<linux/slab.h>
8#include<linux/delay.h>
9#include<linux/fb.h>
10#include<linux/ioport.h>
11#include<linux/init.h>
12#include<linux/pci.h>
13#include<linux/vmalloc.h>
14#include<linux/pagemap.h>
15#include <linux/console.h>
16#ifdef CONFIG_MTRR
17#include <asm/mtrr.h>
18#endif
19#include<linux/platform_device.h>
20#include<linux/screen_info.h>
21
22#include "sm750.h"
23#include "sm750_hw.h"
24#include "ddk750.h"
25#include "sm750_accel.h"
26
Somya Anandd2a60372015-03-12 21:48:45 +053027int hw_sm750_map(struct lynx_share* share, struct pci_dev* pdev)
Sudip Mukherjee81dee672015-03-03 16:21:06 +053028{
29 int ret;
30 struct sm750_share * spec_share;
31
32
Isaac Assegaibdec7772015-06-02 03:14:25 -070033 spec_share = container_of(share, struct sm750_share, share);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053034 ret = 0;
35
Somya Anandd2a60372015-03-12 21:48:45 +053036 share->vidreg_start = pci_resource_start(pdev, 1);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053037 share->vidreg_size = MB(2);
38
Sudip Mukherjeee9363512015-03-10 14:15:35 +053039 pr_info("mmio phyAddr = %lx\n", share->vidreg_start);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053040
41 /* reserve the vidreg space of smi adaptor
42 * if you do this, u need to add release region code
43 * in lynxfb_remove, or memory will not be mapped again
44 * successfully
45 * */
46
Somya Anandd2a60372015-03-12 21:48:45 +053047 if((ret = pci_request_region(pdev, 1, "sm750fb")))
Sudip Mukherjee81dee672015-03-03 16:21:06 +053048 {
49 pr_err("Can not request PCI regions.\n");
50 goto exit;
51 }
52
53 /* now map mmio and vidmem*/
Somya Anandd2a60372015-03-12 21:48:45 +053054 share->pvReg = ioremap_nocache(share->vidreg_start, share->vidreg_size);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053055 if(!share->pvReg){
56 pr_err("mmio failed\n");
57 ret = -EFAULT;
58 goto exit;
59 }else{
Somya Anandd2a60372015-03-12 21:48:45 +053060 pr_info("mmio virtual addr = %p\n", share->pvReg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053061 }
62
63
64 share->accel.dprBase = share->pvReg + DE_BASE_ADDR_TYPE1;
65 share->accel.dpPortBase = share->pvReg + DE_PORT_ADDR_TYPE1;
66
Isaac Assegaibdec7772015-06-02 03:14:25 -070067 ddk750_set_mmio(share->pvReg, share->devid, share->revid);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053068
Somya Anandd2a60372015-03-12 21:48:45 +053069 share->vidmem_start = pci_resource_start(pdev, 0);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053070 /* don't use pdev_resource[x].end - resource[x].start to
71 * calculate the resource size,its only the maximum available
72 * size but not the actual size,use
73 * @hw_sm750_getVMSize function can be safe.
74 * */
75 share->vidmem_size = hw_sm750_getVMSize(share);
Sudip Mukherjeee9363512015-03-10 14:15:35 +053076 pr_info("video memory phyAddr = %lx, size = %u bytes\n",
Somya Anandd2a60372015-03-12 21:48:45 +053077 share->vidmem_start, share->vidmem_size);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053078
79 /* reserve the vidmem space of smi adaptor */
80#if 0
Isaac Assegaibdec7772015-06-02 03:14:25 -070081 if((ret = pci_request_region(pdev, 0, _moduleName_)))
Sudip Mukherjee81dee672015-03-03 16:21:06 +053082 {
83 pr_err("Can not request PCI regions.\n");
84 goto exit;
85 }
86#endif
87
Luis R. Rodriguez2e043a92015-05-14 07:07:55 -070088 share->pvMem = ioremap_wc(share->vidmem_start, share->vidmem_size);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053089
90 if(!share->pvMem){
91 pr_err("Map video memory failed\n");
92 ret = -EFAULT;
93 goto exit;
94 }else{
Somya Anandd2a60372015-03-12 21:48:45 +053095 pr_info("video memory vaddr = %p\n", share->pvMem);
Sudip Mukherjee81dee672015-03-03 16:21:06 +053096 }
97exit:
98 return ret;
99}
100
101
102
Somya Anandd2a60372015-03-12 21:48:45 +0530103int hw_sm750_inithw(struct lynx_share* share, struct pci_dev * pdev)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530104{
105 struct sm750_share * spec_share;
106 struct init_status * parm;
107
Isaac Assegaibdec7772015-06-02 03:14:25 -0700108 spec_share = container_of(share, struct sm750_share, share);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530109 parm = &spec_share->state.initParm;
110 if(parm->chip_clk == 0)
111 parm->chip_clk = (getChipType() == SM750LE)?
112 DEFAULT_SM750LE_CHIP_CLOCK :
113 DEFAULT_SM750_CHIP_CLOCK;
114
115 if(parm->mem_clk == 0)
116 parm->mem_clk = parm->chip_clk;
117 if(parm->master_clk == 0)
118 parm->master_clk = parm->chip_clk/3;
119
120 ddk750_initHw((initchip_param_t *)&spec_share->state.initParm);
121 /* for sm718,open pci burst */
122 if(share->devid == 0x718){
123 POKE32(SYSTEM_CTRL,
Somya Anandd2a60372015-03-12 21:48:45 +0530124 FIELD_SET(PEEK32(SYSTEM_CTRL), SYSTEM_CTRL, PCI_BURST, ON));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530125 }
126
127 /* sm750 use sii164, it can be setup with default value
128 * by on power, so initDVIDisp can be skipped */
129#if 0
130 ddk750_initDVIDisp();
131#endif
132
133 if(getChipType() != SM750LE)
134 {
135 /* does user need CRT ?*/
136 if(spec_share->state.nocrt){
137 POKE32(MISC_CTRL,
138 FIELD_SET(PEEK32(MISC_CTRL),
139 MISC_CTRL,
Somya Anandd2a60372015-03-12 21:48:45 +0530140 DAC_POWER, OFF));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530141 /* shut off dpms */
142 POKE32(SYSTEM_CTRL,
143 FIELD_SET(PEEK32(SYSTEM_CTRL),
144 SYSTEM_CTRL,
Somya Anandd2a60372015-03-12 21:48:45 +0530145 DPMS, VNHN));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530146 }else{
147 POKE32(MISC_CTRL,
148 FIELD_SET(PEEK32(MISC_CTRL),
149 MISC_CTRL,
Somya Anandd2a60372015-03-12 21:48:45 +0530150 DAC_POWER, ON));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530151 /* turn on dpms */
152 POKE32(SYSTEM_CTRL,
153 FIELD_SET(PEEK32(SYSTEM_CTRL),
154 SYSTEM_CTRL,
Somya Anandd2a60372015-03-12 21:48:45 +0530155 DPMS, VPHP));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530156 }
157
158 switch (spec_share->state.pnltype){
159 case sm750_doubleTFT:
160 case sm750_24TFT:
161 case sm750_dualTFT:
162 POKE32(PANEL_DISPLAY_CTRL,
163 FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL),
164 PANEL_DISPLAY_CTRL,
165 TFT_DISP,
166 spec_share->state.pnltype));
167 break;
168 }
169 }else{
170 /* for 750LE ,no DVI chip initilization makes Monitor no signal */
171 /* Set up GPIO for software I2C to program DVI chip in the
172 Xilinx SP605 board, in order to have video signal.
173 */
Isaac Assegaibdec7772015-06-02 03:14:25 -0700174 swI2CInit(0, 1);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530175
176
177 /* Customer may NOT use CH7301 DVI chip, which has to be
178 initialized differently.
179 */
180 if (swI2CReadReg(0xec, 0x4a) == 0x95)
181 {
182 /* The following register values for CH7301 are from
183 Chrontel app note and our experiment.
184 */
185 pr_info("yes,CH7301 DVI chip found\n");
186 swI2CWriteReg(0xec, 0x1d, 0x16);
187 swI2CWriteReg(0xec, 0x21, 0x9);
188 swI2CWriteReg(0xec, 0x49, 0xC0);
189 pr_info("okay,CH7301 DVI chip setup done\n");
190 }
191 }
192
193 /* init 2d engine */
194 if(!share->accel_off){
195 hw_sm750_initAccel(share);
196// share->accel.de_wait = hw_sm750_deWait;
197 }
198
199 return 0;
200}
201
202
203resource_size_t hw_sm750_getVMSize(struct lynx_share * share)
204{
205 resource_size_t ret;
206
207 ret = ddk750_getVMSize();
208 return ret;
209}
210
211
212
Somya Anandd2a60372015-03-12 21:48:45 +0530213int hw_sm750_output_checkMode(struct lynxfb_output* output, struct fb_var_screeninfo* var)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530214{
215
216 return 0;
217}
218
219
220int hw_sm750_output_setMode(struct lynxfb_output* output,
Somya Anandd2a60372015-03-12 21:48:45 +0530221 struct fb_var_screeninfo* var, struct fb_fix_screeninfo* fix)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530222{
223 int ret;
224 disp_output_t dispSet;
225 int channel;
226
227 ret = 0;
228 dispSet = 0;
229 channel = *output->channel;
230
231
232 if(getChipType() != SM750LE){
233 if(channel == sm750_primary){
234 pr_info("primary channel\n");
235 if(output->paths & sm750_panel)
236 dispSet |= do_LCD1_PRI;
237 if(output->paths & sm750_crt)
238 dispSet |= do_CRT_PRI;
239
240 }else{
241 pr_info("secondary channel\n");
242 if(output->paths & sm750_panel)
243 dispSet |= do_LCD1_SEC;
244 if(output->paths & sm750_crt)
245 dispSet |= do_CRT_SEC;
246
247 }
248 ddk750_setLogicalDispOut(dispSet);
249 }else{
250 /* just open DISPLAY_CONTROL_750LE register bit 3:0*/
251 u32 reg;
252 reg = PEEK32(DISPLAY_CONTROL_750LE);
253 reg |= 0xf;
Somya Anandd2a60372015-03-12 21:48:45 +0530254 POKE32(DISPLAY_CONTROL_750LE, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530255 }
256
257 pr_info("ddk setlogicdispout done \n");
258 return ret;
259}
260
261void hw_sm750_output_clear(struct lynxfb_output* output)
262{
263
264 return;
265}
266
Somya Anandd2a60372015-03-12 21:48:45 +0530267int hw_sm750_crtc_checkMode(struct lynxfb_crtc* crtc, struct fb_var_screeninfo* var)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530268{
269 struct lynx_share * share;
270
271
Isaac Assegaibdec7772015-06-02 03:14:25 -0700272 share = container_of(crtc, struct lynxfb_par, crtc)->share;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530273
274 switch (var->bits_per_pixel){
275 case 8:
276 case 16:
277 break;
278 case 32:
Sudip Mukherjee62fa8e12015-03-10 14:15:37 +0530279 if (share->revid == SM750LE_REVISION_ID) {
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530280 pr_debug("750le do not support 32bpp\n");
281 return -EINVAL;
282 }
283 break;
284 default:
285 return -EINVAL;
286
287 }
288
289 return 0;
290}
291
292
293/*
294 set the controller's mode for @crtc charged with @var and @fix parameters
295*/
296int hw_sm750_crtc_setMode(struct lynxfb_crtc* crtc,
297 struct fb_var_screeninfo* var,
298 struct fb_fix_screeninfo* fix)
299{
Isaac Assegaibdec7772015-06-02 03:14:25 -0700300 int ret, fmt;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530301 u32 reg;
302 mode_parameter_t modparm;
303 clock_type_t clock;
304 struct lynx_share * share;
305 struct lynxfb_par * par;
306
307
308 ret = 0;
Somya Anandd2a60372015-03-12 21:48:45 +0530309 par = container_of(crtc, struct lynxfb_par, crtc);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530310 share = par->share;
311#if 1
312 if(!share->accel_off){
313 /* set 2d engine pixel format according to mode bpp */
314 switch(var->bits_per_pixel){
315 case 8:
316 fmt = 0;
317 break;
318 case 16:
319 fmt = 1;
320 break;
321 case 32:
322 default:
323 fmt = 2;
324 break;
325 }
Somya Anandd2a60372015-03-12 21:48:45 +0530326 hw_set2dformat(&share->accel, fmt);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530327 }
328#endif
329
330 /* set timing */
331// modparm.pixel_clock = PS_TO_HZ(var->pixclock);
332 modparm.pixel_clock = ps_to_hz(var->pixclock);
333 modparm.vertical_sync_polarity = (var->sync & FB_SYNC_HOR_HIGH_ACT) ? POS:NEG;
334 modparm.horizontal_sync_polarity = (var->sync & FB_SYNC_VERT_HIGH_ACT) ? POS:NEG;
335 modparm.clock_phase_polarity = (var->sync& FB_SYNC_COMP_HIGH_ACT) ? POS:NEG;
336 modparm.horizontal_display_end = var->xres;
337 modparm.horizontal_sync_width = var->hsync_len;
338 modparm.horizontal_sync_start = var->xres + var->right_margin;
339 modparm.horizontal_total = var->xres + var->left_margin + var->right_margin + var->hsync_len;
340 modparm.vertical_display_end = var->yres;
341 modparm.vertical_sync_height = var->vsync_len;
342 modparm.vertical_sync_start = var->yres + var->lower_margin;
343 modparm.vertical_total = var->yres + var->upper_margin + var->lower_margin + var->vsync_len;
344
345 /* choose pll */
346 if(crtc->channel != sm750_secondary)
347 clock = PRIMARY_PLL;
348 else
349 clock = SECONDARY_PLL;
350
Somya Anandd2a60372015-03-12 21:48:45 +0530351 pr_debug("Request pixel clock = %lu\n", modparm.pixel_clock);
352 ret = ddk750_setModeTiming(&modparm, clock);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530353 if(ret){
354 pr_err("Set mode timing failed\n");
355 goto exit;
356 }
357
358 if(crtc->channel != sm750_secondary){
359 /* set pitch, offset ,width,start address ,etc... */
360 POKE32(PANEL_FB_ADDRESS,
Somya Anandd2a60372015-03-12 21:48:45 +0530361 FIELD_SET(0, PANEL_FB_ADDRESS, STATUS, CURRENT)|
362 FIELD_SET(0, PANEL_FB_ADDRESS, EXT, LOCAL)|
363 FIELD_VALUE(0, PANEL_FB_ADDRESS, ADDRESS, crtc->oScreen));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530364
365 reg = var->xres * (var->bits_per_pixel >> 3);
366 /* crtc->channel is not equal to par->index on numeric,be aware of that */
Isaac Assegaibdec7772015-06-02 03:14:25 -0700367 reg = PADDING(crtc->line_pad, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530368
369 POKE32(PANEL_FB_WIDTH,
Somya Anandd2a60372015-03-12 21:48:45 +0530370 FIELD_VALUE(0, PANEL_FB_WIDTH, WIDTH, reg)|
371 FIELD_VALUE(0, PANEL_FB_WIDTH, OFFSET, fix->line_length));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530372
373 POKE32(PANEL_WINDOW_WIDTH,
Somya Anandd2a60372015-03-12 21:48:45 +0530374 FIELD_VALUE(0, PANEL_WINDOW_WIDTH, WIDTH, var->xres -1)|
375 FIELD_VALUE(0, PANEL_WINDOW_WIDTH, X, var->xoffset));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530376
377 POKE32(PANEL_WINDOW_HEIGHT,
Somya Anandd2a60372015-03-12 21:48:45 +0530378 FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, HEIGHT, var->yres_virtual - 1)|
379 FIELD_VALUE(0, PANEL_WINDOW_HEIGHT, Y, var->yoffset));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530380
Somya Anandd2a60372015-03-12 21:48:45 +0530381 POKE32(PANEL_PLANE_TL, 0);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530382
383 POKE32(PANEL_PLANE_BR,
Somya Anandd2a60372015-03-12 21:48:45 +0530384 FIELD_VALUE(0, PANEL_PLANE_BR, BOTTOM, var->yres - 1)|
Isaac Assegaibdec7772015-06-02 03:14:25 -0700385 FIELD_VALUE(0, PANEL_PLANE_BR, RIGHT, var->xres - 1));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530386
387 /* set pixel format */
388 reg = PEEK32(PANEL_DISPLAY_CTRL);
389 POKE32(PANEL_DISPLAY_CTRL,
390 FIELD_VALUE(reg,
Somya Anandd2a60372015-03-12 21:48:45 +0530391 PANEL_DISPLAY_CTRL, FORMAT,
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530392 (var->bits_per_pixel >> 4)
393 ));
394 }else{
395 /* not implemented now */
Somya Anandd2a60372015-03-12 21:48:45 +0530396 POKE32(CRT_FB_ADDRESS, crtc->oScreen);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530397 reg = var->xres * (var->bits_per_pixel >> 3);
398 /* crtc->channel is not equal to par->index on numeric,be aware of that */
Somya Anandd2a60372015-03-12 21:48:45 +0530399 reg = PADDING(crtc->line_pad, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530400
401 POKE32(CRT_FB_WIDTH,
Somya Anandd2a60372015-03-12 21:48:45 +0530402 FIELD_VALUE(0, CRT_FB_WIDTH, WIDTH, reg)|
403 FIELD_VALUE(0, CRT_FB_WIDTH, OFFSET, fix->line_length));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530404
405 /* SET PIXEL FORMAT */
406 reg = PEEK32(CRT_DISPLAY_CTRL);
Somya Anandd2a60372015-03-12 21:48:45 +0530407 reg = FIELD_VALUE(reg, CRT_DISPLAY_CTRL, FORMAT, var->bits_per_pixel >> 4);
408 POKE32(CRT_DISPLAY_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530409
410 }
411
412
413exit:
414 return ret;
415}
416
417void hw_sm750_crtc_clear(struct lynxfb_crtc* crtc)
418{
419
420 return;
421}
422
Somya Anandd2a60372015-03-12 21:48:45 +0530423int hw_sm750_setColReg(struct lynxfb_crtc* crtc, ushort index,
424 ushort red, ushort green, ushort blue)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530425{
Isaac Assegaibdec7772015-06-02 03:14:25 -0700426 static unsigned int add[]={PANEL_PALETTE_RAM, CRT_PALETTE_RAM};
Somya Anandd2a60372015-03-12 21:48:45 +0530427 POKE32(add[crtc->channel] + index*4, (red<<16)|(green<<8)|blue);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530428 return 0;
429}
430
Somya Anandd2a60372015-03-12 21:48:45 +0530431int hw_sm750le_setBLANK(struct lynxfb_output * output, int blank){
Isaac Assegaibdec7772015-06-02 03:14:25 -0700432 int dpms, crtdb;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530433
434 switch(blank)
435 {
Isaac Assegaibdec7772015-06-02 03:14:25 -0700436#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530437 case FB_BLANK_UNBLANK:
438#else
439 case VESA_NO_BLANKING:
440#endif
441 dpms = CRT_DISPLAY_CTRL_DPMS_0;
442 crtdb = CRT_DISPLAY_CTRL_BLANK_OFF;
443 break;
Isaac Assegaibdec7772015-06-02 03:14:25 -0700444#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530445 case FB_BLANK_NORMAL:
446 dpms = CRT_DISPLAY_CTRL_DPMS_0;
447 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
448 break;
449#endif
Isaac Assegaibdec7772015-06-02 03:14:25 -0700450#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530451 case FB_BLANK_VSYNC_SUSPEND:
452#else
453 case VESA_VSYNC_SUSPEND:
454#endif
455 dpms = CRT_DISPLAY_CTRL_DPMS_2;
456 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
457 break;
Isaac Assegaibdec7772015-06-02 03:14:25 -0700458#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530459 case FB_BLANK_HSYNC_SUSPEND:
460#else
461 case VESA_HSYNC_SUSPEND:
462#endif
463 dpms = CRT_DISPLAY_CTRL_DPMS_1;
464 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
465 break;
Isaac Assegaibdec7772015-06-02 03:14:25 -0700466#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530467 case FB_BLANK_POWERDOWN:
468#else
469 case VESA_POWERDOWN:
470#endif
471 dpms = CRT_DISPLAY_CTRL_DPMS_3;
472 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
473 break;
Greg Kroah-Hartmane74ac552015-03-10 22:08:38 +0100474 default:
475 return -EINVAL;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530476 }
477
478 if(output->paths & sm750_crt){
Somya Anandd2a60372015-03-12 21:48:45 +0530479 POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, DPMS, dpms));
480 POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, BLANK, crtdb));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530481 }
482 return 0;
483}
484
Isaac Assegaibdec7772015-06-02 03:14:25 -0700485int hw_sm750_setBLANK(struct lynxfb_output* output, int blank)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530486{
Somya Anandd2a60372015-03-12 21:48:45 +0530487 unsigned int dpms, pps, crtdb;
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530488
489 dpms = pps = crtdb = 0;
490
491 switch (blank)
492 {
Isaac Assegaibdec7772015-06-02 03:14:25 -0700493#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530494 case FB_BLANK_UNBLANK:
495#else
496 case VESA_NO_BLANKING:
497#endif
498 pr_info("flag = FB_BLANK_UNBLANK \n");
499 dpms = SYSTEM_CTRL_DPMS_VPHP;
500 pps = PANEL_DISPLAY_CTRL_DATA_ENABLE;
501 crtdb = CRT_DISPLAY_CTRL_BLANK_OFF;
502 break;
Isaac Assegaibdec7772015-06-02 03:14:25 -0700503#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530504 case FB_BLANK_NORMAL:
505 pr_info("flag = FB_BLANK_NORMAL \n");
506 dpms = SYSTEM_CTRL_DPMS_VPHP;
507 pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
508 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
509 break;
510#endif
Isaac Assegaibdec7772015-06-02 03:14:25 -0700511#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530512 case FB_BLANK_VSYNC_SUSPEND:
513#else
514 case VESA_VSYNC_SUSPEND:
515#endif
516 dpms = SYSTEM_CTRL_DPMS_VNHP;
517 pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
518 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
519 break;
Isaac Assegaibdec7772015-06-02 03:14:25 -0700520#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530521 case FB_BLANK_HSYNC_SUSPEND:
522#else
523 case VESA_HSYNC_SUSPEND:
524#endif
525 dpms = SYSTEM_CTRL_DPMS_VPHN;
526 pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
527 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
528 break;
Isaac Assegaibdec7772015-06-02 03:14:25 -0700529#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 10)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530530 case FB_BLANK_POWERDOWN:
531#else
532 case VESA_POWERDOWN:
533#endif
534 dpms = SYSTEM_CTRL_DPMS_VNHN;
535 pps = PANEL_DISPLAY_CTRL_DATA_DISABLE;
536 crtdb = CRT_DISPLAY_CTRL_BLANK_ON;
537 break;
538 }
539
540 if(output->paths & sm750_crt){
541
Isaac Assegaibdec7772015-06-02 03:14:25 -0700542 POKE32(SYSTEM_CTRL, FIELD_VALUE(PEEK32(SYSTEM_CTRL), SYSTEM_CTRL, DPMS, dpms));
543 POKE32(CRT_DISPLAY_CTRL, FIELD_VALUE(PEEK32(CRT_DISPLAY_CTRL), CRT_DISPLAY_CTRL, BLANK, crtdb));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530544 }
545
546 if(output->paths & sm750_panel){
Somya Anandd2a60372015-03-12 21:48:45 +0530547 POKE32(PANEL_DISPLAY_CTRL, FIELD_VALUE(PEEK32(PANEL_DISPLAY_CTRL), PANEL_DISPLAY_CTRL, DATA, pps));
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530548 }
549
550 return 0;
551}
552
553
554void hw_sm750_initAccel(struct lynx_share * share)
555{
556 u32 reg;
557 enable2DEngine(1);
558
559 if(getChipType() == SM750LE){
560 reg = PEEK32(DE_STATE1);
Isaac Assegaibdec7772015-06-02 03:14:25 -0700561 reg = FIELD_SET(reg, DE_STATE1, DE_ABORT, ON);
562 POKE32(DE_STATE1, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530563
564 reg = PEEK32(DE_STATE1);
Isaac Assegaibdec7772015-06-02 03:14:25 -0700565 reg = FIELD_SET(reg, DE_STATE1, DE_ABORT, OFF);
Somya Anandd2a60372015-03-12 21:48:45 +0530566 POKE32(DE_STATE1, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530567
568 }else{
569 /* engine reset */
570 reg = PEEK32(SYSTEM_CTRL);
Isaac Assegaibdec7772015-06-02 03:14:25 -0700571 reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT, ON);
Somya Anandd2a60372015-03-12 21:48:45 +0530572 POKE32(SYSTEM_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530573
574 reg = PEEK32(SYSTEM_CTRL);
Isaac Assegaibdec7772015-06-02 03:14:25 -0700575 reg = FIELD_SET(reg, SYSTEM_CTRL, DE_ABORT, OFF);
Somya Anandd2a60372015-03-12 21:48:45 +0530576 POKE32(SYSTEM_CTRL, reg);
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530577 }
578
579 /* call 2d init */
580 share->accel.de_init(&share->accel);
581}
582
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900583int hw_sm750le_deWait(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530584{
585 int i=0x10000000;
586 while(i--){
587 unsigned int dwVal = PEEK32(DE_STATE2);
Somya Anandd2a60372015-03-12 21:48:45 +0530588 if((FIELD_GET(dwVal, DE_STATE2, DE_STATUS) == DE_STATE2_DE_STATUS_IDLE) &&
589 (FIELD_GET(dwVal, DE_STATE2, DE_FIFO) == DE_STATE2_DE_FIFO_EMPTY) &&
590 (FIELD_GET(dwVal, DE_STATE2, DE_MEM_FIFO) == DE_STATE2_DE_MEM_FIFO_EMPTY))
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530591 {
592 return 0;
593 }
594 }
595 /* timeout error */
596 return -1;
597}
598
599
Supriya Karanth6fa7db82015-03-12 01:11:00 +0900600int hw_sm750_deWait(void)
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530601{
602 int i=0x10000000;
603 while(i--){
604 unsigned int dwVal = PEEK32(SYSTEM_CTRL);
Isaac Assegaibdec7772015-06-02 03:14:25 -0700605 if((FIELD_GET(dwVal, SYSTEM_CTRL, DE_STATUS) == SYSTEM_CTRL_DE_STATUS_IDLE) &&
606 (FIELD_GET(dwVal, SYSTEM_CTRL, DE_FIFO) == SYSTEM_CTRL_DE_FIFO_EMPTY) &&
607 (FIELD_GET(dwVal, SYSTEM_CTRL, DE_MEM_FIFO) == SYSTEM_CTRL_DE_MEM_FIFO_EMPTY))
Sudip Mukherjee81dee672015-03-03 16:21:06 +0530608 {
609 return 0;
610 }
611 }
612 /* timeout error */
613 return -1;
614}
615
616int hw_sm750_pan_display(struct lynxfb_crtc *crtc,
617 const struct fb_var_screeninfo *var,
618 const struct fb_info *info)
619{
620 uint32_t total;
621 //check params
622 if ((var->xoffset + var->xres > var->xres_virtual) ||
623 (var->yoffset + var->yres > var->yres_virtual)) {
624 return -EINVAL;
625 }
626
627 total = var->yoffset * info->fix.line_length +
628 ((var->xoffset * var->bits_per_pixel) >> 3);
629 total += crtc->oScreen;
630 if (crtc->channel == sm750_primary) {
631 POKE32(PANEL_FB_ADDRESS,
632 FIELD_VALUE(PEEK32(PANEL_FB_ADDRESS),
633 PANEL_FB_ADDRESS, ADDRESS, total));
634 } else {
635 POKE32(CRT_FB_ADDRESS,
636 FIELD_VALUE(PEEK32(CRT_FB_ADDRESS),
637 CRT_FB_ADDRESS, ADDRESS, total));
638 }
639 return 0;
640}
641