diff options
| author | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-22 12:39:58 -0700 | 
|---|---|---|
| committer | Linus Torvalds <torvalds@linux-foundation.org> | 2011-05-22 12:39:58 -0700 | 
| commit | 71a8638480eb8fb6cfabe2ee9ca3fbc6e3453a14 (patch) | |
| tree | 8ee9f7da07bb9461a41a8ded6f9da243db02b279 | |
| parent | 17238005f377888b9d4583835205c77e3d781bb8 (diff) | |
| parent | 8aa4d96fe3e4cda9a6469b22b3f017ed30996b10 (diff) | |
| download | olio-linux-3.10-71a8638480eb8fb6cfabe2ee9ca3fbc6e3453a14.tar.xz olio-linux-3.10-71a8638480eb8fb6cfabe2ee9ca3fbc6e3453a14.zip  | |
Merge branch 'viafb-next' of git://github.com/schandinat/linux-2.6
* 'viafb-next' of git://github.com/schandinat/linux-2.6: (24 commits)
  viafb: Automatic OLPC XO-1.5 configuration
  viafb: remove unused CEA mode
  viafb: try to map less memory in case of failure
  viafb: use write combining for video ram
  viafb: add X server compatibility mode
  viafb: reduce OLPC refresh a bit
  viafb: fix OLPC XO 1.5 device connection
  viafb: fix OLPC DCON refresh rate
  viafb: delete clock and PLL initialization
  viafb: replace custom return values
  viafb: some small cleanup for global variables
  viafb: gather common good, old VGA initialization in one place
  viafb: add engine clock support
  viafb: add VIA slapping capability
  viafb: split clock and PLL code to an extra file
  viafb: add primary/secondary clock on/off switches
  viafb: add clock source selection and PLL power management support
  viafb: prepare for PLL separation
  viafb: call viafb_get_clk_value only in viafb_set_vclock
  viafb: remove unused max_hres/vres
  ...
| -rw-r--r-- | drivers/video/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/video/via/Makefile | 2 | ||||
| -rw-r--r-- | drivers/video/via/chip.h | 6 | ||||
| -rw-r--r-- | drivers/video/via/dvi.c | 160 | ||||
| -rw-r--r-- | drivers/video/via/dvi.h | 2 | ||||
| -rw-r--r-- | drivers/video/via/global.c | 4 | ||||
| -rw-r--r-- | drivers/video/via/global.h | 2 | ||||
| -rw-r--r-- | drivers/video/via/hw.c | 626 | ||||
| -rw-r--r-- | drivers/video/via/hw.h | 15 | ||||
| -rw-r--r-- | drivers/video/via/lcd.c | 23 | ||||
| -rw-r--r-- | drivers/video/via/lcd.h | 2 | ||||
| -rw-r--r-- | drivers/video/via/share.h | 17 | ||||
| -rw-r--r-- | drivers/video/via/via-core.c | 9 | ||||
| -rw-r--r-- | drivers/video/via/via_clock.c | 349 | ||||
| -rw-r--r-- | drivers/video/via/via_clock.h | 76 | ||||
| -rw-r--r-- | drivers/video/via/viafbdev.c | 62 | ||||
| -rw-r--r-- | drivers/video/via/viafbdev.h | 4 | ||||
| -rw-r--r-- | drivers/video/via/viamode.c | 46 | ||||
| -rw-r--r-- | drivers/video/via/viamode.h | 9 | 
19 files changed, 721 insertions, 704 deletions
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig index e6a8d8c0101..6d139679eb7 100644 --- a/drivers/video/Kconfig +++ b/drivers/video/Kconfig @@ -1562,6 +1562,17 @@ config FB_VIA_DIRECT_PROCFS  	  correct output device configuration.  	  Its use is strongly discouraged. +config FB_VIA_X_COMPATIBILITY +	bool "X server compatibility" +	depends on FB_VIA +	default n +	help +	  This option reduces the functionality (power saving, ...) of the +	  framebuffer to avoid negative impact on the OpenChrome X server. +	  If you use any X server other than fbdev you should enable this +	  otherwise it should be safe to disable it and allow using all +	  features. +  endif  config FB_NEOMAGIC diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index 96f01ee2a41..5108136e877 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile @@ -6,4 +6,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 \ -	via-core.o via-gpio.o via_modesetting.o +	via-core.o via-gpio.o via_modesetting.o via_clock.o diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index 29d70244a21..3ebf20c06ee 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h @@ -137,17 +137,11 @@ struct chip_information {  	struct lvds_chip_information lvds_chip_info2;  }; -struct crt_setting_information { -	int iga_path; -}; -  struct tmds_setting_information {  	int iga_path;  	int h_active;  	int v_active;  	int max_pixel_clock; -	int max_hres; -	int max_vres;  };  struct lvds_setting_information { diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 41ca198b509..b1f364745ca 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -28,17 +28,11 @@ static int tmds_register_read_bytes(int index, u8 *buff, int buff_len);  static void __devinit dvi_get_panel_size_from_DDCv1(  	struct tmds_chip_information *tmds_chip,  	struct tmds_setting_information *tmds_setting); -static void __devinit dvi_get_panel_size_from_DDCv2( -	struct tmds_chip_information *tmds_chip, -	struct tmds_setting_information *tmds_setting);  static int viafb_dvi_query_EDID(void); -static int check_tmds_chip(int device_id_subaddr, int device_id) +static inline bool check_tmds_chip(int device_id_subaddr, int device_id)  { -	if (tmds_register_read(device_id_subaddr) == device_id) -		return OK; -	else -		return FAIL; +	return tmds_register_read(device_id_subaddr) == device_id;  }  void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, @@ -47,22 +41,13 @@ void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,  	DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n");  	viafb_dvi_sense(); -	switch (viafb_dvi_query_EDID()) { -	case 1: +	if (viafb_dvi_query_EDID() == 1)  		dvi_get_panel_size_from_DDCv1(tmds_chip, tmds_setting); -		break; -	case 2: -		dvi_get_panel_size_from_DDCv2(tmds_chip, tmds_setting); -		break; -	default: -		printk(KERN_WARNING "viafb_init_dvi_size: DVI panel size undetected!\n"); -		break; -	}  	return;  } -int __devinit viafb_tmds_trasmitter_identify(void) +bool __devinit viafb_tmds_trasmitter_identify(void)  {  	unsigned char sr2a = 0, sr1e = 0, sr3e = 0; @@ -101,7 +86,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)  	viaparinfo->chip_info->  		tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;  	viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31; -	if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) != FAIL) { +	if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {  		/*  		 * Currently only support 12bits,dual edge,add 24bits mode later  		 */ @@ -112,11 +97,10 @@ int __devinit viafb_tmds_trasmitter_identify(void)  			  viaparinfo->chip_info->tmds_chip_info.tmds_chip_name);  		DEBUG_MSG(KERN_INFO "\n %2d",  			  viaparinfo->chip_info->tmds_chip_info.i2c_port); -		return OK; +		return true;  	} else {  		viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_2C; -		if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID) -		    != FAIL) { +		if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {  			tmds_register_write(0x08, 0x3b);  			DEBUG_MSG(KERN_INFO "\n VT1632 TMDS ! \n");  			DEBUG_MSG(KERN_INFO "\n %2d", @@ -125,7 +109,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)  			DEBUG_MSG(KERN_INFO "\n %2d",  				  viaparinfo->chip_info->  				  tmds_chip_info.i2c_port); -			return OK; +			return true;  		}  	} @@ -135,7 +119,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)  	    ((viafb_display_hardware_layout == HW_LAYOUT_DVI_ONLY) ||  	     (viafb_display_hardware_layout == HW_LAYOUT_LCD_DVI))) {  		DEBUG_MSG(KERN_INFO "\n Integrated TMDS ! \n"); -		return OK; +		return true;  	}  	switch (viaparinfo->chip_info->gfx_chip_name) { @@ -159,7 +143,7 @@ int __devinit viafb_tmds_trasmitter_identify(void)  		tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;  	viaparinfo->chip_info->tmds_chip_info.  		tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR; -	return FAIL; +	return false;  }  static void tmds_register_write(int index, u8 data) @@ -306,12 +290,7 @@ static int viafb_dvi_query_EDID(void)  		return EDID_VERSION_1;	/* Found EDID1 Table */  	} -	data0 = (u8) tmds_register_read(0x00); -	viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = restore; -	if (data0 == 0x20) -		return EDID_VERSION_2;	/* Found EDID2 Table */ -	else -		return false; +	return false;  }  /* Get Panel Size Using EDID1 Table */ @@ -319,50 +298,15 @@ static void __devinit dvi_get_panel_size_from_DDCv1(  	struct tmds_chip_information *tmds_chip,  	struct tmds_setting_information *tmds_setting)  { -	int i, max_h = 0, tmp, restore; -	unsigned char rData; +	int i, restore;  	unsigned char EDID_DATA[18];  	DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv1 \n");  	restore = tmds_chip->tmds_chip_slave_addr;  	tmds_chip->tmds_chip_slave_addr = 0xA0; - -	rData = tmds_register_read(0x23); -	if (rData & 0x3C) -		max_h = 640; -	if (rData & 0xC0) -		max_h = 720; -	if (rData & 0x03) -		max_h = 800; - -	rData = tmds_register_read(0x24); -	if (rData & 0xC0) -		max_h = 800; -	if (rData & 0x1E) -		max_h = 1024; -	if (rData & 0x01) -		max_h = 1280; -  	for (i = 0x25; i < 0x6D; i++) {  		switch (i) { -		case 0x26: -		case 0x28: -		case 0x2A: -		case 0x2C: -		case 0x2E: -		case 0x30: -		case 0x32: -		case 0x34: -			rData = tmds_register_read(i); -			if (rData == 1) -				break; -			/* data = (data + 31) * 8 */ -			tmp = (rData + 31) << 3; -			if (tmp > max_h) -				max_h = tmp; -			break; -  		case 0x36:  		case 0x48:  		case 0x5A: @@ -383,91 +327,11 @@ static void __devinit dvi_get_panel_size_from_DDCv1(  		}  	} -	tmds_setting->max_hres = max_h; -	switch (max_h) { -	case 640: -		tmds_setting->max_vres = 480; -		break; -	case 800: -		tmds_setting->max_vres = 600; -		break; -	case 1024: -		tmds_setting->max_vres = 768; -		break; -	case 1280: -		tmds_setting->max_vres = 1024; -		break; -	case 1400: -		tmds_setting->max_vres = 1050; -		break; -	case 1440: -		tmds_setting->max_vres = 1050; -		break; -	case 1600: -		tmds_setting->max_vres = 1200; -		break; -	case 1920: -		tmds_setting->max_vres = 1080; -		break; -	default: -		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d ! " -					 "set default panel size.\n", max_h); -		break; -	} -  	DEBUG_MSG(KERN_INFO "DVI max pixelclock = %d\n",  		tmds_setting->max_pixel_clock);  	tmds_chip->tmds_chip_slave_addr = restore;  } -/* Get Panel Size Using EDID2 Table */ -static void __devinit dvi_get_panel_size_from_DDCv2( -	struct tmds_chip_information *tmds_chip, -	struct tmds_setting_information *tmds_setting) -{ -	int restore; -	unsigned char R_Buffer[2]; - -	DEBUG_MSG(KERN_INFO "\n dvi_get_panel_size_from_DDCv2 \n"); - -	restore = tmds_chip->tmds_chip_slave_addr; -	tmds_chip->tmds_chip_slave_addr = 0xA2; - -	/* Horizontal: 0x76, 0x77 */ -	tmds_register_read_bytes(0x76, R_Buffer, 2); -	tmds_setting->max_hres = R_Buffer[0] + (R_Buffer[1] << 8); - -	switch (tmds_setting->max_hres) { -	case 640: -		tmds_setting->max_vres = 480; -		break; -	case 800: -		tmds_setting->max_vres = 600; -		break; -	case 1024: -		tmds_setting->max_vres = 768; -		break; -	case 1280: -		tmds_setting->max_vres = 1024; -		break; -	case 1400: -		tmds_setting->max_vres = 1050; -		break; -	case 1440: -		tmds_setting->max_vres = 1050; -		break; -	case 1600: -		tmds_setting->max_vres = 1200; -		break; -	default: -		DEBUG_MSG(KERN_INFO "Unknown panel size max resolution = %d! " -			"set default panel size.\n", tmds_setting->max_hres); -		break; -	} - -	tmds_chip->tmds_chip_slave_addr = restore; -} -  /* If Disable DVI, turn off pad */  void viafb_dvi_disable(void)  { diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index 2c525c0c1ad..f473dd01097 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h @@ -56,7 +56,7 @@  int viafb_dvi_sense(void);  void viafb_dvi_disable(void);  void viafb_dvi_enable(void); -int __devinit viafb_tmds_trasmitter_identify(void); +bool __devinit viafb_tmds_trasmitter_identify(void);  void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip,  	struct tmds_setting_information *tmds_setting);  void viafb_dvi_set_mode(struct VideoModeTable *videoMode, int mode_bpp, diff --git a/drivers/video/via/global.c b/drivers/video/via/global.c index 1ee511b7330..e10d8249534 100644 --- a/drivers/video/via/global.c +++ b/drivers/video/via/global.c @@ -40,10 +40,6 @@ int viafb_hotplug_Yres = 480;  int viafb_hotplug_bpp = 32;  int viafb_hotplug_refresh = 60;  int viafb_primary_dev = None_Device; -unsigned int viafb_second_xres = 640; -unsigned int viafb_second_yres = 480; -unsigned int viafb_second_virtual_xres; -unsigned int viafb_second_virtual_yres;  int viafb_lcd_panel_id = LCD_PANEL_ID_MAXIMUM + 1;  struct fb_info *viafbinfo;  struct fb_info *viafbinfo1; diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 38ef5ac6695..ff969dc3459 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -73,8 +73,6 @@ extern int viafb_hotplug_bpp;  extern int viafb_hotplug_refresh;  extern int viafb_primary_dev; -extern unsigned int viafb_second_xres; -extern unsigned int viafb_second_yres;  extern int viafb_lcd_panel_id;  #endif /* __GLOBAL_H__ */ diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index dc4c778877c..47b13535ed2 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -20,274 +20,84 @@   */  #include <linux/via-core.h> +#include <asm/olpc.h>  #include "global.h" +#include "via_clock.h" -static struct pll_config cle266_pll_config[] = { -	{19, 4, 0}, -	{26, 5, 0}, -	{28, 5, 0}, -	{31, 5, 0}, -	{33, 5, 0}, -	{55, 5, 0}, -	{102, 5, 0}, -	{53, 6, 0}, -	{92, 6, 0}, -	{98, 6, 0}, -	{112, 6, 0}, -	{41, 7, 0}, -	{60, 7, 0}, -	{99, 7, 0}, -	{100, 7, 0}, -	{83, 8, 0}, -	{86, 8, 0}, -	{108, 8, 0}, -	{87, 9, 0}, -	{118, 9, 0}, -	{95, 12, 0}, -	{115, 12, 0}, -	{108, 13, 0}, -	{83, 17, 0}, -	{67, 20, 0}, -	{86, 20, 0}, -	{98, 20, 0}, -	{121, 24, 0}, -	{99, 29, 0}, -	{33, 3, 1}, -	{15, 4, 1}, -	{23, 4, 1}, -	{37, 5, 1}, -	{83, 5, 1}, -	{85, 5, 1}, -	{94, 5, 1}, -	{103, 5, 1}, -	{109, 5, 1}, -	{113, 5, 1}, -	{121, 5, 1}, -	{82, 6, 1}, -	{31, 7, 1}, -	{55, 7, 1}, -	{84, 7, 1}, -	{83, 8, 1}, -	{76, 9, 1}, -	{127, 9, 1}, -	{33, 4, 2}, -	{75, 4, 2}, -	{119, 4, 2}, -	{121, 4, 2}, -	{91, 5, 2}, -	{118, 5, 2}, -	{83, 6, 2}, -	{109, 6, 2}, -	{90, 7, 2}, -	{93, 2, 3}, -	{53, 3, 3}, -	{73, 4, 3}, -	{89, 4, 3}, -	{105, 4, 3}, -	{117, 4, 3}, -	{101, 5, 3}, -	{121, 5, 3}, -	{127, 5, 3}, -	{99, 7, 3} +static struct pll_limit cle266_pll_limits[] = { +	{19, 19, 4, 0}, +	{26, 102, 5, 0}, +	{53, 112, 6, 0}, +	{41, 100, 7, 0}, +	{83, 108, 8, 0}, +	{87, 118, 9, 0}, +	{95, 115, 12, 0}, +	{108, 108, 13, 0}, +	{83, 83, 17, 0}, +	{67, 98, 20, 0}, +	{121, 121, 24, 0}, +	{99, 99, 29, 0}, +	{33, 33, 3, 1}, +	{15, 23, 4, 1}, +	{37, 121, 5, 1}, +	{82, 82, 6, 1}, +	{31, 84, 7, 1}, +	{83, 83, 8, 1}, +	{76, 127, 9, 1}, +	{33, 121, 4, 2}, +	{91, 118, 5, 2}, +	{83, 109, 6, 2}, +	{90, 90, 7, 2}, +	{93, 93, 2, 3}, +	{53, 53, 3, 3}, +	{73, 117, 4, 3}, +	{101, 127, 5, 3}, +	{99, 99, 7, 3}  }; -static struct pll_config k800_pll_config[] = { -	{22, 2, 0}, -	{28, 3, 0}, -	{81, 3, 1}, -	{85, 3, 1}, -	{98, 3, 1}, -	{112, 3, 1}, -	{86, 4, 1}, -	{166, 4, 1}, -	{109, 5, 1}, -	{113, 5, 1}, -	{121, 5, 1}, -	{131, 5, 1}, -	{143, 5, 1}, -	{153, 5, 1}, -	{66, 3, 2}, -	{68, 3, 2}, -	{95, 3, 2}, -	{106, 3, 2}, -	{116, 3, 2}, -	{93, 4, 2}, -	{119, 4, 2}, -	{121, 4, 2}, -	{133, 4, 2}, -	{137, 4, 2}, -	{117, 5, 2}, -	{118, 5, 2}, -	{120, 5, 2}, -	{124, 5, 2}, -	{132, 5, 2}, -	{137, 5, 2}, -	{141, 5, 2}, -	{166, 5, 2}, -	{170, 5, 2}, -	{191, 5, 2}, -	{206, 5, 2}, -	{208, 5, 2}, -	{30, 2, 3}, -	{69, 3, 3}, -	{82, 3, 3}, -	{83, 3, 3}, -	{109, 3, 3}, -	{114, 3, 3}, -	{125, 3, 3}, -	{89, 4, 3}, -	{103, 4, 3}, -	{117, 4, 3}, -	{126, 4, 3}, -	{150, 4, 3}, -	{161, 4, 3}, -	{121, 5, 3}, -	{127, 5, 3}, -	{131, 5, 3}, -	{134, 5, 3}, -	{148, 5, 3}, -	{169, 5, 3}, -	{172, 5, 3}, -	{182, 5, 3}, -	{195, 5, 3}, -	{196, 5, 3}, -	{208, 5, 3}, -	{66, 2, 4}, -	{85, 3, 4}, -	{141, 4, 4}, -	{146, 4, 4}, -	{161, 4, 4}, -	{177, 5, 4} +static struct pll_limit k800_pll_limits[] = { +	{22, 22, 2, 0}, +	{28, 28, 3, 0}, +	{81, 112, 3, 1}, +	{86, 166, 4, 1}, +	{109, 153, 5, 1}, +	{66, 116, 3, 2}, +	{93, 137, 4, 2}, +	{117, 208, 5, 2}, +	{30, 30, 2, 3}, +	{69, 125, 3, 3}, +	{89, 161, 4, 3}, +	{121, 208, 5, 3}, +	{66, 66, 2, 4}, +	{85, 85, 3, 4}, +	{141, 161, 4, 4}, +	{177, 177, 5, 4}  }; -static struct pll_config cx700_pll_config[] = { -	{98, 3, 1}, -	{86, 4, 1}, -	{109, 5, 1}, -	{110, 5, 1}, -	{113, 5, 1}, -	{121, 5, 1}, -	{131, 5, 1}, -	{135, 5, 1}, -	{142, 5, 1}, -	{143, 5, 1}, -	{153, 5, 1}, -	{187, 5, 1}, -	{208, 5, 1}, -	{68, 2, 2}, -	{95, 3, 2}, -	{116, 3, 2}, -	{93, 4, 2}, -	{119, 4, 2}, -	{133, 4, 2}, -	{137, 4, 2}, -	{151, 4, 2}, -	{166, 4, 2}, -	{110, 5, 2}, -	{112, 5, 2}, -	{117, 5, 2}, -	{118, 5, 2}, -	{120, 5, 2}, -	{132, 5, 2}, -	{137, 5, 2}, -	{141, 5, 2}, -	{151, 5, 2}, -	{166, 5, 2}, -	{175, 5, 2}, -	{191, 5, 2}, -	{206, 5, 2}, -	{174, 7, 2}, -	{82, 3, 3}, -	{109, 3, 3}, -	{117, 4, 3}, -	{150, 4, 3}, -	{161, 4, 3}, -	{112, 5, 3}, -	{115, 5, 3}, -	{121, 5, 3}, -	{127, 5, 3}, -	{129, 5, 3}, -	{131, 5, 3}, -	{134, 5, 3}, -	{138, 5, 3}, -	{148, 5, 3}, -	{157, 5, 3}, -	{169, 5, 3}, -	{172, 5, 3}, -	{190, 5, 3}, -	{195, 5, 3}, -	{196, 5, 3}, -	{208, 5, 3}, -	{141, 5, 4}, -	{150, 5, 4}, -	{166, 5, 4}, -	{176, 5, 4}, -	{177, 5, 4}, -	{183, 5, 4}, -	{202, 5, 4} +static struct pll_limit cx700_pll_limits[] = { +	{98, 98, 3, 1}, +	{86, 86, 4, 1}, +	{109, 208, 5, 1}, +	{68, 68, 2, 2}, +	{95, 116, 3, 2}, +	{93, 166, 4, 2}, +	{110, 206, 5, 2}, +	{174, 174, 7, 2}, +	{82, 109, 3, 3}, +	{117, 161, 4, 3}, +	{112, 208, 5, 3}, +	{141, 202, 5, 4}  }; -static struct pll_config vx855_pll_config[] = { -	{86, 4, 1}, -	{108, 5, 1}, -	{110, 5, 1}, -	{113, 5, 1}, -	{121, 5, 1}, -	{131, 5, 1}, -	{135, 5, 1}, -	{142, 5, 1}, -	{143, 5, 1}, -	{153, 5, 1}, -	{164, 5, 1}, -	{187, 5, 1}, -	{208, 5, 1}, -	{110, 5, 2}, -	{112, 5, 2}, -	{117, 5, 2}, -	{118, 5, 2}, -	{124, 5, 2}, -	{132, 5, 2}, -	{137, 5, 2}, -	{141, 5, 2}, -	{149, 5, 2}, -	{151, 5, 2}, -	{159, 5, 2}, -	{166, 5, 2}, -	{167, 5, 2}, -	{172, 5, 2}, -	{189, 5, 2}, -	{191, 5, 2}, -	{194, 5, 2}, -	{206, 5, 2}, -	{208, 5, 2}, -	{83, 3, 3}, -	{88, 3, 3}, -	{109, 3, 3}, -	{112, 3, 3}, -	{103, 4, 3}, -	{105, 4, 3}, -	{161, 4, 3}, -	{112, 5, 3}, -	{115, 5, 3}, -	{121, 5, 3}, -	{127, 5, 3}, -	{134, 5, 3}, -	{137, 5, 3}, -	{148, 5, 3}, -	{157, 5, 3}, -	{169, 5, 3}, -	{172, 5, 3}, -	{182, 5, 3}, -	{191, 5, 3}, -	{195, 5, 3}, -	{209, 5, 3}, -	{142, 4, 4}, -	{146, 4, 4}, -	{161, 4, 4}, -	{141, 5, 4}, -	{150, 5, 4}, -	{165, 5, 4}, -	{176, 5, 4} +static struct pll_limit vx855_pll_limits[] = { +	{86, 86, 4, 1}, +	{108, 208, 5, 1}, +	{110, 208, 5, 2}, +	{83, 112, 3, 3}, +	{103, 161, 4, 3}, +	{112, 209, 5, 3}, +	{142, 161, 4, 4}, +	{141, 176, 5, 4}  };  /* according to VIA Technologies these values are based on experiment */ @@ -308,6 +118,42 @@ static struct io_reg scaling_parameters[] = {  	{VIACR, CR87, 0xFF, 0x1F},	/* LCD Scaling Parameter 14 */  }; +static struct io_reg common_vga[] = { +	{VIACR, CR07, 0x10, 0x10}, /* [0] vertical total (bit 8) +					[1] vertical display end (bit 8) +					[2] vertical retrace start (bit 8) +					[3] start vertical blanking (bit 8) +					[4] line compare (bit 8) +					[5] vertical total (bit 9) +					[6] vertical display end (bit 9) +					[7] vertical retrace start (bit 9) */ +	{VIACR, CR08, 0xFF, 0x00}, /* [0-4] preset row scan +					[5-6] byte panning */ +	{VIACR, CR09, 0xDF, 0x40}, /* [0-4] max scan line +					[5] start vertical blanking (bit 9) +					[6] line compare (bit 9) +					[7] scan doubling */ +	{VIACR, CR0A, 0xFF, 0x1E}, /* [0-4] cursor start +					[5] cursor disable */ +	{VIACR, CR0B, 0xFF, 0x00}, /* [0-4] cursor end +					[5-6] cursor skew */ +	{VIACR, CR0E, 0xFF, 0x00}, /* [0-7] cursor location (high) */ +	{VIACR, CR0F, 0xFF, 0x00}, /* [0-7] cursor location (low) */ +	{VIACR, CR11, 0xF0, 0x80}, /* [0-3] vertical retrace end +					[6] memory refresh bandwidth +					[7] CRTC register protect enable */ +	{VIACR, CR14, 0xFF, 0x00}, /* [0-4] underline location +					[5] divide memory address clock by 4 +					[6] double word addressing */ +	{VIACR, CR17, 0xFF, 0x63}, /* [0-1] mapping of display address 13-14 +					[2] divide scan line clock by 2 +					[3] divide memory address clock by 2 +					[5] address wrap +					[6] byte mode select +					[7] sync enable */ +	{VIACR, CR18, 0xFF, 0xFF}, /* [0-7] line compare */ +}; +  static struct fifo_depth_select display_fifo_depth_reg = {  	/* IGA1 FIFO Depth_Select */  	{IGA1_FIFO_DEPTH_SELECT_REG_NUM, {{SR17, 0, 7} } }, @@ -676,6 +522,9 @@ static struct via_device_mapping device_mapping[] = {  	{VIA_LVDS2, "LVDS2"}  }; +/* structure with function pointers to support clock control */ +static struct via_clock clock; +  static void load_fix_bit_crtc_reg(void);  static void __devinit init_gfx_chip_info(int chip_type);  static void __devinit init_tmds_chip_info(void); @@ -770,13 +619,14 @@ static u32 get_lcd_devices(int output_interface)  /*Set IGA path for each device*/  void viafb_set_iga_path(void)  { +	int crt_iga_path = 0;  	if (viafb_SAMM_ON == 1) {  		if (viafb_CRT_ON) {  			if (viafb_primary_dev == CRT_Device) -				viaparinfo->crt_setting_info->iga_path = IGA1; +				crt_iga_path = IGA1;  			else -				viaparinfo->crt_setting_info->iga_path = IGA2; +				crt_iga_path = IGA2;  		}  		if (viafb_DVI_ON) { @@ -793,8 +643,7 @@ void viafb_set_iga_path(void)  					UNICHROME_CLE266)) {  					viaparinfo->  					lvds_setting_info->iga_path = IGA2; -					viaparinfo-> -					crt_setting_info->iga_path = IGA1; +					crt_iga_path = IGA1;  					viaparinfo->  					tmds_setting_info->iga_path = IGA1;  				} else @@ -814,10 +663,10 @@ void viafb_set_iga_path(void)  		viafb_SAMM_ON = 0;  		if (viafb_CRT_ON && viafb_LCD_ON) { -			viaparinfo->crt_setting_info->iga_path = IGA1; +			crt_iga_path = IGA1;  			viaparinfo->lvds_setting_info->iga_path = IGA2;  		} else if (viafb_CRT_ON && viafb_DVI_ON) { -			viaparinfo->crt_setting_info->iga_path = IGA1; +			crt_iga_path = IGA1;  			viaparinfo->tmds_setting_info->iga_path = IGA2;  		} else if (viafb_LCD_ON && viafb_DVI_ON) {  			viaparinfo->tmds_setting_info->iga_path = IGA1; @@ -826,7 +675,7 @@ void viafb_set_iga_path(void)  			viaparinfo->lvds_setting_info->iga_path = IGA2;  			viaparinfo->lvds_setting_info2->iga_path = IGA2;  		} else if (viafb_CRT_ON) { -			viaparinfo->crt_setting_info->iga_path = IGA1; +			crt_iga_path = IGA1;  		} else if (viafb_LCD_ON) {  			viaparinfo->lvds_setting_info->iga_path = IGA2;  		} else if (viafb_DVI_ON) { @@ -837,7 +686,7 @@ void viafb_set_iga_path(void)  	viaparinfo->shared->iga1_devices = 0;  	viaparinfo->shared->iga2_devices = 0;  	if (viafb_CRT_ON) { -		if (viaparinfo->crt_setting_info->iga_path == IGA1) +		if (crt_iga_path == IGA1)  			viaparinfo->shared->iga1_devices |= VIA_CRT;  		else  			viaparinfo->shared->iga2_devices |= VIA_CRT; @@ -875,6 +724,10 @@ void viafb_set_iga_path(void)  				viaparinfo->chip_info->  				lvds_chip_info2.output_interface);  	} + +	/* looks like the OLPC has its display wired to DVP1 and LVDS2 */ +	if (machine_is_olpc()) +		viaparinfo->shared->iga2_devices = VIA_DVP1 | VIA_LVDS2;  }  static void set_color_register(u8 index, u8 red, u8 green, u8 blue) @@ -1162,25 +1015,17 @@ void via_odev_to_seq(struct seq_file *m, u32 odev)  static void load_fix_bit_crtc_reg(void)  { +	viafb_unlock_crt(); +  	/* always set to 1 */  	viafb_write_reg_mask(CR03, VIACR, 0x80, BIT7);  	/* line compare should set all bits = 1 (extend modes) */ -	viafb_write_reg(CR18, VIACR, 0xff); -	/* line compare should set all bits = 1 (extend modes) */ -	viafb_write_reg_mask(CR07, VIACR, 0x10, BIT4); -	/* line compare should set all bits = 1 (extend modes) */ -	viafb_write_reg_mask(CR09, VIACR, 0x40, BIT6); -	/* line compare should set all bits = 1 (extend modes) */  	viafb_write_reg_mask(CR35, VIACR, 0x10, BIT4);  	/* line compare should set all bits = 1 (extend modes) */  	viafb_write_reg_mask(CR33, VIACR, 0x06, BIT0 + BIT1 + BIT2);  	/*viafb_write_reg_mask(CR32, VIACR, 0x01, BIT0); */ -	/* extend mode always set to e3h */ -	viafb_write_reg(CR17, VIACR, 0xe3); -	/* extend mode always set to 0h */ -	viafb_write_reg(CR08, VIACR, 0x00); -	/* extend mode always set to 0h */ -	viafb_write_reg(CR14, VIACR, 0x00); + +	viafb_lock_crt();  	/* If K8M800, enable Prefetch Mode. */  	if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) @@ -1601,69 +1446,54 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active)  } -static u32 cle266_encode_pll(struct pll_config pll) -{ -	return (pll.multiplier << 8) -		| (pll.rshift << 6) -		| pll.divisor; -} - -static u32 k800_encode_pll(struct pll_config pll) -{ -	return ((pll.divisor - 2) << 16) -		| (pll.rshift << 10) -		| (pll.multiplier - 2); -} - -static u32 vx855_encode_pll(struct pll_config pll) -{ -	return (pll.divisor << 16) -		| (pll.rshift << 10) -		| pll.multiplier; -} - -static inline u32 get_pll_internal_frequency(u32 ref_freq, -	struct pll_config pll) -{ -	return ref_freq / pll.divisor * pll.multiplier; -} - -static inline u32 get_pll_output_frequency(u32 ref_freq, struct pll_config pll) -{ -	return get_pll_internal_frequency(ref_freq, pll)>>pll.rshift; -} - -static struct pll_config get_pll_config(struct pll_config *config, int size, +static struct via_pll_config get_pll_config(struct pll_limit *limits, int size,  	int clk)  { -	struct pll_config best = config[0]; +	struct via_pll_config cur, up, down, best = {0, 1, 0};  	const u32 f0 = 14318180; /* X1 frequency */ -	int i; +	int i, f; -	for (i = 1; i < size; i++) { -		if (abs(get_pll_output_frequency(f0, config[i]) - clk) -			< abs(get_pll_output_frequency(f0, best) - clk)) -			best = config[i]; +	for (i = 0; i < size; i++) { +		cur.rshift = limits[i].rshift; +		cur.divisor = limits[i].divisor; +		cur.multiplier = clk / ((f0 / cur.divisor)>>cur.rshift); +		f = abs(get_pll_output_frequency(f0, cur) - clk); +		up = down = cur; +		up.multiplier++; +		down.multiplier--; +		if (abs(get_pll_output_frequency(f0, up) - clk) < f) +			cur = up; +		else if (abs(get_pll_output_frequency(f0, down) - clk) < f) +			cur = down; + +		if (cur.multiplier < limits[i].multiplier_min) +			cur.multiplier = limits[i].multiplier_min; +		else if (cur.multiplier > limits[i].multiplier_max) +			cur.multiplier = limits[i].multiplier_max; + +		f = abs(get_pll_output_frequency(f0, cur) - clk); +		if (f < abs(get_pll_output_frequency(f0, best) - clk)) +			best = cur;  	}  	return best;  } -u32 viafb_get_clk_value(int clk) +static struct via_pll_config get_best_pll_config(int clk)  { -	u32 value = 0; +	struct via_pll_config config;  	switch (viaparinfo->chip_info->gfx_chip_name) {  	case UNICHROME_CLE266:  	case UNICHROME_K400: -		value = cle266_encode_pll(get_pll_config(cle266_pll_config, -			ARRAY_SIZE(cle266_pll_config), clk)); +		config = get_pll_config(cle266_pll_limits, +			ARRAY_SIZE(cle266_pll_limits), clk);  		break;  	case UNICHROME_K800:  	case UNICHROME_PM800:  	case UNICHROME_CN700: -		value = k800_encode_pll(get_pll_config(k800_pll_config, -			ARRAY_SIZE(k800_pll_config), clk)); +		config = get_pll_config(k800_pll_limits, +			ARRAY_SIZE(k800_pll_limits), clk);  		break;  	case UNICHROME_CX700:  	case UNICHROME_CN750: @@ -1671,92 +1501,28 @@ u32 viafb_get_clk_value(int clk)  	case UNICHROME_P4M890:  	case UNICHROME_P4M900:  	case UNICHROME_VX800: -		value = k800_encode_pll(get_pll_config(cx700_pll_config, -			ARRAY_SIZE(cx700_pll_config), clk)); +		config = get_pll_config(cx700_pll_limits, +			ARRAY_SIZE(cx700_pll_limits), clk);  		break;  	case UNICHROME_VX855:  	case UNICHROME_VX900: -		value = vx855_encode_pll(get_pll_config(vx855_pll_config, -			ARRAY_SIZE(vx855_pll_config), clk)); +		config = get_pll_config(vx855_pll_limits, +			ARRAY_SIZE(vx855_pll_limits), clk);  		break;  	} -	return value; +	return config;  }  /* Set VCLK*/  void viafb_set_vclock(u32 clk, int set_iga)  { -	/* H.W. Reset : ON */ -	viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7); - -	if (set_iga == IGA1) { -		/* Change D,N FOR VCLK */ -		switch (viaparinfo->chip_info->gfx_chip_name) { -		case UNICHROME_CLE266: -		case UNICHROME_K400: -			via_write_reg(VIASR, SR46, (clk & 0x00FF)); -			via_write_reg(VIASR, SR47, (clk & 0xFF00) >> 8); -			break; - -		case UNICHROME_K800: -		case UNICHROME_PM800: -		case UNICHROME_CN700: -		case UNICHROME_CX700: -		case UNICHROME_CN750: -		case UNICHROME_K8M890: -		case UNICHROME_P4M890: -		case UNICHROME_P4M900: -		case UNICHROME_VX800: -		case UNICHROME_VX855: -		case UNICHROME_VX900: -			via_write_reg(VIASR, SR44, (clk & 0x0000FF)); -			via_write_reg(VIASR, SR45, (clk & 0x00FF00) >> 8); -			via_write_reg(VIASR, SR46, (clk & 0xFF0000) >> 16); -			break; -		} -	} +	struct via_pll_config config = get_best_pll_config(clk); -	if (set_iga == IGA2) { -		/* Change D,N FOR LCK */ -		switch (viaparinfo->chip_info->gfx_chip_name) { -		case UNICHROME_CLE266: -		case UNICHROME_K400: -			via_write_reg(VIASR, SR44, (clk & 0x00FF)); -			via_write_reg(VIASR, SR45, (clk & 0xFF00) >> 8); -			break; - -		case UNICHROME_K800: -		case UNICHROME_PM800: -		case UNICHROME_CN700: -		case UNICHROME_CX700: -		case UNICHROME_CN750: -		case UNICHROME_K8M890: -		case UNICHROME_P4M890: -		case UNICHROME_P4M900: -		case UNICHROME_VX800: -		case UNICHROME_VX855: -		case UNICHROME_VX900: -			via_write_reg(VIASR, SR4A, (clk & 0x0000FF)); -			via_write_reg(VIASR, SR4B, (clk & 0x00FF00) >> 8); -			via_write_reg(VIASR, SR4C, (clk & 0xFF0000) >> 16); -			break; -		} -	} - -	/* H.W. Reset : OFF */ -	viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7); - -	/* Reset PLL */ -	if (set_iga == IGA1) { -		viafb_write_reg_mask(SR40, VIASR, 0x02, BIT1); -		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT1); -	} - -	if (set_iga == IGA2) { -		viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); -		viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); -	} +	if (set_iga == IGA1) +		clock.set_primary_pll(config); +	if (set_iga == IGA2) +		clock.set_secondary_pll(config);  	/* Fire! */  	via_write_misc_reg_mask(0x0C, 0x0C); /* select external clock */ @@ -2002,7 +1768,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,  	int i;  	int index = 0;  	int h_addr, v_addr; -	u32 pll_D_N, clock, refresh = viafb_refresh; +	u32 clock, refresh = viafb_refresh;  	if (viafb_SAMM_ON && set_iga == IGA2)  		refresh = viafb_refresh1; @@ -2033,8 +1799,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,  	v_addr = crt_reg.ver_addr;  	if (set_iga == IGA1) {  		viafb_unlock_crt(); -		viafb_write_reg(CR09, VIACR, 0x00);	/*initial CR09=0 */ -		viafb_write_reg_mask(CR11, VIACR, 0x00, BIT4 + BIT5 + BIT6);  		viafb_write_reg_mask(CR17, VIACR, 0x00, BIT7);  	} @@ -2047,7 +1811,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,  		break;  	} -	load_fix_bit_crtc_reg();  	viafb_lock_crt();  	viafb_write_reg_mask(CR17, VIACR, 0x80, BIT7);  	viafb_load_fetch_count_reg(h_addr, bpp_byte, set_iga); @@ -2059,20 +1822,17 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table,  	clock = crt_reg.hor_total * crt_reg.ver_total  		* crt_table[index].refresh_rate; -	pll_D_N = viafb_get_clk_value(clock); -	DEBUG_MSG(KERN_INFO "PLL=%x", pll_D_N); -	viafb_set_vclock(pll_D_N, set_iga); +	viafb_set_vclock(clock, set_iga);  }  void __devinit viafb_init_chip_info(int chip_type)  { +	via_clock_init(&clock, chip_type);  	init_gfx_chip_info(chip_type);  	init_tmds_chip_info();  	init_lvds_chip_info(); -	viaparinfo->crt_setting_info->iga_path = IGA1; -  	/*Set IGA path for each device */  	viafb_set_iga_path(); @@ -2354,6 +2114,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,  	outb(0x00, VIAAR);  	/* Write Common Setting for Video Mode */ +	viafb_write_regx(common_vga, ARRAY_SIZE(common_vga));  	switch (viaparinfo->chip_info->gfx_chip_name) {  	case UNICHROME_CLE266:  		viafb_write_regx(CLE266_ModeXregs, NUM_TOTAL_CLE266_ModeXregs); @@ -2400,9 +2161,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,  	viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); -	/* Write CRTC */ -	viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); -  	/* Write Graphic Controller */  	for (i = 0; i < StdGR; i++)  		via_write_reg(VIAGR, i, VPIT.GR[i]); @@ -2432,6 +2190,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,  		}  	} +	load_fix_bit_crtc_reg();  	via_set_primary_pitch(viafbinfo->fix.line_length);  	via_set_secondary_pitch(viafb_dual_fb ? viafbinfo1->fix.line_length  		: viafbinfo->fix.line_length); @@ -2451,15 +2210,15 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,  	/* CRT set mode */  	if (viafb_CRT_ON) { -		if (viafb_SAMM_ON && (viaparinfo->crt_setting_info->iga_path == -			IGA2)) { +		if (viafb_SAMM_ON && +			viaparinfo->shared->iga2_devices & VIA_CRT) {  			viafb_fill_crtc_timing(crt_timing1, vmode_tbl1, -				video_bpp1 / 8, -				viaparinfo->crt_setting_info->iga_path); +				video_bpp1 / 8, IGA2);  		} else {  			viafb_fill_crtc_timing(crt_timing, vmode_tbl,  				video_bpp / 8, -				viaparinfo->crt_setting_info->iga_path); +				(viaparinfo->shared->iga1_devices & VIA_CRT) +				? IGA1 : IGA2);  		}  		/* Patch if set_hres is not 8 alignment (1366) to viafb_setmode @@ -2557,6 +2316,33 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp,  			get_sync(viafbinfo1));  	} +	clock.set_engine_pll_state(VIA_STATE_ON); +	clock.set_primary_clock_source(VIA_CLKSRC_X1, true); +	clock.set_secondary_clock_source(VIA_CLKSRC_X1, true); + +#ifdef CONFIG_FB_VIA_X_COMPATIBILITY +	clock.set_primary_pll_state(VIA_STATE_ON); +	clock.set_primary_clock_state(VIA_STATE_ON); +	clock.set_secondary_pll_state(VIA_STATE_ON); +	clock.set_secondary_clock_state(VIA_STATE_ON); +#else +	if (viaparinfo->shared->iga1_devices) { +		clock.set_primary_pll_state(VIA_STATE_ON); +		clock.set_primary_clock_state(VIA_STATE_ON); +	} else { +		clock.set_primary_pll_state(VIA_STATE_OFF); +		clock.set_primary_clock_state(VIA_STATE_OFF); +	} + +	if (viaparinfo->shared->iga2_devices) { +		clock.set_secondary_pll_state(VIA_STATE_ON); +		clock.set_secondary_clock_state(VIA_STATE_ON); +	} else { +		clock.set_secondary_pll_state(VIA_STATE_OFF); +		clock.set_secondary_clock_state(VIA_STATE_OFF); +	} +#endif /*CONFIG_FB_VIA_X_COMPATIBILITY*/ +  	via_set_state(devices, VIA_STATE_ON);  	device_screen_on();  	return 1; @@ -2598,8 +2384,12 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh)  			best = &vmode->crtc[i];  	} -	if (abs(best->refresh_rate - long_refresh) > 3) -		return 60; +	if (abs(best->refresh_rate - long_refresh) > 3) { +		if (hres == 1200 && vres == 900) +			return 49; /* OLPC DCON only supports 50 Hz */ +		else +			return 60; +	}  	return best->refresh_rate;  } diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 8858593405a..c7239eb83ba 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -732,20 +732,13 @@ struct _lcd_scaling_factor {  	struct _lcd_ver_scaling_factor lcd_ver_scaling_factor;  }; -struct pll_config { -	u16 multiplier; +struct pll_limit { +	u16 multiplier_min; +	u16 multiplier_max;  	u8 divisor;  	u8 rshift;  }; -struct pll_map { -	u32 clk; -	struct pll_config cle266_pll; -	struct pll_config k800_pll; -	struct pll_config cx700_pll; -	struct pll_config vx855_pll; -}; -  struct rgbLUT {  	u8 red;  	u8 green; @@ -910,7 +903,6 @@ struct via_device_mapping {  	const char *name;  }; -extern unsigned int viafb_second_virtual_xres;  extern int viafb_SAMM_ON;  extern int viafb_dual_fb;  extern int viafb_LCD2_ON; @@ -936,7 +928,6 @@ void viafb_lock_crt(void);  void viafb_unlock_crt(void);  void viafb_load_fetch_count_reg(int h_addr, int bpp_byte, int set_iga);  void viafb_write_regx(struct io_reg RegTable[], int ItemNum); -u32 viafb_get_clk_value(int clk);  void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active);  void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\  					*p_gfx_dpa_setting); diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index 64bc7e76310..6e06981d638 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -48,7 +48,6 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = {  	{LCD_VER_SCALING_FACTOR_REG_NUM_CLE, {{CR78, 0, 7}, {CR79, 6, 7} } }  }; -static int check_lvds_chip(int device_id_subaddr, int device_id);  static bool lvds_identify_integratedlvds(void);  static void __devinit fp_id_to_vindex(int panel_id);  static int lvds_register_read(int index); @@ -84,12 +83,9 @@ static struct display_timing lcd_centering_timging(struct display_timing  					    mode_crt_reg,  					   struct display_timing panel_crt_reg); -static int check_lvds_chip(int device_id_subaddr, int device_id) +static inline bool check_lvds_chip(int device_id_subaddr, int device_id)  { -	if (lvds_register_read(device_id_subaddr) == device_id) -		return OK; -	else -		return FAIL; +	return lvds_register_read(device_id_subaddr) == device_id;  }  void __devinit viafb_init_lcd_size(void) @@ -150,7 +146,7 @@ static bool lvds_identify_integratedlvds(void)  	return true;  } -int __devinit viafb_lvds_trasmitter_identify(void) +bool __devinit viafb_lvds_trasmitter_identify(void)  {  	if (viafb_lvds_identify_vt1636(VIA_PORT_31)) {  		viaparinfo->chip_info->lvds_chip_info.i2c_port = VIA_PORT_31; @@ -175,20 +171,20 @@ int __devinit viafb_lvds_trasmitter_identify(void)  	viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =  		VT1631_LVDS_I2C_ADDR; -	if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID) != FAIL) { +	if (check_lvds_chip(VT1631_DEVICE_ID_REG, VT1631_DEVICE_ID)) {  		DEBUG_MSG(KERN_INFO "\n VT1631 LVDS ! \n");  		DEBUG_MSG(KERN_INFO "\n %2d",  			  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name);  		DEBUG_MSG(KERN_INFO "\n %2d",  			  viaparinfo->chip_info->lvds_chip_info.lvds_chip_name); -		return OK; +		return true;  	}  	viaparinfo->chip_info->lvds_chip_info.lvds_chip_name =  		NON_LVDS_TRANSMITTER;  	viaparinfo->chip_info->lvds_chip_info.lvds_chip_slave_addr =  		VT1631_LVDS_I2C_ADDR; -	return FAIL; +	return false;  }  static void __devinit fp_id_to_vindex(int panel_id) @@ -562,7 +558,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,  	int set_vres = plvds_setting_info->v_active;  	int panel_hres = plvds_setting_info->lcd_panel_hres;  	int panel_vres = plvds_setting_info->lcd_panel_vres; -	u32 pll_D_N, clock; +	u32 clock;  	struct display_timing mode_crt_reg, panel_crt_reg;  	struct crt_mode_table *panel_crt_table = NULL;  	struct VideoModeTable *vmode_tbl = viafb_get_mode(panel_hres, @@ -613,10 +609,7 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,  		viafb_load_FIFO_reg(set_iga, set_hres, set_vres);  	fill_lcd_format(); - -	pll_D_N = viafb_get_clk_value(clock); -	DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); -	viafb_set_vclock(pll_D_N, set_iga); +	viafb_set_vclock(clock, set_iga);  	lcd_patch_skew(plvds_setting_info, plvds_chip_info);  	/* If K8M800, enable LCD Prefetch Mode. */ diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h index c7909fe2955..75f60a655b0 100644 --- a/drivers/video/via/lcd.h +++ b/drivers/video/via/lcd.h @@ -79,7 +79,7 @@ void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information  void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table,  		  struct lvds_setting_information *plvds_setting_info,  		  struct lvds_chip_information *plvds_chip_info); -int __devinit viafb_lvds_trasmitter_identify(void); +bool __devinit viafb_lvds_trasmitter_identify(void);  void viafb_init_lvds_output_interface(struct lvds_chip_information  				*plvds_chip_info,  				struct lvds_setting_information diff --git a/drivers/video/via/share.h b/drivers/video/via/share.h index 4b7831f0d01..61b0bd596b8 100644 --- a/drivers/video/via/share.h +++ b/drivers/video/via/share.h @@ -22,14 +22,6 @@  #ifndef __SHARE_H__  #define __SHARE_H__ -/* Define Return Value */ -#define FAIL        -1 -#define OK          1 - -#ifndef NULL -#define NULL 0 -#endif -  /* Define Bit Field */  #define BIT0    0x01  #define BIT1    0x02 @@ -290,6 +282,7 @@  #define HW_LAYOUT_LCD_EXTERNAL_LCD2 0x10  /* Definition Refresh Rate */ +#define REFRESH_49      49  #define REFRESH_50      50  #define REFRESH_60      60  #define REFRESH_75      75 @@ -575,10 +568,6 @@  #define M1280X720_R50_HSP       NEGATIVE  #define M1280X720_R50_VSP       POSITIVE -/* 1280x720@60 Sync Polarity  (CEA Mode) */ -#define M1280X720_CEA_R60_HSP       POSITIVE -#define M1280X720_CEA_R60_VSP       POSITIVE -  /* 1440x900@60 Sync Polarity (CVT Mode) */  #define M1440X900_R60_HSP       NEGATIVE  #define M1440X900_R60_VSP       POSITIVE @@ -619,10 +608,6 @@  #define M1920X1200_RB_R60_HSP  POSITIVE  #define M1920X1200_RB_R60_VSP  NEGATIVE -/* 1920x1080@60 Sync Polarity  (CEA Mode) */ -#define M1920X1080_CEA_R60_HSP       POSITIVE -#define M1920X1080_CEA_R60_VSP       POSITIVE -  /* 2048x1536@60 Sync Polarity (CVT Mode) */  #define M2048x1536_R60_HSP      NEGATIVE  #define M2048x1536_R60_VSP      POSITIVE diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 6723d6910cd..eb112b62173 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -505,7 +505,14 @@ static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev)  	ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type);  	if (ret < 0)  		goto out_unmap; -	vdev->fbmem = ioremap_nocache(vdev->fbmem_start, vdev->fbmem_len); + +	/* try to map less memory on failure, 8 MB should be still enough */ +	for (; vdev->fbmem_len >= 8 << 20; vdev->fbmem_len /= 2) { +		vdev->fbmem = ioremap_wc(vdev->fbmem_start, vdev->fbmem_len); +		if (vdev->fbmem) +			break; +	} +  	if (vdev->fbmem == NULL) {  		ret = -ENOMEM;  		goto out_unmap; diff --git a/drivers/video/via/via_clock.c b/drivers/video/via/via_clock.c new file mode 100644 index 00000000000..af8f26b643c --- /dev/null +++ b/drivers/video/via/via_clock.c @@ -0,0 +1,349 @@ +/* + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> + * + * 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. + */ +/* + * clock and PLL management functions + */ + +#include <linux/kernel.h> +#include <linux/via-core.h> +#include "via_clock.h" +#include "global.h" +#include "debug.h" + +const char *via_slap = "Please slap VIA Technologies to motivate them " +	"releasing full documentation for your platform!\n"; + +static inline u32 cle266_encode_pll(struct via_pll_config pll) +{ +	return (pll.multiplier << 8) +		| (pll.rshift << 6) +		| pll.divisor; +} + +static inline u32 k800_encode_pll(struct via_pll_config pll) +{ +	return ((pll.divisor - 2) << 16) +		| (pll.rshift << 10) +		| (pll.multiplier - 2); +} + +static inline u32 vx855_encode_pll(struct via_pll_config pll) +{ +	return (pll.divisor << 16) +		| (pll.rshift << 10) +		| pll.multiplier; +} + +static inline void cle266_set_primary_pll_encoded(u32 data) +{ +	via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ +	via_write_reg(VIASR, 0x46, data & 0xFF); +	via_write_reg(VIASR, 0x47, (data >> 8) & 0xFF); +	via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void k800_set_primary_pll_encoded(u32 data) +{ +	via_write_reg_mask(VIASR, 0x40, 0x02, 0x02); /* enable reset */ +	via_write_reg(VIASR, 0x44, data & 0xFF); +	via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); +	via_write_reg(VIASR, 0x46, (data >> 16) & 0xFF); +	via_write_reg_mask(VIASR, 0x40, 0x00, 0x02); /* disable reset */ +} + +static inline void cle266_set_secondary_pll_encoded(u32 data) +{ +	via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ +	via_write_reg(VIASR, 0x44, data & 0xFF); +	via_write_reg(VIASR, 0x45, (data >> 8) & 0xFF); +	via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static inline void k800_set_secondary_pll_encoded(u32 data) +{ +	via_write_reg_mask(VIASR, 0x40, 0x04, 0x04); /* enable reset */ +	via_write_reg(VIASR, 0x4A, data & 0xFF); +	via_write_reg(VIASR, 0x4B, (data >> 8) & 0xFF); +	via_write_reg(VIASR, 0x4C, (data >> 16) & 0xFF); +	via_write_reg_mask(VIASR, 0x40, 0x00, 0x04); /* disable reset */ +} + +static inline void set_engine_pll_encoded(u32 data) +{ +	via_write_reg_mask(VIASR, 0x40, 0x01, 0x01); /* enable reset */ +	via_write_reg(VIASR, 0x47, data & 0xFF); +	via_write_reg(VIASR, 0x48, (data >> 8) & 0xFF); +	via_write_reg(VIASR, 0x49, (data >> 16) & 0xFF); +	via_write_reg_mask(VIASR, 0x40, 0x00, 0x01); /* disable reset */ +} + +static void cle266_set_primary_pll(struct via_pll_config config) +{ +	cle266_set_primary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_primary_pll(struct via_pll_config config) +{ +	k800_set_primary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_primary_pll(struct via_pll_config config) +{ +	k800_set_primary_pll_encoded(vx855_encode_pll(config)); +} + +static void cle266_set_secondary_pll(struct via_pll_config config) +{ +	cle266_set_secondary_pll_encoded(cle266_encode_pll(config)); +} + +static void k800_set_secondary_pll(struct via_pll_config config) +{ +	k800_set_secondary_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_secondary_pll(struct via_pll_config config) +{ +	k800_set_secondary_pll_encoded(vx855_encode_pll(config)); +} + +static void k800_set_engine_pll(struct via_pll_config config) +{ +	set_engine_pll_encoded(k800_encode_pll(config)); +} + +static void vx855_set_engine_pll(struct via_pll_config config) +{ +	set_engine_pll_encoded(vx855_encode_pll(config)); +} + +static void set_primary_pll_state(u8 state) +{ +	u8 value; + +	switch (state) { +	case VIA_STATE_ON: +		value = 0x20; +		break; +	case VIA_STATE_OFF: +		value = 0x00; +		break; +	default: +		return; +	} + +	via_write_reg_mask(VIASR, 0x2D, value, 0x30); +} + +static void set_secondary_pll_state(u8 state) +{ +	u8 value; + +	switch (state) { +	case VIA_STATE_ON: +		value = 0x08; +		break; +	case VIA_STATE_OFF: +		value = 0x00; +		break; +	default: +		return; +	} + +	via_write_reg_mask(VIASR, 0x2D, value, 0x0C); +} + +static void set_engine_pll_state(u8 state) +{ +	u8 value; + +	switch (state) { +	case VIA_STATE_ON: +		value = 0x02; +		break; +	case VIA_STATE_OFF: +		value = 0x00; +		break; +	default: +		return; +	} + +	via_write_reg_mask(VIASR, 0x2D, value, 0x03); +} + +static void set_primary_clock_state(u8 state) +{ +	u8 value; + +	switch (state) { +	case VIA_STATE_ON: +		value = 0x20; +		break; +	case VIA_STATE_OFF: +		value = 0x00; +		break; +	default: +		return; +	} + +	via_write_reg_mask(VIASR, 0x1B, value, 0x30); +} + +static void set_secondary_clock_state(u8 state) +{ +	u8 value; + +	switch (state) { +	case VIA_STATE_ON: +		value = 0x80; +		break; +	case VIA_STATE_OFF: +		value = 0x00; +		break; +	default: +		return; +	} + +	via_write_reg_mask(VIASR, 0x1B, value, 0xC0); +} + +static inline u8 set_clock_source_common(enum via_clksrc source, bool use_pll) +{ +	u8 data = 0; + +	switch (source) { +	case VIA_CLKSRC_X1: +		data = 0x00; +		break; +	case VIA_CLKSRC_TVX1: +		data = 0x02; +		break; +	case VIA_CLKSRC_TVPLL: +		data = 0x04; /* 0x06 should be the same */ +		break; +	case VIA_CLKSRC_DVP1TVCLKR: +		data = 0x0A; +		break; +	case VIA_CLKSRC_CAP0: +		data = 0xC; +		break; +	case VIA_CLKSRC_CAP1: +		data = 0x0E; +		break; +	} + +	if (!use_pll) +		data |= 1; + +	return data; +} + +static void set_primary_clock_source(enum via_clksrc source, bool use_pll) +{ +	u8 data = set_clock_source_common(source, use_pll) << 4; +	via_write_reg_mask(VIACR, 0x6C, data, 0xF0); +} + +static void set_secondary_clock_source(enum via_clksrc source, bool use_pll) +{ +	u8 data = set_clock_source_common(source, use_pll); +	via_write_reg_mask(VIACR, 0x6C, data, 0x0F); +} + +static void dummy_set_clock_state(u8 state) +{ +	printk(KERN_INFO "Using undocumented set clock state.\n%s", via_slap); +} + +static void dummy_set_clock_source(enum via_clksrc source, bool use_pll) +{ +	printk(KERN_INFO "Using undocumented set clock source.\n%s", via_slap); +} + +static void dummy_set_pll_state(u8 state) +{ +	printk(KERN_INFO "Using undocumented set PLL state.\n%s", via_slap); +} + +static void dummy_set_pll(struct via_pll_config config) +{ +	printk(KERN_INFO "Using undocumented set PLL.\n%s", via_slap); +} + +void via_clock_init(struct via_clock *clock, int gfx_chip) +{ +	switch (gfx_chip) { +	case UNICHROME_CLE266: +	case UNICHROME_K400: +		clock->set_primary_clock_state = dummy_set_clock_state; +		clock->set_primary_clock_source = dummy_set_clock_source; +		clock->set_primary_pll_state = dummy_set_pll_state; +		clock->set_primary_pll = cle266_set_primary_pll; + +		clock->set_secondary_clock_state = dummy_set_clock_state; +		clock->set_secondary_clock_source = dummy_set_clock_source; +		clock->set_secondary_pll_state = dummy_set_pll_state; +		clock->set_secondary_pll = cle266_set_secondary_pll; + +		clock->set_engine_pll_state = dummy_set_pll_state; +		clock->set_engine_pll = dummy_set_pll; +		break; +	case UNICHROME_K800: +	case UNICHROME_PM800: +	case UNICHROME_CN700: +	case UNICHROME_CX700: +	case UNICHROME_CN750: +	case UNICHROME_K8M890: +	case UNICHROME_P4M890: +	case UNICHROME_P4M900: +	case UNICHROME_VX800: +		clock->set_primary_clock_state = set_primary_clock_state; +		clock->set_primary_clock_source = set_primary_clock_source; +		clock->set_primary_pll_state = set_primary_pll_state; +		clock->set_primary_pll = k800_set_primary_pll; + +		clock->set_secondary_clock_state = set_secondary_clock_state; +		clock->set_secondary_clock_source = set_secondary_clock_source; +		clock->set_secondary_pll_state = set_secondary_pll_state; +		clock->set_secondary_pll = k800_set_secondary_pll; + +		clock->set_engine_pll_state = set_engine_pll_state; +		clock->set_engine_pll = k800_set_engine_pll; +		break; +	case UNICHROME_VX855: +	case UNICHROME_VX900: +		clock->set_primary_clock_state = set_primary_clock_state; +		clock->set_primary_clock_source = set_primary_clock_source; +		clock->set_primary_pll_state = set_primary_pll_state; +		clock->set_primary_pll = vx855_set_primary_pll; + +		clock->set_secondary_clock_state = set_secondary_clock_state; +		clock->set_secondary_clock_source = set_secondary_clock_source; +		clock->set_secondary_pll_state = set_secondary_pll_state; +		clock->set_secondary_pll = vx855_set_secondary_pll; + +		clock->set_engine_pll_state = set_engine_pll_state; +		clock->set_engine_pll = vx855_set_engine_pll; +		break; + +	} +} diff --git a/drivers/video/via/via_clock.h b/drivers/video/via/via_clock.h new file mode 100644 index 00000000000..88714ae0d15 --- /dev/null +++ b/drivers/video/via/via_clock.h @@ -0,0 +1,76 @@ +/* + * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved. + * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved. + * Copyright 2011 Florian Tobias Schandinat <FlorianSchandinat@gmx.de> + * + * 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. + */ +/* + * clock and PLL management functions + */ + +#ifndef __VIA_CLOCK_H__ +#define __VIA_CLOCK_H__ + +#include <linux/types.h> + +enum via_clksrc { +	VIA_CLKSRC_X1 = 0, +	VIA_CLKSRC_TVX1, +	VIA_CLKSRC_TVPLL, +	VIA_CLKSRC_DVP1TVCLKR, +	VIA_CLKSRC_CAP0, +	VIA_CLKSRC_CAP1, +}; + +struct via_pll_config { +	u16 multiplier; +	u8 divisor; +	u8 rshift; +}; + +struct via_clock { +	void (*set_primary_clock_state)(u8 state); +	void (*set_primary_clock_source)(enum via_clksrc src, bool use_pll); +	void (*set_primary_pll_state)(u8 state); +	void (*set_primary_pll)(struct via_pll_config config); + +	void (*set_secondary_clock_state)(u8 state); +	void (*set_secondary_clock_source)(enum via_clksrc src, bool use_pll); +	void (*set_secondary_pll_state)(u8 state); +	void (*set_secondary_pll)(struct via_pll_config config); + +	void (*set_engine_pll_state)(u8 state); +	void (*set_engine_pll)(struct via_pll_config config); +}; + + +static inline u32 get_pll_internal_frequency(u32 ref_freq, +	struct via_pll_config pll) +{ +	return ref_freq / pll.divisor * pll.multiplier; +} + +static inline u32 get_pll_output_frequency(u32 ref_freq, +	struct via_pll_config pll) +{ +	return get_pll_internal_frequency(ref_freq, pll) >> pll.rshift; +} + +void via_clock_init(struct via_clock *clock, int gfx_chip); + +#endif /* __VIA_CLOCK_H__ */ diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index a542bed086e..cf43c80d27f 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -24,6 +24,7 @@  #include <linux/slab.h>  #include <linux/stat.h>  #include <linux/via-core.h> +#include <asm/olpc.h>  #define _MASTER_FILE  #include "global.h" @@ -37,6 +38,8 @@ static char *viafb_mode1;  static int viafb_bpp = 32;  static int viafb_bpp1 = 32; +static unsigned int viafb_second_xres = 640; +static unsigned int viafb_second_yres = 480;  static unsigned int viafb_second_offset;  static int viafb_second_size; @@ -440,8 +443,8 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg)  		if (viafb_SAMM_ON == 1) {  			u.viamode.xres_sec = viafb_second_xres;  			u.viamode.yres_sec = viafb_second_yres; -			u.viamode.virtual_xres_sec = viafb_second_virtual_xres; -			u.viamode.virtual_yres_sec = viafb_second_virtual_yres; +			u.viamode.virtual_xres_sec = viafb_dual_fb ? viafbinfo1->var.xres_virtual : viafbinfo->var.xres_virtual; +			u.viamode.virtual_yres_sec = viafb_dual_fb ? viafbinfo1->var.yres_virtual : viafbinfo->var.yres_virtual;  			u.viamode.refresh_sec = viafb_refresh1;  			u.viamode.bpp_sec = viafb_bpp1;  		} else { @@ -930,10 +933,8 @@ static int get_primary_device(void)  	/* Rule: device on iga1 path are the primary device. */  	if (viafb_SAMM_ON) {  		if (viafb_CRT_ON) { -			if (viaparinfo->crt_setting_info->iga_path == IGA1) { -				DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", -					viaparinfo-> -					crt_setting_info->iga_path); +			if (viaparinfo->shared->iga1_devices & VIA_CRT) { +				DEBUG_MSG(KERN_INFO "CRT IGA Path:%d\n", IGA1);  				primary_device = CRT_Device;  			}  		} @@ -1011,8 +1012,13 @@ static int __init parse_active_dev(void)  	/*    Note: The previous of active_dev is primary device,  	   and the following is secondary device. */  	if (!viafb_active_dev) { -		viafb_CRT_ON = STATE_ON; -		viafb_SAMM_ON = STATE_OFF; +		if (machine_is_olpc()) { /* LCD only */ +			viafb_LCD_ON = STATE_ON; +			viafb_SAMM_ON = STATE_OFF; +		} else { +			viafb_CRT_ON = STATE_ON; +			viafb_SAMM_ON = STATE_OFF; +		}  	} else if (!strcmp(viafb_active_dev, "CRT+DVI")) {  		/* CRT+DVI */  		viafb_CRT_ON = STATE_ON; @@ -1665,8 +1671,13 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres)  	char *ptr;  	if (!str) { -		*xres = 640; -		*yres = 480; +		if (machine_is_olpc()) { +			*xres = 1200; +			*yres = 900; +		} else { +			*xres = 640; +			*yres = 480; +		}  		return 0;  	} @@ -1746,7 +1757,6 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)  	viaparinfo->lvds_setting_info = &viaparinfo->shared->lvds_setting_info;  	viaparinfo->lvds_setting_info2 =  		&viaparinfo->shared->lvds_setting_info2; -	viaparinfo->crt_setting_info = &viaparinfo->shared->crt_setting_info;  	viaparinfo->chip_info = &viaparinfo->shared->chip_info;  	if (viafb_dual_fb) @@ -1793,14 +1803,10 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)  	parse_mode(viafb_mode, &default_xres, &default_yres);  	vmode_entry = viafb_get_mode(default_xres, default_yres); -	if (viafb_SAMM_ON == 1) { +	if (viafb_SAMM_ON == 1)  		parse_mode(viafb_mode1, &viafb_second_xres,  			&viafb_second_yres); -		viafb_second_virtual_xres = viafb_second_xres; -		viafb_second_virtual_yres = viafb_second_yres; -	} -  	default_var.xres = default_xres;  	default_var.yres = default_yres;  	default_var.xres_virtual = default_xres; @@ -1844,8 +1850,8 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev)  		default_var.xres = viafb_second_xres;  		default_var.yres = viafb_second_yres; -		default_var.xres_virtual = viafb_second_virtual_xres; -		default_var.yres_virtual = viafb_second_virtual_yres; +		default_var.xres_virtual = viafb_second_xres; +		default_var.yres_virtual = viafb_second_yres;  		default_var.bits_per_pixel = viafb_bpp1;  		viafb_fill_var_timing_info(&default_var, viafb_get_refresh(  			default_var.xres, default_var.yres, viafb_refresh1), @@ -1927,11 +1933,16 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev)  }  #ifndef MODULE -static int __init viafb_setup(char *options) +static int __init viafb_setup(void)  {  	char *this_opt; +	char *options; +  	DEBUG_MSG(KERN_INFO "viafb_setup!\n"); +	if (fb_get_options("viafb", &options)) +		return -ENODEV; +  	if (!options || !*options)  		return 0; @@ -2005,11 +2016,16 @@ static int __init viafb_setup(char *options)  int __init viafb_init(void)  {  	u32 dummy_x, dummy_y; +	int r; + +	if (machine_is_olpc()) +		/* Apply XO-1.5-specific configuration. */ +		viafb_lcd_panel_id = 23; +  #ifndef MODULE -	char *option = NULL; -	if (fb_get_options("viafb", &option)) -		return -ENODEV; -	viafb_setup(option); +	r = viafb_setup(); +	if (r < 0) +		return r;  #endif  	if (parse_mode(viafb_mode, &dummy_x, &dummy_y)  		|| !viafb_get_mode(dummy_x, dummy_y) diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 137996dc547..d9440635d1d 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -50,7 +50,6 @@ struct viafb_shared {  	/* All the information will be needed to set engine */  	struct tmds_setting_information tmds_setting_info; -	struct crt_setting_information crt_setting_info;  	struct lvds_setting_information lvds_setting_info;  	struct lvds_setting_information lvds_setting_info2;  	struct chip_information chip_info; @@ -79,14 +78,11 @@ struct viafb_par {  	/* All the information will be needed to set engine */  	/* depreciated, use the ones in shared directly */  	struct tmds_setting_information *tmds_setting_info; -	struct crt_setting_information *crt_setting_info;  	struct lvds_setting_information *lvds_setting_info;  	struct lvds_setting_information *lvds_setting_info2;  	struct chip_information *chip_info;  }; -extern unsigned int viafb_second_virtual_yres; -extern unsigned int viafb_second_virtual_xres;  extern int viafb_SAMM_ON;  extern int viafb_dual_fb;  extern int viafb_LCD2_ON; diff --git a/drivers/video/via/viamode.c b/drivers/video/via/viamode.c index 8c5bc41ff6a..58df74e1417 100644 --- a/drivers/video/via/viamode.c +++ b/drivers/video/via/viamode.c @@ -30,10 +30,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},  {VIASR, SR1A, 0xFB, 0x08},  {VIASR, SR1E, 0x0F, 0x01},  {VIASR, SR2A, 0xFF, 0x00}, -{VIACR, CR0A, 0xFF, 0x1E},	/* Cursor Start                        */ -{VIACR, CR0B, 0xFF, 0x00},	/* Cursor End                          */ -{VIACR, CR0E, 0xFF, 0x00},	/* Cursor Location High                */ -{VIACR, CR0F, 0xFF, 0x00},	/* Cursor Localtion Low                */  {VIACR, CR32, 0xFF, 0x00},  {VIACR, CR33, 0xFF, 0x00},  {VIACR, CR35, 0xFF, 0x00}, @@ -41,7 +37,6 @@ struct io_reg CN400_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},  {VIACR, CR69, 0xFF, 0x00},  {VIACR, CR6A, 0xFF, 0x40},  {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00},  {VIACR, CR88, 0xFF, 0x40},	/* LCD Panel Type                      */  {VIACR, CR89, 0xFF, 0x00},	/* LCD Timing Control 0                */  {VIACR, CR8A, 0xFF, 0x88},	/* LCD Timing Control 1                */ @@ -87,7 +82,6 @@ struct io_reg CN700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},  {VIACR, CR69, 0xFF, 0x00},  {VIACR, CR6A, 0xFD, 0x40},  {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00},  {VIACR, CR77, 0xFF, 0x00},	/* LCD scaling Factor */  {VIACR, CR78, 0xFF, 0x00},	/* LCD scaling Factor */  {VIACR, CR79, 0xFF, 0x00},	/* LCD scaling Factor */ @@ -125,10 +119,6 @@ struct io_reg KM400_ModeXregs[] = {  	{VIASR, SR2A, 0xFF, 0x00},	/* Power Management Control 5      */  	{VIASR, SR2D, 0xFF, 0xFF},	/* Power Management Control 1      */  	{VIASR, SR2E, 0xFF, 0xFF},	/* Power Management Control 2      */ -	{VIACR, CR0A, 0xFF, 0x1E},	/* Cursor Start                    */ -	{VIACR, CR0B, 0xFF, 0x00},	/* Cursor End                      */ -	{VIACR, CR0E, 0xFF, 0x00},	/* Cursor Location High            */ -	{VIACR, CR0F, 0xFF, 0x00},	/* Cursor Localtion Low            */  	{VIACR, CR33, 0xFF, 0x00},  	{VIACR, CR55, 0x80, 0x00},  	{VIACR, CR5D, 0x80, 0x00}, @@ -161,11 +151,7 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},  {VIASR, SR1B, 0xFF, 0xF0},  {VIASR, SR1E, 0xFF, 0x01},  {VIASR, SR2A, 0xFF, 0x00}, -{VIASR, SR2D, 0xFF, 0xFF},	/* VCK and LCK PLL power on.           */ -{VIACR, CR0A, 0xFF, 0x1E},	/* Cursor Start                        */ -{VIACR, CR0B, 0xFF, 0x00},	/* Cursor End                          */ -{VIACR, CR0E, 0xFF, 0x00},	/* Cursor Location High                */ -{VIACR, CR0F, 0xFF, 0x00},	/* Cursor Localtion Low                */ +{VIASR, SR2D, 0xC0, 0xC0},	/* delayed E3_ECK */  {VIACR, CR32, 0xFF, 0x00},  {VIACR, CR33, 0xFF, 0x00},  {VIACR, CR35, 0xFF, 0x00}, @@ -174,7 +160,6 @@ struct io_reg CX700_ModeXregs[] = { {VIASR, SR10, 0xFF, 0x01},  {VIACR, CR69, 0xFF, 0x00},  {VIACR, CR6A, 0xFF, 0x40},  {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00},  {VIACR, CR88, 0xFF, 0x40},	/* LCD Panel Type                      */  {VIACR, CR89, 0xFF, 0x00},	/* LCD Timing Control 0                */  {VIACR, CR8A, 0xFF, 0x88},	/* LCD Timing Control 1                */ @@ -204,14 +189,7 @@ struct io_reg VX855_ModeXregs[] = {  {VIASR, SR2A, 0xF0, 0x00},  {VIASR, SR58, 0xFF, 0x00},  {VIASR, SR59, 0xFF, 0x00}, -{VIASR, SR2D, 0xFF, 0xFF},	/* VCK and LCK PLL power on.           */ -{VIACR, CR09, 0xFF, 0x00},	/* Initial CR09=0*/ -{VIACR, CR11, 0x8F, 0x00},	/* IGA1 initial  Vertical end       */ -{VIACR, CR17, 0x7F, 0x00}, 	/* IGA1 CRT Mode control init   */ -{VIACR, CR0A, 0xFF, 0x1E},	/* Cursor Start                        */ -{VIACR, CR0B, 0xFF, 0x00},	/* Cursor End                          */ -{VIACR, CR0E, 0xFF, 0x00},	/* Cursor Location High                */ -{VIACR, CR0F, 0xFF, 0x00},	/* Cursor Localtion Low                */ +{VIASR, SR2D, 0xC0, 0xC0},	/* delayed E3_ECK */  {VIACR, CR32, 0xFF, 0x00},  {VIACR, CR33, 0x7F, 0x00},  {VIACR, CR35, 0xFF, 0x00}, @@ -219,7 +197,6 @@ struct io_reg VX855_ModeXregs[] = {  {VIACR, CR69, 0xFF, 0x00},  {VIACR, CR6A, 0xFD, 0x60},  {VIACR, CR6B, 0xFF, 0x00}, -{VIACR, CR6C, 0xFF, 0x00},  {VIACR, CR88, 0xFF, 0x40},          /* LCD Panel Type                      */  {VIACR, CR89, 0xFF, 0x00},          /* LCD Timing Control 0                */  {VIACR, CR8A, 0xFF, 0x88},          /* LCD Timing Control 1                */ @@ -606,7 +583,7 @@ static struct crt_mode_table CRTM1200x720[] = {  /* 1200x900 (DCON) */  static struct crt_mode_table DCON1200x900[] = {  	/* r_rate,               hsp,               vsp   */ -	{REFRESH_60, M1200X900_R60_HSP, M1200X900_R60_VSP, +	{REFRESH_49, M1200X900_R60_HSP, M1200X900_R60_VSP,  	/* The correct htotal is 1240, but this doesn't raster on VX855. */  	/* Via suggested changing to a multiple of 16, hence 1264.       */  	/*  HT,   HA,  HBS, HBE,  HSS, HSE,  VT,  VA, VBS, VBE, VSS, VSE */ @@ -877,23 +854,6 @@ static struct VideoModeTable viafb_rb_modes[] = {  	{CRTM1920x1200_RB, ARRAY_SIZE(CRTM1920x1200_RB)}  }; -struct crt_mode_table CEAM1280x720[] = { -	{REFRESH_60, M1280X720_CEA_R60_HSP, M1280X720_CEA_R60_VSP, -	 /* HT,    HA,   HBS,  HBE,  HSS, HSE,  VT,   VA,  VBS, VBE, VSS, VSE */ -	 {1650, 1280, 1280, 370, 1390, 40, 750, 720, 720, 30, 725, 5} } -}; -struct crt_mode_table CEAM1920x1080[] = { -	{REFRESH_60, M1920X1080_CEA_R60_HSP, M1920X1080_CEA_R60_VSP, -	 /* HT,    HA,   HBS,  HBE,  HSS, HSE,  VT,  VA, VBS, VBE,  VSS, VSE */ -	 {2200, 1920, 1920, 300, 2008, 44, 1125, 1080, 1080, 45, 1084, 5} } -}; -struct VideoModeTable CEA_HDMI_Modes[] = { -	/* Display : 1280x720 */ -	{CEAM1280x720, ARRAY_SIZE(CEAM1280x720)}, -	{CEAM1920x1080, ARRAY_SIZE(CEAM1920x1080)} -}; - -int NUM_TOTAL_CEA_MODES = ARRAY_SIZE(CEA_HDMI_Modes);  int NUM_TOTAL_CN400_ModeXregs = ARRAY_SIZE(CN400_ModeXregs);  int NUM_TOTAL_CN700_ModeXregs = ARRAY_SIZE(CN700_ModeXregs);  int NUM_TOTAL_KM400_ModeXregs = ARRAY_SIZE(KM400_ModeXregs); diff --git a/drivers/video/via/viamode.h b/drivers/video/via/viamode.h index 8a67ea1b5ef..3751289eb45 100644 --- a/drivers/video/via/viamode.h +++ b/drivers/video/via/viamode.h @@ -41,7 +41,6 @@ struct patch_table {  	struct io_reg *io_reg_table;  }; -extern int NUM_TOTAL_CEA_MODES;  extern int NUM_TOTAL_CN400_ModeXregs;  extern int NUM_TOTAL_CN700_ModeXregs;  extern int NUM_TOTAL_KM400_ModeXregs; @@ -50,14 +49,6 @@ extern int NUM_TOTAL_VX855_ModeXregs;  extern int NUM_TOTAL_CLE266_ModeXregs;  extern int NUM_TOTAL_PATCH_MODE; -/********************/ -/* Mode Table       */ -/********************/ - -extern struct crt_mode_table CEAM1280x720[]; -extern struct crt_mode_table CEAM1920x1080[]; -extern struct VideoModeTable CEA_HDMI_Modes[]; -  extern struct io_reg CN400_ModeXregs[];  extern struct io_reg CN700_ModeXregs[];  extern struct io_reg KM400_ModeXregs[];  |