1
#include <linux/module.h>
3
#include <linux/types.h>
4
#include <linux/errno.h>
5
#include <linux/smp_lock.h>
6
#include <linux/kernel.h>
7
#include <linux/major.h>
8
#include <linux/slab.h>
10
#include <linux/mman.h>
12
#include <linux/init.h>
13
#include <linux/linux_logo.h>
14
#include <linux/proc_fs.h>
15
#include <linux/seq_file.h>
16
#include <linux/console.h>
17
#include <linux/kmod.h>
18
#include <linux/err.h>
19
#include <linux/device.h>
20
#include <linux/efi.h>
23
#include <video/dovefb.h>
24
#include <video/dovefbreg.h>
25
#include <video/dovedcon.h>
26
#include <video/dovefb_display.h>
29
* LCD controll register physical address
31
static unsigned int lcd_regbase;
32
//module_param(lcd_regbase, uint, 0xf1810000);
33
module_param(lcd_regbase, uint, 0);
34
MODULE_PARM_DESC(lcd_regbase, "LCD controller register base");
37
* 0 means lcd0 = regbase + 0x0, lcd1 = regbase + 0x10000;
38
* 1 means lcd0 = regbase + 0x10000, lcd1 = regbase + 0x0;
40
static unsigned int lcdseq;
41
module_param(lcdseq, uint, 1);
42
MODULE_PARM_DESC(lcdseq, "LCD sequence");
44
extern struct display_settings lcd_config;
45
extern struct class *fb_class;
46
static void *lcd0_regbase;
47
static void *lcd1_regbase;
48
static void *dcon_regbase;
50
static void set_graphics_start(struct fb_info *fi, int xoffset, int yoffset,
51
struct fb_info *newfi)
53
struct dovefb_layer_info *dfli = fi->par;
54
struct fb_var_screeninfo *var = &fi->var;
60
fi->var.xres_virtual = newfi->var.xres_virtual;
62
x = readl(dfli->reg_base + LCD_CFG_GRA_PITCH);
63
x = (x & ~0xFFFF) | ((var->xres_virtual * var->bits_per_pixel) >> 3);
64
writel(x, dfli->reg_base + LCD_CFG_GRA_PITCH);
66
pixel_offset = (yoffset * var->xres_virtual) + xoffset;
69
struct dovefb_layer_info *newdfli = newfi->par;
70
addr = newdfli->fb_start_dma + (pixel_offset * (var->bits_per_pixel >> 3));
72
addr = dfli->fb_start_dma + (pixel_offset * (var->bits_per_pixel >> 3));
74
writel(addr, dfli->reg_base + LCD_CFG_GRA_START_ADDR0);
77
static void dcon_portb(uint mode)
81
/* enable lcd0 pass to PortB */
82
ctrl0 = readl(dcon_regbase+DCON_CTRL0);
85
writel(ctrl0, dcon_regbase+DCON_CTRL0);
89
static void set_back(void)
92
struct dovefb_layer_info *dfli0_gfx = lcd_config.lcd0_gfx->par;
93
//struct dovefb_layer_info *dfli0_vid = lcd_config.lcd0_vid->par;
94
struct dovefb_layer_info *dfli1_gfx = lcd_config.lcd1_gfx->par;
95
//struct dovefb_layer_info *dfli1_vid = lcd_config.lcd1_vid->par;
97
struct fb_var_screeninfo *var0_gfx = &lcd_config.lcd0_gfx->var;
98
//struct fb_var_screeninfo *var0_vid = &lcd_config.lcd0_vid->var;
99
struct fb_var_screeninfo *var1_gfx = &lcd_config.lcd1_gfx->var;
100
//struct fb_var_screeninfo *var1_vid = &lcd_config.lcd1_vid->var;
102
/* set lcd0 src scan line */
103
writel((var0_gfx->yres << 16) | (var0_gfx->xres),
104
dfli0_gfx->reg_base + LCD_SPU_GRA_HPXL_VLN);
106
/* set lcd1 src scan line */
107
writel((var1_gfx->yres << 16) | (var1_gfx->xres),
108
dfli1_gfx->reg_base + LCD_SPU_GRA_HPXL_VLN);
110
/* set lcd1 refresh whole area. */
111
set_graphics_start(lcd_config.lcd1_gfx,
114
lcd_config.lcd0_gfx);
117
static int setup_display(struct display_settings *config)
120
//struct dovefb_layer_info *dfli0_gfx = lcd_config.lcd0_gfx->par;
121
//struct dovefb_layer_info *dfli0_vid = lcd_config.lcd0_vid->par;
122
//struct dovefb_layer_info *dfli1_gfx = lcd_config.lcd1_gfx->par;
123
//struct dovefb_layer_info *dfli1_vid = lcd_config.lcd1_vid->par;
125
//struct fb_var_screeninfo *var0_gfx = &lcd_config.lcd0_gfx->var;
126
//struct fb_var_screeninfo *var0_vid = &lcd_config.lcd0_vid->var;
127
struct fb_var_screeninfo *var1_gfx = &lcd_config.lcd1_gfx->var;
128
//struct fb_var_screeninfo *var1_vid = &lcd_config.lcd1_vid->var;
133
switch (config->display_mode) {
134
case DISPLAY_EXTENDED:
136
printk(KERN_INFO "configure to EXTENDED Mode\n");
137
/* set lcd0 src scan line */
138
// writel((var0_gfx->yres << 16) | (var0_gfx->xres*lcd_config.extend_ratio/4),
139
// dfli0_gfx->reg_base + LCD_SPU_GRA_HPXL_VLN);
141
/* set lcd1 src scan line */
142
// writel((var1_gfx->yres << 16) | (var1_gfx->xres*lcd_config.extend_ratio/4),
143
// dfli1_gfx->reg_base + LCD_SPU_GRA_HPXL_VLN);
145
/* set lcd1 refresh second half portion. */
146
set_graphics_start(lcd_config.lcd1_gfx,
147
var1_gfx->xoffset+(var1_gfx->xres),
148
var1_gfx->yoffset, lcd_config.lcd0_gfx);
151
printk(KERN_INFO "configure to NORMAL Mode\n");
154
set_graphics_start(lcd_config.lcd1_gfx,
156
var1_gfx->yoffset, 0);
158
/* switch lcd1's buffer addr back. */
161
printk(KERN_INFO "configure to CLONE Mode\n");
164
#if 0 // test code, set lcd0 to dump16bit mode.
167
case DISPLAY_DUALVIEW:
168
printk(KERN_INFO "configure to DUALVIEW Mode\n");
180
static long display_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
182
struct display_settings config;
184
case 0: /* configure display mode. */
185
printk(KERN_INFO "driver set display config.\n");
187
/* Get data from user space. */
188
if (copy_from_user(&config, (void *)arg, sizeof(struct display_settings)))
191
lcd_config.display_mode = config.display_mode;
192
lcd_config.extend_ratio = config.extend_ratio;
195
printk("Get mode = %d\n", lcd_config.display_mode);
196
printk("Get ratio = %d\n", lcd_config.extend_ratio);
201
//printk(KERN_INFO "case 0 .... driver set display config.\n");
202
setup_display(&lcd_config);
205
/* get display configuration. */
206
printk(KERN_INFO "get display config.\n");
207
if (copy_to_user((void *)arg, &lcd_config, sizeof(struct display_settings)))
211
printk(KERN_ERR "Unknown command\n");
217
static const struct file_operations display_fops = {
218
.owner = THIS_MODULE,
219
.unlocked_ioctl = display_ioctl,
224
dovefb_display_init(void)
229
printk(KERN_INFO "lcd_regbase = 0x%08x\n", lcd_regbase);
230
printk(KERN_INFO "lcdseq = %d, 1^lcdseq = %d\n", lcdseq, 1^lcdseq);
231
printk(KERN_INFO "lcdseq = %d, 0^lcdseq = %d\n", lcdseq, 0^lcdseq);
233
printk(KERN_WARNING "dovefb_display_init\n");
235
/* register character. */
236
if (register_chrdev(30, "display tools", &display_fops))
237
printk("unable to get major %d for fb devs\n", 30);
240
/* remap to ctrl registers. */
241
lcd0_regbase = ioremap_nocache( lcd_regbase + (0x10000*(0^lcdseq)), (0x10000 - 1));
242
lcd1_regbase = ioremap_nocache( lcd_regbase + (0x10000*(1^lcdseq)), (0x10000 - 1));
243
dcon_regbase = ioremap_nocache( lcd_regbase + 0x20000, (0x10000 - 1));
245
x = readl( lcd0_regbase + 0x104 );
246
printk(KERN_INFO "debug lcd0 reg 0x104 = 0x%08x\n", x);
247
x = readl( lcd1_regbase + 0x108 );
248
printk(KERN_INFO "debug lcd0 reg 0x104 = 0x%08x\n", x);
249
x = readl( dcon_regbase + 0x000 );
250
printk(KERN_INFO "debug dcon reg 0x000 = 0x%08x\n", x);
254
printk(KERN_WARNING "dovefb_display driver init ok.\n");
259
dovefb_display_exit(void)
261
iounmap(lcd0_regbase);
262
iounmap(lcd1_regbase);
263
iounmap(dcon_regbase);
264
unregister_chrdev(30, "display tools");
265
printk(KERN_WARNING "dovefb_display driver unload OK.\n");
268
module_init(dovefb_display_init);
269
module_exit(dovefb_display_exit);
271
MODULE_LICENSE("GPL");
272
MODULE_DESCRIPTION("Display mode driver");