aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/radeon/radeon_combios.c
diff options
context:
space:
mode:
authorAlex Deucher <alexdeucher@gmail.com>2009-11-10 21:25:07 -0500
committerDave Airlie <airlied@redhat.com>2009-12-01 20:36:40 -0500
commitfcec570b27a47e428a9bfc8572ae4c7c230d0488 (patch)
tree10cbff0900c7de4b0cd6c83df5cc220d5844b8a9 /drivers/gpu/drm/radeon/radeon_combios.c
parent9b9fe72488a3a637e0550cc888e3f7a8f70e521e (diff)
drm/radeon/kms: add support for external tmds on legacy boards
This enables initialization of external tmds chips on pre-atom and mac systems. Macs are untested. Also, some macs have single link tmds chips while others have dual link tmds chips. We need to figure out which ones have which. This gets external TMDS working on my RS485 and RV380. Signed-off-by: Alex Deucher <alexdeucher@gmail.com> Signed-off-by: Dave Airlie <airlied@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/radeon/radeon_combios.c')
-rw-r--r--drivers/gpu/drm/radeon/radeon_combios.c332
1 files changed, 305 insertions, 27 deletions
diff --git a/drivers/gpu/drm/radeon/radeon_combios.c b/drivers/gpu/drm/radeon/radeon_combios.c
index e2a51de67aa1..f745971c6a53 100644
--- a/drivers/gpu/drm/radeon/radeon_combios.c
+++ b/drivers/gpu/drm/radeon/radeon_combios.c
@@ -993,8 +993,8 @@ static const struct radeon_tmds_pll default_tmds_pll[CHIP_LAST][4] = {
993 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */ 993 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R420 */
994 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */ 994 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_R423 */
995 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */ 995 {{0xffffffff, 0xb01cb}, {0, 0}, {0, 0}, {0, 0}}, /* CHIP_RV410 */
996 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS400 */ 996 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS400 */
997 {{15000, 0xb0155}, {0xffffffff, 0xb01cb}, {0, 0}, {0, 0}}, /* CHIP_RS480 */ 997 { {0, 0}, {0, 0}, {0, 0}, {0, 0} }, /* CHIP_RS480 */
998}; 998};
999 999
1000bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder, 1000bool radeon_legacy_get_tmds_info_from_table(struct radeon_encoder *encoder,
@@ -1028,7 +1028,6 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
1028 tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE); 1028 tmds_info = combios_get_table_offset(dev, COMBIOS_DFP_INFO_TABLE);
1029 1029
1030 if (tmds_info) { 1030 if (tmds_info) {
1031
1032 ver = RBIOS8(tmds_info); 1031 ver = RBIOS8(tmds_info);
1033 DRM_INFO("DFP table revision: %d\n", ver); 1032 DRM_INFO("DFP table revision: %d\n", ver);
1034 if (ver == 3) { 1033 if (ver == 3) {
@@ -1063,45 +1062,132 @@ bool radeon_legacy_get_tmds_info_from_combios(struct radeon_encoder *encoder,
1063 tmds->tmds_pll[i].value); 1062 tmds->tmds_pll[i].value);
1064 } 1063 }
1065 } 1064 }
1066 } else 1065 } else {
1067 DRM_INFO("No TMDS info found in BIOS\n"); 1066 DRM_INFO("No TMDS info found in BIOS\n");
1067 return false;
1068 }
1068 return true; 1069 return true;
1069} 1070}
1070 1071
1071struct radeon_encoder_int_tmds *radeon_combios_get_tmds_info(struct radeon_encoder *encoder) 1072bool radeon_legacy_get_ext_tmds_info_from_table(struct radeon_encoder *encoder,
1073 struct radeon_encoder_ext_tmds *tmds)
1072{ 1074{
1073 struct radeon_encoder_int_tmds *tmds = NULL; 1075 struct drm_device *dev = encoder->base.dev;
1074 bool ret; 1076 struct radeon_device *rdev = dev->dev_private;
1075 1077 struct radeon_i2c_bus_rec i2c_bus;
1076 tmds = kzalloc(sizeof(struct radeon_encoder_int_tmds), GFP_KERNEL);
1077 1078
1078 if (!tmds) 1079 /* default for macs */
1079 return NULL; 1080 i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
1081 tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
1080 1082
1081 ret = radeon_legacy_get_tmds_info_from_combios(encoder, tmds); 1083 /* XXX some macs have duallink chips */
1082 if (ret == false) 1084 switch (rdev->mode_info.connector_table) {
1083 radeon_legacy_get_tmds_info_from_table(encoder, tmds); 1085 case CT_POWERBOOK_EXTERNAL:
1086 case CT_MINI_EXTERNAL:
1087 default:
1088 tmds->dvo_chip = DVO_SIL164;
1089 tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
1090 break;
1091 }
1084 1092
1085 return tmds; 1093 return true;
1086} 1094}
1087 1095
1088void radeon_combios_get_ext_tmds_info(struct radeon_encoder *encoder) 1096bool radeon_legacy_get_ext_tmds_info_from_combios(struct radeon_encoder *encoder,
1097 struct radeon_encoder_ext_tmds *tmds)
1089{ 1098{
1090 struct drm_device *dev = encoder->base.dev; 1099 struct drm_device *dev = encoder->base.dev;
1091 struct radeon_device *rdev = dev->dev_private; 1100 struct radeon_device *rdev = dev->dev_private;
1092 uint16_t ext_tmds_info; 1101 uint16_t offset;
1093 uint8_t ver; 1102 uint8_t ver, id, blocks, clk, data;
1103 int i;
1104 enum radeon_combios_ddc gpio;
1105 struct radeon_i2c_bus_rec i2c_bus;
1094 1106
1095 if (rdev->bios == NULL) 1107 if (rdev->bios == NULL)
1096 return; 1108 return false;
1097 1109
1098 ext_tmds_info = 1110 tmds->i2c_bus = NULL;
1099 combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE); 1111 if (rdev->flags & RADEON_IS_IGP) {
1100 if (ext_tmds_info) { 1112 offset = combios_get_table_offset(dev, COMBIOS_I2C_INFO_TABLE);
1101 ver = RBIOS8(ext_tmds_info); 1113 if (offset) {
1102 DRM_INFO("External TMDS Table revision: %d\n", ver); 1114 ver = RBIOS8(offset);
1103 // TODO 1115 DRM_INFO("GPIO Table revision: %d\n", ver);
1116 blocks = RBIOS8(offset + 2);
1117 for (i = 0; i < blocks; i++) {
1118 id = RBIOS8(offset + 3 + (i * 5) + 0);
1119 if (id == 136) {
1120 clk = RBIOS8(offset + 3 + (i * 5) + 3);
1121 data = RBIOS8(offset + 3 + (i * 5) + 4);
1122 i2c_bus.valid = true;
1123 i2c_bus.mask_clk_mask = (1 << clk);
1124 i2c_bus.mask_data_mask = (1 << data);
1125 i2c_bus.a_clk_mask = (1 << clk);
1126 i2c_bus.a_data_mask = (1 << data);
1127 i2c_bus.en_clk_mask = (1 << clk);
1128 i2c_bus.en_data_mask = (1 << data);
1129 i2c_bus.y_clk_mask = (1 << clk);
1130 i2c_bus.y_data_mask = (1 << data);
1131 i2c_bus.mask_clk_reg = RADEON_GPIOPAD_MASK;
1132 i2c_bus.mask_data_reg = RADEON_GPIOPAD_MASK;
1133 i2c_bus.a_clk_reg = RADEON_GPIOPAD_A;
1134 i2c_bus.a_data_reg = RADEON_GPIOPAD_A;
1135 i2c_bus.en_clk_reg = RADEON_GPIOPAD_EN;
1136 i2c_bus.en_data_reg = RADEON_GPIOPAD_EN;
1137 i2c_bus.y_clk_reg = RADEON_GPIOPAD_Y;
1138 i2c_bus.y_data_reg = RADEON_GPIOPAD_Y;
1139 tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
1140 tmds->dvo_chip = DVO_SIL164;
1141 tmds->slave_addr = 0x70 >> 1; /* 7 bit addressing */
1142 break;
1143 }
1144 }
1145 }
1146 } else {
1147 offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
1148 if (offset) {
1149 ver = RBIOS8(offset);
1150 DRM_INFO("External TMDS Table revision: %d\n", ver);
1151 tmds->slave_addr = RBIOS8(offset + 4 + 2);
1152 tmds->slave_addr >>= 1; /* 7 bit addressing */
1153 gpio = RBIOS8(offset + 4 + 3);
1154 switch (gpio) {
1155 case DDC_MONID:
1156 i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
1157 tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
1158 break;
1159 case DDC_DVI:
1160 i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
1161 tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
1162 break;
1163 case DDC_VGA:
1164 i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_VGA_DDC);
1165 tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
1166 break;
1167 case DDC_CRT2:
1168 /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
1169 if (rdev->family >= CHIP_R300)
1170 i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_MONID);
1171 else
1172 i2c_bus = combios_setup_i2c_bus(RADEON_GPIO_CRT2_DDC);
1173 tmds->i2c_bus = radeon_i2c_create(dev, &i2c_bus, "DVO");
1174 break;
1175 case DDC_LCD: /* MM i2c */
1176 DRM_ERROR("MM i2c requires hw i2c engine\n");
1177 break;
1178 default:
1179 DRM_ERROR("Unsupported gpio %d\n", gpio);
1180 break;
1181 }
1182 }
1104 } 1183 }
1184
1185 if (!tmds->i2c_bus) {
1186 DRM_INFO("No valid Ext TMDS info found in BIOS\n");
1187 return false;
1188 }
1189
1190 return true;
1105} 1191}
1106 1192
1107bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev) 1193bool radeon_get_legacy_connector_info_from_table(struct drm_device *dev)
@@ -1577,10 +1663,15 @@ static bool radeon_apply_legacy_quirks(struct drm_device *dev,
1577 ddc_i2c->a_data_reg = RADEON_GPIOPAD_A; 1663 ddc_i2c->a_data_reg = RADEON_GPIOPAD_A;
1578 ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN; 1664 ddc_i2c->en_clk_reg = RADEON_GPIOPAD_EN;
1579 ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN; 1665 ddc_i2c->en_data_reg = RADEON_GPIOPAD_EN;
1580 ddc_i2c->y_clk_reg = RADEON_LCD_GPIO_Y_REG; 1666 ddc_i2c->y_clk_reg = RADEON_GPIOPAD_Y;
1581 ddc_i2c->y_data_reg = RADEON_LCD_GPIO_Y_REG; 1667 ddc_i2c->y_data_reg = RADEON_GPIOPAD_Y;
1582 } 1668 }
1583 1669
1670 /* R3xx+ chips don't have GPIO_CRT2_DDC gpio pad */
1671 if ((rdev->family >= CHIP_R300) &&
1672 ddc_i2c->mask_clk_reg == RADEON_GPIO_CRT2_DDC)
1673 *ddc_i2c = combios_setup_i2c_bus(RADEON_GPIO_DVI_DDC);
1674
1584 /* Certain IBM chipset RN50s have a BIOS reporting two VGAs, 1675 /* Certain IBM chipset RN50s have a BIOS reporting two VGAs,
1585 one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */ 1676 one with VGA DDC and one with CRT2 DDC. - kill the CRT2 DDC one */
1586 if (dev->pdev->device == 0x515e && 1677 if (dev->pdev->device == 0x515e &&
@@ -2014,6 +2105,193 @@ bool radeon_get_legacy_connector_info_from_bios(struct drm_device *dev)
2014 return true; 2105 return true;
2015} 2106}
2016 2107
2108void radeon_external_tmds_setup(struct drm_encoder *encoder)
2109{
2110 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2111 struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
2112
2113 if (!tmds)
2114 return;
2115
2116 switch (tmds->dvo_chip) {
2117 case DVO_SIL164:
2118 /* sil 164 */
2119 radeon_i2c_do_lock(tmds->i2c_bus, 1);
2120 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2121 tmds->slave_addr,
2122 0x08, 0x30);
2123 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2124 tmds->slave_addr,
2125 0x09, 0x00);
2126 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2127 tmds->slave_addr,
2128 0x0a, 0x90);
2129 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2130 tmds->slave_addr,
2131 0x0c, 0x89);
2132 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2133 tmds->slave_addr,
2134 0x08, 0x3b);
2135 radeon_i2c_do_lock(tmds->i2c_bus, 0);
2136 break;
2137 case DVO_SIL1178:
2138 /* sil 1178 - untested */
2139 /*
2140 * 0x0f, 0x44
2141 * 0x0f, 0x4c
2142 * 0x0e, 0x01
2143 * 0x0a, 0x80
2144 * 0x09, 0x30
2145 * 0x0c, 0xc9
2146 * 0x0d, 0x70
2147 * 0x08, 0x32
2148 * 0x08, 0x33
2149 */
2150 break;
2151 default:
2152 break;
2153 }
2154
2155}
2156
2157bool radeon_combios_external_tmds_setup(struct drm_encoder *encoder)
2158{
2159 struct drm_device *dev = encoder->dev;
2160 struct radeon_device *rdev = dev->dev_private;
2161 struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder);
2162 uint16_t offset;
2163 uint8_t blocks, slave_addr, rev;
2164 uint32_t index, id;
2165 uint32_t reg, val, and_mask, or_mask;
2166 struct radeon_encoder_ext_tmds *tmds = radeon_encoder->enc_priv;
2167
2168 if (rdev->bios == NULL)
2169 return false;
2170
2171 if (!tmds)
2172 return false;
2173
2174 if (rdev->flags & RADEON_IS_IGP) {
2175 offset = combios_get_table_offset(dev, COMBIOS_TMDS_POWER_ON_TABLE);
2176 rev = RBIOS8(offset);
2177 if (offset) {
2178 rev = RBIOS8(offset);
2179 if (rev > 1) {
2180 blocks = RBIOS8(offset + 3);
2181 index = offset + 4;
2182 while (blocks > 0) {
2183 id = RBIOS16(index);
2184 index += 2;
2185 switch (id >> 13) {
2186 case 0:
2187 reg = (id & 0x1fff) * 4;
2188 val = RBIOS32(index);
2189 index += 4;
2190 WREG32(reg, val);
2191 break;
2192 case 2:
2193 reg = (id & 0x1fff) * 4;
2194 and_mask = RBIOS32(index);
2195 index += 4;
2196 or_mask = RBIOS32(index);
2197 index += 4;
2198 val = RREG32(reg);
2199 val = (val & and_mask) | or_mask;
2200 WREG32(reg, val);
2201 break;
2202 case 3:
2203 val = RBIOS16(index);
2204 index += 2;
2205 udelay(val);
2206 break;
2207 case 4:
2208 val = RBIOS16(index);
2209 index += 2;
2210 udelay(val * 1000);
2211 break;
2212 case 6:
2213 slave_addr = id & 0xff;
2214 slave_addr >>= 1; /* 7 bit addressing */
2215 index++;
2216 reg = RBIOS8(index);
2217 index++;
2218 val = RBIOS8(index);
2219 index++;
2220 radeon_i2c_do_lock(tmds->i2c_bus, 1);
2221 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2222 slave_addr,
2223 reg, val);
2224 radeon_i2c_do_lock(tmds->i2c_bus, 0);
2225 break;
2226 default:
2227 DRM_ERROR("Unknown id %d\n", id >> 13);
2228 break;
2229 }
2230 blocks--;
2231 }
2232 return true;
2233 }
2234 }
2235 } else {
2236 offset = combios_get_table_offset(dev, COMBIOS_EXT_TMDS_INFO_TABLE);
2237 if (offset) {
2238 index = offset + 10;
2239 id = RBIOS16(index);
2240 while (id != 0xffff) {
2241 index += 2;
2242 switch (id >> 13) {
2243 case 0:
2244 reg = (id & 0x1fff) * 4;
2245 val = RBIOS32(index);
2246 WREG32(reg, val);
2247 break;
2248 case 2:
2249 reg = (id & 0x1fff) * 4;
2250 and_mask = RBIOS32(index);
2251 index += 4;
2252 or_mask = RBIOS32(index);
2253 index += 4;
2254 val = RREG32(reg);
2255 val = (val & and_mask) | or_mask;
2256 WREG32(reg, val);
2257 break;
2258 case 4:
2259 val = RBIOS16(index);
2260 index += 2;
2261 udelay(val);
2262 break;
2263 case 5:
2264 reg = id & 0x1fff;
2265 and_mask = RBIOS32(index);
2266 index += 4;
2267 or_mask = RBIOS32(index);
2268 index += 4;
2269 val = RREG32_PLL(reg);
2270 val = (val & and_mask) | or_mask;
2271 WREG32_PLL(reg, val);
2272 break;
2273 case 6:
2274 reg = id & 0x1fff;
2275 val = RBIOS8(index);
2276 index += 1;
2277 radeon_i2c_do_lock(tmds->i2c_bus, 1);
2278 radeon_i2c_sw_put_byte(tmds->i2c_bus,
2279 tmds->slave_addr,
2280 reg, val);
2281 radeon_i2c_do_lock(tmds->i2c_bus, 0);
2282 break;
2283 default:
2284 DRM_ERROR("Unknown id %d\n", id >> 13);
2285 break;
2286 }
2287 id = RBIOS16(index);
2288 }
2289 return true;
2290 }
2291 }
2292 return false;
2293}
2294
2017static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset) 2295static void combios_parse_mmio_table(struct drm_device *dev, uint16_t offset)
2018{ 2296{
2019 struct radeon_device *rdev = dev->dev_private; 2297 struct radeon_device *rdev = dev->dev_private;