aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
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
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')
-rw-r--r--drivers/video/Kconfig16
-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
24 files changed, 1641 insertions, 584 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6e16244f3ed1..fd55c279915c 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -1511,6 +1511,7 @@ config FB_VIA
1511 select FB_CFB_IMAGEBLIT 1511 select FB_CFB_IMAGEBLIT
1512 select I2C_ALGOBIT 1512 select I2C_ALGOBIT
1513 select I2C 1513 select I2C
1514 select GPIOLIB
1514 help 1515 help
1515 This is the frame buffer device driver for Graphics chips of VIA 1516 This is the frame buffer device driver for Graphics chips of VIA
1516 UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/ 1517 UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
@@ -1520,6 +1521,21 @@ config FB_VIA
1520 1521
1521 To compile this driver as a module, choose M here: the 1522 To compile this driver as a module, choose M here: the
1522 module will be called viafb. 1523 module will be called viafb.
1524
1525if FB_VIA
1526
1527config FB_VIA_DIRECT_PROCFS
1528 bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
1529 depends on FB_VIA
1530 default n
1531 help
1532 Allow direct hardware access to some output registers via procfs.
1533 This is dangerous but may provide the only chance to get the
1534 correct output device configuration.
1535 Its use is strongly discouraged.
1536
1537endif
1538
1523config FB_NEOMAGIC 1539config FB_NEOMAGIC
1524 tristate "NeoMagic display support" 1540 tristate "NeoMagic display support"
1525 depends on FB && PCI 1541 depends on FB && PCI
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