diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2011-07-02 23:40:01 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2011-09-20 02:05:40 -0400 |
commit | 75139063b7a369f7fa849922d5a204b8ba96d582 (patch) | |
tree | 1f3ca7193ef1bf90c1b886bcb2380eb2d51c183d /drivers/gpu/drm | |
parent | d7f8172ca93b61135d6db293c6440b2e97fc87ee (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.c | 73 |
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 | ||
3224 | static void | ||
3225 | init_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 | |||
3248 | static void | ||
3249 | init_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 | |||
3224 | static int | 3267 | static int |
3225 | init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 3268 | init_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; |