Merge branch 'viafb-next' of git://git.lwn.net/linux-2.6
[sfrench/cifs-2.6.git] / drivers / video / via / via_utility.c
1 /*
2  * Copyright 1998-2008 VIA Technologies, Inc. All Rights Reserved.
3  * Copyright 2001-2008 S3 Graphics, Inc. All Rights Reserved.
4
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public
7  * License as published by the Free Software Foundation;
8  * either version 2, or (at your option) any later version.
9
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTIES OR REPRESENTATIONS; without even
12  * the implied warranty of MERCHANTABILITY or FITNESS FOR
13  * A PARTICULAR PURPOSE.See the GNU General Public License
14  * for more details.
15
16  * You should have received a copy of the GNU General Public License
17  * along with this program; if not, write to the Free Software
18  * Foundation, Inc.,
19  * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
20  */
21
22 #include <linux/via-core.h>
23 #include "global.h"
24
25 void viafb_get_device_support_state(u32 *support_state)
26 {
27         *support_state = CRT_Device;
28
29         if (viaparinfo->chip_info->tmds_chip_info.tmds_chip_name == VT1632_TMDS)
30                 *support_state |= DVI_Device;
31
32         if (viaparinfo->chip_info->lvds_chip_info.lvds_chip_name == VT1631_LVDS)
33                 *support_state |= LCD_Device;
34 }
35
36 void viafb_get_device_connect_state(u32 *connect_state)
37 {
38         bool mobile = false;
39
40         *connect_state = CRT_Device;
41
42         if (viafb_dvi_sense())
43                 *connect_state |= DVI_Device;
44
45         viafb_lcd_get_mobile_state(&mobile);
46         if (mobile)
47                 *connect_state |= LCD_Device;
48 }
49
50 bool viafb_lcd_get_support_expand_state(u32 xres, u32 yres)
51 {
52         unsigned int support_state = 0;
53
54         switch (viafb_lcd_panel_id) {
55         case LCD_PANEL_ID0_640X480:
56                 if ((xres < 640) && (yres < 480))
57                         support_state = true;
58                 break;
59
60         case LCD_PANEL_ID1_800X600:
61                 if ((xres < 800) && (yres < 600))
62                         support_state = true;
63                 break;
64
65         case LCD_PANEL_ID2_1024X768:
66                 if ((xres < 1024) && (yres < 768))
67                         support_state = true;
68                 break;
69
70         case LCD_PANEL_ID3_1280X768:
71                 if ((xres < 1280) && (yres < 768))
72                         support_state = true;
73                 break;
74
75         case LCD_PANEL_ID4_1280X1024:
76                 if ((xres < 1280) && (yres < 1024))
77                         support_state = true;
78                 break;
79
80         case LCD_PANEL_ID5_1400X1050:
81                 if ((xres < 1400) && (yres < 1050))
82                         support_state = true;
83                 break;
84
85         case LCD_PANEL_ID6_1600X1200:
86                 if ((xres < 1600) && (yres < 1200))
87                         support_state = true;
88                 break;
89
90         case LCD_PANEL_ID7_1366X768:
91                 if ((xres < 1366) && (yres < 768))
92                         support_state = true;
93                 break;
94
95         case LCD_PANEL_ID8_1024X600:
96                 if ((xres < 1024) && (yres < 600))
97                         support_state = true;
98                 break;
99
100         case LCD_PANEL_ID9_1280X800:
101                 if ((xres < 1280) && (yres < 800))
102                         support_state = true;
103                 break;
104
105         case LCD_PANEL_IDA_800X480:
106                 if ((xres < 800) && (yres < 480))
107                         support_state = true;
108                 break;
109
110         case LCD_PANEL_IDB_1360X768:
111                 if ((xres < 1360) && (yres < 768))
112                         support_state = true;
113                 break;
114
115         case LCD_PANEL_IDC_480X640:
116                 if ((xres < 480) && (yres < 640))
117                         support_state = true;
118                 break;
119
120         default:
121                 support_state = false;
122                 break;
123         }
124
125         return support_state;
126 }
127
128 /*====================================================================*/
129 /*                      Gamma Function Implementation*/
130 /*====================================================================*/
131
132 void viafb_set_gamma_table(int bpp, unsigned int *gamma_table)
133 {
134         int i, sr1a;
135         int active_device_amount = 0;
136         int device_status = viafb_DeviceStatus;
137
138         for (i = 0; i < sizeof(viafb_DeviceStatus) * 8; i++) {
139                 if (device_status & 1)
140                         active_device_amount++;
141                 device_status >>= 1;
142         }
143
144         /* 8 bpp mode can't adjust gamma */
145         if (bpp == 8)
146                 return ;
147
148         /* Enable Gamma */
149         switch (viaparinfo->chip_info->gfx_chip_name) {
150         case UNICHROME_CLE266:
151         case UNICHROME_K400:
152                 viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
153                 break;
154
155         case UNICHROME_K800:
156         case UNICHROME_PM800:
157         case UNICHROME_CN700:
158         case UNICHROME_CX700:
159         case UNICHROME_K8M890:
160         case UNICHROME_P4M890:
161         case UNICHROME_P4M900:
162                 viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
163                 break;
164         }
165         sr1a = (unsigned int)viafb_read_reg(VIASR, SR1A);
166         viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
167
168         /* Fill IGA1 Gamma Table */
169         outb(0, LUT_INDEX_WRITE);
170         for (i = 0; i < 256; i++) {
171                 outb(gamma_table[i] >> 16, LUT_DATA);
172                 outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
173                 outb(gamma_table[i] & 0xFF, LUT_DATA);
174         }
175
176         /* If adjust Gamma value in SAMM, fill IGA1,
177            IGA2 Gamma table simultanous. */
178         /* Switch to IGA2 Gamma Table */
179         if ((active_device_amount > 1) &&
180                 !((viaparinfo->chip_info->gfx_chip_name ==
181                 UNICHROME_CLE266) &&
182                 (viaparinfo->chip_info->gfx_chip_revision < 15))) {
183                 viafb_write_reg_mask(SR1A, VIASR, 0x01, BIT0);
184                 viafb_write_reg_mask(CR6A, VIACR, 0x02, BIT1);
185
186                 /* Fill IGA2 Gamma Table */
187                 outb(0, LUT_INDEX_WRITE);
188                 for (i = 0; i < 256; i++) {
189                         outb(gamma_table[i] >> 16, LUT_DATA);
190                         outb(gamma_table[i] >> 8 & 0xFF, LUT_DATA);
191                         outb(gamma_table[i] & 0xFF, LUT_DATA);
192                 }
193         }
194         viafb_write_reg(SR1A, VIASR, sr1a);
195 }
196
197 void viafb_get_gamma_table(unsigned int *gamma_table)
198 {
199         unsigned char color_r, color_g, color_b;
200         unsigned char sr1a = 0;
201         int i;
202
203         /* Enable Gamma */
204         switch (viaparinfo->chip_info->gfx_chip_name) {
205         case UNICHROME_CLE266:
206         case UNICHROME_K400:
207                 viafb_write_reg_mask(SR16, VIASR, 0x80, BIT7);
208                 break;
209
210         case UNICHROME_K800:
211         case UNICHROME_PM800:
212         case UNICHROME_CN700:
213         case UNICHROME_CX700:
214         case UNICHROME_K8M890:
215         case UNICHROME_P4M890:
216         case UNICHROME_P4M900:
217                 viafb_write_reg_mask(CR33, VIACR, 0x80, BIT7);
218                 break;
219         }
220         sr1a = viafb_read_reg(VIASR, SR1A);
221         viafb_write_reg_mask(SR1A, VIASR, 0x0, BIT0);
222
223         /* Reading gamma table to get color value */
224         outb(0, LUT_INDEX_READ);
225         for (i = 0; i < 256; i++) {
226                 color_r = inb(LUT_DATA);
227                 color_g = inb(LUT_DATA);
228                 color_b = inb(LUT_DATA);
229                 gamma_table[i] =
230                     ((((u32) color_r) << 16) |
231                      (((u16) color_g) << 8)) | color_b;
232         }
233         viafb_write_reg(SR1A, VIASR, sr1a);
234 }
235
236 void viafb_get_gamma_support_state(int bpp, unsigned int *support_state)
237 {
238         if (bpp == 8)
239                 *support_state = None_Device;
240         else
241                 *support_state = CRT_Device | DVI_Device | LCD_Device;
242 }