diff options
Diffstat (limited to 'drivers/video')
40 files changed, 1951 insertions, 187 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index 99c0df1c7ebf..5a5c303a6373 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig | |||
@@ -614,6 +614,21 @@ config FB_BFIN_T350MCQB | |||
614 | This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI | 614 | This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI |
615 | It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. | 615 | It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK. |
616 | 616 | ||
617 | config FB_BFIN_LQ035Q1 | ||
618 | tristate "SHARP LQ035Q1DH02 TFT LCD" | ||
619 | depends on FB && BLACKFIN && SPI | ||
620 | select FB_CFB_FILLRECT | ||
621 | select FB_CFB_COPYAREA | ||
622 | select FB_CFB_IMAGEBLIT | ||
623 | select BFIN_GPTIMERS | ||
624 | help | ||
625 | This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on | ||
626 | the Blackfin Landscape LCD EZ-Extender Card. | ||
627 | This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI | ||
628 | It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK. | ||
629 | |||
630 | To compile this driver as a module, choose M here: the | ||
631 | module will be called bfin-lq035q1-fb. | ||
617 | 632 | ||
618 | config FB_STI | 633 | config FB_STI |
619 | tristate "HP STI frame buffer device support" | 634 | tristate "HP STI frame buffer device support" |
diff --git a/drivers/video/Makefile b/drivers/video/Makefile index 0f8da331ba0f..4ecb30c4f3f2 100644 --- a/drivers/video/Makefile +++ b/drivers/video/Makefile | |||
@@ -137,6 +137,7 @@ obj-$(CONFIG_FB_EFI) += efifb.o | |||
137 | obj-$(CONFIG_FB_VGA16) += vga16fb.o | 137 | obj-$(CONFIG_FB_VGA16) += vga16fb.o |
138 | obj-$(CONFIG_FB_OF) += offb.o | 138 | obj-$(CONFIG_FB_OF) += offb.o |
139 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o | 139 | obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o |
140 | obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o | ||
140 | obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o | 141 | obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o |
141 | obj-$(CONFIG_FB_MX3) += mx3fb.o | 142 | obj-$(CONFIG_FB_MX3) += mx3fb.o |
142 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o | 143 | obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o |
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c index b7687c55fe16..2051c9dc813b 100644 --- a/drivers/video/atafb.c +++ b/drivers/video/atafb.c | |||
@@ -2245,6 +2245,9 @@ static int ext_setcolreg(unsigned int regno, unsigned int red, | |||
2245 | if (regno > 255) | 2245 | if (regno > 255) |
2246 | return 1; | 2246 | return 1; |
2247 | 2247 | ||
2248 | if (regno > 255) | ||
2249 | return 1; | ||
2250 | |||
2248 | switch (external_card_type) { | 2251 | switch (external_card_type) { |
2249 | case IS_VGA: | 2252 | case IS_VGA: |
2250 | OUTB(0x3c8, regno); | 2253 | OUTB(0x3c8, regno); |
diff --git a/drivers/video/backlight/da903x_bl.c b/drivers/video/backlight/da903x_bl.c index 7fcb0eb54c60..f2d76dae1eb3 100644 --- a/drivers/video/backlight/da903x_bl.c +++ b/drivers/video/backlight/da903x_bl.c | |||
@@ -177,7 +177,7 @@ static int da903x_backlight_resume(struct device *dev) | |||
177 | return 0; | 177 | return 0; |
178 | } | 178 | } |
179 | 179 | ||
180 | static struct dev_pm_ops da903x_backlight_pm_ops = { | 180 | static const struct dev_pm_ops da903x_backlight_pm_ops = { |
181 | .suspend = da903x_backlight_suspend, | 181 | .suspend = da903x_backlight_suspend, |
182 | .resume = da903x_backlight_resume, | 182 | .resume = da903x_backlight_resume, |
183 | }; | 183 | }; |
diff --git a/drivers/video/backlight/lcd.c b/drivers/video/backlight/lcd.c index a482dd7b0311..9b3be74cee5a 100644 --- a/drivers/video/backlight/lcd.c +++ b/drivers/video/backlight/lcd.c | |||
@@ -101,7 +101,7 @@ static ssize_t lcd_store_power(struct device *dev, | |||
101 | int power = simple_strtoul(buf, &endp, 0); | 101 | int power = simple_strtoul(buf, &endp, 0); |
102 | size_t size = endp - buf; | 102 | size_t size = endp - buf; |
103 | 103 | ||
104 | if (*endp && isspace(*endp)) | 104 | if (isspace(*endp)) |
105 | size++; | 105 | size++; |
106 | if (size != count) | 106 | if (size != count) |
107 | return -EINVAL; | 107 | return -EINVAL; |
@@ -140,7 +140,7 @@ static ssize_t lcd_store_contrast(struct device *dev, | |||
140 | int contrast = simple_strtoul(buf, &endp, 0); | 140 | int contrast = simple_strtoul(buf, &endp, 0); |
141 | size_t size = endp - buf; | 141 | size_t size = endp - buf; |
142 | 142 | ||
143 | if (*endp && isspace(*endp)) | 143 | if (isspace(*endp)) |
144 | size++; | 144 | size++; |
145 | if (size != count) | 145 | if (size != count) |
146 | return -EINVAL; | 146 | return -EINVAL; |
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/bfin-lq035q1-fb.c new file mode 100644 index 000000000000..b690c269784a --- /dev/null +++ b/drivers/video/bfin-lq035q1-fb.c | |||
@@ -0,0 +1,826 @@ | |||
1 | /* | ||
2 | * Blackfin LCD Framebuffer driver SHARP LQ035Q1DH02 | ||
3 | * | ||
4 | * Copyright 2008-2009 Analog Devices Inc. | ||
5 | * Licensed under the GPL-2 or later. | ||
6 | */ | ||
7 | |||
8 | #define DRIVER_NAME "bfin-lq035q1" | ||
9 | #define pr_fmt(fmt) DRIVER_NAME ": " fmt | ||
10 | |||
11 | #include <linux/module.h> | ||
12 | #include <linux/kernel.h> | ||
13 | #include <linux/errno.h> | ||
14 | #include <linux/string.h> | ||
15 | #include <linux/fb.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/types.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/device.h> | ||
20 | #include <linux/backlight.h> | ||
21 | #include <linux/lcd.h> | ||
22 | #include <linux/dma-mapping.h> | ||
23 | #include <linux/platform_device.h> | ||
24 | #include <linux/spi/spi.h> | ||
25 | #include <linux/dma-mapping.h> | ||
26 | |||
27 | #include <asm/blackfin.h> | ||
28 | #include <asm/irq.h> | ||
29 | #include <asm/dma.h> | ||
30 | #include <asm/portmux.h> | ||
31 | #include <asm/gptimers.h> | ||
32 | |||
33 | #include <asm/bfin-lq035q1.h> | ||
34 | |||
35 | #if defined(BF533_FAMILY) || defined(BF538_FAMILY) | ||
36 | #define TIMER_HSYNC_id TIMER1_id | ||
37 | #define TIMER_HSYNCbit TIMER1bit | ||
38 | #define TIMER_HSYNC_STATUS_TRUN TIMER_STATUS_TRUN1 | ||
39 | #define TIMER_HSYNC_STATUS_TIMIL TIMER_STATUS_TIMIL1 | ||
40 | #define TIMER_HSYNC_STATUS_TOVF TIMER_STATUS_TOVF1 | ||
41 | |||
42 | #define TIMER_VSYNC_id TIMER2_id | ||
43 | #define TIMER_VSYNCbit TIMER2bit | ||
44 | #define TIMER_VSYNC_STATUS_TRUN TIMER_STATUS_TRUN2 | ||
45 | #define TIMER_VSYNC_STATUS_TIMIL TIMER_STATUS_TIMIL2 | ||
46 | #define TIMER_VSYNC_STATUS_TOVF TIMER_STATUS_TOVF2 | ||
47 | #else | ||
48 | #define TIMER_HSYNC_id TIMER0_id | ||
49 | #define TIMER_HSYNCbit TIMER0bit | ||
50 | #define TIMER_HSYNC_STATUS_TRUN TIMER_STATUS_TRUN0 | ||
51 | #define TIMER_HSYNC_STATUS_TIMIL TIMER_STATUS_TIMIL0 | ||
52 | #define TIMER_HSYNC_STATUS_TOVF TIMER_STATUS_TOVF0 | ||
53 | |||
54 | #define TIMER_VSYNC_id TIMER1_id | ||
55 | #define TIMER_VSYNCbit TIMER1bit | ||
56 | #define TIMER_VSYNC_STATUS_TRUN TIMER_STATUS_TRUN1 | ||
57 | #define TIMER_VSYNC_STATUS_TIMIL TIMER_STATUS_TIMIL1 | ||
58 | #define TIMER_VSYNC_STATUS_TOVF TIMER_STATUS_TOVF1 | ||
59 | #endif | ||
60 | |||
61 | #define LCD_X_RES 320 /* Horizontal Resolution */ | ||
62 | #define LCD_Y_RES 240 /* Vertical Resolution */ | ||
63 | #define DMA_BUS_SIZE 16 | ||
64 | |||
65 | #define USE_RGB565_16_BIT_PPI | ||
66 | |||
67 | #ifdef USE_RGB565_16_BIT_PPI | ||
68 | #define LCD_BPP 16 /* Bit Per Pixel */ | ||
69 | #define CLOCKS_PER_PIX 1 | ||
70 | #define CPLD_PIPELINE_DELAY_COR 0 /* NO CPLB */ | ||
71 | #endif | ||
72 | |||
73 | /* Interface 16/18-bit TFT over an 8-bit wide PPI using a small Programmable Logic Device (CPLD) | ||
74 | * http://blackfin.uclinux.org/gf/project/stamp/frs/?action=FrsReleaseBrowse&frs_package_id=165 | ||
75 | */ | ||
76 | |||
77 | #ifdef USE_RGB565_8_BIT_PPI | ||
78 | #define LCD_BPP 16 /* Bit Per Pixel */ | ||
79 | #define CLOCKS_PER_PIX 2 | ||
80 | #define CPLD_PIPELINE_DELAY_COR 3 /* RGB565 */ | ||
81 | #endif | ||
82 | |||
83 | #ifdef USE_RGB888_8_BIT_PPI | ||
84 | #define LCD_BPP 24 /* Bit Per Pixel */ | ||
85 | #define CLOCKS_PER_PIX 3 | ||
86 | #define CPLD_PIPELINE_DELAY_COR 5 /* RGB888 */ | ||
87 | #endif | ||
88 | |||
89 | /* | ||
90 | * HS and VS timing parameters (all in number of PPI clk ticks) | ||
91 | */ | ||
92 | |||
93 | #define U_LINE 4 /* Blanking Lines */ | ||
94 | |||
95 | #define H_ACTPIX (LCD_X_RES * CLOCKS_PER_PIX) /* active horizontal pixel */ | ||
96 | #define H_PERIOD (336 * CLOCKS_PER_PIX) /* HS period */ | ||
97 | #define H_PULSE (2 * CLOCKS_PER_PIX) /* HS pulse width */ | ||
98 | #define H_START (7 * CLOCKS_PER_PIX + CPLD_PIPELINE_DELAY_COR) /* first valid pixel */ | ||
99 | |||
100 | #define V_LINES (LCD_Y_RES + U_LINE) /* total vertical lines */ | ||
101 | #define V_PULSE (2 * CLOCKS_PER_PIX) /* VS pulse width (1-5 H_PERIODs) */ | ||
102 | #define V_PERIOD (H_PERIOD * V_LINES) /* VS period */ | ||
103 | |||
104 | #define ACTIVE_VIDEO_MEM_OFFSET ((U_LINE / 2) * LCD_X_RES * (LCD_BPP / 8)) | ||
105 | |||
106 | #define BFIN_LCD_NBR_PALETTE_ENTRIES 256 | ||
107 | |||
108 | #define PPI_TX_MODE 0x2 | ||
109 | #define PPI_XFER_TYPE_11 0xC | ||
110 | #define PPI_PORT_CFG_01 0x10 | ||
111 | #define PPI_POLS_1 0x8000 | ||
112 | |||
113 | #if (CLOCKS_PER_PIX > 1) | ||
114 | #define PPI_PMODE (DLEN_8 | PACK_EN) | ||
115 | #else | ||
116 | #define PPI_PMODE (DLEN_16) | ||
117 | #endif | ||
118 | |||
119 | #define LQ035_INDEX 0x74 | ||
120 | #define LQ035_DATA 0x76 | ||
121 | |||
122 | #define LQ035_DRIVER_OUTPUT_CTL 0x1 | ||
123 | #define LQ035_SHUT_CTL 0x11 | ||
124 | |||
125 | #define LQ035_DRIVER_OUTPUT_MASK (LQ035_LR | LQ035_TB | LQ035_BGR | LQ035_REV) | ||
126 | #define LQ035_DRIVER_OUTPUT_DEFAULT (0x2AEF & ~LQ035_DRIVER_OUTPUT_MASK) | ||
127 | |||
128 | #define LQ035_SHUT (1 << 0) /* Shutdown */ | ||
129 | #define LQ035_ON (0 << 0) /* Shutdown */ | ||
130 | |||
131 | struct bfin_lq035q1fb_info { | ||
132 | struct fb_info *fb; | ||
133 | struct device *dev; | ||
134 | struct spi_driver spidrv; | ||
135 | struct bfin_lq035q1fb_disp_info *disp_info; | ||
136 | unsigned char *fb_buffer; /* RGB Buffer */ | ||
137 | dma_addr_t dma_handle; | ||
138 | int lq035_open_cnt; | ||
139 | int irq; | ||
140 | spinlock_t lock; /* lock */ | ||
141 | u32 pseudo_pal[16]; | ||
142 | }; | ||
143 | |||
144 | static int nocursor; | ||
145 | module_param(nocursor, int, 0644); | ||
146 | MODULE_PARM_DESC(nocursor, "cursor enable/disable"); | ||
147 | |||
148 | struct spi_control { | ||
149 | unsigned short mode; | ||
150 | }; | ||
151 | |||
152 | static int lq035q1_control(struct spi_device *spi, unsigned char reg, unsigned short value) | ||
153 | { | ||
154 | int ret; | ||
155 | u8 regs[3] = { LQ035_INDEX, 0, 0 }; | ||
156 | u8 dat[3] = { LQ035_DATA, 0, 0 }; | ||
157 | |||
158 | if (!spi) | ||
159 | return -ENODEV; | ||
160 | |||
161 | regs[2] = reg; | ||
162 | dat[1] = value >> 8; | ||
163 | dat[2] = value & 0xFF; | ||
164 | |||
165 | ret = spi_write(spi, regs, ARRAY_SIZE(regs)); | ||
166 | ret |= spi_write(spi, dat, ARRAY_SIZE(dat)); | ||
167 | return ret; | ||
168 | } | ||
169 | |||
170 | static int __devinit lq035q1_spidev_probe(struct spi_device *spi) | ||
171 | { | ||
172 | int ret; | ||
173 | struct spi_control *ctl; | ||
174 | struct bfin_lq035q1fb_info *info = container_of(spi->dev.driver, | ||
175 | struct bfin_lq035q1fb_info, | ||
176 | spidrv.driver); | ||
177 | |||
178 | ctl = kzalloc(sizeof(*ctl), GFP_KERNEL); | ||
179 | |||
180 | if (!ctl) | ||
181 | return -ENOMEM; | ||
182 | |||
183 | ctl->mode = (info->disp_info->mode & | ||
184 | LQ035_DRIVER_OUTPUT_MASK) | LQ035_DRIVER_OUTPUT_DEFAULT; | ||
185 | |||
186 | ret = lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON); | ||
187 | ret |= lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode); | ||
188 | if (ret) | ||
189 | return ret; | ||
190 | |||
191 | spi_set_drvdata(spi, ctl); | ||
192 | |||
193 | return 0; | ||
194 | } | ||
195 | |||
196 | static int lq035q1_spidev_remove(struct spi_device *spi) | ||
197 | { | ||
198 | return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_SHUT); | ||
199 | } | ||
200 | |||
201 | #ifdef CONFIG_PM | ||
202 | static int lq035q1_spidev_suspend(struct spi_device *spi, pm_message_t state) | ||
203 | { | ||
204 | return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_SHUT); | ||
205 | } | ||
206 | |||
207 | static int lq035q1_spidev_resume(struct spi_device *spi) | ||
208 | { | ||
209 | int ret; | ||
210 | struct spi_control *ctl = spi_get_drvdata(spi); | ||
211 | |||
212 | ret = lq035q1_control(spi, LQ035_DRIVER_OUTPUT_CTL, ctl->mode); | ||
213 | if (ret) | ||
214 | return ret; | ||
215 | |||
216 | return lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_ON); | ||
217 | } | ||
218 | #else | ||
219 | # define lq035q1_spidev_suspend NULL | ||
220 | # define lq035q1_spidev_resume NULL | ||
221 | #endif | ||
222 | |||
223 | /* Power down all displays on reboot, poweroff or halt */ | ||
224 | static void lq035q1_spidev_shutdown(struct spi_device *spi) | ||
225 | { | ||
226 | lq035q1_control(spi, LQ035_SHUT_CTL, LQ035_SHUT); | ||
227 | } | ||
228 | |||
229 | static int lq035q1_backlight(struct bfin_lq035q1fb_info *info, unsigned arg) | ||
230 | { | ||
231 | if (info->disp_info->use_bl) | ||
232 | gpio_set_value(info->disp_info->gpio_bl, arg); | ||
233 | |||
234 | return 0; | ||
235 | } | ||
236 | |||
237 | static void bfin_lq035q1_config_ppi(struct bfin_lq035q1fb_info *fbi) | ||
238 | { | ||
239 | bfin_write_PPI_DELAY(H_START); | ||
240 | bfin_write_PPI_COUNT(H_ACTPIX - 1); | ||
241 | bfin_write_PPI_FRAME(V_LINES); | ||
242 | |||
243 | bfin_write_PPI_CONTROL(PPI_TX_MODE | /* output mode , PORT_DIR */ | ||
244 | PPI_XFER_TYPE_11 | /* sync mode XFR_TYPE */ | ||
245 | PPI_PORT_CFG_01 | /* two frame sync PORT_CFG */ | ||
246 | PPI_PMODE | /* 8/16 bit data length / PACK_EN? */ | ||
247 | PPI_POLS_1); /* faling edge syncs POLS */ | ||
248 | } | ||
249 | |||
250 | static inline void bfin_lq035q1_disable_ppi(void) | ||
251 | { | ||
252 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() & ~PORT_EN); | ||
253 | } | ||
254 | |||
255 | static inline void bfin_lq035q1_enable_ppi(void) | ||
256 | { | ||
257 | bfin_write_PPI_CONTROL(bfin_read_PPI_CONTROL() | PORT_EN); | ||
258 | } | ||
259 | |||
260 | static void bfin_lq035q1_start_timers(void) | ||
261 | { | ||
262 | enable_gptimers(TIMER_VSYNCbit | TIMER_HSYNCbit); | ||
263 | } | ||
264 | |||
265 | static void bfin_lq035q1_stop_timers(void) | ||
266 | { | ||
267 | disable_gptimers(TIMER_HSYNCbit | TIMER_VSYNCbit); | ||
268 | |||
269 | set_gptimer_status(0, TIMER_HSYNC_STATUS_TRUN | TIMER_VSYNC_STATUS_TRUN | | ||
270 | TIMER_HSYNC_STATUS_TIMIL | TIMER_VSYNC_STATUS_TIMIL | | ||
271 | TIMER_HSYNC_STATUS_TOVF | TIMER_VSYNC_STATUS_TOVF); | ||
272 | |||
273 | } | ||
274 | |||
275 | static void bfin_lq035q1_init_timers(void) | ||
276 | { | ||
277 | |||
278 | bfin_lq035q1_stop_timers(); | ||
279 | |||
280 | set_gptimer_period(TIMER_HSYNC_id, H_PERIOD); | ||
281 | set_gptimer_pwidth(TIMER_HSYNC_id, H_PULSE); | ||
282 | set_gptimer_config(TIMER_HSYNC_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | | ||
283 | TIMER_TIN_SEL | TIMER_CLK_SEL| | ||
284 | TIMER_EMU_RUN); | ||
285 | |||
286 | set_gptimer_period(TIMER_VSYNC_id, V_PERIOD); | ||
287 | set_gptimer_pwidth(TIMER_VSYNC_id, V_PULSE); | ||
288 | set_gptimer_config(TIMER_VSYNC_id, TIMER_MODE_PWM | TIMER_PERIOD_CNT | | ||
289 | TIMER_TIN_SEL | TIMER_CLK_SEL | | ||
290 | TIMER_EMU_RUN); | ||
291 | |||
292 | } | ||
293 | |||
294 | static void bfin_lq035q1_config_dma(struct bfin_lq035q1fb_info *fbi) | ||
295 | { | ||
296 | |||
297 | set_dma_config(CH_PPI, | ||
298 | set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO, | ||
299 | INTR_DISABLE, DIMENSION_2D, | ||
300 | DATA_SIZE_16, | ||
301 | DMA_NOSYNC_KEEP_DMA_BUF)); | ||
302 | set_dma_x_count(CH_PPI, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE); | ||
303 | set_dma_x_modify(CH_PPI, DMA_BUS_SIZE / 8); | ||
304 | set_dma_y_count(CH_PPI, V_LINES); | ||
305 | |||
306 | set_dma_y_modify(CH_PPI, DMA_BUS_SIZE / 8); | ||
307 | set_dma_start_addr(CH_PPI, (unsigned long)fbi->fb_buffer); | ||
308 | |||
309 | } | ||
310 | |||
311 | #if (CLOCKS_PER_PIX == 1) | ||
312 | static const u16 ppi0_req_16[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | ||
313 | P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, | ||
314 | P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, | ||
315 | P_PPI0_D6, P_PPI0_D7, P_PPI0_D8, | ||
316 | P_PPI0_D9, P_PPI0_D10, P_PPI0_D11, | ||
317 | P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, | ||
318 | P_PPI0_D15, 0}; | ||
319 | #else | ||
320 | static const u16 ppi0_req_16[] = {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, | ||
321 | P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, | ||
322 | P_PPI0_D3, P_PPI0_D4, P_PPI0_D5, | ||
323 | P_PPI0_D6, P_PPI0_D7, 0}; | ||
324 | #endif | ||
325 | |||
326 | static inline void bfin_lq035q1_free_ports(void) | ||
327 | { | ||
328 | peripheral_free_list(ppi0_req_16); | ||
329 | if (ANOMALY_05000400) | ||
330 | gpio_free(P_IDENT(P_PPI0_FS3)); | ||
331 | } | ||
332 | |||
333 | static int __devinit bfin_lq035q1_request_ports(struct platform_device *pdev) | ||
334 | { | ||
335 | /* ANOMALY_05000400 - PPI Does Not Start Properly In Specific Mode: | ||
336 | * Drive PPI_FS3 Low | ||
337 | */ | ||
338 | if (ANOMALY_05000400) { | ||
339 | int ret = gpio_request(P_IDENT(P_PPI0_FS3), "PPI_FS3"); | ||
340 | if (ret) | ||
341 | return ret; | ||
342 | gpio_direction_output(P_IDENT(P_PPI0_FS3), 0); | ||
343 | } | ||
344 | |||
345 | if (peripheral_request_list(ppi0_req_16, DRIVER_NAME)) { | ||
346 | dev_err(&pdev->dev, "requesting peripherals failed\n"); | ||
347 | return -EFAULT; | ||
348 | } | ||
349 | |||
350 | return 0; | ||
351 | } | ||
352 | |||
353 | static int bfin_lq035q1_fb_open(struct fb_info *info, int user) | ||
354 | { | ||
355 | struct bfin_lq035q1fb_info *fbi = info->par; | ||
356 | |||
357 | spin_lock(&fbi->lock); | ||
358 | fbi->lq035_open_cnt++; | ||
359 | |||
360 | if (fbi->lq035_open_cnt <= 1) { | ||
361 | |||
362 | bfin_lq035q1_disable_ppi(); | ||
363 | SSYNC(); | ||
364 | |||
365 | bfin_lq035q1_config_dma(fbi); | ||
366 | bfin_lq035q1_config_ppi(fbi); | ||
367 | bfin_lq035q1_init_timers(); | ||
368 | |||
369 | /* start dma */ | ||
370 | enable_dma(CH_PPI); | ||
371 | bfin_lq035q1_enable_ppi(); | ||
372 | bfin_lq035q1_start_timers(); | ||
373 | lq035q1_backlight(fbi, 1); | ||
374 | } | ||
375 | |||
376 | spin_unlock(&fbi->lock); | ||
377 | |||
378 | return 0; | ||
379 | } | ||
380 | |||
381 | static int bfin_lq035q1_fb_release(struct fb_info *info, int user) | ||
382 | { | ||
383 | struct bfin_lq035q1fb_info *fbi = info->par; | ||
384 | |||
385 | spin_lock(&fbi->lock); | ||
386 | |||
387 | fbi->lq035_open_cnt--; | ||
388 | |||
389 | if (fbi->lq035_open_cnt <= 0) { | ||
390 | lq035q1_backlight(fbi, 0); | ||
391 | bfin_lq035q1_disable_ppi(); | ||
392 | SSYNC(); | ||
393 | disable_dma(CH_PPI); | ||
394 | bfin_lq035q1_stop_timers(); | ||
395 | } | ||
396 | |||
397 | spin_unlock(&fbi->lock); | ||
398 | |||
399 | return 0; | ||
400 | } | ||
401 | |||
402 | static int bfin_lq035q1_fb_check_var(struct fb_var_screeninfo *var, | ||
403 | struct fb_info *info) | ||
404 | { | ||
405 | switch (var->bits_per_pixel) { | ||
406 | #if (LCD_BPP == 24) | ||
407 | case 24:/* TRUECOLOUR, 16m */ | ||
408 | #else | ||
409 | case 16:/* DIRECTCOLOUR, 64k */ | ||
410 | #endif | ||
411 | var->red.offset = info->var.red.offset; | ||
412 | var->green.offset = info->var.green.offset; | ||
413 | var->blue.offset = info->var.blue.offset; | ||
414 | var->red.length = info->var.red.length; | ||
415 | var->green.length = info->var.green.length; | ||
416 | var->blue.length = info->var.blue.length; | ||
417 | var->transp.offset = 0; | ||
418 | var->transp.length = 0; | ||
419 | var->transp.msb_right = 0; | ||
420 | var->red.msb_right = 0; | ||
421 | var->green.msb_right = 0; | ||
422 | var->blue.msb_right = 0; | ||
423 | break; | ||
424 | default: | ||
425 | pr_debug("%s: depth not supported: %u BPP\n", __func__, | ||
426 | var->bits_per_pixel); | ||
427 | return -EINVAL; | ||
428 | } | ||
429 | |||
430 | if (info->var.xres != var->xres || info->var.yres != var->yres || | ||
431 | info->var.xres_virtual != var->xres_virtual || | ||
432 | info->var.yres_virtual != var->yres_virtual) { | ||
433 | pr_debug("%s: Resolution not supported: X%u x Y%u \n", | ||
434 | __func__, var->xres, var->yres); | ||
435 | return -EINVAL; | ||
436 | } | ||
437 | |||
438 | /* | ||
439 | * Memory limit | ||
440 | */ | ||
441 | |||
442 | if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) { | ||
443 | pr_debug("%s: Memory Limit requested yres_virtual = %u\n", | ||
444 | __func__, var->yres_virtual); | ||
445 | return -ENOMEM; | ||
446 | } | ||
447 | |||
448 | |||
449 | return 0; | ||
450 | } | ||
451 | |||
452 | int bfin_lq035q1_fb_cursor(struct fb_info *info, struct fb_cursor *cursor) | ||
453 | { | ||
454 | if (nocursor) | ||
455 | return 0; | ||
456 | else | ||
457 | return -EINVAL; /* just to force soft_cursor() call */ | ||
458 | } | ||
459 | |||
460 | static int bfin_lq035q1_fb_setcolreg(u_int regno, u_int red, u_int green, | ||
461 | u_int blue, u_int transp, | ||
462 | struct fb_info *info) | ||
463 | { | ||
464 | if (regno >= BFIN_LCD_NBR_PALETTE_ENTRIES) | ||
465 | return -EINVAL; | ||
466 | |||
467 | if (info->var.grayscale) { | ||
468 | /* grayscale = 0.30*R + 0.59*G + 0.11*B */ | ||
469 | red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; | ||
470 | } | ||
471 | |||
472 | if (info->fix.visual == FB_VISUAL_TRUECOLOR) { | ||
473 | |||
474 | u32 value; | ||
475 | /* Place color in the pseudopalette */ | ||
476 | if (regno > 16) | ||
477 | return -EINVAL; | ||
478 | |||
479 | red >>= (16 - info->var.red.length); | ||
480 | green >>= (16 - info->var.green.length); | ||
481 | blue >>= (16 - info->var.blue.length); | ||
482 | |||
483 | value = (red << info->var.red.offset) | | ||
484 | (green << info->var.green.offset) | | ||
485 | (blue << info->var.blue.offset); | ||
486 | value &= 0xFFFFFF; | ||
487 | |||
488 | ((u32 *) (info->pseudo_palette))[regno] = value; | ||
489 | |||
490 | } | ||
491 | |||
492 | return 0; | ||
493 | } | ||
494 | |||
495 | static struct fb_ops bfin_lq035q1_fb_ops = { | ||
496 | .owner = THIS_MODULE, | ||
497 | .fb_open = bfin_lq035q1_fb_open, | ||
498 | .fb_release = bfin_lq035q1_fb_release, | ||
499 | .fb_check_var = bfin_lq035q1_fb_check_var, | ||
500 | .fb_fillrect = cfb_fillrect, | ||
501 | .fb_copyarea = cfb_copyarea, | ||
502 | .fb_imageblit = cfb_imageblit, | ||
503 | .fb_cursor = bfin_lq035q1_fb_cursor, | ||
504 | .fb_setcolreg = bfin_lq035q1_fb_setcolreg, | ||
505 | }; | ||
506 | |||
507 | static irqreturn_t bfin_lq035q1_irq_error(int irq, void *dev_id) | ||
508 | { | ||
509 | /*struct bfin_lq035q1fb_info *info = (struct bfin_lq035q1fb_info *)dev_id;*/ | ||
510 | |||
511 | u16 status = bfin_read_PPI_STATUS(); | ||
512 | bfin_write_PPI_STATUS(-1); | ||
513 | |||
514 | if (status) { | ||
515 | bfin_lq035q1_disable_ppi(); | ||
516 | disable_dma(CH_PPI); | ||
517 | |||
518 | /* start dma */ | ||
519 | enable_dma(CH_PPI); | ||
520 | bfin_lq035q1_enable_ppi(); | ||
521 | bfin_write_PPI_STATUS(-1); | ||
522 | } | ||
523 | |||
524 | return IRQ_HANDLED; | ||
525 | } | ||
526 | |||
527 | static int __devinit bfin_lq035q1_probe(struct platform_device *pdev) | ||
528 | { | ||
529 | struct bfin_lq035q1fb_info *info; | ||
530 | struct fb_info *fbinfo; | ||
531 | int ret; | ||
532 | |||
533 | ret = request_dma(CH_PPI, DRIVER_NAME"_CH_PPI"); | ||
534 | if (ret < 0) { | ||
535 | dev_err(&pdev->dev, "PPI DMA unavailable\n"); | ||
536 | goto out1; | ||
537 | } | ||
538 | |||
539 | fbinfo = framebuffer_alloc(sizeof(*info), &pdev->dev); | ||
540 | if (!fbinfo) { | ||
541 | ret = -ENOMEM; | ||
542 | goto out2; | ||
543 | } | ||
544 | |||
545 | info = fbinfo->par; | ||
546 | info->fb = fbinfo; | ||
547 | info->dev = &pdev->dev; | ||
548 | |||
549 | info->disp_info = pdev->dev.platform_data; | ||
550 | |||
551 | platform_set_drvdata(pdev, fbinfo); | ||
552 | |||
553 | strcpy(fbinfo->fix.id, DRIVER_NAME); | ||
554 | |||
555 | fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; | ||
556 | fbinfo->fix.type_aux = 0; | ||
557 | fbinfo->fix.xpanstep = 0; | ||
558 | fbinfo->fix.ypanstep = 0; | ||
559 | fbinfo->fix.ywrapstep = 0; | ||
560 | fbinfo->fix.accel = FB_ACCEL_NONE; | ||
561 | fbinfo->fix.visual = FB_VISUAL_TRUECOLOR; | ||
562 | |||
563 | fbinfo->var.nonstd = 0; | ||
564 | fbinfo->var.activate = FB_ACTIVATE_NOW; | ||
565 | fbinfo->var.height = -1; | ||
566 | fbinfo->var.width = -1; | ||
567 | fbinfo->var.accel_flags = 0; | ||
568 | fbinfo->var.vmode = FB_VMODE_NONINTERLACED; | ||
569 | |||
570 | fbinfo->var.xres = LCD_X_RES; | ||
571 | fbinfo->var.xres_virtual = LCD_X_RES; | ||
572 | fbinfo->var.yres = LCD_Y_RES; | ||
573 | fbinfo->var.yres_virtual = LCD_Y_RES; | ||
574 | fbinfo->var.bits_per_pixel = LCD_BPP; | ||
575 | |||
576 | if (info->disp_info->mode & LQ035_BGR) { | ||
577 | #if (LCD_BPP == 24) | ||
578 | fbinfo->var.red.offset = 0; | ||
579 | fbinfo->var.green.offset = 8; | ||
580 | fbinfo->var.blue.offset = 16; | ||
581 | #else | ||
582 | fbinfo->var.red.offset = 0; | ||
583 | fbinfo->var.green.offset = 5; | ||
584 | fbinfo->var.blue.offset = 11; | ||
585 | #endif | ||
586 | } else { | ||
587 | #if (LCD_BPP == 24) | ||
588 | fbinfo->var.red.offset = 16; | ||
589 | fbinfo->var.green.offset = 8; | ||
590 | fbinfo->var.blue.offset = 0; | ||
591 | #else | ||
592 | fbinfo->var.red.offset = 11; | ||
593 | fbinfo->var.green.offset = 5; | ||
594 | fbinfo->var.blue.offset = 0; | ||
595 | #endif | ||
596 | } | ||
597 | |||
598 | fbinfo->var.transp.offset = 0; | ||
599 | |||
600 | #if (LCD_BPP == 24) | ||
601 | fbinfo->var.red.length = 8; | ||
602 | fbinfo->var.green.length = 8; | ||
603 | fbinfo->var.blue.length = 8; | ||
604 | #else | ||
605 | fbinfo->var.red.length = 5; | ||
606 | fbinfo->var.green.length = 6; | ||
607 | fbinfo->var.blue.length = 5; | ||
608 | #endif | ||
609 | |||
610 | fbinfo->var.transp.length = 0; | ||
611 | |||
612 | fbinfo->fix.smem_len = LCD_X_RES * LCD_Y_RES * LCD_BPP / 8 | ||
613 | + ACTIVE_VIDEO_MEM_OFFSET; | ||
614 | |||
615 | fbinfo->fix.line_length = fbinfo->var.xres_virtual * | ||
616 | fbinfo->var.bits_per_pixel / 8; | ||
617 | |||
618 | |||
619 | fbinfo->fbops = &bfin_lq035q1_fb_ops; | ||
620 | fbinfo->flags = FBINFO_FLAG_DEFAULT; | ||
621 | |||
622 | info->fb_buffer = | ||
623 | dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle, | ||
624 | GFP_KERNEL); | ||
625 | |||
626 | if (NULL == info->fb_buffer) { | ||
627 | dev_err(&pdev->dev, "couldn't allocate dma buffer\n"); | ||
628 | ret = -ENOMEM; | ||
629 | goto out3; | ||
630 | } | ||
631 | |||
632 | fbinfo->screen_base = (void *)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; | ||
633 | fbinfo->fix.smem_start = (int)info->fb_buffer + ACTIVE_VIDEO_MEM_OFFSET; | ||
634 | |||
635 | fbinfo->fbops = &bfin_lq035q1_fb_ops; | ||
636 | |||
637 | fbinfo->pseudo_palette = &info->pseudo_pal; | ||
638 | |||
639 | ret = fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0); | ||
640 | if (ret < 0) { | ||
641 | dev_err(&pdev->dev, "failed to allocate colormap (%d entries)\n", | ||
642 | BFIN_LCD_NBR_PALETTE_ENTRIES); | ||
643 | goto out4; | ||
644 | } | ||
645 | |||
646 | ret = bfin_lq035q1_request_ports(pdev); | ||
647 | if (ret) { | ||
648 | dev_err(&pdev->dev, "couldn't request gpio port\n"); | ||
649 | goto out6; | ||
650 | } | ||
651 | |||
652 | info->irq = platform_get_irq(pdev, 0); | ||
653 | if (info->irq < 0) { | ||
654 | ret = -EINVAL; | ||
655 | goto out7; | ||
656 | } | ||
657 | |||
658 | ret = request_irq(info->irq, bfin_lq035q1_irq_error, IRQF_DISABLED, | ||
659 | DRIVER_NAME" PPI ERROR", info); | ||
660 | if (ret < 0) { | ||
661 | dev_err(&pdev->dev, "unable to request PPI ERROR IRQ\n"); | ||
662 | goto out7; | ||
663 | } | ||
664 | |||
665 | info->spidrv.driver.name = DRIVER_NAME"-spi"; | ||
666 | info->spidrv.probe = lq035q1_spidev_probe; | ||
667 | info->spidrv.remove = __devexit_p(lq035q1_spidev_remove); | ||
668 | info->spidrv.shutdown = lq035q1_spidev_shutdown; | ||
669 | info->spidrv.suspend = lq035q1_spidev_suspend; | ||
670 | info->spidrv.resume = lq035q1_spidev_resume; | ||
671 | |||
672 | ret = spi_register_driver(&info->spidrv); | ||
673 | if (ret < 0) { | ||
674 | dev_err(&pdev->dev, "couldn't register SPI Interface\n"); | ||
675 | goto out8; | ||
676 | } | ||
677 | |||
678 | if (info->disp_info->use_bl) { | ||
679 | ret = gpio_request(info->disp_info->gpio_bl, "LQ035 Backlight"); | ||
680 | |||
681 | if (ret) { | ||
682 | dev_err(&pdev->dev, "failed to request GPIO %d\n", | ||
683 | info->disp_info->gpio_bl); | ||
684 | goto out9; | ||
685 | } | ||
686 | gpio_direction_output(info->disp_info->gpio_bl, 0); | ||
687 | } | ||
688 | |||
689 | ret = register_framebuffer(fbinfo); | ||
690 | if (ret < 0) { | ||
691 | dev_err(&pdev->dev, "unable to register framebuffer\n"); | ||
692 | goto out10; | ||
693 | } | ||
694 | |||
695 | dev_info(&pdev->dev, "%dx%d %d-bit RGB FrameBuffer initialized\n", | ||
696 | LCD_X_RES, LCD_Y_RES, LCD_BPP); | ||
697 | |||
698 | return 0; | ||
699 | |||
700 | out10: | ||
701 | if (info->disp_info->use_bl) | ||
702 | gpio_free(info->disp_info->gpio_bl); | ||
703 | out9: | ||
704 | spi_unregister_driver(&info->spidrv); | ||
705 | out8: | ||
706 | free_irq(info->irq, info); | ||
707 | out7: | ||
708 | bfin_lq035q1_free_ports(); | ||
709 | out6: | ||
710 | fb_dealloc_cmap(&fbinfo->cmap); | ||
711 | out4: | ||
712 | dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, | ||
713 | info->dma_handle); | ||
714 | out3: | ||
715 | framebuffer_release(fbinfo); | ||
716 | out2: | ||
717 | free_dma(CH_PPI); | ||
718 | out1: | ||
719 | platform_set_drvdata(pdev, NULL); | ||
720 | |||
721 | return ret; | ||
722 | } | ||
723 | |||
724 | static int __devexit bfin_lq035q1_remove(struct platform_device *pdev) | ||
725 | { | ||
726 | struct fb_info *fbinfo = platform_get_drvdata(pdev); | ||
727 | struct bfin_lq035q1fb_info *info = fbinfo->par; | ||
728 | |||
729 | if (info->disp_info->use_bl) | ||
730 | gpio_free(info->disp_info->gpio_bl); | ||
731 | |||
732 | spi_unregister_driver(&info->spidrv); | ||
733 | |||
734 | unregister_framebuffer(fbinfo); | ||
735 | |||
736 | free_dma(CH_PPI); | ||
737 | free_irq(info->irq, info); | ||
738 | |||
739 | if (info->fb_buffer != NULL) | ||
740 | dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer, | ||
741 | info->dma_handle); | ||
742 | |||
743 | fb_dealloc_cmap(&fbinfo->cmap); | ||
744 | |||
745 | bfin_lq035q1_free_ports(); | ||
746 | |||
747 | platform_set_drvdata(pdev, NULL); | ||
748 | framebuffer_release(fbinfo); | ||
749 | |||
750 | dev_info(&pdev->dev, "unregistered LCD driver\n"); | ||
751 | |||
752 | return 0; | ||
753 | } | ||
754 | |||
755 | #ifdef CONFIG_PM | ||
756 | static int bfin_lq035q1_suspend(struct device *dev) | ||
757 | { | ||
758 | struct fb_info *fbinfo = dev_get_drvdata(dev); | ||
759 | struct bfin_lq035q1fb_info *info = fbinfo->par; | ||
760 | |||
761 | if (info->lq035_open_cnt) { | ||
762 | lq035q1_backlight(info, 0); | ||
763 | bfin_lq035q1_disable_ppi(); | ||
764 | SSYNC(); | ||
765 | disable_dma(CH_PPI); | ||
766 | bfin_lq035q1_stop_timers(); | ||
767 | bfin_write_PPI_STATUS(-1); | ||
768 | } | ||
769 | |||
770 | return 0; | ||
771 | } | ||
772 | |||
773 | static int bfin_lq035q1_resume(struct device *dev) | ||
774 | { | ||
775 | struct fb_info *fbinfo = dev_get_drvdata(dev); | ||
776 | struct bfin_lq035q1fb_info *info = fbinfo->par; | ||
777 | |||
778 | if (info->lq035_open_cnt) { | ||
779 | bfin_lq035q1_disable_ppi(); | ||
780 | SSYNC(); | ||
781 | |||
782 | bfin_lq035q1_config_dma(info); | ||
783 | bfin_lq035q1_config_ppi(info); | ||
784 | bfin_lq035q1_init_timers(); | ||
785 | |||
786 | /* start dma */ | ||
787 | enable_dma(CH_PPI); | ||
788 | bfin_lq035q1_enable_ppi(); | ||
789 | bfin_lq035q1_start_timers(); | ||
790 | lq035q1_backlight(info, 1); | ||
791 | } | ||
792 | |||
793 | return 0; | ||
794 | } | ||
795 | |||
796 | static struct dev_pm_ops bfin_lq035q1_dev_pm_ops = { | ||
797 | .suspend = bfin_lq035q1_suspend, | ||
798 | .resume = bfin_lq035q1_resume, | ||
799 | }; | ||
800 | #endif | ||
801 | |||
802 | static struct platform_driver bfin_lq035q1_driver = { | ||
803 | .probe = bfin_lq035q1_probe, | ||
804 | .remove = __devexit_p(bfin_lq035q1_remove), | ||
805 | .driver = { | ||
806 | .name = DRIVER_NAME, | ||
807 | #ifdef CONFIG_PM | ||
808 | .pm = &bfin_lq035q1_dev_pm_ops, | ||
809 | #endif | ||
810 | }, | ||
811 | }; | ||
812 | |||
813 | static int __init bfin_lq035q1_driver_init(void) | ||
814 | { | ||
815 | return platform_driver_register(&bfin_lq035q1_driver); | ||
816 | } | ||
817 | module_init(bfin_lq035q1_driver_init); | ||
818 | |||
819 | static void __exit bfin_lq035q1_driver_cleanup(void) | ||
820 | { | ||
821 | platform_driver_unregister(&bfin_lq035q1_driver); | ||
822 | } | ||
823 | module_exit(bfin_lq035q1_driver_cleanup); | ||
824 | |||
825 | MODULE_DESCRIPTION("Blackfin TFT LCD Driver"); | ||
826 | MODULE_LICENSE("GPL"); | ||
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/bfin-t350mcqb-fb.c index 5cc36cfbf07b..2549c53b26a0 100644 --- a/drivers/video/bfin-t350mcqb-fb.c +++ b/drivers/video/bfin-t350mcqb-fb.c | |||
@@ -487,8 +487,8 @@ static int __devinit bfin_t350mcqb_probe(struct platform_device *pdev) | |||
487 | 487 | ||
488 | fbinfo->var.nonstd = 0; | 488 | fbinfo->var.nonstd = 0; |
489 | fbinfo->var.activate = FB_ACTIVATE_NOW; | 489 | fbinfo->var.activate = FB_ACTIVATE_NOW; |
490 | fbinfo->var.height = -1; | 490 | fbinfo->var.height = 53; |
491 | fbinfo->var.width = -1; | 491 | fbinfo->var.width = 70; |
492 | fbinfo->var.accel_flags = 0; | 492 | fbinfo->var.accel_flags = 0; |
493 | fbinfo->var.vmode = FB_VMODE_NONINTERLACED; | 493 | fbinfo->var.vmode = FB_VMODE_NONINTERLACED; |
494 | 494 | ||
@@ -634,17 +634,35 @@ static int __devexit bfin_t350mcqb_remove(struct platform_device *pdev) | |||
634 | #ifdef CONFIG_PM | 634 | #ifdef CONFIG_PM |
635 | static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state) | 635 | static int bfin_t350mcqb_suspend(struct platform_device *pdev, pm_message_t state) |
636 | { | 636 | { |
637 | bfin_t350mcqb_disable_ppi(); | 637 | struct fb_info *fbinfo = platform_get_drvdata(pdev); |
638 | disable_dma(CH_PPI); | 638 | struct bfin_t350mcqbfb_info *fbi = fbinfo->par; |
639 | bfin_write_PPI_STATUS(0xFFFF); | 639 | |
640 | if (fbi->lq043_open_cnt) { | ||
641 | bfin_t350mcqb_disable_ppi(); | ||
642 | disable_dma(CH_PPI); | ||
643 | bfin_t350mcqb_stop_timers(); | ||
644 | bfin_write_PPI_STATUS(-1); | ||
645 | } | ||
646 | |||
640 | 647 | ||
641 | return 0; | 648 | return 0; |
642 | } | 649 | } |
643 | 650 | ||
644 | static int bfin_t350mcqb_resume(struct platform_device *pdev) | 651 | static int bfin_t350mcqb_resume(struct platform_device *pdev) |
645 | { | 652 | { |
646 | enable_dma(CH_PPI); | 653 | struct fb_info *fbinfo = platform_get_drvdata(pdev); |
647 | bfin_t350mcqb_enable_ppi(); | 654 | struct bfin_t350mcqbfb_info *fbi = fbinfo->par; |
655 | |||
656 | if (fbi->lq043_open_cnt) { | ||
657 | bfin_t350mcqb_config_dma(fbi); | ||
658 | bfin_t350mcqb_config_ppi(fbi); | ||
659 | bfin_t350mcqb_init_timers(); | ||
660 | |||
661 | /* start dma */ | ||
662 | enable_dma(CH_PPI); | ||
663 | bfin_t350mcqb_enable_ppi(); | ||
664 | bfin_t350mcqb_start_timers(); | ||
665 | } | ||
648 | 666 | ||
649 | return 0; | 667 | return 0; |
650 | } | 668 | } |
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c index 16f5db471ab5..99b354b8e257 100644 --- a/drivers/video/clps711xfb.c +++ b/drivers/video/clps711xfb.c | |||
@@ -19,8 +19,10 @@ | |||
19 | * | 19 | * |
20 | * Framebuffer driver for the CLPS7111 and EP7212 processors. | 20 | * Framebuffer driver for the CLPS7111 and EP7212 processors. |
21 | */ | 21 | */ |
22 | #include <linux/mm.h> | ||
22 | #include <linux/module.h> | 23 | #include <linux/module.h> |
23 | #include <linux/kernel.h> | 24 | #include <linux/kernel.h> |
25 | #include <linux/seq_file.h> | ||
24 | #include <linux/slab.h> | 26 | #include <linux/slab.h> |
25 | #include <linux/fb.h> | 27 | #include <linux/fb.h> |
26 | #include <linux/init.h> | 28 | #include <linux/init.h> |
@@ -38,14 +40,6 @@ struct fb_info *cfb; | |||
38 | 40 | ||
39 | #define CMAP_MAX_SIZE 16 | 41 | #define CMAP_MAX_SIZE 16 |
40 | 42 | ||
41 | /* The /proc entry for the backlight. */ | ||
42 | static struct proc_dir_entry *clps7111fb_backlight_proc_entry = NULL; | ||
43 | |||
44 | static int clps7111fb_proc_backlight_read(char *page, char **start, off_t off, | ||
45 | int count, int *eof, void *data); | ||
46 | static int clps7111fb_proc_backlight_write(struct file *file, | ||
47 | const char *buffer, unsigned long count, void *data); | ||
48 | |||
49 | /* | 43 | /* |
50 | * LCD AC Prescale. This comes from the LCD panel manufacturers specifications. | 44 | * LCD AC Prescale. This comes from the LCD panel manufacturers specifications. |
51 | * This determines how many clocks + 1 of CL1 before the M signal toggles. | 45 | * This determines how many clocks + 1 of CL1 before the M signal toggles. |
@@ -221,26 +215,23 @@ static struct fb_ops clps7111fb_ops = { | |||
221 | .fb_imageblit = cfb_imageblit, | 215 | .fb_imageblit = cfb_imageblit, |
222 | }; | 216 | }; |
223 | 217 | ||
224 | static int | 218 | static int backlight_proc_show(struct seq_file *m, void *v) |
225 | clps7111fb_proc_backlight_read(char *page, char **start, off_t off, | ||
226 | int count, int *eof, void *data) | ||
227 | { | 219 | { |
228 | /* We need at least two characters, one for the digit, and one for | ||
229 | * the terminating NULL. */ | ||
230 | if (count < 2) | ||
231 | return -EINVAL; | ||
232 | |||
233 | if (machine_is_edb7211()) { | 220 | if (machine_is_edb7211()) { |
234 | return sprintf(page, "%d\n", | 221 | seq_printf(m, "%d\n", |
235 | (clps_readb(PDDR) & EDB_PD3_LCDBL) ? 1 : 0); | 222 | (clps_readb(PDDR) & EDB_PD3_LCDBL) ? 1 : 0); |
236 | } | 223 | } |
237 | 224 | ||
238 | return 0; | 225 | return 0; |
239 | } | 226 | } |
240 | 227 | ||
241 | static int | 228 | static int backlight_proc_open(struct inode *inode, struct file *file) |
242 | clps7111fb_proc_backlight_write(struct file *file, const char *buffer, | 229 | { |
243 | unsigned long count, void *data) | 230 | return single_open(file, backlight_proc_show, NULL); |
231 | } | ||
232 | |||
233 | static ssize_t backlight_proc_write(struct file *file, const char *buffer, | ||
234 | size_t count, loff_t *pos) | ||
244 | { | 235 | { |
245 | unsigned char char_value; | 236 | unsigned char char_value; |
246 | int value; | 237 | int value; |
@@ -271,6 +262,15 @@ clps7111fb_proc_backlight_write(struct file *file, const char *buffer, | |||
271 | return count; | 262 | return count; |
272 | } | 263 | } |
273 | 264 | ||
265 | static const struct file_operations backlight_proc_fops = { | ||
266 | .owner = THIS_MODULE, | ||
267 | .open = backlight_proc_open, | ||
268 | .read = seq_read, | ||
269 | .llseek = seq_lseek, | ||
270 | .release = single_release, | ||
271 | .write = backlight_proc_write, | ||
272 | }; | ||
273 | |||
274 | static void __init clps711x_guess_lcd_params(struct fb_info *info) | 274 | static void __init clps711x_guess_lcd_params(struct fb_info *info) |
275 | { | 275 | { |
276 | unsigned int lcdcon, syscon, size; | 276 | unsigned int lcdcon, syscon, size; |
@@ -379,19 +379,11 @@ int __init clps711xfb_init(void) | |||
379 | 379 | ||
380 | fb_alloc_cmap(&cfb->cmap, CMAP_MAX_SIZE, 0); | 380 | fb_alloc_cmap(&cfb->cmap, CMAP_MAX_SIZE, 0); |
381 | 381 | ||
382 | /* Register the /proc entries. */ | 382 | if (!proc_create("backlight", 0444, NULL, &backlight_proc_fops)) { |
383 | clps7111fb_backlight_proc_entry = create_proc_entry("backlight", 0444, | ||
384 | NULL); | ||
385 | if (clps7111fb_backlight_proc_entry == NULL) { | ||
386 | printk("Couldn't create the /proc entry for the backlight.\n"); | 383 | printk("Couldn't create the /proc entry for the backlight.\n"); |
387 | return -EINVAL; | 384 | return -EINVAL; |
388 | } | 385 | } |
389 | 386 | ||
390 | clps7111fb_backlight_proc_entry->read_proc = | ||
391 | &clps7111fb_proc_backlight_read; | ||
392 | clps7111fb_backlight_proc_entry->write_proc = | ||
393 | &clps7111fb_proc_backlight_write; | ||
394 | |||
395 | /* | 387 | /* |
396 | * Power up the LCD | 388 | * Power up the LCD |
397 | */ | 389 | */ |
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/da8xx-fb.c index ea1fd3f47511..369a5b3ac649 100644 --- a/drivers/video/da8xx-fb.c +++ b/drivers/video/da8xx-fb.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include <linux/uaccess.h> | 28 | #include <linux/uaccess.h> |
29 | #include <linux/interrupt.h> | 29 | #include <linux/interrupt.h> |
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/cpufreq.h> | ||
32 | #include <linux/console.h> | ||
31 | #include <video/da8xx-fb.h> | 33 | #include <video/da8xx-fb.h> |
32 | 34 | ||
33 | #define DRIVER_NAME "da8xx_lcdc" | 35 | #define DRIVER_NAME "da8xx_lcdc" |
@@ -113,6 +115,12 @@ struct da8xx_fb_par { | |||
113 | unsigned short pseudo_palette[16]; | 115 | unsigned short pseudo_palette[16]; |
114 | unsigned int databuf_sz; | 116 | unsigned int databuf_sz; |
115 | unsigned int palette_sz; | 117 | unsigned int palette_sz; |
118 | unsigned int pxl_clk; | ||
119 | int blank; | ||
120 | #ifdef CONFIG_CPU_FREQ | ||
121 | struct notifier_block freq_transition; | ||
122 | #endif | ||
123 | void (*panel_power_ctrl)(int); | ||
116 | }; | 124 | }; |
117 | 125 | ||
118 | /* Variable Screen Information */ | 126 | /* Variable Screen Information */ |
@@ -155,7 +163,7 @@ struct da8xx_panel { | |||
155 | int vfp; /* Vertical front porch */ | 163 | int vfp; /* Vertical front porch */ |
156 | int vbp; /* Vertical back porch */ | 164 | int vbp; /* Vertical back porch */ |
157 | int vsw; /* Vertical Sync Pulse Width */ | 165 | int vsw; /* Vertical Sync Pulse Width */ |
158 | int pxl_clk; /* Pixel clock */ | 166 | unsigned int pxl_clk; /* Pixel clock */ |
159 | unsigned char invert_pxl_clk; /* Invert Pixel clock */ | 167 | unsigned char invert_pxl_clk; /* Invert Pixel clock */ |
160 | }; | 168 | }; |
161 | 169 | ||
@@ -171,7 +179,7 @@ static struct da8xx_panel known_lcd_panels[] = { | |||
171 | .vfp = 2, | 179 | .vfp = 2, |
172 | .vbp = 2, | 180 | .vbp = 2, |
173 | .vsw = 0, | 181 | .vsw = 0, |
174 | .pxl_clk = 0x10, | 182 | .pxl_clk = 4608000, |
175 | .invert_pxl_clk = 1, | 183 | .invert_pxl_clk = 1, |
176 | }, | 184 | }, |
177 | /* Sharp LK043T1DG01 */ | 185 | /* Sharp LK043T1DG01 */ |
@@ -185,13 +193,23 @@ static struct da8xx_panel known_lcd_panels[] = { | |||
185 | .vfp = 2, | 193 | .vfp = 2, |
186 | .vbp = 2, | 194 | .vbp = 2, |
187 | .vsw = 10, | 195 | .vsw = 10, |
188 | .pxl_clk = 0x12, | 196 | .pxl_clk = 7833600, |
189 | .invert_pxl_clk = 0, | 197 | .invert_pxl_clk = 0, |
190 | }, | 198 | }, |
191 | }; | 199 | }; |
192 | 200 | ||
201 | /* Enable the Raster Engine of the LCD Controller */ | ||
202 | static inline void lcd_enable_raster(void) | ||
203 | { | ||
204 | u32 reg; | ||
205 | |||
206 | reg = lcdc_read(LCD_RASTER_CTRL_REG); | ||
207 | if (!(reg & LCD_RASTER_ENABLE)) | ||
208 | lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | ||
209 | } | ||
210 | |||
193 | /* Disable the Raster Engine of the LCD Controller */ | 211 | /* Disable the Raster Engine of the LCD Controller */ |
194 | static void lcd_disable_raster(struct da8xx_fb_par *par) | 212 | static inline void lcd_disable_raster(void) |
195 | { | 213 | { |
196 | u32 reg; | 214 | u32 reg; |
197 | 215 | ||
@@ -443,14 +461,25 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
443 | static void lcd_reset(struct da8xx_fb_par *par) | 461 | static void lcd_reset(struct da8xx_fb_par *par) |
444 | { | 462 | { |
445 | /* Disable the Raster if previously Enabled */ | 463 | /* Disable the Raster if previously Enabled */ |
446 | if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE) | 464 | lcd_disable_raster(); |
447 | lcd_disable_raster(par); | ||
448 | 465 | ||
449 | /* DMA has to be disabled */ | 466 | /* DMA has to be disabled */ |
450 | lcdc_write(0, LCD_DMA_CTRL_REG); | 467 | lcdc_write(0, LCD_DMA_CTRL_REG); |
451 | lcdc_write(0, LCD_RASTER_CTRL_REG); | 468 | lcdc_write(0, LCD_RASTER_CTRL_REG); |
452 | } | 469 | } |
453 | 470 | ||
471 | static void lcd_calc_clk_divider(struct da8xx_fb_par *par) | ||
472 | { | ||
473 | unsigned int lcd_clk, div; | ||
474 | |||
475 | lcd_clk = clk_get_rate(par->lcdc_clk); | ||
476 | div = lcd_clk / par->pxl_clk; | ||
477 | |||
478 | /* Configure the LCD clock divisor. */ | ||
479 | lcdc_write(LCD_CLK_DIVISOR(div) | | ||
480 | (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); | ||
481 | } | ||
482 | |||
454 | static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | 483 | static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, |
455 | struct da8xx_panel *panel) | 484 | struct da8xx_panel *panel) |
456 | { | 485 | { |
@@ -459,9 +488,8 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | |||
459 | 488 | ||
460 | lcd_reset(par); | 489 | lcd_reset(par); |
461 | 490 | ||
462 | /* Configure the LCD clock divisor. */ | 491 | /* Calculate the divider */ |
463 | lcdc_write(LCD_CLK_DIVISOR(panel->pxl_clk) | | 492 | lcd_calc_clk_divider(par); |
464 | (LCD_RASTER_MODE & 0x1), LCD_CTRL_REG); | ||
465 | 493 | ||
466 | if (panel->invert_pxl_clk) | 494 | if (panel->invert_pxl_clk) |
467 | lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | | 495 | lcdc_write((lcdc_read(LCD_RASTER_TIMING_2_REG) | |
@@ -513,13 +541,11 @@ static int lcd_init(struct da8xx_fb_par *par, const struct lcd_ctrl_config *cfg, | |||
513 | static irqreturn_t lcdc_irq_handler(int irq, void *arg) | 541 | static irqreturn_t lcdc_irq_handler(int irq, void *arg) |
514 | { | 542 | { |
515 | u32 stat = lcdc_read(LCD_STAT_REG); | 543 | u32 stat = lcdc_read(LCD_STAT_REG); |
516 | u32 reg; | ||
517 | 544 | ||
518 | if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { | 545 | if ((stat & LCD_SYNC_LOST) && (stat & LCD_FIFO_UNDERFLOW)) { |
519 | reg = lcdc_read(LCD_RASTER_CTRL_REG); | 546 | lcd_disable_raster(); |
520 | lcdc_write(reg & ~LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | ||
521 | lcdc_write(stat, LCD_STAT_REG); | 547 | lcdc_write(stat, LCD_STAT_REG); |
522 | lcdc_write(reg | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | 548 | lcd_enable_raster(); |
523 | } else | 549 | } else |
524 | lcdc_write(stat, LCD_STAT_REG); | 550 | lcdc_write(stat, LCD_STAT_REG); |
525 | 551 | ||
@@ -574,6 +600,38 @@ static int fb_check_var(struct fb_var_screeninfo *var, | |||
574 | return err; | 600 | return err; |
575 | } | 601 | } |
576 | 602 | ||
603 | #ifdef CONFIG_CPU_FREQ | ||
604 | static int lcd_da8xx_cpufreq_transition(struct notifier_block *nb, | ||
605 | unsigned long val, void *data) | ||
606 | { | ||
607 | struct da8xx_fb_par *par; | ||
608 | |||
609 | par = container_of(nb, struct da8xx_fb_par, freq_transition); | ||
610 | if (val == CPUFREQ_PRECHANGE) { | ||
611 | lcd_disable_raster(); | ||
612 | } else if (val == CPUFREQ_POSTCHANGE) { | ||
613 | lcd_calc_clk_divider(par); | ||
614 | lcd_enable_raster(); | ||
615 | } | ||
616 | |||
617 | return 0; | ||
618 | } | ||
619 | |||
620 | static inline int lcd_da8xx_cpufreq_register(struct da8xx_fb_par *par) | ||
621 | { | ||
622 | par->freq_transition.notifier_call = lcd_da8xx_cpufreq_transition; | ||
623 | |||
624 | return cpufreq_register_notifier(&par->freq_transition, | ||
625 | CPUFREQ_TRANSITION_NOTIFIER); | ||
626 | } | ||
627 | |||
628 | static inline void lcd_da8xx_cpufreq_deregister(struct da8xx_fb_par *par) | ||
629 | { | ||
630 | cpufreq_unregister_notifier(&par->freq_transition, | ||
631 | CPUFREQ_TRANSITION_NOTIFIER); | ||
632 | } | ||
633 | #endif | ||
634 | |||
577 | static int __devexit fb_remove(struct platform_device *dev) | 635 | static int __devexit fb_remove(struct platform_device *dev) |
578 | { | 636 | { |
579 | struct fb_info *info = dev_get_drvdata(&dev->dev); | 637 | struct fb_info *info = dev_get_drvdata(&dev->dev); |
@@ -581,8 +639,13 @@ static int __devexit fb_remove(struct platform_device *dev) | |||
581 | if (info) { | 639 | if (info) { |
582 | struct da8xx_fb_par *par = info->par; | 640 | struct da8xx_fb_par *par = info->par; |
583 | 641 | ||
584 | if (lcdc_read(LCD_RASTER_CTRL_REG) & LCD_RASTER_ENABLE) | 642 | #ifdef CONFIG_CPU_FREQ |
585 | lcd_disable_raster(par); | 643 | lcd_da8xx_cpufreq_deregister(par); |
644 | #endif | ||
645 | if (par->panel_power_ctrl) | ||
646 | par->panel_power_ctrl(0); | ||
647 | |||
648 | lcd_disable_raster(); | ||
586 | lcdc_write(0, LCD_RASTER_CTRL_REG); | 649 | lcdc_write(0, LCD_RASTER_CTRL_REG); |
587 | 650 | ||
588 | /* disable DMA */ | 651 | /* disable DMA */ |
@@ -639,6 +702,35 @@ static int fb_ioctl(struct fb_info *info, unsigned int cmd, | |||
639 | return 0; | 702 | return 0; |
640 | } | 703 | } |
641 | 704 | ||
705 | static int cfb_blank(int blank, struct fb_info *info) | ||
706 | { | ||
707 | struct da8xx_fb_par *par = info->par; | ||
708 | int ret = 0; | ||
709 | |||
710 | if (par->blank == blank) | ||
711 | return 0; | ||
712 | |||
713 | par->blank = blank; | ||
714 | switch (blank) { | ||
715 | case FB_BLANK_UNBLANK: | ||
716 | if (par->panel_power_ctrl) | ||
717 | par->panel_power_ctrl(1); | ||
718 | |||
719 | lcd_enable_raster(); | ||
720 | break; | ||
721 | case FB_BLANK_POWERDOWN: | ||
722 | if (par->panel_power_ctrl) | ||
723 | par->panel_power_ctrl(0); | ||
724 | |||
725 | lcd_disable_raster(); | ||
726 | break; | ||
727 | default: | ||
728 | ret = -EINVAL; | ||
729 | } | ||
730 | |||
731 | return ret; | ||
732 | } | ||
733 | |||
642 | static struct fb_ops da8xx_fb_ops = { | 734 | static struct fb_ops da8xx_fb_ops = { |
643 | .owner = THIS_MODULE, | 735 | .owner = THIS_MODULE, |
644 | .fb_check_var = fb_check_var, | 736 | .fb_check_var = fb_check_var, |
@@ -647,6 +739,7 @@ static struct fb_ops da8xx_fb_ops = { | |||
647 | .fb_fillrect = cfb_fillrect, | 739 | .fb_fillrect = cfb_fillrect, |
648 | .fb_copyarea = cfb_copyarea, | 740 | .fb_copyarea = cfb_copyarea, |
649 | .fb_imageblit = cfb_imageblit, | 741 | .fb_imageblit = cfb_imageblit, |
742 | .fb_blank = cfb_blank, | ||
650 | }; | 743 | }; |
651 | 744 | ||
652 | static int __init fb_probe(struct platform_device *device) | 745 | static int __init fb_probe(struct platform_device *device) |
@@ -721,6 +814,12 @@ static int __init fb_probe(struct platform_device *device) | |||
721 | } | 814 | } |
722 | 815 | ||
723 | par = da8xx_fb_info->par; | 816 | par = da8xx_fb_info->par; |
817 | par->lcdc_clk = fb_clk; | ||
818 | par->pxl_clk = lcdc_info->pxl_clk; | ||
819 | if (fb_pdata->panel_power_ctrl) { | ||
820 | par->panel_power_ctrl = fb_pdata->panel_power_ctrl; | ||
821 | par->panel_power_ctrl(1); | ||
822 | } | ||
724 | 823 | ||
725 | if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { | 824 | if (lcd_init(par, lcd_cfg, lcdc_info) < 0) { |
726 | dev_err(&device->dev, "lcd_init failed\n"); | 825 | dev_err(&device->dev, "lcd_init failed\n"); |
@@ -754,8 +853,6 @@ static int __init fb_probe(struct platform_device *device) | |||
754 | da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz; | 853 | da8xx_fb_fix.smem_len = par->databuf_sz - par->palette_sz; |
755 | da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; | 854 | da8xx_fb_fix.line_length = (lcdc_info->width * lcd_cfg->bpp) / 8; |
756 | 855 | ||
757 | par->lcdc_clk = fb_clk; | ||
758 | |||
759 | par->irq = platform_get_irq(device, 0); | 856 | par->irq = platform_get_irq(device, 0); |
760 | if (par->irq < 0) { | 857 | if (par->irq < 0) { |
761 | ret = -ENOENT; | 858 | ret = -ENOENT; |
@@ -814,12 +911,24 @@ static int __init fb_probe(struct platform_device *device) | |||
814 | goto err_dealloc_cmap; | 911 | goto err_dealloc_cmap; |
815 | } | 912 | } |
816 | 913 | ||
914 | #ifdef CONFIG_CPU_FREQ | ||
915 | ret = lcd_da8xx_cpufreq_register(par); | ||
916 | if (ret) { | ||
917 | dev_err(&device->dev, "failed to register cpufreq\n"); | ||
918 | goto err_cpu_freq; | ||
919 | } | ||
920 | #endif | ||
921 | |||
817 | /* enable raster engine */ | 922 | /* enable raster engine */ |
818 | lcdc_write(lcdc_read(LCD_RASTER_CTRL_REG) | | 923 | lcd_enable_raster(); |
819 | LCD_RASTER_ENABLE, LCD_RASTER_CTRL_REG); | ||
820 | 924 | ||
821 | return 0; | 925 | return 0; |
822 | 926 | ||
927 | #ifdef CONFIG_CPU_FREQ | ||
928 | err_cpu_freq: | ||
929 | unregister_framebuffer(da8xx_fb_info); | ||
930 | #endif | ||
931 | |||
823 | err_dealloc_cmap: | 932 | err_dealloc_cmap: |
824 | fb_dealloc_cmap(&da8xx_fb_info->cmap); | 933 | fb_dealloc_cmap(&da8xx_fb_info->cmap); |
825 | 934 | ||
@@ -852,11 +961,35 @@ err_request_mem: | |||
852 | #ifdef CONFIG_PM | 961 | #ifdef CONFIG_PM |
853 | static int fb_suspend(struct platform_device *dev, pm_message_t state) | 962 | static int fb_suspend(struct platform_device *dev, pm_message_t state) |
854 | { | 963 | { |
855 | return -EBUSY; | 964 | struct fb_info *info = platform_get_drvdata(dev); |
965 | struct da8xx_fb_par *par = info->par; | ||
966 | |||
967 | acquire_console_sem(); | ||
968 | if (par->panel_power_ctrl) | ||
969 | par->panel_power_ctrl(0); | ||
970 | |||
971 | fb_set_suspend(info, 1); | ||
972 | lcd_disable_raster(); | ||
973 | clk_disable(par->lcdc_clk); | ||
974 | release_console_sem(); | ||
975 | |||
976 | return 0; | ||
856 | } | 977 | } |
857 | static int fb_resume(struct platform_device *dev) | 978 | static int fb_resume(struct platform_device *dev) |
858 | { | 979 | { |
859 | return -EBUSY; | 980 | struct fb_info *info = platform_get_drvdata(dev); |
981 | struct da8xx_fb_par *par = info->par; | ||
982 | |||
983 | acquire_console_sem(); | ||
984 | if (par->panel_power_ctrl) | ||
985 | par->panel_power_ctrl(1); | ||
986 | |||
987 | clk_enable(par->lcdc_clk); | ||
988 | lcd_enable_raster(); | ||
989 | fb_set_suspend(info, 0); | ||
990 | release_console_sem(); | ||
991 | |||
992 | return 0; | ||
860 | } | 993 | } |
861 | #else | 994 | #else |
862 | #define fb_suspend NULL | 995 | #define fb_suspend NULL |
diff --git a/drivers/video/display/display-sysfs.c b/drivers/video/display/display-sysfs.c index 4830b1bf51e5..80abbf323b99 100644 --- a/drivers/video/display/display-sysfs.c +++ b/drivers/video/display/display-sysfs.c | |||
@@ -67,7 +67,7 @@ static ssize_t display_store_contrast(struct device *dev, | |||
67 | contrast = simple_strtoul(buf, &endp, 0); | 67 | contrast = simple_strtoul(buf, &endp, 0); |
68 | size = endp - buf; | 68 | size = endp - buf; |
69 | 69 | ||
70 | if (*endp && isspace(*endp)) | 70 | if (isspace(*endp)) |
71 | size++; | 71 | size++; |
72 | 72 | ||
73 | if (size != count) | 73 | if (size != count) |
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/ep93xx-fb.c index bd9d46f95291..27aab4a06198 100644 --- a/drivers/video/ep93xx-fb.c +++ b/drivers/video/ep93xx-fb.c | |||
@@ -358,6 +358,8 @@ static int ep93xxfb_setcolreg(unsigned int regno, unsigned int red, | |||
358 | 358 | ||
359 | switch (info->fix.visual) { | 359 | switch (info->fix.visual) { |
360 | case FB_VISUAL_PSEUDOCOLOR: | 360 | case FB_VISUAL_PSEUDOCOLOR: |
361 | if (regno > 255) | ||
362 | return 1; | ||
361 | rgb = ((red & 0xff00) << 8) | (green & 0xff00) | | 363 | rgb = ((red & 0xff00) << 8) | (green & 0xff00) | |
362 | ((blue & 0xff00) >> 8); | 364 | ((blue & 0xff00) >> 8); |
363 | 365 | ||
diff --git a/drivers/video/geode/display_gx.c b/drivers/video/geode/display_gx.c index e759895bf3d3..f0af911a096d 100644 --- a/drivers/video/geode/display_gx.c +++ b/drivers/video/geode/display_gx.c | |||
@@ -17,7 +17,7 @@ | |||
17 | #include <asm/io.h> | 17 | #include <asm/io.h> |
18 | #include <asm/div64.h> | 18 | #include <asm/div64.h> |
19 | #include <asm/delay.h> | 19 | #include <asm/delay.h> |
20 | #include <asm/geode.h> | 20 | #include <linux/cs5535.h> |
21 | 21 | ||
22 | #include "gxfb.h" | 22 | #include "gxfb.h" |
23 | 23 | ||
@@ -25,7 +25,7 @@ unsigned int gx_frame_buffer_size(void) | |||
25 | { | 25 | { |
26 | unsigned int val; | 26 | unsigned int val; |
27 | 27 | ||
28 | if (!geode_has_vsa2()) { | 28 | if (!cs5535_has_vsa2()) { |
29 | uint32_t hi, lo; | 29 | uint32_t hi, lo; |
30 | 30 | ||
31 | /* The number of pages is (PMAX - PMIN)+1 */ | 31 | /* The number of pages is (PMAX - PMIN)+1 */ |
diff --git a/drivers/video/geode/gxfb.h b/drivers/video/geode/gxfb.h index 16a96f8fd8c5..d19e9378b0c0 100644 --- a/drivers/video/geode/gxfb.h +++ b/drivers/video/geode/gxfb.h | |||
@@ -340,7 +340,7 @@ static inline void write_fp(struct gxfb_par *par, int reg, uint32_t val) | |||
340 | } | 340 | } |
341 | 341 | ||
342 | 342 | ||
343 | /* MSRs are defined in asm/geode.h; their bitfields are here */ | 343 | /* MSRs are defined in linux/cs5535.h; their bitfields are here */ |
344 | 344 | ||
345 | #define MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3 (1 << 3) | 345 | #define MSR_GLCP_SYS_RSTPLL_DOTPOSTDIV3 (1 << 3) |
346 | #define MSR_GLCP_SYS_RSTPLL_DOTPREMULT2 (1 << 2) | 346 | #define MSR_GLCP_SYS_RSTPLL_DOTPREMULT2 (1 << 2) |
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/geode/gxfb_core.c index 2552cac39e1c..b3e639d1e12c 100644 --- a/drivers/video/geode/gxfb_core.c +++ b/drivers/video/geode/gxfb_core.c | |||
@@ -32,7 +32,7 @@ | |||
32 | #include <linux/suspend.h> | 32 | #include <linux/suspend.h> |
33 | #include <linux/init.h> | 33 | #include <linux/init.h> |
34 | #include <linux/pci.h> | 34 | #include <linux/pci.h> |
35 | #include <asm/geode.h> | 35 | #include <linux/cs5535.h> |
36 | 36 | ||
37 | #include "gxfb.h" | 37 | #include "gxfb.h" |
38 | 38 | ||
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/geode/lxfb.h index 6a51448fd3f7..cc781c00f75d 100644 --- a/drivers/video/geode/lxfb.h +++ b/drivers/video/geode/lxfb.h | |||
@@ -1,3 +1,13 @@ | |||
1 | /* Geode LX framebuffer driver | ||
2 | * | ||
3 | * Copyright (C) 2006-2007, Advanced Micro Devices,Inc. | ||
4 | * Copyright (c) 2008 Andres Salomon <dilinger@debian.org> | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | */ | ||
1 | #ifndef _LXFB_H_ | 11 | #ifndef _LXFB_H_ |
2 | #define _LXFB_H_ | 12 | #define _LXFB_H_ |
3 | 13 | ||
@@ -409,7 +419,7 @@ static inline void write_fp(struct lxfb_par *par, int reg, uint32_t val) | |||
409 | } | 419 | } |
410 | 420 | ||
411 | 421 | ||
412 | /* MSRs are defined in asm/geode.h; their bitfields are here */ | 422 | /* MSRs are defined in linux/cs5535.h; their bitfields are here */ |
413 | 423 | ||
414 | #define MSR_GLCP_DOTPLL_LOCK (1 << 25) /* r/o */ | 424 | #define MSR_GLCP_DOTPLL_LOCK (1 << 25) /* r/o */ |
415 | #define MSR_GLCP_DOTPLL_HALFPIX (1 << 24) | 425 | #define MSR_GLCP_DOTPLL_HALFPIX (1 << 24) |
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/geode/lxfb_ops.c index b1cd49c99356..0e5d8c7c3eba 100644 --- a/drivers/video/geode/lxfb_ops.c +++ b/drivers/video/geode/lxfb_ops.c | |||
@@ -13,7 +13,7 @@ | |||
13 | #include <linux/fb.h> | 13 | #include <linux/fb.h> |
14 | #include <linux/uaccess.h> | 14 | #include <linux/uaccess.h> |
15 | #include <linux/delay.h> | 15 | #include <linux/delay.h> |
16 | #include <asm/geode.h> | 16 | #include <linux/cs5535.h> |
17 | 17 | ||
18 | #include "lxfb.h" | 18 | #include "lxfb.h" |
19 | 19 | ||
@@ -307,7 +307,7 @@ unsigned int lx_framebuffer_size(void) | |||
307 | { | 307 | { |
308 | unsigned int val; | 308 | unsigned int val; |
309 | 309 | ||
310 | if (!geode_has_vsa2()) { | 310 | if (!cs5535_has_vsa2()) { |
311 | uint32_t hi, lo; | 311 | uint32_t hi, lo; |
312 | 312 | ||
313 | /* The number of pages is (PMAX - PMIN)+1 */ | 313 | /* The number of pages is (PMAX - PMIN)+1 */ |
diff --git a/drivers/video/geode/suspend_gx.c b/drivers/video/geode/suspend_gx.c index 9aff32ef8bb6..1bb043d70c64 100644 --- a/drivers/video/geode/suspend_gx.c +++ b/drivers/video/geode/suspend_gx.c | |||
@@ -10,7 +10,7 @@ | |||
10 | #include <linux/fb.h> | 10 | #include <linux/fb.h> |
11 | #include <asm/io.h> | 11 | #include <asm/io.h> |
12 | #include <asm/msr.h> | 12 | #include <asm/msr.h> |
13 | #include <asm/geode.h> | 13 | #include <linux/cs5535.h> |
14 | #include <asm/delay.h> | 14 | #include <asm/delay.h> |
15 | 15 | ||
16 | #include "gxfb.h" | 16 | #include "gxfb.h" |
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/geode/video_gx.c index b8d52a8360db..6082f653c68a 100644 --- a/drivers/video/geode/video_gx.c +++ b/drivers/video/geode/video_gx.c | |||
@@ -16,7 +16,7 @@ | |||
16 | #include <asm/io.h> | 16 | #include <asm/io.h> |
17 | #include <asm/delay.h> | 17 | #include <asm/delay.h> |
18 | #include <asm/msr.h> | 18 | #include <asm/msr.h> |
19 | #include <asm/geode.h> | 19 | #include <linux/cs5535.h> |
20 | 20 | ||
21 | #include "gxfb.h" | 21 | #include "gxfb.h" |
22 | 22 | ||
diff --git a/drivers/video/hitfb.c b/drivers/video/hitfb.c index e7116a6d82d3..73c83a8de2d3 100644 --- a/drivers/video/hitfb.c +++ b/drivers/video/hitfb.c | |||
@@ -456,7 +456,7 @@ static int hitfb_resume(struct device *dev) | |||
456 | return 0; | 456 | return 0; |
457 | } | 457 | } |
458 | 458 | ||
459 | static struct dev_pm_ops hitfb_dev_pm_ops = { | 459 | static const struct dev_pm_ops hitfb_dev_pm_ops = { |
460 | .suspend = hitfb_suspend, | 460 | .suspend = hitfb_suspend, |
461 | .resume = hitfb_resume, | 461 | .resume = hitfb_resume, |
462 | }; | 462 | }; |
diff --git a/drivers/video/i810/i810_dvt.c b/drivers/video/i810/i810_dvt.c index 27fa703a2e0a..b4b3670667ab 100644 --- a/drivers/video/i810/i810_dvt.c +++ b/drivers/video/i810/i810_dvt.c | |||
@@ -212,24 +212,29 @@ inline void round_off_yres(u32 *xres, u32 *yres) | |||
212 | *yres = (*xres * 3) >> 2; | 212 | *yres = (*xres * 3) >> 2; |
213 | } | 213 | } |
214 | 214 | ||
215 | void i810fb_encode_registers(const struct fb_var_screeninfo *var, | 215 | static int i810fb_find_best_mode(u32 xres, u32 yres, u32 pixclock) |
216 | struct i810fb_par *par, u32 xres, u32 yres) | ||
217 | { | 216 | { |
218 | u32 diff = 0, diff_best = 0xFFFFFFFF, i = 0, i_best = 0; | 217 | u32 diff = 0, diff_best = 0xFFFFFFFF, i = 0, i_best = 0; |
219 | u8 hfl; | 218 | u8 hfl = (u8) ((xres >> 3) - 1); |
220 | 219 | ||
221 | hfl = (u8) ((xres >> 3) - 1); | ||
222 | for (i = 0; i < ARRAY_SIZE(std_modes); i++) { | 220 | for (i = 0; i < ARRAY_SIZE(std_modes); i++) { |
223 | if (std_modes[i].cr01 == hfl) { | 221 | if (std_modes[i].cr01 == hfl) { |
224 | if (std_modes[i].pixclock <= par->regs.pixclock) | 222 | if (std_modes[i].pixclock <= pixclock) |
225 | diff = par->regs.pixclock - | 223 | diff = pixclock - std_modes[i].pixclock; |
226 | std_modes[i].pixclock; | ||
227 | if (diff < diff_best) { | 224 | if (diff < diff_best) { |
228 | i_best = i; | 225 | i_best = i; |
229 | diff_best = diff; | 226 | diff_best = diff; |
230 | } | 227 | } |
231 | } | 228 | } |
232 | } | 229 | } |
230 | return i_best; | ||
231 | } | ||
232 | |||
233 | void i810fb_encode_registers(const struct fb_var_screeninfo *var, | ||
234 | struct i810fb_par *par, u32 xres, u32 yres) | ||
235 | { | ||
236 | u32 i_best = i810fb_find_best_mode(xres, yres, par->regs.pixclock); | ||
237 | |||
233 | par->regs = std_modes[i_best]; | 238 | par->regs = std_modes[i_best]; |
234 | 239 | ||
235 | /* overlay */ | 240 | /* overlay */ |
@@ -239,36 +244,36 @@ void i810fb_encode_registers(const struct fb_var_screeninfo *var, | |||
239 | 244 | ||
240 | void i810fb_fill_var_timings(struct fb_var_screeninfo *var) | 245 | void i810fb_fill_var_timings(struct fb_var_screeninfo *var) |
241 | { | 246 | { |
242 | struct i810fb_par par; | ||
243 | u32 total, xres, yres; | 247 | u32 total, xres, yres; |
248 | u32 mode, pixclock; | ||
244 | 249 | ||
245 | xres = var->xres; | 250 | xres = var->xres; |
246 | yres = var->yres; | 251 | yres = var->yres; |
247 | 252 | ||
248 | par.regs.pixclock = 1000000000/var->pixclock; | 253 | pixclock = 1000000000 / var->pixclock; |
249 | i810fb_encode_registers(var, &par, xres, yres); | 254 | mode = i810fb_find_best_mode(xres, yres, pixclock); |
250 | 255 | ||
251 | total = ((par.regs.cr00 | (par.regs.cr35 & 1) << 8) + 3) << 3; | 256 | total = (std_modes[mode].cr00 | (std_modes[mode].cr35 & 1) << 8) + 3; |
257 | total <<= 3; | ||
252 | 258 | ||
253 | var->pixclock = 1000000000/par.regs.pixclock; | 259 | var->pixclock = 1000000000 / std_modes[mode].pixclock; |
254 | var->right_margin = (par.regs.cr04 << 3) - xres; | 260 | var->right_margin = (std_modes[mode].cr04 << 3) - xres; |
255 | var->hsync_len = ((par.regs.cr05 & 0x1F) - | 261 | var->hsync_len = ((std_modes[mode].cr05 & 0x1F) - |
256 | (par.regs.cr04 & 0x1F)) << 3; | 262 | (std_modes[mode].cr04 & 0x1F)) << 3; |
257 | var->left_margin = (total - (xres + var->right_margin + | 263 | var->left_margin = (total - (xres + var->right_margin + |
258 | var->hsync_len)); | 264 | var->hsync_len)); |
259 | var->sync = FB_SYNC_ON_GREEN; | 265 | var->sync = FB_SYNC_ON_GREEN; |
260 | if (~(par.regs.msr & (1 << 6))) | 266 | if (~(std_modes[mode].msr & (1 << 6))) |
261 | var->sync |= FB_SYNC_HOR_HIGH_ACT; | 267 | var->sync |= FB_SYNC_HOR_HIGH_ACT; |
262 | if (~(par.regs.msr & (1 << 7))) | 268 | if (~(std_modes[mode].msr & (1 << 7))) |
263 | var->sync |= FB_SYNC_VERT_HIGH_ACT; | 269 | var->sync |= FB_SYNC_VERT_HIGH_ACT; |
264 | 270 | ||
265 | 271 | total = (std_modes[mode].cr06 | (std_modes[mode].cr30 & 0xF) << 8) + 2; | |
266 | total = ((par.regs.cr06 | (par.regs.cr30 & 0x0F) << 8)) + 2; | 272 | var->lower_margin = (std_modes[mode].cr10 | |
267 | var->lower_margin = (par.regs.cr10 | | 273 | (std_modes[mode].cr32 & 0x0F) << 8) - yres; |
268 | (par.regs.cr32 & 0x0F) << 8) - yres; | 274 | var->vsync_len = (std_modes[mode].cr11 & 0x0F) - |
269 | var->vsync_len = (par.regs.cr11 & 0x0F) - (var->lower_margin & 0x0F); | 275 | (var->lower_margin & 0x0F); |
270 | var->upper_margin = total - (yres + var->lower_margin + | 276 | var->upper_margin = total - (yres + var->lower_margin + var->vsync_len); |
271 | var->vsync_len); | ||
272 | } | 277 | } |
273 | 278 | ||
274 | u32 i810_get_watermark(struct fb_var_screeninfo *var, | 279 | u32 i810_get_watermark(struct fb_var_screeninfo *var, |
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c index 0cafd642fbc0..5ba399991050 100644 --- a/drivers/video/intelfb/intelfbdrv.c +++ b/drivers/video/intelfb/intelfbdrv.c | |||
@@ -874,6 +874,9 @@ static int __devinit intelfb_pci_register(struct pci_dev *pdev, | |||
874 | if (bailearly == 18) | 874 | if (bailearly == 18) |
875 | bailout(dinfo); | 875 | bailout(dinfo); |
876 | 876 | ||
877 | /* read active pipe */ | ||
878 | dinfo->pipe = intelfbhw_active_pipe(&dinfo->save_state); | ||
879 | |||
877 | /* Cursor initialisation */ | 880 | /* Cursor initialisation */ |
878 | if (dinfo->hwcursor) { | 881 | if (dinfo->hwcursor) { |
879 | intelfbhw_cursor_init(dinfo); | 882 | intelfbhw_cursor_init(dinfo); |
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c index 0689f97c5238..81627466804e 100644 --- a/drivers/video/intelfb/intelfbhw.c +++ b/drivers/video/intelfb/intelfbhw.c | |||
@@ -469,6 +469,32 @@ void intelfbhw_do_blank(int blank, struct fb_info *info) | |||
469 | } | 469 | } |
470 | 470 | ||
471 | 471 | ||
472 | /* Check which pipe is connected to an active display plane. */ | ||
473 | int intelfbhw_active_pipe(const struct intelfb_hwstate *hw) | ||
474 | { | ||
475 | int pipe = -1; | ||
476 | |||
477 | /* keep old default behaviour - prefer PIPE_A */ | ||
478 | if (hw->disp_b_ctrl & DISPPLANE_PLANE_ENABLE) { | ||
479 | pipe = (hw->disp_b_ctrl >> DISPPLANE_SEL_PIPE_SHIFT); | ||
480 | pipe &= PIPE_MASK; | ||
481 | if (unlikely(pipe == PIPE_A)) | ||
482 | return PIPE_A; | ||
483 | } | ||
484 | if (hw->disp_a_ctrl & DISPPLANE_PLANE_ENABLE) { | ||
485 | pipe = (hw->disp_a_ctrl >> DISPPLANE_SEL_PIPE_SHIFT); | ||
486 | pipe &= PIPE_MASK; | ||
487 | if (likely(pipe == PIPE_A)) | ||
488 | return PIPE_A; | ||
489 | } | ||
490 | /* Impossible that no pipe is selected - return PIPE_A */ | ||
491 | WARN_ON(pipe == -1); | ||
492 | if (unlikely(pipe == -1)) | ||
493 | pipe = PIPE_A; | ||
494 | |||
495 | return pipe; | ||
496 | } | ||
497 | |||
472 | void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, | 498 | void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, |
473 | unsigned red, unsigned green, unsigned blue, | 499 | unsigned red, unsigned green, unsigned blue, |
474 | unsigned transp) | 500 | unsigned transp) |
@@ -1019,7 +1045,7 @@ int intelfbhw_mode_to_hw(struct intelfb_info *dinfo, | |||
1019 | struct intelfb_hwstate *hw, | 1045 | struct intelfb_hwstate *hw, |
1020 | struct fb_var_screeninfo *var) | 1046 | struct fb_var_screeninfo *var) |
1021 | { | 1047 | { |
1022 | int pipe = PIPE_A; | 1048 | int pipe = intelfbhw_active_pipe(hw); |
1023 | u32 *dpll, *fp0, *fp1; | 1049 | u32 *dpll, *fp0, *fp1; |
1024 | u32 m1, m2, n, p1, p2, clock_target, clock; | 1050 | u32 m1, m2, n, p1, p2, clock_target, clock; |
1025 | u32 hsync_start, hsync_end, hblank_start, hblank_end, htotal, hactive; | 1051 | u32 hsync_start, hsync_end, hblank_start, hblank_end, htotal, hactive; |
@@ -1033,12 +1059,6 @@ int intelfbhw_mode_to_hw(struct intelfb_info *dinfo, | |||
1033 | /* Disable VGA */ | 1059 | /* Disable VGA */ |
1034 | hw->vgacntrl |= VGA_DISABLE; | 1060 | hw->vgacntrl |= VGA_DISABLE; |
1035 | 1061 | ||
1036 | /* Check whether pipe A or pipe B is enabled. */ | ||
1037 | if (hw->pipe_a_conf & PIPECONF_ENABLE) | ||
1038 | pipe = PIPE_A; | ||
1039 | else if (hw->pipe_b_conf & PIPECONF_ENABLE) | ||
1040 | pipe = PIPE_B; | ||
1041 | |||
1042 | /* Set which pipe's registers will be set. */ | 1062 | /* Set which pipe's registers will be set. */ |
1043 | if (pipe == PIPE_B) { | 1063 | if (pipe == PIPE_B) { |
1044 | dpll = &hw->dpll_b; | 1064 | dpll = &hw->dpll_b; |
@@ -1262,7 +1282,6 @@ int intelfbhw_mode_to_hw(struct intelfb_info *dinfo, | |||
1262 | int intelfbhw_program_mode(struct intelfb_info *dinfo, | 1282 | int intelfbhw_program_mode(struct intelfb_info *dinfo, |
1263 | const struct intelfb_hwstate *hw, int blank) | 1283 | const struct intelfb_hwstate *hw, int blank) |
1264 | { | 1284 | { |
1265 | int pipe = PIPE_A; | ||
1266 | u32 tmp; | 1285 | u32 tmp; |
1267 | const u32 *dpll, *fp0, *fp1, *pipe_conf; | 1286 | const u32 *dpll, *fp0, *fp1, *pipe_conf; |
1268 | const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss; | 1287 | const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss; |
@@ -1272,7 +1291,7 @@ int intelfbhw_program_mode(struct intelfb_info *dinfo, | |||
1272 | u32 src_size_reg; | 1291 | u32 src_size_reg; |
1273 | u32 count, tmp_val[3]; | 1292 | u32 count, tmp_val[3]; |
1274 | 1293 | ||
1275 | /* Assume single pipe, display plane A, analog CRT. */ | 1294 | /* Assume single pipe */ |
1276 | 1295 | ||
1277 | #if VERBOSE > 0 | 1296 | #if VERBOSE > 0 |
1278 | DBG_MSG("intelfbhw_program_mode\n"); | 1297 | DBG_MSG("intelfbhw_program_mode\n"); |
@@ -1283,15 +1302,9 @@ int intelfbhw_program_mode(struct intelfb_info *dinfo, | |||
1283 | tmp |= VGA_DISABLE; | 1302 | tmp |= VGA_DISABLE; |
1284 | OUTREG(VGACNTRL, tmp); | 1303 | OUTREG(VGACNTRL, tmp); |
1285 | 1304 | ||
1286 | /* Check whether pipe A or pipe B is enabled. */ | 1305 | dinfo->pipe = intelfbhw_active_pipe(hw); |
1287 | if (hw->pipe_a_conf & PIPECONF_ENABLE) | ||
1288 | pipe = PIPE_A; | ||
1289 | else if (hw->pipe_b_conf & PIPECONF_ENABLE) | ||
1290 | pipe = PIPE_B; | ||
1291 | |||
1292 | dinfo->pipe = pipe; | ||
1293 | 1306 | ||
1294 | if (pipe == PIPE_B) { | 1307 | if (dinfo->pipe == PIPE_B) { |
1295 | dpll = &hw->dpll_b; | 1308 | dpll = &hw->dpll_b; |
1296 | fp0 = &hw->fpb0; | 1309 | fp0 = &hw->fpb0; |
1297 | fp1 = &hw->fpb1; | 1310 | fp1 = &hw->fpb1; |
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h index 0b076bac321b..216ca20f259f 100644 --- a/drivers/video/intelfb/intelfbhw.h +++ b/drivers/video/intelfb/intelfbhw.h | |||
@@ -604,5 +604,6 @@ extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo); | |||
604 | extern int intelfbhw_enable_irq(struct intelfb_info *dinfo); | 604 | extern int intelfbhw_enable_irq(struct intelfb_info *dinfo); |
605 | extern void intelfbhw_disable_irq(struct intelfb_info *dinfo); | 605 | extern void intelfbhw_disable_irq(struct intelfb_info *dinfo); |
606 | extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe); | 606 | extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe); |
607 | extern int intelfbhw_active_pipe(const struct intelfb_hwstate *hw); | ||
607 | 608 | ||
608 | #endif /* _INTELFBHW_H */ | 609 | #endif /* _INTELFBHW_H */ |
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/matrox/g450_pll.c index 09f6e045d5be..c15f8a57498e 100644 --- a/drivers/video/matrox/g450_pll.c +++ b/drivers/video/matrox/g450_pll.c | |||
@@ -368,7 +368,8 @@ static int __g450_setclk(struct matrox_fb_info *minfo, unsigned int fout, | |||
368 | M1064_XDVICLKCTRL_C1DVICLKEN | | 368 | M1064_XDVICLKCTRL_C1DVICLKEN | |
369 | M1064_XDVICLKCTRL_DVILOOPCTL | | 369 | M1064_XDVICLKCTRL_DVILOOPCTL | |
370 | M1064_XDVICLKCTRL_P1LOOPBWDTCTL; | 370 | M1064_XDVICLKCTRL_P1LOOPBWDTCTL; |
371 | matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp); | 371 | /* Setting this breaks PC systems so don't do it */ |
372 | /* matroxfb_DAC_out(minfo, M1064_XDVICLKCTRL, tmp); */ | ||
372 | matroxfb_DAC_out(minfo, M1064_XPWRCTRL, | 373 | matroxfb_DAC_out(minfo, M1064_XPWRCTRL, |
373 | xpwrctrl); | 374 | xpwrctrl); |
374 | 375 | ||
diff --git a/drivers/video/maxinefb.c b/drivers/video/maxinefb.c index 5e91c2b30af9..7854c7a37dc5 100644 --- a/drivers/video/maxinefb.c +++ b/drivers/video/maxinefb.c | |||
@@ -92,6 +92,9 @@ static int maxinefb_setcolreg(unsigned regno, unsigned red, unsigned green, | |||
92 | /* value to be written into the palette reg. */ | 92 | /* value to be written into the palette reg. */ |
93 | unsigned long hw_colorvalue = 0; | 93 | unsigned long hw_colorvalue = 0; |
94 | 94 | ||
95 | if (regno > 255) | ||
96 | return 1; | ||
97 | |||
95 | red >>= 8; /* The cmap fields are 16 bits */ | 98 | red >>= 8; /* The cmap fields are 16 bits */ |
96 | green >>= 8; /* wide, but the harware colormap */ | 99 | green >>= 8; /* wide, but the harware colormap */ |
97 | blue >>= 8; /* registers are only 8 bits wide */ | 100 | blue >>= 8; /* registers are only 8 bits wide */ |
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/mb862xx/Makefile index 07664814bb1d..d7777714166b 100644 --- a/drivers/video/mb862xx/Makefile +++ b/drivers/video/mb862xx/Makefile | |||
@@ -2,4 +2,4 @@ | |||
2 | # Makefile for the MB862xx framebuffer driver | 2 | # Makefile for the MB862xx framebuffer driver |
3 | # | 3 | # |
4 | 4 | ||
5 | obj-$(CONFIG_FB_MB862XX) := mb862xxfb.o | 5 | obj-$(CONFIG_FB_MB862XX) := mb862xxfb.o mb862xxfb_accel.o |
diff --git a/drivers/video/mb862xx/mb862xxfb.c b/drivers/video/mb862xx/mb862xxfb.c index a28e3cfbbf70..fabb0c59a211 100644 --- a/drivers/video/mb862xx/mb862xxfb.c +++ b/drivers/video/mb862xx/mb862xxfb.c | |||
@@ -214,6 +214,8 @@ static int mb862xxfb_set_par(struct fb_info *fbi) | |||
214 | unsigned long reg, sc; | 214 | unsigned long reg, sc; |
215 | 215 | ||
216 | dev_dbg(par->dev, "%s\n", __func__); | 216 | dev_dbg(par->dev, "%s\n", __func__); |
217 | if (par->type == BT_CORALP) | ||
218 | mb862xxfb_init_accel(fbi, fbi->var.xres); | ||
217 | 219 | ||
218 | if (par->pre_init) | 220 | if (par->pre_init) |
219 | return 0; | 221 | return 0; |
@@ -453,6 +455,18 @@ static ssize_t mb862xxfb_show_dispregs(struct device *dev, | |||
453 | ptr += sprintf(ptr, "%08x = %08x\n", | 455 | ptr += sprintf(ptr, "%08x = %08x\n", |
454 | reg, inreg(disp, reg)); | 456 | reg, inreg(disp, reg)); |
455 | 457 | ||
458 | for (reg = 0x400; reg <= 0x410; reg += 4) | ||
459 | ptr += sprintf(ptr, "geo %08x = %08x\n", | ||
460 | reg, inreg(geo, reg)); | ||
461 | |||
462 | for (reg = 0x400; reg <= 0x410; reg += 4) | ||
463 | ptr += sprintf(ptr, "draw %08x = %08x\n", | ||
464 | reg, inreg(draw, reg)); | ||
465 | |||
466 | for (reg = 0x440; reg <= 0x450; reg += 4) | ||
467 | ptr += sprintf(ptr, "draw %08x = %08x\n", | ||
468 | reg, inreg(draw, reg)); | ||
469 | |||
456 | return ptr - buf; | 470 | return ptr - buf; |
457 | } | 471 | } |
458 | 472 | ||
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/mb862xx/mb862xxfb.h index c4c8f4dd2217..d7e7cb76bbf2 100644 --- a/drivers/video/mb862xx/mb862xxfb.h +++ b/drivers/video/mb862xx/mb862xxfb.h | |||
@@ -61,6 +61,8 @@ struct mb862xxfb_par { | |||
61 | u32 pseudo_palette[16]; | 61 | u32 pseudo_palette[16]; |
62 | }; | 62 | }; |
63 | 63 | ||
64 | extern void mb862xxfb_init_accel(struct fb_info *info, int xres); | ||
65 | |||
64 | #if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC) | 66 | #if defined(CONFIG_FB_MB862XX_LIME) && defined(CONFIG_FB_MB862XX_PCI_GDC) |
65 | #error "Select Lime GDC or CoralP/Carmine support, but not both together" | 67 | #error "Select Lime GDC or CoralP/Carmine support, but not both together" |
66 | #endif | 68 | #endif |
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/mb862xx/mb862xxfb_accel.c new file mode 100644 index 000000000000..049256052b1a --- /dev/null +++ b/drivers/video/mb862xx/mb862xxfb_accel.c | |||
@@ -0,0 +1,331 @@ | |||
1 | /* | ||
2 | * drivers/mb862xx/mb862xxfb_accel.c | ||
3 | * | ||
4 | * Fujitsu Carmine/Coral-P(A)/Lime framebuffer driver acceleration support | ||
5 | * | ||
6 | * (C) 2007 Alexander Shishkin <virtuoso@slind.org> | ||
7 | * (C) 2009 Valentin Sitdikov <valentin.sitdikov@siemens.com> | ||
8 | * (C) 2009 Siemens AG | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify | ||
11 | * it under the terms of the GNU General Public License version 2 as | ||
12 | * published by the Free Software Foundation. | ||
13 | * | ||
14 | */ | ||
15 | #include <linux/fb.h> | ||
16 | #include <linux/delay.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/interrupt.h> | ||
19 | #include <linux/pci.h> | ||
20 | #if defined(CONFIG_OF) | ||
21 | #include <linux/of_platform.h> | ||
22 | #endif | ||
23 | #include "mb862xxfb.h" | ||
24 | #include "mb862xx_reg.h" | ||
25 | #include "mb862xxfb_accel.h" | ||
26 | |||
27 | static void mb862xxfb_write_fifo(u32 count, u32 *data, struct fb_info *info) | ||
28 | { | ||
29 | struct mb862xxfb_par *par = info->par; | ||
30 | static u32 free; | ||
31 | |||
32 | u32 total = 0; | ||
33 | while (total < count) { | ||
34 | if (free) { | ||
35 | outreg(geo, GDC_GEO_REG_INPUT_FIFO, data[total]); | ||
36 | total++; | ||
37 | free--; | ||
38 | } else { | ||
39 | free = (u32) inreg(draw, GDC_REG_FIFO_COUNT); | ||
40 | } | ||
41 | } | ||
42 | } | ||
43 | |||
44 | static void mb86290fb_copyarea(struct fb_info *info, | ||
45 | const struct fb_copyarea *area) | ||
46 | { | ||
47 | __u32 cmd[6]; | ||
48 | |||
49 | cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; | ||
50 | /* Set raster operation */ | ||
51 | cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); | ||
52 | cmd[2] = GDC_TYPE_BLTCOPYP << 24; | ||
53 | |||
54 | if (area->sx >= area->dx && area->sy >= area->dy) | ||
55 | cmd[2] |= GDC_CMD_BLTCOPY_TOP_LEFT << 16; | ||
56 | else if (area->sx >= area->dx && area->sy <= area->dy) | ||
57 | cmd[2] |= GDC_CMD_BLTCOPY_BOTTOM_LEFT << 16; | ||
58 | else if (area->sx <= area->dx && area->sy >= area->dy) | ||
59 | cmd[2] |= GDC_CMD_BLTCOPY_TOP_RIGHT << 16; | ||
60 | else | ||
61 | cmd[2] |= GDC_CMD_BLTCOPY_BOTTOM_RIGHT << 16; | ||
62 | |||
63 | cmd[3] = (area->sy << 16) | area->sx; | ||
64 | cmd[4] = (area->dy << 16) | area->dx; | ||
65 | cmd[5] = (area->height << 16) | area->width; | ||
66 | mb862xxfb_write_fifo(6, cmd, info); | ||
67 | } | ||
68 | |||
69 | /* | ||
70 | * Fill in the cmd array /GDC FIFO commands/ to draw a 1bit image. | ||
71 | * Make sure cmd has enough room! | ||
72 | */ | ||
73 | static void mb86290fb_imageblit1(u32 *cmd, u16 step, u16 dx, u16 dy, | ||
74 | u16 width, u16 height, u32 fgcolor, | ||
75 | u32 bgcolor, const struct fb_image *image, | ||
76 | struct fb_info *info) | ||
77 | { | ||
78 | int i; | ||
79 | unsigned const char *line; | ||
80 | u16 bytes; | ||
81 | |||
82 | /* set colors and raster operation regs */ | ||
83 | cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; | ||
84 | /* Set raster operation */ | ||
85 | cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); | ||
86 | cmd[2] = | ||
87 | (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_FORE_COLOR << 16); | ||
88 | cmd[3] = fgcolor; | ||
89 | cmd[4] = | ||
90 | (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_BACK_COLOR << 16); | ||
91 | cmd[5] = bgcolor; | ||
92 | |||
93 | i = 0; | ||
94 | line = image->data; | ||
95 | bytes = (image->width + 7) >> 3; | ||
96 | |||
97 | /* and the image */ | ||
98 | cmd[6] = (GDC_TYPE_DRAWBITMAPP << 24) | | ||
99 | (GDC_CMD_BITMAP << 16) | (2 + (step * height)); | ||
100 | cmd[7] = (dy << 16) | dx; | ||
101 | cmd[8] = (height << 16) | width; | ||
102 | |||
103 | while (i < height) { | ||
104 | memcpy(&cmd[9 + i * step], line, step << 2); | ||
105 | #ifdef __LITTLE_ENDIAN | ||
106 | { | ||
107 | int k = 0; | ||
108 | for (k = 0; k < step; k++) | ||
109 | cmd[9 + i * step + k] = | ||
110 | cpu_to_be32(cmd[9 + i * step + k]); | ||
111 | } | ||
112 | #endif | ||
113 | line += bytes; | ||
114 | i++; | ||
115 | } | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * Fill in the cmd array /GDC FIFO commands/ to draw a 8bit image. | ||
120 | * Make sure cmd has enough room! | ||
121 | */ | ||
122 | static void mb86290fb_imageblit8(u32 *cmd, u16 step, u16 dx, u16 dy, | ||
123 | u16 width, u16 height, u32 fgcolor, | ||
124 | u32 bgcolor, const struct fb_image *image, | ||
125 | struct fb_info *info) | ||
126 | { | ||
127 | int i, j; | ||
128 | unsigned const char *line, *ptr; | ||
129 | u16 bytes; | ||
130 | |||
131 | cmd[0] = (GDC_TYPE_DRAWBITMAPP << 24) | | ||
132 | (GDC_CMD_BLT_DRAW << 16) | (2 + (height * step)); | ||
133 | cmd[1] = (dy << 16) | dx; | ||
134 | cmd[2] = (height << 16) | width; | ||
135 | |||
136 | i = 0; | ||
137 | line = ptr = image->data; | ||
138 | bytes = image->width; | ||
139 | |||
140 | while (i < height) { | ||
141 | ptr = line; | ||
142 | for (j = 0; j < step; j++) { | ||
143 | cmd[3 + i * step + j] = | ||
144 | (((u32 *) (info->pseudo_palette))[*ptr]) & 0xffff; | ||
145 | ptr++; | ||
146 | cmd[3 + i * step + j] |= | ||
147 | ((((u32 *) (info-> | ||
148 | pseudo_palette))[*ptr]) & 0xffff) << 16; | ||
149 | ptr++; | ||
150 | } | ||
151 | |||
152 | line += bytes; | ||
153 | i++; | ||
154 | } | ||
155 | } | ||
156 | |||
157 | /* | ||
158 | * Fill in the cmd array /GDC FIFO commands/ to draw a 16bit image. | ||
159 | * Make sure cmd has enough room! | ||
160 | */ | ||
161 | static void mb86290fb_imageblit16(u32 *cmd, u16 step, u16 dx, u16 dy, | ||
162 | u16 width, u16 height, u32 fgcolor, | ||
163 | u32 bgcolor, const struct fb_image *image, | ||
164 | struct fb_info *info) | ||
165 | { | ||
166 | int i; | ||
167 | unsigned const char *line; | ||
168 | u16 bytes; | ||
169 | |||
170 | i = 0; | ||
171 | line = image->data; | ||
172 | bytes = image->width << 1; | ||
173 | |||
174 | cmd[0] = (GDC_TYPE_DRAWBITMAPP << 24) | | ||
175 | (GDC_CMD_BLT_DRAW << 16) | (2 + step * height); | ||
176 | cmd[1] = (dy << 16) | dx; | ||
177 | cmd[2] = (height << 16) | width; | ||
178 | |||
179 | while (i < height) { | ||
180 | memcpy(&cmd[3 + i * step], line, step); | ||
181 | line += bytes; | ||
182 | i++; | ||
183 | } | ||
184 | } | ||
185 | |||
186 | static void mb86290fb_imageblit(struct fb_info *info, | ||
187 | const struct fb_image *image) | ||
188 | { | ||
189 | int mdr; | ||
190 | u32 *cmd = NULL; | ||
191 | void (*cmdfn) (u32 *, u16, u16, u16, u16, u16, u32, u32, | ||
192 | const struct fb_image *, struct fb_info *) = NULL; | ||
193 | u32 cmdlen; | ||
194 | u32 fgcolor = 0, bgcolor = 0; | ||
195 | u16 step; | ||
196 | |||
197 | u16 width = image->width, height = image->height; | ||
198 | u16 dx = image->dx, dy = image->dy; | ||
199 | int x2, y2, vxres, vyres; | ||
200 | |||
201 | mdr = (GDC_ROP_COPY << 9); | ||
202 | x2 = image->dx + image->width; | ||
203 | y2 = image->dy + image->height; | ||
204 | vxres = info->var.xres_virtual; | ||
205 | vyres = info->var.yres_virtual; | ||
206 | x2 = min(x2, vxres); | ||
207 | y2 = min(y2, vyres); | ||
208 | width = x2 - dx; | ||
209 | height = y2 - dy; | ||
210 | |||
211 | switch (image->depth) { | ||
212 | case 1: | ||
213 | step = (width + 31) >> 5; | ||
214 | cmdlen = 9 + height * step; | ||
215 | cmdfn = mb86290fb_imageblit1; | ||
216 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
217 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) { | ||
218 | fgcolor = | ||
219 | ((u32 *) (info->pseudo_palette))[image->fg_color]; | ||
220 | bgcolor = | ||
221 | ((u32 *) (info->pseudo_palette))[image->bg_color]; | ||
222 | } else { | ||
223 | fgcolor = image->fg_color; | ||
224 | bgcolor = image->bg_color; | ||
225 | } | ||
226 | |||
227 | break; | ||
228 | |||
229 | case 8: | ||
230 | step = (width + 1) >> 1; | ||
231 | cmdlen = 3 + height * step; | ||
232 | cmdfn = mb86290fb_imageblit8; | ||
233 | break; | ||
234 | |||
235 | case 16: | ||
236 | step = (width + 1) >> 1; | ||
237 | cmdlen = 3 + height * step; | ||
238 | cmdfn = mb86290fb_imageblit16; | ||
239 | break; | ||
240 | |||
241 | default: | ||
242 | cfb_imageblit(info, image); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | cmd = kmalloc(cmdlen * 4, GFP_DMA); | ||
247 | if (!cmd) | ||
248 | return cfb_imageblit(info, image); | ||
249 | cmdfn(cmd, step, dx, dy, width, height, fgcolor, bgcolor, image, info); | ||
250 | mb862xxfb_write_fifo(cmdlen, cmd, info); | ||
251 | kfree(cmd); | ||
252 | } | ||
253 | |||
254 | static void mb86290fb_fillrect(struct fb_info *info, | ||
255 | const struct fb_fillrect *rect) | ||
256 | { | ||
257 | |||
258 | u32 x2, y2, vxres, vyres, height, width, fg; | ||
259 | u32 cmd[7]; | ||
260 | |||
261 | vxres = info->var.xres_virtual; | ||
262 | vyres = info->var.yres_virtual; | ||
263 | |||
264 | if (!rect->width || !rect->height || rect->dx > vxres | ||
265 | || rect->dy > vyres) | ||
266 | return; | ||
267 | |||
268 | /* We could use hardware clipping but on many cards you get around | ||
269 | * hardware clipping by writing to framebuffer directly. */ | ||
270 | x2 = rect->dx + rect->width; | ||
271 | y2 = rect->dy + rect->height; | ||
272 | x2 = min(x2, vxres); | ||
273 | y2 = min(y2, vyres); | ||
274 | width = x2 - rect->dx; | ||
275 | height = y2 - rect->dy; | ||
276 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | ||
277 | info->fix.visual == FB_VISUAL_DIRECTCOLOR) | ||
278 | fg = ((u32 *) (info->pseudo_palette))[rect->color]; | ||
279 | else | ||
280 | fg = rect->color; | ||
281 | |||
282 | switch (rect->rop) { | ||
283 | |||
284 | case ROP_XOR: | ||
285 | /* Set raster operation */ | ||
286 | cmd[1] = (2 << 7) | (GDC_ROP_XOR << 9); | ||
287 | break; | ||
288 | |||
289 | case ROP_COPY: | ||
290 | /* Set raster operation */ | ||
291 | cmd[1] = (2 << 7) | (GDC_ROP_COPY << 9); | ||
292 | break; | ||
293 | |||
294 | } | ||
295 | |||
296 | cmd[0] = (GDC_TYPE_SETREGISTER << 24) | (1 << 16) | GDC_REG_MODE_BITMAP; | ||
297 | /* cmd[1] set earlier */ | ||
298 | cmd[2] = | ||
299 | (GDC_TYPE_SETCOLORREGISTER << 24) | (GDC_CMD_BODY_FORE_COLOR << 16); | ||
300 | cmd[3] = fg; | ||
301 | cmd[4] = (GDC_TYPE_DRAWRECTP << 24) | (GDC_CMD_BLT_FILL << 16); | ||
302 | cmd[5] = (rect->dy << 16) | (rect->dx); | ||
303 | cmd[6] = (height << 16) | width; | ||
304 | |||
305 | mb862xxfb_write_fifo(7, cmd, info); | ||
306 | } | ||
307 | |||
308 | void mb862xxfb_init_accel(struct fb_info *info, int xres) | ||
309 | { | ||
310 | struct mb862xxfb_par *par = info->par; | ||
311 | |||
312 | if (info->var.bits_per_pixel == 32) { | ||
313 | info->fbops->fb_fillrect = cfb_fillrect; | ||
314 | info->fbops->fb_copyarea = cfb_copyarea; | ||
315 | info->fbops->fb_imageblit = cfb_imageblit; | ||
316 | } else { | ||
317 | outreg(disp, GC_L0EM, 3); | ||
318 | info->fbops->fb_fillrect = mb86290fb_fillrect; | ||
319 | info->fbops->fb_copyarea = mb86290fb_copyarea; | ||
320 | info->fbops->fb_imageblit = mb86290fb_imageblit; | ||
321 | } | ||
322 | outreg(draw, GDC_REG_DRAW_BASE, 0); | ||
323 | outreg(draw, GDC_REG_MODE_MISC, 0x8000); | ||
324 | outreg(draw, GDC_REG_X_RESOLUTION, xres); | ||
325 | |||
326 | info->flags |= | ||
327 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | | ||
328 | FBINFO_HWACCEL_IMAGEBLIT; | ||
329 | info->fix.accel = 0xff; /*FIXME: add right define */ | ||
330 | } | ||
331 | EXPORT_SYMBOL(mb862xxfb_init_accel); | ||
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.h b/drivers/video/mb862xx/mb862xxfb_accel.h new file mode 100644 index 000000000000..96a2dfef0f60 --- /dev/null +++ b/drivers/video/mb862xx/mb862xxfb_accel.h | |||
@@ -0,0 +1,203 @@ | |||
1 | #ifndef __MB826XXFB_ACCEL_H__ | ||
2 | #define __MB826XXFB_ACCEL_H__ | ||
3 | |||
4 | /* registers */ | ||
5 | #define GDC_GEO_REG_INPUT_FIFO 0x00000400L | ||
6 | |||
7 | /* Special Registers */ | ||
8 | #define GDC_REG_CTRL 0x00000400L | ||
9 | #define GDC_REG_FIFO_STATUS 0x00000404L | ||
10 | #define GDC_REG_FIFO_COUNT 0x00000408L | ||
11 | #define GDC_REG_SETUP_STATUS 0x0000040CL | ||
12 | #define GDC_REG_DDA_STATUS 0x00000410L | ||
13 | #define GDC_REG_ENGINE_STATUS 0x00000414L | ||
14 | #define GDC_REG_ERROR_STATUS 0x00000418L | ||
15 | #define GDC_REG_MODE_MISC 0x00000420L /* MDR0 */ | ||
16 | #define GDC_REG_MODE_LINE 0x00000424L /* MDR1 */ | ||
17 | #define GDC_REG_MODE_POLYGON 0x00000428L /* MDR2 */ | ||
18 | #define GDC_REG_MODE_TEXTURE 0x0000042CL /* MDR3 */ | ||
19 | #define GDC_REG_MODE_BITMAP 0x00000430L /* MDR4 */ | ||
20 | #define GDC_REG_MODE_EXTENSION 0x0000043CL /* MDR7 */ | ||
21 | |||
22 | /* Configuration Registers */ | ||
23 | #define GDC_REG_DRAW_BASE 0x00000440L | ||
24 | #define GDC_REG_X_RESOLUTION 0x00000444L | ||
25 | #define GDC_REG_Z_BASE 0x00000448L | ||
26 | #define GDC_REG_TEXTURE_BASE 0x0000044CL | ||
27 | #define GDC_REG_POLYGON_FLAG_BASE 0x00000450L | ||
28 | #define GDC_REG_CLIP_XMIN 0x00000454L | ||
29 | #define GDC_REG_CLIP_XMAX 0x00000458L | ||
30 | #define GDC_REG_CLIP_YMIN 0x0000045CL | ||
31 | #define GDC_REG_CLIP_YMAX 0x00000460L | ||
32 | #define GDC_REG_TEXURE_SIZE 0x00000464L | ||
33 | #define GDC_REG_TILE_SIZE 0x00000468L | ||
34 | #define GDC_REG_TEX_BUF_OFFSET 0x0000046CL | ||
35 | |||
36 | /* for MB86293 or later */ | ||
37 | #define GDC_REG_ALPHA_MAP_BASE 0x00000474L /* ABR */ | ||
38 | |||
39 | /* Constant Registers */ | ||
40 | #define GDC_REG_FOREGROUND_COLOR 0x00000480L | ||
41 | #define GDC_REG_BACKGROUND_COLOR 0x00000484L | ||
42 | #define GDC_REG_ALPHA 0x00000488L | ||
43 | #define GDC_REG_LINE_PATTERN 0x0000048CL | ||
44 | #define GDC_REG_TEX_BORDER_COLOR 0x00000494L | ||
45 | #define GDC_REG_LINE_PATTERN_OFFSET 0x000003E0L | ||
46 | |||
47 | /* Coomand Code */ | ||
48 | #define GDC_CMD_PIXEL 0x00000000L | ||
49 | #define GDC_CMD_PIXEL_Z 0x00000001L | ||
50 | |||
51 | #define GDC_CMD_X_VECTOR 0x00000020L | ||
52 | #define GDC_CMD_Y_VECTOR 0x00000021L | ||
53 | #define GDC_CMD_X_VECTOR_NOEND 0x00000022L | ||
54 | #define GDC_CMD_Y_VECTOR_NOEND 0x00000023L | ||
55 | #define GDC_CMD_X_VECTOR_BLPO 0x00000024L | ||
56 | #define GDC_CMD_Y_VECTOR_BLPO 0x00000025L | ||
57 | #define GDC_CMD_X_VECTOR_NOEND_BLPO 0x00000026L | ||
58 | #define GDC_CMD_Y_VECTOR_NOEND_BLPO 0x00000027L | ||
59 | #define GDC_CMD_AA_X_VECTOR 0x00000028L | ||
60 | #define GDC_CMD_AA_Y_VECTOR 0x00000029L | ||
61 | #define GDC_CMD_AA_X_VECTOR_NOEND 0x0000002AL | ||
62 | #define GDC_CMD_AA_Y_VECTOR_NOEND 0x0000002BL | ||
63 | #define GDC_CMD_AA_X_VECTOR_BLPO 0x0000002CL | ||
64 | #define GDC_CMD_AA_Y_VECTOR_BLPO 0x0000002DL | ||
65 | #define GDC_CMD_AA_X_VECTOR_NOEND_BLPO 0x0000002EL | ||
66 | #define GDC_CMD_AA_Y_VECTOR_NOEND_BLPO 0x0000002FL | ||
67 | |||
68 | #define GDC_CMD_0_VECTOR 0x00000030L | ||
69 | #define GDC_CMD_1_VECTOR 0x00000031L | ||
70 | #define GDC_CMD_0_VECTOR_NOEND 0x00000032L | ||
71 | #define GDC_CMD_1_VECTOR_NOEND 0x00000033L | ||
72 | #define GDC_CMD_0_VECTOR_BLPO 0x00000034L | ||
73 | #define GDC_CMD_1_VECTOR_BLPO 0x00000035L | ||
74 | #define GDC_CMD_0_VECTOR_NOEND_BLPO 0x00000036L | ||
75 | #define GDC_CMD_1_VECTOR_NOEND_BLPO 0x00000037L | ||
76 | #define GDC_CMD_AA_0_VECTOR 0x00000038L | ||
77 | #define GDC_CMD_AA_1_VECTOR 0x00000039L | ||
78 | #define GDC_CMD_AA_0_VECTOR_NOEND 0x0000003AL | ||
79 | #define GDC_CMD_AA_1_VECTOR_NOEND 0x0000003BL | ||
80 | #define GDC_CMD_AA_0_VECTOR_BLPO 0x0000003CL | ||
81 | #define GDC_CMD_AA_1_VECTOR_BLPO 0x0000003DL | ||
82 | #define GDC_CMD_AA_0_VECTOR_NOEND_BLPO 0x0000003EL | ||
83 | #define GDC_CMD_AA_1_VECTOR_NOEND_BLPO 0x0000003FL | ||
84 | |||
85 | #define GDC_CMD_BLT_FILL 0x00000041L | ||
86 | #define GDC_CMD_BLT_DRAW 0x00000042L | ||
87 | #define GDC_CMD_BITMAP 0x00000043L | ||
88 | #define GDC_CMD_BLTCOPY_TOP_LEFT 0x00000044L | ||
89 | #define GDC_CMD_BLTCOPY_TOP_RIGHT 0x00000045L | ||
90 | #define GDC_CMD_BLTCOPY_BOTTOM_LEFT 0x00000046L | ||
91 | #define GDC_CMD_BLTCOPY_BOTTOM_RIGHT 0x00000047L | ||
92 | #define GDC_CMD_LOAD_TEXTURE 0x00000048L | ||
93 | #define GDC_CMD_LOAD_TILE 0x00000049L | ||
94 | |||
95 | #define GDC_CMD_TRAP_RIGHT 0x00000060L | ||
96 | #define GDC_CMD_TRAP_LEFT 0x00000061L | ||
97 | #define GDC_CMD_TRIANGLE_FAN 0x00000062L | ||
98 | #define GDC_CMD_FLAG_TRIANGLE_FAN 0x00000063L | ||
99 | |||
100 | #define GDC_CMD_FLUSH_FB 0x000000C1L | ||
101 | #define GDC_CMD_FLUSH_Z 0x000000C2L | ||
102 | |||
103 | #define GDC_CMD_POLYGON_BEGIN 0x000000E0L | ||
104 | #define GDC_CMD_POLYGON_END 0x000000E1L | ||
105 | #define GDC_CMD_CLEAR_POLY_FLAG 0x000000E2L | ||
106 | #define GDC_CMD_NORMAL 0x000000FFL | ||
107 | |||
108 | #define GDC_CMD_VECTOR_BLPO_FLAG 0x00040000L | ||
109 | #define GDC_CMD_FAST_VECTOR_BLPO_FLAG 0x00000004L | ||
110 | |||
111 | /* for MB86293 or later */ | ||
112 | #define GDC_CMD_MDR1 0x00000000L | ||
113 | #define GDC_CMD_MDR1S 0x00000002L | ||
114 | #define GDC_CMD_MDR1B 0x00000004L | ||
115 | #define GDC_CMD_MDR2 0x00000001L | ||
116 | #define GDC_CMD_MDR2S 0x00000003L | ||
117 | #define GDC_CMD_MDR2TL 0x00000007L | ||
118 | #define GDC_CMD_GMDR1E 0x00000010L | ||
119 | #define GDC_CMD_GMDR2E 0x00000020L | ||
120 | #define GDC_CMD_OVERLAP_SHADOW_XY 0x00000000L | ||
121 | #define GDC_CMD_OVERLAP_SHADOW_XY_COMPOSITION 0x00000001L | ||
122 | #define GDC_CMD_OVERLAP_Z_PACKED_ONBS 0x00000007L | ||
123 | #define GDC_CMD_OVERLAP_Z_ORIGIN 0x00000000L | ||
124 | #define GDC_CMD_OVERLAP_Z_NON_TOPLEFT 0x00000001L | ||
125 | #define GDC_CMD_OVERLAP_Z_BORDER 0x00000002L | ||
126 | #define GDC_CMD_OVERLAP_Z_SHADOW 0x00000003L | ||
127 | #define GDC_CMD_BLTCOPY_ALT_ALPHA 0x00000000L /* Reserverd */ | ||
128 | #define GDC_CMD_DC_LOGOUT 0x00000000L /* Reserverd */ | ||
129 | #define GDC_CMD_BODY_FORE_COLOR 0x00000000L | ||
130 | #define GDC_CMD_BODY_BACK_COLOR 0x00000001L | ||
131 | #define GDC_CMD_SHADOW_FORE_COLOR 0x00000002L | ||
132 | #define GDC_CMD_SHADOW_BACK_COLOR 0x00000003L | ||
133 | #define GDC_CMD_BORDER_FORE_COLOR 0x00000004L | ||
134 | #define GDC_CMD_BORDER_BACK_COLOR 0x00000005L | ||
135 | |||
136 | /* Type Code Table */ | ||
137 | #define GDC_TYPE_G_NOP 0x00000020L | ||
138 | #define GDC_TYPE_G_BEGIN 0x00000021L | ||
139 | #define GDC_TYPE_G_BEGINCONT 0x00000022L | ||
140 | #define GDC_TYPE_G_END 0x00000023L | ||
141 | #define GDC_TYPE_G_VERTEX 0x00000030L | ||
142 | #define GDC_TYPE_G_VERTEXLOG 0x00000032L | ||
143 | #define GDC_TYPE_G_VERTEXNOPLOG 0x00000033L | ||
144 | #define GDC_TYPE_G_INIT 0x00000040L | ||
145 | #define GDC_TYPE_G_VIEWPORT 0x00000041L | ||
146 | #define GDC_TYPE_G_DEPTHRANGE 0x00000042L | ||
147 | #define GDC_TYPE_G_LOADMATRIX 0x00000043L | ||
148 | #define GDC_TYPE_G_VIEWVOLUMEXYCLIP 0x00000044L | ||
149 | #define GDC_TYPE_G_VIEWVOLUMEZCLIP 0x00000045L | ||
150 | #define GDC_TYPE_G_VIEWVOLUMEWCLIP 0x00000046L | ||
151 | #define GDC_TYPE_SETLVERTEX2I 0x00000072L | ||
152 | #define GDC_TYPE_SETLVERTEX2IP 0x00000073L | ||
153 | #define GDC_TYPE_SETMODEREGISTER 0x000000C0L | ||
154 | #define GDC_TYPE_SETGMODEREGISTER 0x000000C1L | ||
155 | #define GDC_TYPE_OVERLAPXYOFFT 0x000000C8L | ||
156 | #define GDC_TYPE_OVERLAPZOFFT 0x000000C9L | ||
157 | #define GDC_TYPE_DC_LOGOUTADDR 0x000000CCL | ||
158 | #define GDC_TYPE_SETCOLORREGISTER 0x000000CEL | ||
159 | #define GDC_TYPE_G_BEGINE 0x000000E1L | ||
160 | #define GDC_TYPE_G_BEGINCONTE 0x000000E2L | ||
161 | #define GDC_TYPE_G_ENDE 0x000000E3L | ||
162 | #define GDC_TYPE_DRAWPIXEL 0x00000000L | ||
163 | #define GDC_TYPE_DRAWPIXELZ 0x00000001L | ||
164 | #define GDC_TYPE_DRAWLINE 0x00000002L | ||
165 | #define GDC_TYPE_DRAWLINE2I 0x00000003L | ||
166 | #define GDC_TYPE_DRAWLINE2IP 0x00000004L | ||
167 | #define GDC_TYPE_DRAWTRAP 0x00000005L | ||
168 | #define GDC_TYPE_DRAWVERTEX2I 0x00000006L | ||
169 | #define GDC_TYPE_DRAWVERTEX2IP 0x00000007L | ||
170 | #define GDC_TYPE_DRAWRECTP 0x00000009L | ||
171 | #define GDC_TYPE_DRAWBITMAPP 0x0000000BL | ||
172 | #define GDC_TYPE_BLTCOPYP 0x0000000DL | ||
173 | #define GDC_TYPE_BLTCOPYALTERNATEP 0x0000000FL | ||
174 | #define GDC_TYPE_LOADTEXTUREP 0x00000011L | ||
175 | #define GDC_TYPE_BLTTEXTUREP 0x00000013L | ||
176 | #define GDC_TYPE_BLTCOPYALTALPHABLENDP 0x0000001FL | ||
177 | #define GDC_TYPE_SETVERTEX2I 0x00000070L | ||
178 | #define GDC_TYPE_SETVERTEX2IP 0x00000071L | ||
179 | #define GDC_TYPE_DRAW 0x000000F0L | ||
180 | #define GDC_TYPE_SETREGISTER 0x000000F1L | ||
181 | #define GDC_TYPE_SYNC 0x000000FCL | ||
182 | #define GDC_TYPE_INTERRUPT 0x000000FDL | ||
183 | #define GDC_TYPE_NOP 0x0 | ||
184 | |||
185 | /* Raster operation */ | ||
186 | #define GDC_ROP_CLEAR 0x0000 | ||
187 | #define GDC_ROP_AND 0x0001 | ||
188 | #define GDC_ROP_AND_REVERSE 0x0002 | ||
189 | #define GDC_ROP_COPY 0x0003 | ||
190 | #define GDC_ROP_AND_INVERTED 0x0004 | ||
191 | #define GDC_ROP_NOP 0x0005 | ||
192 | #define GDC_ROP_XOR 0x0006 | ||
193 | #define GDC_ROP_OR 0x0007 | ||
194 | #define GDC_ROP_NOR 0x0008 | ||
195 | #define GDC_ROP_EQUIV 0x0009 | ||
196 | #define GDC_ROP_INVERT 0x000A | ||
197 | #define GDC_ROP_OR_REVERSE 0x000B | ||
198 | #define GDC_ROP_COPY_INVERTED 0x000C | ||
199 | #define GDC_ROP_OR_INVERTED 0x000D | ||
200 | #define GDC_ROP_NAND 0x000E | ||
201 | #define GDC_ROP_SET 0x000F | ||
202 | |||
203 | #endif | ||
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c index 34e4e7995169..0129f1bc3522 100644 --- a/drivers/video/modedb.c +++ b/drivers/video/modedb.c | |||
@@ -13,6 +13,7 @@ | |||
13 | 13 | ||
14 | #include <linux/module.h> | 14 | #include <linux/module.h> |
15 | #include <linux/fb.h> | 15 | #include <linux/fb.h> |
16 | #include <linux/kernel.h> | ||
16 | 17 | ||
17 | #undef DEBUG | 18 | #undef DEBUG |
18 | 19 | ||
@@ -402,21 +403,6 @@ const struct fb_videomode vesa_modes[] = { | |||
402 | EXPORT_SYMBOL(vesa_modes); | 403 | EXPORT_SYMBOL(vesa_modes); |
403 | #endif /* CONFIG_FB_MODE_HELPERS */ | 404 | #endif /* CONFIG_FB_MODE_HELPERS */ |
404 | 405 | ||
405 | static int my_atoi(const char *name) | ||
406 | { | ||
407 | int val = 0; | ||
408 | |||
409 | for (;; name++) { | ||
410 | switch (*name) { | ||
411 | case '0' ... '9': | ||
412 | val = 10*val+(*name-'0'); | ||
413 | break; | ||
414 | default: | ||
415 | return val; | ||
416 | } | ||
417 | } | ||
418 | } | ||
419 | |||
420 | /** | 406 | /** |
421 | * fb_try_mode - test a video mode | 407 | * fb_try_mode - test a video mode |
422 | * @var: frame buffer user defined part of display | 408 | * @var: frame buffer user defined part of display |
@@ -539,7 +525,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
539 | namelen = i; | 525 | namelen = i; |
540 | if (!refresh_specified && !bpp_specified && | 526 | if (!refresh_specified && !bpp_specified && |
541 | !yres_specified) { | 527 | !yres_specified) { |
542 | refresh = my_atoi(&name[i+1]); | 528 | refresh = simple_strtol(&name[i+1], NULL, 10); |
543 | refresh_specified = 1; | 529 | refresh_specified = 1; |
544 | if (cvt || rb) | 530 | if (cvt || rb) |
545 | cvt = 0; | 531 | cvt = 0; |
@@ -549,7 +535,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
549 | case '-': | 535 | case '-': |
550 | namelen = i; | 536 | namelen = i; |
551 | if (!bpp_specified && !yres_specified) { | 537 | if (!bpp_specified && !yres_specified) { |
552 | bpp = my_atoi(&name[i+1]); | 538 | bpp = simple_strtol(&name[i+1], NULL, 10); |
553 | bpp_specified = 1; | 539 | bpp_specified = 1; |
554 | if (cvt || rb) | 540 | if (cvt || rb) |
555 | cvt = 0; | 541 | cvt = 0; |
@@ -558,7 +544,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
558 | break; | 544 | break; |
559 | case 'x': | 545 | case 'x': |
560 | if (!yres_specified) { | 546 | if (!yres_specified) { |
561 | yres = my_atoi(&name[i+1]); | 547 | yres = simple_strtol(&name[i+1], NULL, 10); |
562 | yres_specified = 1; | 548 | yres_specified = 1; |
563 | } else | 549 | } else |
564 | goto done; | 550 | goto done; |
@@ -586,7 +572,7 @@ int fb_find_mode(struct fb_var_screeninfo *var, | |||
586 | } | 572 | } |
587 | } | 573 | } |
588 | if (i < 0 && yres_specified) { | 574 | if (i < 0 && yres_specified) { |
589 | xres = my_atoi(name); | 575 | xres = simple_strtol(name, NULL, 10); |
590 | res_specified = 1; | 576 | res_specified = 1; |
591 | } | 577 | } |
592 | done: | 578 | done: |
diff --git a/drivers/video/output.c b/drivers/video/output.c index 5e6439ae7394..5137aa016b83 100644 --- a/drivers/video/output.c +++ b/drivers/video/output.c | |||
@@ -50,7 +50,7 @@ static ssize_t video_output_store_state(struct device *dev, | |||
50 | int request_state = simple_strtoul(buf,&endp,0); | 50 | int request_state = simple_strtoul(buf,&endp,0); |
51 | size_t size = endp - buf; | 51 | size_t size = endp - buf; |
52 | 52 | ||
53 | if (*endp && isspace(*endp)) | 53 | if (isspace(*endp)) |
54 | size++; | 54 | size++; |
55 | if (size != count) | 55 | if (size != count) |
56 | return -EINVAL; | 56 | return -EINVAL; |
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c index 0573ec685a57..0f361b6100d2 100644 --- a/drivers/video/pmag-ba-fb.c +++ b/drivers/video/pmag-ba-fb.c | |||
@@ -98,7 +98,8 @@ static int pmagbafb_setcolreg(unsigned int regno, unsigned int red, | |||
98 | { | 98 | { |
99 | struct pmagbafb_par *par = info->par; | 99 | struct pmagbafb_par *par = info->par; |
100 | 100 | ||
101 | BUG_ON(regno >= info->cmap.len); | 101 | if (regno >= info->cmap.len) |
102 | return 1; | ||
102 | 103 | ||
103 | red >>= 8; /* The cmap fields are 16 bits */ | 104 | red >>= 8; /* The cmap fields are 16 bits */ |
104 | green >>= 8; /* wide, but the hardware colormap */ | 105 | green >>= 8; /* wide, but the hardware colormap */ |
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c index 98748723af9f..2de0806421b4 100644 --- a/drivers/video/pmagb-b-fb.c +++ b/drivers/video/pmagb-b-fb.c | |||
@@ -102,7 +102,8 @@ static int pmagbbfb_setcolreg(unsigned int regno, unsigned int red, | |||
102 | { | 102 | { |
103 | struct pmagbbfb_par *par = info->par; | 103 | struct pmagbbfb_par *par = info->par; |
104 | 104 | ||
105 | BUG_ON(regno >= info->cmap.len); | 105 | if (regno >= info->cmap.len) |
106 | return 1; | ||
106 | 107 | ||
107 | red >>= 8; /* The cmap fields are 16 bits */ | 108 | red >>= 8; /* The cmap fields are 16 bits */ |
108 | green >>= 8; /* wide, but the hardware colormap */ | 109 | green >>= 8; /* wide, but the hardware colormap */ |
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c index f58a3aae6ea6..415858b421b3 100644 --- a/drivers/video/pxafb.c +++ b/drivers/video/pxafb.c | |||
@@ -1221,13 +1221,14 @@ static void setup_smart_timing(struct pxafb_info *fbi, | |||
1221 | static int pxafb_smart_thread(void *arg) | 1221 | static int pxafb_smart_thread(void *arg) |
1222 | { | 1222 | { |
1223 | struct pxafb_info *fbi = arg; | 1223 | struct pxafb_info *fbi = arg; |
1224 | struct pxafb_mach_info *inf = fbi->dev->platform_data; | 1224 | struct pxafb_mach_info *inf; |
1225 | 1225 | ||
1226 | if (!fbi || !inf->smart_update) { | 1226 | if (!fbi || !fbi->dev->platform_data->smart_update) { |
1227 | pr_err("%s: not properly initialized, thread terminated\n", | 1227 | pr_err("%s: not properly initialized, thread terminated\n", |
1228 | __func__); | 1228 | __func__); |
1229 | return -EINVAL; | 1229 | return -EINVAL; |
1230 | } | 1230 | } |
1231 | inf = fbi->dev->platform_data; | ||
1231 | 1232 | ||
1232 | pr_debug("%s(): task starting\n", __func__); | 1233 | pr_debug("%s(): task starting\n", __func__); |
1233 | 1234 | ||
@@ -1667,7 +1668,7 @@ static int pxafb_resume(struct device *dev) | |||
1667 | return 0; | 1668 | return 0; |
1668 | } | 1669 | } |
1669 | 1670 | ||
1670 | static struct dev_pm_ops pxafb_pm_ops = { | 1671 | static const struct dev_pm_ops pxafb_pm_ops = { |
1671 | .suspend = pxafb_suspend, | 1672 | .suspend = pxafb_suspend, |
1672 | .resume = pxafb_resume, | 1673 | .resume = pxafb_resume, |
1673 | }; | 1674 | }; |
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/sh_mobile_lcdcfb.c index d346bbab6cad..a69830d26f7f 100644 --- a/drivers/video/sh_mobile_lcdcfb.c +++ b/drivers/video/sh_mobile_lcdcfb.c | |||
@@ -898,7 +898,7 @@ static int sh_mobile_lcdc_runtime_resume(struct device *dev) | |||
898 | return 0; | 898 | return 0; |
899 | } | 899 | } |
900 | 900 | ||
901 | static struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { | 901 | static const struct dev_pm_ops sh_mobile_lcdc_dev_pm_ops = { |
902 | .suspend = sh_mobile_lcdc_suspend, | 902 | .suspend = sh_mobile_lcdc_suspend, |
903 | .resume = sh_mobile_lcdc_resume, | 903 | .resume = sh_mobile_lcdc_resume, |
904 | .runtime_suspend = sh_mobile_lcdc_runtime_suspend, | 904 | .runtime_suspend = sh_mobile_lcdc_runtime_suspend, |
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c index a4e05e4d7501..9d2b6bc49036 100644 --- a/drivers/video/sis/sis_main.c +++ b/drivers/video/sis/sis_main.c | |||
@@ -2115,7 +2115,7 @@ sisfb_detect_VB_connect(struct sis_video_info *ivideo) | |||
2115 | if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) && | 2115 | if( (!(ivideo->vbflags2 & VB2_SISBRIDGE)) && |
2116 | (!((ivideo->sisvga_engine == SIS_315_VGA) && | 2116 | (!((ivideo->sisvga_engine == SIS_315_VGA) && |
2117 | (ivideo->vbflags2 & VB2_CHRONTEL))) ) { | 2117 | (ivideo->vbflags2 & VB2_CHRONTEL))) ) { |
2118 | if(ivideo->sisfb_tvstd & (TV_PALN | TV_PALN | TV_NTSCJ)) { | 2118 | if(ivideo->sisfb_tvstd & (TV_PALM | TV_PALN | TV_NTSCJ)) { |
2119 | ivideo->sisfb_tvstd = -1; | 2119 | ivideo->sisfb_tvstd = -1; |
2120 | printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n"); | 2120 | printk(KERN_ERR "sisfb: PALM/PALN/NTSCJ not supported\n"); |
2121 | } | 2121 | } |
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c index 924d79462780..35370d0ecf03 100644 --- a/drivers/video/sm501fb.c +++ b/drivers/video/sm501fb.c | |||
@@ -29,8 +29,8 @@ | |||
29 | #include <linux/platform_device.h> | 29 | #include <linux/platform_device.h> |
30 | #include <linux/clk.h> | 30 | #include <linux/clk.h> |
31 | #include <linux/console.h> | 31 | #include <linux/console.h> |
32 | #include <linux/io.h> | ||
32 | 33 | ||
33 | #include <asm/io.h> | ||
34 | #include <asm/uaccess.h> | 34 | #include <asm/uaccess.h> |
35 | #include <asm/div64.h> | 35 | #include <asm/div64.h> |
36 | 36 | ||
@@ -66,6 +66,7 @@ struct sm501fb_info { | |||
66 | struct fb_info *fb[2]; /* fb info for both heads */ | 66 | struct fb_info *fb[2]; /* fb info for both heads */ |
67 | struct resource *fbmem_res; /* framebuffer resource */ | 67 | struct resource *fbmem_res; /* framebuffer resource */ |
68 | struct resource *regs_res; /* registers resource */ | 68 | struct resource *regs_res; /* registers resource */ |
69 | struct resource *regs2d_res; /* 2d registers resource */ | ||
69 | struct sm501_platdata_fb *pdata; /* our platform data */ | 70 | struct sm501_platdata_fb *pdata; /* our platform data */ |
70 | 71 | ||
71 | unsigned long pm_crt_ctrl; /* pm: crt ctrl save */ | 72 | unsigned long pm_crt_ctrl; /* pm: crt ctrl save */ |
@@ -73,6 +74,7 @@ struct sm501fb_info { | |||
73 | int irq; | 74 | int irq; |
74 | int swap_endian; /* set to swap rgb=>bgr */ | 75 | int swap_endian; /* set to swap rgb=>bgr */ |
75 | void __iomem *regs; /* remapped registers */ | 76 | void __iomem *regs; /* remapped registers */ |
77 | void __iomem *regs2d; /* 2d remapped registers */ | ||
76 | void __iomem *fbmem; /* remapped framebuffer */ | 78 | void __iomem *fbmem; /* remapped framebuffer */ |
77 | size_t fbmem_len; /* length of remapped region */ | 79 | size_t fbmem_len; /* length of remapped region */ |
78 | }; | 80 | }; |
@@ -123,9 +125,9 @@ static inline void sm501fb_sync_regs(struct sm501fb_info *info) | |||
123 | * This is an attempt to lay out memory for the two framebuffers and | 125 | * This is an attempt to lay out memory for the two framebuffers and |
124 | * everything else | 126 | * everything else |
125 | * | 127 | * |
126 | * |fbmem_res->start fbmem_res->end| | 128 | * |fbmem_res->start fbmem_res->end| |
127 | * | | | 129 | * | | |
128 | * |fb[0].fix.smem_start | |fb[1].fix.smem_start | 2K | | 130 | * |fb[0].fix.smem_start | |fb[1].fix.smem_start | 2K | |
129 | * |-> fb[0].fix.smem_len <-| spare |-> fb[1].fix.smem_len <-|-> cursors <-| | 131 | * |-> fb[0].fix.smem_len <-| spare |-> fb[1].fix.smem_len <-|-> cursors <-| |
130 | * | 132 | * |
131 | * The "spare" space is for the 2d engine data | 133 | * The "spare" space is for the 2d engine data |
@@ -1246,7 +1248,173 @@ static ssize_t sm501fb_debug_show_pnl(struct device *dev, | |||
1246 | 1248 | ||
1247 | static DEVICE_ATTR(fbregs_pnl, 0444, sm501fb_debug_show_pnl, NULL); | 1249 | static DEVICE_ATTR(fbregs_pnl, 0444, sm501fb_debug_show_pnl, NULL); |
1248 | 1250 | ||
1249 | /* framebuffer ops */ | 1251 | /* acceleration operations */ |
1252 | static int sm501fb_sync(struct fb_info *info) | ||
1253 | { | ||
1254 | int count = 1000000; | ||
1255 | struct sm501fb_par *par = info->par; | ||
1256 | struct sm501fb_info *fbi = par->info; | ||
1257 | |||
1258 | /* wait for the 2d engine to be ready */ | ||
1259 | while ((count > 0) && | ||
1260 | (readl(fbi->regs + SM501_SYSTEM_CONTROL) & | ||
1261 | SM501_SYSCTRL_2D_ENGINE_STATUS) != 0) | ||
1262 | count--; | ||
1263 | |||
1264 | if (count <= 0) { | ||
1265 | dev_err(info->dev, "Timeout waiting for 2d engine sync\n"); | ||
1266 | return 1; | ||
1267 | } | ||
1268 | return 0; | ||
1269 | } | ||
1270 | |||
1271 | static void sm501fb_copyarea(struct fb_info *info, const struct fb_copyarea *area) | ||
1272 | { | ||
1273 | struct sm501fb_par *par = info->par; | ||
1274 | struct sm501fb_info *fbi = par->info; | ||
1275 | int width = area->width; | ||
1276 | int height = area->height; | ||
1277 | int sx = area->sx; | ||
1278 | int sy = area->sy; | ||
1279 | int dx = area->dx; | ||
1280 | int dy = area->dy; | ||
1281 | unsigned long rtl = 0; | ||
1282 | |||
1283 | /* source clip */ | ||
1284 | if ((sx >= info->var.xres_virtual) || | ||
1285 | (sy >= info->var.yres_virtual)) | ||
1286 | /* source Area not within virtual screen, skipping */ | ||
1287 | return; | ||
1288 | if ((sx + width) >= info->var.xres_virtual) | ||
1289 | width = info->var.xres_virtual - sx - 1; | ||
1290 | if ((sy + height) >= info->var.yres_virtual) | ||
1291 | height = info->var.yres_virtual - sy - 1; | ||
1292 | |||
1293 | /* dest clip */ | ||
1294 | if ((dx >= info->var.xres_virtual) || | ||
1295 | (dy >= info->var.yres_virtual)) | ||
1296 | /* Destination Area not within virtual screen, skipping */ | ||
1297 | return; | ||
1298 | if ((dx + width) >= info->var.xres_virtual) | ||
1299 | width = info->var.xres_virtual - dx - 1; | ||
1300 | if ((dy + height) >= info->var.yres_virtual) | ||
1301 | height = info->var.yres_virtual - dy - 1; | ||
1302 | |||
1303 | if ((sx < dx) || (sy < dy)) { | ||
1304 | rtl = 1 << 27; | ||
1305 | sx += width - 1; | ||
1306 | dx += width - 1; | ||
1307 | sy += height - 1; | ||
1308 | dy += height - 1; | ||
1309 | } | ||
1310 | |||
1311 | if (sm501fb_sync(info)) | ||
1312 | return; | ||
1313 | |||
1314 | /* set the base addresses */ | ||
1315 | writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); | ||
1316 | writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); | ||
1317 | |||
1318 | /* set the window width */ | ||
1319 | writel((info->var.xres << 16) | info->var.xres, | ||
1320 | fbi->regs2d + SM501_2D_WINDOW_WIDTH); | ||
1321 | |||
1322 | /* set window stride */ | ||
1323 | writel((info->var.xres_virtual << 16) | info->var.xres_virtual, | ||
1324 | fbi->regs2d + SM501_2D_PITCH); | ||
1325 | |||
1326 | /* set data format */ | ||
1327 | switch (info->var.bits_per_pixel) { | ||
1328 | case 8: | ||
1329 | writel(0, fbi->regs2d + SM501_2D_STRETCH); | ||
1330 | break; | ||
1331 | case 16: | ||
1332 | writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); | ||
1333 | break; | ||
1334 | case 32: | ||
1335 | writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); | ||
1336 | break; | ||
1337 | } | ||
1338 | |||
1339 | /* 2d compare mask */ | ||
1340 | writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); | ||
1341 | |||
1342 | /* 2d mask */ | ||
1343 | writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); | ||
1344 | |||
1345 | /* source and destination x y */ | ||
1346 | writel((sx << 16) | sy, fbi->regs2d + SM501_2D_SOURCE); | ||
1347 | writel((dx << 16) | dy, fbi->regs2d + SM501_2D_DESTINATION); | ||
1348 | |||
1349 | /* w/h */ | ||
1350 | writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); | ||
1351 | |||
1352 | /* do area move */ | ||
1353 | writel(0x800000cc | rtl, fbi->regs2d + SM501_2D_CONTROL); | ||
1354 | } | ||
1355 | |||
1356 | static void sm501fb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) | ||
1357 | { | ||
1358 | struct sm501fb_par *par = info->par; | ||
1359 | struct sm501fb_info *fbi = par->info; | ||
1360 | int width = rect->width, height = rect->height; | ||
1361 | |||
1362 | if ((rect->dx >= info->var.xres_virtual) || | ||
1363 | (rect->dy >= info->var.yres_virtual)) | ||
1364 | /* Rectangle not within virtual screen, skipping */ | ||
1365 | return; | ||
1366 | if ((rect->dx + width) >= info->var.xres_virtual) | ||
1367 | width = info->var.xres_virtual - rect->dx - 1; | ||
1368 | if ((rect->dy + height) >= info->var.yres_virtual) | ||
1369 | height = info->var.yres_virtual - rect->dy - 1; | ||
1370 | |||
1371 | if (sm501fb_sync(info)) | ||
1372 | return; | ||
1373 | |||
1374 | /* set the base addresses */ | ||
1375 | writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_SOURCE_BASE); | ||
1376 | writel(par->screen.sm_addr, fbi->regs2d + SM501_2D_DESTINATION_BASE); | ||
1377 | |||
1378 | /* set the window width */ | ||
1379 | writel((info->var.xres << 16) | info->var.xres, | ||
1380 | fbi->regs2d + SM501_2D_WINDOW_WIDTH); | ||
1381 | |||
1382 | /* set window stride */ | ||
1383 | writel((info->var.xres_virtual << 16) | info->var.xres_virtual, | ||
1384 | fbi->regs2d + SM501_2D_PITCH); | ||
1385 | |||
1386 | /* set data format */ | ||
1387 | switch (info->var.bits_per_pixel) { | ||
1388 | case 8: | ||
1389 | writel(0, fbi->regs2d + SM501_2D_STRETCH); | ||
1390 | break; | ||
1391 | case 16: | ||
1392 | writel(0x00100000, fbi->regs2d + SM501_2D_STRETCH); | ||
1393 | break; | ||
1394 | case 32: | ||
1395 | writel(0x00200000, fbi->regs2d + SM501_2D_STRETCH); | ||
1396 | break; | ||
1397 | } | ||
1398 | |||
1399 | /* 2d compare mask */ | ||
1400 | writel(0xffffffff, fbi->regs2d + SM501_2D_COLOR_COMPARE_MASK); | ||
1401 | |||
1402 | /* 2d mask */ | ||
1403 | writel(0xffffffff, fbi->regs2d + SM501_2D_MASK); | ||
1404 | |||
1405 | /* colour */ | ||
1406 | writel(rect->color, fbi->regs2d + SM501_2D_FOREGROUND); | ||
1407 | |||
1408 | /* x y */ | ||
1409 | writel((rect->dx << 16) | rect->dy, fbi->regs2d + SM501_2D_DESTINATION); | ||
1410 | |||
1411 | /* w/h */ | ||
1412 | writel((width << 16) | height, fbi->regs2d + SM501_2D_DIMENSION); | ||
1413 | |||
1414 | /* do rectangle fill */ | ||
1415 | writel(0x800100cc, fbi->regs2d + SM501_2D_CONTROL); | ||
1416 | } | ||
1417 | |||
1250 | 1418 | ||
1251 | static struct fb_ops sm501fb_ops_crt = { | 1419 | static struct fb_ops sm501fb_ops_crt = { |
1252 | .owner = THIS_MODULE, | 1420 | .owner = THIS_MODULE, |
@@ -1256,9 +1424,10 @@ static struct fb_ops sm501fb_ops_crt = { | |||
1256 | .fb_setcolreg = sm501fb_setcolreg, | 1424 | .fb_setcolreg = sm501fb_setcolreg, |
1257 | .fb_pan_display = sm501fb_pan_crt, | 1425 | .fb_pan_display = sm501fb_pan_crt, |
1258 | .fb_cursor = sm501fb_cursor, | 1426 | .fb_cursor = sm501fb_cursor, |
1259 | .fb_fillrect = cfb_fillrect, | 1427 | .fb_fillrect = sm501fb_fillrect, |
1260 | .fb_copyarea = cfb_copyarea, | 1428 | .fb_copyarea = sm501fb_copyarea, |
1261 | .fb_imageblit = cfb_imageblit, | 1429 | .fb_imageblit = cfb_imageblit, |
1430 | .fb_sync = sm501fb_sync, | ||
1262 | }; | 1431 | }; |
1263 | 1432 | ||
1264 | static struct fb_ops sm501fb_ops_pnl = { | 1433 | static struct fb_ops sm501fb_ops_pnl = { |
@@ -1269,9 +1438,10 @@ static struct fb_ops sm501fb_ops_pnl = { | |||
1269 | .fb_blank = sm501fb_blank_pnl, | 1438 | .fb_blank = sm501fb_blank_pnl, |
1270 | .fb_setcolreg = sm501fb_setcolreg, | 1439 | .fb_setcolreg = sm501fb_setcolreg, |
1271 | .fb_cursor = sm501fb_cursor, | 1440 | .fb_cursor = sm501fb_cursor, |
1272 | .fb_fillrect = cfb_fillrect, | 1441 | .fb_fillrect = sm501fb_fillrect, |
1273 | .fb_copyarea = cfb_copyarea, | 1442 | .fb_copyarea = sm501fb_copyarea, |
1274 | .fb_imageblit = cfb_imageblit, | 1443 | .fb_imageblit = cfb_imageblit, |
1444 | .fb_sync = sm501fb_sync, | ||
1275 | }; | 1445 | }; |
1276 | 1446 | ||
1277 | /* sm501_init_cursor | 1447 | /* sm501_init_cursor |
@@ -1329,7 +1499,8 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1329 | dev_warn(dev, "no irq for device\n"); | 1499 | dev_warn(dev, "no irq for device\n"); |
1330 | } | 1500 | } |
1331 | 1501 | ||
1332 | /* allocate, reserve and remap resources for registers */ | 1502 | /* allocate, reserve and remap resources for display |
1503 | * controller registers */ | ||
1333 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 1504 | res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
1334 | if (res == NULL) { | 1505 | if (res == NULL) { |
1335 | dev_err(dev, "no resource definition for registers\n"); | 1506 | dev_err(dev, "no resource definition for registers\n"); |
@@ -1338,7 +1509,7 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1338 | } | 1509 | } |
1339 | 1510 | ||
1340 | info->regs_res = request_mem_region(res->start, | 1511 | info->regs_res = request_mem_region(res->start, |
1341 | res->end - res->start, | 1512 | resource_size(res), |
1342 | pdev->name); | 1513 | pdev->name); |
1343 | 1514 | ||
1344 | if (info->regs_res == NULL) { | 1515 | if (info->regs_res == NULL) { |
@@ -1347,37 +1518,63 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1347 | goto err_release; | 1518 | goto err_release; |
1348 | } | 1519 | } |
1349 | 1520 | ||
1350 | info->regs = ioremap(res->start, (res->end - res->start)+1); | 1521 | info->regs = ioremap(res->start, resource_size(res)); |
1351 | if (info->regs == NULL) { | 1522 | if (info->regs == NULL) { |
1352 | dev_err(dev, "cannot remap registers\n"); | 1523 | dev_err(dev, "cannot remap registers\n"); |
1353 | ret = -ENXIO; | 1524 | ret = -ENXIO; |
1354 | goto err_regs_res; | 1525 | goto err_regs_res; |
1355 | } | 1526 | } |
1356 | 1527 | ||
1528 | /* allocate, reserve and remap resources for 2d | ||
1529 | * controller registers */ | ||
1530 | res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
1531 | if (res == NULL) { | ||
1532 | dev_err(dev, "no resource definition for 2d registers\n"); | ||
1533 | ret = -ENOENT; | ||
1534 | goto err_regs_map; | ||
1535 | } | ||
1536 | |||
1537 | info->regs2d_res = request_mem_region(res->start, | ||
1538 | resource_size(res), | ||
1539 | pdev->name); | ||
1540 | |||
1541 | if (info->regs2d_res == NULL) { | ||
1542 | dev_err(dev, "cannot claim registers\n"); | ||
1543 | ret = -ENXIO; | ||
1544 | goto err_regs_map; | ||
1545 | } | ||
1546 | |||
1547 | info->regs2d = ioremap(res->start, resource_size(res)); | ||
1548 | if (info->regs2d == NULL) { | ||
1549 | dev_err(dev, "cannot remap registers\n"); | ||
1550 | ret = -ENXIO; | ||
1551 | goto err_regs2d_res; | ||
1552 | } | ||
1553 | |||
1357 | /* allocate, reserve resources for framebuffer */ | 1554 | /* allocate, reserve resources for framebuffer */ |
1358 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); | 1555 | res = platform_get_resource(pdev, IORESOURCE_MEM, 2); |
1359 | if (res == NULL) { | 1556 | if (res == NULL) { |
1360 | dev_err(dev, "no memory resource defined\n"); | 1557 | dev_err(dev, "no memory resource defined\n"); |
1361 | ret = -ENXIO; | 1558 | ret = -ENXIO; |
1362 | goto err_regs_map; | 1559 | goto err_regs2d_map; |
1363 | } | 1560 | } |
1364 | 1561 | ||
1365 | info->fbmem_res = request_mem_region(res->start, | 1562 | info->fbmem_res = request_mem_region(res->start, |
1366 | (res->end - res->start)+1, | 1563 | resource_size(res), |
1367 | pdev->name); | 1564 | pdev->name); |
1368 | if (info->fbmem_res == NULL) { | 1565 | if (info->fbmem_res == NULL) { |
1369 | dev_err(dev, "cannot claim framebuffer\n"); | 1566 | dev_err(dev, "cannot claim framebuffer\n"); |
1370 | ret = -ENXIO; | 1567 | ret = -ENXIO; |
1371 | goto err_regs_map; | 1568 | goto err_regs2d_map; |
1372 | } | 1569 | } |
1373 | 1570 | ||
1374 | info->fbmem = ioremap(res->start, (res->end - res->start)+1); | 1571 | info->fbmem = ioremap(res->start, resource_size(res)); |
1375 | if (info->fbmem == NULL) { | 1572 | if (info->fbmem == NULL) { |
1376 | dev_err(dev, "cannot remap framebuffer\n"); | 1573 | dev_err(dev, "cannot remap framebuffer\n"); |
1377 | goto err_mem_res; | 1574 | goto err_mem_res; |
1378 | } | 1575 | } |
1379 | 1576 | ||
1380 | info->fbmem_len = (res->end - res->start)+1; | 1577 | info->fbmem_len = resource_size(res); |
1381 | 1578 | ||
1382 | /* clear framebuffer memory - avoids garbage data on unused fb */ | 1579 | /* clear framebuffer memory - avoids garbage data on unused fb */ |
1383 | memset(info->fbmem, 0, info->fbmem_len); | 1580 | memset(info->fbmem, 0, info->fbmem_len); |
@@ -1389,8 +1586,10 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1389 | /* enable display controller */ | 1586 | /* enable display controller */ |
1390 | sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); | 1587 | sm501_unit_power(dev->parent, SM501_GATE_DISPLAY, 1); |
1391 | 1588 | ||
1392 | /* setup cursors */ | 1589 | /* enable 2d controller */ |
1590 | sm501_unit_power(dev->parent, SM501_GATE_2D_ENGINE, 1); | ||
1393 | 1591 | ||
1592 | /* setup cursors */ | ||
1394 | sm501_init_cursor(info->fb[HEAD_CRT], SM501_DC_CRT_HWC_ADDR); | 1593 | sm501_init_cursor(info->fb[HEAD_CRT], SM501_DC_CRT_HWC_ADDR); |
1395 | sm501_init_cursor(info->fb[HEAD_PANEL], SM501_DC_PANEL_HWC_ADDR); | 1594 | sm501_init_cursor(info->fb[HEAD_PANEL], SM501_DC_PANEL_HWC_ADDR); |
1396 | 1595 | ||
@@ -1400,6 +1599,13 @@ static int sm501fb_start(struct sm501fb_info *info, | |||
1400 | release_resource(info->fbmem_res); | 1599 | release_resource(info->fbmem_res); |
1401 | kfree(info->fbmem_res); | 1600 | kfree(info->fbmem_res); |
1402 | 1601 | ||
1602 | err_regs2d_map: | ||
1603 | iounmap(info->regs2d); | ||
1604 | |||
1605 | err_regs2d_res: | ||
1606 | release_resource(info->regs2d_res); | ||
1607 | kfree(info->regs2d_res); | ||
1608 | |||
1403 | err_regs_map: | 1609 | err_regs_map: |
1404 | iounmap(info->regs); | 1610 | iounmap(info->regs); |
1405 | 1611 | ||
@@ -1420,6 +1626,10 @@ static void sm501fb_stop(struct sm501fb_info *info) | |||
1420 | release_resource(info->fbmem_res); | 1626 | release_resource(info->fbmem_res); |
1421 | kfree(info->fbmem_res); | 1627 | kfree(info->fbmem_res); |
1422 | 1628 | ||
1629 | iounmap(info->regs2d); | ||
1630 | release_resource(info->regs2d_res); | ||
1631 | kfree(info->regs2d_res); | ||
1632 | |||
1423 | iounmap(info->regs); | 1633 | iounmap(info->regs); |
1424 | release_resource(info->regs_res); | 1634 | release_resource(info->regs_res); |
1425 | kfree(info->regs_res); | 1635 | kfree(info->regs_res); |
@@ -1486,7 +1696,8 @@ static int sm501fb_init_fb(struct fb_info *fb, | |||
1486 | par->ops.fb_cursor = NULL; | 1696 | par->ops.fb_cursor = NULL; |
1487 | 1697 | ||
1488 | fb->fbops = &par->ops; | 1698 | fb->fbops = &par->ops; |
1489 | fb->flags = FBINFO_FLAG_DEFAULT | | 1699 | fb->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST | |
1700 | FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | | ||
1490 | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; | 1701 | FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN; |
1491 | 1702 | ||
1492 | /* fixed data */ | 1703 | /* fixed data */ |
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index e3e597f937a5..09353e2b92f6 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c | |||
@@ -1134,45 +1134,33 @@ static void integrated_lvds_enable(struct lvds_setting_information | |||
1134 | *plvds_setting_info, | 1134 | *plvds_setting_info, |
1135 | struct lvds_chip_information *plvds_chip_info) | 1135 | struct lvds_chip_information *plvds_chip_info) |
1136 | { | 1136 | { |
1137 | bool turn_on_first_powersequence = false; | ||
1138 | bool turn_on_second_powersequence = false; | ||
1139 | |||
1140 | DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n", | 1137 | DEBUG_MSG(KERN_INFO "integrated_lvds_enable, out_interface:%d\n", |
1141 | plvds_chip_info->output_interface); | 1138 | plvds_chip_info->output_interface); |
1142 | if (plvds_setting_info->lcd_mode == LCD_SPWG) | 1139 | if (plvds_setting_info->lcd_mode == LCD_SPWG) |
1143 | viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1); | 1140 | viafb_write_reg_mask(CRD2, VIACR, 0x00, BIT0 + BIT1); |
1144 | else | 1141 | else |
1145 | viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1); | 1142 | viafb_write_reg_mask(CRD2, VIACR, 0x03, BIT0 + BIT1); |
1146 | if (INTERFACE_LVDS0LVDS1 == plvds_chip_info->output_interface) | ||
1147 | turn_on_first_powersequence = true; | ||
1148 | if (INTERFACE_LVDS0 == plvds_chip_info->output_interface) | ||
1149 | turn_on_first_powersequence = true; | ||
1150 | if (INTERFACE_LVDS1 == plvds_chip_info->output_interface) | ||
1151 | turn_on_second_powersequence = true; | ||
1152 | |||
1153 | if (turn_on_second_powersequence) { | ||
1154 | /* Use second power sequence control: */ | ||
1155 | |||
1156 | /* Use hardware control power sequence. */ | ||
1157 | viafb_write_reg_mask(CRD3, VIACR, 0, BIT0); | ||
1158 | |||
1159 | /* Turn on back light. */ | ||
1160 | viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7); | ||
1161 | 1143 | ||
1162 | /* Turn on hardware power sequence. */ | 1144 | switch (plvds_chip_info->output_interface) { |
1163 | viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1); | 1145 | case INTERFACE_LVDS0LVDS1: |
1164 | } | 1146 | case INTERFACE_LVDS0: |
1165 | if (turn_on_first_powersequence) { | ||
1166 | /* Use first power sequence control: */ | 1147 | /* Use first power sequence control: */ |
1167 | |||
1168 | /* Use hardware control power sequence. */ | 1148 | /* Use hardware control power sequence. */ |
1169 | viafb_write_reg_mask(CR91, VIACR, 0, BIT0); | 1149 | viafb_write_reg_mask(CR91, VIACR, 0, BIT0); |
1170 | |||
1171 | /* Turn on back light. */ | 1150 | /* Turn on back light. */ |
1172 | viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7); | 1151 | viafb_write_reg_mask(CR91, VIACR, 0, BIT6 + BIT7); |
1173 | |||
1174 | /* Turn on hardware power sequence. */ | 1152 | /* Turn on hardware power sequence. */ |
1175 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); | 1153 | viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); |
1154 | break; | ||
1155 | case INTERFACE_LVDS1: | ||
1156 | /* Use second power sequence control: */ | ||
1157 | /* Use hardware control power sequence. */ | ||
1158 | viafb_write_reg_mask(CRD3, VIACR, 0, BIT0); | ||
1159 | /* Turn on back light. */ | ||
1160 | viafb_write_reg_mask(CRD3, VIACR, 0, BIT6 + BIT7); | ||
1161 | /* Turn on hardware power sequence. */ | ||
1162 | viafb_write_reg_mask(CRD4, VIACR, 0x02, BIT1); | ||
1163 | break; | ||
1176 | } | 1164 | } |
1177 | 1165 | ||
1178 | /* Turn DFP High/Low pad on. */ | 1166 | /* Turn DFP High/Low pad on. */ |
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 56ec696e8afa..10d8c4b4baeb 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c | |||
@@ -1797,7 +1797,7 @@ static const struct file_operations viafb_vt1636_proc_fops = { | |||
1797 | static void viafb_init_proc(struct proc_dir_entry **viafb_entry) | 1797 | static void viafb_init_proc(struct proc_dir_entry **viafb_entry) |
1798 | { | 1798 | { |
1799 | *viafb_entry = proc_mkdir("viafb", NULL); | 1799 | *viafb_entry = proc_mkdir("viafb", NULL); |
1800 | if (viafb_entry) { | 1800 | if (*viafb_entry) { |
1801 | proc_create("dvp0", 0, *viafb_entry, &viafb_dvp0_proc_fops); | 1801 | proc_create("dvp0", 0, *viafb_entry, &viafb_dvp0_proc_fops); |
1802 | proc_create("dvp1", 0, *viafb_entry, &viafb_dvp1_proc_fops); | 1802 | proc_create("dvp1", 0, *viafb_entry, &viafb_dvp1_proc_fops); |
1803 | proc_create("dfph", 0, *viafb_entry, &viafb_dfph_proc_fops); | 1803 | proc_create("dfph", 0, *viafb_entry, &viafb_dfph_proc_fops); |