diff options
Diffstat (limited to 'drivers/gpu/drm/nouveau/nouveau_bios.c')
| -rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 297 |
1 files changed, 152 insertions, 145 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index b311faba34f8..5fc201b49d30 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -296,6 +296,11 @@ munge_reg(struct nvbios *bios, uint32_t reg) | |||
| 296 | if (dev_priv->card_type < NV_50) | 296 | if (dev_priv->card_type < NV_50) |
| 297 | return reg; | 297 | return reg; |
| 298 | 298 | ||
| 299 | if (reg & 0x80000000) { | ||
| 300 | BUG_ON(bios->display.crtc < 0); | ||
| 301 | reg += bios->display.crtc * 0x800; | ||
| 302 | } | ||
| 303 | |||
| 299 | if (reg & 0x40000000) { | 304 | if (reg & 0x40000000) { |
| 300 | BUG_ON(!dcbent); | 305 | BUG_ON(!dcbent); |
| 301 | 306 | ||
| @@ -304,7 +309,7 @@ munge_reg(struct nvbios *bios, uint32_t reg) | |||
| 304 | reg += 0x00000080; | 309 | reg += 0x00000080; |
| 305 | } | 310 | } |
| 306 | 311 | ||
| 307 | reg &= ~0x60000000; | 312 | reg &= ~0xe0000000; |
| 308 | return reg; | 313 | return reg; |
| 309 | } | 314 | } |
| 310 | 315 | ||
| @@ -635,10 +640,9 @@ static int | |||
| 635 | nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) | 640 | nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) |
| 636 | { | 641 | { |
| 637 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 642 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 638 | uint32_t reg0 = nv_rd32(dev, reg + 0); | ||
| 639 | uint32_t reg1 = nv_rd32(dev, reg + 4); | ||
| 640 | struct nouveau_pll_vals pll; | 643 | struct nouveau_pll_vals pll; |
| 641 | struct pll_lims pll_limits; | 644 | struct pll_lims pll_limits; |
| 645 | u32 ctrl, mask, coef; | ||
| 642 | int ret; | 646 | int ret; |
| 643 | 647 | ||
| 644 | ret = get_pll_limits(dev, reg, &pll_limits); | 648 | ret = get_pll_limits(dev, reg, &pll_limits); |
| @@ -649,15 +653,20 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) | |||
| 649 | if (!clk) | 653 | if (!clk) |
| 650 | return -ERANGE; | 654 | return -ERANGE; |
| 651 | 655 | ||
| 652 | reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); | 656 | coef = pll.N1 << 8 | pll.M1; |
| 653 | reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; | 657 | ctrl = pll.log2P << 16; |
| 654 | 658 | mask = 0x00070000; | |
| 655 | if (dev_priv->vbios.execute) { | 659 | if (reg == 0x004008) { |
| 656 | still_alive(); | 660 | mask |= 0x01f80000; |
| 657 | nv_wr32(dev, reg + 4, reg1); | 661 | ctrl |= (pll_limits.log2p_bias << 19); |
| 658 | nv_wr32(dev, reg + 0, reg0); | 662 | ctrl |= (pll.log2P << 22); |
| 659 | } | 663 | } |
| 660 | 664 | ||
| 665 | if (!dev_priv->vbios.execute) | ||
| 666 | return 0; | ||
| 667 | |||
| 668 | nv_mask(dev, reg + 0, mask, ctrl); | ||
| 669 | nv_wr32(dev, reg + 4, coef); | ||
| 661 | return 0; | 670 | return 0; |
| 662 | } | 671 | } |
| 663 | 672 | ||
| @@ -1174,22 +1183,19 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1174 | * | 1183 | * |
| 1175 | */ | 1184 | */ |
| 1176 | 1185 | ||
| 1177 | struct bit_displayport_encoder_table *dpe = NULL; | ||
| 1178 | struct dcb_entry *dcb = bios->display.output; | 1186 | struct dcb_entry *dcb = bios->display.output; |
| 1179 | struct drm_device *dev = bios->dev; | 1187 | struct drm_device *dev = bios->dev; |
| 1180 | uint8_t cond = bios->data[offset + 1]; | 1188 | uint8_t cond = bios->data[offset + 1]; |
| 1181 | int dummy; | 1189 | uint8_t *table, *entry; |
| 1182 | 1190 | ||
| 1183 | BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond); | 1191 | BIOSLOG(bios, "0x%04X: subop 0x%02X\n", offset, cond); |
| 1184 | 1192 | ||
| 1185 | if (!iexec->execute) | 1193 | if (!iexec->execute) |
| 1186 | return 3; | 1194 | return 3; |
| 1187 | 1195 | ||
| 1188 | dpe = nouveau_bios_dp_table(dev, dcb, &dummy); | 1196 | table = nouveau_dp_bios_data(dev, dcb, &entry); |
| 1189 | if (!dpe) { | 1197 | if (!table) |
| 1190 | NV_ERROR(dev, "0x%04X: INIT_3A: no encoder table!!\n", offset); | ||
| 1191 | return 3; | 1198 | return 3; |
| 1192 | } | ||
| 1193 | 1199 | ||
| 1194 | switch (cond) { | 1200 | switch (cond) { |
| 1195 | case 0: | 1201 | case 0: |
| @@ -1203,7 +1209,7 @@ init_dp_condition(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 1203 | break; | 1209 | break; |
| 1204 | case 1: | 1210 | case 1: |
| 1205 | case 2: | 1211 | case 2: |
| 1206 | if (!(dpe->unknown & cond)) | 1212 | if (!(entry[5] & cond)) |
| 1207 | iexec->execute = false; | 1213 | iexec->execute = false; |
| 1208 | break; | 1214 | break; |
| 1209 | case 5: | 1215 | case 5: |
| @@ -3221,6 +3227,49 @@ init_8d(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 3221 | return 1; | 3227 | return 1; |
| 3222 | } | 3228 | } |
| 3223 | 3229 | ||
| 3230 | static void | ||
| 3231 | init_gpio_unknv50(struct nvbios *bios, struct dcb_gpio_entry *gpio) | ||
| 3232 | { | ||
| 3233 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; | ||
| 3234 | u32 r, s, v; | ||
| 3235 | |||
| 3236 | /* Not a clue, needs de-magicing */ | ||
| 3237 | r = nv50_gpio_ctl[gpio->line >> 4]; | ||
| 3238 | s = (gpio->line & 0x0f); | ||
| 3239 | v = bios_rd32(bios, r) & ~(0x00010001 << s); | ||
| 3240 | switch ((gpio->entry & 0x06000000) >> 25) { | ||
| 3241 | case 1: | ||
| 3242 | v |= (0x00000001 << s); | ||
| 3243 | break; | ||
| 3244 | case 2: | ||
| 3245 | v |= (0x00010000 << s); | ||
| 3246 | break; | ||
| 3247 | default: | ||
| 3248 | break; | ||
| 3249 | } | ||
| 3250 | |||
| 3251 | bios_wr32(bios, r, v); | ||
| 3252 | } | ||
| 3253 | |||
| 3254 | static void | ||
| 3255 | init_gpio_unknvd0(struct nvbios *bios, struct dcb_gpio_entry *gpio) | ||
| 3256 | { | ||
| 3257 | u32 v, i; | ||
| 3258 | |||
| 3259 | v = bios_rd32(bios, 0x00d610 + (gpio->line * 4)); | ||
| 3260 | v &= 0xffffff00; | ||
| 3261 | v |= (gpio->entry & 0x00ff0000) >> 16; | ||
| 3262 | bios_wr32(bios, 0x00d610 + (gpio->line * 4), v); | ||
| 3263 | |||
| 3264 | i = (gpio->entry & 0x1f000000) >> 24; | ||
| 3265 | if (i) { | ||
| 3266 | v = bios_rd32(bios, 0x00d640 + ((i - 1) * 4)); | ||
| 3267 | v &= 0xffffff00; | ||
| 3268 | v |= gpio->line; | ||
| 3269 | bios_wr32(bios, 0x00d640 + ((i - 1) * 4), v); | ||
| 3270 | } | ||
| 3271 | } | ||
| 3272 | |||
| 3224 | static int | 3273 | static int |
| 3225 | init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 3274 | init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
| 3226 | { | 3275 | { |
| @@ -3235,7 +3284,6 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 3235 | 3284 | ||
| 3236 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | 3285 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
| 3237 | struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; | 3286 | struct nouveau_gpio_engine *pgpio = &dev_priv->engine.gpio; |
| 3238 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; | ||
| 3239 | int i; | 3287 | int i; |
| 3240 | 3288 | ||
| 3241 | if (dev_priv->card_type < NV_50) { | 3289 | if (dev_priv->card_type < NV_50) { |
| @@ -3248,33 +3296,20 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 3248 | 3296 | ||
| 3249 | for (i = 0; i < bios->dcb.gpio.entries; i++) { | 3297 | for (i = 0; i < bios->dcb.gpio.entries; i++) { |
| 3250 | struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i]; | 3298 | struct dcb_gpio_entry *gpio = &bios->dcb.gpio.entry[i]; |
| 3251 | uint32_t r, s, v; | ||
| 3252 | 3299 | ||
| 3253 | BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); | 3300 | BIOSLOG(bios, "0x%04X: Entry: 0x%08X\n", offset, gpio->entry); |
| 3254 | 3301 | ||
| 3255 | BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", | 3302 | BIOSLOG(bios, "0x%04X: set gpio 0x%02x, state %d\n", |
| 3256 | offset, gpio->tag, gpio->state_default); | 3303 | offset, gpio->tag, gpio->state_default); |
| 3257 | if (bios->execute) | ||
| 3258 | pgpio->set(bios->dev, gpio->tag, gpio->state_default); | ||
| 3259 | 3304 | ||
| 3260 | /* The NVIDIA binary driver doesn't appear to actually do | 3305 | if (!bios->execute) |
| 3261 | * any of this, my VBIOS does however. | 3306 | continue; |
| 3262 | */ | 3307 | |
| 3263 | /* Not a clue, needs de-magicing */ | 3308 | pgpio->set(bios->dev, gpio->tag, gpio->state_default); |
| 3264 | r = nv50_gpio_ctl[gpio->line >> 4]; | 3309 | if (dev_priv->card_type < NV_D0) |
| 3265 | s = (gpio->line & 0x0f); | 3310 | init_gpio_unknv50(bios, gpio); |
| 3266 | v = bios_rd32(bios, r) & ~(0x00010001 << s); | 3311 | else |
| 3267 | switch ((gpio->entry & 0x06000000) >> 25) { | 3312 | 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 | } | 3313 | } |
| 3279 | 3314 | ||
| 3280 | return 1; | 3315 | return 1; |
| @@ -3737,6 +3772,10 @@ parse_init_table(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
| 3737 | int count = 0, i, ret; | 3772 | int count = 0, i, ret; |
| 3738 | uint8_t id; | 3773 | uint8_t id; |
| 3739 | 3774 | ||
| 3775 | /* catch NULL script pointers */ | ||
| 3776 | if (offset == 0) | ||
| 3777 | return 0; | ||
| 3778 | |||
| 3740 | /* | 3779 | /* |
| 3741 | * Loop until INIT_DONE causes us to break out of the loop | 3780 | * Loop until INIT_DONE causes us to break out of the loop |
| 3742 | * (or until offset > bios length just in case... ) | 3781 | * (or until offset > bios length just in case... ) |
| @@ -4389,86 +4428,37 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
| 4389 | return 0; | 4428 | return 0; |
| 4390 | } | 4429 | } |
| 4391 | 4430 | ||
| 4392 | static uint8_t * | 4431 | /* BIT 'U'/'d' table encoder subtables have hashes matching them to |
| 4393 | bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, | 4432 | * a particular set of encoders. |
| 4394 | uint16_t record, int record_len, int record_nr, | 4433 | * |
| 4395 | bool match_link) | 4434 | * This function returns true if a particular DCB entry matches. |
| 4435 | */ | ||
| 4436 | bool | ||
| 4437 | bios_encoder_match(struct dcb_entry *dcb, u32 hash) | ||
| 4396 | { | 4438 | { |
| 4397 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 4439 | if ((hash & 0x000000f0) != (dcb->location << 4)) |
| 4398 | struct nvbios *bios = &dev_priv->vbios; | 4440 | return false; |
| 4399 | uint32_t entry; | 4441 | if ((hash & 0x0000000f) != dcb->type) |
| 4400 | uint16_t table; | 4442 | return false; |
| 4401 | int i, v; | 4443 | if (!(hash & (dcb->or << 16))) |
| 4444 | return false; | ||
| 4402 | 4445 | ||
| 4403 | switch (dcbent->type) { | 4446 | switch (dcb->type) { |
| 4404 | case OUTPUT_TMDS: | 4447 | case OUTPUT_TMDS: |
| 4405 | case OUTPUT_LVDS: | 4448 | case OUTPUT_LVDS: |
| 4406 | case OUTPUT_DP: | 4449 | case OUTPUT_DP: |
| 4407 | break; | 4450 | if (hash & 0x00c00000) { |
| 4408 | default: | 4451 | if (!(hash & (dcb->sorconf.link << 22))) |
| 4409 | match_link = false; | 4452 | return false; |
| 4410 | break; | ||
| 4411 | } | ||
| 4412 | |||
| 4413 | for (i = 0; i < record_nr; i++, record += record_len) { | ||
| 4414 | table = ROM16(bios->data[record]); | ||
| 4415 | if (!table) | ||
| 4416 | continue; | ||
| 4417 | entry = ROM32(bios->data[table]); | ||
| 4418 | |||
| 4419 | if (match_link) { | ||
| 4420 | v = (entry & 0x00c00000) >> 22; | ||
| 4421 | if (!(v & dcbent->sorconf.link)) | ||
| 4422 | continue; | ||
| 4423 | } | 4453 | } |
| 4424 | 4454 | default: | |
| 4425 | v = (entry & 0x000f0000) >> 16; | 4455 | return true; |
| 4426 | if (!(v & dcbent->or)) | ||
| 4427 | continue; | ||
| 4428 | |||
| 4429 | v = (entry & 0x000000f0) >> 4; | ||
| 4430 | if (v != dcbent->location) | ||
| 4431 | continue; | ||
| 4432 | |||
| 4433 | v = (entry & 0x0000000f); | ||
| 4434 | if (v != dcbent->type) | ||
| 4435 | continue; | ||
| 4436 | |||
| 4437 | return &bios->data[table]; | ||
| 4438 | } | ||
| 4439 | |||
| 4440 | return NULL; | ||
| 4441 | } | ||
| 4442 | |||
| 4443 | void * | ||
| 4444 | nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, | ||
| 4445 | int *length) | ||
| 4446 | { | ||
| 4447 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 4448 | struct nvbios *bios = &dev_priv->vbios; | ||
| 4449 | uint8_t *table; | ||
| 4450 | |||
| 4451 | if (!bios->display.dp_table_ptr) { | ||
| 4452 | NV_ERROR(dev, "No pointer to DisplayPort table\n"); | ||
| 4453 | return NULL; | ||
| 4454 | } | ||
| 4455 | table = &bios->data[bios->display.dp_table_ptr]; | ||
| 4456 | |||
| 4457 | if (table[0] != 0x20 && table[0] != 0x21) { | ||
| 4458 | NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n", | ||
| 4459 | table[0]); | ||
| 4460 | return NULL; | ||
| 4461 | } | 4456 | } |
| 4462 | |||
| 4463 | *length = table[4]; | ||
| 4464 | return bios_output_config_match(dev, dcbent, | ||
| 4465 | bios->display.dp_table_ptr + table[1], | ||
| 4466 | table[2], table[3], table[0] >= 0x21); | ||
| 4467 | } | 4457 | } |
| 4468 | 4458 | ||
| 4469 | int | 4459 | int |
| 4470 | nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | 4460 | nouveau_bios_run_display_table(struct drm_device *dev, u16 type, int pclk, |
| 4471 | uint32_t sub, int pxclk) | 4461 | struct dcb_entry *dcbent, int crtc) |
| 4472 | { | 4462 | { |
| 4473 | /* | 4463 | /* |
| 4474 | * The display script table is located by the BIT 'U' table. | 4464 | * The display script table is located by the BIT 'U' table. |
| @@ -4498,7 +4488,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4498 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; | 4488 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; |
| 4499 | uint8_t *otable = NULL; | 4489 | uint8_t *otable = NULL; |
| 4500 | uint16_t script; | 4490 | uint16_t script; |
| 4501 | int i = 0; | 4491 | int i; |
| 4502 | 4492 | ||
| 4503 | if (!bios->display.script_table_ptr) { | 4493 | if (!bios->display.script_table_ptr) { |
| 4504 | NV_ERROR(dev, "No pointer to output script table\n"); | 4494 | NV_ERROR(dev, "No pointer to output script table\n"); |
| @@ -4550,30 +4540,33 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4550 | 4540 | ||
| 4551 | NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", | 4541 | NV_DEBUG_KMS(dev, "Searching for output entry for %d %d %d\n", |
| 4552 | dcbent->type, dcbent->location, dcbent->or); | 4542 | dcbent->type, dcbent->location, dcbent->or); |
| 4553 | otable = bios_output_config_match(dev, dcbent, table[1] + | 4543 | for (i = 0; i < table[3]; i++) { |
| 4554 | bios->display.script_table_ptr, | 4544 | otable = ROMPTR(bios, table[table[1] + (i * table[2])]); |
| 4555 | table[2], table[3], table[0] >= 0x21); | 4545 | if (otable && bios_encoder_match(dcbent, ROM32(otable[0]))) |
| 4546 | break; | ||
| 4547 | } | ||
| 4548 | |||
| 4556 | if (!otable) { | 4549 | if (!otable) { |
| 4557 | NV_DEBUG_KMS(dev, "failed to match any output table\n"); | 4550 | NV_DEBUG_KMS(dev, "failed to match any output table\n"); |
| 4558 | return 1; | 4551 | return 1; |
| 4559 | } | 4552 | } |
| 4560 | 4553 | ||
| 4561 | if (pxclk < -2 || pxclk > 0) { | 4554 | if (pclk < -2 || pclk > 0) { |
| 4562 | /* Try to find matching script table entry */ | 4555 | /* Try to find matching script table entry */ |
| 4563 | for (i = 0; i < otable[5]; i++) { | 4556 | for (i = 0; i < otable[5]; i++) { |
| 4564 | if (ROM16(otable[table[4] + i*6]) == sub) | 4557 | if (ROM16(otable[table[4] + i*6]) == type) |
| 4565 | break; | 4558 | break; |
| 4566 | } | 4559 | } |
| 4567 | 4560 | ||
| 4568 | if (i == otable[5]) { | 4561 | if (i == otable[5]) { |
| 4569 | NV_ERROR(dev, "Table 0x%04x not found for %d/%d, " | 4562 | NV_ERROR(dev, "Table 0x%04x not found for %d/%d, " |
| 4570 | "using first\n", | 4563 | "using first\n", |
| 4571 | sub, dcbent->type, dcbent->or); | 4564 | type, dcbent->type, dcbent->or); |
| 4572 | i = 0; | 4565 | i = 0; |
| 4573 | } | 4566 | } |
| 4574 | } | 4567 | } |
| 4575 | 4568 | ||
| 4576 | if (pxclk == 0) { | 4569 | if (pclk == 0) { |
| 4577 | script = ROM16(otable[6]); | 4570 | script = ROM16(otable[6]); |
| 4578 | if (!script) { | 4571 | if (!script) { |
| 4579 | NV_DEBUG_KMS(dev, "output script 0 not found\n"); | 4572 | NV_DEBUG_KMS(dev, "output script 0 not found\n"); |
| @@ -4581,9 +4574,9 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4581 | } | 4574 | } |
| 4582 | 4575 | ||
| 4583 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); | 4576 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 0\n", script); |
| 4584 | nouveau_bios_run_init_table(dev, script, dcbent); | 4577 | nouveau_bios_run_init_table(dev, script, dcbent, crtc); |
| 4585 | } else | 4578 | } else |
| 4586 | if (pxclk == -1) { | 4579 | if (pclk == -1) { |
| 4587 | script = ROM16(otable[8]); | 4580 | script = ROM16(otable[8]); |
| 4588 | if (!script) { | 4581 | if (!script) { |
| 4589 | NV_DEBUG_KMS(dev, "output script 1 not found\n"); | 4582 | NV_DEBUG_KMS(dev, "output script 1 not found\n"); |
| @@ -4591,9 +4584,9 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4591 | } | 4584 | } |
| 4592 | 4585 | ||
| 4593 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); | 4586 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 1\n", script); |
| 4594 | nouveau_bios_run_init_table(dev, script, dcbent); | 4587 | nouveau_bios_run_init_table(dev, script, dcbent, crtc); |
| 4595 | } else | 4588 | } else |
| 4596 | if (pxclk == -2) { | 4589 | if (pclk == -2) { |
| 4597 | if (table[4] >= 12) | 4590 | if (table[4] >= 12) |
| 4598 | script = ROM16(otable[10]); | 4591 | script = ROM16(otable[10]); |
| 4599 | else | 4592 | else |
| @@ -4604,31 +4597,31 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
| 4604 | } | 4597 | } |
| 4605 | 4598 | ||
| 4606 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); | 4599 | NV_DEBUG_KMS(dev, "0x%04X: parsing output script 2\n", script); |
| 4607 | nouveau_bios_run_init_table(dev, script, dcbent); | 4600 | nouveau_bios_run_init_table(dev, script, dcbent, crtc); |
| 4608 | } else | 4601 | } else |
| 4609 | if (pxclk > 0) { | 4602 | if (pclk > 0) { |
| 4610 | script = ROM16(otable[table[4] + i*6 + 2]); | 4603 | script = ROM16(otable[table[4] + i*6 + 2]); |
| 4611 | if (script) | 4604 | if (script) |
| 4612 | script = clkcmptable(bios, script, pxclk); | 4605 | script = clkcmptable(bios, script, pclk); |
| 4613 | if (!script) { | 4606 | if (!script) { |
| 4614 | NV_DEBUG_KMS(dev, "clock script 0 not found\n"); | 4607 | NV_DEBUG_KMS(dev, "clock script 0 not found\n"); |
| 4615 | return 1; | 4608 | return 1; |
| 4616 | } | 4609 | } |
| 4617 | 4610 | ||
| 4618 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); | 4611 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 0\n", script); |
| 4619 | nouveau_bios_run_init_table(dev, script, dcbent); | 4612 | nouveau_bios_run_init_table(dev, script, dcbent, crtc); |
| 4620 | } else | 4613 | } else |
| 4621 | if (pxclk < 0) { | 4614 | if (pclk < 0) { |
| 4622 | script = ROM16(otable[table[4] + i*6 + 4]); | 4615 | script = ROM16(otable[table[4] + i*6 + 4]); |
| 4623 | if (script) | 4616 | if (script) |
| 4624 | script = clkcmptable(bios, script, -pxclk); | 4617 | script = clkcmptable(bios, script, -pclk); |
| 4625 | if (!script) { | 4618 | if (!script) { |
| 4626 | NV_DEBUG_KMS(dev, "clock script 1 not found\n"); | 4619 | NV_DEBUG_KMS(dev, "clock script 1 not found\n"); |
| 4627 | return 1; | 4620 | return 1; |
| 4628 | } | 4621 | } |
| 4629 | 4622 | ||
| 4630 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); | 4623 | NV_DEBUG_KMS(dev, "0x%04X: parsing clock script 1\n", script); |
| 4631 | nouveau_bios_run_init_table(dev, script, dcbent); | 4624 | nouveau_bios_run_init_table(dev, script, dcbent, crtc); |
| 4632 | } | 4625 | } |
| 4633 | 4626 | ||
| 4634 | return 0; | 4627 | return 0; |
| @@ -5478,14 +5471,6 @@ parse_bit_U_tbl_entry(struct drm_device *dev, struct nvbios *bios, | |||
| 5478 | return 0; | 5471 | return 0; |
| 5479 | } | 5472 | } |
| 5480 | 5473 | ||
| 5481 | static int | ||
| 5482 | parse_bit_displayport_tbl_entry(struct drm_device *dev, struct nvbios *bios, | ||
| 5483 | struct bit_entry *bitentry) | ||
| 5484 | { | ||
| 5485 | bios->display.dp_table_ptr = ROM16(bios->data[bitentry->offset]); | ||
| 5486 | return 0; | ||
| 5487 | } | ||
| 5488 | |||
| 5489 | struct bit_table { | 5474 | struct bit_table { |
| 5490 | const char id; | 5475 | const char id; |
| 5491 | int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *); | 5476 | int (* const parse_fn)(struct drm_device *, struct nvbios *, struct bit_entry *); |
| @@ -5559,7 +5544,6 @@ parse_bit_structure(struct nvbios *bios, const uint16_t bitoffset) | |||
| 5559 | parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds)); | 5544 | parse_bit_table(bios, bitoffset, &BIT_TABLE('L', lvds)); |
| 5560 | parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds)); | 5545 | parse_bit_table(bios, bitoffset, &BIT_TABLE('T', tmds)); |
| 5561 | parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U)); | 5546 | parse_bit_table(bios, bitoffset, &BIT_TABLE('U', U)); |
| 5562 | parse_bit_table(bios, bitoffset, &BIT_TABLE('d', displayport)); | ||
| 5563 | 5547 | ||
| 5564 | return 0; | 5548 | return 0; |
| 5565 | } | 5549 | } |
| @@ -5884,9 +5868,15 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
| 5884 | } | 5868 | } |
| 5885 | 5869 | ||
| 5886 | e->line = (e->entry & 0x0000001f) >> 0; | 5870 | e->line = (e->entry & 0x0000001f) >> 0; |
| 5887 | e->state_default = (e->entry & 0x01000000) >> 24; | 5871 | if (gpio[0] == 0x40) { |
| 5888 | e->state[0] = (e->entry & 0x18000000) >> 27; | 5872 | e->state_default = (e->entry & 0x01000000) >> 24; |
| 5889 | e->state[1] = (e->entry & 0x60000000) >> 29; | 5873 | e->state[0] = (e->entry & 0x18000000) >> 27; |
| 5874 | e->state[1] = (e->entry & 0x60000000) >> 29; | ||
| 5875 | } else { | ||
| 5876 | e->state_default = (e->entry & 0x00000080) >> 7; | ||
| 5877 | e->state[0] = (entry[4] >> 4) & 3; | ||
| 5878 | e->state[1] = (entry[4] >> 6) & 3; | ||
| 5879 | } | ||
| 5890 | } | 5880 | } |
| 5891 | } | 5881 | } |
| 5892 | 5882 | ||
| @@ -6156,7 +6146,14 @@ parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, | |||
| 6156 | } | 6146 | } |
| 6157 | case OUTPUT_DP: | 6147 | case OUTPUT_DP: |
| 6158 | entry->dpconf.sor.link = (conf & 0x00000030) >> 4; | 6148 | entry->dpconf.sor.link = (conf & 0x00000030) >> 4; |
| 6159 | entry->dpconf.link_bw = (conf & 0x00e00000) >> 21; | 6149 | switch ((conf & 0x00e00000) >> 21) { |
| 6150 | case 0: | ||
| 6151 | entry->dpconf.link_bw = 162000; | ||
| 6152 | break; | ||
| 6153 | default: | ||
| 6154 | entry->dpconf.link_bw = 270000; | ||
| 6155 | break; | ||
| 6156 | } | ||
| 6160 | switch ((conf & 0x0f000000) >> 24) { | 6157 | switch ((conf & 0x0f000000) >> 24) { |
| 6161 | case 0xf: | 6158 | case 0xf: |
| 6162 | entry->dpconf.link_nr = 4; | 6159 | entry->dpconf.link_nr = 4; |
| @@ -6769,7 +6766,7 @@ uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) | |||
| 6769 | 6766 | ||
| 6770 | void | 6767 | void |
| 6771 | nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, | 6768 | nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, |
| 6772 | struct dcb_entry *dcbent) | 6769 | struct dcb_entry *dcbent, int crtc) |
| 6773 | { | 6770 | { |
| 6774 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6771 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 6775 | struct nvbios *bios = &dev_priv->vbios; | 6772 | struct nvbios *bios = &dev_priv->vbios; |
| @@ -6777,11 +6774,22 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, | |||
| 6777 | 6774 | ||
| 6778 | spin_lock_bh(&bios->lock); | 6775 | spin_lock_bh(&bios->lock); |
| 6779 | bios->display.output = dcbent; | 6776 | bios->display.output = dcbent; |
| 6777 | bios->display.crtc = crtc; | ||
| 6780 | parse_init_table(bios, table, &iexec); | 6778 | parse_init_table(bios, table, &iexec); |
| 6781 | bios->display.output = NULL; | 6779 | bios->display.output = NULL; |
| 6782 | spin_unlock_bh(&bios->lock); | 6780 | spin_unlock_bh(&bios->lock); |
| 6783 | } | 6781 | } |
| 6784 | 6782 | ||
| 6783 | void | ||
| 6784 | nouveau_bios_init_exec(struct drm_device *dev, uint16_t table) | ||
| 6785 | { | ||
| 6786 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 6787 | struct nvbios *bios = &dev_priv->vbios; | ||
| 6788 | struct init_exec iexec = { true, false }; | ||
| 6789 | |||
| 6790 | parse_init_table(bios, table, &iexec); | ||
| 6791 | } | ||
| 6792 | |||
| 6785 | static bool NVInitVBIOS(struct drm_device *dev) | 6793 | static bool NVInitVBIOS(struct drm_device *dev) |
| 6786 | { | 6794 | { |
| 6787 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6795 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| @@ -6863,9 +6871,8 @@ nouveau_run_vbios_init(struct drm_device *dev) | |||
| 6863 | 6871 | ||
| 6864 | if (dev_priv->card_type >= NV_50) { | 6872 | if (dev_priv->card_type >= NV_50) { |
| 6865 | for (i = 0; i < bios->dcb.entries; i++) { | 6873 | for (i = 0; i < bios->dcb.entries; i++) { |
| 6866 | nouveau_bios_run_display_table(dev, | 6874 | nouveau_bios_run_display_table(dev, 0, 0, |
| 6867 | &bios->dcb.entry[i], | 6875 | &bios->dcb.entry[i], -1); |
| 6868 | 0, 0); | ||
| 6869 | } | 6876 | } |
| 6870 | } | 6877 | } |
| 6871 | 6878 | ||
