~ubuntu-branches/ubuntu/karmic/linux-mvl-dove/karmic-proposed

« back to all changes in this revision

Viewing changes to drivers/video/marvell/dovefb_display.c

  • Committer: Bazaar Package Importer
  • Author(s): Stefan Bader
  • Date: 2010-03-10 22:24:12 UTC
  • mto: (15.1.2 karmic-security)
  • mto: This revision was merged to the branch mainline in revision 18.
  • Revision ID: james.westby@ubuntu.com-20100310222412-k86m3r53jw0je7x1
Tags: upstream-2.6.31
ImportĀ upstreamĀ versionĀ 2.6.31

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
#include <linux/module.h>
2
 
 
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>
9
 
#include <linux/mm.h>
10
 
#include <linux/mman.h>
11
 
#include <linux/vt.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>
21
 
#include <linux/fb.h>
22
 
 
23
 
#include <video/dovefb.h>
24
 
#include <video/dovefbreg.h>
25
 
#include <video/dovedcon.h>
26
 
#include <video/dovefb_display.h>
27
 
 
28
 
/*
29
 
 * LCD controll register physical address
30
 
 */
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");
35
 
 
36
 
/*
37
 
 * 0 means lcd0 = regbase + 0x0, lcd1 = regbase + 0x10000;
38
 
 * 1 means lcd0 = regbase + 0x10000, lcd1 = regbase + 0x0;
39
 
 */
40
 
static unsigned int lcdseq;
41
 
module_param(lcdseq, uint, 1);
42
 
MODULE_PARM_DESC(lcdseq, "LCD sequence");
43
 
 
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;
49
 
 
50
 
static void set_graphics_start(struct fb_info *fi, int xoffset, int yoffset,
51
 
        struct fb_info *newfi)
52
 
{
53
 
        struct dovefb_layer_info *dfli = fi->par;
54
 
        struct fb_var_screeninfo *var = &fi->var;
55
 
        int pixel_offset;
56
 
        unsigned long addr;
57
 
        unsigned int x;
58
 
 
59
 
        if (newfi) {
60
 
                fi->var.xres_virtual = newfi->var.xres_virtual;
61
 
 
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);
65
 
        }
66
 
        pixel_offset = (yoffset * var->xres_virtual) + xoffset;
67
 
 
68
 
        if (newfi) {
69
 
                struct dovefb_layer_info *newdfli = newfi->par;
70
 
                addr = newdfli->fb_start_dma + (pixel_offset * (var->bits_per_pixel >> 3));
71
 
        } else
72
 
                addr = dfli->fb_start_dma + (pixel_offset * (var->bits_per_pixel >> 3));
73
 
 
74
 
        writel(addr, dfli->reg_base + LCD_CFG_GRA_START_ADDR0);
75
 
}
76
 
 
77
 
static void dcon_portb(uint mode)
78
 
{
79
 
        unsigned int ctrl0;
80
 
 
81
 
        /* enable lcd0 pass to PortB */
82
 
        ctrl0 = readl(dcon_regbase+DCON_CTRL0);
83
 
        ctrl0 &= ~(0x3 << 8);
84
 
        ctrl0 |= (mode << 8);
85
 
        writel(ctrl0, dcon_regbase+DCON_CTRL0);
86
 
 
87
 
}
88
 
 
89
 
static void set_back(void)
90
 
{
91
 
        //uint x;
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;
96
 
 
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;
101
 
 
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);
105
 
 
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);
109
 
        
110
 
        /* set lcd1 refresh whole area. */
111
 
        set_graphics_start(lcd_config.lcd1_gfx,
112
 
                var1_gfx->xoffset,
113
 
                var1_gfx->yoffset,
114
 
                lcd_config.lcd0_gfx);
115
 
}
116
 
 
117
 
static int setup_display(struct display_settings *config)
118
 
{
119
 
        //uint x;
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;
124
 
 
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;
129
 
 
130
 
        if (!config)
131
 
                return -1;
132
 
 
133
 
        switch (config->display_mode) {
134
 
        case DISPLAY_EXTENDED:
135
 
                dcon_portb(0);
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);
140
 
 
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);
144
 
        
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);
149
 
                break;
150
 
        case DISPLAY_NORMAL:
151
 
                printk(KERN_INFO "configure to NORMAL Mode\n");
152
 
                dcon_portb(0);
153
 
                set_back();
154
 
                set_graphics_start(lcd_config.lcd1_gfx,
155
 
                        var1_gfx->xoffset,
156
 
                        var1_gfx->yoffset, 0);
157
 
        
158
 
                /* switch lcd1's buffer addr back. */
159
 
                break;
160
 
        case DISPLAY_CLONE:
161
 
                printk(KERN_INFO "configure to CLONE Mode\n");
162
 
                dcon_portb(1);
163
 
                set_back();
164
 
#if 0 // test code, set lcd0 to dump16bit mode.
165
 
#endif
166
 
                break;
167
 
        case DISPLAY_DUALVIEW:
168
 
                printk(KERN_INFO "configure to DUALVIEW Mode\n");
169
 
                dcon_portb(0);
170
 
                set_back();
171
 
                break;
172
 
        default:
173
 
                ;
174
 
        }
175
 
 
176
 
 
177
 
        return 0;
178
 
}
179
 
 
180
 
static long display_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
181
 
{
182
 
        struct display_settings config;
183
 
        switch (cmd) {
184
 
        case 0: /* configure display mode. */
185
 
                printk(KERN_INFO "driver set display config.\n");
186
 
 
187
 
                /* Get data from user space. */
188
 
                if (copy_from_user(&config, (void *)arg, sizeof(struct display_settings)))
189
 
                        return -EFAULT;
190
 
 
191
 
                lcd_config.display_mode = config.display_mode;
192
 
                lcd_config.extend_ratio = config.extend_ratio;
193
 
 
194
 
#ifdef MTL_DEBUG
195
 
                printk("Get mode = %d\n", lcd_config.display_mode);
196
 
                printk("Get ratio = %d\n", lcd_config.extend_ratio);
197
 
#endif
198
 
                /*
199
 
                 * set up lcd0
200
 
                 */
201
 
                //printk(KERN_INFO "case 0 .... driver set display config.\n");
202
 
                setup_display(&lcd_config);
203
 
                break;
204
 
        case 1:
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)))
208
 
                        return -EFAULT;
209
 
                break;
210
 
        default:
211
 
                printk(KERN_ERR "Unknown command\n");
212
 
        }
213
 
 
214
 
        return 0;
215
 
}
216
 
 
217
 
static const struct file_operations display_fops = {
218
 
        .owner =        THIS_MODULE,
219
 
        .unlocked_ioctl = display_ioctl,
220
 
};
221
 
 
222
 
 
223
 
static int __init
224
 
dovefb_display_init(void)
225
 
{
226
 
#ifdef MTL_DEBUG
227
 
        uint x;
228
 
 
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);
232
 
#endif
233
 
        printk(KERN_WARNING "dovefb_display_init\n");
234
 
 
235
 
        /* register character. */
236
 
        if (register_chrdev(30, "display tools", &display_fops))
237
 
                printk("unable to get major %d for fb devs\n", 30);
238
 
 
239
 
        if (lcd_regbase) {
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));
244
 
#ifdef MTL_DEBUG
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);
251
 
#endif
252
 
        }
253
 
 
254
 
        printk(KERN_WARNING "dovefb_display driver init ok.\n");
255
 
        return 0;
256
 
}
257
 
 
258
 
static void __exit
259
 
dovefb_display_exit(void)
260
 
{
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");
266
 
}
267
 
 
268
 
module_init(dovefb_display_init);
269
 
module_exit(dovefb_display_exit);
270
 
 
271
 
MODULE_LICENSE("GPL");
272
 
MODULE_DESCRIPTION("Display mode driver");
273