aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2011-07-02 23:40:01 -0400
committerBen Skeggs <bskeggs@redhat.com>2011-09-20 02:05:40 -0400
commit75139063b7a369f7fa849922d5a204b8ba96d582 (patch)
tree1f3ca7193ef1bf90c1b886bcb2380eb2d51c183d /drivers/gpu/drm
parentd7f8172ca93b61135d6db293c6440b2e97fc87ee (diff)
drm/nouveau/bios: fix INIT_GPIO for new chipsets
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm')
-rw-r--r--drivers/gpu/drm/nouveau/nouveau_bios.c73
1 files changed, 51 insertions, 22 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c
index 30e723c81069..f0a77b7ce60e 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bios.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bios.c
@@ -3221,6 +3221,49 @@ init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3221 return 1; 3221 return 1;
3222} 3222}
3223 3223
3224static void
3225init_gpio_unknv50(struct nvbios *bios, struct dcb_gpio_entry *gpio)
3226{
3227 const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
3228 u32 r, s, v;
3229
3230 /* Not a clue, needs de-magicing */
3231 r = nv50_gpio_ctl[gpio->line >> 4];
3232 s = (gpio->line & 0x0f);
3233 v = bios_rd32(bios, r) & ~(0x00010001 << s);
3234 switch ((gpio->entry & 0x06000000) >> 25) {
3235 case 1:
3236 v |= (0x00000001 << s);
3237 break;
3238 case 2:
3239 v |= (0x00010000 << s);
3240 break;
3241 default:
3242 break;
3243 }
3244
3245 bios_wr32(bios, r, v);
3246}
3247
3248static void
3249init_gpio_unknvd0(struct nvbios *bios, struct dcb_gpio_entry *gpio)
3250{
3251 u32 v, i;
3252
3253 v = bios_rd32(bios, 0x00d610 + (gpio->line * 4));
3254 v &= 0xffffff00;
3255 v |= (gpio->entry & 0x00ff0000) >> 16;
3256 bios_wr32(bios, 0x00d610 + (gpio->line * 4), v);
3257
3258 i = (gpio->entry & 0x1f000000) >> 24;
3259 if (i) {
3260 v = bios_rd32(bios, 0x00d640 + ((i - 1) * 4));
3261 v &= 0xffffff00;
3262 v |= gpio->line;
3263 bios_wr32(bios, 0x00d640 + ((i - 1) * 4), v);
3264 }
3265}
3266
3224static int 3267static int
3225init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) 3268init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3226{ 3269{
@@ -3235,7 +3278,6 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3235 3278
3236 struct drm_nouveau_private *dev_priv = bios->dev->dev_private; 3279 struct drm_nouveau_private *dev_priv = bios->dev->dev_private;
3237 struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; 3280 struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio;
3238 const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c };
3239 int i; 3281 int i;
3240 3282
3241 if (dev_priv->card_type < NV_50) { 3283 if (dev_priv->card_type < NV_50) {
@@ -3248,33 +3290,20 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec)
3248 3290
3249 for (i = 0; i < bios->dcb.gpio.entries; i++) { 3291 for (i = 0; i < bios->dcb.gpio.entries; i++) {
3250 struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i]; 3292 struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i];
3251 uint32_t r, s, v;
3252 3293
3253 BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); 3294 BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry);
3254 3295
3255 BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", 3296 BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n",
3256 offset, gpio->tag, gpio->state_default); 3297 offset, gpio->tag, gpio->state_default);
3257 if (bios->execute)
3258 pgpio->set(bios->dev, gpio->tag, gpio->state_default);
3259 3298
3260 /* The NVIDIA binary driver doesn't appear to actually do 3299 if (!bios->execute)
3261 * any of this, my VBIOS does however. 3300 continue;
3262 */ 3301
3263 /* Not a clue, needs de-magicing */ 3302 pgpio->set(bios->dev, gpio->tag, gpio->state_default);
3264 r = nv50_gpio_ctl[gpio->line >> 4]; 3303 if (dev_priv->card_type < NV_D0)
3265 s = (gpio->line & 0x0f); 3304 init_gpio_unknv50(bios, gpio);
3266 v = bios_rd32(bios, r) & ~(0x00010001 << s); 3305 else
3267 switch ((gpio->entry & 0x06000000) >> 25) { 3306 init_gpio_unknvd0(bios, gpio);
3268 case 1:
3269 v |= (0x00000001 << s);
3270 break;
3271 case 2:
3272 v |= (0x00010000 << s);
3273 break;
3274 default:
3275 break;
3276 }
3277 bios_wr32(bios, r, v);
3278 } 3307 }
3279 3308
3280 return 1; 3309 return 1;