aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video/via
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2010-05-20 16:34:17 -0400
committerLinus Torvalds <torvalds@linux-foundation.org>2010-05-20 16:34:17 -0400
commit7c6d87ac843bfbc5a7669736882a0e88c217a820 (patch)
treeb757687fcc7493a322c5c27aa141c87668900234 /drivers/video/via
parenta0fe3cc5d36a5f5b4f60abfe1a4b1caf4a5cce5a (diff)
parentec66841e495b9ab4f92bdf91efe8cf56e1471fbd (diff)
Merge branch 'viafb-next' of git://git.lwn.net/linux-2.6
* 'viafb-next' of git://git.lwn.net/linux-2.6: (35 commits) viafb: move some include files to include/linux viafb: Eliminate some global.h references viafb: get rid of i2c debug cruft viafb: fold via_io.h into via-core.h viafb: Fix initialization error paths viafb: Do not remove gpiochip under spinlock viafb: make procfs entries optional viafb: fix proc entry removal viafb: improve misc register handling viafb: replace inb/outb viafb: move some modesetting functions to a seperate file viafb: unify modesetting functions viafb: Reserve framebuffer memory for the upcoming camera driver viafb: Add a simple VX855 DMA engine driver viafb: Add a simple interrupt management infrastructure via: Rationalize vt1636 detection viafb: Introduce viafb_find_i2c_adapter() via: Do not attempt I/O on inactive I2C adapters viafb: Turn GPIO and i2c into proper platform devices viafb: Convert GPIO and i2c to the new indexed port ops ...
Diffstat (limited to 'drivers/video/via')
-rw-r--r--drivers/video/via/Makefile4
-rw-r--r--drivers/video/via/accel.c137
-rw-r--r--drivers/video/via/accel.h40
-rw-r--r--drivers/video/via/chip.h8
-rw-r--r--drivers/video/via/dvi.c37
-rw-r--r--drivers/video/via/global.h1
-rw-r--r--drivers/video/via/hw.c307
-rw-r--r--drivers/video/via/hw.h20
-rw-r--r--drivers/video/via/ioctl.h2
-rw-r--r--drivers/video/via/lcd.c31
-rw-r--r--drivers/video/via/lcd.h2
-rw-r--r--drivers/video/via/share.h20
-rw-r--r--drivers/video/via/via-core.c668
-rw-r--r--drivers/video/via/via-gpio.c285
-rw-r--r--drivers/video/via/via_i2c.c232
-rw-r--r--drivers/video/via/via_modesetting.c126
-rw-r--r--drivers/video/via/via_modesetting.h (renamed from drivers/video/via/via_i2c.h)42
-rw-r--r--drivers/video/via/via_utility.c1
-rw-r--r--drivers/video/via/viafbdev.c181
-rw-r--r--drivers/video/via/viafbdev.h14
-rw-r--r--drivers/video/via/viamode.c15
-rw-r--r--drivers/video/via/vt1636.c34
-rw-r--r--drivers/video/via/vt1636.h2
23 files changed, 1625 insertions, 584 deletions
diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile
index eeed238ad6a2..d496adb0f832 100644
--- a/drivers/video/via/Makefile
+++ b/drivers/video/via/Makefile
@@ -4,4 +4,6 @@
4 4
5obj-$(CONFIG_FB_VIA) += viafb.o 5obj-$(CONFIG_FB_VIA) += viafb.o
6 6
7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o 7viafb-y :=viafbdev.o hw.o via_i2c.o dvi.o lcd.o ioctl.o accel.o \
8 via_utility.o vt1636.o global.o tblDPASetting.o viamode.o tbl1636.o \
9 via-core.o via-gpio.o via_modesetting.o
diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c
index d5077dfa9e00..e44893ea590d 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/via/accel.c
@@ -18,14 +18,45 @@
18 * Foundation, Inc., 18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21#include <linux/via-core.h>
21#include "global.h" 22#include "global.h"
22 23
24/*
25 * Figure out an appropriate bytes-per-pixel setting.
26 */
27static int viafb_set_bpp(void __iomem *engine, u8 bpp)
28{
29 u32 gemode;
30
31 /* Preserve the reserved bits */
32 /* Lowest 2 bits to zero gives us no rotation */
33 gemode = readl(engine + VIA_REG_GEMODE) & 0xfffffcfc;
34 switch (bpp) {
35 case 8:
36 gemode |= VIA_GEM_8bpp;
37 break;
38 case 16:
39 gemode |= VIA_GEM_16bpp;
40 break;
41 case 32:
42 gemode |= VIA_GEM_32bpp;
43 break;
44 default:
45 printk(KERN_WARNING "viafb_set_bpp: Unsupported bpp %d\n", bpp);
46 return -EINVAL;
47 }
48 writel(gemode, engine + VIA_REG_GEMODE);
49 return 0;
50}
51
52
23static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height, 53static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
24 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, 54 u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y,
25 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, 55 u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y,
26 u32 fg_color, u32 bg_color, u8 fill_rop) 56 u32 fg_color, u32 bg_color, u8 fill_rop)
27{ 57{
28 u32 ge_cmd = 0, tmp, i; 58 u32 ge_cmd = 0, tmp, i;
59 int ret;
29 60
30 if (!op || op > 3) { 61 if (!op || op > 3) {
31 printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op); 62 printk(KERN_WARNING "hw_bitblt_1: Invalid operation: %d\n", op);
@@ -59,22 +90,9 @@ static int hw_bitblt_1(void __iomem *engine, u8 op, u32 width, u32 height,
59 } 90 }
60 } 91 }
61 92
62 switch (dst_bpp) { 93 ret = viafb_set_bpp(engine, dst_bpp);
63 case 8: 94 if (ret)
64 tmp = 0x00000000; 95 return ret;
65 break;
66 case 16:
67 tmp = 0x00000100;
68 break;
69 case 32:
70 tmp = 0x00000300;
71 break;
72 default:
73 printk(KERN_WARNING "hw_bitblt_1: Unsupported bpp %d\n",
74 dst_bpp);
75 return -EINVAL;
76 }
77 writel(tmp, engine + 0x04);
78 96
79 if (op != VIA_BITBLT_FILL) { 97 if (op != VIA_BITBLT_FILL) {
80 if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000) 98 if (src_x & (op == VIA_BITBLT_MONO ? 0xFFFF8000 : 0xFFFFF000)
@@ -171,6 +189,7 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
171 u32 fg_color, u32 bg_color, u8 fill_rop) 189 u32 fg_color, u32 bg_color, u8 fill_rop)
172{ 190{
173 u32 ge_cmd = 0, tmp, i; 191 u32 ge_cmd = 0, tmp, i;
192 int ret;
174 193
175 if (!op || op > 3) { 194 if (!op || op > 3) {
176 printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op); 195 printk(KERN_WARNING "hw_bitblt_2: Invalid operation: %d\n", op);
@@ -204,22 +223,9 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height,
204 } 223 }
205 } 224 }
206 225
207 switch (dst_bpp) { 226 ret = viafb_set_bpp(engine, dst_bpp);
208 case 8: 227 if (ret)
209 tmp = 0x00000000; 228 return ret;
210 break;
211 case 16:
212 tmp = 0x00000100;
213 break;
214 case 32:
215 tmp = 0x00000300;
216 break;
217 default:
218 printk(KERN_WARNING "hw_bitblt_2: Unsupported bpp %d\n",
219 dst_bpp);
220 return -EINVAL;
221 }
222 writel(tmp, engine + 0x04);
223 229
224 if (op == VIA_BITBLT_FILL) 230 if (op == VIA_BITBLT_FILL)
225 tmp = 0; 231 tmp = 0;
@@ -312,17 +318,29 @@ int viafb_init_engine(struct fb_info *info)
312{ 318{
313 struct viafb_par *viapar = info->par; 319 struct viafb_par *viapar = info->par;
314 void __iomem *engine; 320 void __iomem *engine;
321 int highest_reg, i;
315 u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, 322 u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high,
316 vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; 323 vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name;
317 324
318 engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); 325 engine = viapar->shared->vdev->engine_mmio;
319 viapar->shared->engine_mmio = engine;
320 if (!engine) { 326 if (!engine) {
321 printk(KERN_WARNING "viafb_init_accel: ioremap failed, " 327 printk(KERN_WARNING "viafb_init_accel: ioremap failed, "
322 "hardware acceleration disabled\n"); 328 "hardware acceleration disabled\n");
323 return -ENOMEM; 329 return -ENOMEM;
324 } 330 }
325 331
332 /* Initialize registers to reset the 2D engine */
333 switch (viapar->shared->chip_info.twod_engine) {
334 case VIA_2D_ENG_M1:
335 highest_reg = 0x5c;
336 break;
337 default:
338 highest_reg = 0x40;
339 break;
340 }
341 for (i = 0; i <= highest_reg; i += 4)
342 writel(0x0, engine + i);
343
326 switch (chip_name) { 344 switch (chip_name) {
327 case UNICHROME_CLE266: 345 case UNICHROME_CLE266:
328 case UNICHROME_K400: 346 case UNICHROME_K400:
@@ -352,13 +370,28 @@ int viafb_init_engine(struct fb_info *info)
352 viapar->shared->vq_vram_addr = viapar->fbmem_free; 370 viapar->shared->vq_vram_addr = viapar->fbmem_free;
353 viapar->fbmem_used += VQ_SIZE; 371 viapar->fbmem_used += VQ_SIZE;
354 372
355 /* Init 2D engine reg to reset 2D engine */ 373#if defined(CONFIG_FB_VIA_CAMERA) || defined(CONFIG_FB_VIA_CAMERA_MODULE)
356 writel(0x0, engine + VIA_REG_KEYCONTROL); 374 /*
375 * Set aside a chunk of framebuffer memory for the camera
376 * driver. Someday this driver probably needs a proper allocator
377 * for fbmem; for now, we just have to do this before the
378 * framebuffer initializes itself.
379 *
380 * As for the size: the engine can handle three frames,
381 * 16 bits deep, up to VGA resolution.
382 */
383 viapar->shared->vdev->camera_fbmem_size = 3*VGA_HEIGHT*VGA_WIDTH*2;
384 viapar->fbmem_free -= viapar->shared->vdev->camera_fbmem_size;
385 viapar->fbmem_used += viapar->shared->vdev->camera_fbmem_size;
386 viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free;
387#endif
357 388
358 /* Init AGP and VQ regs */ 389 /* Init AGP and VQ regs */
359 switch (chip_name) { 390 switch (chip_name) {
360 case UNICHROME_K8M890: 391 case UNICHROME_K8M890:
361 case UNICHROME_P4M900: 392 case UNICHROME_P4M900:
393 case UNICHROME_VX800:
394 case UNICHROME_VX855:
362 writel(0x00100000, engine + VIA_REG_CR_TRANSET); 395 writel(0x00100000, engine + VIA_REG_CR_TRANSET);
363 writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE); 396 writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE);
364 writel(0x02000000, engine + VIA_REG_CR_TRANSPACE); 397 writel(0x02000000, engine + VIA_REG_CR_TRANSPACE);
@@ -393,6 +426,8 @@ int viafb_init_engine(struct fb_info *info)
393 switch (chip_name) { 426 switch (chip_name) {
394 case UNICHROME_K8M890: 427 case UNICHROME_K8M890:
395 case UNICHROME_P4M900: 428 case UNICHROME_P4M900:
429 case UNICHROME_VX800:
430 case UNICHROME_VX855:
396 vq_start_low |= 0x20000000; 431 vq_start_low |= 0x20000000;
397 vq_end_low |= 0x20000000; 432 vq_end_low |= 0x20000000;
398 vq_high |= 0x20000000; 433 vq_high |= 0x20000000;
@@ -446,7 +481,7 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status)
446 struct viafb_par *viapar = info->par; 481 struct viafb_par *viapar = info->par;
447 u32 temp, iga_path = viapar->iga_path; 482 u32 temp, iga_path = viapar->iga_path;
448 483
449 temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); 484 temp = readl(viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE);
450 switch (Status) { 485 switch (Status) {
451 case HW_Cursor_ON: 486 case HW_Cursor_ON:
452 temp |= 0x1; 487 temp |= 0x1;
@@ -463,23 +498,33 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status)
463 default: 498 default:
464 temp &= 0x7FFFFFFF; 499 temp &= 0x7FFFFFFF;
465 } 500 }
466 writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); 501 writel(temp, viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE);
467} 502}
468 503
469void viafb_wait_engine_idle(struct fb_info *info) 504void viafb_wait_engine_idle(struct fb_info *info)
470{ 505{
471 struct viafb_par *viapar = info->par; 506 struct viafb_par *viapar = info->par;
472 int loop = 0; 507 int loop = 0;
473 508 u32 mask;
474 while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & 509 void __iomem *engine = viapar->shared->vdev->engine_mmio;
475 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { 510
476 loop++; 511 switch (viapar->shared->chip_info.twod_engine) {
477 cpu_relax(); 512 case VIA_2D_ENG_H5:
513 case VIA_2D_ENG_M1:
514 mask = VIA_CMD_RGTR_BUSY_M1 | VIA_2D_ENG_BUSY_M1 |
515 VIA_3D_ENG_BUSY_M1;
516 break;
517 default:
518 while (!(readl(engine + VIA_REG_STATUS) &
519 VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) {
520 loop++;
521 cpu_relax();
522 }
523 mask = VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY;
524 break;
478 } 525 }
479 526
480 while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & 527 while ((readl(engine + VIA_REG_STATUS) & mask) && (loop < MAXLOOP)) {
481 (VIA_CMD_RGTR_BUSY | VIA_2D_ENG_BUSY | VIA_3D_ENG_BUSY)) &&
482 (loop < MAXLOOP)) {
483 loop++; 528 loop++;
484 cpu_relax(); 529 cpu_relax();
485 } 530 }
diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h
index 615c84ad0f01..2c122d292365 100644
--- a/drivers/video/via/accel.h
+++ b/drivers/video/via/accel.h
@@ -67,6 +67,34 @@
67/* from 0x100 to 0x1ff */ 67/* from 0x100 to 0x1ff */
68#define VIA_REG_COLORPAT 0x100 68#define VIA_REG_COLORPAT 0x100
69 69
70/* defines for VIA 2D registers for vt3353/3409 (M1 engine)*/
71#define VIA_REG_GECMD_M1 0x000
72#define VIA_REG_GEMODE_M1 0x004
73#define VIA_REG_GESTATUS_M1 0x004 /* as same as VIA_REG_GEMODE */
74#define VIA_REG_PITCH_M1 0x008 /* pitch of src and dst */
75#define VIA_REG_DIMENSION_M1 0x00C /* width and height */
76#define VIA_REG_DSTPOS_M1 0x010
77#define VIA_REG_LINE_XY_M1 0x010
78#define VIA_REG_DSTBASE_M1 0x014
79#define VIA_REG_SRCPOS_M1 0x018
80#define VIA_REG_LINE_K1K2_M1 0x018
81#define VIA_REG_SRCBASE_M1 0x01C
82#define VIA_REG_PATADDR_M1 0x020
83#define VIA_REG_MONOPAT0_M1 0x024
84#define VIA_REG_MONOPAT1_M1 0x028
85#define VIA_REG_OFFSET_M1 0x02C
86#define VIA_REG_LINE_ERROR_M1 0x02C
87#define VIA_REG_CLIPTL_M1 0x040 /* top and left of clipping */
88#define VIA_REG_CLIPBR_M1 0x044 /* bottom and right of clipping */
89#define VIA_REG_KEYCONTROL_M1 0x048 /* color key control */
90#define VIA_REG_FGCOLOR_M1 0x04C
91#define VIA_REG_DSTCOLORKEY_M1 0x04C /* as same as VIA_REG_FG */
92#define VIA_REG_BGCOLOR_M1 0x050
93#define VIA_REG_SRCCOLORKEY_M1 0x050 /* as same as VIA_REG_BG */
94#define VIA_REG_MONOPATFGC_M1 0x058 /* Add BG color of Pattern. */
95#define VIA_REG_MONOPATBGC_M1 0x05C /* Add FG color of Pattern. */
96#define VIA_REG_COLORPAT_M1 0x100 /* from 0x100 to 0x1ff */
97
70/* VIA_REG_PITCH(0x38): Pitch Setting */ 98/* VIA_REG_PITCH(0x38): Pitch Setting */
71#define VIA_PITCH_ENABLE 0x80000000 99#define VIA_PITCH_ENABLE 0x80000000
72 100
@@ -157,6 +185,18 @@
157/* Virtual Queue is busy */ 185/* Virtual Queue is busy */
158#define VIA_VR_QUEUE_BUSY 0x00020000 186#define VIA_VR_QUEUE_BUSY 0x00020000
159 187
188/* VIA_REG_STATUS(0x400): Engine Status for H5 */
189#define VIA_CMD_RGTR_BUSY_H5 0x00000010 /* Command Regulator is busy */
190#define VIA_2D_ENG_BUSY_H5 0x00000002 /* 2D Engine is busy */
191#define VIA_3D_ENG_BUSY_H5 0x00001FE1 /* 3D Engine is busy */
192#define VIA_VR_QUEUE_BUSY_H5 0x00000004 /* Virtual Queue is busy */
193
194/* VIA_REG_STATUS(0x400): Engine Status for VT3353/3409 */
195#define VIA_CMD_RGTR_BUSY_M1 0x00000010 /* Command Regulator is busy */
196#define VIA_2D_ENG_BUSY_M1 0x00000002 /* 2D Engine is busy */
197#define VIA_3D_ENG_BUSY_M1 0x00001FE1 /* 3D Engine is busy */
198#define VIA_VR_QUEUE_BUSY_M1 0x00000004 /* Virtual Queue is busy */
199
160#define MAXLOOP 0xFFFFFF 200#define MAXLOOP 0xFFFFFF
161 201
162#define VIA_BITBLT_COLOR 1 202#define VIA_BITBLT_COLOR 1
diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h
index 8c06bd3c0b4d..d9b6e06e0700 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/via/chip.h
@@ -121,9 +121,17 @@ struct lvds_chip_information {
121 int i2c_port; 121 int i2c_port;
122}; 122};
123 123
124/* The type of 2D engine */
125enum via_2d_engine {
126 VIA_2D_ENG_H2,
127 VIA_2D_ENG_H5,
128 VIA_2D_ENG_M1,
129};
130
124struct chip_information { 131struct chip_information {
125 int gfx_chip_name; 132 int gfx_chip_name;
126 int gfx_chip_revision; 133 int gfx_chip_revision;
134 enum via_2d_engine twod_engine;
127 struct tmds_chip_information tmds_chip_info; 135 struct tmds_chip_information tmds_chip_info;
128 struct lvds_chip_information lvds_chip_info; 136 struct lvds_chip_information lvds_chip_info;
129 struct lvds_chip_information lvds_chip_info2; 137 struct lvds_chip_information lvds_chip_info2;
diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c
index abe59b8c7a05..39b040bb3817 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/via/dvi.c
@@ -18,6 +18,8 @@
18 * Foundation, Inc., 18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21#include <linux/via-core.h>
22#include <linux/via_i2c.h>
21#include "global.h" 23#include "global.h"
22 24
23static void tmds_register_write(int index, u8 data); 25static void tmds_register_write(int index, u8 data);
@@ -96,7 +98,7 @@ int viafb_tmds_trasmitter_identify(void)
96 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; 98 viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
97 viaparinfo->chip_info-> 99 viaparinfo->chip_info->
98 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; 100 tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
99 viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX; 101 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31;
100 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { 102 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) {
101 /* 103 /*
102 * Currently only support 12bits,dual edge,add 24bits mode later 104 * Currently only support 12bits,dual edge,add 24bits mode later
@@ -110,7 +112,7 @@ int viafb_tmds_trasmitter_identify(void)
110 viaparinfo->chip_info->tmds_chip_info.i2c_port); 112 viaparinfo->chip_info->tmds_chip_info.i2c_port);
111 return OK; 113 return OK;
112 } else { 114 } else {
113 viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX; 115 viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C;
114 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) 116 if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)
115 != FAIL) { 117 != FAIL) {
116 tmds_register_write(0x08, 0x3b); 118 tmds_register_write(0x08, 0x3b);
@@ -160,32 +162,26 @@ int viafb_tmds_trasmitter_identify(void)
160 162
161static void tmds_register_write(int index, u8 data) 163static void tmds_register_write(int index, u8 data)
162{ 164{
163 viaparinfo->shared->i2c_stuff.i2c_port = 165 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
164 viaparinfo->chip_info->tmds_chip_info.i2c_port; 166 viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
165 167 index, data);
166 viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.
167 tmds_chip_slave_addr, index,
168 data);
169} 168}
170 169
171static int tmds_register_read(int index) 170static int tmds_register_read(int index)
172{ 171{
173 u8 data; 172 u8 data;
174 173
175 viaparinfo->shared->i2c_stuff.i2c_port = 174 viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
176 viaparinfo->chip_info->tmds_chip_info.i2c_port; 175 (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
177 viafb_i2c_readbyte((u8) viaparinfo->chip_info-> 176 (u8) index, &data);
178 tmds_chip_info.tmds_chip_slave_addr,
179 (u8) index, &data);
180 return data; 177 return data;
181} 178}
182 179
183static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) 180static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
184{ 181{
185 viaparinfo->shared->i2c_stuff.i2c_port = 182 viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port,
186 viaparinfo->chip_info->tmds_chip_info.i2c_port; 183 (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
187 viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. 184 (u8) index, buff, buff_len);
188 tmds_chip_slave_addr, (u8) index, buff, buff_len);
189 return 0; 185 return 0;
190} 186}
191 187
@@ -541,9 +537,10 @@ void viafb_dvi_enable(void)
541 else 537 else
542 data = 0x37; 538 data = 0x37;
543 viafb_i2c_writebyte(viaparinfo->chip_info-> 539 viafb_i2c_writebyte(viaparinfo->chip_info->
544 tmds_chip_info. 540 tmds_chip_info.i2c_port,
545 tmds_chip_slave_addr, 541 viaparinfo->chip_info->
546 0x08, data); 542 tmds_chip_info.tmds_chip_slave_addr,
543 0x08, data);
547 } 544 }
548 } 545 }
549 } 546 }
diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h
index 8d95d5fd1388..28221a062dda 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/via/global.h
@@ -41,7 +41,6 @@
41#include "share.h" 41#include "share.h"
42#include "dvi.h" 42#include "dvi.h"
43#include "viamode.h" 43#include "viamode.h"
44#include "via_i2c.h"
45#include "hw.h" 44#include "hw.h"
46 45
47#include "lcd.h" 46#include "lcd.h"
diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c
index f2583b1b527f..b996803ae2c1 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/via/hw.c
@@ -19,6 +19,7 @@
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22#include <linux/via-core.h>
22#include "global.h" 23#include "global.h"
23 24
24static struct pll_map pll_value[] = { 25static struct pll_map pll_value[] = {
@@ -62,6 +63,7 @@ static struct pll_map pll_value[] = {
62 CX700_52_977M, VX855_52_977M}, 63 CX700_52_977M, VX855_52_977M},
63 {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M, 64 {CLK_56_250M, CLE266_PLL_56_250M, K800_PLL_56_250M,
64 CX700_56_250M, VX855_56_250M}, 65 CX700_56_250M, VX855_56_250M},
66 {CLK_57_275M, 0, 0, 0, VX855_57_275M},
65 {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M, 67 {CLK_60_466M, CLE266_PLL_60_466M, K800_PLL_60_466M,
66 CX700_60_466M, VX855_60_466M}, 68 CX700_60_466M, VX855_60_466M},
67 {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M, 69 {CLK_61_500M, CLE266_PLL_61_500M, K800_PLL_61_500M,
@@ -525,8 +527,7 @@ static void dvi_patch_skew_dvp_low(void);
525static void set_dvi_output_path(int set_iga, int output_interface); 527static void set_dvi_output_path(int set_iga, int output_interface);
526static void set_lcd_output_path(int set_iga, int output_interface); 528static void set_lcd_output_path(int set_iga, int output_interface);
527static void load_fix_bit_crtc_reg(void); 529static void load_fix_bit_crtc_reg(void);
528static void init_gfx_chip_info(struct pci_dev *pdev, 530static void init_gfx_chip_info(int chip_type);
529 const struct pci_device_id *pdi);
530static void init_tmds_chip_info(void); 531static void init_tmds_chip_info(void);
531static void init_lvds_chip_info(void); 532static void init_lvds_chip_info(void);
532static void device_screen_off(void); 533static void device_screen_off(void);
@@ -537,18 +538,6 @@ static void device_on(void);
537static void enable_second_display_channel(void); 538static void enable_second_display_channel(void);
538static void disable_second_display_channel(void); 539static void disable_second_display_channel(void);
539 540
540void viafb_write_reg(u8 index, u16 io_port, u8 data)
541{
542 outb(index, io_port);
543 outb(data, io_port + 1);
544 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, data); */
545}
546u8 viafb_read_reg(int io_port, u8 index)
547{
548 outb(index, io_port);
549 return inb(io_port + 1);
550}
551
552void viafb_lock_crt(void) 541void viafb_lock_crt(void)
553{ 542{
554 viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7); 543 viafb_write_reg_mask(CR11, VIACR, BIT7, BIT7);
@@ -560,16 +549,6 @@ void viafb_unlock_crt(void)
560 viafb_write_reg_mask(CR47, VIACR, 0, BIT0); 549 viafb_write_reg_mask(CR47, VIACR, 0, BIT0);
561} 550}
562 551
563void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask)
564{
565 u8 tmp;
566
567 outb(index, io_port);
568 tmp = inb(io_port + 1);
569 outb((data & mask) | (tmp & (~mask)), io_port + 1);
570 /*DEBUG_MSG(KERN_INFO "\nIndex=%2d Value=%2d", index, tmp); */
571}
572
573void write_dac_reg(u8 index, u8 r, u8 g, u8 b) 552void write_dac_reg(u8 index, u8 r, u8 g, u8 b)
574{ 553{
575 outb(index, LUT_INDEX_WRITE); 554 outb(index, LUT_INDEX_WRITE);
@@ -646,102 +625,6 @@ void viafb_set_iga_path(void)
646 } 625 }
647} 626}
648 627
649void viafb_set_primary_address(u32 addr)
650{
651 DEBUG_MSG(KERN_DEBUG "viafb_set_primary_address(0x%08X)\n", addr);
652 viafb_write_reg(CR0D, VIACR, addr & 0xFF);
653 viafb_write_reg(CR0C, VIACR, (addr >> 8) & 0xFF);
654 viafb_write_reg(CR34, VIACR, (addr >> 16) & 0xFF);
655 viafb_write_reg_mask(CR48, VIACR, (addr >> 24) & 0x1F, 0x1F);
656}
657
658void viafb_set_secondary_address(u32 addr)
659{
660 DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_address(0x%08X)\n", addr);
661 /* secondary display supports only quadword aligned memory */
662 viafb_write_reg_mask(CR62, VIACR, (addr >> 2) & 0xFE, 0xFE);
663 viafb_write_reg(CR63, VIACR, (addr >> 10) & 0xFF);
664 viafb_write_reg(CR64, VIACR, (addr >> 18) & 0xFF);
665 viafb_write_reg_mask(CRA3, VIACR, (addr >> 26) & 0x07, 0x07);
666}
667
668void viafb_set_primary_pitch(u32 pitch)
669{
670 DEBUG_MSG(KERN_DEBUG "viafb_set_primary_pitch(0x%08X)\n", pitch);
671 /* spec does not say that first adapter skips 3 bits but old
672 * code did it and seems to be reasonable in analogy to 2nd adapter
673 */
674 pitch = pitch >> 3;
675 viafb_write_reg(0x13, VIACR, pitch & 0xFF);
676 viafb_write_reg_mask(0x35, VIACR, (pitch >> (8 - 5)) & 0xE0, 0xE0);
677}
678
679void viafb_set_secondary_pitch(u32 pitch)
680{
681 DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_pitch(0x%08X)\n", pitch);
682 pitch = pitch >> 3;
683 viafb_write_reg(0x66, VIACR, pitch & 0xFF);
684 viafb_write_reg_mask(0x67, VIACR, (pitch >> 8) & 0x03, 0x03);
685 viafb_write_reg_mask(0x71, VIACR, (pitch >> (10 - 7)) & 0x80, 0x80);
686}
687
688void viafb_set_primary_color_depth(u8 depth)
689{
690 u8 value;
691
692 DEBUG_MSG(KERN_DEBUG "viafb_set_primary_color_depth(%d)\n", depth);
693 switch (depth) {
694 case 8:
695 value = 0x00;
696 break;
697 case 15:
698 value = 0x04;
699 break;
700 case 16:
701 value = 0x14;
702 break;
703 case 24:
704 value = 0x0C;
705 break;
706 case 30:
707 value = 0x08;
708 break;
709 default:
710 printk(KERN_WARNING "viafb_set_primary_color_depth: "
711 "Unsupported depth: %d\n", depth);
712 return;
713 }
714
715 viafb_write_reg_mask(0x15, VIASR, value, 0x1C);
716}
717
718void viafb_set_secondary_color_depth(u8 depth)
719{
720 u8 value;
721
722 DEBUG_MSG(KERN_DEBUG "viafb_set_secondary_color_depth(%d)\n", depth);
723 switch (depth) {
724 case 8:
725 value = 0x00;
726 break;
727 case 16:
728 value = 0x40;
729 break;
730 case 24:
731 value = 0xC0;
732 break;
733 case 30:
734 value = 0x80;
735 break;
736 default:
737 printk(KERN_WARNING "viafb_set_secondary_color_depth: "
738 "Unsupported depth: %d\n", depth);
739 return;
740 }
741
742 viafb_write_reg_mask(0x67, VIACR, value, 0xC0);
743}
744
745static void set_color_register(u8 index, u8 red, u8 green, u8 blue) 628static void set_color_register(u8 index, u8 red, u8 green, u8 blue)
746{ 629{
747 outb(0xFF, 0x3C6); /* bit mask of palette */ 630 outb(0xFF, 0x3C6); /* bit mask of palette */
@@ -1126,16 +1009,12 @@ void viafb_load_reg(int timing_value, int viafb_load_reg_num,
1126void viafb_write_regx(struct io_reg RegTable[], int ItemNum) 1009void viafb_write_regx(struct io_reg RegTable[], int ItemNum)
1127{ 1010{
1128 int i; 1011 int i;
1129 unsigned char RegTemp;
1130 1012
1131 /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */ 1013 /*DEBUG_MSG(KERN_INFO "Table Size : %x!!\n",ItemNum ); */
1132 1014
1133 for (i = 0; i < ItemNum; i++) { 1015 for (i = 0; i < ItemNum; i++)
1134 outb(RegTable[i].index, RegTable[i].port); 1016 via_write_reg_mask(RegTable[i].port, RegTable[i].index,
1135 RegTemp = inb(RegTable[i].port + 1); 1017 RegTable[i].value, RegTable[i].mask);
1136 RegTemp = (RegTemp & (~RegTable[i].mask)) | RegTable[i].value;
1137 outb(RegTemp, RegTable[i].port + 1);
1138 }
1139} 1018}
1140 1019
1141void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga) 1020void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga)
@@ -1516,8 +1395,6 @@ u32 viafb_get_clk_value(int clk)
1516/* Set VCLK*/ 1395/* Set VCLK*/
1517void viafb_set_vclock(u32 CLK, int set_iga) 1396void viafb_set_vclock(u32 CLK, int set_iga)
1518{ 1397{
1519 unsigned char RegTemp;
1520
1521 /* H.W. Reset : ON */ 1398 /* H.W. Reset : ON */
1522 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); 1399 viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);
1523 1400
@@ -1590,8 +1467,7 @@ void viafb_set_vclock(u32 CLK, int set_iga)
1590 } 1467 }
1591 1468
1592 /* Fire! */ 1469 /* Fire! */
1593 RegTemp = inb(VIARMisc); 1470 via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */
1594 outb(RegTemp | (BIT2 + BIT3), VIAWMisc);
1595} 1471}
1596 1472
1597void viafb_load_crtc_timing(struct display_timing device_timing, 1473void viafb_load_crtc_timing(struct display_timing device_timing,
@@ -1835,6 +1711,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1835 int index = 0; 1711 int index = 0;
1836 int h_addr, v_addr; 1712 int h_addr, v_addr;
1837 u32 pll_D_N; 1713 u32 pll_D_N;
1714 u8 polarity = 0;
1838 1715
1839 for (i = 0; i < video_mode->mode_array; i++) { 1716 for (i = 0; i < video_mode->mode_array; i++) {
1840 index = i; 1717 index = i;
@@ -1863,20 +1740,11 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1863 v_addr = crt_reg.ver_addr; 1740 v_addr = crt_reg.ver_addr;
1864 1741
1865 /* update polarity for CRT timing */ 1742 /* update polarity for CRT timing */
1866 if (crt_table[index].h_sync_polarity == NEGATIVE) { 1743 if (crt_table[index].h_sync_polarity == NEGATIVE)
1867 if (crt_table[index].v_sync_polarity == NEGATIVE) 1744 polarity |= BIT6;
1868 outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | 1745 if (crt_table[index].v_sync_polarity == NEGATIVE)
1869 (BIT6 + BIT7), VIAWMisc); 1746 polarity |= BIT7;
1870 else 1747 via_write_misc_reg_mask(polarity, BIT6 | BIT7);
1871 outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT6),
1872 VIAWMisc);
1873 } else {
1874 if (crt_table[index].v_sync_polarity == NEGATIVE)
1875 outb((inb(VIARMisc) & (~(BIT6 + BIT7))) | (BIT7),
1876 VIAWMisc);
1877 else
1878 outb((inb(VIARMisc) & (~(BIT6 + BIT7))), VIAWMisc);
1879 }
1880 1748
1881 if (set_iga == IGA1) { 1749 if (set_iga == IGA1) {
1882 viafb_unlock_crt(); 1750 viafb_unlock_crt();
@@ -1910,10 +1778,9 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,
1910 1778
1911} 1779}
1912 1780
1913void viafb_init_chip_info(struct pci_dev *pdev, 1781void viafb_init_chip_info(int chip_type)
1914 const struct pci_device_id *pdi)
1915{ 1782{
1916 init_gfx_chip_info(pdev, pdi); 1783 init_gfx_chip_info(chip_type);
1917 init_tmds_chip_info(); 1784 init_tmds_chip_info();
1918 init_lvds_chip_info(); 1785 init_lvds_chip_info();
1919 1786
@@ -1980,12 +1847,11 @@ void viafb_update_device_setting(int hres, int vres,
1980 } 1847 }
1981} 1848}
1982 1849
1983static void init_gfx_chip_info(struct pci_dev *pdev, 1850static void init_gfx_chip_info(int chip_type)
1984 const struct pci_device_id *pdi)
1985{ 1851{
1986 u8 tmp; 1852 u8 tmp;
1987 1853
1988 viaparinfo->chip_info->gfx_chip_name = pdi->driver_data; 1854 viaparinfo->chip_info->gfx_chip_name = chip_type;
1989 1855
1990 /* Check revision of CLE266 Chip */ 1856 /* Check revision of CLE266 Chip */
1991 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { 1857 if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) {
@@ -2016,6 +1882,21 @@ static void init_gfx_chip_info(struct pci_dev *pdev,
2016 CX700_REVISION_700; 1882 CX700_REVISION_700;
2017 } 1883 }
2018 } 1884 }
1885
1886 /* Determine which 2D engine we have */
1887 switch (viaparinfo->chip_info->gfx_chip_name) {
1888 case UNICHROME_VX800:
1889 case UNICHROME_VX855:
1890 viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1;
1891 break;
1892 case UNICHROME_K8M890:
1893 case UNICHROME_P4M900:
1894 viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H5;
1895 break;
1896 default:
1897 viaparinfo->chip_info->twod_engine = VIA_2D_ENG_H2;
1898 break;
1899 }
2019} 1900}
2020 1901
2021static void init_tmds_chip_info(void) 1902static void init_tmds_chip_info(void)
@@ -2232,13 +2113,11 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2232 2113
2233 /* Fill VPIT Parameters */ 2114 /* Fill VPIT Parameters */
2234 /* Write Misc Register */ 2115 /* Write Misc Register */
2235 outb(VPIT.Misc, VIAWMisc); 2116 outb(VPIT.Misc, VIA_MISC_REG_WRITE);
2236 2117
2237 /* Write Sequencer */ 2118 /* Write Sequencer */
2238 for (i = 1; i <= StdSR; i++) { 2119 for (i = 1; i <= StdSR; i++)
2239 outb(i, VIASR); 2120 via_write_reg(VIASR, i, VPIT.SR[i - 1]);
2240 outb(VPIT.SR[i - 1], VIASR + 1);
2241 }
2242 2121
2243 viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); 2122 viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2);
2244 viafb_set_iga_path(); 2123 viafb_set_iga_path();
@@ -2247,10 +2126,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2247 viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); 2126 viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1);
2248 2127
2249 /* Write Graphic Controller */ 2128 /* Write Graphic Controller */
2250 for (i = 0; i < StdGR; i++) { 2129 for (i = 0; i < StdGR; i++)
2251 outb(i, VIAGR); 2130 via_write_reg(VIAGR, i, VPIT.GR[i]);
2252 outb(VPIT.GR[i], VIAGR + 1);
2253 }
2254 2131
2255 /* Write Attribute Controller */ 2132 /* Write Attribute Controller */
2256 for (i = 0; i < StdAR; i++) { 2133 for (i = 0; i < StdAR; i++) {
@@ -2277,11 +2154,11 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
2277 } 2154 }
2278 } 2155 }
2279 2156
2280 viafb_set_primary_pitch(viafbinfo->fix.line_length); 2157 via_set_primary_pitch(viafbinfo->fix.line_length);
2281 viafb_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length 2158 via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length
2282 : viafbinfo->fix.line_length); 2159 : viafbinfo->fix.line_length);
2283 viafb_set_primary_color_depth(viaparinfo->depth); 2160 via_set_primary_color_depth(viaparinfo->depth);
2284 viafb_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth 2161 via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth
2285 : viaparinfo->depth); 2162 : viaparinfo->depth);
2286 /* Update Refresh Rate Setting */ 2163 /* Update Refresh Rate Setting */
2287 2164
@@ -2473,108 +2350,6 @@ static void disable_second_display_channel(void)
2473 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); 2350 viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6);
2474} 2351}
2475 2352
2476int viafb_get_fb_size_from_pci(void)
2477{
2478 unsigned long configid, deviceid, FBSize = 0;
2479 int VideoMemSize;
2480 int DeviceFound = false;
2481
2482 for (configid = 0x80000000; configid < 0x80010800; configid += 0x100) {
2483 outl(configid, (unsigned long)0xCF8);
2484 deviceid = (inl((unsigned long)0xCFC) >> 16) & 0xffff;
2485
2486 switch (deviceid) {
2487 case CLE266:
2488 case KM400:
2489 outl(configid + 0xE0, (unsigned long)0xCF8);
2490 FBSize = inl((unsigned long)0xCFC);
2491 DeviceFound = true; /* Found device id */
2492 break;
2493
2494 case CN400_FUNCTION3:
2495 case CN700_FUNCTION3:
2496 case CX700_FUNCTION3:
2497 case KM800_FUNCTION3:
2498 case KM890_FUNCTION3:
2499 case P4M890_FUNCTION3:
2500 case P4M900_FUNCTION3:
2501 case VX800_FUNCTION3:
2502 case VX855_FUNCTION3:
2503 /*case CN750_FUNCTION3: */
2504 outl(configid + 0xA0, (unsigned long)0xCF8);
2505 FBSize = inl((unsigned long)0xCFC);
2506 DeviceFound = true; /* Found device id */
2507 break;
2508
2509 default:
2510 break;
2511 }
2512
2513 if (DeviceFound)
2514 break;
2515 }
2516
2517 DEBUG_MSG(KERN_INFO "Device ID = %lx\n", deviceid);
2518
2519 FBSize = FBSize & 0x00007000;
2520 DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
2521
2522 if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) {
2523 switch (FBSize) {
2524 case 0x00004000:
2525 VideoMemSize = (16 << 20); /*16M */
2526 break;
2527
2528 case 0x00005000:
2529 VideoMemSize = (32 << 20); /*32M */
2530 break;
2531
2532 case 0x00006000:
2533 VideoMemSize = (64 << 20); /*64M */
2534 break;
2535
2536 default:
2537 VideoMemSize = (32 << 20); /*32M */
2538 break;
2539 }
2540 } else {
2541 switch (FBSize) {
2542 case 0x00001000:
2543 VideoMemSize = (8 << 20); /*8M */
2544 break;
2545
2546 case 0x00002000:
2547 VideoMemSize = (16 << 20); /*16M */
2548 break;
2549
2550 case 0x00003000:
2551 VideoMemSize = (32 << 20); /*32M */
2552 break;
2553
2554 case 0x00004000:
2555 VideoMemSize = (64 << 20); /*64M */
2556 break;
2557
2558 case 0x00005000:
2559 VideoMemSize = (128 << 20); /*128M */
2560 break;
2561
2562 case 0x00006000:
2563 VideoMemSize = (256 << 20); /*256M */
2564 break;
2565
2566 case 0x00007000: /* Only on VX855/875 */
2567 VideoMemSize = (512 << 20); /*512M */
2568 break;
2569
2570 default:
2571 VideoMemSize = (32 << 20); /*32M */
2572 break;
2573 }
2574 }
2575
2576 return VideoMemSize;
2577}
2578 2353
2579void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ 2354void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\
2580 *p_gfx_dpa_setting) 2355 *p_gfx_dpa_setting)
diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h
index 12ef32d334cb..a109de379816 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/via/hw.h
@@ -24,6 +24,11 @@
24 24
25#include "viamode.h" 25#include "viamode.h"
26#include "global.h" 26#include "global.h"
27#include "via_modesetting.h"
28
29#define viafb_read_reg(p, i) via_read_reg(p, i)
30#define viafb_write_reg(i, p, d) via_write_reg(p, i, d)
31#define viafb_write_reg_mask(i, p, d, m) via_write_reg_mask(p, i, d, m)
27 32
28/*************************************************** 33/***************************************************
29* Definition IGA1 Design Method of CRTC Registers * 34* Definition IGA1 Design Method of CRTC Registers *
@@ -823,8 +828,8 @@ struct iga2_crtc_timing {
823}; 828};
824 829
825/* device ID */ 830/* device ID */
826#define CLE266 0x3123 831#define CLE266_FUNCTION3 0x3123
827#define KM400 0x3205 832#define KM400_FUNCTION3 0x3205
828#define CN400_FUNCTION2 0x2259 833#define CN400_FUNCTION2 0x2259
829#define CN400_FUNCTION3 0x3259 834#define CN400_FUNCTION3 0x3259
830/* support VT3314 chipset */ 835/* support VT3314 chipset */
@@ -870,7 +875,6 @@ extern int viafb_LCD_ON;
870extern int viafb_DVI_ON; 875extern int viafb_DVI_ON;
871extern int viafb_hotplug; 876extern int viafb_hotplug;
872 877
873void viafb_write_reg_mask(u8 index, int io_port, u8 data, u8 mask);
874void viafb_set_output_path(int device, int set_iga, 878void viafb_set_output_path(int device, int set_iga,
875 int output_interface); 879 int output_interface);
876 880
@@ -885,8 +889,6 @@ void viafb_crt_disable(void);
885void viafb_crt_enable(void); 889void viafb_crt_enable(void);
886void init_ad9389(void); 890void init_ad9389(void);
887/* Access I/O Function */ 891/* Access I/O Function */
888void viafb_write_reg(u8 index, u16 io_port, u8 data);
889u8 viafb_read_reg(int io_port, u8 index);
890void viafb_lock_crt(void); 892void viafb_lock_crt(void);
891void viafb_unlock_crt(void); 893void viafb_unlock_crt(void);
892void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga); 894void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);
@@ -900,20 +902,14 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,
900 struct VideoModeTable *vmode_tbl1, int video_bpp1); 902 struct VideoModeTable *vmode_tbl1, int video_bpp1);
901void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, 903void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh,
902 struct VideoModeTable *vmode_tbl); 904 struct VideoModeTable *vmode_tbl);
903void viafb_init_chip_info(struct pci_dev *pdev, 905void viafb_init_chip_info(int chip_type);
904 const struct pci_device_id *pdi);
905void viafb_init_dac(int set_iga); 906void viafb_init_dac(int set_iga);
906int viafb_get_pixclock(int hres, int vres, int vmode_refresh); 907int viafb_get_pixclock(int hres, int vres, int vmode_refresh);
907int viafb_get_refresh(int hres, int vres, u32 float_refresh); 908int viafb_get_refresh(int hres, int vres, u32 float_refresh);
908void viafb_update_device_setting(int hres, int vres, int bpp, 909void viafb_update_device_setting(int hres, int vres, int bpp,
909 int vmode_refresh, int flag); 910 int vmode_refresh, int flag);
910 911
911int viafb_get_fb_size_from_pci(void);
912void viafb_set_iga_path(void); 912void viafb_set_iga_path(void);
913void viafb_set_primary_address(u32 addr);
914void viafb_set_secondary_address(u32 addr);
915void viafb_set_primary_pitch(u32 pitch);
916void viafb_set_secondary_pitch(u32 pitch);
917void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue); 913void viafb_set_primary_color_register(u8 index, u8 red, u8 green, u8 blue);
918void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue); 914void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue);
919void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len); 915void viafb_get_fb_info(unsigned int *fb_base, unsigned int *fb_len);
diff --git a/drivers/video/via/ioctl.h b/drivers/video/via/ioctl.h
index de899807eade..c430fa23008a 100644
--- a/drivers/video/via/ioctl.h
+++ b/drivers/video/via/ioctl.h
@@ -75,7 +75,7 @@
75/*SAMM operation flag*/ 75/*SAMM operation flag*/
76#define OP_SAMM 0x80 76#define OP_SAMM 0x80
77 77
78#define LCD_PANEL_ID_MAXIMUM 22 78#define LCD_PANEL_ID_MAXIMUM 23
79 79
80#define STATE_ON 0x1 80#define STATE_ON 0x1
81#define STATE_OFF 0x0 81#define STATE_OFF 0x0
diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c
index 1b1ccdc2d83d..2ab0f156439a 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/via/lcd.c
@@ -18,7 +18,8 @@
18 * Foundation, Inc., 18 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21#include <linux/via-core.h>
22#include <linux/via_i2c.h>
22#include "global.h" 23#include "global.h"
23#include "lcdtbl.h" 24#include "lcdtbl.h"
24 25
@@ -172,18 +173,16 @@ static bool lvds_identify_integratedlvds(void)
172 173
173int viafb_lvds_trasmitter_identify(void) 174int viafb_lvds_trasmitter_identify(void)
174{ 175{
175 viaparinfo->shared->i2c_stuff.i2c_port = I2CPORTINDEX; 176 if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {
176 if (viafb_lvds_identify_vt1636()) { 177 viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31;
177 viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX;
178 DEBUG_MSG(KERN_INFO 178 DEBUG_MSG(KERN_INFO
179 "Found VIA VT1636 LVDS on port i2c 0x31 \n"); 179 "Found VIA VT1636 LVDS on port i2c 0x31\n");
180 } else { 180 } else {
181 viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; 181 if (viafb_lvds_identify_vt1636(VIA_PORT_2C)) {
182 if (viafb_lvds_identify_vt1636()) {
183 viaparinfo->chip_info->lvds_chip_info.i2c_port = 182 viaparinfo->chip_info->lvds_chip_info.i2c_port =
184 GPIOPORTINDEX; 183 VIA_PORT_2C;
185 DEBUG_MSG(KERN_INFO 184 DEBUG_MSG(KERN_INFO
186 "Found VIA VT1636 LVDS on port gpio 0x2c \n"); 185 "Found VIA VT1636 LVDS on port gpio 0x2c\n");
187 } 186 }
188 } 187 }
189 188
@@ -398,6 +397,15 @@ static void fp_id_to_vindex(int panel_id)
398 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; 397 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
399 viaparinfo->lvds_setting_info->LCDDithering = 1; 398 viaparinfo->lvds_setting_info->LCDDithering = 1;
400 break; 399 break;
400 case 0x17:
401 /* OLPC XO-1.5 panel */
402 viaparinfo->lvds_setting_info->lcd_panel_hres = 1200;
403 viaparinfo->lvds_setting_info->lcd_panel_vres = 900;
404 viaparinfo->lvds_setting_info->lcd_panel_id =
405 LCD_PANEL_IDD_1200X900;
406 viaparinfo->lvds_setting_info->device_lcd_dualedge = 0;
407 viaparinfo->lvds_setting_info->LCDDithering = 0;
408 break;
401 default: 409 default:
402 viaparinfo->lvds_setting_info->lcd_panel_hres = 800; 410 viaparinfo->lvds_setting_info->lcd_panel_hres = 800;
403 viaparinfo->lvds_setting_info->lcd_panel_vres = 600; 411 viaparinfo->lvds_setting_info->lcd_panel_vres = 600;
@@ -412,9 +420,8 @@ static int lvds_register_read(int index)
412{ 420{
413 u8 data; 421 u8 data;
414 422
415 viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; 423 viafb_i2c_readbyte(VIA_PORT_2C,
416 viafb_i2c_readbyte((u8) viaparinfo->chip_info-> 424 (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr,
417 lvds_chip_info.lvds_chip_slave_addr,
418 (u8) index, &data); 425 (u8) index, &data);
419 return data; 426 return data;
420} 427}
diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h
index 071f47cf5be1..9762ec62b495 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/via/lcd.h
@@ -60,6 +60,8 @@
60#define LCD_PANEL_IDB_1360X768 0x0B 60#define LCD_PANEL_IDB_1360X768 0x0B
61/* Resolution: 480x640, Channel: single, Dithering: Enable */ 61/* Resolution: 480x640, Channel: single, Dithering: Enable */
62#define LCD_PANEL_IDC_480X640 0x0C 62#define LCD_PANEL_IDC_480X640 0x0C
63/* Resolution: 1200x900, Channel: single, Dithering: Disable */
64#define LCD_PANEL_IDD_1200X900 0x0D
63 65
64 66
65extern int viafb_LCD2_ON; 67extern int viafb_LCD2_ON;
diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h
index d55aaa7b912c..7f0de7f006ad 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/via/share.h
@@ -43,16 +43,9 @@
43/* Video Memory Size */ 43/* Video Memory Size */
44#define VIDEO_MEMORY_SIZE_16M 0x1000000 44#define VIDEO_MEMORY_SIZE_16M 0x1000000
45 45
46/* standard VGA IO port 46/*
47*/ 47 * Lengths of the VPIT structure arrays.
48#define VIARMisc 0x3CC 48 */
49#define VIAWMisc 0x3C2
50#define VIAStatus 0x3DA
51#define VIACR 0x3D4
52#define VIASR 0x3C4
53#define VIAGR 0x3CE
54#define VIAAR 0x3C0
55
56#define StdCR 0x19 49#define StdCR 0x19
57#define StdSR 0x04 50#define StdSR 0x04
58#define StdGR 0x09 51#define StdGR 0x09
@@ -570,6 +563,10 @@
570#define M1200X720_R60_HSP NEGATIVE 563#define M1200X720_R60_HSP NEGATIVE
571#define M1200X720_R60_VSP POSITIVE 564#define M1200X720_R60_VSP POSITIVE
572 565
566/* 1200x900@60 Sync Polarity (DCON) */
567#define M1200X900_R60_HSP NEGATIVE
568#define M1200X900_R60_VSP NEGATIVE
569
573/* 1280x600@60 Sync Polarity (GTF Mode) */ 570/* 1280x600@60 Sync Polarity (GTF Mode) */
574#define M1280x600_R60_HSP NEGATIVE 571#define M1280x600_R60_HSP NEGATIVE
575#define M1280x600_R60_VSP POSITIVE 572#define M1280x600_R60_VSP POSITIVE
@@ -651,6 +648,7 @@
651#define CLK_52_406M 52406000 648#define CLK_52_406M 52406000
652#define CLK_52_977M 52977000 649#define CLK_52_977M 52977000
653#define CLK_56_250M 56250000 650#define CLK_56_250M 56250000
651#define CLK_57_275M 57275000
654#define CLK_60_466M 60466000 652#define CLK_60_466M 60466000
655#define CLK_61_500M 61500000 653#define CLK_61_500M 61500000
656#define CLK_65_000M 65000000 654#define CLK_65_000M 65000000
@@ -939,6 +937,7 @@
939#define VX855_52_406M 0x00580C03 937#define VX855_52_406M 0x00580C03
940#define VX855_52_977M 0x00940C05 938#define VX855_52_977M 0x00940C05
941#define VX855_56_250M 0x009D0C05 939#define VX855_56_250M 0x009D0C05
940#define VX855_57_275M 0x009D8C85 /* Used by XO panel */
942#define VX855_60_466M 0x00A90C05 941#define VX855_60_466M 0x00A90C05
943#define VX855_61_500M 0x00AC0C05 942#define VX855_61_500M 0x00AC0C05
944#define VX855_65_000M 0x006D0C03 943#define VX855_65_000M 0x006D0C03
@@ -1065,6 +1064,7 @@
1065#define RES_1600X1200_60HZ_PIXCLOCK 6172 1064#define RES_1600X1200_60HZ_PIXCLOCK 6172
1066#define RES_1600X1200_75HZ_PIXCLOCK 4938 1065#define RES_1600X1200_75HZ_PIXCLOCK 4938
1067#define RES_1280X720_60HZ_PIXCLOCK 13426 1066#define RES_1280X720_60HZ_PIXCLOCK 13426
1067#define RES_1200X900_60HZ_PIXCLOCK 17459
1068#define RES_1920X1080_60HZ_PIXCLOCK 5787 1068#define RES_1920X1080_60HZ_PIXCLOCK 5787
1069#define RES_1400X1050_60HZ_PIXCLOCK 8214 1069#define RES_1400X1050_60HZ_PIXCLOCK 8214
1070#define RES_1400X1050_75HZ_PIXCLOCK 6410 1070#define RES_1400X1050_75HZ_PIXCLOCK 6410
diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c
new file mode 100644
index 000000000000..e8cfe8392110
--- /dev/null
+++ b/drivers/video/via/via-core.c
@@ -0,0 +1,668 @@
1/*
2 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 * Copyright 2009 Jonathan Corbet <corbet@lwn.net>
5 */
6
7/*
8 * Core code for the Via multifunction framebuffer device.
9 */
10#include <linux/via-core.h>
11#include <linux/via_i2c.h>
12#include <linux/via-gpio.h>
13#include "global.h"
14
15#include <linux/module.h>
16#include <linux/interrupt.h>
17#include <linux/platform_device.h>
18
19/*
20 * The default port config.
21 */
22static struct via_port_cfg adap_configs[] = {
23 [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_OFF, VIASR, 0x26 },
24 [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 },
25 [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 },
26 [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_I2C, VIASR, 0x2c },
27 [VIA_PORT_3D] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x3d },
28 { 0, 0, 0, 0 }
29};
30
31/*
32 * We currently only support one viafb device (will there ever be
33 * more than one?), so just declare it globally here.
34 */
35static struct viafb_dev global_dev;
36
37
38/*
39 * Basic register access; spinlock required.
40 */
41static inline void viafb_mmio_write(int reg, u32 v)
42{
43 iowrite32(v, global_dev.engine_mmio + reg);
44}
45
46static inline int viafb_mmio_read(int reg)
47{
48 return ioread32(global_dev.engine_mmio + reg);
49}
50
51/* ---------------------------------------------------------------------- */
52/*
53 * Interrupt management. We have a single IRQ line for a lot of
54 * different functions, so we need to share it. The design here
55 * is that we don't want to reimplement the shared IRQ code here;
56 * we also want to avoid having contention for a single handler thread.
57 * So each subdev driver which needs interrupts just requests
58 * them directly from the kernel. We just have what's needed for
59 * overall access to the interrupt control register.
60 */
61
62/*
63 * Which interrupts are enabled now?
64 */
65static u32 viafb_enabled_ints;
66
67static void viafb_int_init(void)
68{
69 viafb_enabled_ints = 0;
70
71 viafb_mmio_write(VDE_INTERRUPT, 0);
72}
73
74/*
75 * Allow subdevs to ask for specific interrupts to be enabled. These
76 * functions must be called with reg_lock held
77 */
78void viafb_irq_enable(u32 mask)
79{
80 viafb_enabled_ints |= mask;
81 viafb_mmio_write(VDE_INTERRUPT, viafb_enabled_ints | VDE_I_ENABLE);
82}
83EXPORT_SYMBOL_GPL(viafb_irq_enable);
84
85void viafb_irq_disable(u32 mask)
86{
87 viafb_enabled_ints &= ~mask;
88 if (viafb_enabled_ints == 0)
89 viafb_mmio_write(VDE_INTERRUPT, 0); /* Disable entirely */
90 else
91 viafb_mmio_write(VDE_INTERRUPT,
92 viafb_enabled_ints | VDE_I_ENABLE);
93}
94EXPORT_SYMBOL_GPL(viafb_irq_disable);
95
96/* ---------------------------------------------------------------------- */
97/*
98 * Access to the DMA engine. This currently provides what the camera
99 * driver needs (i.e. outgoing only) but is easily expandable if need
100 * be.
101 */
102
103/*
104 * There are four DMA channels in the vx855. For now, we only
105 * use one of them, though. Most of the time, the DMA channel
106 * will be idle, so we keep the IRQ handler unregistered except
107 * when some subsystem has indicated an interest.
108 */
109static int viafb_dma_users;
110static DECLARE_COMPLETION(viafb_dma_completion);
111/*
112 * This mutex protects viafb_dma_users and our global interrupt
113 * registration state; it also serializes access to the DMA
114 * engine.
115 */
116static DEFINE_MUTEX(viafb_dma_lock);
117
118/*
119 * The VX855 DMA descriptor (used for s/g transfers) looks
120 * like this.
121 */
122struct viafb_vx855_dma_descr {
123 u32 addr_low; /* Low part of phys addr */
124 u32 addr_high; /* High 12 bits of addr */
125 u32 fb_offset; /* Offset into FB memory */
126 u32 seg_size; /* Size, 16-byte units */
127 u32 tile_mode; /* "tile mode" setting */
128 u32 next_desc_low; /* Next descriptor addr */
129 u32 next_desc_high;
130 u32 pad; /* Fill out to 64 bytes */
131};
132
133/*
134 * Flags added to the "next descriptor low" pointers
135 */
136#define VIAFB_DMA_MAGIC 0x01 /* ??? Just has to be there */
137#define VIAFB_DMA_FINAL_SEGMENT 0x02 /* Final segment */
138
139/*
140 * The completion IRQ handler.
141 */
142static irqreturn_t viafb_dma_irq(int irq, void *data)
143{
144 int csr;
145 irqreturn_t ret = IRQ_NONE;
146
147 spin_lock(&global_dev.reg_lock);
148 csr = viafb_mmio_read(VDMA_CSR0);
149 if (csr & VDMA_C_DONE) {
150 viafb_mmio_write(VDMA_CSR0, VDMA_C_DONE);
151 complete(&viafb_dma_completion);
152 ret = IRQ_HANDLED;
153 }
154 spin_unlock(&global_dev.reg_lock);
155 return ret;
156}
157
158/*
159 * Indicate a need for DMA functionality.
160 */
161int viafb_request_dma(void)
162{
163 int ret = 0;
164
165 /*
166 * Only VX855 is supported currently.
167 */
168 if (global_dev.chip_type != UNICHROME_VX855)
169 return -ENODEV;
170 /*
171 * Note the new user and set up our interrupt handler
172 * if need be.
173 */
174 mutex_lock(&viafb_dma_lock);
175 viafb_dma_users++;
176 if (viafb_dma_users == 1) {
177 ret = request_irq(global_dev.pdev->irq, viafb_dma_irq,
178 IRQF_SHARED, "via-dma", &viafb_dma_users);
179 if (ret)
180 viafb_dma_users--;
181 else
182 viafb_irq_enable(VDE_I_DMA0TDEN);
183 }
184 mutex_unlock(&viafb_dma_lock);
185 return ret;
186}
187EXPORT_SYMBOL_GPL(viafb_request_dma);
188
189void viafb_release_dma(void)
190{
191 mutex_lock(&viafb_dma_lock);
192 viafb_dma_users--;
193 if (viafb_dma_users == 0) {
194 viafb_irq_disable(VDE_I_DMA0TDEN);
195 free_irq(global_dev.pdev->irq, &viafb_dma_users);
196 }
197 mutex_unlock(&viafb_dma_lock);
198}
199EXPORT_SYMBOL_GPL(viafb_release_dma);
200
201
202#if 0
203/*
204 * Copy a single buffer from FB memory, synchronously. This code works
205 * but is not currently used.
206 */
207void viafb_dma_copy_out(unsigned int offset, dma_addr_t paddr, int len)
208{
209 unsigned long flags;
210 int csr;
211
212 mutex_lock(&viafb_dma_lock);
213 init_completion(&viafb_dma_completion);
214 /*
215 * Program the controller.
216 */
217 spin_lock_irqsave(&global_dev.reg_lock, flags);
218 viafb_mmio_write(VDMA_CSR0, VDMA_C_ENABLE|VDMA_C_DONE);
219 /* Enable ints; must happen after CSR0 write! */
220 viafb_mmio_write(VDMA_MR0, VDMA_MR_TDIE);
221 viafb_mmio_write(VDMA_MARL0, (int) (paddr & 0xfffffff0));
222 viafb_mmio_write(VDMA_MARH0, (int) ((paddr >> 28) & 0xfff));
223 /* Data sheet suggests DAR0 should be <<4, but it lies */
224 viafb_mmio_write(VDMA_DAR0, offset);
225 viafb_mmio_write(VDMA_DQWCR0, len >> 4);
226 viafb_mmio_write(VDMA_TMR0, 0);
227 viafb_mmio_write(VDMA_DPRL0, 0);
228 viafb_mmio_write(VDMA_DPRH0, 0);
229 viafb_mmio_write(VDMA_PMR0, 0);
230 csr = viafb_mmio_read(VDMA_CSR0);
231 viafb_mmio_write(VDMA_CSR0, VDMA_C_ENABLE|VDMA_C_START);
232 spin_unlock_irqrestore(&global_dev.reg_lock, flags);
233 /*
234 * Now we just wait until the interrupt handler says
235 * we're done.
236 */
237 wait_for_completion_interruptible(&viafb_dma_completion);
238 viafb_mmio_write(VDMA_MR0, 0); /* Reset int enable */
239 mutex_unlock(&viafb_dma_lock);
240}
241EXPORT_SYMBOL_GPL(viafb_dma_copy_out);
242#endif
243
244/*
245 * Do a scatter/gather DMA copy from FB memory. You must have done
246 * a successful call to viafb_request_dma() first.
247 */
248int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg)
249{
250 struct viafb_vx855_dma_descr *descr;
251 void *descrpages;
252 dma_addr_t descr_handle;
253 unsigned long flags;
254 int i;
255 struct scatterlist *sgentry;
256 dma_addr_t nextdesc;
257
258 /*
259 * Get a place to put the descriptors.
260 */
261 descrpages = dma_alloc_coherent(&global_dev.pdev->dev,
262 nsg*sizeof(struct viafb_vx855_dma_descr),
263 &descr_handle, GFP_KERNEL);
264 if (descrpages == NULL) {
265 dev_err(&global_dev.pdev->dev, "Unable to get descr page.\n");
266 return -ENOMEM;
267 }
268 mutex_lock(&viafb_dma_lock);
269 /*
270 * Fill them in.
271 */
272 descr = descrpages;
273 nextdesc = descr_handle + sizeof(struct viafb_vx855_dma_descr);
274 for_each_sg(sg, sgentry, nsg, i) {
275 dma_addr_t paddr = sg_dma_address(sgentry);
276 descr->addr_low = paddr & 0xfffffff0;
277 descr->addr_high = ((u64) paddr >> 32) & 0x0fff;
278 descr->fb_offset = offset;
279 descr->seg_size = sg_dma_len(sgentry) >> 4;
280 descr->tile_mode = 0;
281 descr->next_desc_low = (nextdesc&0xfffffff0) | VIAFB_DMA_MAGIC;
282 descr->next_desc_high = ((u64) nextdesc >> 32) & 0x0fff;
283 descr->pad = 0xffffffff; /* VIA driver does this */
284 offset += sg_dma_len(sgentry);
285 nextdesc += sizeof(struct viafb_vx855_dma_descr);
286 descr++;
287 }
288 descr[-1].next_desc_low = VIAFB_DMA_FINAL_SEGMENT|VIAFB_DMA_MAGIC;
289 /*
290 * Program the engine.
291 */
292 spin_lock_irqsave(&global_dev.reg_lock, flags);
293 init_completion(&viafb_dma_completion);
294 viafb_mmio_write(VDMA_DQWCR0, 0);
295 viafb_mmio_write(VDMA_CSR0, VDMA_C_ENABLE|VDMA_C_DONE);
296 viafb_mmio_write(VDMA_MR0, VDMA_MR_TDIE | VDMA_MR_CHAIN);
297 viafb_mmio_write(VDMA_DPRL0, descr_handle | VIAFB_DMA_MAGIC);
298 viafb_mmio_write(VDMA_DPRH0,
299 (((u64)descr_handle >> 32) & 0x0fff) | 0xf0000);
300 (void) viafb_mmio_read(VDMA_CSR0);
301 viafb_mmio_write(VDMA_CSR0, VDMA_C_ENABLE|VDMA_C_START);
302 spin_unlock_irqrestore(&global_dev.reg_lock, flags);
303 /*
304 * Now we just wait until the interrupt handler says
305 * we're done. Except that, actually, we need to wait a little
306 * longer: the interrupts seem to jump the gun a little and we
307 * get corrupted frames sometimes.
308 */
309 wait_for_completion_timeout(&viafb_dma_completion, 1);
310 msleep(1);
311 if ((viafb_mmio_read(VDMA_CSR0)&VDMA_C_DONE) == 0)
312 printk(KERN_ERR "VIA DMA timeout!\n");
313 /*
314 * Clean up and we're done.
315 */
316 viafb_mmio_write(VDMA_CSR0, VDMA_C_DONE);
317 viafb_mmio_write(VDMA_MR0, 0); /* Reset int enable */
318 mutex_unlock(&viafb_dma_lock);
319 dma_free_coherent(&global_dev.pdev->dev,
320 nsg*sizeof(struct viafb_vx855_dma_descr), descrpages,
321 descr_handle);
322 return 0;
323}
324EXPORT_SYMBOL_GPL(viafb_dma_copy_out_sg);
325
326
327/* ---------------------------------------------------------------------- */
328/*
329 * Figure out how big our framebuffer memory is. Kind of ugly,
330 * but evidently we can't trust the information found in the
331 * fbdev configuration area.
332 */
333static u16 via_function3[] = {
334 CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3,
335 CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3,
336 P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3,
337};
338
339/* Get the BIOS-configured framebuffer size from PCI configuration space
340 * of function 3 in the respective chipset */
341static int viafb_get_fb_size_from_pci(int chip_type)
342{
343 int i;
344 u8 offset = 0;
345 u32 FBSize;
346 u32 VideoMemSize;
347
348 /* search for the "FUNCTION3" device in this chipset */
349 for (i = 0; i < ARRAY_SIZE(via_function3); i++) {
350 struct pci_dev *pdev;
351
352 pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i],
353 NULL);
354 if (!pdev)
355 continue;
356
357 DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device);
358
359 switch (pdev->device) {
360 case CLE266_FUNCTION3:
361 case KM400_FUNCTION3:
362 offset = 0xE0;
363 break;
364 case CN400_FUNCTION3:
365 case CN700_FUNCTION3:
366 case CX700_FUNCTION3:
367 case KM800_FUNCTION3:
368 case KM890_FUNCTION3:
369 case P4M890_FUNCTION3:
370 case P4M900_FUNCTION3:
371 case VX800_FUNCTION3:
372 case VX855_FUNCTION3:
373 /*case CN750_FUNCTION3: */
374 offset = 0xA0;
375 break;
376 }
377
378 if (!offset)
379 break;
380
381 pci_read_config_dword(pdev, offset, &FBSize);
382 pci_dev_put(pdev);
383 }
384
385 if (!offset) {
386 printk(KERN_ERR "cannot determine framebuffer size\n");
387 return -EIO;
388 }
389
390 FBSize = FBSize & 0x00007000;
391 DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize);
392
393 if (chip_type < UNICHROME_CX700) {
394 switch (FBSize) {
395 case 0x00004000:
396 VideoMemSize = (16 << 20); /*16M */
397 break;
398
399 case 0x00005000:
400 VideoMemSize = (32 << 20); /*32M */
401 break;
402
403 case 0x00006000:
404 VideoMemSize = (64 << 20); /*64M */
405 break;
406
407 default:
408 VideoMemSize = (32 << 20); /*32M */
409 break;
410 }
411 } else {
412 switch (FBSize) {
413 case 0x00001000:
414 VideoMemSize = (8 << 20); /*8M */
415 break;
416
417 case 0x00002000:
418 VideoMemSize = (16 << 20); /*16M */
419 break;
420
421 case 0x00003000:
422 VideoMemSize = (32 << 20); /*32M */
423 break;
424
425 case 0x00004000:
426 VideoMemSize = (64 << 20); /*64M */
427 break;
428
429 case 0x00005000:
430 VideoMemSize = (128 << 20); /*128M */
431 break;
432
433 case 0x00006000:
434 VideoMemSize = (256 << 20); /*256M */
435 break;
436
437 case 0x00007000: /* Only on VX855/875 */
438 VideoMemSize = (512 << 20); /*512M */
439 break;
440
441 default:
442 VideoMemSize = (32 << 20); /*32M */
443 break;
444 }
445 }
446
447 return VideoMemSize;
448}
449
450
451/*
452 * Figure out and map our MMIO regions.
453 */
454static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)
455{
456 int ret;
457 /*
458 * Hook up to the device registers. Note that we soldier
459 * on if it fails; the framebuffer can operate (without
460 * acceleration) without this region.
461 */
462 vdev->engine_start = pci_resource_start(vdev->pdev, 1);
463 vdev->engine_len = pci_resource_len(vdev->pdev, 1);
464 vdev->engine_mmio = ioremap_nocache(vdev->engine_start,
465 vdev->engine_len);
466 if (vdev->engine_mmio == NULL)
467 dev_err(&vdev->pdev->dev,
468 "Unable to map engine MMIO; operation will be "
469 "slow and crippled.\n");
470 /*
471 * Map in framebuffer memory. For now, failure here is
472 * fatal. Unfortunately, in the absence of significant
473 * vmalloc space, failure here is also entirely plausible.
474 * Eventually we want to move away from mapping this
475 * entire region.
476 */
477 vdev->fbmem_start = pci_resource_start(vdev->pdev, 0);
478 ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type);
479 if (ret < 0)
480 goto out_unmap;
481 vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len);
482 if (vdev->fbmem == NULL) {
483 ret = -ENOMEM;
484 goto out_unmap;
485 }
486 return 0;
487out_unmap:
488 iounmap(vdev->engine_mmio);
489 return ret;
490}
491
492static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev)
493{
494 iounmap(vdev->fbmem);
495 iounmap(vdev->engine_mmio);
496}
497
498/*
499 * Create our subsidiary devices.
500 */
501static struct viafb_subdev_info {
502 char *name;
503 struct platform_device *platdev;
504} viafb_subdevs[] = {
505 {
506 .name = "viafb-gpio",
507 },
508 {
509 .name = "viafb-i2c",
510 }
511};
512#define N_SUBDEVS ARRAY_SIZE(viafb_subdevs)
513
514static int __devinit via_create_subdev(struct viafb_dev *vdev,
515 struct viafb_subdev_info *info)
516{
517 int ret;
518
519 info->platdev = platform_device_alloc(info->name, -1);
520 if (!info->platdev) {
521 dev_err(&vdev->pdev->dev, "Unable to allocate pdev %s\n",
522 info->name);
523 return -ENOMEM;
524 }
525 info->platdev->dev.parent = &vdev->pdev->dev;
526 info->platdev->dev.platform_data = vdev;
527 ret = platform_device_add(info->platdev);
528 if (ret) {
529 dev_err(&vdev->pdev->dev, "Unable to add pdev %s\n",
530 info->name);
531 platform_device_put(info->platdev);
532 info->platdev = NULL;
533 }
534 return ret;
535}
536
537static int __devinit via_setup_subdevs(struct viafb_dev *vdev)
538{
539 int i;
540
541 /*
542 * Ignore return values. Even if some of the devices
543 * fail to be created, we'll still be able to use some
544 * of the rest.
545 */
546 for (i = 0; i < N_SUBDEVS; i++)
547 via_create_subdev(vdev, viafb_subdevs + i);
548 return 0;
549}
550
551static void __devexit via_teardown_subdevs(void)
552{
553 int i;
554
555 for (i = 0; i < N_SUBDEVS; i++)
556 if (viafb_subdevs[i].platdev) {
557 viafb_subdevs[i].platdev->dev.platform_data = NULL;
558 platform_device_unregister(viafb_subdevs[i].platdev);
559 }
560}
561
562
563static int __devinit via_pci_probe(struct pci_dev *pdev,
564 const struct pci_device_id *ent)
565{
566 int ret;
567
568 ret = pci_enable_device(pdev);
569 if (ret)
570 return ret;
571 /*
572 * Global device initialization.
573 */
574 memset(&global_dev, 0, sizeof(global_dev));
575 global_dev.pdev = pdev;
576 global_dev.chip_type = ent->driver_data;
577 global_dev.port_cfg = adap_configs;
578 spin_lock_init(&global_dev.reg_lock);
579 ret = via_pci_setup_mmio(&global_dev);
580 if (ret)
581 goto out_disable;
582 /*
583 * Set up interrupts and create our subdevices. Continue even if
584 * some things fail.
585 */
586 viafb_int_init();
587 via_setup_subdevs(&global_dev);
588 /*
589 * Set up the framebuffer device
590 */
591 ret = via_fb_pci_probe(&global_dev);
592 if (ret)
593 goto out_subdevs;
594 return 0;
595
596out_subdevs:
597 via_teardown_subdevs();
598 via_pci_teardown_mmio(&global_dev);
599out_disable:
600 pci_disable_device(pdev);
601 return ret;
602}
603
604static void __devexit via_pci_remove(struct pci_dev *pdev)
605{
606 via_teardown_subdevs();
607 via_fb_pci_remove(pdev);
608 via_pci_teardown_mmio(&global_dev);
609 pci_disable_device(pdev);
610}
611
612
613static struct pci_device_id via_pci_table[] __devinitdata = {
614 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID),
615 .driver_data = UNICHROME_CLE266 },
616 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID),
617 .driver_data = UNICHROME_PM800 },
618 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
619 .driver_data = UNICHROME_K400 },
620 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
621 .driver_data = UNICHROME_K800 },
622 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
623 .driver_data = UNICHROME_CN700 },
624 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
625 .driver_data = UNICHROME_K8M890 },
626 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
627 .driver_data = UNICHROME_CX700 },
628 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
629 .driver_data = UNICHROME_P4M900 },
630 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
631 .driver_data = UNICHROME_CN750 },
632 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
633 .driver_data = UNICHROME_VX800 },
634 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
635 .driver_data = UNICHROME_VX855 },
636 { }
637};
638MODULE_DEVICE_TABLE(pci, via_pci_table);
639
640static struct pci_driver via_driver = {
641 .name = "viafb",
642 .id_table = via_pci_table,
643 .probe = via_pci_probe,
644 .remove = __devexit_p(via_pci_remove),
645};
646
647static int __init via_core_init(void)
648{
649 int ret;
650
651 ret = viafb_init();
652 if (ret)
653 return ret;
654 viafb_i2c_init();
655 viafb_gpio_init();
656 return pci_register_driver(&via_driver);
657}
658
659static void __exit via_core_exit(void)
660{
661 pci_unregister_driver(&via_driver);
662 viafb_gpio_exit();
663 viafb_i2c_exit();
664 viafb_exit();
665}
666
667module_init(via_core_init);
668module_exit(via_core_exit);
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/via/via-gpio.c
new file mode 100644
index 000000000000..595516aea691
--- /dev/null
+++ b/drivers/video/via/via-gpio.c
@@ -0,0 +1,285 @@
1/*
2 * Support for viafb GPIO ports.
3 *
4 * Copyright 2009 Jonathan Corbet <corbet@lwn.net>
5 * Distributable under version 2 of the GNU General Public License.
6 */
7
8#include <linux/spinlock.h>
9#include <linux/gpio.h>
10#include <linux/platform_device.h>
11#include <linux/via-core.h>
12#include <linux/via-gpio.h>
13
14/*
15 * The ports we know about. Note that the port-25 gpios are not
16 * mentioned in the datasheet.
17 */
18
19struct viafb_gpio {
20 char *vg_name; /* Data sheet name */
21 u16 vg_io_port;
22 u8 vg_port_index;
23 int vg_mask_shift;
24};
25
26static struct viafb_gpio viafb_all_gpios[] = {
27 {
28 .vg_name = "VGPIO0", /* Guess - not in datasheet */
29 .vg_io_port = VIASR,
30 .vg_port_index = 0x25,
31 .vg_mask_shift = 1
32 },
33 {
34 .vg_name = "VGPIO1",
35 .vg_io_port = VIASR,
36 .vg_port_index = 0x25,
37 .vg_mask_shift = 0
38 },
39 {
40 .vg_name = "VGPIO2", /* aka DISPCLKI0 */
41 .vg_io_port = VIASR,
42 .vg_port_index = 0x2c,
43 .vg_mask_shift = 1
44 },
45 {
46 .vg_name = "VGPIO3", /* aka DISPCLKO0 */
47 .vg_io_port = VIASR,
48 .vg_port_index = 0x2c,
49 .vg_mask_shift = 0
50 },
51 {
52 .vg_name = "VGPIO4", /* DISPCLKI1 */
53 .vg_io_port = VIASR,
54 .vg_port_index = 0x3d,
55 .vg_mask_shift = 1
56 },
57 {
58 .vg_name = "VGPIO5", /* DISPCLKO1 */
59 .vg_io_port = VIASR,
60 .vg_port_index = 0x3d,
61 .vg_mask_shift = 0
62 },
63};
64
65#define VIAFB_NUM_GPIOS ARRAY_SIZE(viafb_all_gpios)
66
67/*
68 * This structure controls the active GPIOs, which may be a subset
69 * of those which are known.
70 */
71
72struct viafb_gpio_cfg {
73 struct gpio_chip gpio_chip;
74 struct viafb_dev *vdev;
75 struct viafb_gpio *active_gpios[VIAFB_NUM_GPIOS];
76 char *gpio_names[VIAFB_NUM_GPIOS];
77};
78
79/*
80 * GPIO access functions
81 */
82static void via_gpio_set(struct gpio_chip *chip, unsigned int nr,
83 int value)
84{
85 struct viafb_gpio_cfg *cfg = container_of(chip,
86 struct viafb_gpio_cfg,
87 gpio_chip);
88 u8 reg;
89 struct viafb_gpio *gpio;
90 unsigned long flags;
91
92 spin_lock_irqsave(&cfg->vdev->reg_lock, flags);
93 gpio = cfg->active_gpios[nr];
94 reg = via_read_reg(VIASR, gpio->vg_port_index);
95 reg |= 0x40 << gpio->vg_mask_shift; /* output enable */
96 if (value)
97 reg |= 0x10 << gpio->vg_mask_shift;
98 else
99 reg &= ~(0x10 << gpio->vg_mask_shift);
100 via_write_reg(VIASR, gpio->vg_port_index, reg);
101 spin_unlock_irqrestore(&cfg->vdev->reg_lock, flags);
102}
103
104static int via_gpio_dir_out(struct gpio_chip *chip, unsigned int nr,
105 int value)
106{
107 via_gpio_set(chip, nr, value);
108 return 0;
109}
110
111/*
112 * Set the input direction. I'm not sure this is right; we should
113 * be able to do input without disabling output.
114 */
115static int via_gpio_dir_input(struct gpio_chip *chip, unsigned int nr)
116{
117 struct viafb_gpio_cfg *cfg = container_of(chip,
118 struct viafb_gpio_cfg,
119 gpio_chip);
120 struct viafb_gpio *gpio;
121 unsigned long flags;
122
123 spin_lock_irqsave(&cfg->vdev->reg_lock, flags);
124 gpio = cfg->active_gpios[nr];
125 via_write_reg_mask(VIASR, gpio->vg_port_index, 0,
126 0x40 << gpio->vg_mask_shift);
127 spin_unlock_irqrestore(&cfg->vdev->reg_lock, flags);
128 return 0;
129}
130
131static int via_gpio_get(struct gpio_chip *chip, unsigned int nr)
132{
133 struct viafb_gpio_cfg *cfg = container_of(chip,
134 struct viafb_gpio_cfg,
135 gpio_chip);
136 u8 reg;
137 struct viafb_gpio *gpio;
138 unsigned long flags;
139
140 spin_lock_irqsave(&cfg->vdev->reg_lock, flags);
141 gpio = cfg->active_gpios[nr];
142 reg = via_read_reg(VIASR, gpio->vg_port_index);
143 spin_unlock_irqrestore(&cfg->vdev->reg_lock, flags);
144 return reg & (0x04 << gpio->vg_mask_shift);
145}
146
147
148static struct viafb_gpio_cfg gpio_config = {
149 .gpio_chip = {
150 .label = "VIAFB onboard GPIO",
151 .owner = THIS_MODULE,
152 .direction_output = via_gpio_dir_out,
153 .set = via_gpio_set,
154 .direction_input = via_gpio_dir_input,
155 .get = via_gpio_get,
156 .base = -1,
157 .ngpio = 0,
158 .can_sleep = 0
159 }
160};
161
162/*
163 * Manage the software enable bit.
164 */
165static void viafb_gpio_enable(struct viafb_gpio *gpio)
166{
167 via_write_reg_mask(VIASR, gpio->vg_port_index, 0x02, 0x02);
168}
169
170static void viafb_gpio_disable(struct viafb_gpio *gpio)
171{
172 via_write_reg_mask(VIASR, gpio->vg_port_index, 0, 0x02);
173}
174
175/*
176 * Look up a specific gpio and return the number it was assigned.
177 */
178int viafb_gpio_lookup(const char *name)
179{
180 int i;
181
182 for (i = 0; i < gpio_config.gpio_chip.ngpio; i++)
183 if (!strcmp(name, gpio_config.active_gpios[i]->vg_name))
184 return gpio_config.gpio_chip.base + i;
185 return -1;
186}
187EXPORT_SYMBOL_GPL(viafb_gpio_lookup);
188
189/*
190 * Platform device stuff.
191 */
192static __devinit int viafb_gpio_probe(struct platform_device *platdev)
193{
194 struct viafb_dev *vdev = platdev->dev.platform_data;
195 struct via_port_cfg *port_cfg = vdev->port_cfg;
196 int i, ngpio = 0, ret;
197 struct viafb_gpio *gpio;
198 unsigned long flags;
199
200 /*
201 * Set up entries for all GPIOs which have been configured to
202 * operate as such (as opposed to as i2c ports).
203 */
204 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
205 if (port_cfg[i].mode != VIA_MODE_GPIO)
206 continue;
207 for (gpio = viafb_all_gpios;
208 gpio < viafb_all_gpios + VIAFB_NUM_GPIOS; gpio++)
209 if (gpio->vg_port_index == port_cfg[i].ioport_index) {
210 gpio_config.active_gpios[ngpio] = gpio;
211 gpio_config.gpio_names[ngpio] = gpio->vg_name;
212 ngpio++;
213 }
214 }
215 gpio_config.gpio_chip.ngpio = ngpio;
216 gpio_config.gpio_chip.names = gpio_config.gpio_names;
217 gpio_config.vdev = vdev;
218 if (ngpio == 0) {
219 printk(KERN_INFO "viafb: no GPIOs configured\n");
220 return 0;
221 }
222 /*
223 * Enable the ports. They come in pairs, with a single
224 * enable bit for both.
225 */
226 spin_lock_irqsave(&gpio_config.vdev->reg_lock, flags);
227 for (i = 0; i < ngpio; i += 2)
228 viafb_gpio_enable(gpio_config.active_gpios[i]);
229 spin_unlock_irqrestore(&gpio_config.vdev->reg_lock, flags);
230 /*
231 * Get registered.
232 */
233 gpio_config.gpio_chip.base = -1; /* Dynamic */
234 ret = gpiochip_add(&gpio_config.gpio_chip);
235 if (ret) {
236 printk(KERN_ERR "viafb: failed to add gpios (%d)\n", ret);
237 gpio_config.gpio_chip.ngpio = 0;
238 }
239 return ret;
240}
241
242
243static int viafb_gpio_remove(struct platform_device *platdev)
244{
245 unsigned long flags;
246 int ret = 0, i;
247
248 /*
249 * Get unregistered.
250 */
251 if (gpio_config.gpio_chip.ngpio > 0) {
252 ret = gpiochip_remove(&gpio_config.gpio_chip);
253 if (ret) { /* Somebody still using it? */
254 printk(KERN_ERR "Viafb: GPIO remove failed\n");
255 return ret;
256 }
257 }
258 /*
259 * Disable the ports.
260 */
261 spin_lock_irqsave(&gpio_config.vdev->reg_lock, flags);
262 for (i = 0; i < gpio_config.gpio_chip.ngpio; i += 2)
263 viafb_gpio_disable(gpio_config.active_gpios[i]);
264 gpio_config.gpio_chip.ngpio = 0;
265 spin_unlock_irqrestore(&gpio_config.vdev->reg_lock, flags);
266 return ret;
267}
268
269static struct platform_driver via_gpio_driver = {
270 .driver = {
271 .name = "viafb-gpio",
272 },
273 .probe = viafb_gpio_probe,
274 .remove = viafb_gpio_remove,
275};
276
277int viafb_gpio_init(void)
278{
279 return platform_driver_register(&via_gpio_driver);
280}
281
282void viafb_gpio_exit(void)
283{
284 platform_driver_unregister(&via_gpio_driver);
285}
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c
index 15543e968248..da9e4ca94b17 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/via/via_i2c.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 2 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 4
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -19,77 +19,106 @@
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22#include "global.h" 22#include <linux/platform_device.h>
23#include <linux/delay.h>
24#include <linux/spinlock.h>
25#include <linux/module.h>
26#include <linux/via-core.h>
27#include <linux/via_i2c.h>
28
29/*
30 * There can only be one set of these, so there's no point in having
31 * them be dynamically allocated...
32 */
33#define VIAFB_NUM_I2C 5
34static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C];
35struct viafb_dev *i2c_vdev; /* Passed in from core */
23 36
24static void via_i2c_setscl(void *data, int state) 37static void via_i2c_setscl(void *data, int state)
25{ 38{
26 u8 val; 39 u8 val;
27 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 40 struct via_port_cfg *adap_data = data;
41 unsigned long flags;
28 42
29 val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; 43 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
44 val = via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0xF0;
30 if (state) 45 if (state)
31 val |= 0x20; 46 val |= 0x20;
32 else 47 else
33 val &= ~0x20; 48 val &= ~0x20;
34 switch (via_i2c_chan->i2c_port) { 49 switch (adap_data->type) {
35 case I2CPORTINDEX: 50 case VIA_PORT_I2C:
36 val |= 0x01; 51 val |= 0x01;
37 break; 52 break;
38 case GPIOPORTINDEX: 53 case VIA_PORT_GPIO:
39 val |= 0x80; 54 val |= 0x80;
40 break; 55 break;
41 default: 56 default:
42 DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); 57 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
43 } 58 }
44 viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); 59 via_write_reg(adap_data->io_port, adap_data->ioport_index, val);
60 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
45} 61}
46 62
47static int via_i2c_getscl(void *data) 63static int via_i2c_getscl(void *data)
48{ 64{
49 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 65 struct via_port_cfg *adap_data = data;
66 unsigned long flags;
67 int ret = 0;
50 68
51 if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08) 69 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
52 return 1; 70 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08)
53 return 0; 71 ret = 1;
72 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
73 return ret;
54} 74}
55 75
56static int via_i2c_getsda(void *data) 76static int via_i2c_getsda(void *data)
57{ 77{
58 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 78 struct via_port_cfg *adap_data = data;
79 unsigned long flags;
80 int ret = 0;
59 81
60 if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04) 82 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
61 return 1; 83 if (via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04)
62 return 0; 84 ret = 1;
85 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
86 return ret;
63} 87}
64 88
65static void via_i2c_setsda(void *data, int state) 89static void via_i2c_setsda(void *data, int state)
66{ 90{
67 u8 val; 91 u8 val;
68 struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; 92 struct via_port_cfg *adap_data = data;
93 unsigned long flags;
69 94
70 val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; 95 spin_lock_irqsave(&i2c_vdev->reg_lock, flags);
96 val = via_read_reg(adap_data->io_port, adap_data->ioport_index) & 0xF0;
71 if (state) 97 if (state)
72 val |= 0x10; 98 val |= 0x10;
73 else 99 else
74 val &= ~0x10; 100 val &= ~0x10;
75 switch (via_i2c_chan->i2c_port) { 101 switch (adap_data->type) {
76 case I2CPORTINDEX: 102 case VIA_PORT_I2C:
77 val |= 0x01; 103 val |= 0x01;
78 break; 104 break;
79 case GPIOPORTINDEX: 105 case VIA_PORT_GPIO:
80 val |= 0x40; 106 val |= 0x40;
81 break; 107 break;
82 default: 108 default:
83 DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); 109 printk(KERN_ERR "viafb_i2c: specify wrong i2c type.\n");
84 } 110 }
85 viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); 111 via_write_reg(adap_data->io_port, adap_data->ioport_index, val);
112 spin_unlock_irqrestore(&i2c_vdev->reg_lock, flags);
86} 113}
87 114
88int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) 115int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata)
89{ 116{
90 u8 mm1[] = {0x00}; 117 u8 mm1[] = {0x00};
91 struct i2c_msg msgs[2]; 118 struct i2c_msg msgs[2];
92 119
120 if (!via_i2c_par[adap].is_active)
121 return -ENODEV;
93 *pdata = 0; 122 *pdata = 0;
94 msgs[0].flags = 0; 123 msgs[0].flags = 0;
95 msgs[1].flags = I2C_M_RD; 124 msgs[1].flags = I2C_M_RD;
@@ -97,81 +126,144 @@ int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata)
97 mm1[0] = index; 126 mm1[0] = index;
98 msgs[0].len = 1; msgs[1].len = 1; 127 msgs[0].len = 1; msgs[1].len = 1;
99 msgs[0].buf = mm1; msgs[1].buf = pdata; 128 msgs[0].buf = mm1; msgs[1].buf = pdata;
100 i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); 129 return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
101
102 return 0;
103} 130}
104 131
105int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) 132int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data)
106{ 133{
107 u8 msg[2] = { index, data }; 134 u8 msg[2] = { index, data };
108 struct i2c_msg msgs; 135 struct i2c_msg msgs;
109 136
137 if (!via_i2c_par[adap].is_active)
138 return -ENODEV;
110 msgs.flags = 0; 139 msgs.flags = 0;
111 msgs.addr = slave_addr / 2; 140 msgs.addr = slave_addr / 2;
112 msgs.len = 2; 141 msgs.len = 2;
113 msgs.buf = msg; 142 msgs.buf = msg;
114 return i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, &msgs, 1); 143 return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1);
115} 144}
116 145
117int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) 146int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len)
118{ 147{
119 u8 mm1[] = {0x00}; 148 u8 mm1[] = {0x00};
120 struct i2c_msg msgs[2]; 149 struct i2c_msg msgs[2];
121 150
151 if (!via_i2c_par[adap].is_active)
152 return -ENODEV;
122 msgs[0].flags = 0; 153 msgs[0].flags = 0;
123 msgs[1].flags = I2C_M_RD; 154 msgs[1].flags = I2C_M_RD;
124 msgs[0].addr = msgs[1].addr = slave_addr / 2; 155 msgs[0].addr = msgs[1].addr = slave_addr / 2;
125 mm1[0] = index; 156 mm1[0] = index;
126 msgs[0].len = 1; msgs[1].len = buff_len; 157 msgs[0].len = 1; msgs[1].len = buff_len;
127 msgs[0].buf = mm1; msgs[1].buf = buff; 158 msgs[0].buf = mm1; msgs[1].buf = buff;
128 i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); 159 return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2);
129 return 0;
130} 160}
131 161
132int viafb_create_i2c_bus(void *viapar) 162/*
163 * Allow other viafb subdevices to look up a specific adapter
164 * by port name.
165 */
166struct i2c_adapter *viafb_find_i2c_adapter(enum viafb_i2c_adap which)
133{ 167{
134 int ret; 168 struct via_i2c_stuff *stuff = &via_i2c_par[which];
135 struct via_i2c_stuff *i2c_stuff =
136 &((struct viafb_par *)viapar)->shared->i2c_stuff;
137
138 strcpy(i2c_stuff->adapter.name, "via_i2c");
139 i2c_stuff->i2c_port = 0x0;
140 i2c_stuff->adapter.owner = THIS_MODULE;
141 i2c_stuff->adapter.id = 0x01FFFF;
142 i2c_stuff->adapter.class = 0;
143 i2c_stuff->adapter.algo_data = &i2c_stuff->algo;
144 i2c_stuff->adapter.dev.parent = NULL;
145 i2c_stuff->algo.setsda = via_i2c_setsda;
146 i2c_stuff->algo.setscl = via_i2c_setscl;
147 i2c_stuff->algo.getsda = via_i2c_getsda;
148 i2c_stuff->algo.getscl = via_i2c_getscl;
149 i2c_stuff->algo.udelay = 40;
150 i2c_stuff->algo.timeout = 20;
151 i2c_stuff->algo.data = i2c_stuff;
152
153 i2c_set_adapdata(&i2c_stuff->adapter, i2c_stuff);
154 169
155 /* Raise SCL and SDA */ 170 return &stuff->adapter;
156 i2c_stuff->i2c_port = I2CPORTINDEX; 171}
157 via_i2c_setsda(i2c_stuff, 1); 172EXPORT_SYMBOL_GPL(viafb_find_i2c_adapter);
158 via_i2c_setscl(i2c_stuff, 1);
159 173
160 i2c_stuff->i2c_port = GPIOPORTINDEX;
161 via_i2c_setsda(i2c_stuff, 1);
162 via_i2c_setscl(i2c_stuff, 1);
163 udelay(20);
164 174
165 ret = i2c_bit_add_bus(&i2c_stuff->adapter); 175static int create_i2c_bus(struct i2c_adapter *adapter,
166 if (ret == 0) 176 struct i2c_algo_bit_data *algo,
167 DEBUG_MSG("I2C bus %s registered.\n", i2c_stuff->adapter.name); 177 struct via_port_cfg *adap_cfg,
178 struct pci_dev *pdev)
179{
180 algo->setsda = via_i2c_setsda;
181 algo->setscl = via_i2c_setscl;
182 algo->getsda = via_i2c_getsda;
183 algo->getscl = via_i2c_getscl;
184 algo->udelay = 40;
185 algo->timeout = 20;
186 algo->data = adap_cfg;
187
188 sprintf(adapter->name, "viafb i2c io_port idx 0x%02x",
189 adap_cfg->ioport_index);
190 adapter->owner = THIS_MODULE;
191 adapter->id = 0x01FFFF;
192 adapter->class = I2C_CLASS_DDC;
193 adapter->algo_data = algo;
194 if (pdev)
195 adapter->dev.parent = &pdev->dev;
168 else 196 else
169 DEBUG_MSG("Failed to register I2C bus %s.\n", 197 adapter->dev.parent = NULL;
170 i2c_stuff->adapter.name); 198 /* i2c_set_adapdata(adapter, adap_cfg); */
171 return ret; 199
200 /* Raise SCL and SDA */
201 via_i2c_setsda(adap_cfg, 1);
202 via_i2c_setscl(adap_cfg, 1);
203 udelay(20);
204
205 return i2c_bit_add_bus(adapter);
206}
207
208static int viafb_i2c_probe(struct platform_device *platdev)
209{
210 int i, ret;
211 struct via_port_cfg *configs;
212
213 i2c_vdev = platdev->dev.platform_data;
214 configs = i2c_vdev->port_cfg;
215
216 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
217 struct via_port_cfg *adap_cfg = configs++;
218 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
219
220 i2c_stuff->is_active = 0;
221 if (adap_cfg->type == 0 || adap_cfg->mode != VIA_MODE_I2C)
222 continue;
223 ret = create_i2c_bus(&i2c_stuff->adapter,
224 &i2c_stuff->algo, adap_cfg,
225 NULL); /* FIXME: PCIDEV */
226 if (ret < 0) {
227 printk(KERN_ERR "viafb: cannot create i2c bus %u:%d\n",
228 i, ret);
229 continue; /* Still try to make the rest */
230 }
231 i2c_stuff->is_active = 1;
232 }
233
234 return 0;
235}
236
237static int viafb_i2c_remove(struct platform_device *platdev)
238{
239 int i;
240
241 for (i = 0; i < VIAFB_NUM_PORTS; i++) {
242 struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i];
243 /*
244 * Only remove those entries in the array that we've
245 * actually used (and thus initialized algo_data)
246 */
247 if (i2c_stuff->is_active)
248 i2c_del_adapter(&i2c_stuff->adapter);
249 }
250 return 0;
251}
252
253static struct platform_driver via_i2c_driver = {
254 .driver = {
255 .name = "viafb-i2c",
256 },
257 .probe = viafb_i2c_probe,
258 .remove = viafb_i2c_remove,
259};
260
261int viafb_i2c_init(void)
262{
263 return platform_driver_register(&via_i2c_driver);
172} 264}
173 265
174void viafb_delete_i2c_buss(void *par) 266void viafb_i2c_exit(void)
175{ 267{
176 i2c_del_adapter(&((struct viafb_par *)par)->shared->i2c_stuff.adapter); 268 platform_driver_unregister(&via_i2c_driver);
177} 269}
diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/via/via_modesetting.c
new file mode 100644
index 000000000000..3cddcff88ab9
--- /dev/null
+++ b/drivers/video/via/via_modesetting.c
@@ -0,0 +1,126 @@
1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 * Copyright 2010 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public
8 * License as published by the Free Software Foundation;
9 * either version 2, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
13 * the implied warranty of MERCHANTABILITY or FITNESS FOR
14 * A PARTICULAR PURPOSE.See the GNU General Public License
15 * for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc.,
20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 */
22/*
23 * basic modesetting functions
24 */
25
26#include <linux/kernel.h>
27#include <linux/via-core.h>
28#include "via_modesetting.h"
29#include "share.h"
30#include "debug.h"
31
32void via_set_primary_address(u32 addr)
33{
34 DEBUG_MSG(KERN_DEBUG "via_set_primary_address(0x%08X)\n", addr);
35 via_write_reg(VIACR, 0x0D, addr & 0xFF);
36 via_write_reg(VIACR, 0x0C, (addr >> 8) & 0xFF);
37 via_write_reg(VIACR, 0x34, (addr >> 16) & 0xFF);
38 via_write_reg_mask(VIACR, 0x48, (addr >> 24) & 0x1F, 0x1F);
39}
40
41void via_set_secondary_address(u32 addr)
42{
43 DEBUG_MSG(KERN_DEBUG "via_set_secondary_address(0x%08X)\n", addr);
44 /* secondary display supports only quadword aligned memory */
45 via_write_reg_mask(VIACR, 0x62, (addr >> 2) & 0xFE, 0xFE);
46 via_write_reg(VIACR, 0x63, (addr >> 10) & 0xFF);
47 via_write_reg(VIACR, 0x64, (addr >> 18) & 0xFF);
48 via_write_reg_mask(VIACR, 0xA3, (addr >> 26) & 0x07, 0x07);
49}
50
51void via_set_primary_pitch(u32 pitch)
52{
53 DEBUG_MSG(KERN_DEBUG "via_set_primary_pitch(0x%08X)\n", pitch);
54 /* spec does not say that first adapter skips 3 bits but old
55 * code did it and seems to be reasonable in analogy to 2nd adapter
56 */
57 pitch = pitch >> 3;
58 via_write_reg(VIACR, 0x13, pitch & 0xFF);
59 via_write_reg_mask(VIACR, 0x35, (pitch >> (8 - 5)) & 0xE0, 0xE0);
60}
61
62void via_set_secondary_pitch(u32 pitch)
63{
64 DEBUG_MSG(KERN_DEBUG "via_set_secondary_pitch(0x%08X)\n", pitch);
65 pitch = pitch >> 3;
66 via_write_reg(VIACR, 0x66, pitch & 0xFF);
67 via_write_reg_mask(VIACR, 0x67, (pitch >> 8) & 0x03, 0x03);
68 via_write_reg_mask(VIACR, 0x71, (pitch >> (10 - 7)) & 0x80, 0x80);
69}
70
71void via_set_primary_color_depth(u8 depth)
72{
73 u8 value;
74
75 DEBUG_MSG(KERN_DEBUG "via_set_primary_color_depth(%d)\n", depth);
76 switch (depth) {
77 case 8:
78 value = 0x00;
79 break;
80 case 15:
81 value = 0x04;
82 break;
83 case 16:
84 value = 0x14;
85 break;
86 case 24:
87 value = 0x0C;
88 break;
89 case 30:
90 value = 0x08;
91 break;
92 default:
93 printk(KERN_WARNING "via_set_primary_color_depth: "
94 "Unsupported depth: %d\n", depth);
95 return;
96 }
97
98 via_write_reg_mask(VIASR, 0x15, value, 0x1C);
99}
100
101void via_set_secondary_color_depth(u8 depth)
102{
103 u8 value;
104
105 DEBUG_MSG(KERN_DEBUG "via_set_secondary_color_depth(%d)\n", depth);
106 switch (depth) {
107 case 8:
108 value = 0x00;
109 break;
110 case 16:
111 value = 0x40;
112 break;
113 case 24:
114 value = 0xC0;
115 break;
116 case 30:
117 value = 0x80;
118 break;
119 default:
120 printk(KERN_WARNING "via_set_secondary_color_depth: "
121 "Unsupported depth: %d\n", depth);
122 return;
123 }
124
125 via_write_reg_mask(VIACR, 0x67, value, 0xC0);
126}
diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_modesetting.h
index 3a13242a3152..ae35cfdeb37c 100644
--- a/drivers/video/via/via_i2c.h
+++ b/drivers/video/via/via_modesetting.h
@@ -1,46 +1,38 @@
1/* 1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 4 * Copyright 2010 Florian Tobias Schandinat <FlorianSchandinat@gmx.de>
5 *
5 * This program is free software; you can redistribute it and/or 6 * This program is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU General Public 7 * modify it under the terms of the GNU General Public
7 * License as published by the Free Software Foundation; 8 * License as published by the Free Software Foundation;
8 * either version 2, or (at your option) any later version. 9 * either version 2, or (at your option) any later version.
9 10 *
10 * This program is distributed in the hope that it will be useful, 11 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even 12 * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12 * the implied warranty of MERCHANTABILITY or FITNESS FOR 13 * the implied warranty of MERCHANTABILITY or FITNESS FOR
13 * A PARTICULAR PURPOSE.See the GNU General Public License 14 * A PARTICULAR PURPOSE.See the GNU General Public License
14 * for more details. 15 * for more details.
15 16 *
16 * You should have received a copy of the GNU General Public License 17 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software 18 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 19 * Foundation, Inc.,
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 20 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 21 */
21#ifndef __VIA_I2C_H__ 22/*
22#define __VIA_I2C_H__ 23 * basic modesetting functions
24 */
23 25
24#include <linux/i2c.h> 26#ifndef __VIA_MODESETTING_H__
25#include <linux/i2c-algo-bit.h> 27#define __VIA_MODESETTING_H__
26 28
27struct via_i2c_stuff { 29#include <linux/types.h>
28 u16 i2c_port; /* GPIO or I2C port */
29 struct i2c_adapter adapter;
30 struct i2c_algo_bit_data algo;
31};
32 30
33#define I2CPORT 0x3c4 31void via_set_primary_address(u32 addr);
34#define I2CPORTINDEX 0x31 32void via_set_secondary_address(u32 addr);
35#define GPIOPORT 0x3C4 33void via_set_primary_pitch(u32 pitch);
36#define GPIOPORTINDEX 0x2C 34void via_set_secondary_pitch(u32 pitch);
37#define I2C_BUS 1 35void via_set_primary_color_depth(u8 depth);
38#define GPIO_BUS 2 36void via_set_secondary_color_depth(u8 depth);
39#define DELAYPORT 0x3C3
40 37
41int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata); 38#endif /* __VIA_MODESETTING_H__ */
42int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data);
43int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len);
44int viafb_create_i2c_bus(void *par);
45void viafb_delete_i2c_buss(void *par);
46#endif /* __VIA_I2C_H__ */
diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c
index aefdeeec89b1..d05ccb62b55f 100644
--- a/drivers/video/via/via_utility.c
+++ b/drivers/video/via/via_utility.c
@@ -19,6 +19,7 @@
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22#include <linux/via-core.h>
22#include "global.h" 23#include "global.h"
23 24
24void viafb_get_device_support_state(u32 *support_state) 25void viafb_get_device_support_state(u32 *support_state)
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c
index 777b38a06d40..2bc40e682f95 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/via/viafbdev.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. 2 * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved.
3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. 3 * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4 4
5 * This program is free software; you can redistribute it and/or 5 * This program is free software; you can redistribute it and/or
@@ -23,8 +23,9 @@
23#include <linux/seq_file.h> 23#include <linux/seq_file.h>
24#include <linux/slab.h> 24#include <linux/slab.h>
25#include <linux/stat.h> 25#include <linux/stat.h>
26#define _MASTER_FILE 26#include <linux/via-core.h>
27 27
28#define _MASTER_FILE
28#include "global.h" 29#include "global.h"
29 30
30static char *viafb_name = "Via"; 31static char *viafb_name = "Via";
@@ -221,7 +222,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var,
221 /* Adjust var according to our driver's own table */ 222 /* Adjust var according to our driver's own table */
222 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); 223 viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry);
223 if (info->var.accel_flags & FB_ACCELF_TEXT && 224 if (info->var.accel_flags & FB_ACCELF_TEXT &&
224 !ppar->shared->engine_mmio) 225 !ppar->shared->vdev->engine_mmio)
225 info->var.accel_flags = 0; 226 info->var.accel_flags = 0;
226 227
227 return 0; 228 return 0;
@@ -317,12 +318,12 @@ static int viafb_pan_display(struct fb_var_screeninfo *var,
317 318
318 DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr); 319 DEBUG_MSG(KERN_DEBUG "viafb_pan_display, address = %d\n", vram_addr);
319 if (!viafb_dual_fb) { 320 if (!viafb_dual_fb) {
320 viafb_set_primary_address(vram_addr); 321 via_set_primary_address(vram_addr);
321 viafb_set_secondary_address(vram_addr); 322 via_set_secondary_address(vram_addr);
322 } else if (viapar->iga_path == IGA1) 323 } else if (viapar->iga_path == IGA1)
323 viafb_set_primary_address(vram_addr); 324 via_set_primary_address(vram_addr);
324 else 325 else
325 viafb_set_secondary_address(vram_addr); 326 via_set_secondary_address(vram_addr);
326 327
327 return 0; 328 return 0;
328} 329}
@@ -696,7 +697,7 @@ static void viafb_fillrect(struct fb_info *info,
696 rop = 0xF0; 697 rop = 0xF0;
697 698
698 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n"); 699 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n");
699 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_FILL, 700 if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_FILL,
700 rect->width, rect->height, info->var.bits_per_pixel, 701 rect->width, rect->height, info->var.bits_per_pixel,
701 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy, 702 viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy,
702 NULL, 0, 0, 0, 0, fg_color, 0, rop)) 703 NULL, 0, 0, 0, 0, fg_color, 0, rop))
@@ -718,7 +719,7 @@ static void viafb_copyarea(struct fb_info *info,
718 return; 719 return;
719 720
720 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n"); 721 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n");
721 if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_COLOR, 722 if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_COLOR,
722 area->width, area->height, info->var.bits_per_pixel, 723 area->width, area->height, info->var.bits_per_pixel,
723 viapar->vram_addr, info->fix.line_length, area->dx, area->dy, 724 viapar->vram_addr, info->fix.line_length, area->dx, area->dy,
724 NULL, viapar->vram_addr, info->fix.line_length, 725 NULL, viapar->vram_addr, info->fix.line_length,
@@ -755,7 +756,7 @@ static void viafb_imageblit(struct fb_info *info,
755 op = VIA_BITBLT_COLOR; 756 op = VIA_BITBLT_COLOR;
756 757
757 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n"); 758 DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n");
758 if (shared->hw_bitblt(shared->engine_mmio, op, 759 if (shared->hw_bitblt(shared->vdev->engine_mmio, op,
759 image->width, image->height, info->var.bits_per_pixel, 760 image->width, image->height, info->var.bits_per_pixel,
760 viapar->vram_addr, info->fix.line_length, image->dx, image->dy, 761 viapar->vram_addr, info->fix.line_length, image->dx, image->dy,
761 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0)) 762 (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0))
@@ -765,7 +766,7 @@ static void viafb_imageblit(struct fb_info *info,
765static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) 766static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor)
766{ 767{
767 struct viafb_par *viapar = info->par; 768 struct viafb_par *viapar = info->par;
768 void __iomem *engine = viapar->shared->engine_mmio; 769 void __iomem *engine = viapar->shared->vdev->engine_mmio;
769 u32 temp, xx, yy, bg_color = 0, fg_color = 0, 770 u32 temp, xx, yy, bg_color = 0, fg_color = 0,
770 chip_name = viapar->shared->chip_info.gfx_chip_name; 771 chip_name = viapar->shared->chip_info.gfx_chip_name;
771 int i, j = 0, cur_size = 64; 772 int i, j = 0, cur_size = 64;
@@ -1018,8 +1019,8 @@ static void viafb_set_device(struct device_t active_dev)
1018 viafb_SAMM_ON = active_dev.samm; 1019 viafb_SAMM_ON = active_dev.samm;
1019 viafb_primary_dev = active_dev.primary_dev; 1020 viafb_primary_dev = active_dev.primary_dev;
1020 1021
1021 viafb_set_primary_address(0); 1022 via_set_primary_address(0);
1022 viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); 1023 via_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0);
1023 viafb_set_iga_path(); 1024 viafb_set_iga_path();
1024} 1025}
1025 1026
@@ -1165,8 +1166,9 @@ static int apply_device_setting(struct viafb_ioctl_setting setting_info,
1165 if (viafb_SAMM_ON) 1166 if (viafb_SAMM_ON)
1166 viafb_primary_dev = setting_info.primary_device; 1167 viafb_primary_dev = setting_info.primary_device;
1167 1168
1168 viafb_set_primary_address(0); 1169 via_set_primary_address(0);
1169 viafb_set_secondary_address(viafb_SAMM_ON ? viafb_second_offset : 0); 1170 via_set_secondary_address(viafb_SAMM_ON ?
1171 viafb_second_offset : 0);
1170 viafb_set_iga_path(); 1172 viafb_set_iga_path();
1171 } 1173 }
1172 need_set_mode = 1; 1174 need_set_mode = 1;
@@ -1325,6 +1327,8 @@ static void parse_dvi_port(void)
1325 output_interface); 1327 output_interface);
1326} 1328}
1327 1329
1330#ifdef CONFIG_FB_VIA_DIRECT_PROCFS
1331
1328/* 1332/*
1329 * The proc filesystem read/write function, a simple proc implement to 1333 * The proc filesystem read/write function, a simple proc implement to
1330 * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1, 1334 * get/set the value of DPA DVP0, DVP0DataDriving, DVP0ClockDriving, DVP1,
@@ -1701,16 +1705,21 @@ static void viafb_init_proc(struct proc_dir_entry **viafb_entry)
1701} 1705}
1702static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) 1706static void viafb_remove_proc(struct proc_dir_entry *viafb_entry)
1703{ 1707{
1704 /* no problem if it was not registered */ 1708 struct chip_information *chip_info = &viaparinfo->shared->chip_info;
1709
1705 remove_proc_entry("dvp0", viafb_entry);/* parent dir */ 1710 remove_proc_entry("dvp0", viafb_entry);/* parent dir */
1706 remove_proc_entry("dvp1", viafb_entry); 1711 remove_proc_entry("dvp1", viafb_entry);
1707 remove_proc_entry("dfph", viafb_entry); 1712 remove_proc_entry("dfph", viafb_entry);
1708 remove_proc_entry("dfpl", viafb_entry); 1713 remove_proc_entry("dfpl", viafb_entry);
1709 remove_proc_entry("vt1636", viafb_entry); 1714 if (chip_info->lvds_chip_info.lvds_chip_name == VT1636_LVDS
1710 remove_proc_entry("vt1625", viafb_entry); 1715 || chip_info->lvds_chip_info2.lvds_chip_name == VT1636_LVDS)
1716 remove_proc_entry("vt1636", viafb_entry);
1717
1711 remove_proc_entry("viafb", NULL); 1718 remove_proc_entry("viafb", NULL);
1712} 1719}
1713 1720
1721#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */
1722
1714static int parse_mode(const char *str, u32 *xres, u32 *yres) 1723static int parse_mode(const char *str, u32 *xres, u32 *yres)
1715{ 1724{
1716 char *ptr; 1725 char *ptr;
@@ -1732,12 +1741,13 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres)
1732 return 0; 1741 return 0;
1733} 1742}
1734 1743
1735static int __devinit via_pci_probe(struct pci_dev *pdev, 1744
1736 const struct pci_device_id *ent) 1745int __devinit via_fb_pci_probe(struct viafb_dev *vdev)
1737{ 1746{
1738 u32 default_xres, default_yres; 1747 u32 default_xres, default_yres;
1739 struct VideoModeTable *vmode_entry; 1748 struct VideoModeTable *vmode_entry;
1740 struct fb_var_screeninfo default_var; 1749 struct fb_var_screeninfo default_var;
1750 int rc;
1741 u32 viafb_par_length; 1751 u32 viafb_par_length;
1742 1752
1743 DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n"); 1753 DEBUG_MSG(KERN_INFO "VIAFB PCI Probe!!\n");
@@ -1749,14 +1759,15 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
1749 */ 1759 */
1750 viafbinfo = framebuffer_alloc(viafb_par_length + 1760 viafbinfo = framebuffer_alloc(viafb_par_length +
1751 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8), 1761 ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8),
1752 &pdev->dev); 1762 &vdev->pdev->dev);
1753 if (!viafbinfo) { 1763 if (!viafbinfo) {
1754 printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); 1764 printk(KERN_ERR"Could not allocate memory for viafb_info.\n");
1755 return -ENODEV; 1765 return -ENOMEM;
1756 } 1766 }
1757 1767
1758 viaparinfo = (struct viafb_par *)viafbinfo->par; 1768 viaparinfo = (struct viafb_par *)viafbinfo->par;
1759 viaparinfo->shared = viafbinfo->par + viafb_par_length; 1769 viaparinfo->shared = viafbinfo->par + viafb_par_length;
1770 viaparinfo->shared->vdev = vdev;
1760 viaparinfo->vram_addr = 0; 1771 viaparinfo->vram_addr = 0;
1761 viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info; 1772 viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info;
1762 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; 1773 viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info;
@@ -1774,23 +1785,20 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
1774 if (!viafb_SAMM_ON) 1785 if (!viafb_SAMM_ON)
1775 viafb_dual_fb = 0; 1786 viafb_dual_fb = 0;
1776 1787
1777 /* Set up I2C bus stuff */ 1788 viafb_init_chip_info(vdev->chip_type);
1778 viafb_create_i2c_bus(viaparinfo); 1789 /*
1779 1790 * The framebuffer will have been successfully mapped by
1780 viafb_init_chip_info(pdev, ent); 1791 * the core (or we'd not be here), but we still need to
1781 viaparinfo->fbmem = pci_resource_start(pdev, 0); 1792 * set up our own accounting.
1782 viaparinfo->memsize = viafb_get_fb_size_from_pci(); 1793 */
1794 viaparinfo->fbmem = vdev->fbmem_start;
1795 viaparinfo->memsize = vdev->fbmem_len;
1783 viaparinfo->fbmem_free = viaparinfo->memsize; 1796 viaparinfo->fbmem_free = viaparinfo->memsize;
1784 viaparinfo->fbmem_used = 0; 1797 viaparinfo->fbmem_used = 0;
1785 viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem, 1798 viafbinfo->screen_base = vdev->fbmem;
1786 viaparinfo->memsize);
1787 if (!viafbinfo->screen_base) {
1788 printk(KERN_INFO "ioremap failed\n");
1789 return -ENOMEM;
1790 }
1791 1799
1792 viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1); 1800 viafbinfo->fix.mmio_start = vdev->engine_start;
1793 viafbinfo->fix.mmio_len = pci_resource_len(pdev, 1); 1801 viafbinfo->fix.mmio_len = vdev->engine_len;
1794 viafbinfo->node = 0; 1802 viafbinfo->node = 0;
1795 viafbinfo->fbops = &viafb_ops; 1803 viafbinfo->fbops = &viafb_ops;
1796 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1804 viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
@@ -1858,12 +1866,13 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
1858 viafbinfo->var = default_var; 1866 viafbinfo->var = default_var;
1859 1867
1860 if (viafb_dual_fb) { 1868 if (viafb_dual_fb) {
1861 viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); 1869 viafbinfo1 = framebuffer_alloc(viafb_par_length,
1870 &vdev->pdev->dev);
1862 if (!viafbinfo1) { 1871 if (!viafbinfo1) {
1863 printk(KERN_ERR 1872 printk(KERN_ERR
1864 "allocate the second framebuffer struct error\n"); 1873 "allocate the second framebuffer struct error\n");
1865 framebuffer_release(viafbinfo); 1874 rc = -ENOMEM;
1866 return -ENOMEM; 1875 goto out_fb_release;
1867 } 1876 }
1868 viaparinfo1 = viafbinfo1->par; 1877 viaparinfo1 = viafbinfo1->par;
1869 memcpy(viaparinfo1, viaparinfo, viafb_par_length); 1878 memcpy(viaparinfo1, viaparinfo, viafb_par_length);
@@ -1914,48 +1923,66 @@ static int __devinit via_pci_probe(struct pci_dev *pdev,
1914 viaparinfo->depth = fb_get_color_depth(&viafbinfo->var, 1923 viaparinfo->depth = fb_get_color_depth(&viafbinfo->var,
1915 &viafbinfo->fix); 1924 &viafbinfo->fix);
1916 default_var.activate = FB_ACTIVATE_NOW; 1925 default_var.activate = FB_ACTIVATE_NOW;
1917 fb_alloc_cmap(&viafbinfo->cmap, 256, 0); 1926 rc = fb_alloc_cmap(&viafbinfo->cmap, 256, 0);
1927 if (rc)
1928 goto out_fb1_release;
1918 1929
1919 if (viafb_dual_fb && (viafb_primary_dev == LCD_Device) 1930 if (viafb_dual_fb && (viafb_primary_dev == LCD_Device)
1920 && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) { 1931 && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266)) {
1921 if (register_framebuffer(viafbinfo1) < 0) 1932 rc = register_framebuffer(viafbinfo1);
1922 return -EINVAL; 1933 if (rc)
1934 goto out_dealloc_cmap;
1923 } 1935 }
1924 if (register_framebuffer(viafbinfo) < 0) 1936 rc = register_framebuffer(viafbinfo);
1925 return -EINVAL; 1937 if (rc)
1938 goto out_fb1_unreg_lcd_cle266;
1926 1939
1927 if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device) 1940 if (viafb_dual_fb && ((viafb_primary_dev != LCD_Device)
1928 || (viaparinfo->chip_info->gfx_chip_name != 1941 || (viaparinfo->chip_info->gfx_chip_name !=
1929 UNICHROME_CLE266))) { 1942 UNICHROME_CLE266))) {
1930 if (register_framebuffer(viafbinfo1) < 0) 1943 rc = register_framebuffer(viafbinfo1);
1931 return -EINVAL; 1944 if (rc)
1945 goto out_fb_unreg;
1932 } 1946 }
1933 DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n", 1947 DEBUG_MSG(KERN_INFO "fb%d: %s frame buffer device %dx%d-%dbpp\n",
1934 viafbinfo->node, viafbinfo->fix.id, default_var.xres, 1948 viafbinfo->node, viafbinfo->fix.id, default_var.xres,
1935 default_var.yres, default_var.bits_per_pixel); 1949 default_var.yres, default_var.bits_per_pixel);
1936 1950
1951#ifdef CONFIG_FB_VIA_DIRECT_PROCFS
1937 viafb_init_proc(&viaparinfo->shared->proc_entry); 1952 viafb_init_proc(&viaparinfo->shared->proc_entry);
1953#endif
1938 viafb_init_dac(IGA2); 1954 viafb_init_dac(IGA2);
1939 return 0; 1955 return 0;
1956
1957out_fb_unreg:
1958 unregister_framebuffer(viafbinfo);
1959out_fb1_unreg_lcd_cle266:
1960 if (viafb_dual_fb && (viafb_primary_dev == LCD_Device)
1961 && (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266))
1962 unregister_framebuffer(viafbinfo1);
1963out_dealloc_cmap:
1964 fb_dealloc_cmap(&viafbinfo->cmap);
1965out_fb1_release:
1966 if (viafbinfo1)
1967 framebuffer_release(viafbinfo1);
1968out_fb_release:
1969 framebuffer_release(viafbinfo);
1970 return rc;
1940} 1971}
1941 1972
1942static void __devexit via_pci_remove(struct pci_dev *pdev) 1973void __devexit via_fb_pci_remove(struct pci_dev *pdev)
1943{ 1974{
1944 DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); 1975 DEBUG_MSG(KERN_INFO "via_pci_remove!\n");
1945 fb_dealloc_cmap(&viafbinfo->cmap); 1976 fb_dealloc_cmap(&viafbinfo->cmap);
1946 unregister_framebuffer(viafbinfo); 1977 unregister_framebuffer(viafbinfo);
1947 if (viafb_dual_fb) 1978 if (viafb_dual_fb)
1948 unregister_framebuffer(viafbinfo1); 1979 unregister_framebuffer(viafbinfo1);
1949 iounmap((void *)viafbinfo->screen_base); 1980#ifdef CONFIG_FB_VIA_DIRECT_PROCFS
1950 iounmap(viaparinfo->shared->engine_mmio); 1981 viafb_remove_proc(viaparinfo->shared->proc_entry);
1951 1982#endif
1952 viafb_delete_i2c_buss(viaparinfo);
1953
1954 framebuffer_release(viafbinfo); 1983 framebuffer_release(viafbinfo);
1955 if (viafb_dual_fb) 1984 if (viafb_dual_fb)
1956 framebuffer_release(viafbinfo1); 1985 framebuffer_release(viafbinfo1);
1957
1958 viafb_remove_proc(viaparinfo->shared->proc_entry);
1959} 1986}
1960 1987
1961#ifndef MODULE 1988#ifndef MODULE
@@ -2031,41 +2058,10 @@ static int __init viafb_setup(char *options)
2031} 2058}
2032#endif 2059#endif
2033 2060
2034static struct pci_device_id viafb_pci_table[] __devinitdata = { 2061/*
2035 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID), 2062 * These are called out of via-core for now.
2036 .driver_data = UNICHROME_CLE266 }, 2063 */
2037 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID), 2064int __init viafb_init(void)
2038 .driver_data = UNICHROME_PM800 },
2039 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID),
2040 .driver_data = UNICHROME_K400 },
2041 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID),
2042 .driver_data = UNICHROME_K800 },
2043 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID),
2044 .driver_data = UNICHROME_CN700 },
2045 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID),
2046 .driver_data = UNICHROME_K8M890 },
2047 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID),
2048 .driver_data = UNICHROME_CX700 },
2049 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID),
2050 .driver_data = UNICHROME_P4M900 },
2051 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID),
2052 .driver_data = UNICHROME_CN750 },
2053 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID),
2054 .driver_data = UNICHROME_VX800 },
2055 { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID),
2056 .driver_data = UNICHROME_VX855 },
2057 { }
2058};
2059MODULE_DEVICE_TABLE(pci, viafb_pci_table);
2060
2061static struct pci_driver viafb_driver = {
2062 .name = "viafb",
2063 .id_table = viafb_pci_table,
2064 .probe = via_pci_probe,
2065 .remove = __devexit_p(via_pci_remove),
2066};
2067
2068static int __init viafb_init(void)
2069{ 2065{
2070 u32 dummy; 2066 u32 dummy;
2071#ifndef MODULE 2067#ifndef MODULE
@@ -2084,13 +2080,12 @@ static int __init viafb_init(void)
2084 printk(KERN_INFO 2080 printk(KERN_INFO
2085 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", 2081 "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n",
2086 VERSION_MAJOR, VERSION_MINOR); 2082 VERSION_MAJOR, VERSION_MINOR);
2087 return pci_register_driver(&viafb_driver); 2083 return 0;
2088} 2084}
2089 2085
2090static void __exit viafb_exit(void) 2086void __exit viafb_exit(void)
2091{ 2087{
2092 DEBUG_MSG(KERN_INFO "viafb_exit!\n"); 2088 DEBUG_MSG(KERN_INFO "viafb_exit!\n");
2093 pci_unregister_driver(&viafb_driver);
2094} 2089}
2095 2090
2096static struct fb_ops viafb_ops = { 2091static struct fb_ops viafb_ops = {
@@ -2110,8 +2105,6 @@ static struct fb_ops viafb_ops = {
2110 .fb_sync = viafb_sync, 2105 .fb_sync = viafb_sync,
2111}; 2106};
2112 2107
2113module_init(viafb_init);
2114module_exit(viafb_exit);
2115 2108
2116#ifdef MODULE 2109#ifdef MODULE
2117module_param(viafb_mode, charp, S_IRUSR); 2110module_param(viafb_mode, charp, S_IRUSR);
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h
index 61b5953cd159..52a35fabba91 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/via/viafbdev.h
@@ -24,12 +24,12 @@
24 24
25#include <linux/proc_fs.h> 25#include <linux/proc_fs.h>
26#include <linux/fb.h> 26#include <linux/fb.h>
27#include <linux/spinlock.h>
27 28
28#include "ioctl.h" 29#include "ioctl.h"
29#include "share.h" 30#include "share.h"
30#include "chip.h" 31#include "chip.h"
31#include "hw.h" 32#include "hw.h"
32#include "via_i2c.h"
33 33
34#define VERSION_MAJOR 2 34#define VERSION_MAJOR 2
35#define VERSION_KERNEL 6 /* For kernel 2.6 */ 35#define VERSION_KERNEL 6 /* For kernel 2.6 */
@@ -37,11 +37,11 @@
37#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ 37#define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */
38#define VERSION_MINOR 4 38#define VERSION_MINOR 4
39 39
40#define VIAFB_NUM_I2C 5
41
40struct viafb_shared { 42struct viafb_shared {
41 struct proc_dir_entry *proc_entry; /*viafb proc entry */ 43 struct proc_dir_entry *proc_entry; /*viafb proc entry */
42 44 struct viafb_dev *vdev; /* Global dev info */
43 /* I2C stuff */
44 struct via_i2c_stuff i2c_stuff;
45 45
46 /* All the information will be needed to set engine */ 46 /* All the information will be needed to set engine */
47 struct tmds_setting_information tmds_setting_info; 47 struct tmds_setting_information tmds_setting_info;
@@ -51,7 +51,6 @@ struct viafb_shared {
51 struct chip_information chip_info; 51 struct chip_information chip_info;
52 52
53 /* hardware acceleration stuff */ 53 /* hardware acceleration stuff */
54 void __iomem *engine_mmio;
55 u32 cursor_vram_addr; 54 u32 cursor_vram_addr;
56 u32 vq_vram_addr; /* virtual queue address in video ram */ 55 u32 vq_vram_addr; /* virtual queue address in video ram */
57 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height, 56 int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height,
@@ -99,4 +98,9 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
99void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information 98void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
100 *plvds_setting_info, struct lvds_chip_information 99 *plvds_setting_info, struct lvds_chip_information
101 *plvds_chip_info, struct IODATA io_data); 100 *plvds_chip_info, struct IODATA io_data);
101int via_fb_pci_probe(struct viafb_dev *vdev);
102void via_fb_pci_remove(struct pci_dev *pdev);
103/* Temporary */
104int viafb_init(void);
105void viafb_exit(void);
102#endif /* __VIAFBDEV_H__ */ 106#endif /* __VIAFBDEV_H__ */
diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c
index af50e244016c..2dbad3c0f679 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/via/viamode.c
@@ -19,6 +19,7 @@
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22#include <linux/via-core.h>
22#include "global.h" 23#include "global.h"
23struct res_map_refresh res_map_refresh_tbl[] = { 24struct res_map_refresh res_map_refresh_tbl[] = {
24/*hres, vres, vclock, vmode_refresh*/ 25/*hres, vres, vclock, vmode_refresh*/
@@ -66,6 +67,7 @@ struct res_map_refresh res_map_refresh_tbl[] = {
66 {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60}, 67 {1088, 612, RES_1088X612_60HZ_PIXCLOCK, 60},
67 {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60}, 68 {1152, 720, RES_1152X720_60HZ_PIXCLOCK, 60},
68 {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60}, 69 {1200, 720, RES_1200X720_60HZ_PIXCLOCK, 60},
70 {1200, 900, RES_1200X900_60HZ_PIXCLOCK, 60},
69 {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60}, 71 {1280, 600, RES_1280X600_60HZ_PIXCLOCK, 60},
70 {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50}, 72 {1280, 720, RES_1280X720_50HZ_PIXCLOCK, 50},
71 {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50}, 73 {1280, 768, RES_1280X768_50HZ_PIXCLOCK, 50},
@@ -759,6 +761,16 @@ struct crt_mode_table CRTM1200x720[] = {
759 {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} } 761 {1568, 1200, 1200, 368, 1256, 128, 746, 720, 720, 26, 721, 3} }
760}; 762};
761 763
764/* 1200x900 (DCON) */
765struct crt_mode_table DCON1200x900[] = {
766 /* r_rate, vclk, hsp, vsp */
767 {REFRESH_60, CLK_57_275M, M1200X900_R60_HSP, M1200X900_R60_VSP,
768 /* The correct htotal is 1240, but this doesn't raster on VX855. */
769 /* Via suggested changing to a multiple of 16, hence 1264. */
770 /* HT, HA, HBS, HBE, HSS, HSE, VT, VA, VBS, VBE, VSS, VSE */
771 {1264, 1200, 1200, 64, 1211, 32, 912, 900, 900, 12, 901, 10} }
772};
773
762/* 1280x600 (GTF) */ 774/* 1280x600 (GTF) */
763struct crt_mode_table CRTM1280x600[] = { 775struct crt_mode_table CRTM1280x600[] = {
764 /* r_rate, vclk, hsp, vsp */ 776 /* r_rate, vclk, hsp, vsp */
@@ -937,6 +949,9 @@ struct VideoModeTable viafb_modes[] = {
937 /* Display : 1200x720 (GTF) */ 949 /* Display : 1200x720 (GTF) */
938 {CRTM1200x720, ARRAY_SIZE(CRTM1200x720)}, 950 {CRTM1200x720, ARRAY_SIZE(CRTM1200x720)},
939 951
952 /* Display : 1200x900 (DCON) */
953 {DCON1200x900, ARRAY_SIZE(DCON1200x900)},
954
940 /* Display : 1280x600 (GTF) */ 955 /* Display : 1280x600 (GTF) */
941 {CRTM1280x600, ARRAY_SIZE(CRTM1280x600)}, 956 {CRTM1280x600, ARRAY_SIZE(CRTM1280x600)},
942 957
diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c
index a6b37494e79a..d65bf1aee87c 100644
--- a/drivers/video/via/vt1636.c
+++ b/drivers/video/via/vt1636.c
@@ -19,6 +19,8 @@
19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. 19 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20 */ 20 */
21 21
22#include <linux/via-core.h>
23#include <linux/via_i2c.h>
22#include "global.h" 24#include "global.h"
23 25
24u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information 26u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
@@ -27,9 +29,8 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information
27{ 29{
28 u8 data; 30 u8 data;
29 31
30 viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; 32 viafb_i2c_readbyte(plvds_chip_info->i2c_port,
31 viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); 33 plvds_chip_info->lvds_chip_slave_addr, index, &data);
32
33 return data; 34 return data;
34} 35}
35 36
@@ -39,14 +40,13 @@ void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information
39{ 40{
40 int index, data; 41 int index, data;
41 42
42 viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port;
43
44 index = io_data.Index; 43 index = io_data.Index;
45 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, 44 data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info,
46 index); 45 index);
47 data = (data & (~io_data.Mask)) | io_data.Data; 46 data = (data & (~io_data.Mask)) | io_data.Data;
48 47
49 viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data); 48 viafb_i2c_writebyte(plvds_chip_info->i2c_port,
49 plvds_chip_info->lvds_chip_slave_addr, index, data);
50} 50}
51 51
52void viafb_init_lvds_vt1636(struct lvds_setting_information 52void viafb_init_lvds_vt1636(struct lvds_setting_information
@@ -159,7 +159,7 @@ void viafb_disable_lvds_vt1636(struct lvds_setting_information
159 } 159 }
160} 160}
161 161
162bool viafb_lvds_identify_vt1636(void) 162bool viafb_lvds_identify_vt1636(u8 i2c_adapter)
163{ 163{
164 u8 Buffer[2]; 164 u8 Buffer[2];
165 165
@@ -167,26 +167,20 @@ bool viafb_lvds_identify_vt1636(void)
167 167
168 /* Sense VT1636 LVDS Transmiter */ 168 /* Sense VT1636 LVDS Transmiter */
169 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr = 169 viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =
170 VT1636_LVDS_I2C_ADDR; 170 VT1636_LVDS_I2C_ADDR;
171 171
172 /* Check vendor ID first: */ 172 /* Check vendor ID first: */
173 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. 173 if (viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR,
174 lvds_chip_slave_addr, 174 0x00, &Buffer[0]))
175 0x00, &Buffer[0]); 175 return false;
176 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. 176 viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x01, &Buffer[1]);
177 lvds_chip_slave_addr,
178 0x01, &Buffer[1]);
179 177
180 if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) 178 if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11)))
181 return false; 179 return false;
182 180
183 /* Check Chip ID: */ 181 /* Check Chip ID: */
184 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. 182 viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x02, &Buffer[0]);
185 lvds_chip_slave_addr, 183 viafb_i2c_readbyte(i2c_adapter, VT1636_LVDS_I2C_ADDR, 0x03, &Buffer[1]);
186 0x02, &Buffer[0]);
187 viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info.
188 lvds_chip_slave_addr,
189 0x03, &Buffer[1]);
190 if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { 184 if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) {
191 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = 185 viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =
192 VT1636_LVDS; 186 VT1636_LVDS;
diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h
index 2a150c58c7ed..4c1314e57468 100644
--- a/drivers/video/via/vt1636.h
+++ b/drivers/video/via/vt1636.h
@@ -22,7 +22,7 @@
22#ifndef _VT1636_H_ 22#ifndef _VT1636_H_
23#define _VT1636_H_ 23#define _VT1636_H_
24#include "chip.h" 24#include "chip.h"
25bool viafb_lvds_identify_vt1636(void); 25bool viafb_lvds_identify_vt1636(u8 i2c_adapter);
26void viafb_init_lvds_vt1636(struct lvds_setting_information 26void viafb_init_lvds_vt1636(struct lvds_setting_information
27 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); 27 *plvds_setting_info, struct lvds_chip_information *plvds_chip_info);
28void viafb_enable_lvds_vt1636(struct lvds_setting_information 28void viafb_enable_lvds_vt1636(struct lvds_setting_information