From c205d932530719d2a6ddb9152650e5bbe80c9400 Mon Sep 17 00:00:00 2001 From: Chris Ball Date: Sun, 7 Jun 2009 13:59:51 -0400 Subject: viafb: Add 1200x900 DCON/LCD panel modes for OLPC XO-1.5 [jc: extensive merge conflict fixes] Cc: Florian Tobias Schandinat Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Signed-off-by: Chris Ball --- drivers/video/via/lcd.c | 9 +++++++++ 1 file changed, 9 insertions(+) (limited to 'drivers/video/via/lcd.c') diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 1b1ccdc2d83..09020f0b2d2 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -398,6 +398,15 @@ static void fp_id_to_vindex(int panel_id) viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; viaparinfo->lvds_setting_info->LCDDithering = 1; break; + case 0x17: + /* OLPC XO-1.5 panel */ + viaparinfo->lvds_setting_info->lcd_panel_hres = 1200; + viaparinfo->lvds_setting_info->lcd_panel_vres = 900; + viaparinfo->lvds_setting_info->lcd_panel_id = + LCD_PANEL_IDD_1200X900; + viaparinfo->lvds_setting_info->device_lcd_dualedge = 0; + viaparinfo->lvds_setting_info->LCDDithering = 0; + break; default: viaparinfo->lvds_setting_info->lcd_panel_hres = 800; viaparinfo->lvds_setting_info->lcd_panel_vres = 600; -- cgit v1.2.3-70-g09d2 From 277d32a36cba0b42c9c6836ff07f9b978566e95c Mon Sep 17 00:00:00 2001 From: Harald Welte Date: Sat, 23 May 2009 00:35:39 +0800 Subject: viafb: rework the I2C support in the VIA framebuffer driver This patch changes the way how the various I2C busses are used internally inside the viafb driver: Previosuly, only a single i2c_adapter was created, even though two different hardware I2C busses are accessed: A structure member in a global variable was modified to indicate the bus to be used. Now, all existing hardware busses are registered with the i2c core, and the viafb_i2c_{read,write}byte[s]() function take the adapter number as function call parameter, rather than referring to the global structure member. [jc: even more painful merge with mainline changes ->2.6.34] [jc: painful merge with OLPC changes] Cc: Florian Tobias Schandinat Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Signed-off-by: Harald Welte Signed-off-by: Jonathan Corbet --- drivers/video/via/dvi.c | 35 ++++----- drivers/video/via/lcd.c | 19 ++--- drivers/video/via/via_i2c.c | 171 +++++++++++++++++++++++++++---------------- drivers/video/via/via_i2c.h | 43 +++++++---- drivers/video/via/viafbdev.c | 6 +- drivers/video/via/viafbdev.h | 4 +- drivers/video/via/vt1636.c | 36 +++++---- drivers/video/via/vt1636.h | 2 +- 8 files changed, 182 insertions(+), 134 deletions(-) (limited to 'drivers/video/via/lcd.c') diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index abe59b8c7a0..be513701e4e 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -96,7 +96,7 @@ int viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; viaparinfo->chip_info-> tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; - viaparinfo->chip_info->tmds_chip_info.i2c_port = I2CPORTINDEX; + viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_31; if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { /* * Currently only support 12bits,dual edge,add 24bits mode later @@ -110,7 +110,7 @@ int viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info->tmds_chip_info.i2c_port); return OK; } else { - viaparinfo->chip_info->tmds_chip_info.i2c_port = GPIOPORTINDEX; + viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_2C; if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { tmds_register_write(0x08, 0x3b); @@ -160,32 +160,26 @@ int viafb_tmds_trasmitter_identify(void) static void tmds_register_write(int index, u8 data) { - viaparinfo->shared->i2c_stuff.i2c_port = - viaparinfo->chip_info->tmds_chip_info.i2c_port; - - viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info. - tmds_chip_slave_addr, index, - data); + viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, + viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + index, data); } static int tmds_register_read(int index) { u8 data; - viaparinfo->shared->i2c_stuff.i2c_port = - viaparinfo->chip_info->tmds_chip_info.i2c_port; - viafb_i2c_readbyte((u8) viaparinfo->chip_info-> - tmds_chip_info.tmds_chip_slave_addr, - (u8) index, &data); + viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port, + (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + (u8) index, &data); return data; } static int tmds_register_read_bytes(int index, u8 *buff, int buff_len) { - viaparinfo->shared->i2c_stuff.i2c_port = - viaparinfo->chip_info->tmds_chip_info.i2c_port; - viafb_i2c_readbytes((u8) viaparinfo->chip_info->tmds_chip_info. - tmds_chip_slave_addr, (u8) index, buff, buff_len); + viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port, + (u8) viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr, + (u8) index, buff, buff_len); return 0; } @@ -541,9 +535,10 @@ void viafb_dvi_enable(void) else data = 0x37; viafb_i2c_writebyte(viaparinfo->chip_info-> - tmds_chip_info. - tmds_chip_slave_addr, - 0x08, data); + tmds_chip_info.i2c_port, + viaparinfo->chip_info-> + tmds_chip_info.tmds_chip_slave_addr, + 0x08, data); } } } diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 09020f0b2d2..e19441d9e49 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -172,18 +172,16 @@ static bool lvds_identify_integratedlvds(void) int viafb_lvds_trasmitter_identify(void) { - viaparinfo->shared->i2c_stuff.i2c_port = I2CPORTINDEX; - if (viafb_lvds_identify_vt1636()) { - viaparinfo->chip_info->lvds_chip_info.i2c_port = I2CPORTINDEX; + if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_31)) { + viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_I2C_ADAP_31; DEBUG_MSG(KERN_INFO - "Found VIA VT1636 LVDS on port i2c 0x31 \n"); + "Found VIA VT1636 LVDS on port i2c 0x31\n"); } else { - viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; - if (viafb_lvds_identify_vt1636()) { + if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_2C)) { viaparinfo->chip_info->lvds_chip_info.i2c_port = - GPIOPORTINDEX; + VIA_I2C_ADAP_2C; DEBUG_MSG(KERN_INFO - "Found VIA VT1636 LVDS on port gpio 0x2c \n"); + "Found VIA VT1636 LVDS on port gpio 0x2c\n"); } } @@ -421,9 +419,8 @@ static int lvds_register_read(int index) { u8 data; - viaparinfo->shared->i2c_stuff.i2c_port = GPIOPORTINDEX; - viafb_i2c_readbyte((u8) viaparinfo->chip_info-> - lvds_chip_info.lvds_chip_slave_addr, + viafb_i2c_readbyte(VIA_I2C_ADAP_2C, + (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, (u8) index, &data); return data; } diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 15543e96824..8f8e0bf0cf9 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. * This program is free software; you can redistribute it and/or @@ -24,40 +24,44 @@ static void via_i2c_setscl(void *data, int state) { u8 val; - struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; + struct via_i2c_adap_cfg *adap_data = data; - val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; + printk(KERN_DEBUG "reading index 0x%02x from IO 0x%x\n", + adap_data->ioport_index, adap_data->io_port); + val = viafb_read_reg(adap_data->io_port, + adap_data->ioport_index) & 0xF0; if (state) val |= 0x20; else val &= ~0x20; - switch (via_i2c_chan->i2c_port) { - case I2CPORTINDEX: + switch (adap_data->type) { + case VIA_I2C_I2C: val |= 0x01; break; - case GPIOPORTINDEX: + case VIA_I2C_GPIO: val |= 0x80; break; default: - DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); + DEBUG_MSG("viafb_i2c: specify wrong i2c type.\n"); } - viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); + viafb_write_reg(adap_data->ioport_index, + adap_data->io_port, val); } static int via_i2c_getscl(void *data) { - struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; + struct via_i2c_adap_cfg *adap_data = data; - if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x08) + if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08) return 1; return 0; } static int via_i2c_getsda(void *data) { - struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; + struct via_i2c_adap_cfg *adap_data = data; - if (viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0x04) + if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04) return 1; return 0; } @@ -65,27 +69,29 @@ static int via_i2c_getsda(void *data) static void via_i2c_setsda(void *data, int state) { u8 val; - struct via_i2c_stuff *via_i2c_chan = (struct via_i2c_stuff *)data; + struct via_i2c_adap_cfg *adap_data = data; - val = viafb_read_reg(VIASR, via_i2c_chan->i2c_port) & 0xF0; + val = viafb_read_reg(adap_data->io_port, + adap_data->ioport_index) & 0xF0; if (state) val |= 0x10; else val &= ~0x10; - switch (via_i2c_chan->i2c_port) { - case I2CPORTINDEX: + switch (adap_data->type) { + case VIA_I2C_I2C: val |= 0x01; break; - case GPIOPORTINDEX: + case VIA_I2C_GPIO: val |= 0x40; break; default: - DEBUG_MSG("via_i2c: specify wrong i2c port.\n"); + DEBUG_MSG("viafb_i2c: specify wrong i2c type.\n"); } - viafb_write_reg(via_i2c_chan->i2c_port, VIASR, val); + viafb_write_reg(adap_data->ioport_index, + adap_data->io_port, val); } -int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) +int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) { u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -97,12 +103,11 @@ int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata) mm1[0] = index; msgs[0].len = 1; msgs[1].len = 1; msgs[0].buf = mm1; msgs[1].buf = pdata; - i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); - - return 0; + return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, + msgs, 2); } -int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) +int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) { u8 msg[2] = { index, data }; struct i2c_msg msgs; @@ -111,10 +116,11 @@ int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data) msgs.addr = slave_addr / 2; msgs.len = 2; msgs.buf = msg; - return i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, &msgs, 1); + return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, + &msgs, 1); } -int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) +int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) { u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -125,53 +131,88 @@ int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len) mm1[0] = index; msgs[0].len = 1; msgs[1].len = buff_len; msgs[0].buf = mm1; msgs[1].buf = buff; - i2c_transfer(&viaparinfo->shared->i2c_stuff.adapter, msgs, 2); - return 0; + return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, + msgs, 2); } -int viafb_create_i2c_bus(void *viapar) +static int create_i2c_bus(struct i2c_adapter *adapter, + struct i2c_algo_bit_data *algo, + struct via_i2c_adap_cfg *adap_cfg, + struct pci_dev *pdev) { - int ret; - struct via_i2c_stuff *i2c_stuff = - &((struct viafb_par *)viapar)->shared->i2c_stuff; - - strcpy(i2c_stuff->adapter.name, "via_i2c"); - i2c_stuff->i2c_port = 0x0; - i2c_stuff->adapter.owner = THIS_MODULE; - i2c_stuff->adapter.id = 0x01FFFF; - i2c_stuff->adapter.class = 0; - i2c_stuff->adapter.algo_data = &i2c_stuff->algo; - i2c_stuff->adapter.dev.parent = NULL; - i2c_stuff->algo.setsda = via_i2c_setsda; - i2c_stuff->algo.setscl = via_i2c_setscl; - i2c_stuff->algo.getsda = via_i2c_getsda; - i2c_stuff->algo.getscl = via_i2c_getscl; - i2c_stuff->algo.udelay = 40; - i2c_stuff->algo.timeout = 20; - i2c_stuff->algo.data = i2c_stuff; - - i2c_set_adapdata(&i2c_stuff->adapter, i2c_stuff); + printk(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg); + + algo->setsda = via_i2c_setsda; + algo->setscl = via_i2c_setscl; + algo->getsda = via_i2c_getsda; + algo->getscl = via_i2c_getscl; + algo->udelay = 40; + algo->timeout = 20; + algo->data = adap_cfg; + + sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", + adap_cfg->ioport_index); + adapter->owner = THIS_MODULE; + adapter->id = 0x01FFFF; + adapter->class = I2C_CLASS_DDC; + adapter->algo_data = algo; + if (pdev) + adapter->dev.parent = &pdev->dev; + else + adapter->dev.parent = NULL; + /* i2c_set_adapdata(adapter, adap_cfg); */ /* Raise SCL and SDA */ - i2c_stuff->i2c_port = I2CPORTINDEX; - via_i2c_setsda(i2c_stuff, 1); - via_i2c_setscl(i2c_stuff, 1); - - i2c_stuff->i2c_port = GPIOPORTINDEX; - via_i2c_setsda(i2c_stuff, 1); - via_i2c_setscl(i2c_stuff, 1); + via_i2c_setsda(adap_cfg, 1); + via_i2c_setscl(adap_cfg, 1); udelay(20); - ret = i2c_bit_add_bus(&i2c_stuff->adapter); - if (ret == 0) - DEBUG_MSG("I2C bus %s registered.\n", i2c_stuff->adapter.name); - else - DEBUG_MSG("Failed to register I2C bus %s.\n", - i2c_stuff->adapter.name); - return ret; + return i2c_bit_add_bus(adapter); +} + +static struct via_i2c_adap_cfg adap_configs[] = { + [VIA_I2C_ADAP_26] = { VIA_I2C_I2C, VIASR, 0x26 }, + [VIA_I2C_ADAP_31] = { VIA_I2C_I2C, VIASR, 0x31 }, + [VIA_I2C_ADAP_25] = { VIA_I2C_GPIO, VIASR, 0x25 }, + [VIA_I2C_ADAP_2C] = { VIA_I2C_GPIO, VIASR, 0x2c }, + [VIA_I2C_ADAP_3D] = { VIA_I2C_GPIO, VIASR, 0x3d }, + { 0, 0, 0 } +}; + +int viafb_create_i2c_busses(struct viafb_par *viapar) +{ + int i, ret; + + for (i = 0; i < VIAFB_NUM_I2C; i++) { + struct via_i2c_adap_cfg *adap_cfg = &adap_configs[i]; + struct via_i2c_stuff *i2c_stuff = &viapar->shared->i2c_stuff[i]; + + if (adap_cfg->type == 0) + break; + + ret = create_i2c_bus(&i2c_stuff->adapter, + &i2c_stuff->algo, adap_cfg, + NULL); /* FIXME: PCIDEV */ + if (ret < 0) { + printk(KERN_ERR "viafb: cannot create i2c bus %u:%d\n", + i, ret); + /* FIXME: properly release previous busses */ + return ret; + } + } + + return 0; } -void viafb_delete_i2c_buss(void *par) +void viafb_delete_i2c_busses(struct viafb_par *par) { - i2c_del_adapter(&((struct viafb_par *)par)->shared->i2c_stuff.adapter); + int i; + + for (i = 0; i < ARRAY_SIZE(par->shared->i2c_stuff); i++) { + struct via_i2c_stuff *i2c_stuff = &par->shared->i2c_stuff[i]; + /* only remove those entries in the array that we've + * actually used (and thus initialized algo_data) */ + if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo) + i2c_del_adapter(&i2c_stuff->adapter); + } } diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h index 3a13242a315..00ed9788684 100644 --- a/drivers/video/via/via_i2c.h +++ b/drivers/video/via/via_i2c.h @@ -1,5 +1,5 @@ /* - * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. * This program is free software; you can redistribute it and/or @@ -24,23 +24,38 @@ #include #include +enum via_i2c_type { + VIA_I2C_NONE, + VIA_I2C_I2C, + VIA_I2C_GPIO, +}; + +/* private data for each adapter */ +struct via_i2c_adap_cfg { + enum via_i2c_type type; + u_int16_t io_port; + u_int8_t ioport_index; +}; + struct via_i2c_stuff { u16 i2c_port; /* GPIO or I2C port */ struct i2c_adapter adapter; struct i2c_algo_bit_data algo; }; -#define I2CPORT 0x3c4 -#define I2CPORTINDEX 0x31 -#define GPIOPORT 0x3C4 -#define GPIOPORTINDEX 0x2C -#define I2C_BUS 1 -#define GPIO_BUS 2 -#define DELAYPORT 0x3C3 - -int viafb_i2c_readbyte(u8 slave_addr, u8 index, u8 *pdata); -int viafb_i2c_writebyte(u8 slave_addr, u8 index, u8 data); -int viafb_i2c_readbytes(u8 slave_addr, u8 index, u8 *buff, int buff_len); -int viafb_create_i2c_bus(void *par); -void viafb_delete_i2c_buss(void *par); +enum viafb_i2c_adap { + VIA_I2C_ADAP_26, + VIA_I2C_ADAP_31, + VIA_I2C_ADAP_25, + VIA_I2C_ADAP_2C, + VIA_I2C_ADAP_3D, +}; + +int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata); +int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data); +int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len); + +struct viafb_par; +int viafb_create_i2c_busses(struct viafb_par *par); +void viafb_delete_i2c_busses(struct viafb_par *par); #endif /* __VIA_I2C_H__ */ diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 8955ab4caac..fa1004997c6 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -1775,7 +1775,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, viafb_dual_fb = 0; /* Set up I2C bus stuff */ - rc = viafb_create_i2c_bus(viaparinfo); + rc = viafb_create_i2c_busses(viaparinfo); if (rc) goto out_fb_release; @@ -1964,7 +1964,7 @@ out_fb1_release: out_unmap_screen: iounmap(viafbinfo->screen_base); out_delete_i2c: - viafb_delete_i2c_buss(viaparinfo); + viafb_delete_i2c_busses(viaparinfo); out_fb_release: framebuffer_release(viafbinfo); return rc; @@ -1980,7 +1980,7 @@ static void __devexit via_pci_remove(struct pci_dev *pdev) iounmap((void *)viafbinfo->screen_base); iounmap(viaparinfo->shared->engine_mmio); - viafb_delete_i2c_buss(viaparinfo); + viafb_delete_i2c_busses(viaparinfo); framebuffer_release(viafbinfo); if (viafb_dual_fb) diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 61b5953cd15..4bc00ec8fb1 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -37,11 +37,13 @@ #define VERSION_OS 0 /* 0: for 32 bits OS, 1: for 64 bits OS */ #define VERSION_MINOR 4 +#define VIAFB_NUM_I2C 5 + struct viafb_shared { struct proc_dir_entry *proc_entry; /*viafb proc entry */ /* I2C stuff */ - struct via_i2c_stuff i2c_stuff; + struct via_i2c_stuff i2c_stuff[VIAFB_NUM_I2C]; /* All the information will be needed to set engine */ struct tmds_setting_information tmds_setting_info; diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index a6b37494e79..4589c6e73c5 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c @@ -27,9 +27,8 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information { u8 data; - viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; - viafb_i2c_readbyte(plvds_chip_info->lvds_chip_slave_addr, index, &data); - + viafb_i2c_readbyte(plvds_chip_info->i2c_port, + plvds_chip_info->lvds_chip_slave_addr, index, &data); return data; } @@ -39,14 +38,13 @@ void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information { int index, data; - viaparinfo->shared->i2c_stuff.i2c_port = plvds_chip_info->i2c_port; - index = io_data.Index; data = viafb_gpio_i2c_read_lvds(plvds_setting_info, plvds_chip_info, index); data = (data & (~io_data.Mask)) | io_data.Data; - viafb_i2c_writebyte(plvds_chip_info->lvds_chip_slave_addr, index, data); + viafb_i2c_writebyte(plvds_chip_info->i2c_port, + plvds_chip_info->lvds_chip_slave_addr, index, data); } void viafb_init_lvds_vt1636(struct lvds_setting_information @@ -159,7 +157,7 @@ void viafb_disable_lvds_vt1636(struct lvds_setting_information } } -bool viafb_lvds_identify_vt1636(void) +bool viafb_lvds_identify_vt1636(u8 i2c_adapter) { u8 Buffer[2]; @@ -170,23 +168,23 @@ bool viafb_lvds_identify_vt1636(void) VT1636_LVDS_I2C_ADDR; /* Check vendor ID first: */ - viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. - lvds_chip_slave_addr, - 0x00, &Buffer[0]); - viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. - lvds_chip_slave_addr, - 0x01, &Buffer[1]); + viafb_i2c_readbyte(i2c_adapter, + (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, + 0x00, &Buffer[0]); + viafb_i2c_readbyte(i2c_adapter, + (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, + 0x01, &Buffer[1]); if (!((Buffer[0] == 0x06) && (Buffer[1] == 0x11))) return false; /* Check Chip ID: */ - viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. - lvds_chip_slave_addr, - 0x02, &Buffer[0]); - viafb_i2c_readbyte((u8) viaparinfo->chip_info->lvds_chip_info. - lvds_chip_slave_addr, - 0x03, &Buffer[1]); + viafb_i2c_readbyte(i2c_adapter, + (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, + 0x02, &Buffer[0]); + viafb_i2c_readbyte(i2c_adapter, + (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, + 0x03, &Buffer[1]); if ((Buffer[0] == 0x45) && (Buffer[1] == 0x33)) { viaparinfo->chip_info->lvds_chip_info.lvds_chip_name = VT1636_LVDS; diff --git a/drivers/video/via/vt1636.h b/drivers/video/via/vt1636.h index 2a150c58c7e..4c1314e5746 100644 --- a/drivers/video/via/vt1636.h +++ b/drivers/video/via/vt1636.h @@ -22,7 +22,7 @@ #ifndef _VT1636_H_ #define _VT1636_H_ #include "chip.h" -bool viafb_lvds_identify_vt1636(void); +bool viafb_lvds_identify_vt1636(u8 i2c_adapter); void viafb_init_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info); void viafb_enable_lvds_vt1636(struct lvds_setting_information -- cgit v1.2.3-70-g09d2 From f045f77bc0bf238a871b10bea9e425329a8e4abc Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Tue, 1 Dec 2009 20:29:39 -0700 Subject: viafb: Move core stuff into via-core.c The first step toward turning viafb into a multifunction driver. This patch creates a new via-core.c file which serves as the main PCI driver; everything else comes below that. Some work has been done to rationalize the i2c drivers in this new scheme. Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Cc: Harald Welte Acked-by: Florian Tobias Schandinat Signed-off-by: Jonathan Corbet --- drivers/video/via/Makefile | 2 +- drivers/video/via/dvi.c | 4 +- drivers/video/via/global.h | 1 + drivers/video/via/lcd.c | 10 ++-- drivers/video/via/via-core.c | 116 +++++++++++++++++++++++++++++++++++++++++++ drivers/video/via/via-core.h | 55 ++++++++++++++++++++ drivers/video/via/via_i2c.c | 74 ++++++++++++--------------- drivers/video/via/via_i2c.h | 26 ++-------- drivers/video/via/viafbdev.c | 69 ++++++------------------- drivers/video/via/viafbdev.h | 17 +++++-- 10 files changed, 242 insertions(+), 132 deletions(-) create mode 100644 drivers/video/via/via-core.c create mode 100644 drivers/video/via/via-core.h (limited to 'drivers/video/via/lcd.c') diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index eeed238ad6a..aec3f8b24a9 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile @@ -4,4 +4,4 @@ obj-$(CONFIG_FB_VIA) += viafb.o -viafb-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 +viafb-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 via-core.o diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index be513701e4e..e357c4d1cd0 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -96,7 +96,7 @@ int viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS; viaparinfo->chip_info-> tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; - viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_31; + viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { /* * Currently only support 12bits,dual edge,add 24bits mode later @@ -110,7 +110,7 @@ int viafb_tmds_trasmitter_identify(void) viaparinfo->chip_info->tmds_chip_info.i2c_port); return OK; } else { - viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_I2C_ADAP_2C; + viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C; if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { tmds_register_write(0x08, 0x3b); diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 8d95d5fd138..be48e73da04 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -35,6 +35,7 @@ #include "debug.h" +#include "via-core.h" #include "viafbdev.h" #include "chip.h" #include "accel.h" diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index e19441d9e49..8ef60c035fa 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -172,14 +172,14 @@ static bool lvds_identify_integratedlvds(void) int viafb_lvds_trasmitter_identify(void) { - if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_31)) { - viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_I2C_ADAP_31; + if (viafb_lvds_identify_vt1636(VIA_PORT_31)) { + viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31; DEBUG_MSG(KERN_INFO "Found VIA VT1636 LVDS on port i2c 0x31\n"); } else { - if (viafb_lvds_identify_vt1636(VIA_I2C_ADAP_2C)) { + if (viafb_lvds_identify_vt1636(VIA_PORT_2C)) { viaparinfo->chip_info->lvds_chip_info.i2c_port = - VIA_I2C_ADAP_2C; + VIA_PORT_2C; DEBUG_MSG(KERN_INFO "Found VIA VT1636 LVDS on port gpio 0x2c\n"); } @@ -419,7 +419,7 @@ static int lvds_register_read(int index) { u8 data; - viafb_i2c_readbyte(VIA_I2C_ADAP_2C, + viafb_i2c_readbyte(VIA_PORT_2C, (u8) viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr, (u8) index, &data); return data; diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c new file mode 100644 index 00000000000..e7201470cf3 --- /dev/null +++ b/drivers/video/via/via-core.c @@ -0,0 +1,116 @@ +/* + * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2009 Jonathan Corbet + */ + +/* + * Core code for the Via multifunction framebuffer device. + */ +#include +#include +#include "global.h" /* Includes everything under the sun */ + +/* + * The default port config. + */ +static struct via_port_cfg adap_configs[] = { + [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_OFF, VIASR, 0x26 }, + [VIA_PORT_31] = { VIA_PORT_I2C, VIA_MODE_I2C, VIASR, 0x31 }, + [VIA_PORT_25] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x25 }, + [VIA_PORT_2C] = { VIA_PORT_GPIO, VIA_MODE_I2C, VIASR, 0x2c }, + [VIA_PORT_3D] = { VIA_PORT_GPIO, VIA_MODE_GPIO, VIASR, 0x3d }, + { 0, 0, 0, 0 } +}; + + +static int __devinit via_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) +{ + int ret; + + ret = pci_enable_device(pdev); + if (ret) + return ret; + /* + * Create the I2C busses. Bailing out on failure seems extreme, + * but that's what the code did before. + */ + ret = viafb_create_i2c_busses(adap_configs); + if (ret) + goto out_disable; + /* + * Set up the framebuffer. + */ + ret = via_fb_pci_probe(pdev, ent); + if (ret) + goto out_i2c; + return 0; + +out_i2c: + viafb_delete_i2c_busses(); +out_disable: + pci_disable_device(pdev); + return ret; +} + +static void __devexit via_pci_remove(struct pci_dev *pdev) +{ + viafb_delete_i2c_busses(); + via_fb_pci_remove(pdev); + pci_disable_device(pdev); +} + + +static struct pci_device_id via_pci_table[] __devinitdata = { + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID), + .driver_data = UNICHROME_CLE266 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID), + .driver_data = UNICHROME_PM800 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID), + .driver_data = UNICHROME_K400 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID), + .driver_data = UNICHROME_K800 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID), + .driver_data = UNICHROME_CN700 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID), + .driver_data = UNICHROME_K8M890 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID), + .driver_data = UNICHROME_CX700 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID), + .driver_data = UNICHROME_P4M900 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID), + .driver_data = UNICHROME_CN750 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID), + .driver_data = UNICHROME_VX800 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), + .driver_data = UNICHROME_VX855 }, + { } +}; +MODULE_DEVICE_TABLE(pci, via_pci_table); + +static struct pci_driver via_driver = { + .name = "viafb", + .id_table = via_pci_table, + .probe = via_pci_probe, + .remove = __devexit_p(via_pci_remove), +}; + +static int __init via_core_init(void) +{ + int ret; + + ret = viafb_init(); + if (ret) + return ret; + return pci_register_driver(&via_driver); +} + +static void __exit via_core_exit(void) +{ + pci_unregister_driver(&via_driver); + viafb_exit(); +} + +module_init(via_core_init); +module_exit(via_core_exit); diff --git a/drivers/video/via/via-core.h b/drivers/video/via/via-core.h new file mode 100644 index 00000000000..1c2fb06b77a --- /dev/null +++ b/drivers/video/via/via-core.h @@ -0,0 +1,55 @@ +/* + * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2009 Jonathan Corbet + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __VIA_CORE_H__ +#define __VIA_CORE_H__ +/* + * A description of each known serial I2C/GPIO port. + */ +enum via_port_type { + VIA_PORT_NONE = 0, + VIA_PORT_I2C, + VIA_PORT_GPIO, +}; + +enum via_port_mode { + VIA_MODE_OFF = 0, + VIA_MODE_I2C, /* Used as I2C port */ + VIA_MODE_GPIO, /* Two GPIO ports */ +}; + +enum viafb_i2c_adap { + VIA_PORT_26 = 0, + VIA_PORT_31, + VIA_PORT_25, + VIA_PORT_2C, + VIA_PORT_3D, +}; +#define VIAFB_NUM_PORTS 5 + +struct via_port_cfg { + enum via_port_type type; + enum via_port_mode mode; + u_int16_t io_port; + u_int8_t ioport_index; +}; +#endif /* __VIA_CORE_H__ */ diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index b5253e3099f..47882928156 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -21,13 +21,18 @@ #include "global.h" +/* + * There can only be one set of these, so there's no point in having + * them be dynamically allocated... + */ +#define VIAFB_NUM_I2C 5 +static struct via_i2c_stuff via_i2c_par[VIAFB_NUM_I2C]; + static void via_i2c_setscl(void *data, int state) { u8 val; - struct via_i2c_adap_cfg *adap_data = data; + struct via_port_cfg *adap_data = data; - DEBUG_MSG(KERN_DEBUG "reading index 0x%02x from IO 0x%x\n", - adap_data->ioport_index, adap_data->io_port); val = viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0xF0; if (state) @@ -35,10 +40,10 @@ static void via_i2c_setscl(void *data, int state) else val &= ~0x20; switch (adap_data->type) { - case VIA_I2C_I2C: + case VIA_PORT_I2C: val |= 0x01; break; - case VIA_I2C_GPIO: + case VIA_PORT_GPIO: val |= 0x80; break; default: @@ -50,7 +55,7 @@ static void via_i2c_setscl(void *data, int state) static int via_i2c_getscl(void *data) { - struct via_i2c_adap_cfg *adap_data = data; + struct via_port_cfg *adap_data = data; if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x08) return 1; @@ -59,7 +64,7 @@ static int via_i2c_getscl(void *data) static int via_i2c_getsda(void *data) { - struct via_i2c_adap_cfg *adap_data = data; + struct via_port_cfg *adap_data = data; if (viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0x04) return 1; @@ -69,7 +74,7 @@ static int via_i2c_getsda(void *data) static void via_i2c_setsda(void *data, int state) { u8 val; - struct via_i2c_adap_cfg *adap_data = data; + struct via_port_cfg *adap_data = data; val = viafb_read_reg(adap_data->io_port, adap_data->ioport_index) & 0xF0; @@ -78,10 +83,10 @@ static void via_i2c_setsda(void *data, int state) else val &= ~0x10; switch (adap_data->type) { - case VIA_I2C_I2C: + case VIA_PORT_I2C: val |= 0x01; break; - case VIA_I2C_GPIO: + case VIA_PORT_GPIO: val |= 0x40; break; default: @@ -103,8 +108,7 @@ int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) mm1[0] = index; msgs[0].len = 1; msgs[1].len = 1; msgs[0].buf = mm1; msgs[1].buf = pdata; - return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, - msgs, 2); + return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); } int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) @@ -116,8 +120,7 @@ int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) msgs.addr = slave_addr / 2; msgs.len = 2; msgs.buf = msg; - return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, - &msgs, 1); + return i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); } int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) @@ -131,13 +134,12 @@ int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len mm1[0] = index; msgs[0].len = 1; msgs[1].len = buff_len; msgs[0].buf = mm1; msgs[1].buf = buff; - return i2c_transfer(&viaparinfo->shared->i2c_stuff[adap].adapter, - msgs, 2); + return i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); } static int create_i2c_bus(struct i2c_adapter *adapter, struct i2c_algo_bit_data *algo, - struct via_i2c_adap_cfg *adap_cfg, + struct via_port_cfg *adap_cfg, struct pci_dev *pdev) { DEBUG_MSG(KERN_DEBUG "viafb: creating bus adap=0x%p, algo_bit_data=0x%p, adap_cfg=0x%p\n", adapter, algo, adap_cfg); @@ -170,31 +172,15 @@ static int create_i2c_bus(struct i2c_adapter *adapter, return i2c_bit_add_bus(adapter); } -/* - * By default, we only activate busses on ports 2c and 31 to avoid - * conflicts with other possible users; that default can be changed - * below. - */ -static struct via_i2c_adap_cfg adap_configs[] = { - [VIA_I2C_ADAP_26] = { VIA_I2C_I2C, VIASR, 0x26, 0 }, - [VIA_I2C_ADAP_31] = { VIA_I2C_I2C, VIASR, 0x31, 1 }, - [VIA_I2C_ADAP_25] = { VIA_I2C_GPIO, VIASR, 0x25, 0 }, - [VIA_I2C_ADAP_2C] = { VIA_I2C_GPIO, VIASR, 0x2c, 1 }, - [VIA_I2C_ADAP_3D] = { VIA_I2C_GPIO, VIASR, 0x3d, 0 }, - { 0, 0, 0, 0 } -}; - -int viafb_create_i2c_busses(struct viafb_par *viapar) +int viafb_create_i2c_busses(struct via_port_cfg *configs) { int i, ret; - for (i = 0; i < VIAFB_NUM_I2C; i++) { - struct via_i2c_adap_cfg *adap_cfg = &adap_configs[i]; - struct via_i2c_stuff *i2c_stuff = &viapar->shared->i2c_stuff[i]; + for (i = 0; i < VIAFB_NUM_PORTS; i++) { + struct via_port_cfg *adap_cfg = configs++; + struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i]; - if (adap_cfg->type == 0) - break; - if (!adap_cfg->is_active) + if (adap_cfg->type == 0 || adap_cfg->mode != VIA_MODE_I2C) continue; ret = create_i2c_bus(&i2c_stuff->adapter, @@ -211,14 +197,16 @@ int viafb_create_i2c_busses(struct viafb_par *viapar) return 0; } -void viafb_delete_i2c_busses(struct viafb_par *par) +void viafb_delete_i2c_busses(void) { int i; - for (i = 0; i < ARRAY_SIZE(par->shared->i2c_stuff); i++) { - struct via_i2c_stuff *i2c_stuff = &par->shared->i2c_stuff[i]; - /* only remove those entries in the array that we've - * actually used (and thus initialized algo_data) */ + for (i = 0; i < VIAFB_NUM_PORTS; i++) { + struct via_i2c_stuff *i2c_stuff = &via_i2c_par[i]; + /* + * Only remove those entries in the array that we've + * actually used (and thus initialized algo_data) + */ if (i2c_stuff->adapter.algo_data == &i2c_stuff->algo) i2c_del_adapter(&i2c_stuff->adapter); } diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h index 73d682fcf26..00932914b4e 100644 --- a/drivers/video/via/via_i2c.h +++ b/drivers/video/via/via_i2c.h @@ -24,39 +24,19 @@ #include #include -enum via_i2c_type { - VIA_I2C_NONE, - VIA_I2C_I2C, - VIA_I2C_GPIO, -}; - -/* private data for each adapter */ -struct via_i2c_adap_cfg { - enum via_i2c_type type; - u_int16_t io_port; - u_int8_t ioport_index; - u8 is_active; -}; - struct via_i2c_stuff { u16 i2c_port; /* GPIO or I2C port */ struct i2c_adapter adapter; struct i2c_algo_bit_data algo; }; -enum viafb_i2c_adap { - VIA_I2C_ADAP_26, - VIA_I2C_ADAP_31, - VIA_I2C_ADAP_25, - VIA_I2C_ADAP_2C, - VIA_I2C_ADAP_3D, -}; int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata); int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data); int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len); struct viafb_par; -int viafb_create_i2c_busses(struct viafb_par *par); -void viafb_delete_i2c_busses(struct viafb_par *par); +int viafb_create_i2c_busses(struct via_port_cfg *cfg); +void viafb_delete_i2c_busses(void); +struct i2c_adapter *viafb_find_adapter(enum viafb_i2c_adap which); #endif /* __VIA_I2C_H__ */ diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index fa1004997c6..17a874f6ea1 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -1731,8 +1731,9 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres) return 0; } -static int __devinit via_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) + +int __devinit via_fb_pci_probe(struct pci_dev *pdev, + const struct pci_device_id *ent) { u32 default_xres, default_yres; struct VideoModeTable *vmode_entry; @@ -1764,6 +1765,7 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, &viaparinfo->shared->lvds_setting_info2; viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info; viaparinfo->chip_info = &viaparinfo->shared->chip_info; + spin_lock_init(&viaparinfo->reg_lock); if (viafb_dual_fb) viafb_SAMM_ON = 1; @@ -1774,26 +1776,21 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, if (!viafb_SAMM_ON) viafb_dual_fb = 0; - /* Set up I2C bus stuff */ - rc = viafb_create_i2c_busses(viaparinfo); - if (rc) - goto out_fb_release; - viafb_init_chip_info(pdev, ent); viaparinfo->fbmem = pci_resource_start(pdev, 0); viaparinfo->memsize = viafb_get_fb_size_from_pci(); if (viaparinfo->memsize < 0) { rc = viaparinfo->memsize; - goto out_delete_i2c; + goto out_fb_release; } viaparinfo->fbmem_free = viaparinfo->memsize; viaparinfo->fbmem_used = 0; viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem, viaparinfo->memsize); if (!viafbinfo->screen_base) { - printk(KERN_INFO "ioremap failed\n"); + printk(KERN_ERR "ioremap of fbmem failed\n"); rc = -ENOMEM; - goto out_delete_i2c; + goto out_fb_release; } viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1); @@ -1963,14 +1960,12 @@ out_fb1_release: framebuffer_release(viafbinfo1); out_unmap_screen: iounmap(viafbinfo->screen_base); -out_delete_i2c: - viafb_delete_i2c_busses(viaparinfo); out_fb_release: framebuffer_release(viafbinfo); return rc; } -static void __devexit via_pci_remove(struct pci_dev *pdev) +void __devexit via_fb_pci_remove(struct pci_dev *pdev) { DEBUG_MSG(KERN_INFO "via_pci_remove!\n"); fb_dealloc_cmap(&viafbinfo->cmap); @@ -1980,8 +1975,6 @@ static void __devexit via_pci_remove(struct pci_dev *pdev) iounmap((void *)viafbinfo->screen_base); iounmap(viaparinfo->shared->engine_mmio); - viafb_delete_i2c_busses(viaparinfo); - framebuffer_release(viafbinfo); if (viafb_dual_fb) framebuffer_release(viafbinfo1); @@ -2062,41 +2055,10 @@ static int __init viafb_setup(char *options) } #endif -static struct pci_device_id viafb_pci_table[] __devinitdata = { - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CLE266_DID), - .driver_data = UNICHROME_CLE266 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_PM800_DID), - .driver_data = UNICHROME_PM800 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K400_DID), - .driver_data = UNICHROME_K400 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K800_DID), - .driver_data = UNICHROME_K800 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M890_DID), - .driver_data = UNICHROME_CN700 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_K8M890_DID), - .driver_data = UNICHROME_K8M890 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CX700_DID), - .driver_data = UNICHROME_CX700 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_P4M900_DID), - .driver_data = UNICHROME_P4M900 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_CN750_DID), - .driver_data = UNICHROME_CN750 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX800_DID), - .driver_data = UNICHROME_VX800 }, - { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), - .driver_data = UNICHROME_VX855 }, - { } -}; -MODULE_DEVICE_TABLE(pci, viafb_pci_table); - -static struct pci_driver viafb_driver = { - .name = "viafb", - .id_table = viafb_pci_table, - .probe = via_pci_probe, - .remove = __devexit_p(via_pci_remove), -}; - -static int __init viafb_init(void) +/* + * These are called out of via-core for now. + */ +int __init viafb_init(void) { u32 dummy; #ifndef MODULE @@ -2115,13 +2077,12 @@ static int __init viafb_init(void) printk(KERN_INFO "VIA Graphics Intergration Chipset framebuffer %d.%d initializing\n", VERSION_MAJOR, VERSION_MINOR); - return pci_register_driver(&viafb_driver); + return 0; } -static void __exit viafb_exit(void) +void __exit viafb_exit(void) { DEBUG_MSG(KERN_INFO "viafb_exit!\n"); - pci_unregister_driver(&viafb_driver); } static struct fb_ops viafb_ops = { @@ -2141,8 +2102,6 @@ static struct fb_ops viafb_ops = { .fb_sync = viafb_sync, }; -module_init(viafb_init); -module_exit(viafb_exit); #ifdef MODULE module_param(viafb_mode, charp, S_IRUSR); diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 4bc00ec8fb1..5604f27eb74 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -24,6 +24,7 @@ #include #include +#include #include "ioctl.h" #include "share.h" @@ -42,9 +43,6 @@ struct viafb_shared { struct proc_dir_entry *proc_entry; /*viafb proc entry */ - /* I2C stuff */ - struct via_i2c_stuff i2c_stuff[VIAFB_NUM_I2C]; - /* All the information will be needed to set engine */ struct tmds_setting_information tmds_setting_info; struct crt_setting_information crt_setting_info; @@ -74,6 +72,14 @@ struct viafb_par { struct viafb_shared *shared; + /* + * (jc) I believe one should use locking to protect against + * concurrent access to the device ports and registers. Thus, + * this lock. Use of it is *far* from universal, though... + * someday... + */ + spinlock_t reg_lock; + /* All the information will be needed to set engine */ /* depreciated, use the ones in shared directly */ struct tmds_setting_information *tmds_setting_info; @@ -101,4 +107,9 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, struct IODATA io_data); +int via_fb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); +void via_fb_pci_remove(struct pci_dev *pdev); +/* Temporary */ +int viafb_init(void); +void viafb_exit(void); #endif /* __VIAFBDEV_H__ */ -- cgit v1.2.3-70-g09d2 From 24b4d82e4715841848a499534ed5cb7db3d6bca3 Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Thu, 22 Apr 2010 13:48:09 -0600 Subject: viafb: Separate global and fb-specific data This patch moves data of interest into a new viafb_dev structure which describes the device as a whole; the idea here is to create a separation between what all devices may need and what the framebuffer device in particular needs. I've also made some small steps toward thinning out the global.h mess. Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Cc: Harald Welte Acked-by: Florian Tobias Schandinat Signed-off-by: Jonathan Corbet --- drivers/video/via/accel.c | 14 ++-- drivers/video/via/dvi.c | 2 + drivers/video/via/global.h | 2 - drivers/video/via/hw.c | 131 ++---------------------------- drivers/video/via/hw.h | 4 +- drivers/video/via/lcd.c | 3 +- drivers/video/via/via-core.c | 185 ++++++++++++++++++++++++++++++++++++++++++- drivers/video/via/via-core.h | 38 ++++++++- drivers/video/via/via_i2c.c | 2 + drivers/video/via/viafbdev.c | 54 ++++++------- drivers/video/via/viafbdev.h | 13 +-- drivers/video/via/vt1636.c | 2 + 12 files changed, 265 insertions(+), 185 deletions(-) (limited to 'drivers/video/via/lcd.c') diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index 0d90c859cc1..e77746857c8 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c @@ -18,6 +18,7 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "via-core.h" #include "global.h" /* @@ -321,8 +322,7 @@ int viafb_init_engine(struct fb_info *info) u32 vq_start_addr, vq_end_addr, vq_start_low, vq_end_low, vq_high, vq_len, chip_name = viapar->shared->chip_info.gfx_chip_name; - engine = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); - viapar->shared->engine_mmio = engine; + engine = viapar->shared->vdev->engine_mmio; if (!engine) { printk(KERN_WARNING "viafb_init_accel: ioremap failed, " "hardware acceleration disabled\n"); @@ -465,7 +465,7 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status) struct viafb_par *viapar = info->par; u32 temp, iga_path = viapar->iga_path; - temp = readl(viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); + temp = readl(viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE); switch (Status) { case HW_Cursor_ON: temp |= 0x1; @@ -482,7 +482,7 @@ void viafb_show_hw_cursor(struct fb_info *info, int Status) default: temp &= 0x7FFFFFFF; } - writel(temp, viapar->shared->engine_mmio + VIA_REG_CURSOR_MODE); + writel(temp, viapar->shared->vdev->engine_mmio + VIA_REG_CURSOR_MODE); } void viafb_wait_engine_idle(struct fb_info *info) @@ -490,6 +490,7 @@ void viafb_wait_engine_idle(struct fb_info *info) struct viafb_par *viapar = info->par; int loop = 0; u32 mask; + void __iomem *engine = viapar->shared->vdev->engine_mmio; switch (viapar->shared->chip_info.twod_engine) { case VIA_2D_ENG_H5: @@ -498,7 +499,7 @@ void viafb_wait_engine_idle(struct fb_info *info) VIA_3D_ENG_BUSY_M1; break; default: - while (!(readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & + while (!(readl(engine + VIA_REG_STATUS) & VIA_VR_QUEUE_BUSY) && (loop < MAXLOOP)) { loop++; cpu_relax(); @@ -507,8 +508,7 @@ void viafb_wait_engine_idle(struct fb_info *info) break; } - while ((readl(viapar->shared->engine_mmio + VIA_REG_STATUS) & mask) && - (loop < MAXLOOP)) { + while ((readl(engine + VIA_REG_STATUS) & mask) && (loop < MAXLOOP)) { loop++; cpu_relax(); } diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index e357c4d1cd0..6271b769632 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -18,6 +18,8 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "via-core.h" +#include "via_i2c.h" #include "global.h" static void tmds_register_write(int index, u8 data); diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index be48e73da04..28221a062dd 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -35,14 +35,12 @@ #include "debug.h" -#include "via-core.h" #include "viafbdev.h" #include "chip.h" #include "accel.h" #include "share.h" #include "dvi.h" #include "viamode.h" -#include "via_i2c.h" #include "hw.h" #include "lcd.h" diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 2322612fbb9..f2425ae228a 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -18,7 +18,7 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#include "via-core.h" #include "global.h" static struct pll_map pll_value[] = { @@ -526,8 +526,7 @@ static void dvi_patch_skew_dvp_low(void); static void set_dvi_output_path(int set_iga, int output_interface); static void set_lcd_output_path(int set_iga, int output_interface); static void load_fix_bit_crtc_reg(void); -static void init_gfx_chip_info(struct pci_dev *pdev, - const struct pci_device_id *pdi); +static void init_gfx_chip_info(int chip_type); static void init_tmds_chip_info(void); static void init_lvds_chip_info(void); static void device_screen_off(void); @@ -1911,10 +1910,9 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, } -void viafb_init_chip_info(struct pci_dev *pdev, - const struct pci_device_id *pdi) +void viafb_init_chip_info(int chip_type) { - init_gfx_chip_info(pdev, pdi); + init_gfx_chip_info(chip_type); init_tmds_chip_info(); init_lvds_chip_info(); @@ -1981,12 +1979,11 @@ void viafb_update_device_setting(int hres, int vres, } } -static void init_gfx_chip_info(struct pci_dev *pdev, - const struct pci_device_id *pdi) +static void init_gfx_chip_info(int chip_type) { u8 tmp; - viaparinfo->chip_info->gfx_chip_name = pdi->driver_data; + viaparinfo->chip_info->gfx_chip_name = chip_type; /* Check revision of CLE266 Chip */ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { @@ -2489,122 +2486,6 @@ static void disable_second_display_channel(void) viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); } -static u_int16_t via_function3[] = { - CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3, - CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3, - P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3, -}; - -/* Get the BIOS-configured framebuffer size from PCI configuration space - * of function 3 in the respective chipset */ -int viafb_get_fb_size_from_pci(void) -{ - int i; - u_int8_t offset = 0; - u_int32_t FBSize; - u_int32_t VideoMemSize; - - /* search for the "FUNCTION3" device in this chipset */ - for (i = 0; i < ARRAY_SIZE(via_function3); i++) { - struct pci_dev *pdev; - - pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i], - NULL); - if (!pdev) - continue; - - DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device); - - switch (pdev->device) { - case CLE266_FUNCTION3: - case KM400_FUNCTION3: - offset = 0xE0; - break; - case CN400_FUNCTION3: - case CN700_FUNCTION3: - case CX700_FUNCTION3: - case KM800_FUNCTION3: - case KM890_FUNCTION3: - case P4M890_FUNCTION3: - case P4M900_FUNCTION3: - case VX800_FUNCTION3: - case VX855_FUNCTION3: - /*case CN750_FUNCTION3: */ - offset = 0xA0; - break; - } - - if (!offset) - break; - - pci_read_config_dword(pdev, offset, &FBSize); - pci_dev_put(pdev); - } - - if (!offset) { - printk(KERN_ERR "cannot determine framebuffer size\n"); - return -EIO; - } - - FBSize = FBSize & 0x00007000; - DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize); - - if (viaparinfo->chip_info->gfx_chip_name < UNICHROME_CX700) { - switch (FBSize) { - case 0x00004000: - VideoMemSize = (16 << 20); /*16M */ - break; - - case 0x00005000: - VideoMemSize = (32 << 20); /*32M */ - break; - - case 0x00006000: - VideoMemSize = (64 << 20); /*64M */ - break; - - default: - VideoMemSize = (32 << 20); /*32M */ - break; - } - } else { - switch (FBSize) { - case 0x00001000: - VideoMemSize = (8 << 20); /*8M */ - break; - - case 0x00002000: - VideoMemSize = (16 << 20); /*16M */ - break; - - case 0x00003000: - VideoMemSize = (32 << 20); /*32M */ - break; - - case 0x00004000: - VideoMemSize = (64 << 20); /*64M */ - break; - - case 0x00005000: - VideoMemSize = (128 << 20); /*128M */ - break; - - case 0x00006000: - VideoMemSize = (256 << 20); /*256M */ - break; - - case 0x00007000: /* Only on VX855/875 */ - VideoMemSize = (512 << 20); /*512M */ - break; - - default: - VideoMemSize = (32 << 20); /*32M */ - break; - } - } - - return VideoMemSize; -} void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ *p_gfx_dpa_setting) diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index d6b25acd4a9..d248f4dc12e 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -900,15 +900,13 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, struct VideoModeTable *vmode_tbl1, int video_bpp1); void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, struct VideoModeTable *vmode_tbl); -void viafb_init_chip_info(struct pci_dev *pdev, - const struct pci_device_id *pdi); +void viafb_init_chip_info(int chip_type); void viafb_init_dac(int set_iga); int viafb_get_pixclock(int hres, int vres, int vmode_refresh); int viafb_get_refresh(int hres, int vres, u32 float_refresh); void viafb_update_device_setting(int hres, int vres, int bpp, int vmode_refresh, int flag); -int viafb_get_fb_size_from_pci(void); void viafb_set_iga_path(void); void viafb_set_primary_address(u32 addr); void viafb_set_secondary_address(u32 addr); diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 8ef60c035fa..04eec31aa9a 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -18,7 +18,8 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ - +#include "via-core.h" +#include "via_i2c.h" #include "global.h" #include "lcdtbl.h" diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index e7201470cf3..b77cd5c2fc9 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -7,9 +7,12 @@ /* * Core code for the Via multifunction framebuffer device. */ +#include "via-core.h" +#include "via_i2c.h" +#include "global.h" + #include #include -#include "global.h" /* Includes everything under the sun */ /* * The default port config. @@ -23,6 +26,169 @@ static struct via_port_cfg adap_configs[] = { { 0, 0, 0, 0 } }; +/* + * We currently only support one viafb device (will there ever be + * more than one?), so just declare it globally here. + */ +static struct viafb_dev global_dev; + + +/* + * Figure out how big our framebuffer memory is. Kind of ugly, + * but evidently we can't trust the information found in the + * fbdev configuration area. + */ +static u16 via_function3[] = { + CLE266_FUNCTION3, KM400_FUNCTION3, CN400_FUNCTION3, CN700_FUNCTION3, + CX700_FUNCTION3, KM800_FUNCTION3, KM890_FUNCTION3, P4M890_FUNCTION3, + P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3, +}; + +/* Get the BIOS-configured framebuffer size from PCI configuration space + * of function 3 in the respective chipset */ +static int viafb_get_fb_size_from_pci(int chip_type) +{ + int i; + u8 offset = 0; + u32 FBSize; + u32 VideoMemSize; + + /* search for the "FUNCTION3" device in this chipset */ + for (i = 0; i < ARRAY_SIZE(via_function3); i++) { + struct pci_dev *pdev; + + pdev = pci_get_device(PCI_VENDOR_ID_VIA, via_function3[i], + NULL); + if (!pdev) + continue; + + DEBUG_MSG(KERN_INFO "Device ID = %x\n", pdev->device); + + switch (pdev->device) { + case CLE266_FUNCTION3: + case KM400_FUNCTION3: + offset = 0xE0; + break; + case CN400_FUNCTION3: + case CN700_FUNCTION3: + case CX700_FUNCTION3: + case KM800_FUNCTION3: + case KM890_FUNCTION3: + case P4M890_FUNCTION3: + case P4M900_FUNCTION3: + case VX800_FUNCTION3: + case VX855_FUNCTION3: + /*case CN750_FUNCTION3: */ + offset = 0xA0; + break; + } + + if (!offset) + break; + + pci_read_config_dword(pdev, offset, &FBSize); + pci_dev_put(pdev); + } + + if (!offset) { + printk(KERN_ERR "cannot determine framebuffer size\n"); + return -EIO; + } + + FBSize = FBSize & 0x00007000; + DEBUG_MSG(KERN_INFO "FB Size = %x\n", FBSize); + + if (chip_type < UNICHROME_CX700) { + switch (FBSize) { + case 0x00004000: + VideoMemSize = (16 << 20); /*16M */ + break; + + case 0x00005000: + VideoMemSize = (32 << 20); /*32M */ + break; + + case 0x00006000: + VideoMemSize = (64 << 20); /*64M */ + break; + + default: + VideoMemSize = (32 << 20); /*32M */ + break; + } + } else { + switch (FBSize) { + case 0x00001000: + VideoMemSize = (8 << 20); /*8M */ + break; + + case 0x00002000: + VideoMemSize = (16 << 20); /*16M */ + break; + + case 0x00003000: + VideoMemSize = (32 << 20); /*32M */ + break; + + case 0x00004000: + VideoMemSize = (64 << 20); /*64M */ + break; + + case 0x00005000: + VideoMemSize = (128 << 20); /*128M */ + break; + + case 0x00006000: + VideoMemSize = (256 << 20); /*256M */ + break; + + case 0x00007000: /* Only on VX855/875 */ + VideoMemSize = (512 << 20); /*512M */ + break; + + default: + VideoMemSize = (32 << 20); /*32M */ + break; + } + } + + return VideoMemSize; +} + + +/* + * Figure out and map our MMIO regions. + */ +static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev) +{ + /* + * Hook up to the device registers. + */ + vdev->engine_start = pci_resource_start(vdev->pdev, 1); + vdev->engine_len = pci_resource_len(vdev->pdev, 1); + /* If this fails, others will notice later */ + vdev->engine_mmio = ioremap_nocache(vdev->engine_start, + vdev->engine_len); + + /* + * Likewise with I/O memory. + */ + vdev->fbmem_start = pci_resource_start(vdev->pdev, 0); + vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type); + if (vdev->fbmem_len < 0) + return vdev->fbmem_len; + vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len); + if (vdev->fbmem == NULL) + return -ENOMEM; + return 0; +} + +static void __devexit via_pci_teardown_mmio(struct viafb_dev *vdev) +{ + iounmap(vdev->fbmem); + iounmap(vdev->engine_mmio); +} + static int __devinit via_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent) @@ -32,23 +198,35 @@ static int __devinit via_pci_probe(struct pci_dev *pdev, ret = pci_enable_device(pdev); if (ret) return ret; + /* + * Global device initialization. + */ + memset(&global_dev, 0, sizeof(global_dev)); + global_dev.pdev = pdev; + global_dev.chip_type = ent->driver_data; + spin_lock_init(&global_dev.reg_lock); + ret = via_pci_setup_mmio(&global_dev); + if (ret) + goto out_disable; /* * Create the I2C busses. Bailing out on failure seems extreme, * but that's what the code did before. */ ret = viafb_create_i2c_busses(adap_configs); if (ret) - goto out_disable; + goto out_teardown; /* * Set up the framebuffer. */ - ret = via_fb_pci_probe(pdev, ent); + ret = via_fb_pci_probe(&global_dev); if (ret) goto out_i2c; return 0; out_i2c: viafb_delete_i2c_busses(); +out_teardown: + via_pci_teardown_mmio(&global_dev); out_disable: pci_disable_device(pdev); return ret; @@ -58,6 +236,7 @@ static void __devexit via_pci_remove(struct pci_dev *pdev) { viafb_delete_i2c_busses(); via_fb_pci_remove(pdev); + via_pci_teardown_mmio(&global_dev); pci_disable_device(pdev); } diff --git a/drivers/video/via/via-core.h b/drivers/video/via/via-core.h index 1c2fb06b77a..d004290dc8f 100644 --- a/drivers/video/via/via-core.h +++ b/drivers/video/via/via-core.h @@ -22,6 +22,9 @@ #ifndef __VIA_CORE_H__ #define __VIA_CORE_H__ +#include +#include + /* * A description of each known serial I2C/GPIO port. */ @@ -49,7 +52,38 @@ enum viafb_i2c_adap { struct via_port_cfg { enum via_port_type type; enum via_port_mode mode; - u_int16_t io_port; - u_int8_t ioport_index; + u16 io_port; + u8 ioport_index; }; + +/* + * This is the global viafb "device" containing stuff needed by + * all subdevs. + */ +struct viafb_dev { + struct pci_dev *pdev; + int chip_type; + /* + * Spinlock for access to device registers. Not yet + * globally used. + */ + spinlock_t reg_lock; + /* + * The framebuffer MMIO region. Little, if anything, touches + * this memory directly, and certainly nothing outside of the + * framebuffer device itself. We *do* have to be able to allocate + * chunks of this memory for other devices, though. + */ + unsigned long fbmem_start; + long fbmem_len; + void __iomem *fbmem; + /* + * The MMIO region for device registers. + */ + unsigned long engine_start; + unsigned long engine_len; + void __iomem *engine_mmio; + +}; + #endif /* __VIA_CORE_H__ */ diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 47882928156..bcf2fe61a6e 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -19,6 +19,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "via-core.h" +#include "via_i2c.h" #include "global.h" /* diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 17a874f6ea1..70ed71facd8 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -24,6 +24,7 @@ #include #define _MASTER_FILE +#include "via-core.h" #include "global.h" static char *viafb_name = "Via"; @@ -220,7 +221,7 @@ static int viafb_check_var(struct fb_var_screeninfo *var, /* Adjust var according to our driver's own table */ viafb_fill_var_timing_info(var, viafb_refresh, vmode_entry); if (info->var.accel_flags & FB_ACCELF_TEXT && - !ppar->shared->engine_mmio) + !ppar->shared->vdev->engine_mmio) info->var.accel_flags = 0; return 0; @@ -695,7 +696,7 @@ static void viafb_fillrect(struct fb_info *info, rop = 0xF0; DEBUG_MSG(KERN_DEBUG "viafb 2D engine: fillrect\n"); - if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_FILL, + if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_FILL, rect->width, rect->height, info->var.bits_per_pixel, viapar->vram_addr, info->fix.line_length, rect->dx, rect->dy, NULL, 0, 0, 0, 0, fg_color, 0, rop)) @@ -717,7 +718,7 @@ static void viafb_copyarea(struct fb_info *info, return; DEBUG_MSG(KERN_DEBUG "viafb 2D engine: copyarea\n"); - if (shared->hw_bitblt(shared->engine_mmio, VIA_BITBLT_COLOR, + if (shared->hw_bitblt(shared->vdev->engine_mmio, VIA_BITBLT_COLOR, area->width, area->height, info->var.bits_per_pixel, viapar->vram_addr, info->fix.line_length, area->dx, area->dy, NULL, viapar->vram_addr, info->fix.line_length, @@ -754,7 +755,7 @@ static void viafb_imageblit(struct fb_info *info, op = VIA_BITBLT_COLOR; DEBUG_MSG(KERN_DEBUG "viafb 2D engine: imageblit\n"); - if (shared->hw_bitblt(shared->engine_mmio, op, + if (shared->hw_bitblt(shared->vdev->engine_mmio, op, image->width, image->height, info->var.bits_per_pixel, viapar->vram_addr, info->fix.line_length, image->dx, image->dy, (u32 *)image->data, 0, 0, 0, 0, fg_color, bg_color, 0)) @@ -764,7 +765,7 @@ static void viafb_imageblit(struct fb_info *info, static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) { struct viafb_par *viapar = info->par; - void __iomem *engine = viapar->shared->engine_mmio; + void __iomem *engine = viapar->shared->vdev->engine_mmio; u32 temp, xx, yy, bg_color = 0, fg_color = 0, chip_name = viapar->shared->chip_info.gfx_chip_name; int i, j = 0, cur_size = 64; @@ -1732,8 +1733,7 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres) } -int __devinit via_fb_pci_probe(struct pci_dev *pdev, - const struct pci_device_id *ent) +int __devinit via_fb_pci_probe(struct viafb_dev *vdev) { u32 default_xres, default_yres; struct VideoModeTable *vmode_entry; @@ -1750,7 +1750,7 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev, */ viafbinfo = framebuffer_alloc(viafb_par_length + ALIGN(sizeof(struct viafb_shared), BITS_PER_LONG/8), - &pdev->dev); + &vdev->pdev->dev); if (!viafbinfo) { printk(KERN_ERR"Could not allocate memory for viafb_info.\n"); return -ENOMEM; @@ -1758,6 +1758,7 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev, viaparinfo = (struct viafb_par *)viafbinfo->par; viaparinfo->shared = viafbinfo->par + viafb_par_length; + viaparinfo->shared->vdev = vdev; viaparinfo->vram_addr = 0; viaparinfo->tmds_setting_info = &viaparinfo->shared->tmds_setting_info; viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info; @@ -1765,7 +1766,6 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev, &viaparinfo->shared->lvds_setting_info2; viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info; viaparinfo->chip_info = &viaparinfo->shared->chip_info; - spin_lock_init(&viaparinfo->reg_lock); if (viafb_dual_fb) viafb_SAMM_ON = 1; @@ -1776,25 +1776,20 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev, if (!viafb_SAMM_ON) viafb_dual_fb = 0; - viafb_init_chip_info(pdev, ent); - viaparinfo->fbmem = pci_resource_start(pdev, 0); - viaparinfo->memsize = viafb_get_fb_size_from_pci(); - if (viaparinfo->memsize < 0) { - rc = viaparinfo->memsize; - goto out_fb_release; - } + viafb_init_chip_info(vdev->chip_type); + /* + * The framebuffer will have been successfully mapped by + * the core (or we'd not be here), but we still need to + * set up our own accounting. + */ + viaparinfo->fbmem = vdev->fbmem_start; + viaparinfo->memsize = vdev->fbmem_len; viaparinfo->fbmem_free = viaparinfo->memsize; viaparinfo->fbmem_used = 0; - viafbinfo->screen_base = ioremap_nocache(viaparinfo->fbmem, - viaparinfo->memsize); - if (!viafbinfo->screen_base) { - printk(KERN_ERR "ioremap of fbmem failed\n"); - rc = -ENOMEM; - goto out_fb_release; - } + viafbinfo->screen_base = vdev->fbmem; - viafbinfo->fix.mmio_start = pci_resource_start(pdev, 1); - viafbinfo->fix.mmio_len = pci_resource_len(pdev, 1); + viafbinfo->fix.mmio_start = vdev->engine_start; + viafbinfo->fix.mmio_len = vdev->engine_len; viafbinfo->node = 0; viafbinfo->fbops = &viafb_ops; viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; @@ -1862,12 +1857,13 @@ int __devinit via_fb_pci_probe(struct pci_dev *pdev, viafbinfo->var = default_var; if (viafb_dual_fb) { - viafbinfo1 = framebuffer_alloc(viafb_par_length, &pdev->dev); + viafbinfo1 = framebuffer_alloc(viafb_par_length, + &vdev->pdev->dev); if (!viafbinfo1) { printk(KERN_ERR "allocate the second framebuffer struct error\n"); rc = -ENOMEM; - goto out_unmap_screen; + goto out_fb_release; } viaparinfo1 = viafbinfo1->par; memcpy(viaparinfo1, viaparinfo, viafb_par_length); @@ -1958,8 +1954,6 @@ out_dealloc_cmap: out_fb1_release: if (viafbinfo1) framebuffer_release(viafbinfo1); -out_unmap_screen: - iounmap(viafbinfo->screen_base); out_fb_release: framebuffer_release(viafbinfo); return rc; @@ -1972,8 +1966,6 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev) unregister_framebuffer(viafbinfo); if (viafb_dual_fb) unregister_framebuffer(viafbinfo1); - iounmap((void *)viafbinfo->screen_base); - iounmap(viaparinfo->shared->engine_mmio); framebuffer_release(viafbinfo); if (viafb_dual_fb) diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 5604f27eb74..52a35fabba9 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -30,7 +30,6 @@ #include "share.h" #include "chip.h" #include "hw.h" -#include "via_i2c.h" #define VERSION_MAJOR 2 #define VERSION_KERNEL 6 /* For kernel 2.6 */ @@ -42,6 +41,7 @@ struct viafb_shared { struct proc_dir_entry *proc_entry; /*viafb proc entry */ + struct viafb_dev *vdev; /* Global dev info */ /* All the information will be needed to set engine */ struct tmds_setting_information tmds_setting_info; @@ -51,7 +51,6 @@ struct viafb_shared { struct chip_information chip_info; /* hardware acceleration stuff */ - void __iomem *engine_mmio; u32 cursor_vram_addr; u32 vq_vram_addr; /* virtual queue address in video ram */ int (*hw_bitblt)(void __iomem *engine, u8 op, u32 width, u32 height, @@ -72,14 +71,6 @@ struct viafb_par { struct viafb_shared *shared; - /* - * (jc) I believe one should use locking to protect against - * concurrent access to the device ports and registers. Thus, - * this lock. Use of it is *far* from universal, though... - * someday... - */ - spinlock_t reg_lock; - /* All the information will be needed to set engine */ /* depreciated, use the ones in shared directly */ struct tmds_setting_information *tmds_setting_info; @@ -107,7 +98,7 @@ u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information void viafb_gpio_i2c_write_mask_lvds(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, struct IODATA io_data); -int via_fb_pci_probe(struct pci_dev *pdev, const struct pci_device_id *ent); +int via_fb_pci_probe(struct viafb_dev *vdev); void via_fb_pci_remove(struct pci_dev *pdev); /* Temporary */ int viafb_init(void); diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index 4589c6e73c5..e9f3661d6b3 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c @@ -19,6 +19,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ +#include "via-core.h" +#include "via_i2c.h" #include "global.h" u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information -- cgit v1.2.3-70-g09d2 From ec66841e495b9ab4f92bdf91efe8cf56e1471fbd Mon Sep 17 00:00:00 2001 From: Jonathan Corbet Date: Wed, 5 May 2010 14:44:55 -0600 Subject: viafb: move some include files to include/linux These are the files which should be available to subdevices compiled outside of drivers/video/via. Cc: ScottFang@viatech.com.cn Cc: JosephChan@via.com.tw Cc: Harald Welte Acked-by: Florian Tobias Schandinat Signed-off-by: Jonathan Corbet --- drivers/video/via/accel.c | 2 +- drivers/video/via/dvi.c | 4 +- drivers/video/via/hw.c | 3 +- drivers/video/via/lcd.c | 4 +- drivers/video/via/via-core.c | 6 +- drivers/video/via/via-core.h | 219 ------------------------------------ drivers/video/via/via-gpio.c | 4 +- drivers/video/via/via-gpio.h | 14 --- drivers/video/via/via_i2c.c | 4 +- drivers/video/via/via_i2c.h | 42 ------- drivers/video/via/via_modesetting.c | 2 +- drivers/video/via/via_utility.c | 2 +- drivers/video/via/viafbdev.c | 4 +- drivers/video/via/viamode.c | 2 +- drivers/video/via/vt1636.c | 4 +- include/linux/via-core.h | 219 ++++++++++++++++++++++++++++++++++++ include/linux/via-gpio.h | 14 +++ include/linux/via_i2c.h | 42 +++++++ 18 files changed, 296 insertions(+), 295 deletions(-) delete mode 100644 drivers/video/via/via-core.h delete mode 100644 drivers/video/via/via-gpio.h delete mode 100644 drivers/video/via/via_i2c.h create mode 100644 include/linux/via-core.h create mode 100644 include/linux/via-gpio.h create mode 100644 include/linux/via_i2c.h (limited to 'drivers/video/via/lcd.c') diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index 189aba41f9b..e44893ea590 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c @@ -18,7 +18,7 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "via-core.h" +#include #include "global.h" /* diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 6271b769632..39b040bb381 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -18,8 +18,8 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "via-core.h" -#include "via_i2c.h" +#include +#include #include "global.h" static void tmds_register_write(int index, u8 data); diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index e356fe8d8a9..b996803ae2c 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -18,7 +18,8 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "via-core.h" + +#include #include "global.h" static struct pll_map pll_value[] = { diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 04eec31aa9a..2ab0f156439 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -18,8 +18,8 @@ * Foundation, Inc., * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "via-core.h" -#include "via_i2c.h" +#include +#include #include "global.h" #include "lcdtbl.h" diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 188c0022dcb..e8cfe839211 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -7,9 +7,9 @@ /* * Core code for the Via multifunction framebuffer device. */ -#include "via-core.h" -#include "via_i2c.h" -#include "via-gpio.h" +#include +#include +#include #include "global.h" #include diff --git a/drivers/video/via/via-core.h b/drivers/video/via/via-core.h deleted file mode 100644 index 7ffb521e1a7..00000000000 --- a/drivers/video/via/via-core.h +++ /dev/null @@ -1,219 +0,0 @@ -/* - * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. - * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. - * Copyright 2009-2010 Jonathan Corbet - * Copyright 2010 Florian Tobias Schandinat - * - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; - * either version 2, or (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE.See the GNU General Public License - * for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ - -#ifndef __VIA_CORE_H__ -#define __VIA_CORE_H__ -#include -#include -#include -#include - -/* - * A description of each known serial I2C/GPIO port. - */ -enum via_port_type { - VIA_PORT_NONE = 0, - VIA_PORT_I2C, - VIA_PORT_GPIO, -}; - -enum via_port_mode { - VIA_MODE_OFF = 0, - VIA_MODE_I2C, /* Used as I2C port */ - VIA_MODE_GPIO, /* Two GPIO ports */ -}; - -enum viafb_i2c_adap { - VIA_PORT_26 = 0, - VIA_PORT_31, - VIA_PORT_25, - VIA_PORT_2C, - VIA_PORT_3D, -}; -#define VIAFB_NUM_PORTS 5 - -struct via_port_cfg { - enum via_port_type type; - enum via_port_mode mode; - u16 io_port; - u8 ioport_index; -}; - -/* - * This is the global viafb "device" containing stuff needed by - * all subdevs. - */ -struct viafb_dev { - struct pci_dev *pdev; - int chip_type; - struct via_port_cfg *port_cfg; - /* - * Spinlock for access to device registers. Not yet - * globally used. - */ - spinlock_t reg_lock; - /* - * The framebuffer MMIO region. Little, if anything, touches - * this memory directly, and certainly nothing outside of the - * framebuffer device itself. We *do* have to be able to allocate - * chunks of this memory for other devices, though. - */ - unsigned long fbmem_start; - long fbmem_len; - void __iomem *fbmem; -#if defined(CONFIG_FB_VIA_CAMERA) || defined(CONFIG_FB_VIA_CAMERA_MODULE) - long camera_fbmem_offset; - long camera_fbmem_size; -#endif - /* - * The MMIO region for device registers. - */ - unsigned long engine_start; - unsigned long engine_len; - void __iomem *engine_mmio; - -}; - -/* - * Interrupt management. - */ - -void viafb_irq_enable(u32 mask); -void viafb_irq_disable(u32 mask); - -/* - * The global interrupt control register and its bits. - */ -#define VDE_INTERRUPT 0x200 /* Video interrupt flags/masks */ -#define VDE_I_DVISENSE 0x00000001 /* DVI sense int status */ -#define VDE_I_VBLANK 0x00000002 /* Vertical blank status */ -#define VDE_I_MCCFI 0x00000004 /* MCE compl. frame int status */ -#define VDE_I_VSYNC 0x00000008 /* VGA VSYNC int status */ -#define VDE_I_DMA0DDONE 0x00000010 /* DMA 0 descr done */ -#define VDE_I_DMA0TDONE 0x00000020 /* DMA 0 transfer done */ -#define VDE_I_DMA1DDONE 0x00000040 /* DMA 1 descr done */ -#define VDE_I_DMA1TDONE 0x00000080 /* DMA 1 transfer done */ -#define VDE_I_C1AV 0x00000100 /* Cap Eng 1 act vid end */ -#define VDE_I_HQV0 0x00000200 /* First HQV engine */ -#define VDE_I_HQV1 0x00000400 /* Second HQV engine */ -#define VDE_I_HQV1EN 0x00000800 /* Second HQV engine enable */ -#define VDE_I_C0AV 0x00001000 /* Cap Eng 0 act vid end */ -#define VDE_I_C0VBI 0x00002000 /* Cap Eng 0 VBI end */ -#define VDE_I_C1VBI 0x00004000 /* Cap Eng 1 VBI end */ -#define VDE_I_VSYNC2 0x00008000 /* Sec. Disp. VSYNC */ -#define VDE_I_DVISNSEN 0x00010000 /* DVI sense enable */ -#define VDE_I_VSYNC2EN 0x00020000 /* Sec Disp VSYNC enable */ -#define VDE_I_MCCFIEN 0x00040000 /* MC comp frame int mask enable */ -#define VDE_I_VSYNCEN 0x00080000 /* VSYNC enable */ -#define VDE_I_DMA0DDEN 0x00100000 /* DMA 0 descr done enable */ -#define VDE_I_DMA0TDEN 0x00200000 /* DMA 0 trans done enable */ -#define VDE_I_DMA1DDEN 0x00400000 /* DMA 1 descr done enable */ -#define VDE_I_DMA1TDEN 0x00800000 /* DMA 1 trans done enable */ -#define VDE_I_C1AVEN 0x01000000 /* cap 1 act vid end enable */ -#define VDE_I_HQV0EN 0x02000000 /* First hqv engine enable */ -#define VDE_I_C1VBIEN 0x04000000 /* Cap 1 VBI end enable */ -#define VDE_I_LVDSSI 0x08000000 /* LVDS sense interrupt */ -#define VDE_I_C0AVEN 0x10000000 /* Cap 0 act vid end enable */ -#define VDE_I_C0VBIEN 0x20000000 /* Cap 0 VBI end enable */ -#define VDE_I_LVDSSIEN 0x40000000 /* LVDS Sense enable */ -#define VDE_I_ENABLE 0x80000000 /* Global interrupt enable */ - -/* - * DMA management. - */ -int viafb_request_dma(void); -void viafb_release_dma(void); -/* void viafb_dma_copy_out(unsigned int offset, dma_addr_t paddr, int len); */ -int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg); - -/* - * DMA Controller registers. - */ -#define VDMA_MR0 0xe00 /* Mod reg 0 */ -#define VDMA_MR_CHAIN 0x01 /* Chaining mode */ -#define VDMA_MR_TDIE 0x02 /* Transfer done int enable */ -#define VDMA_CSR0 0xe04 /* Control/status */ -#define VDMA_C_ENABLE 0x01 /* DMA Enable */ -#define VDMA_C_START 0x02 /* Start a transfer */ -#define VDMA_C_ABORT 0x04 /* Abort a transfer */ -#define VDMA_C_DONE 0x08 /* Transfer is done */ -#define VDMA_MARL0 0xe20 /* Mem addr low */ -#define VDMA_MARH0 0xe24 /* Mem addr high */ -#define VDMA_DAR0 0xe28 /* Device address */ -#define VDMA_DQWCR0 0xe2c /* Count (16-byte) */ -#define VDMA_TMR0 0xe30 /* Tile mode reg */ -#define VDMA_DPRL0 0xe34 /* Not sure */ -#define VDMA_DPR_IN 0x08 /* Inbound transfer to FB */ -#define VDMA_DPRH0 0xe38 -#define VDMA_PMR0 (0xe00 + 0x134) /* Pitch mode */ - -/* - * Useful stuff that probably belongs somewhere global. - */ -#define VGA_WIDTH 640 -#define VGA_HEIGHT 480 - -/* - * Indexed port operations. Note that these are all multi-op - * functions; every invocation will be racy if you're not holding - * reg_lock. - */ - -#define VIAStatus 0x3DA /* Non-indexed port */ -#define VIACR 0x3D4 -#define VIASR 0x3C4 -#define VIAGR 0x3CE -#define VIAAR 0x3C0 - -static inline u8 via_read_reg(u16 port, u8 index) -{ - outb(index, port); - return inb(port + 1); -} - -static inline void via_write_reg(u16 port, u8 index, u8 data) -{ - outb(index, port); - outb(data, port + 1); -} - -static inline void via_write_reg_mask(u16 port, u8 index, u8 data, u8 mask) -{ - u8 old; - - outb(index, port); - old = inb(port + 1); - outb((data & mask) | (old & ~mask), port + 1); -} - -#define VIA_MISC_REG_READ 0x03CC -#define VIA_MISC_REG_WRITE 0x03C2 - -static inline void via_write_misc_reg_mask(u8 data, u8 mask) -{ - u8 old = inb(VIA_MISC_REG_READ); - outb((data & mask) | (old & ~mask), VIA_MISC_REG_WRITE); -} - - -#endif /* __VIA_CORE_H__ */ diff --git a/drivers/video/via/via-gpio.c b/drivers/video/via/via-gpio.c index 67d699cbfd2..595516aea69 100644 --- a/drivers/video/via/via-gpio.c +++ b/drivers/video/via/via-gpio.c @@ -8,8 +8,8 @@ #include #include #include -#include "via-core.h" -#include "via-gpio.h" +#include +#include /* * The ports we know about. Note that the port-25 gpios are not diff --git a/drivers/video/via/via-gpio.h b/drivers/video/via/via-gpio.h deleted file mode 100644 index 8281aea3dd6..00000000000 --- a/drivers/video/via/via-gpio.h +++ /dev/null @@ -1,14 +0,0 @@ -/* - * Support for viafb GPIO ports. - * - * Copyright 2009 Jonathan Corbet - * Distributable under version 2 of the GNU General Public License. - */ - -#ifndef __VIA_GPIO_H__ -#define __VIA_GPIO_H__ - -extern int viafb_gpio_lookup(const char *name); -extern int viafb_gpio_init(void); -extern void viafb_gpio_exit(void); -#endif diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 2291765f2f8..da9e4ca94b1 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -23,8 +23,8 @@ #include #include #include -#include "via-core.h" -#include "via_i2c.h" +#include +#include /* * There can only be one set of these, so there's no point in having diff --git a/drivers/video/via/via_i2c.h b/drivers/video/via/via_i2c.h deleted file mode 100644 index 44532e468c0..00000000000 --- a/drivers/video/via/via_i2c.h +++ /dev/null @@ -1,42 +0,0 @@ -/* - * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. - * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. - - * This program is free software; you can redistribute it and/or - * modify it under the terms of the GNU General Public - * License as published by the Free Software Foundation; - * either version 2, or (at your option) any later version. - - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even - * the implied warranty of MERCHANTABILITY or FITNESS FOR - * A PARTICULAR PURPOSE.See the GNU General Public License - * for more details. - - * You should have received a copy of the GNU General Public License - * along with this program; if not, write to the Free Software - * Foundation, Inc., - * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - */ -#ifndef __VIA_I2C_H__ -#define __VIA_I2C_H__ - -#include -#include - -struct via_i2c_stuff { - u16 i2c_port; /* GPIO or I2C port */ - u16 is_active; /* Being used as I2C? */ - struct i2c_adapter adapter; - struct i2c_algo_bit_data algo; -}; - - -int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata); -int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data); -int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len); -struct i2c_adapter *viafb_find_i2c_adapter(enum viafb_i2c_adap which); - -extern int viafb_i2c_init(void); -extern void viafb_i2c_exit(void); -#endif /* __VIA_I2C_H__ */ diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/via/via_modesetting.c index b4e735cc350..3cddcff88ab 100644 --- a/drivers/video/via/via_modesetting.c +++ b/drivers/video/via/via_modesetting.c @@ -24,8 +24,8 @@ */ #include +#include #include "via_modesetting.h" -#include "via-core.h" #include "share.h" #include "debug.h" diff --git a/drivers/video/via/via_utility.c b/drivers/video/via/via_utility.c index 57570314186..d05ccb62b55 100644 --- a/drivers/video/via/via_utility.c +++ b/drivers/video/via/via_utility.c @@ -19,7 +19,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "via-core.h" +#include #include "global.h" void viafb_get_device_support_state(u32 *support_state) diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 3d033186a82..d3dd2eb9558 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -22,9 +22,9 @@ #include #include #include -#define _MASTER_FILE +#include -#include "via-core.h" +#define _MASTER_FILE #include "global.h" static char *viafb_name = "Via"; diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index 2fdb9e6724a..2dbad3c0f67 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c @@ -19,7 +19,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "via-core.h" +#include #include "global.h" struct res_map_refresh res_map_refresh_tbl[] = { /*hres, vres, vclock, vmode_refresh*/ diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index e5f80247288..d65bf1aee87 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c @@ -19,8 +19,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ -#include "via-core.h" -#include "via_i2c.h" +#include +#include #include "global.h" u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information diff --git a/include/linux/via-core.h b/include/linux/via-core.h new file mode 100644 index 00000000000..7ffb521e1a7 --- /dev/null +++ b/include/linux/via-core.h @@ -0,0 +1,219 @@ +/* + * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2009-2010 Jonathan Corbet + * Copyright 2010 Florian Tobias Schandinat + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ + +#ifndef __VIA_CORE_H__ +#define __VIA_CORE_H__ +#include +#include +#include +#include + +/* + * A description of each known serial I2C/GPIO port. + */ +enum via_port_type { + VIA_PORT_NONE = 0, + VIA_PORT_I2C, + VIA_PORT_GPIO, +}; + +enum via_port_mode { + VIA_MODE_OFF = 0, + VIA_MODE_I2C, /* Used as I2C port */ + VIA_MODE_GPIO, /* Two GPIO ports */ +}; + +enum viafb_i2c_adap { + VIA_PORT_26 = 0, + VIA_PORT_31, + VIA_PORT_25, + VIA_PORT_2C, + VIA_PORT_3D, +}; +#define VIAFB_NUM_PORTS 5 + +struct via_port_cfg { + enum via_port_type type; + enum via_port_mode mode; + u16 io_port; + u8 ioport_index; +}; + +/* + * This is the global viafb "device" containing stuff needed by + * all subdevs. + */ +struct viafb_dev { + struct pci_dev *pdev; + int chip_type; + struct via_port_cfg *port_cfg; + /* + * Spinlock for access to device registers. Not yet + * globally used. + */ + spinlock_t reg_lock; + /* + * The framebuffer MMIO region. Little, if anything, touches + * this memory directly, and certainly nothing outside of the + * framebuffer device itself. We *do* have to be able to allocate + * chunks of this memory for other devices, though. + */ + unsigned long fbmem_start; + long fbmem_len; + void __iomem *fbmem; +#if defined(CONFIG_FB_VIA_CAMERA) || defined(CONFIG_FB_VIA_CAMERA_MODULE) + long camera_fbmem_offset; + long camera_fbmem_size; +#endif + /* + * The MMIO region for device registers. + */ + unsigned long engine_start; + unsigned long engine_len; + void __iomem *engine_mmio; + +}; + +/* + * Interrupt management. + */ + +void viafb_irq_enable(u32 mask); +void viafb_irq_disable(u32 mask); + +/* + * The global interrupt control register and its bits. + */ +#define VDE_INTERRUPT 0x200 /* Video interrupt flags/masks */ +#define VDE_I_DVISENSE 0x00000001 /* DVI sense int status */ +#define VDE_I_VBLANK 0x00000002 /* Vertical blank status */ +#define VDE_I_MCCFI 0x00000004 /* MCE compl. frame int status */ +#define VDE_I_VSYNC 0x00000008 /* VGA VSYNC int status */ +#define VDE_I_DMA0DDONE 0x00000010 /* DMA 0 descr done */ +#define VDE_I_DMA0TDONE 0x00000020 /* DMA 0 transfer done */ +#define VDE_I_DMA1DDONE 0x00000040 /* DMA 1 descr done */ +#define VDE_I_DMA1TDONE 0x00000080 /* DMA 1 transfer done */ +#define VDE_I_C1AV 0x00000100 /* Cap Eng 1 act vid end */ +#define VDE_I_HQV0 0x00000200 /* First HQV engine */ +#define VDE_I_HQV1 0x00000400 /* Second HQV engine */ +#define VDE_I_HQV1EN 0x00000800 /* Second HQV engine enable */ +#define VDE_I_C0AV 0x00001000 /* Cap Eng 0 act vid end */ +#define VDE_I_C0VBI 0x00002000 /* Cap Eng 0 VBI end */ +#define VDE_I_C1VBI 0x00004000 /* Cap Eng 1 VBI end */ +#define VDE_I_VSYNC2 0x00008000 /* Sec. Disp. VSYNC */ +#define VDE_I_DVISNSEN 0x00010000 /* DVI sense enable */ +#define VDE_I_VSYNC2EN 0x00020000 /* Sec Disp VSYNC enable */ +#define VDE_I_MCCFIEN 0x00040000 /* MC comp frame int mask enable */ +#define VDE_I_VSYNCEN 0x00080000 /* VSYNC enable */ +#define VDE_I_DMA0DDEN 0x00100000 /* DMA 0 descr done enable */ +#define VDE_I_DMA0TDEN 0x00200000 /* DMA 0 trans done enable */ +#define VDE_I_DMA1DDEN 0x00400000 /* DMA 1 descr done enable */ +#define VDE_I_DMA1TDEN 0x00800000 /* DMA 1 trans done enable */ +#define VDE_I_C1AVEN 0x01000000 /* cap 1 act vid end enable */ +#define VDE_I_HQV0EN 0x02000000 /* First hqv engine enable */ +#define VDE_I_C1VBIEN 0x04000000 /* Cap 1 VBI end enable */ +#define VDE_I_LVDSSI 0x08000000 /* LVDS sense interrupt */ +#define VDE_I_C0AVEN 0x10000000 /* Cap 0 act vid end enable */ +#define VDE_I_C0VBIEN 0x20000000 /* Cap 0 VBI end enable */ +#define VDE_I_LVDSSIEN 0x40000000 /* LVDS Sense enable */ +#define VDE_I_ENABLE 0x80000000 /* Global interrupt enable */ + +/* + * DMA management. + */ +int viafb_request_dma(void); +void viafb_release_dma(void); +/* void viafb_dma_copy_out(unsigned int offset, dma_addr_t paddr, int len); */ +int viafb_dma_copy_out_sg(unsigned int offset, struct scatterlist *sg, int nsg); + +/* + * DMA Controller registers. + */ +#define VDMA_MR0 0xe00 /* Mod reg 0 */ +#define VDMA_MR_CHAIN 0x01 /* Chaining mode */ +#define VDMA_MR_TDIE 0x02 /* Transfer done int enable */ +#define VDMA_CSR0 0xe04 /* Control/status */ +#define VDMA_C_ENABLE 0x01 /* DMA Enable */ +#define VDMA_C_START 0x02 /* Start a transfer */ +#define VDMA_C_ABORT 0x04 /* Abort a transfer */ +#define VDMA_C_DONE 0x08 /* Transfer is done */ +#define VDMA_MARL0 0xe20 /* Mem addr low */ +#define VDMA_MARH0 0xe24 /* Mem addr high */ +#define VDMA_DAR0 0xe28 /* Device address */ +#define VDMA_DQWCR0 0xe2c /* Count (16-byte) */ +#define VDMA_TMR0 0xe30 /* Tile mode reg */ +#define VDMA_DPRL0 0xe34 /* Not sure */ +#define VDMA_DPR_IN 0x08 /* Inbound transfer to FB */ +#define VDMA_DPRH0 0xe38 +#define VDMA_PMR0 (0xe00 + 0x134) /* Pitch mode */ + +/* + * Useful stuff that probably belongs somewhere global. + */ +#define VGA_WIDTH 640 +#define VGA_HEIGHT 480 + +/* + * Indexed port operations. Note that these are all multi-op + * functions; every invocation will be racy if you're not holding + * reg_lock. + */ + +#define VIAStatus 0x3DA /* Non-indexed port */ +#define VIACR 0x3D4 +#define VIASR 0x3C4 +#define VIAGR 0x3CE +#define VIAAR 0x3C0 + +static inline u8 via_read_reg(u16 port, u8 index) +{ + outb(index, port); + return inb(port + 1); +} + +static inline void via_write_reg(u16 port, u8 index, u8 data) +{ + outb(index, port); + outb(data, port + 1); +} + +static inline void via_write_reg_mask(u16 port, u8 index, u8 data, u8 mask) +{ + u8 old; + + outb(index, port); + old = inb(port + 1); + outb((data & mask) | (old & ~mask), port + 1); +} + +#define VIA_MISC_REG_READ 0x03CC +#define VIA_MISC_REG_WRITE 0x03C2 + +static inline void via_write_misc_reg_mask(u8 data, u8 mask) +{ + u8 old = inb(VIA_MISC_REG_READ); + outb((data & mask) | (old & ~mask), VIA_MISC_REG_WRITE); +} + + +#endif /* __VIA_CORE_H__ */ diff --git a/include/linux/via-gpio.h b/include/linux/via-gpio.h new file mode 100644 index 00000000000..8281aea3dd6 --- /dev/null +++ b/include/linux/via-gpio.h @@ -0,0 +1,14 @@ +/* + * Support for viafb GPIO ports. + * + * Copyright 2009 Jonathan Corbet + * Distributable under version 2 of the GNU General Public License. + */ + +#ifndef __VIA_GPIO_H__ +#define __VIA_GPIO_H__ + +extern int viafb_gpio_lookup(const char *name); +extern int viafb_gpio_init(void); +extern void viafb_gpio_exit(void); +#endif diff --git a/include/linux/via_i2c.h b/include/linux/via_i2c.h new file mode 100644 index 00000000000..44532e468c0 --- /dev/null +++ b/include/linux/via_i2c.h @@ -0,0 +1,42 @@ +/* + * Copyright 1998-2009 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public + * License as published by the Free Software Foundation; + * either version 2, or (at your option) any later version. + + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even + * the implied warranty of MERCHANTABILITY or FITNESS FOR + * A PARTICULAR PURPOSE.See the GNU General Public License + * for more details. + + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + */ +#ifndef __VIA_I2C_H__ +#define __VIA_I2C_H__ + +#include +#include + +struct via_i2c_stuff { + u16 i2c_port; /* GPIO or I2C port */ + u16 is_active; /* Being used as I2C? */ + struct i2c_adapter adapter; + struct i2c_algo_bit_data algo; +}; + + +int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata); +int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data); +int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len); +struct i2c_adapter *viafb_find_i2c_adapter(enum viafb_i2c_adap which); + +extern int viafb_i2c_init(void); +extern void viafb_i2c_exit(void); +#endif /* __VIA_I2C_H__ */ -- cgit v1.2.3-70-g09d2