From e3812ce4ee43f50a7423de70609f42990039f4ae Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 28 Jul 2010 00:57:18 +0000 Subject: [PATCH 01/29] viafb: reset correct PLL Looks like we did reset the PLL of the (whatever) engine instead of the PLL of the secondary display (IGA2, LCDCK). This patch fixes it. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 7dcb4d5bb9c3..53b06514cd1e 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1688,8 +1688,8 @@ void viafb_set_vclock(u32 clk, int set_iga) } if (set_iga == IGA2) { - viafb_write_reg_mask(SR40, VIASR, 0x01, BIT0); - viafb_write_reg_mask(SR40, VIASR, 0x00, BIT0); + viafb_write_reg_mask(SR40, VIASR, 0x04, BIT2); + viafb_write_reg_mask(SR40, VIASR, 0x00, BIT2); } /* Fire! */ From 91336712ce579dd8e83bc07bf0a45b7c6963eed2 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sat, 7 Aug 2010 18:47:01 +0000 Subject: [PATCH 02/29] viafb: remove lcdtbl.h This patch moves the power on/off sequences to lcd.c as they are only used there. This allows removing lcdtbl.h as the other stuff is not used. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/lcd.c | 8 +- drivers/video/via/lcdtbl.h | 591 ------------------------------------- 2 files changed, 7 insertions(+), 592 deletions(-) delete mode 100644 drivers/video/via/lcdtbl.h diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index fc25ae30c5f6..bda124682dab 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -21,10 +21,16 @@ #include #include #include "global.h" -#include "lcdtbl.h" #define viafb_compact_res(x, y) (((x)<<16)|(y)) +/* CLE266 Software Power Sequence */ +/* {Mask}, {Data}, {Delay} */ +int PowerSequenceOn[3][3] = { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, + {0x19, 0x1FE, 0x01} }; +int PowerSequenceOff[3][3] = { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, + {0xD2, 0x19, 0x01} }; + static struct _lcd_scaling_factor lcd_scaling_factor = { /* LCD Horizontal Scaling Factor Register */ {LCD_HOR_SCALING_FACTOR_REG_NUM, diff --git a/drivers/video/via/lcdtbl.h b/drivers/video/via/lcdtbl.h deleted file mode 100644 index 6f3dd800be59..000000000000 --- a/drivers/video/via/lcdtbl.h +++ /dev/null @@ -1,591 +0,0 @@ -/* - * Copyright 1998-2008 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 __LCDTBL_H__ -#define __LCDTBL_H__ - -#include "share.h" - -/* CLE266 Software Power Sequence */ -/* {Mask}, {Data}, {Delay} */ -int PowerSequenceOn[3][3] = - { {0x10, 0x08, 0x06}, {0x10, 0x08, 0x06}, {0x19, 0x1FE, 0x01} }; -int PowerSequenceOff[3][3] = - { {0x06, 0x08, 0x10}, {0x00, 0x00, 0x00}, {0xD2, 0x19, 0x01} }; - -/* ++++++ P880 ++++++ */ -/* Panel 1600x1200 */ -struct io_reg P880_LCD_RES_6X4_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x5E}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xD6}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR44, 0xFF, 0x7D}, {VIASR, SR45, 0xFF, 0x8C}, - {VIASR, SR46, 0xFF, 0x02} - -}; - -#define NUM_TOTAL_P880_LCD_RES_6X4_16X12 ARRAY_SIZE(P880_LCD_RES_6X4_16X12) - -struct io_reg P880_LCD_RES_7X4_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x78}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR44, 0xFF, 0x78}, {VIASR, SR45, 0xFF, 0x8C}, - {VIASR, SR46, 0xFF, 0x01} - -}; - -#define NUM_TOTAL_P880_LCD_RES_7X4_16X12 ARRAY_SIZE(P880_LCD_RES_7X4_16X12) - -struct io_reg P880_LCD_RES_8X6_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x83}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR44, 0xFF, 0x6D}, {VIASR, SR45, 0xFF, 0x88}, - {VIASR, SR46, 0xFF, 0x03} - -}; - -#define NUM_TOTAL_P880_LCD_RES_8X6_16X12 ARRAY_SIZE(P880_LCD_RES_8X6_16X12) - -struct io_reg P880_LCD_RES_10X7_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xAF}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR44, 0xFF, 0x92}, {VIASR, SR45, 0xFF, 0x88}, - {VIASR, SR46, 0xFF, 0x03} - -}; - -#define NUM_TOTAL_P880_LCD_RES_10X7_16X12 ARRAY_SIZE(P880_LCD_RES_10X7_16X12) - -struct io_reg P880_LCD_RES_12X10_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xD4}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR44, 0xFF, 0xF6}, {VIASR, SR45, 0xFF, 0x88}, - {VIASR, SR46, 0xFF, 0x05} - -}; - -#define NUM_TOTAL_P880_LCD_RES_12X10_16X12 ARRAY_SIZE(P880_LCD_RES_12X10_16X12) - -/* Panel 1400x1050 */ -struct io_reg P880_LCD_RES_6X4_14X10[] = { - /* 640x480 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x63}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00}, - /* VCLK */ - {VIASR, SR44, 0xFF, 0xC6}, {VIASR, SR45, 0xFF, 0x8C}, - {VIASR, SR46, 0xFF, 0x05} -}; - -#define NUM_TOTAL_P880_LCD_RES_6X4_14X10 ARRAY_SIZE(P880_LCD_RES_6X4_14X10) - -struct io_reg P880_LCD_RES_8X6_14X10[] = { - /* 800x600 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x83}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00}, - /* VCLK */ - {VIASR, SR44, 0xFF, 0x06}, {VIASR, SR45, 0xFF, 0x8D}, - {VIASR, SR46, 0xFF, 0x05} -}; - -#define NUM_TOTAL_P880_LCD_RES_8X6_14X10 ARRAY_SIZE(P880_LCD_RES_8X6_14X10) - -/* ++++++ K400 ++++++ */ -/* Panel 1600x1200 */ -struct io_reg K400_LCD_RES_6X4_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x73}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x73}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x5A}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x5E}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xDA}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x7F} -}; - -#define NUM_TOTAL_K400_LCD_RES_6X4_16X12 ARRAY_SIZE(K400_LCD_RES_6X4_16X12) - -struct io_reg K400_LCD_RES_7X4_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x67}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x67}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x74}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x78}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xF5}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x46}, {VIASR, SR47, 0xFF, 0x3D} -}; - -#define NUM_TOTAL_K400_LCD_RES_7X4_16X12 ARRAY_SIZE(K400_LCD_RES_7X4_16X12) - -struct io_reg K400_LCD_RES_8X6_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x83}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xE1}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x85}, {VIASR, SR47, 0xFF, 0x6F} -}; - -#define NUM_TOTAL_K400_LCD_RES_8X6_16X12 ARRAY_SIZE(K400_LCD_RES_8X6_16X12) - -struct io_reg K400_LCD_RES_10X7_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x65}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x65}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xAB}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xAF}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xF0}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x45}, {VIASR, SR47, 0xFF, 0x4A} -}; - -#define NUM_TOTAL_K400_LCD_RES_10X7_16X12 ARRAY_SIZE(K400_LCD_RES_10X7_16X12) - -struct io_reg K400_LCD_RES_12X10_16X12[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x7D}, {VIACR, CR55, 0x0F, 0x08}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x7D}, {VIACR, CR54, 0x38, 0x00}, - {VIACR, CR5D, 0x40, 0x40}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xD0}, {VIACR, CR71, 0x08, 0x00}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xD4}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xFA}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x47}, {VIASR, SR47, 0xFF, 0x7C} -}; - -#define NUM_TOTAL_K400_LCD_RES_12X10_16X12 ARRAY_SIZE(K400_LCD_RES_12X10_16X12) - -/* Panel 1400x1050 */ -struct io_reg K400_LCD_RES_6X4_14X10[] = { - /* 640x400 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x63}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xB4}, {VIACR, CR67, 0x03, 0x00}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19} -}; - -#define NUM_TOTAL_K400_LCD_RES_6X4_14X10 ARRAY_SIZE(K400_LCD_RES_6X4_14X10) - -struct io_reg K400_LCD_RES_8X6_14X10[] = { - /* 800x600 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x83}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21} -}; - -#define NUM_TOTAL_K400_LCD_RES_8X6_14X10 ARRAY_SIZE(K400_LCD_RES_8X6_14X10) - -struct io_reg K400_LCD_RES_10X7_14X10[] = { - /* 1024x768 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xA7}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E} -}; - -#define NUM_TOTAL_K400_LCD_RES_10X7_14X10 ARRAY_SIZE(K400_LCD_RES_10X7_14X10) - -struct io_reg K400_LCD_RES_12X10_14X10[] = { - /* 1280x768, 1280x960, 1280x1024 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xD2}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79} -}; - -#define NUM_TOTAL_K400_LCD_RES_12X10_14X10 ARRAY_SIZE(K400_LCD_RES_12X10_14X10) - -/* ++++++ K400 ++++++ */ -/* Panel 1366x768 */ -struct io_reg K400_LCD_RES_6X4_1366X7[] = { - /* 640x400 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B}, - {VIACR, CR5D, 0x40, 0x13}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x64}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C} -}; - -#define NUM_TOTAL_K400_LCD_RES_6X4_1366X7 ARRAY_SIZE(K400_LCD_RES_6X4_1366X7) - -struct io_reg K400_LCD_RES_7X4_1366X7[] = { - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B}, - {VIACR, CR5D, 0x40, 0x13}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x75}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10} -}; - -#define NUM_TOTAL_K400_LCD_RES_7X4_1366X7 ARRAY_SIZE(K400_LCD_RES_7X4_1366X7) - -struct io_reg K400_LCD_RES_8X6_1366X7[] = { - /* 800x600 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B}, - {VIACR, CR5D, 0x40, 0x13}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x82}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9} -}; - -#define NUM_TOTAL_K400_LCD_RES_8X6_1366X7 ARRAY_SIZE(K400_LCD_RES_8X6_1366X7) - -struct io_reg K400_LCD_RES_10X7_1366X7[] = { - /* 1024x768 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xA7}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xC3}, {VIACR, CR67, 0x03, 0x04}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E} -}; - -#define NUM_TOTAL_K400_LCD_RES_10X7_1366X7 ARRAY_SIZE(K400_LCD_RES_10X7_1366X7) - -struct io_reg K400_LCD_RES_12X10_1366X7[] = { - /* 1280x768, 1280x960, 1280x1024 */ - /* IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x97}, {VIACR, CR55, 0x0F, 0x56}, - /* IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x97}, {VIACR, CR54, 0x38, 0x75}, - {VIACR, CR5D, 0x40, 0x24}, - /* IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xCE}, {VIACR, CR71, 0x08, 0x44}, - /* IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xD2}, - /* IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xC9}, {VIACR, CR67, 0x03, 0x04}, - /* VCLK */ - {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0x79} -}; - -#define NUM_TOTAL_K400_LCD_RES_12X10_1366X7\ - ARRAY_SIZE(K400_LCD_RES_12X10_1366X7) - -/* ++++++ K400 ++++++ */ -/* Panel 1280x1024 */ -struct io_reg K400_LCD_RES_6X4_12X10[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, - {VIACR, CR5D, 0x40, 0x1C}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x34}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x63}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xAA}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x19} -}; - -#define NUM_TOTAL_K400_LCD_RES_6X4_12X10 ARRAY_SIZE(K400_LCD_RES_6X4_12X10) - -struct io_reg K400_LCD_RES_7X4_12X10[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, - {VIACR, CR5D, 0x40, 0x1C}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x68}, {VIACR, CR71, 0x08, 0x34}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x6C}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xA8}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0xED} -}; - -#define NUM_TOTAL_K400_LCD_RES_7X4_12X10 ARRAY_SIZE(K400_LCD_RES_7X4_12X10) - -struct io_reg K400_LCD_RES_8X6_12X10[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, - {VIACR, CR5D, 0x40, 0x1C}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x34}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x83}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x07}, {VIASR, SR47, 0xFF, 0x21} -}; - -#define NUM_TOTAL_K400_LCD_RES_8X6_12X10 ARRAY_SIZE(K400_LCD_RES_8X6_12X10) - -struct io_reg K400_LCD_RES_10X7_12X10[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x9D}, {VIACR, CR55, 0x0F, 0x46}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x9D}, {VIACR, CR54, 0x38, 0x74}, - {VIACR, CR5D, 0x40, 0x1C}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0xA3}, {VIACR, CR71, 0x08, 0x34}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0xA7}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0xBE}, {VIACR, CR67, 0x03, 0x04}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x1E} -}; - -#define NUM_TOTAL_K400_LCD_RES_10X7_12X10 ARRAY_SIZE(K400_LCD_RES_10X7_12X10) - -/* ++++++ K400 ++++++ */ -/* Panel 1024x768 */ -struct io_reg K400_LCD_RES_6X4_10X7[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x47}, {VIACR, CR55, 0x0F, 0x35}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x47}, {VIACR, CR54, 0x38, 0x2B}, - {VIACR, CR5D, 0x40, 0x13}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x60}, {VIACR, CR71, 0x08, 0x23}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x64}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x87}, {VIASR, SR47, 0xFF, 0x4C} -}; - -#define NUM_TOTAL_K400_LCD_RES_6X4_10X7 ARRAY_SIZE(K400_LCD_RES_6X4_10X7) - -struct io_reg K400_LCD_RES_7X4_10X7[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x3B}, {VIACR, CR55, 0x0F, 0x35}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x3B}, {VIACR, CR54, 0x38, 0x2B}, - {VIACR, CR5D, 0x40, 0x13}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x71}, {VIACR, CR71, 0x08, 0x23}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x75}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x96}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x05}, {VIASR, SR47, 0xFF, 0x10} -}; - -#define NUM_TOTAL_K400_LCD_RES_7X4_10X7 ARRAY_SIZE(K400_LCD_RES_7X4_10X7) - -struct io_reg K400_LCD_RES_8X6_10X7[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x37}, {VIACR, CR55, 0x0F, 0x35}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x37}, {VIACR, CR54, 0x38, 0x2B}, - {VIACR, CR5D, 0x40, 0x13}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7E}, {VIACR, CR71, 0x08, 0x23}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x82}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x8C}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x84}, {VIASR, SR47, 0xFF, 0xB9} -}; - -#define NUM_TOTAL_K400_LCD_RES_8X6_10X7 ARRAY_SIZE(K400_LCD_RES_8X6_10X7) - -/* ++++++ K400 ++++++ */ -/* Panel 800x600 */ -struct io_reg K400_LCD_RES_6X4_8X6[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x1A}, {VIACR, CR55, 0x0F, 0x34}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x1A}, {VIACR, CR54, 0x38, 0xE3}, - {VIACR, CR5D, 0x40, 0x12}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x5F}, {VIACR, CR71, 0x08, 0x22}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x63}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x6E}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0x86}, {VIASR, SR47, 0xFF, 0xB3} -}; - -#define NUM_TOTAL_K400_LCD_RES_6X4_8X6 ARRAY_SIZE(K400_LCD_RES_6X4_8X6) - -struct io_reg K400_LCD_RES_7X4_8X6[] = { - /*IGA2 Horizontal Total */ - {VIACR, CR50, 0xFF, 0x1F}, {VIACR, CR55, 0x0F, 0x34}, - /*IGA2 Horizontal Blank End */ - {VIACR, CR53, 0xFF, 0x1F}, {VIACR, CR54, 0x38, 0xE3}, - {VIACR, CR5D, 0x40, 0x12}, - /*IGA2 Horizontal Total Shadow */ - {VIACR, CR6D, 0xFF, 0x7F}, {VIACR, CR71, 0x08, 0x22}, - /*IGA2 Horizontal Blank End Shadow */ - {VIACR, CR6E, 0xFF, 0x83}, - /*IGA2 Offset */ - {VIACR, CR66, 0xFF, 0x78}, {VIACR, CR67, 0x03, 0x00}, - /*VCLK*/ {VIASR, SR46, 0xFF, 0xC4}, {VIASR, SR47, 0xFF, 0x59} -}; - -#define NUM_TOTAL_K400_LCD_RES_7X4_8X6 ARRAY_SIZE(K400_LCD_RES_7X4_8X6) - -#endif /* __LCDTBL_H__ */ From 646aafa649abb5362e55176cc5ee9c14c3c463a1 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Fri, 30 Jul 2010 22:49:17 +0000 Subject: [PATCH 03/29] viafb: remove stub This is a nop so removing it is safe. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 53b06514cd1e..63b672260479 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -720,7 +720,6 @@ static struct rgbLUT palLUT_table[] = { static void set_crt_output_path(int set_iga); static void dvi_patch_skew_dvp0(void); -static void dvi_patch_skew_dvp1(void); 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); @@ -910,21 +909,6 @@ static void dvi_patch_skew_dvp0(void) } } -static void dvi_patch_skew_dvp1(void) -{ - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_CX700: - { - break; - } - - default: - { - break; - } - } -} - static void dvi_patch_skew_dvp_low(void) { switch (viaparinfo->chip_info->gfx_chip_name) { @@ -992,7 +976,6 @@ static void set_dvi_output_path(int set_iga, int output_interface) } viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); - dvi_patch_skew_dvp1(); break; case INTERFACE_DFP_HIGH: if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) { From 414d3ce1b34384dd42e31536075583b9edb3cab6 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 8 Aug 2010 02:14:59 +0000 Subject: [PATCH 04/29] viafb: unify output path configuration Move all output path routing directly in the viafb_setmode. This gives a better overview and allows to factor similar parts out. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/dvi.c | 2 -- drivers/video/via/hw.c | 19 +++++++++++++++++-- drivers/video/via/lcd.c | 3 --- 3 files changed, 17 insertions(+), 7 deletions(-) diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 39b040bb3817..92a2027593d3 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -208,8 +208,6 @@ void viafb_dvi_set_mode(struct VideoModeTable *mode, int mode_bpp, } } viafb_fill_crtc_timing(pDviTiming, mode, mode_bpp / 8, set_iga); - viafb_set_output_path(DEVICE_DVI, set_iga, - viaparinfo->chip_info->tmds_chip_info.output_interface); } /* Sense DVI Connector */ diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 63b672260479..a3db80417593 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2377,8 +2377,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viaparinfo->crt_setting_info->iga_path); } - set_crt_output_path(viaparinfo->crt_setting_info->iga_path); - /* Patch if set_hres is not 8 alignment (1366) to viafb_setmode to 8 alignment (1368),there is several pixels (2 pixels) on right side of screen. */ @@ -2388,6 +2386,9 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_read_reg(VIACR, CR02) - 1); viafb_lock_crt(); } + + viafb_set_output_path(DEVICE_CRT, + viaparinfo->crt_setting_info->iga_path, 0); } if (viafb_DVI_ON) { @@ -2407,6 +2408,10 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, video_bpp, viaparinfo-> tmds_setting_info->iga_path); } + + viafb_set_output_path(DEVICE_DVI, + viaparinfo->tmds_setting_info->iga_path, + viaparinfo->chip_info->tmds_chip_info.output_interface); } if (viafb_LCD_ON) { @@ -2427,6 +2432,11 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info); } + + viafb_set_output_path(DEVICE_LCD, + viaparinfo->lvds_setting_info->iga_path, + viaparinfo->chip_info-> + lvds_chip_info.output_interface); } if (viafb_LCD2_ON) { if (viafb_SAMM_ON && @@ -2446,6 +2456,11 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, lvds_setting_info2, &viaparinfo->chip_info->lvds_chip_info2); } + + viafb_set_output_path(DEVICE_LCD, + viaparinfo->lvds_setting_info2->iga_path, + viaparinfo->chip_info-> + lvds_chip_info2.output_interface); } if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index bda124682dab..e48117e40102 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -661,9 +661,6 @@ void viafb_lcd_set_mode(struct crt_mode_table *mode_crt_table, pll_D_N = viafb_get_clk_value(panel_crt_table[0].clk); DEBUG_MSG(KERN_INFO "PLL=0x%x", pll_D_N); viafb_set_vclock(pll_D_N, set_iga); - - viafb_set_output_path(DEVICE_LCD, set_iga, - plvds_chip_info->output_interface); lcd_patch_skew(plvds_setting_info, plvds_chip_info); /* If K8M800, enable LCD Prefetch Mode. */ From b002741d174a32f8162b2110ad9757b6fb6afcc3 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 28 Jul 2010 01:11:41 +0000 Subject: [PATCH 05/29] viafb: enable second display channel at central place Move the enabling of the second display channel to the generic output routing function and do it exactly if something is using it. This unifies a zoo of variants how to do it and does no longer disable it if LCD is not on the second display which is much saner as there can be other users who need it. Probably this did not cause any problems so far as we only recently started dual fb support and otherwise there won't be other users and LCD is preferred assigned to second display channel. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 35 +++++------------------------------ 1 file changed, 5 insertions(+), 30 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index a3db80417593..1ce2c211bd1d 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -733,7 +733,6 @@ static void set_display_channel(void); static void device_off(void); static void device_on(void); static void enable_second_display_channel(void); -static void disable_second_display_channel(void); void viafb_lock_crt(void) { @@ -856,6 +855,9 @@ void viafb_set_output_path(int device, int set_iga, int output_interface) set_lcd_output_path(set_iga, output_interface); break; } + + if (set_iga == IGA2) + enable_second_display_channel(); } static void set_crt_output_path(int set_iga) @@ -867,7 +869,6 @@ static void set_crt_output_path(int set_iga) viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); break; case IGA2: - viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6); break; } @@ -1017,7 +1018,6 @@ static void set_dvi_output_path(int set_iga, int output_interface) } if (set_iga == IGA2) { - enable_second_display_channel(); /* Disable LCD Scaling */ viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); } @@ -1028,21 +1028,9 @@ static void set_lcd_output_path(int set_iga, int output_interface) DEBUG_MSG(KERN_INFO "set_lcd_output_path, iga:%d,out_interface:%d\n", set_iga, output_interface); - switch (set_iga) { - case IGA1: - viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); - viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); - disable_second_display_channel(); - break; - - case IGA2: - viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); - viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); - - enable_second_display_channel(); - break; - } + viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); + viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); switch (output_interface) { case INTERFACE_DVP0: @@ -2480,10 +2468,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_DeviceStatus = CRT_Device; } device_on(); - - if (viafb_SAMM_ON == 1) - viafb_write_reg_mask(CR6A, VIACR, 0xC0, BIT6 + BIT7); - device_screen_on(); return 1; } @@ -2557,15 +2541,6 @@ static void enable_second_display_channel(void) viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); } -static void disable_second_display_channel(void) -{ - /* to disable second display channel. */ - viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6); - viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7); - viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); -} - - void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ *p_gfx_dpa_setting) { From a54be174e425cb41eb774714d03ff98562ee0824 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 28 Jul 2010 23:06:04 +0000 Subject: [PATCH 06/29] viafb: rework output device routing This patch rips the device routing out of the 3 main functions to separate functions to make them available for transition to a better controlling scheme. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 191 +++++++++++++++++++++-------------------- 1 file changed, 98 insertions(+), 93 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 1ce2c211bd1d..2f7f64006499 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -860,18 +860,78 @@ void viafb_set_output_path(int device, int set_iga, int output_interface) enable_second_display_channel(); } +static void set_source_common(u8 index, u8 offset, u8 iga) +{ + u8 value, mask = 1 << offset; + + switch (iga) { + case IGA1: + value = 0x00; + break; + case IGA2: + value = mask; + break; + default: + printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga); + return; + } + + via_write_reg_mask(VIACR, index, value, mask); +} + +static void set_crt_source(u8 iga) +{ + u8 value; + + switch (iga) { + case IGA1: + value = 0x00; + break; + case IGA2: + value = 0x40; + break; + default: + printk(KERN_WARNING "viafb: Unsupported source: %d\n", iga); + return; + } + + via_write_reg_mask(VIASR, 0x16, value, 0x40); +} + +static inline void set_6C_source(u8 iga) +{ + set_source_common(0x6C, 7, iga); +} + +static inline void set_93_source(u8 iga) +{ + set_source_common(0x93, 7, iga); +} + +static inline void set_96_source(u8 iga) +{ + set_source_common(0x96, 4, iga); +} + +static inline void set_dvp1_source(u8 iga) +{ + set_source_common(0x9B, 4, iga); +} + +static inline void set_lvds1_source(u8 iga) +{ + set_source_common(0x99, 4, iga); +} + +static inline void set_lvds2_source(u8 iga) +{ + set_source_common(0x97, 4, iga); +} + static void set_crt_output_path(int set_iga) { viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); - - switch (set_iga) { - case IGA1: - viafb_write_reg_mask(SR16, VIASR, 0x00, BIT6); - break; - case IGA2: - viafb_write_reg_mask(SR16, VIASR, 0x40, BIT6); - break; - } + set_crt_source(set_iga); } static void dvi_patch_skew_dvp0(void) @@ -944,76 +1004,45 @@ static void set_dvi_output_path(int set_iga, int output_interface) { switch (output_interface) { case INTERFACE_DVP0: + set_96_source(set_iga); + set_6C_source(set_iga); viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); - - if (set_iga == IGA1) { - viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); - viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + - BIT5 + BIT7); - } else { - viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); - viafb_write_reg_mask(CR6C, VIACR, 0xA1, BIT0 + - BIT5 + BIT7); - } - + viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6); - dvi_patch_skew_dvp0(); break; case INTERFACE_DVP1: if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { - if (set_iga == IGA1) - viafb_write_reg_mask(CR93, VIACR, 0x21, - BIT0 + BIT5 + BIT7); - else - viafb_write_reg_mask(CR93, VIACR, 0xA1, - BIT0 + BIT5 + BIT7); + set_93_source(set_iga); + viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); } else { - if (set_iga == IGA1) - viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); - else - viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); + set_dvp1_source(set_iga); } viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); break; case INTERFACE_DFP_HIGH: if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) { - if (set_iga == IGA1) { - viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); - viafb_write_reg_mask(CR97, VIACR, 0x03, - BIT0 + BIT1 + BIT4); - } else { - viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); - viafb_write_reg_mask(CR97, VIACR, 0x13, - BIT0 + BIT1 + BIT4); - } + via_write_reg_mask(VIACR, CR97, 0x03, 0x03); + set_lvds2_source(set_iga); + set_96_source(set_iga); } + viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); break; case INTERFACE_DFP_LOW: if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) break; - - if (set_iga == IGA1) { - viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); - viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); - } else { - viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); - viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); - } - + set_dvp1_source(set_iga); + set_lvds1_source(set_iga); viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); dvi_patch_skew_dvp_low(); break; case INTERFACE_TMDS: - if (set_iga == IGA1) - viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); - else - viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); + set_lvds1_source(set_iga); break; } @@ -1031,45 +1060,31 @@ static void set_lcd_output_path(int set_iga, int output_interface) viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); - switch (output_interface) { case INTERFACE_DVP0: - if (set_iga == IGA1) { - viafb_write_reg_mask(CR96, VIACR, 0x00, BIT4); - } else { + set_96_source(set_iga); + if (set_iga == IGA2) viafb_write_reg(CR91, VIACR, 0x00); - viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); - } break; case INTERFACE_DVP1: - if (set_iga == IGA1) - viafb_write_reg_mask(CR9B, VIACR, 0x00, BIT4); - else { + set_dvp1_source(set_iga); + if (set_iga == IGA2) viafb_write_reg(CR91, VIACR, 0x00); - viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); - } break; case INTERFACE_DFP_HIGH: - if (set_iga == IGA1) - viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); - else { + set_lvds2_source(set_iga); + set_96_source(set_iga); + if (set_iga == IGA2) viafb_write_reg(CR91, VIACR, 0x00); - viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); - viafb_write_reg_mask(CR96, VIACR, 0x10, BIT4); - } break; case INTERFACE_DFP_LOW: - if (set_iga == IGA1) - viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); - else { + set_lvds1_source(set_iga); + set_dvp1_source(set_iga); + if (set_iga == IGA2) viafb_write_reg(CR91, VIACR, 0x00); - viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); - viafb_write_reg_mask(CR9B, VIACR, 0x10, BIT4); - } - break; case INTERFACE_DFP: @@ -1078,30 +1093,20 @@ static void set_lcd_output_path(int set_iga, int output_interface) viaparinfo->chip_info->gfx_chip_name)) viafb_write_reg_mask(CR97, VIACR, 0x84, BIT7 + BIT2 + BIT1 + BIT0); - if (set_iga == IGA1) { - viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); - viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); - } else { + + set_lvds1_source(set_iga); + set_lvds2_source(set_iga); + if (set_iga == IGA2) viafb_write_reg(CR91, VIACR, 0x00); - viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); - viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); - } break; case INTERFACE_LVDS0: case INTERFACE_LVDS0LVDS1: - if (set_iga == IGA1) - viafb_write_reg_mask(CR99, VIACR, 0x00, BIT4); - else - viafb_write_reg_mask(CR99, VIACR, 0x10, BIT4); - + set_lvds1_source(set_iga); break; case INTERFACE_LVDS1: - if (set_iga == IGA1) - viafb_write_reg_mask(CR97, VIACR, 0x00, BIT4); - else - viafb_write_reg_mask(CR97, VIACR, 0x10, BIT4); + set_lvds2_source(set_iga); break; } } From f4ab2f7a21338ae0f59ad925c23545e790cd51e3 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Mon, 9 Aug 2010 01:34:27 +0000 Subject: [PATCH 07/29] viafb: propagate __init and __devinit There are a lot of init functions which are not marked as such. Fix this. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/dvi.c | 24 ++++++++++++++---------- drivers/video/via/dvi.h | 4 ++-- drivers/video/via/hw.c | 16 ++++++++-------- drivers/video/via/hw.h | 4 ++-- drivers/video/via/lcd.c | 10 +++++----- drivers/video/via/lcd.h | 6 +++--- drivers/video/via/viafbdev.c | 8 ++++---- 7 files changed, 38 insertions(+), 34 deletions(-) diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 92a2027593d3..ab6145da1a2f 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -25,10 +25,12 @@ static void tmds_register_write(int index, u8 data); static int tmds_register_read(int index); static int tmds_register_read_bytes(int index, u8 *buff, int buff_len); -static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information - *tmds_chip, struct tmds_setting_information *tmds_setting); -static void dvi_get_panel_size_from_DDCv2(struct tmds_chip_information - *tmds_chip, struct tmds_setting_information *tmds_setting); +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) @@ -39,7 +41,7 @@ static int check_tmds_chip(int device_id_subaddr, int device_id) return FAIL; } -void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, +void __devinit viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, struct tmds_setting_information *tmds_setting) { DEBUG_MSG(KERN_INFO "viafb_init_dvi_size()\n"); @@ -60,7 +62,7 @@ void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, return; } -int viafb_tmds_trasmitter_identify(void) +int __devinit viafb_tmds_trasmitter_identify(void) { unsigned char sr2a = 0, sr1e = 0, sr3e = 0; @@ -311,8 +313,9 @@ static int viafb_dvi_query_EDID(void) } /* Get Panel Size Using EDID1 Table */ -static void 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_DDCv1( + struct tmds_chip_information *tmds_chip, + struct tmds_setting_information *tmds_setting) { int i, max_h = 0, tmp, restore; unsigned char rData; @@ -416,8 +419,9 @@ static void dvi_get_panel_size_from_DDCv1(struct tmds_chip_information } /* Get Panel Size Using EDID2 Table */ -static void dvi_get_panel_size_from_DDCv2(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) { int restore; unsigned char R_Buffer[2]; diff --git a/drivers/video/via/dvi.h b/drivers/video/via/dvi.h index 0dffcfd395f3..2c525c0c1adb 100644 --- a/drivers/video/via/dvi.h +++ b/drivers/video/via/dvi.h @@ -56,8 +56,8 @@ int viafb_dvi_sense(void); void viafb_dvi_disable(void); void viafb_dvi_enable(void); -int viafb_tmds_trasmitter_identify(void); -void viafb_init_dvi_size(struct tmds_chip_information *tmds_chip, +int __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, int set_iga); diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 2f7f64006499..4407943fa7d7 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -724,9 +724,9 @@ 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(int chip_type); -static void init_tmds_chip_info(void); -static void init_lvds_chip_info(void); +static void __devinit init_gfx_chip_info(int chip_type); +static void __devinit init_tmds_chip_info(void); +static void __devinit init_lvds_chip_info(void); static void device_screen_off(void); static void device_screen_on(void); static void set_display_channel(void); @@ -1980,7 +1980,7 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, } -void viafb_init_chip_info(int chip_type) +void __devinit viafb_init_chip_info(int chip_type) { init_gfx_chip_info(chip_type); init_tmds_chip_info(); @@ -2047,7 +2047,7 @@ void viafb_update_device_setting(int hres, int vres, } } -static void init_gfx_chip_info(int chip_type) +static void __devinit init_gfx_chip_info(int chip_type) { u8 tmp; @@ -2099,7 +2099,7 @@ static void init_gfx_chip_info(int chip_type) } } -static void init_tmds_chip_info(void) +static void __devinit init_tmds_chip_info(void) { viafb_tmds_trasmitter_identify(); @@ -2144,7 +2144,7 @@ static void init_tmds_chip_info(void) &viaparinfo->shared->tmds_setting_info); } -static void init_lvds_chip_info(void) +static void __devinit init_lvds_chip_info(void) { viafb_lvds_trasmitter_identify(); viafb_init_lcd_size(); @@ -2178,7 +2178,7 @@ static void init_lvds_chip_info(void) viaparinfo->chip_info->lvds_chip_info.output_interface); } -void viafb_init_dac(int set_iga) +void __devinit viafb_init_dac(int set_iga) { int i; u8 tmp; diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index c44399895294..39f3a69bbbd8 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -908,8 +908,8 @@ 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(int chip_type); -void viafb_init_dac(int set_iga); +void __devinit viafb_init_chip_info(int chip_type); +void __devinit 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, diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index e48117e40102..c7de16430867 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -48,7 +48,7 @@ static struct _lcd_scaling_factor lcd_scaling_factor_CLE = { static int check_lvds_chip(int device_id_subaddr, int device_id); static bool lvds_identify_integratedlvds(void); -static void fp_id_to_vindex(int panel_id); +static void __devinit fp_id_to_vindex(int panel_id); static int lvds_register_read(int index); static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, int panel_vres); @@ -90,7 +90,7 @@ static int check_lvds_chip(int device_id_subaddr, int device_id) return FAIL; } -void viafb_init_lcd_size(void) +void __devinit viafb_init_lcd_size(void) { DEBUG_MSG(KERN_INFO "viafb_init_lcd_size()\n"); @@ -150,7 +150,7 @@ static bool lvds_identify_integratedlvds(void) return true; } -int viafb_lvds_trasmitter_identify(void) +int __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; @@ -191,7 +191,7 @@ int viafb_lvds_trasmitter_identify(void) return FAIL; } -static void fp_id_to_vindex(int panel_id) +static void __devinit fp_id_to_vindex(int panel_id) { DEBUG_MSG(KERN_INFO "fp_get_panel_id()\n"); @@ -996,7 +996,7 @@ static void check_diport_of_integrated_lvds( plvds_chip_info->output_interface); } -void viafb_init_lvds_output_interface(struct lvds_chip_information +void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information *plvds_setting_info) diff --git a/drivers/video/via/lcd.h b/drivers/video/via/lcd.h index b348efc360b8..c7909fe29550 100644 --- a/drivers/video/via/lcd.h +++ b/drivers/video/via/lcd.h @@ -71,15 +71,15 @@ void viafb_enable_lvds_vt1636(struct lvds_setting_information struct lvds_chip_information *plvds_chip_info); void viafb_lcd_disable(void); void viafb_lcd_enable(void); -void viafb_init_lcd_size(void); -void viafb_init_lvds_output_interface(struct lvds_chip_information +void __devinit viafb_init_lcd_size(void); +void __devinit viafb_init_lvds_output_interface(struct lvds_chip_information *plvds_chip_info, struct lvds_setting_information *plvds_setting_info); 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 viafb_lvds_trasmitter_identify(void); +int __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/viafbdev.c b/drivers/video/via/viafbdev.c index bdd0e4130f4e..5a947b096269 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -961,7 +961,7 @@ static void retrieve_device_setting(struct viafb_ioctl_setting setting_info->lcd_attributes.lcd_mode = viafb_lcd_mode; } -static int parse_active_dev(void) +static int __init parse_active_dev(void) { viafb_CRT_ON = STATE_OFF; viafb_DVI_ON = STATE_OFF; @@ -1031,7 +1031,7 @@ static int parse_active_dev(void) return 0; } -static int parse_port(char *opt_str, int *output_interface) +static int __devinit parse_port(char *opt_str, int *output_interface) { if (!strncmp(opt_str, "DVP0", 4)) *output_interface = INTERFACE_DVP0; @@ -1048,7 +1048,7 @@ static int parse_port(char *opt_str, int *output_interface) return 0; } -static void parse_lcd_port(void) +static void __devinit parse_lcd_port(void) { parse_port(viafb_lcd_port, &viaparinfo->chip_info->lvds_chip_info. output_interface); @@ -1061,7 +1061,7 @@ static void parse_lcd_port(void) output_interface); } -static void parse_dvi_port(void) +static void __devinit parse_dvi_port(void) { parse_port(viafb_dvi_port, &viaparinfo->chip_info->tmds_chip_info. output_interface); From 661c65cd0ce180d5e3a3e05f08fc9e64cedcf91c Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Tue, 10 Aug 2010 00:45:06 +0000 Subject: [PATCH 08/29] viafb: reduce viafb_set_iga_path usage The result of viafb_set_iga_path can change after init only in the hotplug ioctl. So we can move it there rather than doing it always when a new mode is set. The setup during init is done via a call from the init chip funtion. This change enables a stable mapping between the old device scheme and a new more powerfull one. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 1 - drivers/video/via/ioctl.c | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 4407943fa7d7..638cf96c8739 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2313,7 +2313,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, via_write_reg(VIASR, i, VPIT.SR[i - 1]); viafb_write_reg_mask(0x15, VIASR, 0xA2, 0xA2); - viafb_set_iga_path(); /* Write CRTC */ viafb_fill_crtc_timing(crt_timing, vmode_tbl, video_bpp / 8, IGA1); diff --git a/drivers/video/via/ioctl.c b/drivers/video/via/ioctl.c index 4d553d0b8d7a..ea1c51428823 100644 --- a/drivers/video/via/ioctl.c +++ b/drivers/video/via/ioctl.c @@ -94,6 +94,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp) viafb_CRT_ON = 0; viafb_LCD_ON = 0; viafb_DeviceStatus = DVI_Device; + viafb_set_iga_path(); return viafb_DeviceStatus; } status = 1; @@ -107,6 +108,7 @@ int viafb_ioctl_hotplug(int hres, int vres, int bpp) viafb_LCD_ON = 0; viafb_DeviceStatus = CRT_Device; + viafb_set_iga_path(); return viafb_DeviceStatus; } From 18d9dc08b22145adb248d16dd2cefb2ccf9f7665 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Tue, 10 Aug 2010 02:44:44 +0000 Subject: [PATCH 09/29] viafb: add new output device management This patch adds a new output device management that stores for each IGA which output devices are routed to it and a compatiblity layer that converts the old per-output device values in the new format. Bounding the output devices to each IGA is a central idea of the cleanup. Doing it this way should be easier and make much more sense than the old format which happily mixed different output devices together and did not even take into account that some devices are no longer available on newer chipsets. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 102 +++++++++++++++++++++++++++++++++++ drivers/video/via/hw.h | 9 ++++ drivers/video/via/viafbdev.h | 3 ++ 3 files changed, 114 insertions(+) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 638cf96c8739..30cc2f0961e3 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -753,6 +753,66 @@ void write_dac_reg(u8 index, u8 r, u8 g, u8 b) outb(b, LUT_DATA); } +static u32 get_dvi_devices(int output_interface) +{ + switch (output_interface) { + case INTERFACE_DVP0: + return VIA_96 | VIA_6C; + + case INTERFACE_DVP1: + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) + return VIA_93; + else + return VIA_DVP1; + + case INTERFACE_DFP_HIGH: + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) + return 0; + else + return VIA_LVDS2 | VIA_96; + + case INTERFACE_DFP_LOW: + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) + return 0; + else + return VIA_DVP1 | VIA_LVDS1; + + case INTERFACE_TMDS: + return VIA_LVDS1; + } + + return 0; +} + +static u32 get_lcd_devices(int output_interface) +{ + switch (output_interface) { + case INTERFACE_DVP0: + return VIA_96; + + case INTERFACE_DVP1: + return VIA_DVP1; + + case INTERFACE_DFP_HIGH: + return VIA_LVDS2 | VIA_96; + + case INTERFACE_DFP_LOW: + return VIA_LVDS1 | VIA_DVP1; + + case INTERFACE_DFP: + return VIA_LVDS1 | VIA_LVDS2; + + case INTERFACE_LVDS0: + case INTERFACE_LVDS0LVDS1: + return VIA_LVDS1; + + case INTERFACE_LVDS1: + return VIA_LVDS2; + } + + return 0; +} + /*Set IGA path for each device*/ void viafb_set_iga_path(void) { @@ -819,6 +879,48 @@ void viafb_set_iga_path(void) viaparinfo->tmds_setting_info->iga_path = IGA1; } } + + viaparinfo->shared->iga1_devices = 0; + viaparinfo->shared->iga2_devices = 0; + if (viafb_CRT_ON) { + if (viaparinfo->crt_setting_info->iga_path == IGA1) + viaparinfo->shared->iga1_devices |= VIA_CRT; + else + viaparinfo->shared->iga2_devices |= VIA_CRT; + } + + if (viafb_DVI_ON) { + if (viaparinfo->tmds_setting_info->iga_path == IGA1) + viaparinfo->shared->iga1_devices |= get_dvi_devices( + viaparinfo->chip_info-> + tmds_chip_info.output_interface); + else + viaparinfo->shared->iga2_devices |= get_dvi_devices( + viaparinfo->chip_info-> + tmds_chip_info.output_interface); + } + + if (viafb_LCD_ON) { + if (viaparinfo->lvds_setting_info->iga_path == IGA1) + viaparinfo->shared->iga1_devices |= get_lcd_devices( + viaparinfo->chip_info-> + lvds_chip_info.output_interface); + else + viaparinfo->shared->iga2_devices |= get_lcd_devices( + viaparinfo->chip_info-> + lvds_chip_info.output_interface); + } + + if (viafb_LCD2_ON) { + if (viaparinfo->lvds_setting_info2->iga_path == IGA1) + viaparinfo->shared->iga1_devices |= get_lcd_devices( + viaparinfo->chip_info-> + lvds_chip_info2.output_interface); + else + viaparinfo->shared->iga2_devices |= get_lcd_devices( + viaparinfo->chip_info-> + lvds_chip_info2.output_interface); + } } static void set_color_register(u8 index, u8 red, u8 green, u8 blue) diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 39f3a69bbbd8..c52a1d5f092d 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -30,6 +30,15 @@ #define viafb_write_reg(i, p, d) via_write_reg(p, i, d) #define viafb_write_reg_mask(i, p, d, m) via_write_reg_mask(p, i, d, m) +/* VIA output devices */ +#define VIA_6C 0x00000001 +#define VIA_93 0x00000002 +#define VIA_96 0x00000004 +#define VIA_CRT 0x00000010 +#define VIA_DVP1 0x00000020 +#define VIA_LVDS1 0x00000040 +#define VIA_LVDS2 0x00000080 + /*************************************************** * Definition IGA1 Design Method of CRTC Registers * ****************************************************/ diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 52a35fabba91..945a47a63c4d 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -40,6 +40,9 @@ #define VIAFB_NUM_I2C 5 struct viafb_shared { + u32 iga1_devices; + u32 iga2_devices; + struct proc_dir_entry *proc_entry; /*viafb proc entry */ struct viafb_dev *vdev; /* Global dev info */ From bc6848875152f3df860d0f54a2323cc7615527d9 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 11 Aug 2010 00:37:58 +0000 Subject: [PATCH 10/29] viafb: use new device routing This patch uses the iga{1,2}_devices variables to select which IGA should be the source. Doing this is convinient, more powerfull than the older scheme and easy extendable to support further output devices. It is not yet completed as the device on/off selection needs to be converted to the same scheme to take full advantage. No visible changes yet as we want to complete the transition before anouncing any unstabke interface. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 101 ++++++++++++++++------------------------- 1 file changed, 38 insertions(+), 63 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 30cc2f0961e3..c8f24058c570 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -718,7 +718,6 @@ static struct rgbLUT palLUT_table[] = { 0x00} }; -static void set_crt_output_path(int set_iga); static void dvi_patch_skew_dvp0(void); static void dvi_patch_skew_dvp_low(void); static void set_dvi_output_path(int set_iga, int output_interface); @@ -733,6 +732,7 @@ static void set_display_channel(void); static void device_off(void); static void device_on(void); static void enable_second_display_channel(void); +static void disable_second_display_channel(void); void viafb_lock_crt(void) { @@ -948,7 +948,7 @@ void viafb_set_output_path(int device, int set_iga, int output_interface) { switch (device) { case DEVICE_CRT: - set_crt_output_path(set_iga); + viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); break; case DEVICE_DVI: set_dvi_output_path(set_iga, output_interface); @@ -957,9 +957,6 @@ void viafb_set_output_path(int device, int set_iga, int output_interface) set_lcd_output_path(set_iga, output_interface); break; } - - if (set_iga == IGA2) - enable_second_display_channel(); } static void set_source_common(u8 index, u8 offset, u8 iga) @@ -1030,10 +1027,22 @@ static inline void set_lvds2_source(u8 iga) set_source_common(0x97, 4, iga); } -static void set_crt_output_path(int set_iga) +void via_set_source(u32 devices, u8 iga) { - viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); - set_crt_source(set_iga); + if (devices & VIA_6C) + set_6C_source(iga); + if (devices & VIA_93) + set_93_source(iga); + if (devices & VIA_96) + set_96_source(iga); + if (devices & VIA_CRT) + set_crt_source(iga); + if (devices & VIA_DVP1) + set_dvp1_source(iga); + if (devices & VIA_LVDS1) + set_lvds1_source(iga); + if (devices & VIA_LVDS2) + set_lvds2_source(iga); } static void dvi_patch_skew_dvp0(void) @@ -1106,8 +1115,6 @@ static void set_dvi_output_path(int set_iga, int output_interface) { switch (output_interface) { case INTERFACE_DVP0: - set_96_source(set_iga); - set_6C_source(set_iga); viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6); @@ -1115,21 +1122,14 @@ static void set_dvi_output_path(int set_iga, int output_interface) break; case INTERFACE_DVP1: - if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { - set_93_source(set_iga); + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); - } else { - set_dvp1_source(set_iga); - } viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); break; case INTERFACE_DFP_HIGH: - if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) { + if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) via_write_reg_mask(VIACR, CR97, 0x03, 0x03); - set_lvds2_source(set_iga); - set_96_source(set_iga); - } viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); break; @@ -1137,15 +1137,9 @@ static void set_dvi_output_path(int set_iga, int output_interface) case INTERFACE_DFP_LOW: if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) break; - set_dvp1_source(set_iga); - set_lvds1_source(set_iga); viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); dvi_patch_skew_dvp_low(); break; - - case INTERFACE_TMDS: - set_lvds1_source(set_iga); - break; } if (set_iga == IGA2) { @@ -1163,53 +1157,19 @@ static void set_lcd_output_path(int set_iga, int output_interface) viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); switch (output_interface) { - case INTERFACE_DVP0: - set_96_source(set_iga); - if (set_iga == IGA2) - viafb_write_reg(CR91, VIACR, 0x00); - break; - - case INTERFACE_DVP1: - set_dvp1_source(set_iga); - if (set_iga == IGA2) - viafb_write_reg(CR91, VIACR, 0x00); - break; - - case INTERFACE_DFP_HIGH: - set_lvds2_source(set_iga); - set_96_source(set_iga); - if (set_iga == IGA2) - viafb_write_reg(CR91, VIACR, 0x00); - break; - - case INTERFACE_DFP_LOW: - set_lvds1_source(set_iga); - set_dvp1_source(set_iga); - if (set_iga == IGA2) - viafb_write_reg(CR91, VIACR, 0x00); - break; - case INTERFACE_DFP: if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name) || (UNICHROME_P4M890 == viaparinfo->chip_info->gfx_chip_name)) viafb_write_reg_mask(CR97, VIACR, 0x84, BIT7 + BIT2 + BIT1 + BIT0); - - set_lvds1_source(set_iga); - set_lvds2_source(set_iga); + case INTERFACE_DVP0: + case INTERFACE_DVP1: + case INTERFACE_DFP_HIGH: + case INTERFACE_DFP_LOW: if (set_iga == IGA2) viafb_write_reg(CR91, VIACR, 0x00); break; - - case INTERFACE_LVDS0: - case INTERFACE_LVDS0LVDS1: - set_lvds1_source(set_iga); - break; - - case INTERFACE_LVDS1: - set_lvds2_source(set_iga); - break; } } @@ -2454,6 +2414,13 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, via_set_primary_color_depth(viaparinfo->depth); via_set_secondary_color_depth(viafb_dual_fb ? viaparinfo1->depth : viaparinfo->depth); + via_set_source(viaparinfo->shared->iga1_devices, IGA1); + via_set_source(viaparinfo->shared->iga2_devices, IGA2); + if (viaparinfo->shared->iga2_devices) + enable_second_display_channel(); + else + disable_second_display_channel(); + /* Update Refresh Rate Setting */ /* Clear On Screen */ @@ -2647,6 +2614,14 @@ static void enable_second_display_channel(void) viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); } +static void disable_second_display_channel(void) +{ + /* to disable second display channel. */ + viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT6); + viafb_write_reg_mask(CR6A, VIACR, 0x00, BIT7); + viafb_write_reg_mask(CR6A, VIACR, BIT6, BIT6); +} + void viafb_set_dpa_gfx(int output_interface, struct GFX_DPA_SETTING\ *p_gfx_dpa_setting) { From cd7e9103e983ff0f518ac0e85cee265027ccbfa4 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 11 Aug 2010 22:22:54 +0000 Subject: [PATCH 11/29] viafb: merge the remaining output path with enable functions This patch merges the remaining functionality of the output path function in the associated enabling functions. This is very natural as most of the remaining code does actually enable the device. Just some more or less intelligent code merge. If no stupid mistakes occured there should be no regressions. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/dvi.c | 146 +++++++++++++++++++++++++---------- drivers/video/via/hw.c | 164 ---------------------------------------- drivers/video/via/hw.h | 3 - drivers/video/via/lcd.c | 28 +++++++ 4 files changed, 136 insertions(+), 205 deletions(-) diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index ab6145da1a2f..7c82f6fda918 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -496,38 +496,103 @@ void viafb_dvi_disable(void) viafb_read_reg(VIACR, CRD2) | 0x08); } +static void dvi_patch_skew_dvp0(void) +{ + /* Reset data driving first: */ + viafb_write_reg_mask(SR1B, VIASR, 0, BIT1); + viafb_write_reg_mask(SR2A, VIASR, 0, BIT4); + + switch (viaparinfo->chip_info->gfx_chip_name) { + case UNICHROME_P4M890: + { + if ((viaparinfo->tmds_setting_info->h_active == 1600) && + (viaparinfo->tmds_setting_info->v_active == + 1200)) + viafb_write_reg_mask(CR96, VIACR, 0x03, + BIT0 + BIT1 + BIT2); + else + viafb_write_reg_mask(CR96, VIACR, 0x07, + BIT0 + BIT1 + BIT2); + break; + } + + case UNICHROME_P4M900: + { + viafb_write_reg_mask(CR96, VIACR, 0x07, + BIT0 + BIT1 + BIT2 + BIT3); + viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1); + viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4); + break; + } + + default: + { + break; + } + } +} + +static void dvi_patch_skew_dvp_low(void) +{ + switch (viaparinfo->chip_info->gfx_chip_name) { + case UNICHROME_K8M890: + { + viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1); + break; + } + + case UNICHROME_P4M900: + { + viafb_write_reg_mask(CR99, VIACR, 0x08, + BIT0 + BIT1 + BIT2 + BIT3); + break; + } + + case UNICHROME_P4M890: + { + viafb_write_reg_mask(CR99, VIACR, 0x0F, + BIT0 + BIT1 + BIT2 + BIT3); + break; + } + + default: + { + break; + } + } +} + /* If Enable DVI, turn off pad */ void viafb_dvi_enable(void) { u8 data; - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP0) { - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) | 0xC0); + switch (viaparinfo->chip_info->tmds_chip_info.output_interface) { + case INTERFACE_DVP0: + viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); + viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); + viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6); + dvi_patch_skew_dvp0(); if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) tmds_register_write(0x88, 0x3b); else /*clear CR91[5] to direct on display period in the secondary diplay path */ - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); + break; - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP1) { - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) | 0x30); + case INTERFACE_DVP1: + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) + viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); + viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ - if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) tmds_register_write(0x88, 0x3b); - } else { + else /*clear CR91[5] to direct on display period in the secondary diplay path */ - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); /*fix DVI cannot enable on EPIA-M board */ if (viafb_platform_epia_dvi == 1) { @@ -539,36 +604,41 @@ void viafb_dvi_enable(void) else data = 0x37; viafb_i2c_writebyte(viaparinfo->chip_info-> - tmds_chip_info.i2c_port, - 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); } } - } + break; - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) { - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) | 0x0C); - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } + case INTERFACE_DFP_HIGH: + if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) + via_write_reg_mask(VIACR, CR97, 0x03, 0x03); - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_LOW) { - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) | 0x03); - viafb_write_reg(CR91, VIACR, - viafb_read_reg(VIACR, CR91) & 0xDF); - } - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_TMDS) { + viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); + break; + + case INTERFACE_DFP_LOW: + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) + break; + viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); + dvi_patch_skew_dvp_low(); + via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); + break; + + case INTERFACE_TMDS: /* Turn on Display period in the panel path. */ viafb_write_reg_mask(CR91, VIACR, 0, BIT7); /* Turn on TMDS power. */ viafb_write_reg_mask(CRD2, VIACR, 0, BIT3); + break; + } + + if (viaparinfo->tmds_setting_info->iga_path == IGA2) { + /* Disable LCD Scaling */ + viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); } } - diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index c8f24058c570..03303232e543 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -718,10 +718,6 @@ static struct rgbLUT palLUT_table[] = { 0x00} }; -static void dvi_patch_skew_dvp0(void); -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 __devinit init_gfx_chip_info(int chip_type); static void __devinit init_tmds_chip_info(void); @@ -944,21 +940,6 @@ void viafb_set_secondary_color_register(u8 index, u8 red, u8 green, u8 blue) set_color_register(index, red, green, blue); } -void viafb_set_output_path(int device, int set_iga, int output_interface) -{ - switch (device) { - case DEVICE_CRT: - viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); - break; - case DEVICE_DVI: - set_dvi_output_path(set_iga, output_interface); - break; - case DEVICE_LCD: - set_lcd_output_path(set_iga, output_interface); - break; - } -} - static void set_source_common(u8 index, u8 offset, u8 iga) { u8 value, mask = 1 << offset; @@ -1045,134 +1026,6 @@ void via_set_source(u32 devices, u8 iga) set_lvds2_source(iga); } -static void dvi_patch_skew_dvp0(void) -{ - /* Reset data driving first: */ - viafb_write_reg_mask(SR1B, VIASR, 0, BIT1); - viafb_write_reg_mask(SR2A, VIASR, 0, BIT4); - - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_P4M890: - { - if ((viaparinfo->tmds_setting_info->h_active == 1600) && - (viaparinfo->tmds_setting_info->v_active == - 1200)) - viafb_write_reg_mask(CR96, VIACR, 0x03, - BIT0 + BIT1 + BIT2); - else - viafb_write_reg_mask(CR96, VIACR, 0x07, - BIT0 + BIT1 + BIT2); - break; - } - - case UNICHROME_P4M900: - { - viafb_write_reg_mask(CR96, VIACR, 0x07, - BIT0 + BIT1 + BIT2 + BIT3); - viafb_write_reg_mask(SR1B, VIASR, 0x02, BIT1); - viafb_write_reg_mask(SR2A, VIASR, 0x10, BIT4); - break; - } - - default: - { - break; - } - } -} - -static void dvi_patch_skew_dvp_low(void) -{ - switch (viaparinfo->chip_info->gfx_chip_name) { - case UNICHROME_K8M890: - { - viafb_write_reg_mask(CR99, VIACR, 0x03, BIT0 + BIT1); - break; - } - - case UNICHROME_P4M900: - { - viafb_write_reg_mask(CR99, VIACR, 0x08, - BIT0 + BIT1 + BIT2 + BIT3); - break; - } - - case UNICHROME_P4M890: - { - viafb_write_reg_mask(CR99, VIACR, 0x0F, - BIT0 + BIT1 + BIT2 + BIT3); - break; - } - - default: - { - break; - } - } -} - -static void set_dvi_output_path(int set_iga, int output_interface) -{ - switch (output_interface) { - case INTERFACE_DVP0: - viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); - viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); - viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6); - dvi_patch_skew_dvp0(); - break; - - case INTERFACE_DVP1: - if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) - viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); - - viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); - break; - case INTERFACE_DFP_HIGH: - if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) - via_write_reg_mask(VIACR, CR97, 0x03, 0x03); - - viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); - break; - - case INTERFACE_DFP_LOW: - if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) - break; - viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); - dvi_patch_skew_dvp_low(); - break; - } - - if (set_iga == IGA2) { - /* Disable LCD Scaling */ - viafb_write_reg_mask(CR79, VIACR, 0x00, BIT0); - } -} - -static void set_lcd_output_path(int set_iga, int output_interface) -{ - DEBUG_MSG(KERN_INFO - "set_lcd_output_path, iga:%d,out_interface:%d\n", - set_iga, output_interface); - - viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); - viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); - switch (output_interface) { - case INTERFACE_DFP: - if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name) - || (UNICHROME_P4M890 == - viaparinfo->chip_info->gfx_chip_name)) - viafb_write_reg_mask(CR97, VIACR, 0x84, - BIT7 + BIT2 + BIT1 + BIT0); - case INTERFACE_DVP0: - case INTERFACE_DVP1: - case INTERFACE_DFP_HIGH: - case INTERFACE_DFP_LOW: - if (set_iga == IGA2) - viafb_write_reg(CR91, VIACR, 0x00); - break; - } -} - static void load_fix_bit_crtc_reg(void) { /* always set to 1 */ @@ -2447,9 +2300,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_read_reg(VIACR, CR02) - 1); viafb_lock_crt(); } - - viafb_set_output_path(DEVICE_CRT, - viaparinfo->crt_setting_info->iga_path, 0); } if (viafb_DVI_ON) { @@ -2469,10 +2319,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, video_bpp, viaparinfo-> tmds_setting_info->iga_path); } - - viafb_set_output_path(DEVICE_DVI, - viaparinfo->tmds_setting_info->iga_path, - viaparinfo->chip_info->tmds_chip_info.output_interface); } if (viafb_LCD_ON) { @@ -2493,11 +2339,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info); } - - viafb_set_output_path(DEVICE_LCD, - viaparinfo->lvds_setting_info->iga_path, - viaparinfo->chip_info-> - lvds_chip_info.output_interface); } if (viafb_LCD2_ON) { if (viafb_SAMM_ON && @@ -2517,11 +2358,6 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, lvds_setting_info2, &viaparinfo->chip_info->lvds_chip_info2); } - - viafb_set_output_path(DEVICE_LCD, - viaparinfo->lvds_setting_info2->iga_path, - viaparinfo->chip_info-> - lvds_chip_info2.output_interface); } if ((viaparinfo->chip_info->gfx_chip_name == UNICHROME_CX700) diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index c52a1d5f092d..45dee39a8b23 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -890,9 +890,6 @@ extern int viafb_LCD_ON; extern int viafb_DVI_ON; extern int viafb_hotplug; -void viafb_set_output_path(int device, int set_iga, - int output_interface); - void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, struct VideoModeTable *video_mode, int bpp_byte, int set_iga); diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index c7de16430867..e99f933faf19 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -833,8 +833,36 @@ void viafb_lcd_disable(void) } +static void set_lcd_output_path(int set_iga, int output_interface) +{ + switch (output_interface) { + case INTERFACE_DFP: + if ((UNICHROME_K8M890 == viaparinfo->chip_info->gfx_chip_name) + || (UNICHROME_P4M890 == + viaparinfo->chip_info->gfx_chip_name)) + viafb_write_reg_mask(CR97, VIACR, 0x84, + BIT7 + BIT2 + BIT1 + BIT0); + case INTERFACE_DVP0: + case INTERFACE_DVP1: + case INTERFACE_DFP_HIGH: + case INTERFACE_DFP_LOW: + if (set_iga == IGA2) + viafb_write_reg(CR91, VIACR, 0x00); + break; + } +} + void viafb_lcd_enable(void) { + viafb_write_reg_mask(CR6B, VIACR, 0x00, BIT3); + viafb_write_reg_mask(CR6A, VIACR, 0x08, BIT3); + set_lcd_output_path(viaparinfo->lvds_setting_info->iga_path, + viaparinfo->chip_info->lvds_chip_info.output_interface); + if (viafb_LCD2_ON) + set_lcd_output_path(viaparinfo->lvds_setting_info2->iga_path, + viaparinfo->chip_info-> + lvds_chip_info2.output_interface); + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) { /* DI1 pad on */ viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); From 2a9183923af1f6f4da66aeabf9fa5af0dc58ccec Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 5 Sep 2010 01:33:28 +0000 Subject: [PATCH 12/29] viafb: add interface for output device configuration This patch extends the proc entry to contain a possibility to view and change the output devices for each IGA. This is useful for debugging output problems as it provides a reliable way to query which low level devices are active after VIAs output device configuration nightmare happended. It's as well suitable for daily use as one can change the output configuration on the fly for example to connect a projector. At the moment it's still unstable. The reason is that we have to handle a bunch of undocumented output devices (those without a proper name) and that this patch is the first step to collect and verify the needed information. Basically the only configuration change that is expected to work at the moment is switching output devices between IGA1 and IGA2. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan Cc: Andrew Morton --- drivers/video/via/hw.c | 53 +++++++++++ drivers/video/via/hw.h | 10 ++ drivers/video/via/viafbdev.c | 177 ++++++++++++++++++++++++++++++----- drivers/video/via/viafbdev.h | 2 + 4 files changed, 217 insertions(+), 25 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 03303232e543..e65edcea46eb 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -718,6 +718,16 @@ static struct rgbLUT palLUT_table[] = { 0x00} }; +static struct via_device_mapping device_mapping[] = { + {VIA_6C, "6C"}, + {VIA_93, "93"}, + {VIA_96, "96"}, + {VIA_CRT, "CRT"}, + {VIA_DVP1, "DVP1"}, + {VIA_LVDS1, "LVDS1"}, + {VIA_LVDS2, "LVDS2"} +}; + 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); @@ -1026,6 +1036,49 @@ void via_set_source(u32 devices, u8 iga) set_lvds2_source(iga); } +u32 via_parse_odev(char *input, char **end) +{ + char *ptr = input; + u32 odev = 0; + bool next = true; + int i, len; + + while (next) { + next = false; + for (i = 0; i < ARRAY_SIZE(device_mapping); i++) { + len = strlen(device_mapping[i].name); + if (!strncmp(ptr, device_mapping[i].name, len)) { + odev |= device_mapping[i].device; + ptr += len; + if (*ptr == ',') { + ptr++; + next = true; + } + } + } + } + + *end = ptr; + return odev; +} + +void via_odev_to_seq(struct seq_file *m, u32 odev) +{ + int i, count = 0; + + for (i = 0; i < ARRAY_SIZE(device_mapping); i++) { + if (odev & device_mapping[i].device) { + if (count > 0) + seq_putc(m, ','); + + seq_puts(m, device_mapping[i].name); + count++; + } + } + + seq_putc(m, '\n'); +} + static void load_fix_bit_crtc_reg(void) { /* always set to 1 */ diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 45dee39a8b23..657dbd64a089 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -22,6 +22,8 @@ #ifndef __HW_H__ #define __HW_H__ +#include + #include "viamode.h" #include "global.h" #include "via_modesetting.h" @@ -882,6 +884,11 @@ struct pci_device_id_info { u32 chip_index; }; +struct via_device_mapping { + u32 device; + const char *name; +}; + extern unsigned int viafb_second_virtual_xres; extern int viafb_SAMM_ON; extern int viafb_dual_fb; @@ -899,6 +906,9 @@ void viafb_load_reg(int timing_value, int viafb_load_reg_num, int io_type); void viafb_crt_disable(void); void viafb_crt_enable(void); +void via_set_source(u32 devices, u8 iga); +u32 via_parse_odev(char *input, char **end); +void via_odev_to_seq(struct seq_file *m, u32 odev); void init_ad9389(void); /* Access I/O Function */ void viafb_lock_crt(void); diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 5a947b096269..80ce43a318bb 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -1431,38 +1431,169 @@ static const struct file_operations viafb_vt1636_proc_fops = { .write = viafb_vt1636_proc_write, }; -static void viafb_init_proc(struct proc_dir_entry **viafb_entry) -{ - *viafb_entry = proc_mkdir("viafb", NULL); - if (*viafb_entry) { - proc_create("dvp0", 0, *viafb_entry, &viafb_dvp0_proc_fops); - proc_create("dvp1", 0, *viafb_entry, &viafb_dvp1_proc_fops); - proc_create("dfph", 0, *viafb_entry, &viafb_dfph_proc_fops); - proc_create("dfpl", 0, *viafb_entry, &viafb_dfpl_proc_fops); - if (VT1636_LVDS == viaparinfo->chip_info->lvds_chip_info. - lvds_chip_name || VT1636_LVDS == - viaparinfo->chip_info->lvds_chip_info2.lvds_chip_name) { - proc_create("vt1636", 0, *viafb_entry, &viafb_vt1636_proc_fops); - } +#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ +static ssize_t odev_update(const char __user *buffer, size_t count, u32 *odev) +{ + char buf[64], *ptr = buf; + u32 devices; + bool add, sub; + + if (count < 1 || count > 63) + return -EINVAL; + if (copy_from_user(&buf[0], buffer, count)) + return -EFAULT; + buf[count] = '\0'; + add = buf[0] == '+'; + sub = buf[0] == '-'; + if (add || sub) + ptr++; + devices = via_parse_odev(ptr, &ptr); + if (*ptr == '\n') + ptr++; + if (*ptr != 0) + return -EINVAL; + if (add) + *odev |= devices; + else if (sub) + *odev &= ~devices; + else + *odev = devices; + return count; +} + +static int viafb_iga1_odev_proc_show(struct seq_file *m, void *v) +{ + via_odev_to_seq(m, viaparinfo->shared->iga1_devices); + return 0; +} + +static int viafb_iga1_odev_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, viafb_iga1_odev_proc_show, NULL); +} + +static ssize_t viafb_iga1_odev_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) +{ + u32 dev_on, dev_off, dev_old, dev_new; + ssize_t res; + + dev_old = dev_new = viaparinfo->shared->iga1_devices; + res = odev_update(buffer, count, &dev_new); + if (res != count) + return res; + dev_off = dev_old & ~dev_new; + dev_on = dev_new & ~dev_old; + viaparinfo->shared->iga1_devices = dev_new; + viaparinfo->shared->iga2_devices &= ~dev_new; + via_set_source(dev_new, IGA1); + return res; +} + +static const struct file_operations viafb_iga1_odev_proc_fops = { + .owner = THIS_MODULE, + .open = viafb_iga1_odev_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = viafb_iga1_odev_proc_write, +}; + +static int viafb_iga2_odev_proc_show(struct seq_file *m, void *v) +{ + via_odev_to_seq(m, viaparinfo->shared->iga2_devices); + return 0; +} + +static int viafb_iga2_odev_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, viafb_iga2_odev_proc_show, NULL); +} + +static ssize_t viafb_iga2_odev_proc_write(struct file *file, + const char __user *buffer, size_t count, loff_t *pos) +{ + u32 dev_on, dev_off, dev_old, dev_new; + ssize_t res; + + dev_old = dev_new = viaparinfo->shared->iga2_devices; + res = odev_update(buffer, count, &dev_new); + if (res != count) + return res; + dev_off = dev_old & ~dev_new; + dev_on = dev_new & ~dev_old; + viaparinfo->shared->iga2_devices = dev_new; + viaparinfo->shared->iga1_devices &= ~dev_new; + via_set_source(dev_new, IGA2); + return res; +} + +static const struct file_operations viafb_iga2_odev_proc_fops = { + .owner = THIS_MODULE, + .open = viafb_iga2_odev_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, + .write = viafb_iga2_odev_proc_write, +}; + +#define IS_VT1636(lvds_chip) ((lvds_chip).lvds_chip_name == VT1636_LVDS) +static void viafb_init_proc(struct viafb_shared *shared) +{ + struct proc_dir_entry *iga1_entry, *iga2_entry, + *viafb_entry = proc_mkdir("viafb", NULL); + + shared->proc_entry = viafb_entry; + if (viafb_entry) { +#ifdef CONFIG_FB_VIA_DIRECT_PROCFS + proc_create("dvp0", 0, viafb_entry, &viafb_dvp0_proc_fops); + proc_create("dvp1", 0, viafb_entry, &viafb_dvp1_proc_fops); + proc_create("dfph", 0, viafb_entry, &viafb_dfph_proc_fops); + proc_create("dfpl", 0, viafb_entry, &viafb_dfpl_proc_fops); + if (IS_VT1636(shared->chip_info.lvds_chip_info) + || IS_VT1636(shared->chip_info.lvds_chip_info2)) + proc_create("vt1636", 0, viafb_entry, + &viafb_vt1636_proc_fops); +#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ + + iga1_entry = proc_mkdir("iga1", viafb_entry); + shared->iga1_proc_entry = iga1_entry; + proc_create("output_devices", 0, iga1_entry, + &viafb_iga1_odev_proc_fops); + iga2_entry = proc_mkdir("iga2", viafb_entry); + shared->iga2_proc_entry = iga2_entry; + proc_create("output_devices", 0, iga2_entry, + &viafb_iga2_odev_proc_fops); } } -static void viafb_remove_proc(struct proc_dir_entry *viafb_entry) +static void viafb_remove_proc(struct viafb_shared *shared) { - struct chip_information *chip_info = &viaparinfo->shared->chip_info; + struct proc_dir_entry *viafb_entry = shared->proc_entry, + *iga1_entry = shared->iga1_proc_entry, + *iga2_entry = shared->iga2_proc_entry; + if (!viafb_entry) + return; + + remove_proc_entry("output_devices", iga2_entry); + remove_proc_entry("iga2", viafb_entry); + remove_proc_entry("output_devices", iga1_entry); + remove_proc_entry("iga1", viafb_entry); + +#ifdef CONFIG_FB_VIA_DIRECT_PROCFS remove_proc_entry("dvp0", viafb_entry);/* parent dir */ remove_proc_entry("dvp1", viafb_entry); remove_proc_entry("dfph", viafb_entry); remove_proc_entry("dfpl", viafb_entry); - if (chip_info->lvds_chip_info.lvds_chip_name == VT1636_LVDS - || chip_info->lvds_chip_info2.lvds_chip_name == VT1636_LVDS) + if (IS_VT1636(shared->chip_info.lvds_chip_info) + || IS_VT1636(shared->chip_info.lvds_chip_info2)) remove_proc_entry("vt1636", viafb_entry); +#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ remove_proc_entry("viafb", NULL); } - -#endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ +#undef IS_VT1636 static int parse_mode(const char *str, u32 *xres, u32 *yres) { @@ -1671,9 +1802,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) viafbinfo->node, viafbinfo->fix.id, default_var.xres, default_var.yres, default_var.bits_per_pixel); -#ifdef CONFIG_FB_VIA_DIRECT_PROCFS - viafb_init_proc(&viaparinfo->shared->proc_entry); -#endif + viafb_init_proc(viaparinfo->shared); viafb_init_dac(IGA2); return 0; @@ -1700,9 +1829,7 @@ void __devexit via_fb_pci_remove(struct pci_dev *pdev) unregister_framebuffer(viafbinfo); if (viafb_dual_fb) unregister_framebuffer(viafbinfo1); -#ifdef CONFIG_FB_VIA_DIRECT_PROCFS - viafb_remove_proc(viaparinfo->shared->proc_entry); -#endif + viafb_remove_proc(viaparinfo->shared); framebuffer_release(viafbinfo); if (viafb_dual_fb) framebuffer_release(viafbinfo1); diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 945a47a63c4d..d66f963e930e 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -44,6 +44,8 @@ struct viafb_shared { u32 iga2_devices; struct proc_dir_entry *proc_entry; /*viafb proc entry */ + struct proc_dir_entry *iga1_proc_entry; + struct proc_dir_entry *iga2_proc_entry; struct viafb_dev *vdev; /* Global dev info */ /* All the information will be needed to set engine */ From c2a07c932dad49b3b80b11132183b8b2ec8ea1aa Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Tue, 7 Sep 2010 01:24:52 +0000 Subject: [PATCH 13/29] viafb: limit LCD code impact This patch cleans the LCD code up. It forbids overwritting global decissions like what IGA should be used as the source and whether to enable the second display channel. Additionally it removes a bit code duplication. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/lcd.c | 31 ------------------------------- 1 file changed, 31 deletions(-) diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index e99f933faf19..b7d55350be06 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -818,19 +818,12 @@ void viafb_lcd_disable(void) viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20); /* 24 bit DI data paht off */ viafb_write_reg_mask(CR91, VIACR, 0x80, 0x80); - /* Simultaneout disabled */ - viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); } /* Disable expansion bit */ viafb_write_reg_mask(CR79, VIACR, 0x00, 0x01); - /* CRT path set to IGA1 */ - viafb_write_reg_mask(SR16, VIASR, 0x00, 0x40); /* Simultaneout disabled */ viafb_write_reg_mask(CR6B, VIACR, 0x00, 0x08); - /* IGA2 path disabled */ - viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80); - } static void set_lcd_output_path(int set_iga, int output_interface) @@ -892,33 +885,9 @@ void viafb_lcd_enable(void) viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20); /* 24 bit DI data paht on */ viafb_write_reg_mask(CR91, VIACR, 0x00, 0x80); - - /* Set data source selection bit by iga path */ - if (viaparinfo->lvds_setting_info->iga_path == IGA1) { - /* DFP-H set to IGA1 */ - viafb_write_reg_mask(CR97, VIACR, 0x00, 0x10); - /* DFP-L set to IGA1 */ - viafb_write_reg_mask(CR99, VIACR, 0x00, 0x10); - } else { - /* DFP-H set to IGA2 */ - viafb_write_reg_mask(CR97, VIACR, 0x10, 0x10); - /* DFP-L set to IGA2 */ - viafb_write_reg_mask(CR99, VIACR, 0x10, 0x10); - } /* LCD enabled */ viafb_write_reg_mask(CR6A, VIACR, 0x48, 0x48); } - - if (viaparinfo->lvds_setting_info->iga_path == IGA1) { - /* CRT path set to IGA2 */ - viafb_write_reg_mask(SR16, VIASR, 0x40, 0x40); - /* IGA2 path disabled */ - viafb_write_reg_mask(CR6A, VIACR, 0x00, 0x80); - /* IGA2 path enabled */ - } else { /* IGA2 */ - viafb_write_reg_mask(CR6A, VIACR, 0x80, 0x80); - } - } static void lcd_powersequence_off(void) From 6f9422d4e407bd63a9bd665ea09e57c1e3800c47 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Tue, 7 Sep 2010 14:28:26 +0000 Subject: [PATCH 14/29] viafb: introduce per output device power management This patch moves common parts of dvi.c, lcd.c and vt1636.c to hw.c to start a per output device power management. There should be no runtime changes aside that this patch enables the proc interface to enable/disable devices when needed which greatly increases the chances that changes to the output device configuration will work. However the power management is not yet complete so it might fail on some configurations. As this area is quite complex and touches undocumented things there is a slight chance of regressions. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/dvi.c | 25 +------ drivers/video/via/hw.c | 132 +++++++++++++++++++++++++++++++---- drivers/video/via/hw.h | 9 ++- drivers/video/via/lcd.c | 10 --- drivers/video/via/viafbdev.c | 16 +++-- drivers/video/via/vt1636.c | 56 --------------- 6 files changed, 137 insertions(+), 111 deletions(-) diff --git a/drivers/video/via/dvi.c b/drivers/video/via/dvi.c index 7c82f6fda918..84e21b39dd0b 100644 --- a/drivers/video/via/dvi.c +++ b/drivers/video/via/dvi.c @@ -469,26 +469,6 @@ static void __devinit dvi_get_panel_size_from_DDCv2( /* If Disable DVI, turn off pad */ void viafb_dvi_disable(void) { - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP0) - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) & (~0xC0)); - - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DVP1) - viafb_write_reg(SR1E, VIASR, - viafb_read_reg(VIASR, SR1E) & (~0x30)); - - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_HIGH) - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) & (~0x0C)); - - if (viaparinfo->chip_info-> - tmds_chip_info.output_interface == INTERFACE_DFP_LOW) - viafb_write_reg(SR2A, VIASR, - viafb_read_reg(VIASR, SR2A) & (~0x03)); - if (viaparinfo->chip_info-> tmds_chip_info.output_interface == INTERFACE_TMDS) /* Turn off TMDS power. */ @@ -571,7 +551,6 @@ void viafb_dvi_enable(void) case INTERFACE_DVP0: viafb_write_reg_mask(CR6B, VIACR, 0x01, BIT0); viafb_write_reg_mask(CR6C, VIACR, 0x21, BIT0 + BIT5); - viafb_write_reg_mask(SR1E, VIASR, 0xC0, BIT7 + BIT6); dvi_patch_skew_dvp0(); if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) tmds_register_write(0x88, 0x3b); @@ -585,7 +564,6 @@ void viafb_dvi_enable(void) if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) viafb_write_reg_mask(CR93, VIACR, 0x21, BIT0 + BIT5); - viafb_write_reg_mask(SR1E, VIASR, 0x30, BIT4 + BIT5); /*fix dvi cann't be enabled with MB VT5718C4 - Al Zhang */ if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) tmds_register_write(0x88, 0x3b); @@ -616,14 +594,13 @@ void viafb_dvi_enable(void) if (viaparinfo->chip_info->gfx_chip_name != UNICHROME_CLE266) via_write_reg_mask(VIACR, CR97, 0x03, 0x03); - viafb_write_reg_mask(SR2A, VIASR, 0x0C, BIT2 + BIT3); via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); break; case INTERFACE_DFP_LOW: if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) break; - viafb_write_reg_mask(SR2A, VIASR, 0x03, BIT0 + BIT1); + dvi_patch_skew_dvp_low(); via_write_reg_mask(VIACR, 0x91, 0x00, 0x20); break; diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index e65edcea46eb..132d811525ed 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1036,6 +1036,121 @@ void via_set_source(u32 devices, u8 iga) set_lvds2_source(iga); } +static void set_crt_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x00; + break; + case VIA_STATE_STANDBY: + value = 0x10; + break; + case VIA_STATE_SUSPEND: + value = 0x20; + break; + case VIA_STATE_OFF: + value = 0x30; + break; + default: + return; + } + + via_write_reg_mask(VIACR, 0x36, value, 0x30); +} + +static void set_96_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0xC0; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1E, value, 0xC0); +} + +static void set_dvp1_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x30; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x1E, value, 0x30); +} + +static void set_lvds1_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x03; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2A, value, 0x03); +} + +static void set_lvds2_state(u8 state) +{ + u8 value; + + switch (state) { + case VIA_STATE_ON: + value = 0x0C; + break; + case VIA_STATE_OFF: + value = 0x00; + break; + default: + return; + } + + via_write_reg_mask(VIASR, 0x2A, value, 0x0C); +} + +void via_set_state(u32 devices, u8 state) +{ + /* + TODO: Can we enable/disable these devices? How? + if (devices & VIA_6C) + if (devices & VIA_93) + */ + if (devices & VIA_96) + set_96_state(state); + if (devices & VIA_CRT) + set_crt_state(state); + if (devices & VIA_DVP1) + set_dvp1_state(state); + if (devices & VIA_LVDS1) + set_lvds1_state(state); + if (devices & VIA_LVDS2) + set_lvds2_state(state); +} + u32 via_parse_odev(char *input, char **end) { char *ptr = input; @@ -2224,6 +2339,8 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, { int i, j; int port; + u32 devices = viaparinfo->shared->iga1_devices + | viaparinfo->shared->iga2_devices; u8 value, index, mask; struct crt_mode_table *crt_timing; struct crt_mode_table *crt_timing1 = NULL; @@ -2271,6 +2388,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, } device_off(); + via_set_state(devices, VIA_STATE_OFF); /* Fill VPIT Parameters */ /* Write Misc Register */ @@ -2430,6 +2548,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_DeviceStatus = CRT_Device; } device_on(); + via_set_state(devices, VIA_STATE_ON); device_screen_on(); return 1; } @@ -2470,31 +2589,18 @@ int viafb_get_refresh(int hres, int vres, u32 long_refresh) static void device_off(void) { - viafb_crt_disable(); viafb_dvi_disable(); viafb_lcd_disable(); } static void device_on(void) { - if (viafb_CRT_ON == 1) - viafb_crt_enable(); if (viafb_DVI_ON == 1) viafb_dvi_enable(); if (viafb_LCD_ON == 1) viafb_lcd_enable(); } -void viafb_crt_disable(void) -{ - viafb_write_reg_mask(CR36, VIACR, BIT5 + BIT4, BIT5 + BIT4); -} - -void viafb_crt_enable(void) -{ - viafb_write_reg_mask(CR36, VIACR, 0x0, BIT5 + BIT4); -} - static void enable_second_display_channel(void) { /* to enable second display channel. */ diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index 657dbd64a089..b067cbb45ebf 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -41,6 +41,12 @@ #define VIA_LVDS1 0x00000040 #define VIA_LVDS2 0x00000080 +/* VIA output device power states */ +#define VIA_STATE_ON 0 +#define VIA_STATE_STANDBY 1 +#define VIA_STATE_SUSPEND 2 +#define VIA_STATE_OFF 3 + /*************************************************** * Definition IGA1 Design Method of CRTC Registers * ****************************************************/ @@ -904,9 +910,8 @@ void viafb_set_vclock(u32 CLK, int set_iga); void viafb_load_reg(int timing_value, int viafb_load_reg_num, struct io_register *reg, int io_type); -void viafb_crt_disable(void); -void viafb_crt_enable(void); void via_set_source(u32 devices, u8 iga); +void via_set_state(u32 devices, u8 state); u32 via_parse_odev(char *input, char **end); void via_odev_to_seq(struct seq_file *m, u32 odev); void init_ad9389(void); diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index b7d55350be06..de19e4777daf 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -703,9 +703,6 @@ static void integrated_lvds_disable(struct lvds_setting_information viafb_write_reg_mask(CR91, VIACR, 0xC0, BIT6 + BIT7); } - /* Turn DFP High/Low Pad off. */ - viafb_write_reg_mask(SR2A, VIASR, 0, BIT0 + BIT1 + BIT2 + BIT3); - /* Power off LVDS channel. */ switch (plvds_chip_info->output_interface) { case INTERFACE_LVDS0: @@ -761,9 +758,6 @@ static void integrated_lvds_enable(struct lvds_setting_information break; } - /* Turn DFP High/Low pad on. */ - viafb_write_reg_mask(SR2A, VIASR, 0x0F, BIT0 + BIT1 + BIT2 + BIT3); - /* Power on LVDS channel. */ switch (plvds_chip_info->output_interface) { case INTERFACE_LVDS0: @@ -812,8 +806,6 @@ void viafb_lcd_disable(void) viafb_disable_lvds_vt1636(viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info); } else { - /* DFP-HL pad off */ - viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0F); /* Backlight off */ viafb_write_reg_mask(SR3D, VIASR, 0x00, 0x20); /* 24 bit DI data paht off */ @@ -879,8 +871,6 @@ void viafb_lcd_enable(void) viafb_enable_lvds_vt1636(viaparinfo->lvds_setting_info, &viaparinfo->chip_info->lvds_chip_info); } else { - /* DFP-HL pad on */ - viafb_write_reg_mask(SR2A, VIASR, 0x0F, 0x0F); /* Backlight on */ viafb_write_reg_mask(SR3D, VIASR, 0x20, 0x20); /* 24 bit DI data paht on */ diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 80ce43a318bb..164c6ea603d2 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -332,22 +332,22 @@ static int viafb_blank(int blank_mode, struct fb_info *info) case FB_BLANK_UNBLANK: /* Screen: On, HSync: On, VSync: On */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x00, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_ON); break; case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off, HSync: Off, VSync: On */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x10, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_STANDBY); break; case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off, HSync: On, VSync: Off */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x20, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_SUSPEND); break; case FB_BLANK_POWERDOWN: /* Screen: Off, HSync: Off, VSync: Off */ /* control CRT monitor power management */ - viafb_write_reg_mask(CR36, VIACR, 0x30, BIT4 + BIT5); + via_set_state(VIA_CRT, VIA_STATE_OFF); break; } @@ -457,7 +457,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) if (copy_from_user(&gpu32, argp, sizeof(gpu32))) return -EFAULT; if (gpu32 & CRT_Device) - viafb_crt_enable(); + via_set_state(VIA_CRT, VIA_STATE_ON); if (gpu32 & DVI_Device) viafb_dvi_enable(); if (gpu32 & LCD_Device) @@ -467,7 +467,7 @@ static int viafb_ioctl(struct fb_info *info, u_int cmd, u_long arg) if (copy_from_user(&gpu32, argp, sizeof(gpu32))) return -EFAULT; if (gpu32 & CRT_Device) - viafb_crt_disable(); + via_set_state(VIA_CRT, VIA_STATE_OFF); if (gpu32 & DVI_Device) viafb_dvi_disable(); if (gpu32 & LCD_Device) @@ -1487,7 +1487,9 @@ static ssize_t viafb_iga1_odev_proc_write(struct file *file, dev_on = dev_new & ~dev_old; viaparinfo->shared->iga1_devices = dev_new; viaparinfo->shared->iga2_devices &= ~dev_new; + via_set_state(dev_off, VIA_STATE_OFF); via_set_source(dev_new, IGA1); + via_set_state(dev_on, VIA_STATE_ON); return res; } @@ -1525,7 +1527,9 @@ static ssize_t viafb_iga2_odev_proc_write(struct file *file, dev_on = dev_new & ~dev_old; viaparinfo->shared->iga2_devices = dev_new; viaparinfo->shared->iga1_devices &= ~dev_new; + via_set_state(dev_off, VIA_STATE_OFF); via_set_source(dev_new, IGA2); + via_set_state(dev_on, VIA_STATE_ON); return res; } diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index d65bf1aee87c..90aad12c2c4d 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c @@ -92,34 +92,6 @@ void viafb_enable_lvds_vt1636(struct lvds_setting_information viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, VDD_ON_TBL_VT1636[0]); - - /* Pad on: */ - switch (plvds_chip_info->output_interface) { - case INTERFACE_DVP0: - { - viafb_write_reg_mask(SR1E, VIASR, 0xC0, 0xC0); - break; - } - - case INTERFACE_DVP1: - { - viafb_write_reg_mask(SR1E, VIASR, 0x30, 0x30); - break; - } - - case INTERFACE_DFP_LOW: - { - viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x03); - break; - } - - case INTERFACE_DFP_HIGH: - { - viafb_write_reg_mask(SR2A, VIASR, 0x03, 0x0C); - break; - } - - } } void viafb_disable_lvds_vt1636(struct lvds_setting_information @@ -129,34 +101,6 @@ void viafb_disable_lvds_vt1636(struct lvds_setting_information viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, VDD_OFF_TBL_VT1636[0]); - - /* Pad off: */ - switch (plvds_chip_info->output_interface) { - case INTERFACE_DVP0: - { - viafb_write_reg_mask(SR1E, VIASR, 0x00, 0xC0); - break; - } - - case INTERFACE_DVP1: - { - viafb_write_reg_mask(SR1E, VIASR, 0x00, 0x30); - break; - } - - case INTERFACE_DFP_LOW: - { - viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x03); - break; - } - - case INTERFACE_DFP_HIGH: - { - viafb_write_reg_mask(SR2A, VIASR, 0x00, 0x0C); - break; - } - - } } bool viafb_lvds_identify_vt1636(u8 i2c_adapter) From dbc28098248197e6b58f33ca0685f694a8e03e60 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 8 Sep 2010 17:13:55 +0000 Subject: [PATCH 15/29] viafb: vt1636 cleanup This patch merges tbl1636 into vt1636 and cleans it up as the data was only used there anyway. No runtime changes are expected. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/Makefile | 2 +- drivers/video/via/global.h | 1 - drivers/video/via/tbl1636.c | 71 ------------------------------------- drivers/video/via/tbl1636.h | 34 ------------------ drivers/video/via/vt1636.c | 65 ++++++++++++++++++++------------- 5 files changed, 42 insertions(+), 131 deletions(-) delete mode 100644 drivers/video/via/tbl1636.c delete mode 100644 drivers/video/via/tbl1636.h diff --git a/drivers/video/via/Makefile b/drivers/video/via/Makefile index d496adb0f832..96f01ee2a412 100644 --- a/drivers/video/via/Makefile +++ b/drivers/video/via/Makefile @@ -5,5 +5,5 @@ 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 \ + via_utility.o vt1636.o global.o tblDPASetting.o viamode.o \ via-core.o via-gpio.o via_modesetting.o diff --git a/drivers/video/via/global.h b/drivers/video/via/global.h index 28221a062dda..38ef5ac66953 100644 --- a/drivers/video/via/global.h +++ b/drivers/video/via/global.h @@ -48,7 +48,6 @@ #include "via_utility.h" #include "vt1636.h" #include "tblDPASetting.h" -#include "tbl1636.h" /* External struct*/ diff --git a/drivers/video/via/tbl1636.c b/drivers/video/via/tbl1636.c deleted file mode 100644 index 2d8453429d4a..000000000000 --- a/drivers/video/via/tbl1636.c +++ /dev/null @@ -1,71 +0,0 @@ -/* - * Copyright 1998-2008 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. - */ - -#include "global.h" -struct IODATA COMMON_INIT_TBL_VT1636[] = { -/* Index, Mask, Value */ - /* Set panel power sequence timing */ - {0x10, 0xC0, 0x00}, - /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */ - {0x0B, 0xFF, 0x40}, - /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */ - {0x0C, 0xFF, 0x31}, - /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/ - {0x0D, 0xFF, 0x31}, - /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */ - {0x0E, 0xFF, 0x68}, - /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */ - {0x0F, 0xFF, 0x68}, - /* LVDS output power up */ - {0x09, 0xA0, 0xA0}, - /* turn on back light */ - {0x10, 0x33, 0x13} -}; - -struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[] = { -/* Index, Mask, Value */ - {0x08, 0xF0, 0xE0} /* Input Data Mode Select */ -}; - -struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[] = { -/* Index, Mask, Value */ - {0x08, 0xF0, 0x00} /* Input Data Mode Select */ -}; - -struct IODATA DITHERING_ENABLE_TBL_VT1636[] = { -/* Index, Mask, Value */ - {0x0A, 0x70, 0x50} -}; - -struct IODATA DITHERING_DISABLE_TBL_VT1636[] = { -/* Index, Mask, Value */ - {0x0A, 0x70, 0x00} -}; - -struct IODATA VDD_ON_TBL_VT1636[] = { -/* Index, Mask, Value */ - {0x10, 0x20, 0x20} -}; - -struct IODATA VDD_OFF_TBL_VT1636[] = { -/* Index, Mask, Value */ - {0x10, 0x20, 0x00} -}; diff --git a/drivers/video/via/tbl1636.h b/drivers/video/via/tbl1636.h deleted file mode 100644 index d906055f1511..000000000000 --- a/drivers/video/via/tbl1636.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright 1998-2008 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 _TBL1636_H_ -#define _TBL1636_H_ -#include "hw.h" - -extern struct IODATA COMMON_INIT_TBL_VT1636[8]; -extern struct IODATA DUAL_CHANNEL_ENABLE_TBL_VT1636[1]; -extern struct IODATA SINGLE_CHANNEL_ENABLE_TBL_VT1636[1]; -extern struct IODATA DITHERING_ENABLE_TBL_VT1636[1]; -extern struct IODATA DITHERING_DISABLE_TBL_VT1636[1]; -extern struct IODATA VDD_ON_TBL_VT1636[1]; -extern struct IODATA VDD_OFF_TBL_VT1636[1]; - -#endif /* _VIA_TBL1636_H_ */ diff --git a/drivers/video/via/vt1636.c b/drivers/video/via/vt1636.c index 90aad12c2c4d..60e4192c2b34 100644 --- a/drivers/video/via/vt1636.c +++ b/drivers/video/via/vt1636.c @@ -23,6 +23,34 @@ #include #include "global.h" +static const struct IODATA common_init_data[] = { +/* Index, Mask, Value */ + /* Set panel power sequence timing */ + {0x10, 0xC0, 0x00}, + /* T1: VDD on - Data on. Each increment is 1 ms. (50ms = 031h) */ + {0x0B, 0xFF, 0x40}, + /* T2: Data on - Backlight on. Each increment is 2 ms. (210ms = 068h) */ + {0x0C, 0xFF, 0x31}, + /* T3: Backlight off -Data off. Each increment is 2 ms. (210ms = 068h)*/ + {0x0D, 0xFF, 0x31}, + /* T4: Data off - VDD off. Each increment is 1 ms. (50ms = 031h) */ + {0x0E, 0xFF, 0x68}, + /* T5: VDD off - VDD on. Each increment is 100 ms. (500ms = 04h) */ + {0x0F, 0xFF, 0x68}, + /* LVDS output power up */ + {0x09, 0xA0, 0xA0}, + /* turn on back light */ + {0x10, 0x33, 0x13} +}; + +/* Index, Mask, Value */ +static const struct IODATA dual_channel_enable_data = {0x08, 0xF0, 0xE0}; +static const struct IODATA single_channel_enable_data = {0x08, 0xF0, 0x00}; +static const struct IODATA dithering_enable_data = {0x0A, 0x70, 0x50}; +static const struct IODATA dithering_disable_data = {0x0A, 0x70, 0x00}; +static const struct IODATA vdd_on_data = {0x10, 0x20, 0x20}; +static const struct IODATA vdd_off_data = {0x10, 0x20, 0x00}; + u8 viafb_gpio_i2c_read_lvds(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info, u8 index) @@ -55,52 +83,41 @@ void viafb_init_lvds_vt1636(struct lvds_setting_information int reg_num, i; /* Common settings: */ - reg_num = ARRAY_SIZE(COMMON_INIT_TBL_VT1636); - - for (i = 0; i < reg_num; i++) { + reg_num = ARRAY_SIZE(common_init_data); + for (i = 0; i < reg_num; i++) viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - COMMON_INIT_TBL_VT1636[i]); - } + plvds_chip_info, common_init_data[i]); /* Input Data Mode Select */ - if (plvds_setting_info->device_lcd_dualedge) { + if (plvds_setting_info->device_lcd_dualedge) viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - DUAL_CHANNEL_ENABLE_TBL_VT1636[0]); - } else { + plvds_chip_info, dual_channel_enable_data); + else viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - SINGLE_CHANNEL_ENABLE_TBL_VT1636[0]); - } + plvds_chip_info, single_channel_enable_data); - if (plvds_setting_info->LCDDithering) { + if (plvds_setting_info->LCDDithering) viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - DITHERING_ENABLE_TBL_VT1636[0]); - } else { + plvds_chip_info, dithering_enable_data); + else viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, - plvds_chip_info, - DITHERING_DISABLE_TBL_VT1636[0]); - } + plvds_chip_info, dithering_disable_data); } void viafb_enable_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) { - viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, - VDD_ON_TBL_VT1636[0]); + vdd_on_data); } void viafb_disable_lvds_vt1636(struct lvds_setting_information *plvds_setting_info, struct lvds_chip_information *plvds_chip_info) { - viafb_gpio_i2c_write_mask_lvds(plvds_setting_info, plvds_chip_info, - VDD_OFF_TBL_VT1636[0]); + vdd_off_data); } bool viafb_lvds_identify_vt1636(u8 i2c_adapter) From 85c5702ac046b14713f776d59768252d8ed8018f Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Fri, 17 Sep 2010 01:16:25 +0000 Subject: [PATCH 16/29] viafb: fix i2c_transfer error handling i2c_transfer returns negative errno on error and number of messages processed on success. Just returning this value would give a poor interface as it is not obvious that you must compare with 2 after reading 1 or n bytes and with 1 after writing 1 byte to determine if it was successful. To avoid this error prone interface convert the error code of a successful read/write to zero and all other non-negative values to an negative error code. This fixes a regression introduced by via: Rationalize vt1636 detection which resulted in no longer detecting a VT1636 chip and therefore has broken the output in configurations which contain this chip. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan Cc: stable@kernel.org --- drivers/video/via/via_i2c.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index da9e4ca94b17..021112e279de 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -114,6 +114,7 @@ static void via_i2c_setsda(void *data, int state) int viafb_i2c_readbyte(u8 adap, u8 slave_addr, u8 index, u8 *pdata) { + int ret; u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -126,11 +127,18 @@ 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(&via_i2c_par[adap].adapter, msgs, 2); + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } int viafb_i2c_writebyte(u8 adap, u8 slave_addr, u8 index, u8 data) { + int ret; u8 msg[2] = { index, data }; struct i2c_msg msgs; @@ -140,11 +148,18 @@ 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(&via_i2c_par[adap].adapter, &msgs, 1); + ret = i2c_transfer(&via_i2c_par[adap].adapter, &msgs, 1); + if (ret == 1) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } int viafb_i2c_readbytes(u8 adap, u8 slave_addr, u8 index, u8 *buff, int buff_len) { + int ret; u8 mm1[] = {0x00}; struct i2c_msg msgs[2]; @@ -156,7 +171,13 @@ 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(&via_i2c_par[adap].adapter, msgs, 2); + ret = i2c_transfer(&via_i2c_par[adap].adapter, msgs, 2); + if (ret == 2) + ret = 0; + else if (ret >= 0) + ret = -EIO; + + return ret; } /* From ee40b7d1c0391944cdd328d4e2432bd4c110c644 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Fri, 17 Sep 2010 01:56:18 +0000 Subject: [PATCH 17/29] viafb: enable I2C for CRT This patch enables the I2C port to talk with the CRT. This allows adding EDID reading and parsing capability for CRTs. Just a small preparation, no notable changes in user experience yet. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan --- drivers/video/via/via-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 66f403033111..69101ab9f7c9 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -20,7 +20,7 @@ * The default port config. */ static struct via_port_cfg adap_configs[] = { - [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_OFF, VIASR, 0x26 }, + [VIA_PORT_26] = { VIA_PORT_I2C, VIA_MODE_I2C, 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 }, From e029ab0d02b94d633d8e82a46dfdb7fd94a62216 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Fri, 17 Sep 2010 02:10:33 +0000 Subject: [PATCH 18/29] viafb: reduce I2C timeout and delay This patch reduces the value for I2C timeout and udelay. The udelay was reduced to 10 (old: 40) which is still very high as for standard-mode I2C even 5 should work. This gives a speedup of factor 4 when talking to I2C devices. The timeout was reduced to 2 (old: 20) which is taken from the radeon driver so it should work as well. This gives a speedup of factor 10 when detecting that there is no I2C device we want to talk to. This causes a huge improvement of device initialization time. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan --- drivers/video/via/via_i2c.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/video/via/via_i2c.c b/drivers/video/via/via_i2c.c index 021112e279de..3844b558b7bd 100644 --- a/drivers/video/via/via_i2c.c +++ b/drivers/video/via/via_i2c.c @@ -202,8 +202,8 @@ static int create_i2c_bus(struct i2c_adapter *adapter, algo->setscl = via_i2c_setscl; algo->getsda = via_i2c_getsda; algo->getscl = via_i2c_getscl; - algo->udelay = 40; - algo->timeout = 20; + algo->udelay = 10; + algo->timeout = 2; algo->data = adap_cfg; sprintf(adapter->name, "viafb i2c io_port idx 0x%02x", From 7f0e153e2c0b15aa7427ad4ac550640e1e2e9c33 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sat, 18 Sep 2010 23:47:28 +0000 Subject: [PATCH 19/29] viafb: add function to change sync polarity per device At the moment only the sync polarity for CRT is handled but there are also bits for controlling the sync polarity for other output devices. Add a function to change those similar to the other output device functions. There is no runtime change yet as the code still handles only CRT. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 24 +++++++++++++++++++++--- drivers/video/via/hw.h | 5 +++++ 2 files changed, 26 insertions(+), 3 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 132d811525ed..d6bbb0a05c3e 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1151,6 +1151,24 @@ void via_set_state(u32 devices, u8 state) set_lvds2_state(state); } +void via_set_sync_polarity(u32 devices, u8 polarity) +{ + if (polarity & ~(VIA_HSYNC_NEGATIVE | VIA_VSYNC_NEGATIVE)) { + printk(KERN_WARNING "viafb: Unsupported polarity: %d\n", + polarity); + return; + } + + if (devices & VIA_CRT) + via_write_misc_reg_mask(polarity << 6, 0xC0); + if (devices & VIA_DVP1) + via_write_reg_mask(VIACR, 0x9B, polarity << 5, 0x60); + if (devices & VIA_LVDS1) + via_write_reg_mask(VIACR, 0x99, polarity << 5, 0x60); + if (devices & VIA_LVDS2) + via_write_reg_mask(VIACR, 0x97, polarity << 5, 0x60); +} + u32 via_parse_odev(char *input, char **end) { char *ptr = input; @@ -2026,10 +2044,10 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, /* update polarity for CRT timing */ if (crt_table[index].h_sync_polarity == NEGATIVE) - polarity |= BIT6; + polarity |= VIA_HSYNC_NEGATIVE; if (crt_table[index].v_sync_polarity == NEGATIVE) - polarity |= BIT7; - via_write_misc_reg_mask(polarity, BIT6 | BIT7); + polarity |= VIA_VSYNC_NEGATIVE; + via_set_sync_polarity(VIA_CRT, polarity); if (set_iga == IGA1) { viafb_unlock_crt(); diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index b067cbb45ebf..ad6f9b1cf40e 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -47,6 +47,10 @@ #define VIA_STATE_SUSPEND 2 #define VIA_STATE_OFF 3 +/* VIA output device sync polarity */ +#define VIA_HSYNC_NEGATIVE 0x01 +#define VIA_VSYNC_NEGATIVE 0x02 + /*************************************************** * Definition IGA1 Design Method of CRTC Registers * ****************************************************/ @@ -912,6 +916,7 @@ void viafb_load_reg(int timing_value, int viafb_load_reg_num, int io_type); void via_set_source(u32 devices, u8 iga); void via_set_state(u32 devices, u8 state); +void via_set_sync_polarity(u32 devices, u8 polarity); u32 via_parse_odev(char *input, char **end); void via_odev_to_seq(struct seq_file *m, u32 odev); void init_ad9389(void); From 2e1abbdd1dbc49e16eabd13e8b2458ee48e7b560 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 19 Sep 2010 01:20:19 +0000 Subject: [PATCH 20/29] viafb: set sync polarity for all output devices This patch sets the sync polarity for all output devices, not only CRT. This may give some people a working screen but only if lcd scaling and centering are not used as it is currently too dificult to propagate a different resolution (from what the application thinks) to the correct output device. Hopefully this does not introduce regressions as the polarity of non-CRT devices was completly ignored before. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan --- drivers/video/via/hw.c | 34 +++++++++++++++++++++++++--------- 1 file changed, 25 insertions(+), 9 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index d6bbb0a05c3e..00fecb579acc 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -2014,7 +2014,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, int index = 0; int h_addr, v_addr; u32 pll_D_N; - u8 polarity = 0; for (i = 0; i < video_mode->mode_array; i++) { index = i; @@ -2041,14 +2040,6 @@ void viafb_fill_crtc_timing(struct crt_mode_table *crt_table, h_addr = crt_reg.hor_addr; v_addr = crt_reg.ver_addr; - - /* update polarity for CRT timing */ - if (crt_table[index].h_sync_polarity == NEGATIVE) - polarity |= VIA_HSYNC_NEGATIVE; - if (crt_table[index].v_sync_polarity == NEGATIVE) - polarity |= VIA_VSYNC_NEGATIVE; - via_set_sync_polarity(VIA_CRT, polarity); - if (set_iga == IGA1) { viafb_unlock_crt(); viafb_write_reg(CR09, VIACR, 0x00); /*initial CR09=0 */ @@ -2352,6 +2343,17 @@ static void set_display_channel(void) } } +static u8 get_sync(struct fb_info *info) +{ + u8 polarity = 0; + + if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT)) + polarity |= VIA_HSYNC_NEGATIVE; + if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT)) + polarity |= VIA_VSYNC_NEGATIVE; + return polarity; +} + int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, struct VideoModeTable *vmode_tbl1, int video_bpp1) { @@ -2566,6 +2568,15 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, viafb_DeviceStatus = CRT_Device; } device_on(); + if (!viafb_dual_fb) + via_set_sync_polarity(devices, get_sync(viafbinfo)); + else { + via_set_sync_polarity(viaparinfo->shared->iga1_devices, + get_sync(viafbinfo)); + via_set_sync_polarity(viaparinfo->shared->iga2_devices, + get_sync(viafbinfo1)); + } + via_set_state(devices, VIA_STATE_ON); device_screen_on(); return 1; @@ -2719,4 +2730,9 @@ void viafb_fill_var_timing_info(struct fb_var_screeninfo *var, int refresh, crt_reg.ver_total - (crt_reg.ver_sync_start + crt_reg.ver_sync_end); var->lower_margin = crt_reg.ver_sync_start - crt_reg.ver_addr; var->vsync_len = crt_reg.ver_sync_end; + var->sync = 0; + if (crt_timing[index].h_sync_polarity == POSITIVE) + var->sync |= FB_SYNC_HOR_HIGH_ACT; + if (crt_timing[index].v_sync_polarity == POSITIVE) + var->sync |= FB_SYNC_VERT_HIGH_ACT; } From dd7a0b08cd921763e570f693ecc4816aa2f1a3fd Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 19 Sep 2010 04:20:55 +0000 Subject: [PATCH 21/29] viafb: add a mapping of supported output devices This patch maps supported output devices to IGP versions. This list may contain errors as most of it is derived of the driver source but it should be correct enough to provide a good help. The devices are exported via a proc entry in the same format as those showing the output devices per IGA. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan Cc: Andrew Morton --- drivers/video/via/viafbdev.c | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 164c6ea603d2..50f486d9b087 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -56,6 +56,31 @@ static int viafb_pan_display(struct fb_var_screeninfo *var, static struct fb_ops viafb_ops; +/* supported output devices on each IGP + * only CX700, VX800, VX855 were documented + * VIA_CRT should be everywhere + * VIA_6C can be onle pre-CX700 (probably only on CLE266) as 6C is used for PLL + * source selection on CX700 and later + * K400 seems to support VIA_96, VIA_DVP1, VIA_LVDS{1,2} as in viamode.c + */ +static const u32 supported_odev_map[] = { + [UNICHROME_CLE266] = VIA_CRT | VIA_6C | VIA_93, + [UNICHROME_K400] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + | VIA_LVDS2, + [UNICHROME_K800] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + | VIA_LVDS2, + [UNICHROME_PM800] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + | VIA_LVDS2, + [UNICHROME_CN700] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + | VIA_LVDS2, + [UNICHROME_CX700] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, + [UNICHROME_CN750] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, + [UNICHROME_K8M890] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, + [UNICHROME_P4M890] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, + [UNICHROME_P4M900] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, + [UNICHROME_VX800] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, + [UNICHROME_VX855] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, +}; static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth) { @@ -1433,6 +1458,26 @@ static const struct file_operations viafb_vt1636_proc_fops = { #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ +static int viafb_sup_odev_proc_show(struct seq_file *m, void *v) +{ + via_odev_to_seq(m, supported_odev_map[ + viaparinfo->shared->chip_info.gfx_chip_name]); + return 0; +} + +static int viafb_sup_odev_proc_open(struct inode *inode, struct file *file) +{ + return single_open(file, viafb_sup_odev_proc_show, NULL); +} + +static const struct file_operations viafb_sup_odev_proc_fops = { + .owner = THIS_MODULE, + .open = viafb_sup_odev_proc_open, + .read = seq_read, + .llseek = seq_lseek, + .release = single_release, +}; + static ssize_t odev_update(const char __user *buffer, size_t count, u32 *odev) { char buf[64], *ptr = buf; @@ -1561,6 +1606,8 @@ static void viafb_init_proc(struct viafb_shared *shared) &viafb_vt1636_proc_fops); #endif /* CONFIG_FB_VIA_DIRECT_PROCFS */ + proc_create("supported_output_devices", 0, viafb_entry, + &viafb_sup_odev_proc_fops); iga1_entry = proc_mkdir("iga1", viafb_entry); shared->iga1_proc_entry = iga1_entry; proc_create("output_devices", 0, iga1_entry, @@ -1584,6 +1631,7 @@ static void viafb_remove_proc(struct viafb_shared *shared) remove_proc_entry("iga2", viafb_entry); remove_proc_entry("output_devices", iga1_entry); remove_proc_entry("iga1", viafb_entry); + remove_proc_entry("supported_output_devices", viafb_entry); #ifdef CONFIG_FB_VIA_DIRECT_PROCFS remove_proc_entry("dvp0", viafb_entry);/* parent dir */ From a2aa9f9f5ad94c8e0e767110c7a659de84a6b762 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 19 Sep 2010 04:40:15 +0000 Subject: [PATCH 22/29] viafb: rename output devices Now it looks like we finally know enough about the output devices to give them proper names. As VIA_96 is often referred to as DVP0 rename it to VIA_DVP0. As VIA_6C and VIA_93 seem to exist only on CLE266 and "replace" DVP0 and DVP1 there rename them to VIA_LDVP0 and VIA_LDVP1 (L as legacy). The proc names were changed accordingly which should be harmless as they were just introduced and not beyond RFC state. This patch should make things a bit more comfortable and less scary. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan Cc: Andrew Morton --- drivers/video/via/hw.c | 44 ++++++++++++++++++------------------ drivers/video/via/hw.h | 6 ++--- drivers/video/via/viafbdev.c | 10 ++++---- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 00fecb579acc..7d7010acf148 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -719,9 +719,9 @@ static struct rgbLUT palLUT_table[] = { }; static struct via_device_mapping device_mapping[] = { - {VIA_6C, "6C"}, - {VIA_93, "93"}, - {VIA_96, "96"}, + {VIA_LDVP0, "LDVP0"}, + {VIA_LDVP1, "LDVP1"}, + {VIA_DVP0, "DVP0"}, {VIA_CRT, "CRT"}, {VIA_DVP1, "DVP1"}, {VIA_LVDS1, "LVDS1"}, @@ -763,11 +763,11 @@ static u32 get_dvi_devices(int output_interface) { switch (output_interface) { case INTERFACE_DVP0: - return VIA_96 | VIA_6C; + return VIA_DVP0 | VIA_LDVP0; case INTERFACE_DVP1: if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) - return VIA_93; + return VIA_LDVP1; else return VIA_DVP1; @@ -775,7 +775,7 @@ static u32 get_dvi_devices(int output_interface) if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) return 0; else - return VIA_LVDS2 | VIA_96; + return VIA_LVDS2 | VIA_DVP0; case INTERFACE_DFP_LOW: if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_CLE266) @@ -794,13 +794,13 @@ static u32 get_lcd_devices(int output_interface) { switch (output_interface) { case INTERFACE_DVP0: - return VIA_96; + return VIA_DVP0; case INTERFACE_DVP1: return VIA_DVP1; case INTERFACE_DFP_HIGH: - return VIA_LVDS2 | VIA_96; + return VIA_LVDS2 | VIA_DVP0; case INTERFACE_DFP_LOW: return VIA_LVDS1 | VIA_DVP1; @@ -988,17 +988,17 @@ static void set_crt_source(u8 iga) via_write_reg_mask(VIASR, 0x16, value, 0x40); } -static inline void set_6C_source(u8 iga) +static inline void set_ldvp0_source(u8 iga) { set_source_common(0x6C, 7, iga); } -static inline void set_93_source(u8 iga) +static inline void set_ldvp1_source(u8 iga) { set_source_common(0x93, 7, iga); } -static inline void set_96_source(u8 iga) +static inline void set_dvp0_source(u8 iga) { set_source_common(0x96, 4, iga); } @@ -1020,12 +1020,12 @@ static inline void set_lvds2_source(u8 iga) void via_set_source(u32 devices, u8 iga) { - if (devices & VIA_6C) - set_6C_source(iga); - if (devices & VIA_93) - set_93_source(iga); - if (devices & VIA_96) - set_96_source(iga); + if (devices & VIA_LDVP0) + set_ldvp0_source(iga); + if (devices & VIA_LDVP1) + set_ldvp1_source(iga); + if (devices & VIA_DVP0) + set_dvp0_source(iga); if (devices & VIA_CRT) set_crt_source(iga); if (devices & VIA_DVP1) @@ -1060,7 +1060,7 @@ static void set_crt_state(u8 state) via_write_reg_mask(VIACR, 0x36, value, 0x30); } -static void set_96_state(u8 state) +static void set_dvp0_state(u8 state) { u8 value; @@ -1136,11 +1136,11 @@ void via_set_state(u32 devices, u8 state) { /* TODO: Can we enable/disable these devices? How? - if (devices & VIA_6C) - if (devices & VIA_93) + if (devices & VIA_LDVP0) + if (devices & VIA_LDVP1) */ - if (devices & VIA_96) - set_96_state(state); + if (devices & VIA_DVP0) + set_dvp0_state(state); if (devices & VIA_CRT) set_crt_state(state); if (devices & VIA_DVP1) diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index ad6f9b1cf40e..b76440946771 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -33,9 +33,9 @@ #define viafb_write_reg_mask(i, p, d, m) via_write_reg_mask(p, i, d, m) /* VIA output devices */ -#define VIA_6C 0x00000001 -#define VIA_93 0x00000002 -#define VIA_96 0x00000004 +#define VIA_LDVP0 0x00000001 +#define VIA_LDVP1 0x00000002 +#define VIA_DVP0 0x00000004 #define VIA_CRT 0x00000010 #define VIA_DVP1 0x00000020 #define VIA_LVDS1 0x00000040 diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 50f486d9b087..7cc057d7ef5e 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -64,14 +64,14 @@ static struct fb_ops viafb_ops; * K400 seems to support VIA_96, VIA_DVP1, VIA_LVDS{1,2} as in viamode.c */ static const u32 supported_odev_map[] = { - [UNICHROME_CLE266] = VIA_CRT | VIA_6C | VIA_93, - [UNICHROME_K400] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + [UNICHROME_CLE266] = VIA_CRT | VIA_LDVP0 | VIA_LDVP1, + [UNICHROME_K400] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, - [UNICHROME_K800] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + [UNICHROME_K800] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, - [UNICHROME_PM800] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + [UNICHROME_PM800] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, - [UNICHROME_CN700] = VIA_CRT | VIA_96 | VIA_DVP1 | VIA_LVDS1 + [UNICHROME_CN700] = VIA_CRT | VIA_DVP0 | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, [UNICHROME_CX700] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, [UNICHROME_CN750] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, From 47eb1d841790082d2fb4bc7a83c81e0a84a30a9e Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 19 Sep 2010 05:35:44 +0000 Subject: [PATCH 23/29] viafb: add documentation for proc interface This patch adds documentation for the new proc interface that allows modification of the output device configuration. Should be stable and useful enough now for daily use. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan Cc: Andrew Morton --- Documentation/fb/viafb.txt | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/Documentation/fb/viafb.txt b/Documentation/fb/viafb.txt index f3e046a6a987..1a2e8aa3fbb1 100644 --- a/Documentation/fb/viafb.txt +++ b/Documentation/fb/viafb.txt @@ -197,6 +197,54 @@ Notes: example, # fbset -depth 16 + +[Configure viafb via /proc] +--------------------------- + The following files exist in /proc/viafb + + supported_output_devices + + This read-only file contains a full ',' seperated list containing all + output devices that could be available on your platform. It is likely + that not all of those have a connector on your hardware but it should + provide a good starting point to figure out which of those names match + a real connector. + Example: + # cat /proc/viafb/supported_output_devices + + iga1/output_devices + iga2/output_devices + + These two files are readable and writable. iga1 and iga2 are the two + independent units that produce the screen image. Those images can be + forwarded to one or more output devices. Reading those files is a way + to query which output devices are currently used by an iga. + Example: + # cat /proc/viafb/iga1/output_devices + If there are no output devices printed the output of this iga is lost. + This can happen for example if only one (the other) iga is used. + Writing to these files allows adjusting the output devices during + runtime. One can add new devices, remove existing ones or switch + between igas. Essentially you can write a ',' seperated list of device + names (or a single one) in the same format as the output to those + files. You can add a '+' or '-' as a prefix allowing simple addition + and removal of devices. So a prefix '+' adds the devices from your list + to the already existing ones, '-' removes the listed devices from the + existing ones and if no prefix is given it replaces all existing ones + with the listed ones. If you remove devices they are expected to turn + off. If you add devices that are already part of the other iga they are + removed there and added to the new one. + Examples: + Add CRT as output device to iga1 + # echo +CRT > /proc/viafb/iga1/output_devices + + Remove (turn off) DVP1 and LVDS1 as output devices of iga2 + # echo -DVP1,LVDS1 > /proc/viafb/iga2/output_devices + + Replace all iga1 output devices by CRT + # echo CRT > /proc/viafb/iga1/output_devices + + [Bootup with viafb]: -------------------- Add the following line to your grub.conf: From efd4f6398dc92b5bf392670df862f42a19f34cf2 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Wed, 22 Sep 2010 02:33:52 +0000 Subject: [PATCH 24/29] viafb: use proper register for colour when doing fill ops The colour was written to a wrong register for fillrect operations. This sometimes caused empty console space (for example after 'clear') to have a different colour than desired. Fix this by writing to the correct register. Many thanks to Daniel Drake and Jon Nettleton for pointing out this issue and pointing me in the right direction for the fix. Fixes http://dev.laptop.org/ticket/9323 Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan Cc: Daniel Drake Cc: Jon Nettleton Cc: stable@kernel.org --- drivers/video/via/accel.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index e44893ea590d..c2f4e6e166f1 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c @@ -283,11 +283,12 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height, writel(tmp, engine + 0x1C); } - if (op != VIA_BITBLT_COLOR) + if (op == VIA_BITBLT_FILL) { + writel(fg_color, engine + 0x58); + } else if (op == VIA_BITBLT_MONO) { writel(fg_color, engine + 0x4C); - - if (op == VIA_BITBLT_MONO) writel(bg_color, engine + 0x50); + } if (op == VIA_BITBLT_FILL) ge_cmd |= fill_rop << 24 | 0x00002000 | 0x00000001; From 3fd9b6cc38028ea64e9a39c6af9d5ad928594be6 Mon Sep 17 00:00:00 2001 From: Deepak Saxena Date: Thu, 8 Apr 2010 11:15:41 -0600 Subject: [PATCH 25/29] Minimal support for viafb suspend/resume This patch adds minimal support for suspend/resume of the VIA framebuffer device. It requires a version of OFW that restores the video mode. This patch is OLPC-specific as the proper upstream solution is to move the VIA video path to using the kernel modesetting infrastructure and doing a proper save/restore in the kernel. [jc: extensive changes for 2.6.34 merge] Signed-off-by: Deepak Saxena [fts: viafb_driver moved from viafbdev.c to via-core.c] Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan --- drivers/video/via/via-core.c | 4 ++++ drivers/video/via/viafbdev.c | 46 ++++++++++++++++++++++++++++++++++++ drivers/video/via/viafbdev.h | 5 ++++ 3 files changed, 55 insertions(+) diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 69101ab9f7c9..9b487a6a8d08 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -644,6 +644,10 @@ static struct pci_driver via_driver = { .id_table = via_pci_table, .probe = via_pci_probe, .remove = __devexit_p(via_pci_remove), +#ifdef CONFIG_PM + .suspend = viafb_suspend, + .resume = viafb_resume, +#endif }; static int __init via_core_init(void) diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 7cc057d7ef5e..596235b5a5f0 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -1669,6 +1669,52 @@ static int parse_mode(const char *str, u32 *xres, u32 *yres) } +#ifdef CONFIG_PM +int viafb_suspend(struct pci_dev *pdev, pm_message_t state) +{ + if (state.event == PM_EVENT_SUSPEND) { + acquire_console_sem(); + + memcpy_fromio(viaparinfo->shared->saved_regs, + viaparinfo->shared->vdev->engine_mmio + 0x100, + 0xff * sizeof(u32)); + + fb_set_suspend(viafbinfo, 1); + + viafb_sync(viafbinfo); + + pci_save_state(pdev); + pci_disable_device(pdev); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); + release_console_sem(); + } + + return 0; +} + +int viafb_resume(struct pci_dev *pdev) +{ + acquire_console_sem(); + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); + if (pci_enable_device(pdev)) + goto fail; + pci_set_master(pdev); + + memcpy_toio(viaparinfo->shared->vdev->engine_mmio + 0x100, + viaparinfo->shared->saved_regs, + 0x100 * sizeof(u32)); + + fb_set_suspend(viafbinfo, 0); + +fail: + release_console_sem(); + return 0; +} + +#endif + + int __devinit via_fb_pci_probe(struct viafb_dev *vdev) { u32 default_xres, default_yres; diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index d66f963e930e..29a8c6c769ec 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -62,6 +62,9 @@ struct viafb_shared { u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, u32 fg_color, u32 bg_color, u8 fill_rop); + + /* For suspend/resume */ + u32 saved_regs[0x100]; }; struct viafb_par { @@ -108,4 +111,6 @@ void via_fb_pci_remove(struct pci_dev *pdev); /* Temporary */ int viafb_init(void); void viafb_exit(void); +int viafb_suspend(struct pci_dev *pdev, pm_message_t state); +int viafb_resume(struct pci_dev *pdev); #endif /* __VIAFBDEV_H__ */ From b75f2c01de34daf0b25cbd75fcf00511548ffa1e Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Mon, 26 Apr 2010 16:37:53 +0000 Subject: [PATCH 26/29] viafb: restore display on resume This patch makes viafb restore the display on resume by calling viafb_set_par. Resumeing has still its issues: - will probably freeze most machines (for me on VX800 reliable on the second resume) - under some configurations the screen appears on the wrong output device (reason unknown) Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan --- drivers/video/via/viafbdev.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 596235b5a5f0..6a7327eaf869 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -1705,6 +1705,9 @@ int viafb_resume(struct pci_dev *pdev) viaparinfo->shared->saved_regs, 0x100 * sizeof(u32)); + viafb_set_par(viafbinfo); + if (viafb_dual_fb) + viafb_set_par(viafbinfo1); fb_set_suspend(viafbinfo, 0); fail: From 466bc7fc4246d95cbd37edd169eafb8185e41941 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Mon, 26 Apr 2010 17:08:00 +0000 Subject: [PATCH 27/29] viafb: make suspend and resume work (on all machines?) This patch removes the dangerous suspend and resume code that was developed for VX855 only. After this the framebuffer is expected to cause no longer serious (freezing) issues on any machines. However the hardware acceleration is broken now so only doing resume with unaccelerated framebuffers is save. This did not work previously as the 2D engine is not mapped if the framebuffer is not accelerated. The acceleration issue will be addressed later. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan --- drivers/video/via/viafbdev.c | 10 ---------- drivers/video/via/viafbdev.h | 3 --- 2 files changed, 13 deletions(-) diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 6a7327eaf869..4e9e105a6c78 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -1674,11 +1674,6 @@ int viafb_suspend(struct pci_dev *pdev, pm_message_t state) { if (state.event == PM_EVENT_SUSPEND) { acquire_console_sem(); - - memcpy_fromio(viaparinfo->shared->saved_regs, - viaparinfo->shared->vdev->engine_mmio + 0x100, - 0xff * sizeof(u32)); - fb_set_suspend(viafbinfo, 1); viafb_sync(viafbinfo); @@ -1700,11 +1695,6 @@ int viafb_resume(struct pci_dev *pdev) if (pci_enable_device(pdev)) goto fail; pci_set_master(pdev); - - memcpy_toio(viaparinfo->shared->vdev->engine_mmio + 0x100, - viaparinfo->shared->saved_regs, - 0x100 * sizeof(u32)); - viafb_set_par(viafbinfo); if (viafb_dual_fb) viafb_set_par(viafbinfo1); diff --git a/drivers/video/via/viafbdev.h b/drivers/video/via/viafbdev.h index 29a8c6c769ec..4960e3da6645 100644 --- a/drivers/video/via/viafbdev.h +++ b/drivers/video/via/viafbdev.h @@ -62,9 +62,6 @@ struct viafb_shared { u8 dst_bpp, u32 dst_addr, u32 dst_pitch, u32 dst_x, u32 dst_y, u32 *src_mem, u32 src_addr, u32 src_pitch, u32 src_x, u32 src_y, u32 fg_color, u32 bg_color, u8 fill_rop); - - /* For suspend/resume */ - u32 saved_regs[0x100]; }; struct viafb_par { From adac8d65f399b02e8a2222fc75c658e4b8d24f65 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Mon, 26 Apr 2010 17:31:03 +0000 Subject: [PATCH 28/29] viafb: fix hardware acceleration for suspend & resume This patch splits the acceleration initialization in two parts: The first is only called during probe and is used to allocate resources. The second part is also called on resume to reinitalize the 2D engine. This should fix all acceleration issues after resume most notable an "invisible" cursor and as we do nothing special it is reasonable to assume that it works on all supported IGPs. Signed-off-by: Florian Tobias Schandinat Acked-by: Jonathan Corbet Cc: Joseph Chan --- drivers/video/via/accel.c | 43 ++++++++++++++++++++++-------------- drivers/video/via/accel.h | 3 ++- drivers/video/via/viafbdev.c | 4 +++- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index c2f4e6e166f1..bc4905366726 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c @@ -315,13 +315,11 @@ static int hw_bitblt_2(void __iomem *engine, u8 op, u32 width, u32 height, return 0; } -int viafb_init_engine(struct fb_info *info) +int viafb_setup_engine(struct fb_info *info) { struct viafb_par *viapar = info->par; void __iomem *engine; - int highest_reg, i; - 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; + u32 chip_name = viapar->shared->chip_info.gfx_chip_name; engine = viapar->shared->vdev->engine_mmio; if (!engine) { @@ -330,18 +328,6 @@ int viafb_init_engine(struct fb_info *info) return -ENOMEM; } - /* Initialize registers to reset the 2D engine */ - switch (viapar->shared->chip_info.twod_engine) { - case VIA_2D_ENG_M1: - highest_reg = 0x5c; - break; - default: - highest_reg = 0x40; - break; - } - for (i = 0; i <= highest_reg; i += 4) - writel(0x0, engine + i); - switch (chip_name) { case UNICHROME_CLE266: case UNICHROME_K400: @@ -387,6 +373,29 @@ int viafb_init_engine(struct fb_info *info) viapar->shared->vdev->camera_fbmem_offset = viapar->fbmem_free; #endif + viafb_reset_engine(viapar); + return 0; +} + +void viafb_reset_engine(struct viafb_par *viapar) +{ + void __iomem *engine = viapar->shared->vdev->engine_mmio; + int highest_reg, i; + 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; + + /* Initialize registers to reset the 2D engine */ + switch (viapar->shared->chip_info.twod_engine) { + case VIA_2D_ENG_M1: + highest_reg = 0x5c; + break; + default: + highest_reg = 0x40; + break; + } + for (i = 0; i <= highest_reg; i += 4) + writel(0x0, engine + i); + /* Init AGP and VQ regs */ switch (chip_name) { case UNICHROME_K8M890: @@ -474,7 +483,7 @@ int viafb_init_engine(struct fb_info *info) writel(0x0, engine + VIA_REG_CURSOR_ORG); writel(0x0, engine + VIA_REG_CURSOR_BG); writel(0x0, engine + VIA_REG_CURSOR_FG); - return 0; + return; } void viafb_show_hw_cursor(struct fb_info *info, int Status) diff --git a/drivers/video/via/accel.h b/drivers/video/via/accel.h index 2c122d292365..79d5e10cc835 100644 --- a/drivers/video/via/accel.h +++ b/drivers/video/via/accel.h @@ -203,7 +203,8 @@ #define VIA_BITBLT_MONO 2 #define VIA_BITBLT_FILL 3 -int viafb_init_engine(struct fb_info *info); +int viafb_setup_engine(struct fb_info *info); +void viafb_reset_engine(struct viafb_par *viapar); void viafb_show_hw_cursor(struct fb_info *info, int Status); void viafb_wait_engine_idle(struct fb_info *info); diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 4e9e105a6c78..6c651e401dc6 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -1695,6 +1695,8 @@ int viafb_resume(struct pci_dev *pdev) if (pci_enable_device(pdev)) goto fail; pci_set_master(pdev); + if (viaparinfo->shared->vdev->engine_mmio) + viafb_reset_engine(viaparinfo); viafb_set_par(viafbinfo); if (viafb_dual_fb) viafb_set_par(viafbinfo1); @@ -1766,7 +1768,7 @@ int __devinit via_fb_pci_probe(struct viafb_dev *vdev) viafbinfo->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; viafbinfo->pseudo_palette = pseudo_pal; - if (viafb_accel && !viafb_init_engine(viafbinfo)) { + if (viafb_accel && !viafb_setup_engine(viafbinfo)) { viafbinfo->flags |= FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | FBINFO_HWACCEL_IMAGEBLIT; default_var.accel_flags = FB_ACCELF_TEXT; From 51f4332bb5fef869e8a89895a7bac6b4c03b4946 Mon Sep 17 00:00:00 2001 From: Florian Tobias Schandinat Date: Sun, 24 Oct 2010 04:02:14 +0000 Subject: [PATCH 29/29] viafb: add initial VX900 support This patch adds basic support for the new VX900 IGP. Almost everything that was implemented for other IGPs is expected to work also on VX900 after this patch. The only known issue is that on the CRT output mode setting does not always work. It is clear that the possibility for regressions is zero. A big thanks to VIA Technologies for making this possible and supporting this work. Signed-off-by: Florian Tobias Schandinat Cc: Joseph Chan Cc: Jonathan Corbet --- drivers/video/via/accel.c | 3 +++ drivers/video/via/chip.h | 3 +++ drivers/video/via/hw.c | 23 +++++++++++++++++++++++ drivers/video/via/hw.h | 13 +++++++++++++ drivers/video/via/lcd.c | 2 ++ drivers/video/via/via-core.c | 10 ++++++++-- drivers/video/via/viafbdev.c | 6 ++++-- 7 files changed, 56 insertions(+), 4 deletions(-) diff --git a/drivers/video/via/accel.c b/drivers/video/via/accel.c index bc4905366726..3c969cdef0af 100644 --- a/drivers/video/via/accel.c +++ b/drivers/video/via/accel.c @@ -343,6 +343,7 @@ int viafb_setup_engine(struct fb_info *info) break; case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: viapar->shared->hw_bitblt = hw_bitblt_2; break; default: @@ -402,6 +403,7 @@ void viafb_reset_engine(struct viafb_par *viapar) case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: writel(0x00100000, engine + VIA_REG_CR_TRANSET); writel(0x680A0000, engine + VIA_REG_CR_TRANSPACE); writel(0x02000000, engine + VIA_REG_CR_TRANSPACE); @@ -438,6 +440,7 @@ void viafb_reset_engine(struct viafb_par *viapar) case UNICHROME_P4M900: case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: vq_start_low |= 0x20000000; vq_end_low |= 0x20000000; vq_high |= 0x20000000; diff --git a/drivers/video/via/chip.h b/drivers/video/via/chip.h index ef1f3de2e052..48f1342897bd 100644 --- a/drivers/video/via/chip.h +++ b/drivers/video/via/chip.h @@ -71,6 +71,9 @@ #define UNICHROME_VX855 12 #define UNICHROME_VX855_DID 0x5122 +#define UNICHROME_VX900 13 +#define UNICHROME_VX900_DID 0x7122 + /**************************************************/ /* Definition TMDS Trasmitter Information */ /**************************************************/ diff --git a/drivers/video/via/hw.c b/drivers/video/via/hw.c index 7d7010acf148..36d73f940d8b 100644 --- a/drivers/video/via/hw.c +++ b/drivers/video/via/hw.c @@ -1429,6 +1429,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) VX855_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; } + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) { + iga1_fifo_max_depth = VX900_IGA1_FIFO_MAX_DEPTH; + iga1_fifo_threshold = VX900_IGA1_FIFO_THRESHOLD; + iga1_fifo_high_threshold = + VX900_IGA1_FIFO_HIGH_THRESHOLD; + iga1_display_queue_expire_num = + VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM; + } + /* Set Display FIFO Depath Select */ reg_value = IGA1_FIFO_DEPTH_SELECT_FORMULA(iga1_fifo_max_depth); viafb_load_reg_num = @@ -1569,6 +1578,15 @@ void viafb_load_FIFO_reg(int set_iga, int hor_active, int ver_active) VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; } + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_VX900) { + iga2_fifo_max_depth = VX900_IGA2_FIFO_MAX_DEPTH; + iga2_fifo_threshold = VX900_IGA2_FIFO_THRESHOLD; + iga2_fifo_high_threshold = + VX900_IGA2_FIFO_HIGH_THRESHOLD; + iga2_display_queue_expire_num = + VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM; + } + if (viaparinfo->chip_info->gfx_chip_name == UNICHROME_K800) { /* Set Display FIFO Depath Select */ reg_value = @@ -1689,6 +1707,7 @@ u32 viafb_get_clk_value(int clk) break; case UNICHROME_VX855: + case UNICHROME_VX900: value = vx855_encode_pll(pll_value[i].vx855_pll); break; } @@ -1722,6 +1741,7 @@ void viafb_set_vclock(u32 clk, int set_iga) 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); @@ -1748,6 +1768,7 @@ void viafb_set_vclock(u32 clk, int set_iga) 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); @@ -2179,6 +2200,7 @@ static void __devinit init_gfx_chip_info(int chip_type) switch (viaparinfo->chip_info->gfx_chip_name) { case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: viaparinfo->chip_info->twod_engine = VIA_2D_ENG_M1; break; case UNICHROME_K8M890: @@ -2403,6 +2425,7 @@ int viafb_setmode(struct VideoModeTable *vmode_tbl, int video_bpp, break; case UNICHROME_VX855: + case UNICHROME_VX900: viafb_write_regx(VX855_ModeXregs, NUM_TOTAL_VX855_ModeXregs); break; } diff --git a/drivers/video/via/hw.h b/drivers/video/via/hw.h index b76440946771..668d534542ef 100644 --- a/drivers/video/via/hw.h +++ b/drivers/video/via/hw.h @@ -362,6 +362,17 @@ is reserved, so it may have problem to set 1600x1200 on IGA2. */ #define VX855_IGA2_FIFO_HIGH_THRESHOLD 160 #define VX855_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 320 +/* For VT3410 */ +#define VX900_IGA1_FIFO_MAX_DEPTH 400 +#define VX900_IGA1_FIFO_THRESHOLD 320 +#define VX900_IGA1_FIFO_HIGH_THRESHOLD 320 +#define VX900_IGA1_DISPLAY_QUEUE_EXPIRE_NUM 160 + +#define VX900_IGA2_FIFO_MAX_DEPTH 192 +#define VX900_IGA2_FIFO_THRESHOLD 160 +#define VX900_IGA2_FIFO_HIGH_THRESHOLD 160 +#define VX900_IGA2_DISPLAY_QUEUE_EXPIRE_NUM 320 + #define IGA1_FIFO_DEPTH_SELECT_REG_NUM 1 #define IGA1_FIFO_THRESHOLD_REG_NUM 2 #define IGA1_FIFO_HIGH_THRESHOLD_REG_NUM 2 @@ -879,6 +890,8 @@ struct iga2_crtc_timing { #define VX800_FUNCTION3 0x3353 /* VT3409 chipset*/ #define VX855_FUNCTION3 0x3409 +/* VT3410 chipset*/ +#define VX900_FUNCTION3 0x3410 #define NUM_TOTAL_PLL_TABLE ARRAY_SIZE(pll_value) diff --git a/drivers/video/via/lcd.c b/drivers/video/via/lcd.c index de19e4777daf..3425c3969806 100644 --- a/drivers/video/via/lcd.c +++ b/drivers/video/via/lcd.c @@ -442,6 +442,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, case UNICHROME_CN750: case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: reg_value = K800_LCD_HOR_SCF_FORMULA(set_hres, panel_hres); /* Horizontal scaling enabled */ @@ -485,6 +486,7 @@ static void load_lcd_scaling(int set_hres, int set_vres, int panel_hres, case UNICHROME_CN750: case UNICHROME_VX800: case UNICHROME_VX855: + case UNICHROME_VX900: reg_value = K800_LCD_VER_SCF_FORMULA(set_vres, panel_vres); /* Vertical scaling enabled */ diff --git a/drivers/video/via/via-core.c b/drivers/video/via/via-core.c index 9b487a6a8d08..31e30338e893 100644 --- a/drivers/video/via/via-core.c +++ b/drivers/video/via/via-core.c @@ -333,7 +333,7 @@ EXPORT_SYMBOL_GPL(viafb_dma_copy_out_sg); 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, + P4M900_FUNCTION3, VX800_FUNCTION3, VX855_FUNCTION3, VX900_FUNCTION3, }; /* Get the BIOS-configured framebuffer size from PCI configuration space @@ -370,6 +370,7 @@ static int viafb_get_fb_size_from_pci(int chip_type) case P4M900_FUNCTION3: case VX800_FUNCTION3: case VX855_FUNCTION3: + case VX900_FUNCTION3: /*case CN750_FUNCTION3: */ offset = 0xA0; break; @@ -474,7 +475,10 @@ static int __devinit via_pci_setup_mmio(struct viafb_dev *vdev) * Eventually we want to move away from mapping this * entire region. */ - vdev->fbmem_start = pci_resource_start(vdev->pdev, 0); + if (vdev->chip_type == UNICHROME_VX900) + vdev->fbmem_start = pci_resource_start(vdev->pdev, 2); + else + vdev->fbmem_start = pci_resource_start(vdev->pdev, 0); ret = vdev->fbmem_len = viafb_get_fb_size_from_pci(vdev->chip_type); if (ret < 0) goto out_unmap; @@ -635,6 +639,8 @@ static struct pci_device_id via_pci_table[] __devinitdata = { .driver_data = UNICHROME_VX800 }, { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX855_DID), .driver_data = UNICHROME_VX855 }, + { PCI_DEVICE(PCI_VENDOR_ID_VIA, UNICHROME_VX900_DID), + .driver_data = UNICHROME_VX900 }, { } }; MODULE_DEVICE_TABLE(pci, via_pci_table); diff --git a/drivers/video/via/viafbdev.c b/drivers/video/via/viafbdev.c index 6c651e401dc6..d298cfccd6fc 100644 --- a/drivers/video/via/viafbdev.c +++ b/drivers/video/via/viafbdev.c @@ -57,7 +57,7 @@ static int viafb_pan_display(struct fb_var_screeninfo *var, static struct fb_ops viafb_ops; /* supported output devices on each IGP - * only CX700, VX800, VX855 were documented + * only CX700, VX800, VX855, VX900 were documented * VIA_CRT should be everywhere * VIA_6C can be onle pre-CX700 (probably only on CLE266) as 6C is used for PLL * source selection on CX700 and later @@ -80,6 +80,7 @@ static const u32 supported_odev_map[] = { [UNICHROME_P4M900] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, [UNICHROME_VX800] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, [UNICHROME_VX855] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, + [UNICHROME_VX900] = VIA_CRT | VIA_DVP1 | VIA_LVDS1 | VIA_LVDS2, }; static void viafb_fill_var_color_info(struct fb_var_screeninfo *var, u8 depth) @@ -812,7 +813,8 @@ static int viafb_cursor(struct fb_info *info, struct fb_cursor *cursor) bg_color = cursor->image.bg_color; if (chip_name == UNICHROME_CX700 || chip_name == UNICHROME_VX800 || - chip_name == UNICHROME_VX855) { + chip_name == UNICHROME_VX855 || + chip_name == UNICHROME_VX900) { fg_color = ((info->cmap.red[fg_color] & 0xFFC0) << 14) | ((info->cmap.green[fg_color] & 0xFFC0) << 4) |