diff options
Diffstat (limited to 'drivers/gpu')
32 files changed, 3203 insertions, 779 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index 48c290b5da8c..32db806f3b5a 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -16,7 +16,7 @@ nouveau-y := nouveau_drv.o nouveau_state.o nouveau_channel.o nouveau_mem.o \ | |||
16 | nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ | 16 | nv04_fifo.o nv10_fifo.o nv40_fifo.o nv50_fifo.o \ |
17 | nv04_graph.o nv10_graph.o nv20_graph.o \ | 17 | nv04_graph.o nv10_graph.o nv20_graph.o \ |
18 | nv40_graph.o nv50_graph.o \ | 18 | nv40_graph.o nv50_graph.o \ |
19 | nv40_grctx.o \ | 19 | nv40_grctx.o nv50_grctx.o \ |
20 | nv04_instmem.o nv50_instmem.o \ | 20 | nv04_instmem.o nv50_instmem.o \ |
21 | nv50_crtc.o nv50_dac.o nv50_sor.o \ | 21 | nv50_crtc.o nv50_dac.o nv50_sor.o \ |
22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ | 22 | nv50_cursor.o nv50_display.o nv50_fbcon.o \ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 0e9cd1d49130..71247da17da5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -311,11 +311,11 @@ valid_reg(struct nvbios *bios, uint32_t reg) | |||
311 | 311 | ||
312 | /* C51 has misaligned regs on purpose. Marvellous */ | 312 | /* C51 has misaligned regs on purpose. Marvellous */ |
313 | if (reg & 0x2 || | 313 | if (reg & 0x2 || |
314 | (reg & 0x1 && dev_priv->VBIOS.pub.chip_version != 0x51)) | 314 | (reg & 0x1 && dev_priv->vbios.chip_version != 0x51)) |
315 | NV_ERROR(dev, "======= misaligned reg 0x%08X =======\n", reg); | 315 | NV_ERROR(dev, "======= misaligned reg 0x%08X =======\n", reg); |
316 | 316 | ||
317 | /* warn on C51 regs that haven't been verified accessible in tracing */ | 317 | /* warn on C51 regs that haven't been verified accessible in tracing */ |
318 | if (reg & 0x1 && dev_priv->VBIOS.pub.chip_version == 0x51 && | 318 | if (reg & 0x1 && dev_priv->vbios.chip_version == 0x51 && |
319 | reg != 0x130d && reg != 0x1311 && reg != 0x60081d) | 319 | reg != 0x130d && reg != 0x1311 && reg != 0x60081d) |
320 | NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n", | 320 | NV_WARN(dev, "=== C51 misaligned reg 0x%08X not verified ===\n", |
321 | reg); | 321 | reg); |
@@ -420,7 +420,7 @@ bios_wr32(struct nvbios *bios, uint32_t reg, uint32_t data) | |||
420 | LOG_OLD_VALUE(bios_rd32(bios, reg)); | 420 | LOG_OLD_VALUE(bios_rd32(bios, reg)); |
421 | BIOSLOG(bios, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data); | 421 | BIOSLOG(bios, " Write: Reg: 0x%08X, Data: 0x%08X\n", reg, data); |
422 | 422 | ||
423 | if (dev_priv->VBIOS.execute) { | 423 | if (dev_priv->vbios.execute) { |
424 | still_alive(); | 424 | still_alive(); |
425 | nv_wr32(bios->dev, reg, data); | 425 | nv_wr32(bios->dev, reg, data); |
426 | } | 426 | } |
@@ -647,7 +647,7 @@ nv50_pll_set(struct drm_device *dev, uint32_t reg, uint32_t clk) | |||
647 | reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); | 647 | reg0 = (reg0 & 0xfff8ffff) | (pll.log2P << 16); |
648 | reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; | 648 | reg1 = (reg1 & 0xffff0000) | (pll.N1 << 8) | pll.M1; |
649 | 649 | ||
650 | if (dev_priv->VBIOS.execute) { | 650 | if (dev_priv->vbios.execute) { |
651 | still_alive(); | 651 | still_alive(); |
652 | nv_wr32(dev, reg + 4, reg1); | 652 | nv_wr32(dev, reg + 4, reg1); |
653 | nv_wr32(dev, reg + 0, reg0); | 653 | nv_wr32(dev, reg + 0, reg0); |
@@ -689,7 +689,7 @@ setPLL(struct nvbios *bios, uint32_t reg, uint32_t clk) | |||
689 | static int dcb_entry_idx_from_crtchead(struct drm_device *dev) | 689 | static int dcb_entry_idx_from_crtchead(struct drm_device *dev) |
690 | { | 690 | { |
691 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 691 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
692 | struct nvbios *bios = &dev_priv->VBIOS; | 692 | struct nvbios *bios = &dev_priv->vbios; |
693 | 693 | ||
694 | /* | 694 | /* |
695 | * For the results of this function to be correct, CR44 must have been | 695 | * For the results of this function to be correct, CR44 must have been |
@@ -700,7 +700,7 @@ static int dcb_entry_idx_from_crtchead(struct drm_device *dev) | |||
700 | 700 | ||
701 | uint8_t dcb_entry = NVReadVgaCrtc5758(dev, bios->state.crtchead, 0); | 701 | uint8_t dcb_entry = NVReadVgaCrtc5758(dev, bios->state.crtchead, 0); |
702 | 702 | ||
703 | if (dcb_entry > bios->bdcb.dcb.entries) { | 703 | if (dcb_entry > bios->dcb.entries) { |
704 | NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently " | 704 | NV_ERROR(dev, "CR58 doesn't have a valid DCB entry currently " |
705 | "(%02X)\n", dcb_entry); | 705 | "(%02X)\n", dcb_entry); |
706 | dcb_entry = 0x7f; /* unused / invalid marker */ | 706 | dcb_entry = 0x7f; /* unused / invalid marker */ |
@@ -713,25 +713,26 @@ static struct nouveau_i2c_chan * | |||
713 | init_i2c_device_find(struct drm_device *dev, int i2c_index) | 713 | init_i2c_device_find(struct drm_device *dev, int i2c_index) |
714 | { | 714 | { |
715 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 715 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
716 | struct bios_parsed_dcb *bdcb = &dev_priv->VBIOS.bdcb; | 716 | struct dcb_table *dcb = &dev_priv->vbios.dcb; |
717 | 717 | ||
718 | if (i2c_index == 0xff) { | 718 | if (i2c_index == 0xff) { |
719 | /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ | 719 | /* note: dcb_entry_idx_from_crtchead needs pre-script set-up */ |
720 | int idx = dcb_entry_idx_from_crtchead(dev), shift = 0; | 720 | int idx = dcb_entry_idx_from_crtchead(dev), shift = 0; |
721 | int default_indices = bdcb->i2c_default_indices; | 721 | int default_indices = dcb->i2c_default_indices; |
722 | 722 | ||
723 | if (idx != 0x7f && bdcb->dcb.entry[idx].i2c_upper_default) | 723 | if (idx != 0x7f && dcb->entry[idx].i2c_upper_default) |
724 | shift = 4; | 724 | shift = 4; |
725 | 725 | ||
726 | i2c_index = (default_indices >> shift) & 0xf; | 726 | i2c_index = (default_indices >> shift) & 0xf; |
727 | } | 727 | } |
728 | if (i2c_index == 0x80) /* g80+ */ | 728 | if (i2c_index == 0x80) /* g80+ */ |
729 | i2c_index = bdcb->i2c_default_indices & 0xf; | 729 | i2c_index = dcb->i2c_default_indices & 0xf; |
730 | 730 | ||
731 | return nouveau_i2c_find(dev, i2c_index); | 731 | return nouveau_i2c_find(dev, i2c_index); |
732 | } | 732 | } |
733 | 733 | ||
734 | static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) | 734 | static uint32_t |
735 | get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) | ||
735 | { | 736 | { |
736 | /* | 737 | /* |
737 | * For mlv < 0x80, it is an index into a table of TMDS base addresses. | 738 | * For mlv < 0x80, it is an index into a table of TMDS base addresses. |
@@ -744,6 +745,7 @@ static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) | |||
744 | */ | 745 | */ |
745 | 746 | ||
746 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 747 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
748 | struct nvbios *bios = &dev_priv->vbios; | ||
747 | const int pramdac_offset[13] = { | 749 | const int pramdac_offset[13] = { |
748 | 0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 }; | 750 | 0, 0, 0x8, 0, 0x2000, 0, 0, 0, 0x2008, 0, 0, 0, 0x2000 }; |
749 | const uint32_t pramdac_table[4] = { | 751 | const uint32_t pramdac_table[4] = { |
@@ -756,13 +758,12 @@ static uint32_t get_tmds_index_reg(struct drm_device *dev, uint8_t mlv) | |||
756 | dcb_entry = dcb_entry_idx_from_crtchead(dev); | 758 | dcb_entry = dcb_entry_idx_from_crtchead(dev); |
757 | if (dcb_entry == 0x7f) | 759 | if (dcb_entry == 0x7f) |
758 | return 0; | 760 | return 0; |
759 | dacoffset = pramdac_offset[ | 761 | dacoffset = pramdac_offset[bios->dcb.entry[dcb_entry].or]; |
760 | dev_priv->VBIOS.bdcb.dcb.entry[dcb_entry].or]; | ||
761 | if (mlv == 0x81) | 762 | if (mlv == 0x81) |
762 | dacoffset ^= 8; | 763 | dacoffset ^= 8; |
763 | return 0x6808b0 + dacoffset; | 764 | return 0x6808b0 + dacoffset; |
764 | } else { | 765 | } else { |
765 | if (mlv > ARRAY_SIZE(pramdac_table)) { | 766 | if (mlv >= ARRAY_SIZE(pramdac_table)) { |
766 | NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n", | 767 | NV_ERROR(dev, "Magic Lookup Value too big (%02X)\n", |
767 | mlv); | 768 | mlv); |
768 | return 0; | 769 | return 0; |
@@ -2574,19 +2575,19 @@ init_gpio(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2574 | 2575 | ||
2575 | const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | 2576 | const uint32_t nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; |
2576 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; | 2577 | const uint32_t nv50_gpio_ctl[2] = { 0xe100, 0xe28c }; |
2577 | const uint8_t *gpio_table = &bios->data[bios->bdcb.gpio_table_ptr]; | 2578 | const uint8_t *gpio_table = &bios->data[bios->dcb.gpio_table_ptr]; |
2578 | const uint8_t *gpio_entry; | 2579 | const uint8_t *gpio_entry; |
2579 | int i; | 2580 | int i; |
2580 | 2581 | ||
2581 | if (!iexec->execute) | 2582 | if (!iexec->execute) |
2582 | return 1; | 2583 | return 1; |
2583 | 2584 | ||
2584 | if (bios->bdcb.version != 0x40) { | 2585 | if (bios->dcb.version != 0x40) { |
2585 | NV_ERROR(bios->dev, "DCB table not version 4.0\n"); | 2586 | NV_ERROR(bios->dev, "DCB table not version 4.0\n"); |
2586 | return 0; | 2587 | return 0; |
2587 | } | 2588 | } |
2588 | 2589 | ||
2589 | if (!bios->bdcb.gpio_table_ptr) { | 2590 | if (!bios->dcb.gpio_table_ptr) { |
2590 | NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); | 2591 | NV_WARN(bios->dev, "Invalid pointer to INIT_8E table\n"); |
2591 | return 0; | 2592 | return 0; |
2592 | } | 2593 | } |
@@ -3123,7 +3124,7 @@ run_digital_op_script(struct drm_device *dev, uint16_t scriptptr, | |||
3123 | struct dcb_entry *dcbent, int head, bool dl) | 3124 | struct dcb_entry *dcbent, int head, bool dl) |
3124 | { | 3125 | { |
3125 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3126 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3126 | struct nvbios *bios = &dev_priv->VBIOS; | 3127 | struct nvbios *bios = &dev_priv->vbios; |
3127 | struct init_exec iexec = {true, false}; | 3128 | struct init_exec iexec = {true, false}; |
3128 | 3129 | ||
3129 | NV_TRACE(dev, "0x%04X: Parsing digital output script table\n", | 3130 | NV_TRACE(dev, "0x%04X: Parsing digital output script table\n", |
@@ -3140,7 +3141,7 @@ run_digital_op_script(struct drm_device *dev, uint16_t scriptptr, | |||
3140 | static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script) | 3141 | static int call_lvds_manufacturer_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, enum LVDS_script script) |
3141 | { | 3142 | { |
3142 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3143 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3143 | struct nvbios *bios = &dev_priv->VBIOS; | 3144 | struct nvbios *bios = &dev_priv->vbios; |
3144 | uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0); | 3145 | uint8_t sub = bios->data[bios->fp.xlated_entry + script] + (bios->fp.link_c_increment && dcbent->or & OUTPUT_C ? 1 : 0); |
3145 | uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]); | 3146 | uint16_t scriptofs = ROM16(bios->data[bios->init_script_tbls_ptr + sub * 2]); |
3146 | 3147 | ||
@@ -3194,7 +3195,7 @@ static int run_lvds_table(struct drm_device *dev, struct dcb_entry *dcbent, int | |||
3194 | * of a list of pxclks and script pointers. | 3195 | * of a list of pxclks and script pointers. |
3195 | */ | 3196 | */ |
3196 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3197 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3197 | struct nvbios *bios = &dev_priv->VBIOS; | 3198 | struct nvbios *bios = &dev_priv->vbios; |
3198 | unsigned int outputset = (dcbent->or == 4) ? 1 : 0; | 3199 | unsigned int outputset = (dcbent->or == 4) ? 1 : 0; |
3199 | uint16_t scriptptr = 0, clktable; | 3200 | uint16_t scriptptr = 0, clktable; |
3200 | uint8_t clktableptr = 0; | 3201 | uint8_t clktableptr = 0; |
@@ -3261,7 +3262,7 @@ int call_lvds_script(struct drm_device *dev, struct dcb_entry *dcbent, int head, | |||
3261 | */ | 3262 | */ |
3262 | 3263 | ||
3263 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3264 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3264 | struct nvbios *bios = &dev_priv->VBIOS; | 3265 | struct nvbios *bios = &dev_priv->vbios; |
3265 | uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer]; | 3266 | uint8_t lvds_ver = bios->data[bios->fp.lvdsmanufacturerpointer]; |
3266 | uint32_t sel_clk_binding, sel_clk; | 3267 | uint32_t sel_clk_binding, sel_clk; |
3267 | int ret; | 3268 | int ret; |
@@ -3395,7 +3396,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios) | |||
3395 | #ifndef __powerpc__ | 3396 | #ifndef __powerpc__ |
3396 | NV_ERROR(dev, "Pointer to flat panel table invalid\n"); | 3397 | NV_ERROR(dev, "Pointer to flat panel table invalid\n"); |
3397 | #endif | 3398 | #endif |
3398 | bios->pub.digital_min_front_porch = 0x4b; | 3399 | bios->digital_min_front_porch = 0x4b; |
3399 | return 0; | 3400 | return 0; |
3400 | } | 3401 | } |
3401 | 3402 | ||
@@ -3428,7 +3429,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios) | |||
3428 | * fptable[4] is the minimum | 3429 | * fptable[4] is the minimum |
3429 | * RAMDAC_FP_HCRTC -> RAMDAC_FP_HSYNC_START gap | 3430 | * RAMDAC_FP_HCRTC -> RAMDAC_FP_HSYNC_START gap |
3430 | */ | 3431 | */ |
3431 | bios->pub.digital_min_front_porch = fptable[4]; | 3432 | bios->digital_min_front_porch = fptable[4]; |
3432 | ofs = -7; | 3433 | ofs = -7; |
3433 | break; | 3434 | break; |
3434 | default: | 3435 | default: |
@@ -3467,7 +3468,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios) | |||
3467 | 3468 | ||
3468 | /* nv4x cards need both a strap value and fpindex of 0xf to use DDC */ | 3469 | /* nv4x cards need both a strap value and fpindex of 0xf to use DDC */ |
3469 | if (lth.lvds_ver > 0x10) | 3470 | if (lth.lvds_ver > 0x10) |
3470 | bios->pub.fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf; | 3471 | bios->fp_no_ddc = fpstrapping != 0xf || fpindex != 0xf; |
3471 | 3472 | ||
3472 | /* | 3473 | /* |
3473 | * If either the strap or xlated fpindex value are 0xf there is no | 3474 | * If either the strap or xlated fpindex value are 0xf there is no |
@@ -3491,7 +3492,7 @@ static int parse_fp_mode_table(struct drm_device *dev, struct nvbios *bios) | |||
3491 | bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode) | 3492 | bool nouveau_bios_fp_mode(struct drm_device *dev, struct drm_display_mode *mode) |
3492 | { | 3493 | { |
3493 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3494 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3494 | struct nvbios *bios = &dev_priv->VBIOS; | 3495 | struct nvbios *bios = &dev_priv->vbios; |
3495 | uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr]; | 3496 | uint8_t *mode_entry = &bios->data[bios->fp.mode_ptr]; |
3496 | 3497 | ||
3497 | if (!mode) /* just checking whether we can produce a mode */ | 3498 | if (!mode) /* just checking whether we can produce a mode */ |
@@ -3562,11 +3563,11 @@ int nouveau_bios_parse_lvds_table(struct drm_device *dev, int pxclk, bool *dl, b | |||
3562 | * until later, when this function should be called with non-zero pxclk | 3563 | * until later, when this function should be called with non-zero pxclk |
3563 | */ | 3564 | */ |
3564 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3565 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3565 | struct nvbios *bios = &dev_priv->VBIOS; | 3566 | struct nvbios *bios = &dev_priv->vbios; |
3566 | int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0; | 3567 | int fpstrapping = get_fp_strap(dev, bios), lvdsmanufacturerindex = 0; |
3567 | struct lvdstableheader lth; | 3568 | struct lvdstableheader lth; |
3568 | uint16_t lvdsofs; | 3569 | uint16_t lvdsofs; |
3569 | int ret, chip_version = bios->pub.chip_version; | 3570 | int ret, chip_version = bios->chip_version; |
3570 | 3571 | ||
3571 | ret = parse_lvds_manufacturer_table_header(dev, bios, <h); | 3572 | ret = parse_lvds_manufacturer_table_header(dev, bios, <h); |
3572 | if (ret) | 3573 | if (ret) |
@@ -3682,7 +3683,7 @@ bios_output_config_match(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3682 | uint16_t record, int record_len, int record_nr) | 3683 | uint16_t record, int record_len, int record_nr) |
3683 | { | 3684 | { |
3684 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3685 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3685 | struct nvbios *bios = &dev_priv->VBIOS; | 3686 | struct nvbios *bios = &dev_priv->vbios; |
3686 | uint32_t entry; | 3687 | uint32_t entry; |
3687 | uint16_t table; | 3688 | uint16_t table; |
3688 | int i, v; | 3689 | int i, v; |
@@ -3716,7 +3717,7 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3716 | int *length) | 3717 | int *length) |
3717 | { | 3718 | { |
3718 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3719 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3719 | struct nvbios *bios = &dev_priv->VBIOS; | 3720 | struct nvbios *bios = &dev_priv->vbios; |
3720 | uint8_t *table; | 3721 | uint8_t *table; |
3721 | 3722 | ||
3722 | if (!bios->display.dp_table_ptr) { | 3723 | if (!bios->display.dp_table_ptr) { |
@@ -3725,7 +3726,7 @@ nouveau_bios_dp_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3725 | } | 3726 | } |
3726 | table = &bios->data[bios->display.dp_table_ptr]; | 3727 | table = &bios->data[bios->display.dp_table_ptr]; |
3727 | 3728 | ||
3728 | if (table[0] != 0x21) { | 3729 | if (table[0] != 0x20 && table[0] != 0x21) { |
3729 | NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n", | 3730 | NV_ERROR(dev, "DisplayPort table version 0x%02x unknown\n", |
3730 | table[0]); | 3731 | table[0]); |
3731 | return NULL; | 3732 | return NULL; |
@@ -3765,7 +3766,7 @@ nouveau_bios_run_display_table(struct drm_device *dev, struct dcb_entry *dcbent, | |||
3765 | */ | 3766 | */ |
3766 | 3767 | ||
3767 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3768 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3768 | struct nvbios *bios = &dev_priv->VBIOS; | 3769 | struct nvbios *bios = &dev_priv->vbios; |
3769 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; | 3770 | uint8_t *table = &bios->data[bios->display.script_table_ptr]; |
3770 | uint8_t *otable = NULL; | 3771 | uint8_t *otable = NULL; |
3771 | uint16_t script; | 3772 | uint16_t script; |
@@ -3918,8 +3919,8 @@ int run_tmds_table(struct drm_device *dev, struct dcb_entry *dcbent, int head, i | |||
3918 | */ | 3919 | */ |
3919 | 3920 | ||
3920 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3921 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3921 | struct nvbios *bios = &dev_priv->VBIOS; | 3922 | struct nvbios *bios = &dev_priv->vbios; |
3922 | int cv = bios->pub.chip_version; | 3923 | int cv = bios->chip_version; |
3923 | uint16_t clktable = 0, scriptptr; | 3924 | uint16_t clktable = 0, scriptptr; |
3924 | uint32_t sel_clk_binding, sel_clk; | 3925 | uint32_t sel_clk_binding, sel_clk; |
3925 | 3926 | ||
@@ -3978,8 +3979,8 @@ int get_pll_limits(struct drm_device *dev, uint32_t limit_match, struct pll_lims | |||
3978 | */ | 3979 | */ |
3979 | 3980 | ||
3980 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 3981 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
3981 | struct nvbios *bios = &dev_priv->VBIOS; | 3982 | struct nvbios *bios = &dev_priv->vbios; |
3982 | int cv = bios->pub.chip_version, pllindex = 0; | 3983 | int cv = bios->chip_version, pllindex = 0; |
3983 | uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0; | 3984 | uint8_t pll_lim_ver = 0, headerlen = 0, recordlen = 0, entries = 0; |
3984 | uint32_t crystal_strap_mask, crystal_straps; | 3985 | uint32_t crystal_strap_mask, crystal_straps; |
3985 | 3986 | ||
@@ -4332,7 +4333,7 @@ static void parse_bios_version(struct drm_device *dev, struct nvbios *bios, uint | |||
4332 | */ | 4333 | */ |
4333 | 4334 | ||
4334 | bios->major_version = bios->data[offset + 3]; | 4335 | bios->major_version = bios->data[offset + 3]; |
4335 | bios->pub.chip_version = bios->data[offset + 2]; | 4336 | bios->chip_version = bios->data[offset + 2]; |
4336 | NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n", | 4337 | NV_TRACE(dev, "Bios version %02x.%02x.%02x.%02x\n", |
4337 | bios->data[offset + 3], bios->data[offset + 2], | 4338 | bios->data[offset + 3], bios->data[offset + 2], |
4338 | bios->data[offset + 1], bios->data[offset]); | 4339 | bios->data[offset + 1], bios->data[offset]); |
@@ -4402,7 +4403,7 @@ static int parse_bit_A_tbl_entry(struct drm_device *dev, struct nvbios *bios, st | |||
4402 | } | 4403 | } |
4403 | 4404 | ||
4404 | /* First entry is normal dac, 2nd tv-out perhaps? */ | 4405 | /* First entry is normal dac, 2nd tv-out perhaps? */ |
4405 | bios->pub.dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff; | 4406 | bios->dactestval = ROM32(bios->data[load_table_ptr + headerlen]) & 0x3ff; |
4406 | 4407 | ||
4407 | return 0; | 4408 | return 0; |
4408 | } | 4409 | } |
@@ -4526,8 +4527,8 @@ static int parse_bit_i_tbl_entry(struct drm_device *dev, struct nvbios *bios, st | |||
4526 | return -ENOSYS; | 4527 | return -ENOSYS; |
4527 | } | 4528 | } |
4528 | 4529 | ||
4529 | bios->pub.dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]); | 4530 | bios->dactestval = ROM32(bios->data[daccmpoffset + dacheaderlen]); |
4530 | bios->pub.tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]); | 4531 | bios->tvdactestval = ROM32(bios->data[daccmpoffset + dacheaderlen + 4]); |
4531 | 4532 | ||
4532 | return 0; | 4533 | return 0; |
4533 | } | 4534 | } |
@@ -4796,11 +4797,11 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi | |||
4796 | uint16_t legacy_scripts_offset, legacy_i2c_offset; | 4797 | uint16_t legacy_scripts_offset, legacy_i2c_offset; |
4797 | 4798 | ||
4798 | /* load needed defaults in case we can't parse this info */ | 4799 | /* load needed defaults in case we can't parse this info */ |
4799 | bios->bdcb.dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX; | 4800 | bios->dcb.i2c[0].write = NV_CIO_CRE_DDC_WR__INDEX; |
4800 | bios->bdcb.dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX; | 4801 | bios->dcb.i2c[0].read = NV_CIO_CRE_DDC_STATUS__INDEX; |
4801 | bios->bdcb.dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX; | 4802 | bios->dcb.i2c[1].write = NV_CIO_CRE_DDC0_WR__INDEX; |
4802 | bios->bdcb.dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX; | 4803 | bios->dcb.i2c[1].read = NV_CIO_CRE_DDC0_STATUS__INDEX; |
4803 | bios->pub.digital_min_front_porch = 0x4b; | 4804 | bios->digital_min_front_porch = 0x4b; |
4804 | bios->fmaxvco = 256000; | 4805 | bios->fmaxvco = 256000; |
4805 | bios->fminvco = 128000; | 4806 | bios->fminvco = 128000; |
4806 | bios->fp.duallink_transition_clk = 90000; | 4807 | bios->fp.duallink_transition_clk = 90000; |
@@ -4907,10 +4908,10 @@ static int parse_bmp_structure(struct drm_device *dev, struct nvbios *bios, unsi | |||
4907 | bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; | 4908 | bios->legacy.i2c_indices.crt = bios->data[legacy_i2c_offset]; |
4908 | bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; | 4909 | bios->legacy.i2c_indices.tv = bios->data[legacy_i2c_offset + 1]; |
4909 | bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; | 4910 | bios->legacy.i2c_indices.panel = bios->data[legacy_i2c_offset + 2]; |
4910 | bios->bdcb.dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; | 4911 | bios->dcb.i2c[0].write = bios->data[legacy_i2c_offset + 4]; |
4911 | bios->bdcb.dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; | 4912 | bios->dcb.i2c[0].read = bios->data[legacy_i2c_offset + 5]; |
4912 | bios->bdcb.dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; | 4913 | bios->dcb.i2c[1].write = bios->data[legacy_i2c_offset + 6]; |
4913 | bios->bdcb.dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; | 4914 | bios->dcb.i2c[1].read = bios->data[legacy_i2c_offset + 7]; |
4914 | 4915 | ||
4915 | if (bmplength > 74) { | 4916 | if (bmplength > 74) { |
4916 | bios->fmaxvco = ROM32(bmp[67]); | 4917 | bios->fmaxvco = ROM32(bmp[67]); |
@@ -4984,7 +4985,8 @@ read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, i | |||
4984 | else | 4985 | else |
4985 | NV_WARN(dev, | 4986 | NV_WARN(dev, |
4986 | "DCB I2C table has more entries than indexable " | 4987 | "DCB I2C table has more entries than indexable " |
4987 | "(%d entries, max index 15)\n", i2ctable[2]); | 4988 | "(%d entries, max %d)\n", i2ctable[2], |
4989 | DCB_MAX_NUM_I2C_ENTRIES); | ||
4988 | entry_len = i2ctable[3]; | 4990 | entry_len = i2ctable[3]; |
4989 | /* [4] is i2c_default_indices, read in parse_dcb_table() */ | 4991 | /* [4] is i2c_default_indices, read in parse_dcb_table() */ |
4990 | } | 4992 | } |
@@ -5000,8 +5002,8 @@ read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, i | |||
5000 | 5002 | ||
5001 | if (index == 0xf) | 5003 | if (index == 0xf) |
5002 | return 0; | 5004 | return 0; |
5003 | if (index > i2c_entries) { | 5005 | if (index >= i2c_entries) { |
5004 | NV_ERROR(dev, "DCB I2C index too big (%d > %d)\n", | 5006 | NV_ERROR(dev, "DCB I2C index too big (%d >= %d)\n", |
5005 | index, i2ctable[2]); | 5007 | index, i2ctable[2]); |
5006 | return -ENOENT; | 5008 | return -ENOENT; |
5007 | } | 5009 | } |
@@ -5036,7 +5038,7 @@ read_dcb_i2c_entry(struct drm_device *dev, int dcb_version, uint8_t *i2ctable, i | |||
5036 | static struct dcb_gpio_entry * | 5038 | static struct dcb_gpio_entry * |
5037 | new_gpio_entry(struct nvbios *bios) | 5039 | new_gpio_entry(struct nvbios *bios) |
5038 | { | 5040 | { |
5039 | struct parsed_dcb_gpio *gpio = &bios->bdcb.gpio; | 5041 | struct dcb_gpio_table *gpio = &bios->dcb.gpio; |
5040 | 5042 | ||
5041 | return &gpio->entry[gpio->entries++]; | 5043 | return &gpio->entry[gpio->entries++]; |
5042 | } | 5044 | } |
@@ -5045,14 +5047,14 @@ struct dcb_gpio_entry * | |||
5045 | nouveau_bios_gpio_entry(struct drm_device *dev, enum dcb_gpio_tag tag) | 5047 | nouveau_bios_gpio_entry(struct drm_device *dev, enum dcb_gpio_tag tag) |
5046 | { | 5048 | { |
5047 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5049 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5048 | struct nvbios *bios = &dev_priv->VBIOS; | 5050 | struct nvbios *bios = &dev_priv->vbios; |
5049 | int i; | 5051 | int i; |
5050 | 5052 | ||
5051 | for (i = 0; i < bios->bdcb.gpio.entries; i++) { | 5053 | for (i = 0; i < bios->dcb.gpio.entries; i++) { |
5052 | if (bios->bdcb.gpio.entry[i].tag != tag) | 5054 | if (bios->dcb.gpio.entry[i].tag != tag) |
5053 | continue; | 5055 | continue; |
5054 | 5056 | ||
5055 | return &bios->bdcb.gpio.entry[i]; | 5057 | return &bios->dcb.gpio.entry[i]; |
5056 | } | 5058 | } |
5057 | 5059 | ||
5058 | return NULL; | 5060 | return NULL; |
@@ -5100,7 +5102,7 @@ static void | |||
5100 | parse_dcb_gpio_table(struct nvbios *bios) | 5102 | parse_dcb_gpio_table(struct nvbios *bios) |
5101 | { | 5103 | { |
5102 | struct drm_device *dev = bios->dev; | 5104 | struct drm_device *dev = bios->dev; |
5103 | uint16_t gpio_table_ptr = bios->bdcb.gpio_table_ptr; | 5105 | uint16_t gpio_table_ptr = bios->dcb.gpio_table_ptr; |
5104 | uint8_t *gpio_table = &bios->data[gpio_table_ptr]; | 5106 | uint8_t *gpio_table = &bios->data[gpio_table_ptr]; |
5105 | int header_len = gpio_table[1], | 5107 | int header_len = gpio_table[1], |
5106 | entries = gpio_table[2], | 5108 | entries = gpio_table[2], |
@@ -5108,7 +5110,7 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
5108 | void (*parse_entry)(struct nvbios *, uint16_t) = NULL; | 5110 | void (*parse_entry)(struct nvbios *, uint16_t) = NULL; |
5109 | int i; | 5111 | int i; |
5110 | 5112 | ||
5111 | if (bios->bdcb.version >= 0x40) { | 5113 | if (bios->dcb.version >= 0x40) { |
5112 | if (gpio_table_ptr && entry_len != 4) { | 5114 | if (gpio_table_ptr && entry_len != 4) { |
5113 | NV_WARN(dev, "Invalid DCB GPIO table entry length.\n"); | 5115 | NV_WARN(dev, "Invalid DCB GPIO table entry length.\n"); |
5114 | return; | 5116 | return; |
@@ -5116,7 +5118,7 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
5116 | 5118 | ||
5117 | parse_entry = parse_dcb40_gpio_entry; | 5119 | parse_entry = parse_dcb40_gpio_entry; |
5118 | 5120 | ||
5119 | } else if (bios->bdcb.version >= 0x30) { | 5121 | } else if (bios->dcb.version >= 0x30) { |
5120 | if (gpio_table_ptr && entry_len != 2) { | 5122 | if (gpio_table_ptr && entry_len != 2) { |
5121 | NV_WARN(dev, "Invalid DCB GPIO table entry length.\n"); | 5123 | NV_WARN(dev, "Invalid DCB GPIO table entry length.\n"); |
5122 | return; | 5124 | return; |
@@ -5124,7 +5126,7 @@ parse_dcb_gpio_table(struct nvbios *bios) | |||
5124 | 5126 | ||
5125 | parse_entry = parse_dcb30_gpio_entry; | 5127 | parse_entry = parse_dcb30_gpio_entry; |
5126 | 5128 | ||
5127 | } else if (bios->bdcb.version >= 0x22) { | 5129 | } else if (bios->dcb.version >= 0x22) { |
5128 | /* | 5130 | /* |
5129 | * DCBs older than v3.0 don't really have a GPIO | 5131 | * DCBs older than v3.0 don't really have a GPIO |
5130 | * table, instead they keep some GPIO info at fixed | 5132 | * table, instead they keep some GPIO info at fixed |
@@ -5158,30 +5160,67 @@ struct dcb_connector_table_entry * | |||
5158 | nouveau_bios_connector_entry(struct drm_device *dev, int index) | 5160 | nouveau_bios_connector_entry(struct drm_device *dev, int index) |
5159 | { | 5161 | { |
5160 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5162 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5161 | struct nvbios *bios = &dev_priv->VBIOS; | 5163 | struct nvbios *bios = &dev_priv->vbios; |
5162 | struct dcb_connector_table_entry *cte; | 5164 | struct dcb_connector_table_entry *cte; |
5163 | 5165 | ||
5164 | if (index >= bios->bdcb.connector.entries) | 5166 | if (index >= bios->dcb.connector.entries) |
5165 | return NULL; | 5167 | return NULL; |
5166 | 5168 | ||
5167 | cte = &bios->bdcb.connector.entry[index]; | 5169 | cte = &bios->dcb.connector.entry[index]; |
5168 | if (cte->type == 0xff) | 5170 | if (cte->type == 0xff) |
5169 | return NULL; | 5171 | return NULL; |
5170 | 5172 | ||
5171 | return cte; | 5173 | return cte; |
5172 | } | 5174 | } |
5173 | 5175 | ||
5176 | static enum dcb_connector_type | ||
5177 | divine_connector_type(struct nvbios *bios, int index) | ||
5178 | { | ||
5179 | struct dcb_table *dcb = &bios->dcb; | ||
5180 | unsigned encoders = 0, type = DCB_CONNECTOR_NONE; | ||
5181 | int i; | ||
5182 | |||
5183 | for (i = 0; i < dcb->entries; i++) { | ||
5184 | if (dcb->entry[i].connector == index) | ||
5185 | encoders |= (1 << dcb->entry[i].type); | ||
5186 | } | ||
5187 | |||
5188 | if (encoders & (1 << OUTPUT_DP)) { | ||
5189 | if (encoders & (1 << OUTPUT_TMDS)) | ||
5190 | type = DCB_CONNECTOR_DP; | ||
5191 | else | ||
5192 | type = DCB_CONNECTOR_eDP; | ||
5193 | } else | ||
5194 | if (encoders & (1 << OUTPUT_TMDS)) { | ||
5195 | if (encoders & (1 << OUTPUT_ANALOG)) | ||
5196 | type = DCB_CONNECTOR_DVI_I; | ||
5197 | else | ||
5198 | type = DCB_CONNECTOR_DVI_D; | ||
5199 | } else | ||
5200 | if (encoders & (1 << OUTPUT_ANALOG)) { | ||
5201 | type = DCB_CONNECTOR_VGA; | ||
5202 | } else | ||
5203 | if (encoders & (1 << OUTPUT_LVDS)) { | ||
5204 | type = DCB_CONNECTOR_LVDS; | ||
5205 | } else | ||
5206 | if (encoders & (1 << OUTPUT_TV)) { | ||
5207 | type = DCB_CONNECTOR_TV_0; | ||
5208 | } | ||
5209 | |||
5210 | return type; | ||
5211 | } | ||
5212 | |||
5174 | static void | 5213 | static void |
5175 | parse_dcb_connector_table(struct nvbios *bios) | 5214 | parse_dcb_connector_table(struct nvbios *bios) |
5176 | { | 5215 | { |
5177 | struct drm_device *dev = bios->dev; | 5216 | struct drm_device *dev = bios->dev; |
5178 | struct dcb_connector_table *ct = &bios->bdcb.connector; | 5217 | struct dcb_connector_table *ct = &bios->dcb.connector; |
5179 | struct dcb_connector_table_entry *cte; | 5218 | struct dcb_connector_table_entry *cte; |
5180 | uint8_t *conntab = &bios->data[bios->bdcb.connector_table_ptr]; | 5219 | uint8_t *conntab = &bios->data[bios->dcb.connector_table_ptr]; |
5181 | uint8_t *entry; | 5220 | uint8_t *entry; |
5182 | int i; | 5221 | int i; |
5183 | 5222 | ||
5184 | if (!bios->bdcb.connector_table_ptr) { | 5223 | if (!bios->dcb.connector_table_ptr) { |
5185 | NV_DEBUG_KMS(dev, "No DCB connector table present\n"); | 5224 | NV_DEBUG_KMS(dev, "No DCB connector table present\n"); |
5186 | return; | 5225 | return; |
5187 | } | 5226 | } |
@@ -5203,6 +5242,7 @@ parse_dcb_connector_table(struct nvbios *bios) | |||
5203 | cte->entry = ROM16(entry[0]); | 5242 | cte->entry = ROM16(entry[0]); |
5204 | else | 5243 | else |
5205 | cte->entry = ROM32(entry[0]); | 5244 | cte->entry = ROM32(entry[0]); |
5245 | |||
5206 | cte->type = (cte->entry & 0x000000ff) >> 0; | 5246 | cte->type = (cte->entry & 0x000000ff) >> 0; |
5207 | cte->index = (cte->entry & 0x00000f00) >> 8; | 5247 | cte->index = (cte->entry & 0x00000f00) >> 8; |
5208 | switch (cte->entry & 0x00033000) { | 5248 | switch (cte->entry & 0x00033000) { |
@@ -5228,10 +5268,33 @@ parse_dcb_connector_table(struct nvbios *bios) | |||
5228 | 5268 | ||
5229 | NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n", | 5269 | NV_INFO(dev, " %d: 0x%08x: type 0x%02x idx %d tag 0x%02x\n", |
5230 | i, cte->entry, cte->type, cte->index, cte->gpio_tag); | 5270 | i, cte->entry, cte->type, cte->index, cte->gpio_tag); |
5271 | |||
5272 | /* check for known types, fallback to guessing the type | ||
5273 | * from attached encoders if we hit an unknown. | ||
5274 | */ | ||
5275 | switch (cte->type) { | ||
5276 | case DCB_CONNECTOR_VGA: | ||
5277 | case DCB_CONNECTOR_TV_0: | ||
5278 | case DCB_CONNECTOR_TV_1: | ||
5279 | case DCB_CONNECTOR_TV_3: | ||
5280 | case DCB_CONNECTOR_DVI_I: | ||
5281 | case DCB_CONNECTOR_DVI_D: | ||
5282 | case DCB_CONNECTOR_LVDS: | ||
5283 | case DCB_CONNECTOR_DP: | ||
5284 | case DCB_CONNECTOR_eDP: | ||
5285 | case DCB_CONNECTOR_HDMI_0: | ||
5286 | case DCB_CONNECTOR_HDMI_1: | ||
5287 | break; | ||
5288 | default: | ||
5289 | cte->type = divine_connector_type(bios, cte->index); | ||
5290 | NV_WARN(dev, "unknown type, using 0x%02x", cte->type); | ||
5291 | break; | ||
5292 | } | ||
5293 | |||
5231 | } | 5294 | } |
5232 | } | 5295 | } |
5233 | 5296 | ||
5234 | static struct dcb_entry *new_dcb_entry(struct parsed_dcb *dcb) | 5297 | static struct dcb_entry *new_dcb_entry(struct dcb_table *dcb) |
5235 | { | 5298 | { |
5236 | struct dcb_entry *entry = &dcb->entry[dcb->entries]; | 5299 | struct dcb_entry *entry = &dcb->entry[dcb->entries]; |
5237 | 5300 | ||
@@ -5241,7 +5304,7 @@ static struct dcb_entry *new_dcb_entry(struct parsed_dcb *dcb) | |||
5241 | return entry; | 5304 | return entry; |
5242 | } | 5305 | } |
5243 | 5306 | ||
5244 | static void fabricate_vga_output(struct parsed_dcb *dcb, int i2c, int heads) | 5307 | static void fabricate_vga_output(struct dcb_table *dcb, int i2c, int heads) |
5245 | { | 5308 | { |
5246 | struct dcb_entry *entry = new_dcb_entry(dcb); | 5309 | struct dcb_entry *entry = new_dcb_entry(dcb); |
5247 | 5310 | ||
@@ -5252,7 +5315,7 @@ static void fabricate_vga_output(struct parsed_dcb *dcb, int i2c, int heads) | |||
5252 | /* "or" mostly unused in early gen crt modesetting, 0 is fine */ | 5315 | /* "or" mostly unused in early gen crt modesetting, 0 is fine */ |
5253 | } | 5316 | } |
5254 | 5317 | ||
5255 | static void fabricate_dvi_i_output(struct parsed_dcb *dcb, bool twoHeads) | 5318 | static void fabricate_dvi_i_output(struct dcb_table *dcb, bool twoHeads) |
5256 | { | 5319 | { |
5257 | struct dcb_entry *entry = new_dcb_entry(dcb); | 5320 | struct dcb_entry *entry = new_dcb_entry(dcb); |
5258 | 5321 | ||
@@ -5279,7 +5342,7 @@ static void fabricate_dvi_i_output(struct parsed_dcb *dcb, bool twoHeads) | |||
5279 | #endif | 5342 | #endif |
5280 | } | 5343 | } |
5281 | 5344 | ||
5282 | static void fabricate_tv_output(struct parsed_dcb *dcb, bool twoHeads) | 5345 | static void fabricate_tv_output(struct dcb_table *dcb, bool twoHeads) |
5283 | { | 5346 | { |
5284 | struct dcb_entry *entry = new_dcb_entry(dcb); | 5347 | struct dcb_entry *entry = new_dcb_entry(dcb); |
5285 | 5348 | ||
@@ -5290,13 +5353,13 @@ static void fabricate_tv_output(struct parsed_dcb *dcb, bool twoHeads) | |||
5290 | } | 5353 | } |
5291 | 5354 | ||
5292 | static bool | 5355 | static bool |
5293 | parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | 5356 | parse_dcb20_entry(struct drm_device *dev, struct dcb_table *dcb, |
5294 | uint32_t conn, uint32_t conf, struct dcb_entry *entry) | 5357 | uint32_t conn, uint32_t conf, struct dcb_entry *entry) |
5295 | { | 5358 | { |
5296 | entry->type = conn & 0xf; | 5359 | entry->type = conn & 0xf; |
5297 | entry->i2c_index = (conn >> 4) & 0xf; | 5360 | entry->i2c_index = (conn >> 4) & 0xf; |
5298 | entry->heads = (conn >> 8) & 0xf; | 5361 | entry->heads = (conn >> 8) & 0xf; |
5299 | if (bdcb->version >= 0x40) | 5362 | if (dcb->version >= 0x40) |
5300 | entry->connector = (conn >> 12) & 0xf; | 5363 | entry->connector = (conn >> 12) & 0xf; |
5301 | entry->bus = (conn >> 16) & 0xf; | 5364 | entry->bus = (conn >> 16) & 0xf; |
5302 | entry->location = (conn >> 20) & 0x3; | 5365 | entry->location = (conn >> 20) & 0x3; |
@@ -5314,7 +5377,7 @@ parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | |||
5314 | * Although the rest of a CRT conf dword is usually | 5377 | * Although the rest of a CRT conf dword is usually |
5315 | * zeros, mac biosen have stuff there so we must mask | 5378 | * zeros, mac biosen have stuff there so we must mask |
5316 | */ | 5379 | */ |
5317 | entry->crtconf.maxfreq = (bdcb->version < 0x30) ? | 5380 | entry->crtconf.maxfreq = (dcb->version < 0x30) ? |
5318 | (conf & 0xffff) * 10 : | 5381 | (conf & 0xffff) * 10 : |
5319 | (conf & 0xff) * 10000; | 5382 | (conf & 0xff) * 10000; |
5320 | break; | 5383 | break; |
@@ -5323,7 +5386,7 @@ parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | |||
5323 | uint32_t mask; | 5386 | uint32_t mask; |
5324 | if (conf & 0x1) | 5387 | if (conf & 0x1) |
5325 | entry->lvdsconf.use_straps_for_mode = true; | 5388 | entry->lvdsconf.use_straps_for_mode = true; |
5326 | if (bdcb->version < 0x22) { | 5389 | if (dcb->version < 0x22) { |
5327 | mask = ~0xd; | 5390 | mask = ~0xd; |
5328 | /* | 5391 | /* |
5329 | * The laptop in bug 14567 lies and claims to not use | 5392 | * The laptop in bug 14567 lies and claims to not use |
@@ -5347,7 +5410,7 @@ parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | |||
5347 | * Until we even try to use these on G8x, it's | 5410 | * Until we even try to use these on G8x, it's |
5348 | * useless reporting unknown bits. They all are. | 5411 | * useless reporting unknown bits. They all are. |
5349 | */ | 5412 | */ |
5350 | if (bdcb->version >= 0x40) | 5413 | if (dcb->version >= 0x40) |
5351 | break; | 5414 | break; |
5352 | 5415 | ||
5353 | NV_ERROR(dev, "Unknown LVDS configuration bits, " | 5416 | NV_ERROR(dev, "Unknown LVDS configuration bits, " |
@@ -5357,7 +5420,7 @@ parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | |||
5357 | } | 5420 | } |
5358 | case OUTPUT_TV: | 5421 | case OUTPUT_TV: |
5359 | { | 5422 | { |
5360 | if (bdcb->version >= 0x30) | 5423 | if (dcb->version >= 0x30) |
5361 | entry->tvconf.has_component_output = conf & (0x8 << 4); | 5424 | entry->tvconf.has_component_output = conf & (0x8 << 4); |
5362 | else | 5425 | else |
5363 | entry->tvconf.has_component_output = false; | 5426 | entry->tvconf.has_component_output = false; |
@@ -5384,8 +5447,10 @@ parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | |||
5384 | break; | 5447 | break; |
5385 | case 0xe: | 5448 | case 0xe: |
5386 | /* weird g80 mobile type that "nv" treats as a terminator */ | 5449 | /* weird g80 mobile type that "nv" treats as a terminator */ |
5387 | bdcb->dcb.entries--; | 5450 | dcb->entries--; |
5388 | return false; | 5451 | return false; |
5452 | default: | ||
5453 | break; | ||
5389 | } | 5454 | } |
5390 | 5455 | ||
5391 | /* unsure what DCB version introduces this, 3.0? */ | 5456 | /* unsure what DCB version introduces this, 3.0? */ |
@@ -5396,7 +5461,7 @@ parse_dcb20_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | |||
5396 | } | 5461 | } |
5397 | 5462 | ||
5398 | static bool | 5463 | static bool |
5399 | parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb, | 5464 | parse_dcb15_entry(struct drm_device *dev, struct dcb_table *dcb, |
5400 | uint32_t conn, uint32_t conf, struct dcb_entry *entry) | 5465 | uint32_t conn, uint32_t conf, struct dcb_entry *entry) |
5401 | { | 5466 | { |
5402 | switch (conn & 0x0000000f) { | 5467 | switch (conn & 0x0000000f) { |
@@ -5462,27 +5527,27 @@ parse_dcb15_entry(struct drm_device *dev, struct parsed_dcb *dcb, | |||
5462 | return true; | 5527 | return true; |
5463 | } | 5528 | } |
5464 | 5529 | ||
5465 | static bool parse_dcb_entry(struct drm_device *dev, struct bios_parsed_dcb *bdcb, | 5530 | static bool parse_dcb_entry(struct drm_device *dev, struct dcb_table *dcb, |
5466 | uint32_t conn, uint32_t conf) | 5531 | uint32_t conn, uint32_t conf) |
5467 | { | 5532 | { |
5468 | struct dcb_entry *entry = new_dcb_entry(&bdcb->dcb); | 5533 | struct dcb_entry *entry = new_dcb_entry(dcb); |
5469 | bool ret; | 5534 | bool ret; |
5470 | 5535 | ||
5471 | if (bdcb->version >= 0x20) | 5536 | if (dcb->version >= 0x20) |
5472 | ret = parse_dcb20_entry(dev, bdcb, conn, conf, entry); | 5537 | ret = parse_dcb20_entry(dev, dcb, conn, conf, entry); |
5473 | else | 5538 | else |
5474 | ret = parse_dcb15_entry(dev, &bdcb->dcb, conn, conf, entry); | 5539 | ret = parse_dcb15_entry(dev, dcb, conn, conf, entry); |
5475 | if (!ret) | 5540 | if (!ret) |
5476 | return ret; | 5541 | return ret; |
5477 | 5542 | ||
5478 | read_dcb_i2c_entry(dev, bdcb->version, bdcb->i2c_table, | 5543 | read_dcb_i2c_entry(dev, dcb->version, dcb->i2c_table, |
5479 | entry->i2c_index, &bdcb->dcb.i2c[entry->i2c_index]); | 5544 | entry->i2c_index, &dcb->i2c[entry->i2c_index]); |
5480 | 5545 | ||
5481 | return true; | 5546 | return true; |
5482 | } | 5547 | } |
5483 | 5548 | ||
5484 | static | 5549 | static |
5485 | void merge_like_dcb_entries(struct drm_device *dev, struct parsed_dcb *dcb) | 5550 | void merge_like_dcb_entries(struct drm_device *dev, struct dcb_table *dcb) |
5486 | { | 5551 | { |
5487 | /* | 5552 | /* |
5488 | * DCB v2.0 lists each output combination separately. | 5553 | * DCB v2.0 lists each output combination separately. |
@@ -5534,8 +5599,7 @@ static int | |||
5534 | parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | 5599 | parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) |
5535 | { | 5600 | { |
5536 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5601 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5537 | struct bios_parsed_dcb *bdcb = &bios->bdcb; | 5602 | struct dcb_table *dcb = &bios->dcb; |
5538 | struct parsed_dcb *dcb; | ||
5539 | uint16_t dcbptr = 0, i2ctabptr = 0; | 5603 | uint16_t dcbptr = 0, i2ctabptr = 0; |
5540 | uint8_t *dcbtable; | 5604 | uint8_t *dcbtable; |
5541 | uint8_t headerlen = 0x4, entries = DCB_MAX_NUM_ENTRIES; | 5605 | uint8_t headerlen = 0x4, entries = DCB_MAX_NUM_ENTRIES; |
@@ -5543,9 +5607,6 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
5543 | int recordlength = 8, confofs = 4; | 5607 | int recordlength = 8, confofs = 4; |
5544 | int i; | 5608 | int i; |
5545 | 5609 | ||
5546 | dcb = bios->pub.dcb = &bdcb->dcb; | ||
5547 | dcb->entries = 0; | ||
5548 | |||
5549 | /* get the offset from 0x36 */ | 5610 | /* get the offset from 0x36 */ |
5550 | if (dev_priv->card_type > NV_04) { | 5611 | if (dev_priv->card_type > NV_04) { |
5551 | dcbptr = ROM16(bios->data[0x36]); | 5612 | dcbptr = ROM16(bios->data[0x36]); |
@@ -5567,21 +5628,21 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
5567 | dcbtable = &bios->data[dcbptr]; | 5628 | dcbtable = &bios->data[dcbptr]; |
5568 | 5629 | ||
5569 | /* get DCB version */ | 5630 | /* get DCB version */ |
5570 | bdcb->version = dcbtable[0]; | 5631 | dcb->version = dcbtable[0]; |
5571 | NV_TRACE(dev, "Found Display Configuration Block version %d.%d\n", | 5632 | NV_TRACE(dev, "Found Display Configuration Block version %d.%d\n", |
5572 | bdcb->version >> 4, bdcb->version & 0xf); | 5633 | dcb->version >> 4, dcb->version & 0xf); |
5573 | 5634 | ||
5574 | if (bdcb->version >= 0x20) { /* NV17+ */ | 5635 | if (dcb->version >= 0x20) { /* NV17+ */ |
5575 | uint32_t sig; | 5636 | uint32_t sig; |
5576 | 5637 | ||
5577 | if (bdcb->version >= 0x30) { /* NV40+ */ | 5638 | if (dcb->version >= 0x30) { /* NV40+ */ |
5578 | headerlen = dcbtable[1]; | 5639 | headerlen = dcbtable[1]; |
5579 | entries = dcbtable[2]; | 5640 | entries = dcbtable[2]; |
5580 | recordlength = dcbtable[3]; | 5641 | recordlength = dcbtable[3]; |
5581 | i2ctabptr = ROM16(dcbtable[4]); | 5642 | i2ctabptr = ROM16(dcbtable[4]); |
5582 | sig = ROM32(dcbtable[6]); | 5643 | sig = ROM32(dcbtable[6]); |
5583 | bdcb->gpio_table_ptr = ROM16(dcbtable[10]); | 5644 | dcb->gpio_table_ptr = ROM16(dcbtable[10]); |
5584 | bdcb->connector_table_ptr = ROM16(dcbtable[20]); | 5645 | dcb->connector_table_ptr = ROM16(dcbtable[20]); |
5585 | } else { | 5646 | } else { |
5586 | i2ctabptr = ROM16(dcbtable[2]); | 5647 | i2ctabptr = ROM16(dcbtable[2]); |
5587 | sig = ROM32(dcbtable[4]); | 5648 | sig = ROM32(dcbtable[4]); |
@@ -5593,7 +5654,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
5593 | "signature (%08X)\n", sig); | 5654 | "signature (%08X)\n", sig); |
5594 | return -EINVAL; | 5655 | return -EINVAL; |
5595 | } | 5656 | } |
5596 | } else if (bdcb->version >= 0x15) { /* some NV11 and NV20 */ | 5657 | } else if (dcb->version >= 0x15) { /* some NV11 and NV20 */ |
5597 | char sig[8] = { 0 }; | 5658 | char sig[8] = { 0 }; |
5598 | 5659 | ||
5599 | strncpy(sig, (char *)&dcbtable[-7], 7); | 5660 | strncpy(sig, (char *)&dcbtable[-7], 7); |
@@ -5641,14 +5702,11 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
5641 | if (!i2ctabptr) | 5702 | if (!i2ctabptr) |
5642 | NV_WARN(dev, "No pointer to DCB I2C port table\n"); | 5703 | NV_WARN(dev, "No pointer to DCB I2C port table\n"); |
5643 | else { | 5704 | else { |
5644 | bdcb->i2c_table = &bios->data[i2ctabptr]; | 5705 | dcb->i2c_table = &bios->data[i2ctabptr]; |
5645 | if (bdcb->version >= 0x30) | 5706 | if (dcb->version >= 0x30) |
5646 | bdcb->i2c_default_indices = bdcb->i2c_table[4]; | 5707 | dcb->i2c_default_indices = dcb->i2c_table[4]; |
5647 | } | 5708 | } |
5648 | 5709 | ||
5649 | parse_dcb_gpio_table(bios); | ||
5650 | parse_dcb_connector_table(bios); | ||
5651 | |||
5652 | if (entries > DCB_MAX_NUM_ENTRIES) | 5710 | if (entries > DCB_MAX_NUM_ENTRIES) |
5653 | entries = DCB_MAX_NUM_ENTRIES; | 5711 | entries = DCB_MAX_NUM_ENTRIES; |
5654 | 5712 | ||
@@ -5673,7 +5731,7 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
5673 | NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n", | 5731 | NV_TRACEWARN(dev, "Raw DCB entry %d: %08x %08x\n", |
5674 | dcb->entries, connection, config); | 5732 | dcb->entries, connection, config); |
5675 | 5733 | ||
5676 | if (!parse_dcb_entry(dev, bdcb, connection, config)) | 5734 | if (!parse_dcb_entry(dev, dcb, connection, config)) |
5677 | break; | 5735 | break; |
5678 | } | 5736 | } |
5679 | 5737 | ||
@@ -5681,18 +5739,22 @@ parse_dcb_table(struct drm_device *dev, struct nvbios *bios, bool twoHeads) | |||
5681 | * apart for v2.1+ not being known for requiring merging, this | 5739 | * apart for v2.1+ not being known for requiring merging, this |
5682 | * guarantees dcbent->index is the index of the entry in the rom image | 5740 | * guarantees dcbent->index is the index of the entry in the rom image |
5683 | */ | 5741 | */ |
5684 | if (bdcb->version < 0x21) | 5742 | if (dcb->version < 0x21) |
5685 | merge_like_dcb_entries(dev, dcb); | 5743 | merge_like_dcb_entries(dev, dcb); |
5686 | 5744 | ||
5687 | return dcb->entries ? 0 : -ENXIO; | 5745 | if (!dcb->entries) |
5746 | return -ENXIO; | ||
5747 | |||
5748 | parse_dcb_gpio_table(bios); | ||
5749 | parse_dcb_connector_table(bios); | ||
5750 | return 0; | ||
5688 | } | 5751 | } |
5689 | 5752 | ||
5690 | static void | 5753 | static void |
5691 | fixup_legacy_connector(struct nvbios *bios) | 5754 | fixup_legacy_connector(struct nvbios *bios) |
5692 | { | 5755 | { |
5693 | struct bios_parsed_dcb *bdcb = &bios->bdcb; | 5756 | struct dcb_table *dcb = &bios->dcb; |
5694 | struct parsed_dcb *dcb = &bdcb->dcb; | 5757 | int i, i2c, i2c_conn[DCB_MAX_NUM_I2C_ENTRIES] = { }; |
5695 | int high = 0, i; | ||
5696 | 5758 | ||
5697 | /* | 5759 | /* |
5698 | * DCB 3.0 also has the table in most cases, but there are some cards | 5760 | * DCB 3.0 also has the table in most cases, but there are some cards |
@@ -5700,9 +5762,11 @@ fixup_legacy_connector(struct nvbios *bios) | |||
5700 | * indices are all 0. We don't need the connector indices on pre-G80 | 5762 | * indices are all 0. We don't need the connector indices on pre-G80 |
5701 | * chips (yet?) so limit the use to DCB 4.0 and above. | 5763 | * chips (yet?) so limit the use to DCB 4.0 and above. |
5702 | */ | 5764 | */ |
5703 | if (bdcb->version >= 0x40) | 5765 | if (dcb->version >= 0x40) |
5704 | return; | 5766 | return; |
5705 | 5767 | ||
5768 | dcb->connector.entries = 0; | ||
5769 | |||
5706 | /* | 5770 | /* |
5707 | * No known connector info before v3.0, so make it up. the rule here | 5771 | * No known connector info before v3.0, so make it up. the rule here |
5708 | * is: anything on the same i2c bus is considered to be on the same | 5772 | * is: anything on the same i2c bus is considered to be on the same |
@@ -5710,37 +5774,38 @@ fixup_legacy_connector(struct nvbios *bios) | |||
5710 | * its own unique connector index. | 5774 | * its own unique connector index. |
5711 | */ | 5775 | */ |
5712 | for (i = 0; i < dcb->entries; i++) { | 5776 | for (i = 0; i < dcb->entries; i++) { |
5713 | if (dcb->entry[i].i2c_index == 0xf) | ||
5714 | continue; | ||
5715 | |||
5716 | /* | 5777 | /* |
5717 | * Ignore the I2C index for on-chip TV-out, as there | 5778 | * Ignore the I2C index for on-chip TV-out, as there |
5718 | * are cards with bogus values (nv31m in bug 23212), | 5779 | * are cards with bogus values (nv31m in bug 23212), |
5719 | * and it's otherwise useless. | 5780 | * and it's otherwise useless. |
5720 | */ | 5781 | */ |
5721 | if (dcb->entry[i].type == OUTPUT_TV && | 5782 | if (dcb->entry[i].type == OUTPUT_TV && |
5722 | dcb->entry[i].location == DCB_LOC_ON_CHIP) { | 5783 | dcb->entry[i].location == DCB_LOC_ON_CHIP) |
5723 | dcb->entry[i].i2c_index = 0xf; | 5784 | dcb->entry[i].i2c_index = 0xf; |
5785 | i2c = dcb->entry[i].i2c_index; | ||
5786 | |||
5787 | if (i2c_conn[i2c]) { | ||
5788 | dcb->entry[i].connector = i2c_conn[i2c] - 1; | ||
5724 | continue; | 5789 | continue; |
5725 | } | 5790 | } |
5726 | 5791 | ||
5727 | dcb->entry[i].connector = dcb->entry[i].i2c_index; | 5792 | dcb->entry[i].connector = dcb->connector.entries++; |
5728 | if (dcb->entry[i].connector > high) | 5793 | if (i2c != 0xf) |
5729 | high = dcb->entry[i].connector; | 5794 | i2c_conn[i2c] = dcb->connector.entries; |
5730 | } | 5795 | } |
5731 | 5796 | ||
5732 | for (i = 0; i < dcb->entries; i++) { | 5797 | /* Fake the connector table as well as just connector indices */ |
5733 | if (dcb->entry[i].i2c_index != 0xf) | 5798 | for (i = 0; i < dcb->connector.entries; i++) { |
5734 | continue; | 5799 | dcb->connector.entry[i].index = i; |
5735 | 5800 | dcb->connector.entry[i].type = divine_connector_type(bios, i); | |
5736 | dcb->entry[i].connector = ++high; | 5801 | dcb->connector.entry[i].gpio_tag = 0xff; |
5737 | } | 5802 | } |
5738 | } | 5803 | } |
5739 | 5804 | ||
5740 | static void | 5805 | static void |
5741 | fixup_legacy_i2c(struct nvbios *bios) | 5806 | fixup_legacy_i2c(struct nvbios *bios) |
5742 | { | 5807 | { |
5743 | struct parsed_dcb *dcb = &bios->bdcb.dcb; | 5808 | struct dcb_table *dcb = &bios->dcb; |
5744 | int i; | 5809 | int i; |
5745 | 5810 | ||
5746 | for (i = 0; i < dcb->entries; i++) { | 5811 | for (i = 0; i < dcb->entries; i++) { |
@@ -5826,7 +5891,7 @@ static int load_nv17_hw_sequencer_ucode(struct drm_device *dev, | |||
5826 | uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) | 5891 | uint8_t *nouveau_bios_embedded_edid(struct drm_device *dev) |
5827 | { | 5892 | { |
5828 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5893 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5829 | struct nvbios *bios = &dev_priv->VBIOS; | 5894 | struct nvbios *bios = &dev_priv->vbios; |
5830 | const uint8_t edid_sig[] = { | 5895 | const uint8_t edid_sig[] = { |
5831 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; | 5896 | 0x00, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x00 }; |
5832 | uint16_t offset = 0; | 5897 | uint16_t offset = 0; |
@@ -5859,7 +5924,7 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, | |||
5859 | struct dcb_entry *dcbent) | 5924 | struct dcb_entry *dcbent) |
5860 | { | 5925 | { |
5861 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5926 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5862 | struct nvbios *bios = &dev_priv->VBIOS; | 5927 | struct nvbios *bios = &dev_priv->vbios; |
5863 | struct init_exec iexec = { true, false }; | 5928 | struct init_exec iexec = { true, false }; |
5864 | 5929 | ||
5865 | mutex_lock(&bios->lock); | 5930 | mutex_lock(&bios->lock); |
@@ -5872,7 +5937,7 @@ nouveau_bios_run_init_table(struct drm_device *dev, uint16_t table, | |||
5872 | static bool NVInitVBIOS(struct drm_device *dev) | 5937 | static bool NVInitVBIOS(struct drm_device *dev) |
5873 | { | 5938 | { |
5874 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5939 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5875 | struct nvbios *bios = &dev_priv->VBIOS; | 5940 | struct nvbios *bios = &dev_priv->vbios; |
5876 | 5941 | ||
5877 | memset(bios, 0, sizeof(struct nvbios)); | 5942 | memset(bios, 0, sizeof(struct nvbios)); |
5878 | mutex_init(&bios->lock); | 5943 | mutex_init(&bios->lock); |
@@ -5888,7 +5953,7 @@ static bool NVInitVBIOS(struct drm_device *dev) | |||
5888 | static int nouveau_parse_vbios_struct(struct drm_device *dev) | 5953 | static int nouveau_parse_vbios_struct(struct drm_device *dev) |
5889 | { | 5954 | { |
5890 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5955 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5891 | struct nvbios *bios = &dev_priv->VBIOS; | 5956 | struct nvbios *bios = &dev_priv->vbios; |
5892 | const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' }; | 5957 | const uint8_t bit_signature[] = { 0xff, 0xb8, 'B', 'I', 'T' }; |
5893 | const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 }; | 5958 | const uint8_t bmp_signature[] = { 0xff, 0x7f, 'N', 'V', 0x0 }; |
5894 | int offset; | 5959 | int offset; |
@@ -5915,7 +5980,7 @@ int | |||
5915 | nouveau_run_vbios_init(struct drm_device *dev) | 5980 | nouveau_run_vbios_init(struct drm_device *dev) |
5916 | { | 5981 | { |
5917 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 5982 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5918 | struct nvbios *bios = &dev_priv->VBIOS; | 5983 | struct nvbios *bios = &dev_priv->vbios; |
5919 | int i, ret = 0; | 5984 | int i, ret = 0; |
5920 | 5985 | ||
5921 | NVLockVgaCrtcs(dev, false); | 5986 | NVLockVgaCrtcs(dev, false); |
@@ -5946,9 +6011,9 @@ nouveau_run_vbios_init(struct drm_device *dev) | |||
5946 | } | 6011 | } |
5947 | 6012 | ||
5948 | if (dev_priv->card_type >= NV_50) { | 6013 | if (dev_priv->card_type >= NV_50) { |
5949 | for (i = 0; i < bios->bdcb.dcb.entries; i++) { | 6014 | for (i = 0; i < bios->dcb.entries; i++) { |
5950 | nouveau_bios_run_display_table(dev, | 6015 | nouveau_bios_run_display_table(dev, |
5951 | &bios->bdcb.dcb.entry[i], | 6016 | &bios->dcb.entry[i], |
5952 | 0, 0); | 6017 | 0, 0); |
5953 | } | 6018 | } |
5954 | } | 6019 | } |
@@ -5962,11 +6027,11 @@ static void | |||
5962 | nouveau_bios_i2c_devices_takedown(struct drm_device *dev) | 6027 | nouveau_bios_i2c_devices_takedown(struct drm_device *dev) |
5963 | { | 6028 | { |
5964 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6029 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5965 | struct nvbios *bios = &dev_priv->VBIOS; | 6030 | struct nvbios *bios = &dev_priv->vbios; |
5966 | struct dcb_i2c_entry *entry; | 6031 | struct dcb_i2c_entry *entry; |
5967 | int i; | 6032 | int i; |
5968 | 6033 | ||
5969 | entry = &bios->bdcb.dcb.i2c[0]; | 6034 | entry = &bios->dcb.i2c[0]; |
5970 | for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++, entry++) | 6035 | for (i = 0; i < DCB_MAX_NUM_I2C_ENTRIES; i++, entry++) |
5971 | nouveau_i2c_fini(dev, entry); | 6036 | nouveau_i2c_fini(dev, entry); |
5972 | } | 6037 | } |
@@ -5975,13 +6040,11 @@ int | |||
5975 | nouveau_bios_init(struct drm_device *dev) | 6040 | nouveau_bios_init(struct drm_device *dev) |
5976 | { | 6041 | { |
5977 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6042 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
5978 | struct nvbios *bios = &dev_priv->VBIOS; | 6043 | struct nvbios *bios = &dev_priv->vbios; |
5979 | uint32_t saved_nv_pextdev_boot_0; | 6044 | uint32_t saved_nv_pextdev_boot_0; |
5980 | bool was_locked; | 6045 | bool was_locked; |
5981 | int ret; | 6046 | int ret; |
5982 | 6047 | ||
5983 | dev_priv->vbios = &bios->pub; | ||
5984 | |||
5985 | if (!NVInitVBIOS(dev)) | 6048 | if (!NVInitVBIOS(dev)) |
5986 | return -ENODEV; | 6049 | return -ENODEV; |
5987 | 6050 | ||
@@ -6023,10 +6086,8 @@ nouveau_bios_init(struct drm_device *dev) | |||
6023 | bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); | 6086 | bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); |
6024 | 6087 | ||
6025 | ret = nouveau_run_vbios_init(dev); | 6088 | ret = nouveau_run_vbios_init(dev); |
6026 | if (ret) { | 6089 | if (ret) |
6027 | dev_priv->vbios = NULL; | ||
6028 | return ret; | 6090 | return ret; |
6029 | } | ||
6030 | 6091 | ||
6031 | /* feature_byte on BMP is poor, but init always sets CR4B */ | 6092 | /* feature_byte on BMP is poor, but init always sets CR4B */ |
6032 | was_locked = NVLockVgaCrtcs(dev, false); | 6093 | was_locked = NVLockVgaCrtcs(dev, false); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index fd94bd6dc264..9f688aa9a655 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -34,9 +34,67 @@ | |||
34 | 34 | ||
35 | #define DCB_LOC_ON_CHIP 0 | 35 | #define DCB_LOC_ON_CHIP 0 |
36 | 36 | ||
37 | struct dcb_i2c_entry { | ||
38 | uint8_t port_type; | ||
39 | uint8_t read, write; | ||
40 | struct nouveau_i2c_chan *chan; | ||
41 | }; | ||
42 | |||
43 | enum dcb_gpio_tag { | ||
44 | DCB_GPIO_TVDAC0 = 0xc, | ||
45 | DCB_GPIO_TVDAC1 = 0x2d, | ||
46 | }; | ||
47 | |||
48 | struct dcb_gpio_entry { | ||
49 | enum dcb_gpio_tag tag; | ||
50 | int line; | ||
51 | bool invert; | ||
52 | }; | ||
53 | |||
54 | struct dcb_gpio_table { | ||
55 | int entries; | ||
56 | struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES]; | ||
57 | }; | ||
58 | |||
59 | enum dcb_connector_type { | ||
60 | DCB_CONNECTOR_VGA = 0x00, | ||
61 | DCB_CONNECTOR_TV_0 = 0x10, | ||
62 | DCB_CONNECTOR_TV_1 = 0x11, | ||
63 | DCB_CONNECTOR_TV_3 = 0x13, | ||
64 | DCB_CONNECTOR_DVI_I = 0x30, | ||
65 | DCB_CONNECTOR_DVI_D = 0x31, | ||
66 | DCB_CONNECTOR_LVDS = 0x40, | ||
67 | DCB_CONNECTOR_DP = 0x46, | ||
68 | DCB_CONNECTOR_eDP = 0x47, | ||
69 | DCB_CONNECTOR_HDMI_0 = 0x60, | ||
70 | DCB_CONNECTOR_HDMI_1 = 0x61, | ||
71 | DCB_CONNECTOR_NONE = 0xff | ||
72 | }; | ||
73 | |||
74 | struct dcb_connector_table_entry { | ||
75 | uint32_t entry; | ||
76 | enum dcb_connector_type type; | ||
77 | uint8_t index; | ||
78 | uint8_t gpio_tag; | ||
79 | }; | ||
80 | |||
81 | struct dcb_connector_table { | ||
82 | int entries; | ||
83 | struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES]; | ||
84 | }; | ||
85 | |||
86 | enum dcb_type { | ||
87 | OUTPUT_ANALOG = 0, | ||
88 | OUTPUT_TV = 1, | ||
89 | OUTPUT_TMDS = 2, | ||
90 | OUTPUT_LVDS = 3, | ||
91 | OUTPUT_DP = 6, | ||
92 | OUTPUT_ANY = -1 | ||
93 | }; | ||
94 | |||
37 | struct dcb_entry { | 95 | struct dcb_entry { |
38 | int index; /* may not be raw dcb index if merging has happened */ | 96 | int index; /* may not be raw dcb index if merging has happened */ |
39 | uint8_t type; | 97 | enum dcb_type type; |
40 | uint8_t i2c_index; | 98 | uint8_t i2c_index; |
41 | uint8_t heads; | 99 | uint8_t heads; |
42 | uint8_t connector; | 100 | uint8_t connector; |
@@ -71,69 +129,22 @@ struct dcb_entry { | |||
71 | bool i2c_upper_default; | 129 | bool i2c_upper_default; |
72 | }; | 130 | }; |
73 | 131 | ||
74 | struct dcb_i2c_entry { | 132 | struct dcb_table { |
75 | uint8_t port_type; | 133 | uint8_t version; |
76 | uint8_t read, write; | ||
77 | struct nouveau_i2c_chan *chan; | ||
78 | }; | ||
79 | 134 | ||
80 | struct parsed_dcb { | ||
81 | int entries; | 135 | int entries; |
82 | struct dcb_entry entry[DCB_MAX_NUM_ENTRIES]; | 136 | struct dcb_entry entry[DCB_MAX_NUM_ENTRIES]; |
83 | struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES]; | ||
84 | }; | ||
85 | |||
86 | enum dcb_gpio_tag { | ||
87 | DCB_GPIO_TVDAC0 = 0xc, | ||
88 | DCB_GPIO_TVDAC1 = 0x2d, | ||
89 | }; | ||
90 | |||
91 | struct dcb_gpio_entry { | ||
92 | enum dcb_gpio_tag tag; | ||
93 | int line; | ||
94 | bool invert; | ||
95 | }; | ||
96 | |||
97 | struct parsed_dcb_gpio { | ||
98 | int entries; | ||
99 | struct dcb_gpio_entry entry[DCB_MAX_NUM_GPIO_ENTRIES]; | ||
100 | }; | ||
101 | |||
102 | struct dcb_connector_table_entry { | ||
103 | uint32_t entry; | ||
104 | uint8_t type; | ||
105 | uint8_t index; | ||
106 | uint8_t gpio_tag; | ||
107 | }; | ||
108 | |||
109 | struct dcb_connector_table { | ||
110 | int entries; | ||
111 | struct dcb_connector_table_entry entry[DCB_MAX_NUM_CONNECTOR_ENTRIES]; | ||
112 | }; | ||
113 | |||
114 | struct bios_parsed_dcb { | ||
115 | uint8_t version; | ||
116 | |||
117 | struct parsed_dcb dcb; | ||
118 | 137 | ||
119 | uint8_t *i2c_table; | 138 | uint8_t *i2c_table; |
120 | uint8_t i2c_default_indices; | 139 | uint8_t i2c_default_indices; |
140 | struct dcb_i2c_entry i2c[DCB_MAX_NUM_I2C_ENTRIES]; | ||
121 | 141 | ||
122 | uint16_t gpio_table_ptr; | 142 | uint16_t gpio_table_ptr; |
123 | struct parsed_dcb_gpio gpio; | 143 | struct dcb_gpio_table gpio; |
124 | uint16_t connector_table_ptr; | 144 | uint16_t connector_table_ptr; |
125 | struct dcb_connector_table connector; | 145 | struct dcb_connector_table connector; |
126 | }; | 146 | }; |
127 | 147 | ||
128 | enum nouveau_encoder_type { | ||
129 | OUTPUT_ANALOG = 0, | ||
130 | OUTPUT_TV = 1, | ||
131 | OUTPUT_TMDS = 2, | ||
132 | OUTPUT_LVDS = 3, | ||
133 | OUTPUT_DP = 6, | ||
134 | OUTPUT_ANY = -1 | ||
135 | }; | ||
136 | |||
137 | enum nouveau_or { | 148 | enum nouveau_or { |
138 | OUTPUT_A = (1 << 0), | 149 | OUTPUT_A = (1 << 0), |
139 | OUTPUT_B = (1 << 1), | 150 | OUTPUT_B = (1 << 1), |
@@ -190,8 +201,8 @@ struct pll_lims { | |||
190 | int refclk; | 201 | int refclk; |
191 | }; | 202 | }; |
192 | 203 | ||
193 | struct nouveau_bios_info { | 204 | struct nvbios { |
194 | struct parsed_dcb *dcb; | 205 | struct drm_device *dev; |
195 | 206 | ||
196 | uint8_t chip_version; | 207 | uint8_t chip_version; |
197 | 208 | ||
@@ -199,11 +210,6 @@ struct nouveau_bios_info { | |||
199 | uint32_t tvdactestval; | 210 | uint32_t tvdactestval; |
200 | uint8_t digital_min_front_porch; | 211 | uint8_t digital_min_front_porch; |
201 | bool fp_no_ddc; | 212 | bool fp_no_ddc; |
202 | }; | ||
203 | |||
204 | struct nvbios { | ||
205 | struct drm_device *dev; | ||
206 | struct nouveau_bios_info pub; | ||
207 | 213 | ||
208 | struct mutex lock; | 214 | struct mutex lock; |
209 | 215 | ||
@@ -234,7 +240,7 @@ struct nvbios { | |||
234 | uint16_t some_script_ptr; /* BIT I + 14 */ | 240 | uint16_t some_script_ptr; /* BIT I + 14 */ |
235 | uint16_t init96_tbl_ptr; /* BIT I + 16 */ | 241 | uint16_t init96_tbl_ptr; /* BIT I + 16 */ |
236 | 242 | ||
237 | struct bios_parsed_dcb bdcb; | 243 | struct dcb_table dcb; |
238 | 244 | ||
239 | struct { | 245 | struct { |
240 | int crtchead; | 246 | int crtchead; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_calc.c b/drivers/gpu/drm/nouveau/nouveau_calc.c index ee2b84504d05..88f9bc0941eb 100644 --- a/drivers/gpu/drm/nouveau/nouveau_calc.c +++ b/drivers/gpu/drm/nouveau/nouveau_calc.c | |||
@@ -274,7 +274,7 @@ getMNP_single(struct drm_device *dev, struct pll_lims *pll_lim, int clk, | |||
274 | * returns calculated clock | 274 | * returns calculated clock |
275 | */ | 275 | */ |
276 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 276 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
277 | int cv = dev_priv->vbios->chip_version; | 277 | int cv = dev_priv->vbios.chip_version; |
278 | int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq; | 278 | int minvco = pll_lim->vco1.minfreq, maxvco = pll_lim->vco1.maxfreq; |
279 | int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m; | 279 | int minM = pll_lim->vco1.min_m, maxM = pll_lim->vco1.max_m; |
280 | int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n; | 280 | int minN = pll_lim->vco1.min_n, maxN = pll_lim->vco1.max_n; |
@@ -373,7 +373,7 @@ getMNP_double(struct drm_device *dev, struct pll_lims *pll_lim, int clk, | |||
373 | * returns calculated clock | 373 | * returns calculated clock |
374 | */ | 374 | */ |
375 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 375 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
376 | int chip_version = dev_priv->vbios->chip_version; | 376 | int chip_version = dev_priv->vbios.chip_version; |
377 | int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq; | 377 | int minvco1 = pll_lim->vco1.minfreq, maxvco1 = pll_lim->vco1.maxfreq; |
378 | int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq; | 378 | int minvco2 = pll_lim->vco2.minfreq, maxvco2 = pll_lim->vco2.maxfreq; |
379 | int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq; | 379 | int minU1 = pll_lim->vco1.min_inputfreq, minU2 = pll_lim->vco2.min_inputfreq; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_channel.c b/drivers/gpu/drm/nouveau/nouveau_channel.c index 2281f99da7fc..6dfb425cbae9 100644 --- a/drivers/gpu/drm/nouveau/nouveau_channel.c +++ b/drivers/gpu/drm/nouveau/nouveau_channel.c | |||
@@ -35,22 +35,27 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) | |||
35 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 35 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
36 | struct nouveau_bo *pb = chan->pushbuf_bo; | 36 | struct nouveau_bo *pb = chan->pushbuf_bo; |
37 | struct nouveau_gpuobj *pushbuf = NULL; | 37 | struct nouveau_gpuobj *pushbuf = NULL; |
38 | uint32_t start = pb->bo.mem.mm_node->start << PAGE_SHIFT; | ||
39 | int ret; | 38 | int ret; |
40 | 39 | ||
40 | if (dev_priv->card_type >= NV_50) { | ||
41 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, | ||
42 | dev_priv->vm_end, NV_DMA_ACCESS_RO, | ||
43 | NV_DMA_TARGET_AGP, &pushbuf); | ||
44 | chan->pushbuf_base = pb->bo.offset; | ||
45 | } else | ||
41 | if (pb->bo.mem.mem_type == TTM_PL_TT) { | 46 | if (pb->bo.mem.mem_type == TTM_PL_TT) { |
42 | ret = nouveau_gpuobj_gart_dma_new(chan, 0, | 47 | ret = nouveau_gpuobj_gart_dma_new(chan, 0, |
43 | dev_priv->gart_info.aper_size, | 48 | dev_priv->gart_info.aper_size, |
44 | NV_DMA_ACCESS_RO, &pushbuf, | 49 | NV_DMA_ACCESS_RO, &pushbuf, |
45 | NULL); | 50 | NULL); |
46 | chan->pushbuf_base = start; | 51 | chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT; |
47 | } else | 52 | } else |
48 | if (dev_priv->card_type != NV_04) { | 53 | if (dev_priv->card_type != NV_04) { |
49 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, | 54 | ret = nouveau_gpuobj_dma_new(chan, NV_CLASS_DMA_IN_MEMORY, 0, |
50 | dev_priv->fb_available_size, | 55 | dev_priv->fb_available_size, |
51 | NV_DMA_ACCESS_RO, | 56 | NV_DMA_ACCESS_RO, |
52 | NV_DMA_TARGET_VIDMEM, &pushbuf); | 57 | NV_DMA_TARGET_VIDMEM, &pushbuf); |
53 | chan->pushbuf_base = start; | 58 | chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT; |
54 | } else { | 59 | } else { |
55 | /* NV04 cmdbuf hack, from original ddx.. not sure of it's | 60 | /* NV04 cmdbuf hack, from original ddx.. not sure of it's |
56 | * exact reason for existing :) PCI access to cmdbuf in | 61 | * exact reason for existing :) PCI access to cmdbuf in |
@@ -61,7 +66,7 @@ nouveau_channel_pushbuf_ctxdma_init(struct nouveau_channel *chan) | |||
61 | dev_priv->fb_available_size, | 66 | dev_priv->fb_available_size, |
62 | NV_DMA_ACCESS_RO, | 67 | NV_DMA_ACCESS_RO, |
63 | NV_DMA_TARGET_PCI, &pushbuf); | 68 | NV_DMA_TARGET_PCI, &pushbuf); |
64 | chan->pushbuf_base = start; | 69 | chan->pushbuf_base = pb->bo.mem.mm_node->start << PAGE_SHIFT; |
65 | } | 70 | } |
66 | 71 | ||
67 | ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf); | 72 | ret = nouveau_gpuobj_ref_add(dev, chan, 0, pushbuf, &chan->pushbuf); |
@@ -275,9 +280,18 @@ nouveau_channel_free(struct nouveau_channel *chan) | |||
275 | */ | 280 | */ |
276 | nouveau_fence_fini(chan); | 281 | nouveau_fence_fini(chan); |
277 | 282 | ||
278 | /* Ensure the channel is no longer active on the GPU */ | 283 | /* This will prevent pfifo from switching channels. */ |
279 | pfifo->reassign(dev, false); | 284 | pfifo->reassign(dev, false); |
280 | 285 | ||
286 | /* We want to give pgraph a chance to idle and get rid of all potential | ||
287 | * errors. We need to do this before the lock, otherwise the irq handler | ||
288 | * is unable to process them. | ||
289 | */ | ||
290 | if (pgraph->channel(dev) == chan) | ||
291 | nouveau_wait_for_idle(dev); | ||
292 | |||
293 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
294 | |||
281 | pgraph->fifo_access(dev, false); | 295 | pgraph->fifo_access(dev, false); |
282 | if (pgraph->channel(dev) == chan) | 296 | if (pgraph->channel(dev) == chan) |
283 | pgraph->unload_context(dev); | 297 | pgraph->unload_context(dev); |
@@ -293,6 +307,8 @@ nouveau_channel_free(struct nouveau_channel *chan) | |||
293 | 307 | ||
294 | pfifo->reassign(dev, true); | 308 | pfifo->reassign(dev, true); |
295 | 309 | ||
310 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
311 | |||
296 | /* Release the channel's resources */ | 312 | /* Release the channel's resources */ |
297 | nouveau_gpuobj_ref_del(dev, &chan->pushbuf); | 313 | nouveau_gpuobj_ref_del(dev, &chan->pushbuf); |
298 | if (chan->pushbuf_bo) { | 314 | if (chan->pushbuf_bo) { |
@@ -369,6 +385,14 @@ nouveau_ioctl_fifo_alloc(struct drm_device *dev, void *data, | |||
369 | return ret; | 385 | return ret; |
370 | init->channel = chan->id; | 386 | init->channel = chan->id; |
371 | 387 | ||
388 | if (chan->dma.ib_max) | ||
389 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM | | ||
390 | NOUVEAU_GEM_DOMAIN_GART; | ||
391 | else if (chan->pushbuf_bo->bo.mem.mem_type == TTM_PL_VRAM) | ||
392 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_VRAM; | ||
393 | else | ||
394 | init->pushbuf_domains = NOUVEAU_GEM_DOMAIN_GART; | ||
395 | |||
372 | init->subchan[0].handle = NvM2MF; | 396 | init->subchan[0].handle = NvM2MF; |
373 | if (dev_priv->card_type < NV_50) | 397 | if (dev_priv->card_type < NV_50) |
374 | init->subchan[0].grclass = 0x0039; | 398 | init->subchan[0].grclass = 0x0039; |
@@ -408,7 +432,6 @@ nouveau_ioctl_fifo_free(struct drm_device *dev, void *data, | |||
408 | ***********************************/ | 432 | ***********************************/ |
409 | 433 | ||
410 | struct drm_ioctl_desc nouveau_ioctls[] = { | 434 | struct drm_ioctl_desc nouveau_ioctls[] = { |
411 | DRM_IOCTL_DEF(DRM_NOUVEAU_CARD_INIT, nouveau_ioctl_card_init, DRM_AUTH), | ||
412 | DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), | 435 | DRM_IOCTL_DEF(DRM_NOUVEAU_GETPARAM, nouveau_ioctl_getparam, DRM_AUTH), |
413 | DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), | 436 | DRM_IOCTL_DEF(DRM_NOUVEAU_SETPARAM, nouveau_ioctl_setparam, DRM_AUTH|DRM_MASTER|DRM_ROOT_ONLY), |
414 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), | 437 | DRM_IOCTL_DEF(DRM_NOUVEAU_CHANNEL_ALLOC, nouveau_ioctl_fifo_alloc, DRM_AUTH), |
@@ -418,13 +441,9 @@ struct drm_ioctl_desc nouveau_ioctls[] = { | |||
418 | DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), | 441 | DRM_IOCTL_DEF(DRM_NOUVEAU_GPUOBJ_FREE, nouveau_ioctl_gpuobj_free, DRM_AUTH), |
419 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), | 442 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_NEW, nouveau_gem_ioctl_new, DRM_AUTH), |
420 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), | 443 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF, nouveau_gem_ioctl_pushbuf, DRM_AUTH), |
421 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL, nouveau_gem_ioctl_pushbuf_call, DRM_AUTH), | ||
422 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PIN, nouveau_gem_ioctl_pin, DRM_AUTH), | ||
423 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_UNPIN, nouveau_gem_ioctl_unpin, DRM_AUTH), | ||
424 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), | 444 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_PREP, nouveau_gem_ioctl_cpu_prep, DRM_AUTH), |
425 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), | 445 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_CPU_FINI, nouveau_gem_ioctl_cpu_fini, DRM_AUTH), |
426 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), | 446 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_INFO, nouveau_gem_ioctl_info, DRM_AUTH), |
427 | DRM_IOCTL_DEF(DRM_NOUVEAU_GEM_PUSHBUF_CALL2, nouveau_gem_ioctl_pushbuf_call2, DRM_AUTH), | ||
428 | }; | 447 | }; |
429 | 448 | ||
430 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); | 449 | int nouveau_max_ioctl = DRM_ARRAY_SIZE(nouveau_ioctls); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index d2f63353ea97..24327f468c4b 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
@@ -218,7 +218,7 @@ nouveau_connector_set_encoder(struct drm_connector *connector, | |||
218 | connector->interlace_allowed = true; | 218 | connector->interlace_allowed = true; |
219 | } | 219 | } |
220 | 220 | ||
221 | if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) { | 221 | if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) { |
222 | drm_connector_property_set_value(connector, | 222 | drm_connector_property_set_value(connector, |
223 | dev->mode_config.dvi_i_subconnector_property, | 223 | dev->mode_config.dvi_i_subconnector_property, |
224 | nv_encoder->dcb->type == OUTPUT_TMDS ? | 224 | nv_encoder->dcb->type == OUTPUT_TMDS ? |
@@ -236,15 +236,17 @@ nouveau_connector_detect(struct drm_connector *connector) | |||
236 | struct nouveau_i2c_chan *i2c; | 236 | struct nouveau_i2c_chan *i2c; |
237 | int type, flags; | 237 | int type, flags; |
238 | 238 | ||
239 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) | 239 | if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS) |
240 | nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); | 240 | nv_encoder = find_encoder_by_type(connector, OUTPUT_LVDS); |
241 | if (nv_encoder && nv_connector->native_mode) { | 241 | if (nv_encoder && nv_connector->native_mode) { |
242 | unsigned status = connector_status_connected; | ||
243 | |||
242 | #ifdef CONFIG_ACPI | 244 | #ifdef CONFIG_ACPI |
243 | if (!nouveau_ignorelid && !acpi_lid_open()) | 245 | if (!nouveau_ignorelid && !acpi_lid_open()) |
244 | return connector_status_disconnected; | 246 | status = connector_status_unknown; |
245 | #endif | 247 | #endif |
246 | nouveau_connector_set_encoder(connector, nv_encoder); | 248 | nouveau_connector_set_encoder(connector, nv_encoder); |
247 | return connector_status_connected; | 249 | return status; |
248 | } | 250 | } |
249 | 251 | ||
250 | /* Cleanup the previous EDID block. */ | 252 | /* Cleanup the previous EDID block. */ |
@@ -279,7 +281,7 @@ nouveau_connector_detect(struct drm_connector *connector) | |||
279 | * same i2c channel so the value returned from ddc_detect | 281 | * same i2c channel so the value returned from ddc_detect |
280 | * isn't necessarily correct. | 282 | * isn't necessarily correct. |
281 | */ | 283 | */ |
282 | if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) { | 284 | if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) { |
283 | if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) | 285 | if (nv_connector->edid->input & DRM_EDID_INPUT_DIGITAL) |
284 | type = OUTPUT_TMDS; | 286 | type = OUTPUT_TMDS; |
285 | else | 287 | else |
@@ -321,11 +323,11 @@ detect_analog: | |||
321 | static void | 323 | static void |
322 | nouveau_connector_force(struct drm_connector *connector) | 324 | nouveau_connector_force(struct drm_connector *connector) |
323 | { | 325 | { |
324 | struct drm_device *dev = connector->dev; | 326 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
325 | struct nouveau_encoder *nv_encoder; | 327 | struct nouveau_encoder *nv_encoder; |
326 | int type; | 328 | int type; |
327 | 329 | ||
328 | if (connector->connector_type == DRM_MODE_CONNECTOR_DVII) { | 330 | if (nv_connector->dcb->type == DCB_CONNECTOR_DVI_I) { |
329 | if (connector->force == DRM_FORCE_ON_DIGITAL) | 331 | if (connector->force == DRM_FORCE_ON_DIGITAL) |
330 | type = OUTPUT_TMDS; | 332 | type = OUTPUT_TMDS; |
331 | else | 333 | else |
@@ -335,7 +337,7 @@ nouveau_connector_force(struct drm_connector *connector) | |||
335 | 337 | ||
336 | nv_encoder = find_encoder_by_type(connector, type); | 338 | nv_encoder = find_encoder_by_type(connector, type); |
337 | if (!nv_encoder) { | 339 | if (!nv_encoder) { |
338 | NV_ERROR(dev, "can't find encoder to force %s on!\n", | 340 | NV_ERROR(connector->dev, "can't find encoder to force %s on!\n", |
339 | drm_get_connector_name(connector)); | 341 | drm_get_connector_name(connector)); |
340 | connector->status = connector_status_disconnected; | 342 | connector->status = connector_status_disconnected; |
341 | return; | 343 | return; |
@@ -369,7 +371,7 @@ nouveau_connector_set_property(struct drm_connector *connector, | |||
369 | } | 371 | } |
370 | 372 | ||
371 | /* LVDS always needs gpu scaling */ | 373 | /* LVDS always needs gpu scaling */ |
372 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS && | 374 | if (nv_connector->dcb->type == DCB_CONNECTOR_LVDS && |
373 | value == DRM_MODE_SCALE_NONE) | 375 | value == DRM_MODE_SCALE_NONE) |
374 | return -EINVAL; | 376 | return -EINVAL; |
375 | 377 | ||
@@ -535,7 +537,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
535 | /* If we're not LVDS, destroy the previous native mode, the attached | 537 | /* If we're not LVDS, destroy the previous native mode, the attached |
536 | * monitor could have changed. | 538 | * monitor could have changed. |
537 | */ | 539 | */ |
538 | if (connector->connector_type != DRM_MODE_CONNECTOR_LVDS && | 540 | if (nv_connector->dcb->type != DCB_CONNECTOR_LVDS && |
539 | nv_connector->native_mode) { | 541 | nv_connector->native_mode) { |
540 | drm_mode_destroy(dev, nv_connector->native_mode); | 542 | drm_mode_destroy(dev, nv_connector->native_mode); |
541 | nv_connector->native_mode = NULL; | 543 | nv_connector->native_mode = NULL; |
@@ -563,7 +565,7 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
563 | ret = get_slave_funcs(nv_encoder)-> | 565 | ret = get_slave_funcs(nv_encoder)-> |
564 | get_modes(to_drm_encoder(nv_encoder), connector); | 566 | get_modes(to_drm_encoder(nv_encoder), connector); |
565 | 567 | ||
566 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) | 568 | if (nv_encoder->dcb->type == OUTPUT_LVDS) |
567 | ret += nouveau_connector_scaler_modes_add(connector); | 569 | ret += nouveau_connector_scaler_modes_add(connector); |
568 | 570 | ||
569 | return ret; | 571 | return ret; |
@@ -613,6 +615,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
613 | 615 | ||
614 | clock *= 3; | 616 | clock *= 3; |
615 | break; | 617 | break; |
618 | default: | ||
619 | BUG_ON(1); | ||
620 | return MODE_BAD; | ||
616 | } | 621 | } |
617 | 622 | ||
618 | if (clock < min_clock) | 623 | if (clock < min_clock) |
@@ -680,7 +685,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, | |||
680 | /* Firstly try getting EDID over DDC, if allowed and I2C channel | 685 | /* Firstly try getting EDID over DDC, if allowed and I2C channel |
681 | * is available. | 686 | * is available. |
682 | */ | 687 | */ |
683 | if (!dev_priv->VBIOS.pub.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf) | 688 | if (!dev_priv->vbios.fp_no_ddc && nv_encoder->dcb->i2c_index < 0xf) |
684 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); | 689 | i2c = nouveau_i2c_find(dev, nv_encoder->dcb->i2c_index); |
685 | 690 | ||
686 | if (i2c) { | 691 | if (i2c) { |
@@ -695,7 +700,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, | |||
695 | */ | 700 | */ |
696 | if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) && | 701 | if (!nv_connector->edid && nouveau_bios_fp_mode(dev, &native) && |
697 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || | 702 | (nv_encoder->dcb->lvdsconf.use_straps_for_mode || |
698 | dev_priv->VBIOS.pub.fp_no_ddc)) { | 703 | dev_priv->vbios.fp_no_ddc)) { |
699 | nv_connector->native_mode = drm_mode_duplicate(dev, &native); | 704 | nv_connector->native_mode = drm_mode_duplicate(dev, &native); |
700 | goto out; | 705 | goto out; |
701 | } | 706 | } |
@@ -704,7 +709,7 @@ nouveau_connector_create_lvds(struct drm_device *dev, | |||
704 | * stored for the panel stored in them. | 709 | * stored for the panel stored in them. |
705 | */ | 710 | */ |
706 | if (!nv_connector->edid && !nv_connector->native_mode && | 711 | if (!nv_connector->edid && !nv_connector->native_mode && |
707 | !dev_priv->VBIOS.pub.fp_no_ddc) { | 712 | !dev_priv->vbios.fp_no_ddc) { |
708 | struct edid *edid = | 713 | struct edid *edid = |
709 | (struct edid *)nouveau_bios_embedded_edid(dev); | 714 | (struct edid *)nouveau_bios_embedded_edid(dev); |
710 | if (edid) { | 715 | if (edid) { |
@@ -739,46 +744,66 @@ out: | |||
739 | } | 744 | } |
740 | 745 | ||
741 | int | 746 | int |
742 | nouveau_connector_create(struct drm_device *dev, int index, int type) | 747 | nouveau_connector_create(struct drm_device *dev, |
748 | struct dcb_connector_table_entry *dcb) | ||
743 | { | 749 | { |
744 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 750 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
745 | struct nouveau_connector *nv_connector = NULL; | 751 | struct nouveau_connector *nv_connector = NULL; |
746 | struct drm_connector *connector; | 752 | struct drm_connector *connector; |
747 | struct drm_encoder *encoder; | 753 | struct drm_encoder *encoder; |
748 | int ret; | 754 | int ret, type; |
749 | 755 | ||
750 | NV_DEBUG_KMS(dev, "\n"); | 756 | NV_DEBUG_KMS(dev, "\n"); |
751 | 757 | ||
752 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); | 758 | switch (dcb->type) { |
753 | if (!nv_connector) | 759 | case DCB_CONNECTOR_NONE: |
754 | return -ENOMEM; | 760 | return 0; |
755 | nv_connector->dcb = nouveau_bios_connector_entry(dev, index); | 761 | case DCB_CONNECTOR_VGA: |
756 | connector = &nv_connector->base; | ||
757 | |||
758 | switch (type) { | ||
759 | case DRM_MODE_CONNECTOR_VGA: | ||
760 | NV_INFO(dev, "Detected a VGA connector\n"); | 762 | NV_INFO(dev, "Detected a VGA connector\n"); |
763 | type = DRM_MODE_CONNECTOR_VGA; | ||
761 | break; | 764 | break; |
762 | case DRM_MODE_CONNECTOR_DVID: | 765 | case DCB_CONNECTOR_TV_0: |
763 | NV_INFO(dev, "Detected a DVI-D connector\n"); | 766 | case DCB_CONNECTOR_TV_1: |
767 | case DCB_CONNECTOR_TV_3: | ||
768 | NV_INFO(dev, "Detected a TV connector\n"); | ||
769 | type = DRM_MODE_CONNECTOR_TV; | ||
764 | break; | 770 | break; |
765 | case DRM_MODE_CONNECTOR_DVII: | 771 | case DCB_CONNECTOR_DVI_I: |
766 | NV_INFO(dev, "Detected a DVI-I connector\n"); | 772 | NV_INFO(dev, "Detected a DVI-I connector\n"); |
773 | type = DRM_MODE_CONNECTOR_DVII; | ||
767 | break; | 774 | break; |
768 | case DRM_MODE_CONNECTOR_LVDS: | 775 | case DCB_CONNECTOR_DVI_D: |
769 | NV_INFO(dev, "Detected a LVDS connector\n"); | 776 | NV_INFO(dev, "Detected a DVI-D connector\n"); |
777 | type = DRM_MODE_CONNECTOR_DVID; | ||
770 | break; | 778 | break; |
771 | case DRM_MODE_CONNECTOR_TV: | 779 | case DCB_CONNECTOR_HDMI_0: |
772 | NV_INFO(dev, "Detected a TV connector\n"); | 780 | case DCB_CONNECTOR_HDMI_1: |
781 | NV_INFO(dev, "Detected a HDMI connector\n"); | ||
782 | type = DRM_MODE_CONNECTOR_HDMIA; | ||
783 | break; | ||
784 | case DCB_CONNECTOR_LVDS: | ||
785 | NV_INFO(dev, "Detected a LVDS connector\n"); | ||
786 | type = DRM_MODE_CONNECTOR_LVDS; | ||
773 | break; | 787 | break; |
774 | case DRM_MODE_CONNECTOR_DisplayPort: | 788 | case DCB_CONNECTOR_DP: |
775 | NV_INFO(dev, "Detected a DisplayPort connector\n"); | 789 | NV_INFO(dev, "Detected a DisplayPort connector\n"); |
790 | type = DRM_MODE_CONNECTOR_DisplayPort; | ||
776 | break; | 791 | break; |
777 | default: | 792 | case DCB_CONNECTOR_eDP: |
778 | NV_ERROR(dev, "Unknown connector, this is not good.\n"); | 793 | NV_INFO(dev, "Detected an eDP connector\n"); |
794 | type = DRM_MODE_CONNECTOR_eDP; | ||
779 | break; | 795 | break; |
796 | default: | ||
797 | NV_ERROR(dev, "unknown connector type: 0x%02x!!\n", dcb->type); | ||
798 | return -EINVAL; | ||
780 | } | 799 | } |
781 | 800 | ||
801 | nv_connector = kzalloc(sizeof(*nv_connector), GFP_KERNEL); | ||
802 | if (!nv_connector) | ||
803 | return -ENOMEM; | ||
804 | nv_connector->dcb = dcb; | ||
805 | connector = &nv_connector->base; | ||
806 | |||
782 | /* defaults, will get overridden in detect() */ | 807 | /* defaults, will get overridden in detect() */ |
783 | connector->interlace_allowed = false; | 808 | connector->interlace_allowed = false; |
784 | connector->doublescan_allowed = false; | 809 | connector->doublescan_allowed = false; |
@@ -786,55 +811,65 @@ nouveau_connector_create(struct drm_device *dev, int index, int type) | |||
786 | drm_connector_init(dev, connector, &nouveau_connector_funcs, type); | 811 | drm_connector_init(dev, connector, &nouveau_connector_funcs, type); |
787 | drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); | 812 | drm_connector_helper_add(connector, &nouveau_connector_helper_funcs); |
788 | 813 | ||
814 | /* attach encoders */ | ||
815 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | ||
816 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | ||
817 | |||
818 | if (nv_encoder->dcb->connector != dcb->index) | ||
819 | continue; | ||
820 | |||
821 | if (get_slave_funcs(nv_encoder)) | ||
822 | get_slave_funcs(nv_encoder)->create_resources(encoder, connector); | ||
823 | |||
824 | drm_mode_connector_attach_encoder(connector, encoder); | ||
825 | } | ||
826 | |||
827 | if (!connector->encoder_ids[0]) { | ||
828 | NV_WARN(dev, " no encoders, ignoring\n"); | ||
829 | drm_connector_cleanup(connector); | ||
830 | kfree(connector); | ||
831 | return 0; | ||
832 | } | ||
833 | |||
789 | /* Init DVI-I specific properties */ | 834 | /* Init DVI-I specific properties */ |
790 | if (type == DRM_MODE_CONNECTOR_DVII) { | 835 | if (dcb->type == DCB_CONNECTOR_DVI_I) { |
791 | drm_mode_create_dvi_i_properties(dev); | 836 | drm_mode_create_dvi_i_properties(dev); |
792 | drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0); | 837 | drm_connector_attach_property(connector, dev->mode_config.dvi_i_subconnector_property, 0); |
793 | drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0); | 838 | drm_connector_attach_property(connector, dev->mode_config.dvi_i_select_subconnector_property, 0); |
794 | } | 839 | } |
795 | 840 | ||
796 | if (type != DRM_MODE_CONNECTOR_LVDS) | 841 | if (dcb->type != DCB_CONNECTOR_LVDS) |
797 | nv_connector->use_dithering = false; | 842 | nv_connector->use_dithering = false; |
798 | 843 | ||
799 | if (type == DRM_MODE_CONNECTOR_DVID || | 844 | switch (dcb->type) { |
800 | type == DRM_MODE_CONNECTOR_DVII || | 845 | case DCB_CONNECTOR_VGA: |
801 | type == DRM_MODE_CONNECTOR_LVDS || | 846 | if (dev_priv->card_type >= NV_50) { |
802 | type == DRM_MODE_CONNECTOR_DisplayPort) { | ||
803 | nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; | ||
804 | |||
805 | drm_connector_attach_property(connector, dev->mode_config.scaling_mode_property, | ||
806 | nv_connector->scaling_mode); | ||
807 | drm_connector_attach_property(connector, dev->mode_config.dithering_mode_property, | ||
808 | nv_connector->use_dithering ? DRM_MODE_DITHERING_ON | ||
809 | : DRM_MODE_DITHERING_OFF); | ||
810 | |||
811 | } else { | ||
812 | nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; | ||
813 | |||
814 | if (type == DRM_MODE_CONNECTOR_VGA && | ||
815 | dev_priv->card_type >= NV_50) { | ||
816 | drm_connector_attach_property(connector, | 847 | drm_connector_attach_property(connector, |
817 | dev->mode_config.scaling_mode_property, | 848 | dev->mode_config.scaling_mode_property, |
818 | nv_connector->scaling_mode); | 849 | nv_connector->scaling_mode); |
819 | } | 850 | } |
820 | } | 851 | /* fall-through */ |
821 | 852 | case DCB_CONNECTOR_TV_0: | |
822 | /* attach encoders */ | 853 | case DCB_CONNECTOR_TV_1: |
823 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 854 | case DCB_CONNECTOR_TV_3: |
824 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 855 | nv_connector->scaling_mode = DRM_MODE_SCALE_NONE; |
825 | 856 | break; | |
826 | if (nv_encoder->dcb->connector != index) | 857 | default: |
827 | continue; | 858 | nv_connector->scaling_mode = DRM_MODE_SCALE_FULLSCREEN; |
828 | |||
829 | if (get_slave_funcs(nv_encoder)) | ||
830 | get_slave_funcs(nv_encoder)->create_resources(encoder, connector); | ||
831 | 859 | ||
832 | drm_mode_connector_attach_encoder(connector, encoder); | 860 | drm_connector_attach_property(connector, |
861 | dev->mode_config.scaling_mode_property, | ||
862 | nv_connector->scaling_mode); | ||
863 | drm_connector_attach_property(connector, | ||
864 | dev->mode_config.dithering_mode_property, | ||
865 | nv_connector->use_dithering ? | ||
866 | DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); | ||
867 | break; | ||
833 | } | 868 | } |
834 | 869 | ||
835 | drm_sysfs_connector_add(connector); | 870 | drm_sysfs_connector_add(connector); |
836 | 871 | ||
837 | if (connector->connector_type == DRM_MODE_CONNECTOR_LVDS) { | 872 | if (dcb->type == DCB_CONNECTOR_LVDS) { |
838 | ret = nouveau_connector_create_lvds(dev, connector); | 873 | ret = nouveau_connector_create_lvds(dev, connector); |
839 | if (ret) { | 874 | if (ret) { |
840 | connector->funcs->destroy(connector); | 875 | connector->funcs->destroy(connector); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index 728b8090e5ff..4ef38abc2d9c 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h | |||
@@ -49,6 +49,7 @@ static inline struct nouveau_connector *nouveau_connector( | |||
49 | return container_of(con, struct nouveau_connector, base); | 49 | return container_of(con, struct nouveau_connector, base); |
50 | } | 50 | } |
51 | 51 | ||
52 | int nouveau_connector_create(struct drm_device *dev, int i2c_index, int type); | 52 | int nouveau_connector_create(struct drm_device *, |
53 | struct dcb_connector_table_entry *); | ||
53 | 54 | ||
54 | #endif /* __NOUVEAU_CONNECTOR_H__ */ | 55 | #endif /* __NOUVEAU_CONNECTOR_H__ */ |
diff --git a/drivers/gpu/drm/nouveau/nouveau_debugfs.c b/drivers/gpu/drm/nouveau/nouveau_debugfs.c index d79db3698f16..8ff9ef5d4b47 100644 --- a/drivers/gpu/drm/nouveau/nouveau_debugfs.c +++ b/drivers/gpu/drm/nouveau/nouveau_debugfs.c | |||
@@ -47,12 +47,23 @@ nouveau_debugfs_channel_info(struct seq_file *m, void *data) | |||
47 | seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2); | 47 | seq_printf(m, " cur: 0x%08x\n", chan->dma.cur << 2); |
48 | seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2); | 48 | seq_printf(m, " put: 0x%08x\n", chan->dma.put << 2); |
49 | seq_printf(m, " free: 0x%08x\n", chan->dma.free << 2); | 49 | seq_printf(m, " free: 0x%08x\n", chan->dma.free << 2); |
50 | if (chan->dma.ib_max) { | ||
51 | seq_printf(m, " ib max: 0x%08x\n", chan->dma.ib_max); | ||
52 | seq_printf(m, " ib put: 0x%08x\n", chan->dma.ib_put); | ||
53 | seq_printf(m, " ib free: 0x%08x\n", chan->dma.ib_free); | ||
54 | } | ||
50 | 55 | ||
51 | seq_printf(m, "gpu fifo state:\n"); | 56 | seq_printf(m, "gpu fifo state:\n"); |
52 | seq_printf(m, " get: 0x%08x\n", | 57 | seq_printf(m, " get: 0x%08x\n", |
53 | nvchan_rd32(chan, chan->user_get)); | 58 | nvchan_rd32(chan, chan->user_get)); |
54 | seq_printf(m, " put: 0x%08x\n", | 59 | seq_printf(m, " put: 0x%08x\n", |
55 | nvchan_rd32(chan, chan->user_put)); | 60 | nvchan_rd32(chan, chan->user_put)); |
61 | if (chan->dma.ib_max) { | ||
62 | seq_printf(m, " ib get: 0x%08x\n", | ||
63 | nvchan_rd32(chan, 0x88)); | ||
64 | seq_printf(m, " ib put: 0x%08x\n", | ||
65 | nvchan_rd32(chan, 0x8c)); | ||
66 | } | ||
56 | 67 | ||
57 | seq_printf(m, "last fence : %d\n", chan->fence.sequence); | 68 | seq_printf(m, "last fence : %d\n", chan->fence.sequence); |
58 | seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack); | 69 | seq_printf(m, "last signalled: %d\n", chan->fence.sequence_ack); |
@@ -133,9 +144,22 @@ nouveau_debugfs_memory_info(struct seq_file *m, void *data) | |||
133 | return 0; | 144 | return 0; |
134 | } | 145 | } |
135 | 146 | ||
147 | static int | ||
148 | nouveau_debugfs_vbios_image(struct seq_file *m, void *data) | ||
149 | { | ||
150 | struct drm_info_node *node = (struct drm_info_node *) m->private; | ||
151 | struct drm_nouveau_private *dev_priv = node->minor->dev->dev_private; | ||
152 | int i; | ||
153 | |||
154 | for (i = 0; i < dev_priv->vbios.length; i++) | ||
155 | seq_printf(m, "%c", dev_priv->vbios.data[i]); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
136 | static struct drm_info_list nouveau_debugfs_list[] = { | 159 | static struct drm_info_list nouveau_debugfs_list[] = { |
137 | { "chipset", nouveau_debugfs_chipset_info, 0, NULL }, | 160 | { "chipset", nouveau_debugfs_chipset_info, 0, NULL }, |
138 | { "memory", nouveau_debugfs_memory_info, 0, NULL }, | 161 | { "memory", nouveau_debugfs_memory_info, 0, NULL }, |
162 | { "vbios.rom", nouveau_debugfs_vbios_image, 0, NULL }, | ||
139 | }; | 163 | }; |
140 | #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) | 164 | #define NOUVEAU_DEBUGFS_ENTRIES ARRAY_SIZE(nouveau_debugfs_list) |
141 | 165 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.c b/drivers/gpu/drm/nouveau/nouveau_dma.c index 50d9e67745af..c8482a108a78 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.c +++ b/drivers/gpu/drm/nouveau/nouveau_dma.c | |||
@@ -32,7 +32,22 @@ | |||
32 | void | 32 | void |
33 | nouveau_dma_pre_init(struct nouveau_channel *chan) | 33 | nouveau_dma_pre_init(struct nouveau_channel *chan) |
34 | { | 34 | { |
35 | chan->dma.max = (chan->pushbuf_bo->bo.mem.size >> 2) - 2; | 35 | struct drm_nouveau_private *dev_priv = chan->dev->dev_private; |
36 | struct nouveau_bo *pushbuf = chan->pushbuf_bo; | ||
37 | |||
38 | if (dev_priv->card_type == NV_50) { | ||
39 | const int ib_size = pushbuf->bo.mem.size / 2; | ||
40 | |||
41 | chan->dma.ib_base = (pushbuf->bo.mem.size - ib_size) >> 2; | ||
42 | chan->dma.ib_max = (ib_size / 8) - 1; | ||
43 | chan->dma.ib_put = 0; | ||
44 | chan->dma.ib_free = chan->dma.ib_max - chan->dma.ib_put; | ||
45 | |||
46 | chan->dma.max = (pushbuf->bo.mem.size - ib_size) >> 2; | ||
47 | } else { | ||
48 | chan->dma.max = (pushbuf->bo.mem.size >> 2) - 2; | ||
49 | } | ||
50 | |||
36 | chan->dma.put = 0; | 51 | chan->dma.put = 0; |
37 | chan->dma.cur = chan->dma.put; | 52 | chan->dma.cur = chan->dma.put; |
38 | chan->dma.free = chan->dma.max - chan->dma.cur; | 53 | chan->dma.free = chan->dma.max - chan->dma.cur; |
@@ -162,12 +177,101 @@ READ_GET(struct nouveau_channel *chan, uint32_t *prev_get, uint32_t *timeout) | |||
162 | return (val - chan->pushbuf_base) >> 2; | 177 | return (val - chan->pushbuf_base) >> 2; |
163 | } | 178 | } |
164 | 179 | ||
180 | void | ||
181 | nv50_dma_push(struct nouveau_channel *chan, struct nouveau_bo *bo, | ||
182 | int delta, int length) | ||
183 | { | ||
184 | struct nouveau_bo *pb = chan->pushbuf_bo; | ||
185 | uint64_t offset = bo->bo.offset + delta; | ||
186 | int ip = (chan->dma.ib_put * 2) + chan->dma.ib_base; | ||
187 | |||
188 | BUG_ON(chan->dma.ib_free < 1); | ||
189 | nouveau_bo_wr32(pb, ip++, lower_32_bits(offset)); | ||
190 | nouveau_bo_wr32(pb, ip++, upper_32_bits(offset) | length << 8); | ||
191 | |||
192 | chan->dma.ib_put = (chan->dma.ib_put + 1) & chan->dma.ib_max; | ||
193 | nvchan_wr32(chan, 0x8c, chan->dma.ib_put); | ||
194 | chan->dma.ib_free--; | ||
195 | } | ||
196 | |||
197 | static int | ||
198 | nv50_dma_push_wait(struct nouveau_channel *chan, int count) | ||
199 | { | ||
200 | uint32_t cnt = 0, prev_get = 0; | ||
201 | |||
202 | while (chan->dma.ib_free < count) { | ||
203 | uint32_t get = nvchan_rd32(chan, 0x88); | ||
204 | if (get != prev_get) { | ||
205 | prev_get = get; | ||
206 | cnt = 0; | ||
207 | } | ||
208 | |||
209 | if ((++cnt & 0xff) == 0) { | ||
210 | DRM_UDELAY(1); | ||
211 | if (cnt > 100000) | ||
212 | return -EBUSY; | ||
213 | } | ||
214 | |||
215 | chan->dma.ib_free = get - chan->dma.ib_put; | ||
216 | if (chan->dma.ib_free <= 0) | ||
217 | chan->dma.ib_free += chan->dma.ib_max + 1; | ||
218 | } | ||
219 | |||
220 | return 0; | ||
221 | } | ||
222 | |||
223 | static int | ||
224 | nv50_dma_wait(struct nouveau_channel *chan, int slots, int count) | ||
225 | { | ||
226 | uint32_t cnt = 0, prev_get = 0; | ||
227 | int ret; | ||
228 | |||
229 | ret = nv50_dma_push_wait(chan, slots + 1); | ||
230 | if (unlikely(ret)) | ||
231 | return ret; | ||
232 | |||
233 | while (chan->dma.free < count) { | ||
234 | int get = READ_GET(chan, &prev_get, &cnt); | ||
235 | if (unlikely(get < 0)) { | ||
236 | if (get == -EINVAL) | ||
237 | continue; | ||
238 | |||
239 | return get; | ||
240 | } | ||
241 | |||
242 | if (get <= chan->dma.cur) { | ||
243 | chan->dma.free = chan->dma.max - chan->dma.cur; | ||
244 | if (chan->dma.free >= count) | ||
245 | break; | ||
246 | |||
247 | FIRE_RING(chan); | ||
248 | do { | ||
249 | get = READ_GET(chan, &prev_get, &cnt); | ||
250 | if (unlikely(get < 0)) { | ||
251 | if (get == -EINVAL) | ||
252 | continue; | ||
253 | return get; | ||
254 | } | ||
255 | } while (get == 0); | ||
256 | chan->dma.cur = 0; | ||
257 | chan->dma.put = 0; | ||
258 | } | ||
259 | |||
260 | chan->dma.free = get - chan->dma.cur - 1; | ||
261 | } | ||
262 | |||
263 | return 0; | ||
264 | } | ||
265 | |||
165 | int | 266 | int |
166 | nouveau_dma_wait(struct nouveau_channel *chan, int size) | 267 | nouveau_dma_wait(struct nouveau_channel *chan, int slots, int size) |
167 | { | 268 | { |
168 | uint32_t prev_get = 0, cnt = 0; | 269 | uint32_t prev_get = 0, cnt = 0; |
169 | int get; | 270 | int get; |
170 | 271 | ||
272 | if (chan->dma.ib_max) | ||
273 | return nv50_dma_wait(chan, slots, size); | ||
274 | |||
171 | while (chan->dma.free < size) { | 275 | while (chan->dma.free < size) { |
172 | get = READ_GET(chan, &prev_get, &cnt); | 276 | get = READ_GET(chan, &prev_get, &cnt); |
173 | if (unlikely(get == -EBUSY)) | 277 | if (unlikely(get == -EBUSY)) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_dma.h b/drivers/gpu/drm/nouveau/nouveau_dma.h index dabfd655f93e..8b05c15866d5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dma.h +++ b/drivers/gpu/drm/nouveau/nouveau_dma.h | |||
@@ -31,6 +31,9 @@ | |||
31 | #define NOUVEAU_DMA_DEBUG 0 | 31 | #define NOUVEAU_DMA_DEBUG 0 |
32 | #endif | 32 | #endif |
33 | 33 | ||
34 | void nv50_dma_push(struct nouveau_channel *, struct nouveau_bo *, | ||
35 | int delta, int length); | ||
36 | |||
34 | /* | 37 | /* |
35 | * There's a hw race condition where you can't jump to your PUT offset, | 38 | * There's a hw race condition where you can't jump to your PUT offset, |
36 | * to avoid this we jump to offset + SKIPS and fill the difference with | 39 | * to avoid this we jump to offset + SKIPS and fill the difference with |
@@ -96,13 +99,11 @@ enum { | |||
96 | static __must_check inline int | 99 | static __must_check inline int |
97 | RING_SPACE(struct nouveau_channel *chan, int size) | 100 | RING_SPACE(struct nouveau_channel *chan, int size) |
98 | { | 101 | { |
99 | if (chan->dma.free < size) { | 102 | int ret; |
100 | int ret; | ||
101 | 103 | ||
102 | ret = nouveau_dma_wait(chan, size); | 104 | ret = nouveau_dma_wait(chan, 1, size); |
103 | if (ret) | 105 | if (ret) |
104 | return ret; | 106 | return ret; |
105 | } | ||
106 | 107 | ||
107 | chan->dma.free -= size; | 108 | chan->dma.free -= size; |
108 | return 0; | 109 | return 0; |
@@ -146,7 +147,13 @@ FIRE_RING(struct nouveau_channel *chan) | |||
146 | return; | 147 | return; |
147 | chan->accel_done = true; | 148 | chan->accel_done = true; |
148 | 149 | ||
149 | WRITE_PUT(chan->dma.cur); | 150 | if (chan->dma.ib_max) { |
151 | nv50_dma_push(chan, chan->pushbuf_bo, chan->dma.put << 2, | ||
152 | (chan->dma.cur - chan->dma.put) << 2); | ||
153 | } else { | ||
154 | WRITE_PUT(chan->dma.cur); | ||
155 | } | ||
156 | |||
150 | chan->dma.put = chan->dma.cur; | 157 | chan->dma.put = chan->dma.cur; |
151 | } | 158 | } |
152 | 159 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.c b/drivers/gpu/drm/nouveau/nouveau_drv.c index da3b93b84502..874adf55a43f 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.c +++ b/drivers/gpu/drm/nouveau/nouveau_drv.c | |||
@@ -75,11 +75,11 @@ MODULE_PARM_DESC(ignorelid, "Ignore ACPI lid status"); | |||
75 | int nouveau_ignorelid = 0; | 75 | int nouveau_ignorelid = 0; |
76 | module_param_named(ignorelid, nouveau_ignorelid, int, 0400); | 76 | module_param_named(ignorelid, nouveau_ignorelid, int, 0400); |
77 | 77 | ||
78 | MODULE_PARM_DESC(noagp, "Disable all acceleration"); | 78 | MODULE_PARM_DESC(noaccel, "Disable all acceleration"); |
79 | int nouveau_noaccel = 0; | 79 | int nouveau_noaccel = 0; |
80 | module_param_named(noaccel, nouveau_noaccel, int, 0400); | 80 | module_param_named(noaccel, nouveau_noaccel, int, 0400); |
81 | 81 | ||
82 | MODULE_PARM_DESC(noagp, "Disable fbcon acceleration"); | 82 | MODULE_PARM_DESC(nofbaccel, "Disable fbcon acceleration"); |
83 | int nouveau_nofbaccel = 0; | 83 | int nouveau_nofbaccel = 0; |
84 | module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); | 84 | module_param_named(nofbaccel, nouveau_nofbaccel, int, 0400); |
85 | 85 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 1c15ef37b71c..2f8ce42f0725 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
@@ -34,7 +34,7 @@ | |||
34 | 34 | ||
35 | #define DRIVER_MAJOR 0 | 35 | #define DRIVER_MAJOR 0 |
36 | #define DRIVER_MINOR 0 | 36 | #define DRIVER_MINOR 0 |
37 | #define DRIVER_PATCHLEVEL 15 | 37 | #define DRIVER_PATCHLEVEL 16 |
38 | 38 | ||
39 | #define NOUVEAU_FAMILY 0x0000FFFF | 39 | #define NOUVEAU_FAMILY 0x0000FFFF |
40 | #define NOUVEAU_FLAGS 0xFFFF0000 | 40 | #define NOUVEAU_FLAGS 0xFFFF0000 |
@@ -83,6 +83,7 @@ struct nouveau_bo { | |||
83 | struct drm_file *reserved_by; | 83 | struct drm_file *reserved_by; |
84 | struct list_head entry; | 84 | struct list_head entry; |
85 | int pbbo_index; | 85 | int pbbo_index; |
86 | bool validate_mapped; | ||
86 | 87 | ||
87 | struct nouveau_channel *channel; | 88 | struct nouveau_channel *channel; |
88 | 89 | ||
@@ -239,6 +240,11 @@ struct nouveau_channel { | |||
239 | int cur; | 240 | int cur; |
240 | int put; | 241 | int put; |
241 | /* access via pushbuf_bo */ | 242 | /* access via pushbuf_bo */ |
243 | |||
244 | int ib_base; | ||
245 | int ib_max; | ||
246 | int ib_free; | ||
247 | int ib_put; | ||
242 | } dma; | 248 | } dma; |
243 | 249 | ||
244 | uint32_t sw_subchannel[8]; | 250 | uint32_t sw_subchannel[8]; |
@@ -533,6 +539,9 @@ struct drm_nouveau_private { | |||
533 | struct nouveau_engine engine; | 539 | struct nouveau_engine engine; |
534 | struct nouveau_channel *channel; | 540 | struct nouveau_channel *channel; |
535 | 541 | ||
542 | /* For PFIFO and PGRAPH. */ | ||
543 | spinlock_t context_switch_lock; | ||
544 | |||
536 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ | 545 | /* RAMIN configuration, RAMFC, RAMHT and RAMRO offsets */ |
537 | struct nouveau_gpuobj *ramht; | 546 | struct nouveau_gpuobj *ramht; |
538 | uint32_t ramin_rsvd_vram; | 547 | uint32_t ramin_rsvd_vram; |
@@ -596,8 +605,7 @@ struct drm_nouveau_private { | |||
596 | 605 | ||
597 | struct list_head gpuobj_list; | 606 | struct list_head gpuobj_list; |
598 | 607 | ||
599 | struct nvbios VBIOS; | 608 | struct nvbios vbios; |
600 | struct nouveau_bios_info *vbios; | ||
601 | 609 | ||
602 | struct nv04_mode_state mode_reg; | 610 | struct nv04_mode_state mode_reg; |
603 | struct nv04_mode_state saved_reg; | 611 | struct nv04_mode_state saved_reg; |
@@ -696,12 +704,6 @@ extern bool nouveau_wait_until(struct drm_device *, uint64_t timeout, | |||
696 | uint32_t reg, uint32_t mask, uint32_t val); | 704 | uint32_t reg, uint32_t mask, uint32_t val); |
697 | extern bool nouveau_wait_for_idle(struct drm_device *); | 705 | extern bool nouveau_wait_for_idle(struct drm_device *); |
698 | extern int nouveau_card_init(struct drm_device *); | 706 | extern int nouveau_card_init(struct drm_device *); |
699 | extern int nouveau_ioctl_card_init(struct drm_device *, void *data, | ||
700 | struct drm_file *); | ||
701 | extern int nouveau_ioctl_suspend(struct drm_device *, void *data, | ||
702 | struct drm_file *); | ||
703 | extern int nouveau_ioctl_resume(struct drm_device *, void *data, | ||
704 | struct drm_file *); | ||
705 | 707 | ||
706 | /* nouveau_mem.c */ | 708 | /* nouveau_mem.c */ |
707 | extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, | 709 | extern int nouveau_mem_init_heap(struct mem_block **, uint64_t start, |
@@ -845,7 +847,7 @@ nouveau_debugfs_channel_fini(struct nouveau_channel *chan) | |||
845 | /* nouveau_dma.c */ | 847 | /* nouveau_dma.c */ |
846 | extern void nouveau_dma_pre_init(struct nouveau_channel *); | 848 | extern void nouveau_dma_pre_init(struct nouveau_channel *); |
847 | extern int nouveau_dma_init(struct nouveau_channel *); | 849 | extern int nouveau_dma_init(struct nouveau_channel *); |
848 | extern int nouveau_dma_wait(struct nouveau_channel *, int size); | 850 | extern int nouveau_dma_wait(struct nouveau_channel *, int slots, int size); |
849 | 851 | ||
850 | /* nouveau_acpi.c */ | 852 | /* nouveau_acpi.c */ |
851 | #ifdef CONFIG_ACPI | 853 | #ifdef CONFIG_ACPI |
@@ -1027,6 +1029,7 @@ extern void nv50_graph_destroy_context(struct nouveau_channel *); | |||
1027 | extern int nv50_graph_load_context(struct nouveau_channel *); | 1029 | extern int nv50_graph_load_context(struct nouveau_channel *); |
1028 | extern int nv50_graph_unload_context(struct drm_device *); | 1030 | extern int nv50_graph_unload_context(struct drm_device *); |
1029 | extern void nv50_graph_context_switch(struct drm_device *); | 1031 | extern void nv50_graph_context_switch(struct drm_device *); |
1032 | extern int nv50_grctx_init(struct nouveau_grctx *); | ||
1030 | 1033 | ||
1031 | /* nouveau_grctx.c */ | 1034 | /* nouveau_grctx.c */ |
1032 | extern int nouveau_grctx_prog_load(struct drm_device *); | 1035 | extern int nouveau_grctx_prog_load(struct drm_device *); |
@@ -1152,16 +1155,6 @@ extern int nouveau_gem_ioctl_new(struct drm_device *, void *, | |||
1152 | struct drm_file *); | 1155 | struct drm_file *); |
1153 | extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *, | 1156 | extern int nouveau_gem_ioctl_pushbuf(struct drm_device *, void *, |
1154 | struct drm_file *); | 1157 | struct drm_file *); |
1155 | extern int nouveau_gem_ioctl_pushbuf_call(struct drm_device *, void *, | ||
1156 | struct drm_file *); | ||
1157 | extern int nouveau_gem_ioctl_pushbuf_call2(struct drm_device *, void *, | ||
1158 | struct drm_file *); | ||
1159 | extern int nouveau_gem_ioctl_pin(struct drm_device *, void *, | ||
1160 | struct drm_file *); | ||
1161 | extern int nouveau_gem_ioctl_unpin(struct drm_device *, void *, | ||
1162 | struct drm_file *); | ||
1163 | extern int nouveau_gem_ioctl_tile(struct drm_device *, void *, | ||
1164 | struct drm_file *); | ||
1165 | extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *, | 1158 | extern int nouveau_gem_ioctl_cpu_prep(struct drm_device *, void *, |
1166 | struct drm_file *); | 1159 | struct drm_file *); |
1167 | extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, | 1160 | extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *, |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 34063c561899..0d22f66f1c79 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
@@ -241,6 +241,11 @@ validate_fini_list(struct list_head *list, struct nouveau_fence *fence) | |||
241 | nouveau_fence_unref((void *)&prev_fence); | 241 | nouveau_fence_unref((void *)&prev_fence); |
242 | } | 242 | } |
243 | 243 | ||
244 | if (unlikely(nvbo->validate_mapped)) { | ||
245 | ttm_bo_kunmap(&nvbo->kmap); | ||
246 | nvbo->validate_mapped = false; | ||
247 | } | ||
248 | |||
244 | list_del(&nvbo->entry); | 249 | list_del(&nvbo->entry); |
245 | nvbo->reserved_by = NULL; | 250 | nvbo->reserved_by = NULL; |
246 | ttm_bo_unreserve(&nvbo->bo); | 251 | ttm_bo_unreserve(&nvbo->bo); |
@@ -300,11 +305,14 @@ retry: | |||
300 | if (ret == -EAGAIN) | 305 | if (ret == -EAGAIN) |
301 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); | 306 | ret = ttm_bo_wait_unreserved(&nvbo->bo, false); |
302 | drm_gem_object_unreference(gem); | 307 | drm_gem_object_unreference(gem); |
303 | if (ret) | 308 | if (ret) { |
309 | NV_ERROR(dev, "fail reserve\n"); | ||
304 | return ret; | 310 | return ret; |
311 | } | ||
305 | goto retry; | 312 | goto retry; |
306 | } | 313 | } |
307 | 314 | ||
315 | b->user_priv = (uint64_t)(unsigned long)nvbo; | ||
308 | nvbo->reserved_by = file_priv; | 316 | nvbo->reserved_by = file_priv; |
309 | nvbo->pbbo_index = i; | 317 | nvbo->pbbo_index = i; |
310 | if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && | 318 | if ((b->valid_domains & NOUVEAU_GEM_DOMAIN_VRAM) && |
@@ -334,8 +342,10 @@ retry: | |||
334 | } | 342 | } |
335 | 343 | ||
336 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); | 344 | ret = ttm_bo_wait_cpu(&nvbo->bo, false); |
337 | if (ret) | 345 | if (ret) { |
346 | NV_ERROR(dev, "fail wait_cpu\n"); | ||
338 | return ret; | 347 | return ret; |
348 | } | ||
339 | goto retry; | 349 | goto retry; |
340 | } | 350 | } |
341 | } | 351 | } |
@@ -349,6 +359,7 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
349 | { | 359 | { |
350 | struct drm_nouveau_gem_pushbuf_bo __user *upbbo = | 360 | struct drm_nouveau_gem_pushbuf_bo __user *upbbo = |
351 | (void __force __user *)(uintptr_t)user_pbbo_ptr; | 361 | (void __force __user *)(uintptr_t)user_pbbo_ptr; |
362 | struct drm_device *dev = chan->dev; | ||
352 | struct nouveau_bo *nvbo; | 363 | struct nouveau_bo *nvbo; |
353 | int ret, relocs = 0; | 364 | int ret, relocs = 0; |
354 | 365 | ||
@@ -360,39 +371,46 @@ validate_list(struct nouveau_channel *chan, struct list_head *list, | |||
360 | spin_lock(&nvbo->bo.lock); | 371 | spin_lock(&nvbo->bo.lock); |
361 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); | 372 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); |
362 | spin_unlock(&nvbo->bo.lock); | 373 | spin_unlock(&nvbo->bo.lock); |
363 | if (unlikely(ret)) | 374 | if (unlikely(ret)) { |
375 | NV_ERROR(dev, "fail wait other chan\n"); | ||
364 | return ret; | 376 | return ret; |
377 | } | ||
365 | } | 378 | } |
366 | 379 | ||
367 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, | 380 | ret = nouveau_gem_set_domain(nvbo->gem, b->read_domains, |
368 | b->write_domains, | 381 | b->write_domains, |
369 | b->valid_domains); | 382 | b->valid_domains); |
370 | if (unlikely(ret)) | 383 | if (unlikely(ret)) { |
384 | NV_ERROR(dev, "fail set_domain\n"); | ||
371 | return ret; | 385 | return ret; |
386 | } | ||
372 | 387 | ||
373 | nvbo->channel = chan; | 388 | nvbo->channel = chan; |
374 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, | 389 | ret = ttm_bo_validate(&nvbo->bo, &nvbo->placement, |
375 | false, false); | 390 | false, false); |
376 | nvbo->channel = NULL; | 391 | nvbo->channel = NULL; |
377 | if (unlikely(ret)) | 392 | if (unlikely(ret)) { |
393 | NV_ERROR(dev, "fail ttm_validate\n"); | ||
378 | return ret; | 394 | return ret; |
395 | } | ||
379 | 396 | ||
380 | if (nvbo->bo.offset == b->presumed_offset && | 397 | if (nvbo->bo.offset == b->presumed.offset && |
381 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && | 398 | ((nvbo->bo.mem.mem_type == TTM_PL_VRAM && |
382 | b->presumed_domain & NOUVEAU_GEM_DOMAIN_VRAM) || | 399 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_VRAM) || |
383 | (nvbo->bo.mem.mem_type == TTM_PL_TT && | 400 | (nvbo->bo.mem.mem_type == TTM_PL_TT && |
384 | b->presumed_domain & NOUVEAU_GEM_DOMAIN_GART))) | 401 | b->presumed.domain & NOUVEAU_GEM_DOMAIN_GART))) |
385 | continue; | 402 | continue; |
386 | 403 | ||
387 | if (nvbo->bo.mem.mem_type == TTM_PL_TT) | 404 | if (nvbo->bo.mem.mem_type == TTM_PL_TT) |
388 | b->presumed_domain = NOUVEAU_GEM_DOMAIN_GART; | 405 | b->presumed.domain = NOUVEAU_GEM_DOMAIN_GART; |
389 | else | 406 | else |
390 | b->presumed_domain = NOUVEAU_GEM_DOMAIN_VRAM; | 407 | b->presumed.domain = NOUVEAU_GEM_DOMAIN_VRAM; |
391 | b->presumed_offset = nvbo->bo.offset; | 408 | b->presumed.offset = nvbo->bo.offset; |
392 | b->presumed_ok = 0; | 409 | b->presumed.valid = 0; |
393 | relocs++; | 410 | relocs++; |
394 | 411 | ||
395 | if (DRM_COPY_TO_USER(&upbbo[nvbo->pbbo_index], b, sizeof(*b))) | 412 | if (DRM_COPY_TO_USER(&upbbo[nvbo->pbbo_index].presumed, |
413 | &b->presumed, sizeof(b->presumed))) | ||
396 | return -EFAULT; | 414 | return -EFAULT; |
397 | } | 415 | } |
398 | 416 | ||
@@ -406,6 +424,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, | |||
406 | uint64_t user_buffers, int nr_buffers, | 424 | uint64_t user_buffers, int nr_buffers, |
407 | struct validate_op *op, int *apply_relocs) | 425 | struct validate_op *op, int *apply_relocs) |
408 | { | 426 | { |
427 | struct drm_device *dev = chan->dev; | ||
409 | int ret, relocs = 0; | 428 | int ret, relocs = 0; |
410 | 429 | ||
411 | INIT_LIST_HEAD(&op->vram_list); | 430 | INIT_LIST_HEAD(&op->vram_list); |
@@ -416,11 +435,14 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, | |||
416 | return 0; | 435 | return 0; |
417 | 436 | ||
418 | ret = validate_init(chan, file_priv, pbbo, nr_buffers, op); | 437 | ret = validate_init(chan, file_priv, pbbo, nr_buffers, op); |
419 | if (unlikely(ret)) | 438 | if (unlikely(ret)) { |
439 | NV_ERROR(dev, "validate_init\n"); | ||
420 | return ret; | 440 | return ret; |
441 | } | ||
421 | 442 | ||
422 | ret = validate_list(chan, &op->vram_list, pbbo, user_buffers); | 443 | ret = validate_list(chan, &op->vram_list, pbbo, user_buffers); |
423 | if (unlikely(ret < 0)) { | 444 | if (unlikely(ret < 0)) { |
445 | NV_ERROR(dev, "validate vram_list\n"); | ||
424 | validate_fini(op, NULL); | 446 | validate_fini(op, NULL); |
425 | return ret; | 447 | return ret; |
426 | } | 448 | } |
@@ -428,6 +450,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, | |||
428 | 450 | ||
429 | ret = validate_list(chan, &op->gart_list, pbbo, user_buffers); | 451 | ret = validate_list(chan, &op->gart_list, pbbo, user_buffers); |
430 | if (unlikely(ret < 0)) { | 452 | if (unlikely(ret < 0)) { |
453 | NV_ERROR(dev, "validate gart_list\n"); | ||
431 | validate_fini(op, NULL); | 454 | validate_fini(op, NULL); |
432 | return ret; | 455 | return ret; |
433 | } | 456 | } |
@@ -435,6 +458,7 @@ nouveau_gem_pushbuf_validate(struct nouveau_channel *chan, | |||
435 | 458 | ||
436 | ret = validate_list(chan, &op->both_list, pbbo, user_buffers); | 459 | ret = validate_list(chan, &op->both_list, pbbo, user_buffers); |
437 | if (unlikely(ret < 0)) { | 460 | if (unlikely(ret < 0)) { |
461 | NV_ERROR(dev, "validate both_list\n"); | ||
438 | validate_fini(op, NULL); | 462 | validate_fini(op, NULL); |
439 | return ret; | 463 | return ret; |
440 | } | 464 | } |
@@ -463,59 +487,82 @@ u_memcpya(uint64_t user, unsigned nmemb, unsigned size) | |||
463 | } | 487 | } |
464 | 488 | ||
465 | static int | 489 | static int |
466 | nouveau_gem_pushbuf_reloc_apply(struct nouveau_channel *chan, int nr_bo, | 490 | nouveau_gem_pushbuf_reloc_apply(struct drm_device *dev, |
467 | struct drm_nouveau_gem_pushbuf_bo *bo, | 491 | struct drm_nouveau_gem_pushbuf *req, |
468 | unsigned nr_relocs, uint64_t ptr_relocs, | 492 | struct drm_nouveau_gem_pushbuf_bo *bo) |
469 | unsigned nr_dwords, unsigned first_dword, | ||
470 | uint32_t *pushbuf, bool is_iomem) | ||
471 | { | 493 | { |
472 | struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL; | 494 | struct drm_nouveau_gem_pushbuf_reloc *reloc = NULL; |
473 | struct drm_device *dev = chan->dev; | ||
474 | int ret = 0; | 495 | int ret = 0; |
475 | unsigned i; | 496 | unsigned i; |
476 | 497 | ||
477 | reloc = u_memcpya(ptr_relocs, nr_relocs, sizeof(*reloc)); | 498 | reloc = u_memcpya(req->relocs, req->nr_relocs, sizeof(*reloc)); |
478 | if (IS_ERR(reloc)) | 499 | if (IS_ERR(reloc)) |
479 | return PTR_ERR(reloc); | 500 | return PTR_ERR(reloc); |
480 | 501 | ||
481 | for (i = 0; i < nr_relocs; i++) { | 502 | for (i = 0; i < req->nr_relocs; i++) { |
482 | struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i]; | 503 | struct drm_nouveau_gem_pushbuf_reloc *r = &reloc[i]; |
483 | struct drm_nouveau_gem_pushbuf_bo *b; | 504 | struct drm_nouveau_gem_pushbuf_bo *b; |
505 | struct nouveau_bo *nvbo; | ||
484 | uint32_t data; | 506 | uint32_t data; |
485 | 507 | ||
486 | if (r->bo_index >= nr_bo || r->reloc_index < first_dword || | 508 | if (unlikely(r->bo_index > req->nr_buffers)) { |
487 | r->reloc_index >= first_dword + nr_dwords) { | 509 | NV_ERROR(dev, "reloc bo index invalid\n"); |
488 | NV_ERROR(dev, "Bad relocation %d\n", i); | ||
489 | NV_ERROR(dev, " bo: %d max %d\n", r->bo_index, nr_bo); | ||
490 | NV_ERROR(dev, " id: %d max %d\n", r->reloc_index, nr_dwords); | ||
491 | ret = -EINVAL; | 510 | ret = -EINVAL; |
492 | break; | 511 | break; |
493 | } | 512 | } |
494 | 513 | ||
495 | b = &bo[r->bo_index]; | 514 | b = &bo[r->bo_index]; |
496 | if (b->presumed_ok) | 515 | if (b->presumed.valid) |
497 | continue; | 516 | continue; |
498 | 517 | ||
518 | if (unlikely(r->reloc_bo_index > req->nr_buffers)) { | ||
519 | NV_ERROR(dev, "reloc container bo index invalid\n"); | ||
520 | ret = -EINVAL; | ||
521 | break; | ||
522 | } | ||
523 | nvbo = (void *)(unsigned long)bo[r->reloc_bo_index].user_priv; | ||
524 | |||
525 | if (unlikely(r->reloc_bo_offset + 4 > | ||
526 | nvbo->bo.mem.num_pages << PAGE_SHIFT)) { | ||
527 | NV_ERROR(dev, "reloc outside of bo\n"); | ||
528 | ret = -EINVAL; | ||
529 | break; | ||
530 | } | ||
531 | |||
532 | if (!nvbo->kmap.virtual) { | ||
533 | ret = ttm_bo_kmap(&nvbo->bo, 0, nvbo->bo.mem.num_pages, | ||
534 | &nvbo->kmap); | ||
535 | if (ret) { | ||
536 | NV_ERROR(dev, "failed kmap for reloc\n"); | ||
537 | break; | ||
538 | } | ||
539 | nvbo->validate_mapped = true; | ||
540 | } | ||
541 | |||
499 | if (r->flags & NOUVEAU_GEM_RELOC_LOW) | 542 | if (r->flags & NOUVEAU_GEM_RELOC_LOW) |
500 | data = b->presumed_offset + r->data; | 543 | data = b->presumed.offset + r->data; |
501 | else | 544 | else |
502 | if (r->flags & NOUVEAU_GEM_RELOC_HIGH) | 545 | if (r->flags & NOUVEAU_GEM_RELOC_HIGH) |
503 | data = (b->presumed_offset + r->data) >> 32; | 546 | data = (b->presumed.offset + r->data) >> 32; |
504 | else | 547 | else |
505 | data = r->data; | 548 | data = r->data; |
506 | 549 | ||
507 | if (r->flags & NOUVEAU_GEM_RELOC_OR) { | 550 | if (r->flags & NOUVEAU_GEM_RELOC_OR) { |
508 | if (b->presumed_domain == NOUVEAU_GEM_DOMAIN_GART) | 551 | if (b->presumed.domain == NOUVEAU_GEM_DOMAIN_GART) |
509 | data |= r->tor; | 552 | data |= r->tor; |
510 | else | 553 | else |
511 | data |= r->vor; | 554 | data |= r->vor; |
512 | } | 555 | } |
513 | 556 | ||
514 | if (is_iomem) | 557 | spin_lock(&nvbo->bo.lock); |
515 | iowrite32_native(data, (void __force __iomem *) | 558 | ret = ttm_bo_wait(&nvbo->bo, false, false, false); |
516 | &pushbuf[r->reloc_index]); | 559 | spin_unlock(&nvbo->bo.lock); |
517 | else | 560 | if (ret) { |
518 | pushbuf[r->reloc_index] = data; | 561 | NV_ERROR(dev, "reloc wait_idle failed: %d\n", ret); |
562 | break; | ||
563 | } | ||
564 | |||
565 | nouveau_bo_wr32(nvbo, r->reloc_bo_offset >> 2, data); | ||
519 | } | 566 | } |
520 | 567 | ||
521 | kfree(reloc); | 568 | kfree(reloc); |
@@ -526,127 +573,50 @@ int | |||
526 | nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, | 573 | nouveau_gem_ioctl_pushbuf(struct drm_device *dev, void *data, |
527 | struct drm_file *file_priv) | 574 | struct drm_file *file_priv) |
528 | { | 575 | { |
576 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
529 | struct drm_nouveau_gem_pushbuf *req = data; | 577 | struct drm_nouveau_gem_pushbuf *req = data; |
530 | struct drm_nouveau_gem_pushbuf_bo *bo = NULL; | 578 | struct drm_nouveau_gem_pushbuf_push *push; |
579 | struct drm_nouveau_gem_pushbuf_bo *bo; | ||
531 | struct nouveau_channel *chan; | 580 | struct nouveau_channel *chan; |
532 | struct validate_op op; | 581 | struct validate_op op; |
533 | struct nouveau_fence* fence = 0; | 582 | struct nouveau_fence *fence = 0; |
534 | uint32_t *pushbuf = NULL; | 583 | int i, j, ret = 0, do_reloc = 0; |
535 | int ret = 0, do_reloc = 0, i; | ||
536 | 584 | ||
537 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | 585 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; |
538 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); | 586 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); |
539 | 587 | ||
540 | if (req->nr_dwords >= chan->dma.max || | 588 | req->vram_available = dev_priv->fb_aper_free; |
541 | req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS || | 589 | req->gart_available = dev_priv->gart_info.aper_free; |
542 | req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) { | 590 | if (unlikely(req->nr_push == 0)) |
543 | NV_ERROR(dev, "Pushbuf config exceeds limits:\n"); | 591 | goto out_next; |
544 | NV_ERROR(dev, " dwords : %d max %d\n", req->nr_dwords, | ||
545 | chan->dma.max - 1); | ||
546 | NV_ERROR(dev, " buffers: %d max %d\n", req->nr_buffers, | ||
547 | NOUVEAU_GEM_MAX_BUFFERS); | ||
548 | NV_ERROR(dev, " relocs : %d max %d\n", req->nr_relocs, | ||
549 | NOUVEAU_GEM_MAX_RELOCS); | ||
550 | return -EINVAL; | ||
551 | } | ||
552 | |||
553 | pushbuf = u_memcpya(req->dwords, req->nr_dwords, sizeof(uint32_t)); | ||
554 | if (IS_ERR(pushbuf)) | ||
555 | return PTR_ERR(pushbuf); | ||
556 | |||
557 | bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); | ||
558 | if (IS_ERR(bo)) { | ||
559 | kfree(pushbuf); | ||
560 | return PTR_ERR(bo); | ||
561 | } | ||
562 | |||
563 | mutex_lock(&dev->struct_mutex); | ||
564 | |||
565 | /* Validate buffer list */ | ||
566 | ret = nouveau_gem_pushbuf_validate(chan, file_priv, bo, req->buffers, | ||
567 | req->nr_buffers, &op, &do_reloc); | ||
568 | if (ret) | ||
569 | goto out; | ||
570 | |||
571 | /* Apply any relocations that are required */ | ||
572 | if (do_reloc) { | ||
573 | ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers, | ||
574 | bo, req->nr_relocs, | ||
575 | req->relocs, | ||
576 | req->nr_dwords, 0, | ||
577 | pushbuf, false); | ||
578 | if (ret) | ||
579 | goto out; | ||
580 | } | ||
581 | |||
582 | /* Emit push buffer to the hw | ||
583 | */ | ||
584 | ret = RING_SPACE(chan, req->nr_dwords); | ||
585 | if (ret) | ||
586 | goto out; | ||
587 | |||
588 | OUT_RINGp(chan, pushbuf, req->nr_dwords); | ||
589 | 592 | ||
590 | ret = nouveau_fence_new(chan, &fence, true); | 593 | if (unlikely(req->nr_push > NOUVEAU_GEM_MAX_PUSH)) { |
591 | if (ret) { | 594 | NV_ERROR(dev, "pushbuf push count exceeds limit: %d max %d\n", |
592 | NV_ERROR(dev, "error fencing pushbuf: %d\n", ret); | 595 | req->nr_push, NOUVEAU_GEM_MAX_PUSH); |
593 | WIND_RING(chan); | 596 | return -EINVAL; |
594 | goto out; | ||
595 | } | 597 | } |
596 | 598 | ||
597 | if (nouveau_gem_pushbuf_sync(chan)) { | 599 | if (unlikely(req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS)) { |
598 | ret = nouveau_fence_wait(fence, NULL, false, false); | 600 | NV_ERROR(dev, "pushbuf bo count exceeds limit: %d max %d\n", |
599 | if (ret) { | 601 | req->nr_buffers, NOUVEAU_GEM_MAX_BUFFERS); |
600 | for (i = 0; i < req->nr_dwords; i++) | 602 | return -EINVAL; |
601 | NV_ERROR(dev, "0x%08x\n", pushbuf[i]); | ||
602 | NV_ERROR(dev, "^^ above push buffer is fail :(\n"); | ||
603 | } | ||
604 | } | 603 | } |
605 | 604 | ||
606 | out: | 605 | if (unlikely(req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS)) { |
607 | validate_fini(&op, fence); | 606 | NV_ERROR(dev, "pushbuf reloc count exceeds limit: %d max %d\n", |
608 | nouveau_fence_unref((void**)&fence); | 607 | req->nr_relocs, NOUVEAU_GEM_MAX_RELOCS); |
609 | mutex_unlock(&dev->struct_mutex); | ||
610 | kfree(pushbuf); | ||
611 | kfree(bo); | ||
612 | return ret; | ||
613 | } | ||
614 | |||
615 | #define PUSHBUF_CAL (dev_priv->card_type >= NV_20) | ||
616 | |||
617 | int | ||
618 | nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, | ||
619 | struct drm_file *file_priv) | ||
620 | { | ||
621 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
622 | struct drm_nouveau_gem_pushbuf_call *req = data; | ||
623 | struct drm_nouveau_gem_pushbuf_bo *bo = NULL; | ||
624 | struct nouveau_channel *chan; | ||
625 | struct drm_gem_object *gem; | ||
626 | struct nouveau_bo *pbbo; | ||
627 | struct validate_op op; | ||
628 | struct nouveau_fence* fence = 0; | ||
629 | int i, ret = 0, do_reloc = 0; | ||
630 | |||
631 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
632 | NOUVEAU_GET_USER_CHANNEL_WITH_RETURN(req->channel, file_priv, chan); | ||
633 | |||
634 | if (unlikely(req->handle == 0)) | ||
635 | goto out_next; | ||
636 | |||
637 | if (req->nr_buffers > NOUVEAU_GEM_MAX_BUFFERS || | ||
638 | req->nr_relocs > NOUVEAU_GEM_MAX_RELOCS) { | ||
639 | NV_ERROR(dev, "Pushbuf config exceeds limits:\n"); | ||
640 | NV_ERROR(dev, " buffers: %d max %d\n", req->nr_buffers, | ||
641 | NOUVEAU_GEM_MAX_BUFFERS); | ||
642 | NV_ERROR(dev, " relocs : %d max %d\n", req->nr_relocs, | ||
643 | NOUVEAU_GEM_MAX_RELOCS); | ||
644 | return -EINVAL; | 608 | return -EINVAL; |
645 | } | 609 | } |
646 | 610 | ||
611 | push = u_memcpya(req->push, req->nr_push, sizeof(*push)); | ||
612 | if (IS_ERR(push)) | ||
613 | return PTR_ERR(push); | ||
614 | |||
647 | bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); | 615 | bo = u_memcpya(req->buffers, req->nr_buffers, sizeof(*bo)); |
648 | if (IS_ERR(bo)) | 616 | if (IS_ERR(bo)) { |
617 | kfree(push); | ||
649 | return PTR_ERR(bo); | 618 | return PTR_ERR(bo); |
619 | } | ||
650 | 620 | ||
651 | mutex_lock(&dev->struct_mutex); | 621 | mutex_lock(&dev->struct_mutex); |
652 | 622 | ||
@@ -658,122 +628,84 @@ nouveau_gem_ioctl_pushbuf_call(struct drm_device *dev, void *data, | |||
658 | goto out; | 628 | goto out; |
659 | } | 629 | } |
660 | 630 | ||
661 | /* Validate DMA push buffer */ | ||
662 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); | ||
663 | if (!gem) { | ||
664 | NV_ERROR(dev, "Unknown pb handle 0x%08x\n", req->handle); | ||
665 | ret = -EINVAL; | ||
666 | goto out; | ||
667 | } | ||
668 | pbbo = nouveau_gem_object(gem); | ||
669 | |||
670 | if ((req->offset & 3) || req->nr_dwords < 2 || | ||
671 | (unsigned long)req->offset > (unsigned long)pbbo->bo.mem.size || | ||
672 | (unsigned long)req->nr_dwords > | ||
673 | ((unsigned long)(pbbo->bo.mem.size - req->offset ) >> 2)) { | ||
674 | NV_ERROR(dev, "pb call misaligned or out of bounds: " | ||
675 | "%d + %d * 4 > %ld\n", | ||
676 | req->offset, req->nr_dwords, pbbo->bo.mem.size); | ||
677 | ret = -EINVAL; | ||
678 | drm_gem_object_unreference(gem); | ||
679 | goto out; | ||
680 | } | ||
681 | |||
682 | ret = ttm_bo_reserve(&pbbo->bo, false, false, true, | ||
683 | chan->fence.sequence); | ||
684 | if (ret) { | ||
685 | NV_ERROR(dev, "resv pb: %d\n", ret); | ||
686 | drm_gem_object_unreference(gem); | ||
687 | goto out; | ||
688 | } | ||
689 | |||
690 | nouveau_bo_placement_set(pbbo, 1 << chan->pushbuf_bo->bo.mem.mem_type); | ||
691 | ret = ttm_bo_validate(&pbbo->bo, &pbbo->placement, false, false); | ||
692 | if (ret) { | ||
693 | NV_ERROR(dev, "validate pb: %d\n", ret); | ||
694 | ttm_bo_unreserve(&pbbo->bo); | ||
695 | drm_gem_object_unreference(gem); | ||
696 | goto out; | ||
697 | } | ||
698 | |||
699 | list_add_tail(&pbbo->entry, &op.both_list); | ||
700 | |||
701 | /* If presumed return address doesn't match, we need to map the | ||
702 | * push buffer and fix it.. | ||
703 | */ | ||
704 | if (!PUSHBUF_CAL) { | ||
705 | uint32_t retaddy; | ||
706 | |||
707 | if (chan->dma.free < 4 + NOUVEAU_DMA_SKIPS) { | ||
708 | ret = nouveau_dma_wait(chan, 4 + NOUVEAU_DMA_SKIPS); | ||
709 | if (ret) { | ||
710 | NV_ERROR(dev, "jmp_space: %d\n", ret); | ||
711 | goto out; | ||
712 | } | ||
713 | } | ||
714 | |||
715 | retaddy = chan->pushbuf_base + ((chan->dma.cur + 2) << 2); | ||
716 | retaddy |= 0x20000000; | ||
717 | if (retaddy != req->suffix0) { | ||
718 | req->suffix0 = retaddy; | ||
719 | do_reloc = 1; | ||
720 | } | ||
721 | } | ||
722 | |||
723 | /* Apply any relocations that are required */ | 631 | /* Apply any relocations that are required */ |
724 | if (do_reloc) { | 632 | if (do_reloc) { |
725 | void *pbvirt; | 633 | ret = nouveau_gem_pushbuf_reloc_apply(dev, req, bo); |
726 | bool is_iomem; | ||
727 | ret = ttm_bo_kmap(&pbbo->bo, 0, pbbo->bo.mem.num_pages, | ||
728 | &pbbo->kmap); | ||
729 | if (ret) { | 634 | if (ret) { |
730 | NV_ERROR(dev, "kmap pb: %d\n", ret); | 635 | NV_ERROR(dev, "reloc apply: %d\n", ret); |
731 | goto out; | 636 | goto out; |
732 | } | 637 | } |
638 | } | ||
733 | 639 | ||
734 | pbvirt = ttm_kmap_obj_virtual(&pbbo->kmap, &is_iomem); | 640 | if (chan->dma.ib_max) { |
735 | ret = nouveau_gem_pushbuf_reloc_apply(chan, req->nr_buffers, bo, | 641 | ret = nouveau_dma_wait(chan, req->nr_push + 1, 6); |
736 | req->nr_relocs, | ||
737 | req->relocs, | ||
738 | req->nr_dwords, | ||
739 | req->offset / 4, | ||
740 | pbvirt, is_iomem); | ||
741 | |||
742 | if (!PUSHBUF_CAL) { | ||
743 | nouveau_bo_wr32(pbbo, | ||
744 | req->offset / 4 + req->nr_dwords - 2, | ||
745 | req->suffix0); | ||
746 | } | ||
747 | |||
748 | ttm_bo_kunmap(&pbbo->kmap); | ||
749 | if (ret) { | 642 | if (ret) { |
750 | NV_ERROR(dev, "reloc apply: %d\n", ret); | 643 | NV_INFO(dev, "nv50cal_space: %d\n", ret); |
751 | goto out; | 644 | goto out; |
752 | } | 645 | } |
753 | } | ||
754 | 646 | ||
755 | if (PUSHBUF_CAL) { | 647 | for (i = 0; i < req->nr_push; i++) { |
756 | ret = RING_SPACE(chan, 2); | 648 | struct nouveau_bo *nvbo = (void *)(unsigned long) |
649 | bo[push[i].bo_index].user_priv; | ||
650 | |||
651 | nv50_dma_push(chan, nvbo, push[i].offset, | ||
652 | push[i].length); | ||
653 | } | ||
654 | } else | ||
655 | if (dev_priv->card_type >= NV_20) { | ||
656 | ret = RING_SPACE(chan, req->nr_push * 2); | ||
757 | if (ret) { | 657 | if (ret) { |
758 | NV_ERROR(dev, "cal_space: %d\n", ret); | 658 | NV_ERROR(dev, "cal_space: %d\n", ret); |
759 | goto out; | 659 | goto out; |
760 | } | 660 | } |
761 | OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) + | 661 | |
762 | req->offset) | 2); | 662 | for (i = 0; i < req->nr_push; i++) { |
763 | OUT_RING(chan, 0); | 663 | struct nouveau_bo *nvbo = (void *)(unsigned long) |
664 | bo[push[i].bo_index].user_priv; | ||
665 | struct drm_mm_node *mem = nvbo->bo.mem.mm_node; | ||
666 | |||
667 | OUT_RING(chan, ((mem->start << PAGE_SHIFT) + | ||
668 | push[i].offset) | 2); | ||
669 | OUT_RING(chan, 0); | ||
670 | } | ||
764 | } else { | 671 | } else { |
765 | ret = RING_SPACE(chan, 2 + NOUVEAU_DMA_SKIPS); | 672 | ret = RING_SPACE(chan, req->nr_push * (2 + NOUVEAU_DMA_SKIPS)); |
766 | if (ret) { | 673 | if (ret) { |
767 | NV_ERROR(dev, "jmp_space: %d\n", ret); | 674 | NV_ERROR(dev, "jmp_space: %d\n", ret); |
768 | goto out; | 675 | goto out; |
769 | } | 676 | } |
770 | OUT_RING(chan, ((pbbo->bo.mem.mm_node->start << PAGE_SHIFT) + | ||
771 | req->offset) | 0x20000000); | ||
772 | OUT_RING(chan, 0); | ||
773 | 677 | ||
774 | /* Space the jumps apart with NOPs. */ | 678 | for (i = 0; i < req->nr_push; i++) { |
775 | for (i = 0; i < NOUVEAU_DMA_SKIPS; i++) | 679 | struct nouveau_bo *nvbo = (void *)(unsigned long) |
680 | bo[push[i].bo_index].user_priv; | ||
681 | struct drm_mm_node *mem = nvbo->bo.mem.mm_node; | ||
682 | uint32_t cmd; | ||
683 | |||
684 | cmd = chan->pushbuf_base + ((chan->dma.cur + 2) << 2); | ||
685 | cmd |= 0x20000000; | ||
686 | if (unlikely(cmd != req->suffix0)) { | ||
687 | if (!nvbo->kmap.virtual) { | ||
688 | ret = ttm_bo_kmap(&nvbo->bo, 0, | ||
689 | nvbo->bo.mem. | ||
690 | num_pages, | ||
691 | &nvbo->kmap); | ||
692 | if (ret) { | ||
693 | WIND_RING(chan); | ||
694 | goto out; | ||
695 | } | ||
696 | nvbo->validate_mapped = true; | ||
697 | } | ||
698 | |||
699 | nouveau_bo_wr32(nvbo, (push[i].offset + | ||
700 | push[i].length - 8) / 4, cmd); | ||
701 | } | ||
702 | |||
703 | OUT_RING(chan, ((mem->start << PAGE_SHIFT) + | ||
704 | push[i].offset) | 0x20000000); | ||
776 | OUT_RING(chan, 0); | 705 | OUT_RING(chan, 0); |
706 | for (j = 0; j < NOUVEAU_DMA_SKIPS; j++) | ||
707 | OUT_RING(chan, 0); | ||
708 | } | ||
777 | } | 709 | } |
778 | 710 | ||
779 | ret = nouveau_fence_new(chan, &fence, true); | 711 | ret = nouveau_fence_new(chan, &fence, true); |
@@ -788,9 +720,14 @@ out: | |||
788 | nouveau_fence_unref((void**)&fence); | 720 | nouveau_fence_unref((void**)&fence); |
789 | mutex_unlock(&dev->struct_mutex); | 721 | mutex_unlock(&dev->struct_mutex); |
790 | kfree(bo); | 722 | kfree(bo); |
723 | kfree(push); | ||
791 | 724 | ||
792 | out_next: | 725 | out_next: |
793 | if (PUSHBUF_CAL) { | 726 | if (chan->dma.ib_max) { |
727 | req->suffix0 = 0x00000000; | ||
728 | req->suffix1 = 0x00000000; | ||
729 | } else | ||
730 | if (dev_priv->card_type >= NV_20) { | ||
794 | req->suffix0 = 0x00020000; | 731 | req->suffix0 = 0x00020000; |
795 | req->suffix1 = 0x00000000; | 732 | req->suffix1 = 0x00000000; |
796 | } else { | 733 | } else { |
@@ -802,19 +739,6 @@ out_next: | |||
802 | return ret; | 739 | return ret; |
803 | } | 740 | } |
804 | 741 | ||
805 | int | ||
806 | nouveau_gem_ioctl_pushbuf_call2(struct drm_device *dev, void *data, | ||
807 | struct drm_file *file_priv) | ||
808 | { | ||
809 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
810 | struct drm_nouveau_gem_pushbuf_call *req = data; | ||
811 | |||
812 | req->vram_available = dev_priv->fb_aper_free; | ||
813 | req->gart_available = dev_priv->gart_info.aper_free; | ||
814 | |||
815 | return nouveau_gem_ioctl_pushbuf_call(dev, data, file_priv); | ||
816 | } | ||
817 | |||
818 | static inline uint32_t | 742 | static inline uint32_t |
819 | domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain) | 743 | domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain) |
820 | { | 744 | { |
@@ -829,70 +753,6 @@ domain_to_ttm(struct nouveau_bo *nvbo, uint32_t domain) | |||
829 | } | 753 | } |
830 | 754 | ||
831 | int | 755 | int |
832 | nouveau_gem_ioctl_pin(struct drm_device *dev, void *data, | ||
833 | struct drm_file *file_priv) | ||
834 | { | ||
835 | struct drm_nouveau_gem_pin *req = data; | ||
836 | struct drm_gem_object *gem; | ||
837 | struct nouveau_bo *nvbo; | ||
838 | int ret = 0; | ||
839 | |||
840 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
841 | |||
842 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | ||
843 | NV_ERROR(dev, "pin only allowed without kernel modesetting\n"); | ||
844 | return -EINVAL; | ||
845 | } | ||
846 | |||
847 | if (!DRM_SUSER(DRM_CURPROC)) | ||
848 | return -EPERM; | ||
849 | |||
850 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); | ||
851 | if (!gem) | ||
852 | return -EINVAL; | ||
853 | nvbo = nouveau_gem_object(gem); | ||
854 | |||
855 | ret = nouveau_bo_pin(nvbo, domain_to_ttm(nvbo, req->domain)); | ||
856 | if (ret) | ||
857 | goto out; | ||
858 | |||
859 | req->offset = nvbo->bo.offset; | ||
860 | if (nvbo->bo.mem.mem_type == TTM_PL_TT) | ||
861 | req->domain = NOUVEAU_GEM_DOMAIN_GART; | ||
862 | else | ||
863 | req->domain = NOUVEAU_GEM_DOMAIN_VRAM; | ||
864 | |||
865 | out: | ||
866 | drm_gem_object_unreference_unlocked(gem); | ||
867 | |||
868 | return ret; | ||
869 | } | ||
870 | |||
871 | int | ||
872 | nouveau_gem_ioctl_unpin(struct drm_device *dev, void *data, | ||
873 | struct drm_file *file_priv) | ||
874 | { | ||
875 | struct drm_nouveau_gem_pin *req = data; | ||
876 | struct drm_gem_object *gem; | ||
877 | int ret; | ||
878 | |||
879 | NOUVEAU_CHECK_INITIALISED_WITH_RETURN; | ||
880 | |||
881 | if (drm_core_check_feature(dev, DRIVER_MODESET)) | ||
882 | return -EINVAL; | ||
883 | |||
884 | gem = drm_gem_object_lookup(dev, file_priv, req->handle); | ||
885 | if (!gem) | ||
886 | return -EINVAL; | ||
887 | |||
888 | ret = nouveau_bo_unpin(nouveau_gem_object(gem)); | ||
889 | |||
890 | drm_gem_object_unreference_unlocked(gem); | ||
891 | |||
892 | return ret; | ||
893 | } | ||
894 | |||
895 | int | ||
896 | nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, | 756 | nouveau_gem_ioctl_cpu_prep(struct drm_device *dev, void *data, |
897 | struct drm_file *file_priv) | 757 | struct drm_file *file_priv) |
898 | { | 758 | { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c index dc46792a5c96..7855b35effc3 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/nouveau_hw.c | |||
@@ -160,7 +160,7 @@ static void | |||
160 | setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv) | 160 | setPLL_single(struct drm_device *dev, uint32_t reg, struct nouveau_pll_vals *pv) |
161 | { | 161 | { |
162 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 162 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
163 | int chip_version = dev_priv->vbios->chip_version; | 163 | int chip_version = dev_priv->vbios.chip_version; |
164 | uint32_t oldpll = NVReadRAMDAC(dev, 0, reg); | 164 | uint32_t oldpll = NVReadRAMDAC(dev, 0, reg); |
165 | int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff; | 165 | int oldN = (oldpll >> 8) & 0xff, oldM = oldpll & 0xff; |
166 | uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1; | 166 | uint32_t pll = (oldpll & 0xfff80000) | pv->log2P << 16 | pv->NM1; |
@@ -216,7 +216,7 @@ setPLL_double_highregs(struct drm_device *dev, uint32_t reg1, | |||
216 | struct nouveau_pll_vals *pv) | 216 | struct nouveau_pll_vals *pv) |
217 | { | 217 | { |
218 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 218 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
219 | int chip_version = dev_priv->vbios->chip_version; | 219 | int chip_version = dev_priv->vbios.chip_version; |
220 | bool nv3035 = chip_version == 0x30 || chip_version == 0x35; | 220 | bool nv3035 = chip_version == 0x30 || chip_version == 0x35; |
221 | uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70); | 221 | uint32_t reg2 = reg1 + ((reg1 == NV_RAMDAC_VPLL2) ? 0x5c : 0x70); |
222 | uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1); | 222 | uint32_t oldpll1 = NVReadRAMDAC(dev, 0, reg1); |
@@ -374,7 +374,7 @@ nouveau_hw_setpll(struct drm_device *dev, uint32_t reg1, | |||
374 | struct nouveau_pll_vals *pv) | 374 | struct nouveau_pll_vals *pv) |
375 | { | 375 | { |
376 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 376 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
377 | int cv = dev_priv->vbios->chip_version; | 377 | int cv = dev_priv->vbios.chip_version; |
378 | 378 | ||
379 | if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 || | 379 | if (cv == 0x30 || cv == 0x31 || cv == 0x35 || cv == 0x36 || |
380 | cv >= 0x40) { | 380 | cv >= 0x40) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index 70e994d28122..88583e7bf651 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
@@ -254,16 +254,16 @@ struct nouveau_i2c_chan * | |||
254 | nouveau_i2c_find(struct drm_device *dev, int index) | 254 | nouveau_i2c_find(struct drm_device *dev, int index) |
255 | { | 255 | { |
256 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 256 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
257 | struct nvbios *bios = &dev_priv->VBIOS; | 257 | struct nvbios *bios = &dev_priv->vbios; |
258 | 258 | ||
259 | if (index > DCB_MAX_NUM_I2C_ENTRIES) | 259 | if (index >= DCB_MAX_NUM_I2C_ENTRIES) |
260 | return NULL; | 260 | return NULL; |
261 | 261 | ||
262 | if (!bios->bdcb.dcb.i2c[index].chan) { | 262 | if (!bios->dcb.i2c[index].chan) { |
263 | if (nouveau_i2c_init(dev, &bios->bdcb.dcb.i2c[index], index)) | 263 | if (nouveau_i2c_init(dev, &bios->dcb.i2c[index], index)) |
264 | return NULL; | 264 | return NULL; |
265 | } | 265 | } |
266 | 266 | ||
267 | return bios->bdcb.dcb.i2c[index].chan; | 267 | return bios->dcb.i2c[index].chan; |
268 | } | 268 | } |
269 | 269 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 447f9f69d6b1..95220ddebb45 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
@@ -691,11 +691,14 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
691 | struct drm_device *dev = (struct drm_device *)arg; | 691 | struct drm_device *dev = (struct drm_device *)arg; |
692 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 692 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
693 | uint32_t status, fbdev_flags = 0; | 693 | uint32_t status, fbdev_flags = 0; |
694 | unsigned long flags; | ||
694 | 695 | ||
695 | status = nv_rd32(dev, NV03_PMC_INTR_0); | 696 | status = nv_rd32(dev, NV03_PMC_INTR_0); |
696 | if (!status) | 697 | if (!status) |
697 | return IRQ_NONE; | 698 | return IRQ_NONE; |
698 | 699 | ||
700 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
701 | |||
699 | if (dev_priv->fbdev_info) { | 702 | if (dev_priv->fbdev_info) { |
700 | fbdev_flags = dev_priv->fbdev_info->flags; | 703 | fbdev_flags = dev_priv->fbdev_info->flags; |
701 | dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; | 704 | dev_priv->fbdev_info->flags |= FBINFO_HWACCEL_DISABLED; |
@@ -733,5 +736,7 @@ nouveau_irq_handler(DRM_IRQ_ARGS) | |||
733 | if (dev_priv->fbdev_info) | 736 | if (dev_priv->fbdev_info) |
734 | dev_priv->fbdev_info->flags = fbdev_flags; | 737 | dev_priv->fbdev_info->flags = fbdev_flags; |
735 | 738 | ||
739 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
740 | |||
736 | return IRQ_HANDLED; | 741 | return IRQ_HANDLED; |
737 | } | 742 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index a4851af5b05e..516a8d36cb10 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
@@ -391,6 +391,7 @@ nouveau_card_init(struct drm_device *dev) | |||
391 | goto out; | 391 | goto out; |
392 | engine = &dev_priv->engine; | 392 | engine = &dev_priv->engine; |
393 | dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; | 393 | dev_priv->init_state = NOUVEAU_CARD_INIT_FAILED; |
394 | spin_lock_init(&dev_priv->context_switch_lock); | ||
394 | 395 | ||
395 | /* Parse BIOS tables / Run init tables if card not POSTed */ | 396 | /* Parse BIOS tables / Run init tables if card not POSTed */ |
396 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { | 397 | if (drm_core_check_feature(dev, DRIVER_MODESET)) { |
@@ -776,13 +777,6 @@ int nouveau_unload(struct drm_device *dev) | |||
776 | return 0; | 777 | return 0; |
777 | } | 778 | } |
778 | 779 | ||
779 | int | ||
780 | nouveau_ioctl_card_init(struct drm_device *dev, void *data, | ||
781 | struct drm_file *file_priv) | ||
782 | { | ||
783 | return nouveau_card_init(dev); | ||
784 | } | ||
785 | |||
786 | int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | 780 | int nouveau_ioctl_getparam(struct drm_device *dev, void *data, |
787 | struct drm_file *file_priv) | 781 | struct drm_file *file_priv) |
788 | { | 782 | { |
diff --git a/drivers/gpu/drm/nouveau/nv04_dac.c b/drivers/gpu/drm/nouveau/nv04_dac.c index 1d73b15d70da..1cb19e3acb55 100644 --- a/drivers/gpu/drm/nouveau/nv04_dac.c +++ b/drivers/gpu/drm/nouveau/nv04_dac.c | |||
@@ -230,13 +230,13 @@ uint32_t nv17_dac_sample_load(struct drm_encoder *encoder) | |||
230 | if (dcb->type == OUTPUT_TV) { | 230 | if (dcb->type == OUTPUT_TV) { |
231 | testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0); | 231 | testval = RGB_TEST_DATA(0xa0, 0xa0, 0xa0); |
232 | 232 | ||
233 | if (dev_priv->vbios->tvdactestval) | 233 | if (dev_priv->vbios.tvdactestval) |
234 | testval = dev_priv->vbios->tvdactestval; | 234 | testval = dev_priv->vbios.tvdactestval; |
235 | } else { | 235 | } else { |
236 | testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */ | 236 | testval = RGB_TEST_DATA(0x140, 0x140, 0x140); /* 0x94050140 */ |
237 | 237 | ||
238 | if (dev_priv->vbios->dactestval) | 238 | if (dev_priv->vbios.dactestval) |
239 | testval = dev_priv->vbios->dactestval; | 239 | testval = dev_priv->vbios.dactestval; |
240 | } | 240 | } |
241 | 241 | ||
242 | saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); | 242 | saved_rtest_ctrl = NVReadRAMDAC(dev, 0, NV_PRAMDAC_TEST_CONTROL + regoffset); |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index 483f875bdb6a..41634d4752fe 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
@@ -269,10 +269,10 @@ static void nv04_dfp_mode_set(struct drm_encoder *encoder, | |||
269 | regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1; | 269 | regp->fp_horiz_regs[FP_TOTAL] = output_mode->htotal - 1; |
270 | if (!nv_gf4_disp_arch(dev) || | 270 | if (!nv_gf4_disp_arch(dev) || |
271 | (output_mode->hsync_start - output_mode->hdisplay) >= | 271 | (output_mode->hsync_start - output_mode->hdisplay) >= |
272 | dev_priv->vbios->digital_min_front_porch) | 272 | dev_priv->vbios.digital_min_front_porch) |
273 | regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay; | 273 | regp->fp_horiz_regs[FP_CRTC] = output_mode->hdisplay; |
274 | else | 274 | else |
275 | regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios->digital_min_front_porch - 1; | 275 | regp->fp_horiz_regs[FP_CRTC] = output_mode->hsync_start - dev_priv->vbios.digital_min_front_porch - 1; |
276 | regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1; | 276 | regp->fp_horiz_regs[FP_SYNC_START] = output_mode->hsync_start - 1; |
277 | regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1; | 277 | regp->fp_horiz_regs[FP_SYNC_END] = output_mode->hsync_end - 1; |
278 | regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew; | 278 | regp->fp_horiz_regs[FP_VALID_START] = output_mode->hskew; |
diff --git a/drivers/gpu/drm/nouveau/nv04_display.c b/drivers/gpu/drm/nouveau/nv04_display.c index ef77215fa5b9..c7898b4f6dfb 100644 --- a/drivers/gpu/drm/nouveau/nv04_display.c +++ b/drivers/gpu/drm/nouveau/nv04_display.c | |||
@@ -93,10 +93,9 @@ int | |||
93 | nv04_display_create(struct drm_device *dev) | 93 | nv04_display_create(struct drm_device *dev) |
94 | { | 94 | { |
95 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 95 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
96 | struct parsed_dcb *dcb = dev_priv->vbios->dcb; | 96 | struct dcb_table *dcb = &dev_priv->vbios.dcb; |
97 | struct drm_encoder *encoder; | 97 | struct drm_encoder *encoder; |
98 | struct drm_crtc *crtc; | 98 | struct drm_crtc *crtc; |
99 | uint16_t connector[16] = { 0 }; | ||
100 | int i, ret; | 99 | int i, ret; |
101 | 100 | ||
102 | NV_DEBUG_KMS(dev, "\n"); | 101 | NV_DEBUG_KMS(dev, "\n"); |
@@ -154,52 +153,10 @@ nv04_display_create(struct drm_device *dev) | |||
154 | 153 | ||
155 | if (ret) | 154 | if (ret) |
156 | continue; | 155 | continue; |
157 | |||
158 | connector[dcbent->connector] |= (1 << dcbent->type); | ||
159 | } | 156 | } |
160 | 157 | ||
161 | for (i = 0; i < dcb->entries; i++) { | 158 | for (i = 0; i < dcb->connector.entries; i++) |
162 | struct dcb_entry *dcbent = &dcb->entry[i]; | 159 | nouveau_connector_create(dev, &dcb->connector.entry[i]); |
163 | uint16_t encoders; | ||
164 | int type; | ||
165 | |||
166 | encoders = connector[dcbent->connector]; | ||
167 | if (!(encoders & (1 << dcbent->type))) | ||
168 | continue; | ||
169 | connector[dcbent->connector] = 0; | ||
170 | |||
171 | switch (dcbent->type) { | ||
172 | case OUTPUT_ANALOG: | ||
173 | if (!MULTIPLE_ENCODERS(encoders)) | ||
174 | type = DRM_MODE_CONNECTOR_VGA; | ||
175 | else | ||
176 | type = DRM_MODE_CONNECTOR_DVII; | ||
177 | break; | ||
178 | case OUTPUT_TMDS: | ||
179 | if (!MULTIPLE_ENCODERS(encoders)) | ||
180 | type = DRM_MODE_CONNECTOR_DVID; | ||
181 | else | ||
182 | type = DRM_MODE_CONNECTOR_DVII; | ||
183 | break; | ||
184 | case OUTPUT_LVDS: | ||
185 | type = DRM_MODE_CONNECTOR_LVDS; | ||
186 | #if 0 | ||
187 | /* don't create i2c adapter when lvds ddc not allowed */ | ||
188 | if (dcbent->lvdsconf.use_straps_for_mode || | ||
189 | dev_priv->vbios->fp_no_ddc) | ||
190 | i2c_index = 0xf; | ||
191 | #endif | ||
192 | break; | ||
193 | case OUTPUT_TV: | ||
194 | type = DRM_MODE_CONNECTOR_TV; | ||
195 | break; | ||
196 | default: | ||
197 | type = DRM_MODE_CONNECTOR_Unknown; | ||
198 | continue; | ||
199 | } | ||
200 | |||
201 | nouveau_connector_create(dev, dcbent->connector, type); | ||
202 | } | ||
203 | 160 | ||
204 | /* Save previous state */ | 161 | /* Save previous state */ |
205 | NVLockVgaCrtcs(dev, false); | 162 | NVLockVgaCrtcs(dev, false); |
diff --git a/drivers/gpu/drm/nouveau/nv04_fbcon.c b/drivers/gpu/drm/nouveau/nv04_fbcon.c index fd01caabd5c3..3da90c2c4e63 100644 --- a/drivers/gpu/drm/nouveau/nv04_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv04_fbcon.c | |||
@@ -118,7 +118,7 @@ nv04_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
118 | return; | 118 | return; |
119 | } | 119 | } |
120 | 120 | ||
121 | width = (image->width + 31) & ~31; | 121 | width = ALIGN(image->width, 32); |
122 | dsize = (width * image->height) >> 5; | 122 | dsize = (width * image->height) >> 5; |
123 | 123 | ||
124 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || | 124 | if (info->fix.visual == FB_VISUAL_TRUECOLOR || |
diff --git a/drivers/gpu/drm/nouveau/nv04_fifo.c b/drivers/gpu/drm/nouveau/nv04_fifo.c index f31347b8c9b0..66fe55983b6e 100644 --- a/drivers/gpu/drm/nouveau/nv04_fifo.c +++ b/drivers/gpu/drm/nouveau/nv04_fifo.c | |||
@@ -117,6 +117,7 @@ nv04_fifo_create_context(struct nouveau_channel *chan) | |||
117 | { | 117 | { |
118 | struct drm_device *dev = chan->dev; | 118 | struct drm_device *dev = chan->dev; |
119 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 119 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
120 | unsigned long flags; | ||
120 | int ret; | 121 | int ret; |
121 | 122 | ||
122 | ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, | 123 | ret = nouveau_gpuobj_new_fake(dev, NV04_RAMFC(chan->id), ~0, |
@@ -127,6 +128,8 @@ nv04_fifo_create_context(struct nouveau_channel *chan) | |||
127 | if (ret) | 128 | if (ret) |
128 | return ret; | 129 | return ret; |
129 | 130 | ||
131 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
132 | |||
130 | /* Setup initial state */ | 133 | /* Setup initial state */ |
131 | dev_priv->engine.instmem.prepare_access(dev, true); | 134 | dev_priv->engine.instmem.prepare_access(dev, true); |
132 | RAMFC_WR(DMA_PUT, chan->pushbuf_base); | 135 | RAMFC_WR(DMA_PUT, chan->pushbuf_base); |
@@ -144,6 +147,8 @@ nv04_fifo_create_context(struct nouveau_channel *chan) | |||
144 | /* enable the fifo dma operation */ | 147 | /* enable the fifo dma operation */ |
145 | nv_wr32(dev, NV04_PFIFO_MODE, | 148 | nv_wr32(dev, NV04_PFIFO_MODE, |
146 | nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); | 149 | nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); |
150 | |||
151 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
147 | return 0; | 152 | return 0; |
148 | } | 153 | } |
149 | 154 | ||
diff --git a/drivers/gpu/drm/nouveau/nv04_tv.c b/drivers/gpu/drm/nouveau/nv04_tv.c index 9c63099e9c42..c4e3404337d4 100644 --- a/drivers/gpu/drm/nouveau/nv04_tv.c +++ b/drivers/gpu/drm/nouveau/nv04_tv.c | |||
@@ -262,7 +262,7 @@ int nv04_tv_create(struct drm_device *dev, struct dcb_entry *entry) | |||
262 | nv_encoder->or = ffs(entry->or) - 1; | 262 | nv_encoder->or = ffs(entry->or) - 1; |
263 | 263 | ||
264 | /* Run the slave-specific initialization */ | 264 | /* Run the slave-specific initialization */ |
265 | adap = &dev_priv->vbios->dcb->i2c[i2c_index].chan->adapter; | 265 | adap = &dev_priv->vbios.dcb.i2c[i2c_index].chan->adapter; |
266 | 266 | ||
267 | was_locked = NVLockVgaCrtcs(dev, false); | 267 | was_locked = NVLockVgaCrtcs(dev, false); |
268 | 268 | ||
diff --git a/drivers/gpu/drm/nouveau/nv17_tv.c b/drivers/gpu/drm/nouveau/nv17_tv.c index 21ac6e49b6ee..74c880374fb9 100644 --- a/drivers/gpu/drm/nouveau/nv17_tv.c +++ b/drivers/gpu/drm/nouveau/nv17_tv.c | |||
@@ -45,8 +45,8 @@ static uint32_t nv42_tv_sample_load(struct drm_encoder *encoder) | |||
45 | 45 | ||
46 | #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) | 46 | #define RGB_TEST_DATA(r, g, b) (r << 0 | g << 10 | b << 20) |
47 | testval = RGB_TEST_DATA(0x82, 0xeb, 0x82); | 47 | testval = RGB_TEST_DATA(0x82, 0xeb, 0x82); |
48 | if (dev_priv->vbios->tvdactestval) | 48 | if (dev_priv->vbios.tvdactestval) |
49 | testval = dev_priv->vbios->tvdactestval; | 49 | testval = dev_priv->vbios.tvdactestval; |
50 | 50 | ||
51 | dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); | 51 | dacclk = NVReadRAMDAC(dev, 0, NV_PRAMDAC_DACCLK + regoffset); |
52 | head = (dacclk & 0x100) >> 8; | 52 | head = (dacclk & 0x100) >> 8; |
@@ -367,7 +367,7 @@ static void nv17_tv_prepare(struct drm_encoder *encoder) | |||
367 | !enc->crtc && | 367 | !enc->crtc && |
368 | nv04_dfp_get_bound_head(dev, dcb) == head) { | 368 | nv04_dfp_get_bound_head(dev, dcb) == head) { |
369 | nv04_dfp_bind_head(dev, dcb, head ^ 1, | 369 | nv04_dfp_bind_head(dev, dcb, head ^ 1, |
370 | dev_priv->VBIOS.fp.dual_link); | 370 | dev_priv->vbios.fp.dual_link); |
371 | } | 371 | } |
372 | } | 372 | } |
373 | 373 | ||
diff --git a/drivers/gpu/drm/nouveau/nv40_fifo.c b/drivers/gpu/drm/nouveau/nv40_fifo.c index b4f19ccb8b41..6b2ef4a9fce1 100644 --- a/drivers/gpu/drm/nouveau/nv40_fifo.c +++ b/drivers/gpu/drm/nouveau/nv40_fifo.c | |||
@@ -37,6 +37,7 @@ nv40_fifo_create_context(struct nouveau_channel *chan) | |||
37 | struct drm_device *dev = chan->dev; | 37 | struct drm_device *dev = chan->dev; |
38 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 38 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
39 | uint32_t fc = NV40_RAMFC(chan->id); | 39 | uint32_t fc = NV40_RAMFC(chan->id); |
40 | unsigned long flags; | ||
40 | int ret; | 41 | int ret; |
41 | 42 | ||
42 | ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, | 43 | ret = nouveau_gpuobj_new_fake(dev, NV40_RAMFC(chan->id), ~0, |
@@ -45,6 +46,8 @@ nv40_fifo_create_context(struct nouveau_channel *chan) | |||
45 | if (ret) | 46 | if (ret) |
46 | return ret; | 47 | return ret; |
47 | 48 | ||
49 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
50 | |||
48 | dev_priv->engine.instmem.prepare_access(dev, true); | 51 | dev_priv->engine.instmem.prepare_access(dev, true); |
49 | nv_wi32(dev, fc + 0, chan->pushbuf_base); | 52 | nv_wi32(dev, fc + 0, chan->pushbuf_base); |
50 | nv_wi32(dev, fc + 4, chan->pushbuf_base); | 53 | nv_wi32(dev, fc + 4, chan->pushbuf_base); |
@@ -63,6 +66,8 @@ nv40_fifo_create_context(struct nouveau_channel *chan) | |||
63 | /* enable the fifo dma operation */ | 66 | /* enable the fifo dma operation */ |
64 | nv_wr32(dev, NV04_PFIFO_MODE, | 67 | nv_wr32(dev, NV04_PFIFO_MODE, |
65 | nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); | 68 | nv_rd32(dev, NV04_PFIFO_MODE) | (1 << chan->id)); |
69 | |||
70 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
66 | return 0; | 71 | return 0; |
67 | } | 72 | } |
68 | 73 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index f08f042a8e10..1fd9537beff6 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c | |||
@@ -79,8 +79,8 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
79 | } | 79 | } |
80 | 80 | ||
81 | /* Use bios provided value if possible. */ | 81 | /* Use bios provided value if possible. */ |
82 | if (dev_priv->vbios->dactestval) { | 82 | if (dev_priv->vbios.dactestval) { |
83 | load_pattern = dev_priv->vbios->dactestval; | 83 | load_pattern = dev_priv->vbios.dactestval; |
84 | NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n", | 84 | NV_DEBUG_KMS(dev, "Using bios provided load_pattern of %d\n", |
85 | load_pattern); | 85 | load_pattern); |
86 | } else { | 86 | } else { |
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 90f0bf59fbcd..61a89f2dc553 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
@@ -370,9 +370,7 @@ nv50_display_init(struct drm_device *dev) | |||
370 | struct nouveau_connector *conn = nouveau_connector(connector); | 370 | struct nouveau_connector *conn = nouveau_connector(connector); |
371 | struct dcb_gpio_entry *gpio; | 371 | struct dcb_gpio_entry *gpio; |
372 | 372 | ||
373 | if (connector->connector_type != DRM_MODE_CONNECTOR_DVII && | 373 | if (conn->dcb->gpio_tag == 0xff) |
374 | connector->connector_type != DRM_MODE_CONNECTOR_DVID && | ||
375 | connector->connector_type != DRM_MODE_CONNECTOR_DisplayPort) | ||
376 | continue; | 374 | continue; |
377 | 375 | ||
378 | gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag); | 376 | gpio = nouveau_bios_gpio_entry(dev, conn->dcb->gpio_tag); |
@@ -465,8 +463,7 @@ static int nv50_display_disable(struct drm_device *dev) | |||
465 | int nv50_display_create(struct drm_device *dev) | 463 | int nv50_display_create(struct drm_device *dev) |
466 | { | 464 | { |
467 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 465 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
468 | struct parsed_dcb *dcb = dev_priv->vbios->dcb; | 466 | struct dcb_table *dcb = &dev_priv->vbios.dcb; |
469 | uint32_t connector[16] = {}; | ||
470 | int ret, i; | 467 | int ret, i; |
471 | 468 | ||
472 | NV_DEBUG_KMS(dev, "\n"); | 469 | NV_DEBUG_KMS(dev, "\n"); |
@@ -522,44 +519,13 @@ int nv50_display_create(struct drm_device *dev) | |||
522 | NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); | 519 | NV_WARN(dev, "DCB encoder %d unknown\n", entry->type); |
523 | continue; | 520 | continue; |
524 | } | 521 | } |
525 | |||
526 | connector[entry->connector] |= (1 << entry->type); | ||
527 | } | 522 | } |
528 | 523 | ||
529 | /* It appears that DCB 3.0+ VBIOS has a connector table, however, | 524 | for (i = 0 ; i < dcb->connector.entries; i++) { |
530 | * I'm not 100% certain how to decode it correctly yet so just | 525 | if (i != 0 && dcb->connector.entry[i].index == |
531 | * look at what encoders are present on each connector index and | 526 | dcb->connector.entry[i - 1].index) |
532 | * attempt to derive the connector type from that. | ||
533 | */ | ||
534 | for (i = 0 ; i < dcb->entries; i++) { | ||
535 | struct dcb_entry *entry = &dcb->entry[i]; | ||
536 | uint16_t encoders; | ||
537 | int type; | ||
538 | |||
539 | encoders = connector[entry->connector]; | ||
540 | if (!(encoders & (1 << entry->type))) | ||
541 | continue; | 527 | continue; |
542 | connector[entry->connector] = 0; | 528 | nouveau_connector_create(dev, &dcb->connector.entry[i]); |
543 | |||
544 | if (encoders & (1 << OUTPUT_DP)) { | ||
545 | type = DRM_MODE_CONNECTOR_DisplayPort; | ||
546 | } else if (encoders & (1 << OUTPUT_TMDS)) { | ||
547 | if (encoders & (1 << OUTPUT_ANALOG)) | ||
548 | type = DRM_MODE_CONNECTOR_DVII; | ||
549 | else | ||
550 | type = DRM_MODE_CONNECTOR_DVID; | ||
551 | } else if (encoders & (1 << OUTPUT_ANALOG)) { | ||
552 | type = DRM_MODE_CONNECTOR_VGA; | ||
553 | } else if (encoders & (1 << OUTPUT_LVDS)) { | ||
554 | type = DRM_MODE_CONNECTOR_LVDS; | ||
555 | } else { | ||
556 | type = DRM_MODE_CONNECTOR_Unknown; | ||
557 | } | ||
558 | |||
559 | if (type == DRM_MODE_CONNECTOR_Unknown) | ||
560 | continue; | ||
561 | |||
562 | nouveau_connector_create(dev, entry->connector, type); | ||
563 | } | 529 | } |
564 | 530 | ||
565 | ret = nv50_display_init(dev); | 531 | ret = nv50_display_init(dev); |
@@ -667,8 +633,8 @@ nv50_display_irq_head(struct drm_device *dev, int *phead, | |||
667 | return -1; | 633 | return -1; |
668 | } | 634 | } |
669 | 635 | ||
670 | for (i = 0; i < dev_priv->vbios->dcb->entries; i++) { | 636 | for (i = 0; i < dev_priv->vbios.dcb.entries; i++) { |
671 | struct dcb_entry *dcbent = &dev_priv->vbios->dcb->entry[i]; | 637 | struct dcb_entry *dcbent = &dev_priv->vbios.dcb.entry[i]; |
672 | 638 | ||
673 | if (dcbent->type != type) | 639 | if (dcbent->type != type) |
674 | continue; | 640 | continue; |
@@ -692,7 +658,7 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, | |||
692 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 658 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
693 | struct nouveau_connector *nv_connector = NULL; | 659 | struct nouveau_connector *nv_connector = NULL; |
694 | struct drm_encoder *encoder; | 660 | struct drm_encoder *encoder; |
695 | struct nvbios *bios = &dev_priv->VBIOS; | 661 | struct nvbios *bios = &dev_priv->vbios; |
696 | uint32_t mc, script = 0, or; | 662 | uint32_t mc, script = 0, or; |
697 | 663 | ||
698 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { | 664 | list_for_each_entry(encoder, &dev->mode_config.encoder_list, head) { |
@@ -710,7 +676,7 @@ nv50_display_script_select(struct drm_device *dev, struct dcb_entry *dcbent, | |||
710 | switch (dcbent->type) { | 676 | switch (dcbent->type) { |
711 | case OUTPUT_LVDS: | 677 | case OUTPUT_LVDS: |
712 | script = (mc >> 8) & 0xf; | 678 | script = (mc >> 8) & 0xf; |
713 | if (bios->pub.fp_no_ddc) { | 679 | if (bios->fp_no_ddc) { |
714 | if (bios->fp.dual_link) | 680 | if (bios->fp.dual_link) |
715 | script |= 0x0100; | 681 | script |= 0x0100; |
716 | if (bios->fp.if_is_24bit) | 682 | if (bios->fp.if_is_24bit) |
diff --git a/drivers/gpu/drm/nouveau/nv50_fbcon.c b/drivers/gpu/drm/nouveau/nv50_fbcon.c index 0f57cdf7ccb2..993c7126fbde 100644 --- a/drivers/gpu/drm/nouveau/nv50_fbcon.c +++ b/drivers/gpu/drm/nouveau/nv50_fbcon.c | |||
@@ -109,7 +109,7 @@ nv50_fbcon_imageblit(struct fb_info *info, const struct fb_image *image) | |||
109 | return; | 109 | return; |
110 | } | 110 | } |
111 | 111 | ||
112 | width = (image->width + 31) & ~31; | 112 | width = ALIGN(image->width, 32); |
113 | dwords = (width * image->height) >> 5; | 113 | dwords = (width * image->height) >> 5; |
114 | 114 | ||
115 | BEGIN_RING(chan, NvSub2D, 0x0814, 2); | 115 | BEGIN_RING(chan, NvSub2D, 0x0814, 2); |
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index 204a79ff10f4..e20c0e2474f3 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c | |||
@@ -243,6 +243,7 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
243 | struct drm_device *dev = chan->dev; | 243 | struct drm_device *dev = chan->dev; |
244 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 244 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
245 | struct nouveau_gpuobj *ramfc = NULL; | 245 | struct nouveau_gpuobj *ramfc = NULL; |
246 | unsigned long flags; | ||
246 | int ret; | 247 | int ret; |
247 | 248 | ||
248 | NV_DEBUG(dev, "ch%d\n", chan->id); | 249 | NV_DEBUG(dev, "ch%d\n", chan->id); |
@@ -278,19 +279,21 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
278 | return ret; | 279 | return ret; |
279 | } | 280 | } |
280 | 281 | ||
282 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
283 | |||
281 | dev_priv->engine.instmem.prepare_access(dev, true); | 284 | dev_priv->engine.instmem.prepare_access(dev, true); |
282 | 285 | ||
283 | nv_wo32(dev, ramfc, 0x08/4, chan->pushbuf_base); | ||
284 | nv_wo32(dev, ramfc, 0x10/4, chan->pushbuf_base); | ||
285 | nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); | 286 | nv_wo32(dev, ramfc, 0x48/4, chan->pushbuf->instance >> 4); |
286 | nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); | 287 | nv_wo32(dev, ramfc, 0x80/4, (0xc << 24) | (chan->ramht->instance >> 4)); |
287 | nv_wo32(dev, ramfc, 0x3c/4, 0x00086078); | ||
288 | nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); | 288 | nv_wo32(dev, ramfc, 0x44/4, 0x2101ffff); |
289 | nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); | 289 | nv_wo32(dev, ramfc, 0x60/4, 0x7fffffff); |
290 | nv_wo32(dev, ramfc, 0x40/4, 0x00000000); | 290 | nv_wo32(dev, ramfc, 0x40/4, 0x00000000); |
291 | nv_wo32(dev, ramfc, 0x7c/4, 0x30000001); | 291 | nv_wo32(dev, ramfc, 0x7c/4, 0x30000001); |
292 | nv_wo32(dev, ramfc, 0x78/4, 0x00000000); | 292 | nv_wo32(dev, ramfc, 0x78/4, 0x00000000); |
293 | nv_wo32(dev, ramfc, 0x4c/4, 0xffffffff); | 293 | nv_wo32(dev, ramfc, 0x3c/4, 0x403f6078); |
294 | nv_wo32(dev, ramfc, 0x50/4, chan->pushbuf_base + | ||
295 | chan->dma.ib_base * 4); | ||
296 | nv_wo32(dev, ramfc, 0x54/4, drm_order(chan->dma.ib_max + 1) << 16); | ||
294 | 297 | ||
295 | if (!IS_G80) { | 298 | if (!IS_G80) { |
296 | nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); | 299 | nv_wo32(dev, chan->ramin->gpuobj, 0, chan->id); |
@@ -306,10 +309,12 @@ nv50_fifo_create_context(struct nouveau_channel *chan) | |||
306 | ret = nv50_fifo_channel_enable(dev, chan->id, false); | 309 | ret = nv50_fifo_channel_enable(dev, chan->id, false); |
307 | if (ret) { | 310 | if (ret) { |
308 | NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); | 311 | NV_ERROR(dev, "error enabling ch%d: %d\n", chan->id, ret); |
312 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
309 | nouveau_gpuobj_ref_del(dev, &chan->ramfc); | 313 | nouveau_gpuobj_ref_del(dev, &chan->ramfc); |
310 | return ret; | 314 | return ret; |
311 | } | 315 | } |
312 | 316 | ||
317 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
313 | return 0; | 318 | return 0; |
314 | } | 319 | } |
315 | 320 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index 6d504801b514..857a09671a39 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
@@ -28,30 +28,7 @@ | |||
28 | #include "drm.h" | 28 | #include "drm.h" |
29 | #include "nouveau_drv.h" | 29 | #include "nouveau_drv.h" |
30 | 30 | ||
31 | MODULE_FIRMWARE("nouveau/nv50.ctxprog"); | 31 | #include "nouveau_grctx.h" |
32 | MODULE_FIRMWARE("nouveau/nv50.ctxvals"); | ||
33 | MODULE_FIRMWARE("nouveau/nv84.ctxprog"); | ||
34 | MODULE_FIRMWARE("nouveau/nv84.ctxvals"); | ||
35 | MODULE_FIRMWARE("nouveau/nv86.ctxprog"); | ||
36 | MODULE_FIRMWARE("nouveau/nv86.ctxvals"); | ||
37 | MODULE_FIRMWARE("nouveau/nv92.ctxprog"); | ||
38 | MODULE_FIRMWARE("nouveau/nv92.ctxvals"); | ||
39 | MODULE_FIRMWARE("nouveau/nv94.ctxprog"); | ||
40 | MODULE_FIRMWARE("nouveau/nv94.ctxvals"); | ||
41 | MODULE_FIRMWARE("nouveau/nv96.ctxprog"); | ||
42 | MODULE_FIRMWARE("nouveau/nv96.ctxvals"); | ||
43 | MODULE_FIRMWARE("nouveau/nv98.ctxprog"); | ||
44 | MODULE_FIRMWARE("nouveau/nv98.ctxvals"); | ||
45 | MODULE_FIRMWARE("nouveau/nva0.ctxprog"); | ||
46 | MODULE_FIRMWARE("nouveau/nva0.ctxvals"); | ||
47 | MODULE_FIRMWARE("nouveau/nva5.ctxprog"); | ||
48 | MODULE_FIRMWARE("nouveau/nva5.ctxvals"); | ||
49 | MODULE_FIRMWARE("nouveau/nva8.ctxprog"); | ||
50 | MODULE_FIRMWARE("nouveau/nva8.ctxvals"); | ||
51 | MODULE_FIRMWARE("nouveau/nvaa.ctxprog"); | ||
52 | MODULE_FIRMWARE("nouveau/nvaa.ctxvals"); | ||
53 | MODULE_FIRMWARE("nouveau/nvac.ctxprog"); | ||
54 | MODULE_FIRMWARE("nouveau/nvac.ctxvals"); | ||
55 | 32 | ||
56 | #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) | 33 | #define IS_G80 ((dev_priv->chipset & 0xf0) == 0x50) |
57 | 34 | ||
@@ -111,9 +88,34 @@ nv50_graph_init_ctxctl(struct drm_device *dev) | |||
111 | 88 | ||
112 | NV_DEBUG(dev, "\n"); | 89 | NV_DEBUG(dev, "\n"); |
113 | 90 | ||
114 | nouveau_grctx_prog_load(dev); | 91 | if (nouveau_ctxfw) { |
115 | if (!dev_priv->engine.graph.ctxprog) | 92 | nouveau_grctx_prog_load(dev); |
116 | dev_priv->engine.graph.accel_blocked = true; | 93 | dev_priv->engine.graph.grctx_size = 0x70000; |
94 | } | ||
95 | if (!dev_priv->engine.graph.ctxprog) { | ||
96 | struct nouveau_grctx ctx = {}; | ||
97 | uint32_t *cp = kmalloc(512 * 4, GFP_KERNEL); | ||
98 | int i; | ||
99 | if (!cp) { | ||
100 | NV_ERROR(dev, "Couldn't alloc ctxprog! Disabling acceleration.\n"); | ||
101 | dev_priv->engine.graph.accel_blocked = true; | ||
102 | return 0; | ||
103 | } | ||
104 | ctx.dev = dev; | ||
105 | ctx.mode = NOUVEAU_GRCTX_PROG; | ||
106 | ctx.data = cp; | ||
107 | ctx.ctxprog_max = 512; | ||
108 | if (!nv50_grctx_init(&ctx)) { | ||
109 | dev_priv->engine.graph.grctx_size = ctx.ctxvals_pos * 4; | ||
110 | |||
111 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_INDEX, 0); | ||
112 | for (i = 0; i < ctx.ctxprog_len; i++) | ||
113 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_UCODE_DATA, cp[i]); | ||
114 | } else { | ||
115 | dev_priv->engine.graph.accel_blocked = true; | ||
116 | } | ||
117 | kfree(cp); | ||
118 | } | ||
117 | 119 | ||
118 | nv_wr32(dev, 0x400320, 4); | 120 | nv_wr32(dev, 0x400320, 4); |
119 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); | 121 | nv_wr32(dev, NV40_PGRAPH_CTXCTL_CUR, 0); |
@@ -193,13 +195,13 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
193 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 195 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
194 | struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; | 196 | struct nouveau_gpuobj *ramin = chan->ramin->gpuobj; |
195 | struct nouveau_gpuobj *ctx; | 197 | struct nouveau_gpuobj *ctx; |
196 | uint32_t grctx_size = 0x70000; | 198 | struct nouveau_pgraph_engine *pgraph = &dev_priv->engine.graph; |
197 | int hdr, ret; | 199 | int hdr, ret; |
198 | 200 | ||
199 | NV_DEBUG(dev, "ch%d\n", chan->id); | 201 | NV_DEBUG(dev, "ch%d\n", chan->id); |
200 | 202 | ||
201 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, grctx_size, 0x1000, | 203 | ret = nouveau_gpuobj_new_ref(dev, chan, NULL, 0, pgraph->grctx_size, |
202 | NVOBJ_FLAG_ZERO_ALLOC | | 204 | 0x1000, NVOBJ_FLAG_ZERO_ALLOC | |
203 | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); | 205 | NVOBJ_FLAG_ZERO_FREE, &chan->ramin_grctx); |
204 | if (ret) | 206 | if (ret) |
205 | return ret; | 207 | return ret; |
@@ -209,7 +211,7 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
209 | dev_priv->engine.instmem.prepare_access(dev, true); | 211 | dev_priv->engine.instmem.prepare_access(dev, true); |
210 | nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); | 212 | nv_wo32(dev, ramin, (hdr + 0x00)/4, 0x00190002); |
211 | nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + | 213 | nv_wo32(dev, ramin, (hdr + 0x04)/4, chan->ramin_grctx->instance + |
212 | grctx_size - 1); | 214 | pgraph->grctx_size - 1); |
213 | nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); | 215 | nv_wo32(dev, ramin, (hdr + 0x08)/4, chan->ramin_grctx->instance); |
214 | nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); | 216 | nv_wo32(dev, ramin, (hdr + 0x0c)/4, 0); |
215 | nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); | 217 | nv_wo32(dev, ramin, (hdr + 0x10)/4, 0); |
@@ -217,7 +219,15 @@ nv50_graph_create_context(struct nouveau_channel *chan) | |||
217 | dev_priv->engine.instmem.finish_access(dev); | 219 | dev_priv->engine.instmem.finish_access(dev); |
218 | 220 | ||
219 | dev_priv->engine.instmem.prepare_access(dev, true); | 221 | dev_priv->engine.instmem.prepare_access(dev, true); |
220 | nouveau_grctx_vals_load(dev, ctx); | 222 | if (!pgraph->ctxprog) { |
223 | struct nouveau_grctx ctx = {}; | ||
224 | ctx.dev = chan->dev; | ||
225 | ctx.mode = NOUVEAU_GRCTX_VALS; | ||
226 | ctx.data = chan->ramin_grctx->gpuobj; | ||
227 | nv50_grctx_init(&ctx); | ||
228 | } else { | ||
229 | nouveau_grctx_vals_load(dev, ctx); | ||
230 | } | ||
221 | nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); | 231 | nv_wo32(dev, ctx, 0x00000/4, chan->ramin->instance >> 12); |
222 | if ((dev_priv->chipset & 0xf0) == 0xa0) | 232 | if ((dev_priv->chipset & 0xf0) == 0xa0) |
223 | nv_wo32(dev, ctx, 0x00004/4, 0x00000000); | 233 | nv_wo32(dev, ctx, 0x00004/4, 0x00000000); |
diff --git a/drivers/gpu/drm/nouveau/nv50_grctx.c b/drivers/gpu/drm/nouveau/nv50_grctx.c new file mode 100644 index 000000000000..d105fcd42ca0 --- /dev/null +++ b/drivers/gpu/drm/nouveau/nv50_grctx.c | |||
@@ -0,0 +1,2367 @@ | |||
1 | /* | ||
2 | * Copyright 2009 Marcin Kościelnicki | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | */ | ||
22 | |||
23 | #define CP_FLAG_CLEAR 0 | ||
24 | #define CP_FLAG_SET 1 | ||
25 | #define CP_FLAG_SWAP_DIRECTION ((0 * 32) + 0) | ||
26 | #define CP_FLAG_SWAP_DIRECTION_LOAD 0 | ||
27 | #define CP_FLAG_SWAP_DIRECTION_SAVE 1 | ||
28 | #define CP_FLAG_UNK01 ((0 * 32) + 1) | ||
29 | #define CP_FLAG_UNK01_CLEAR 0 | ||
30 | #define CP_FLAG_UNK01_SET 1 | ||
31 | #define CP_FLAG_UNK03 ((0 * 32) + 3) | ||
32 | #define CP_FLAG_UNK03_CLEAR 0 | ||
33 | #define CP_FLAG_UNK03_SET 1 | ||
34 | #define CP_FLAG_USER_SAVE ((0 * 32) + 5) | ||
35 | #define CP_FLAG_USER_SAVE_NOT_PENDING 0 | ||
36 | #define CP_FLAG_USER_SAVE_PENDING 1 | ||
37 | #define CP_FLAG_USER_LOAD ((0 * 32) + 6) | ||
38 | #define CP_FLAG_USER_LOAD_NOT_PENDING 0 | ||
39 | #define CP_FLAG_USER_LOAD_PENDING 1 | ||
40 | #define CP_FLAG_UNK0B ((0 * 32) + 0xb) | ||
41 | #define CP_FLAG_UNK0B_CLEAR 0 | ||
42 | #define CP_FLAG_UNK0B_SET 1 | ||
43 | #define CP_FLAG_UNK1D ((0 * 32) + 0x1d) | ||
44 | #define CP_FLAG_UNK1D_CLEAR 0 | ||
45 | #define CP_FLAG_UNK1D_SET 1 | ||
46 | #define CP_FLAG_UNK20 ((1 * 32) + 0) | ||
47 | #define CP_FLAG_UNK20_CLEAR 0 | ||
48 | #define CP_FLAG_UNK20_SET 1 | ||
49 | #define CP_FLAG_STATUS ((2 * 32) + 0) | ||
50 | #define CP_FLAG_STATUS_BUSY 0 | ||
51 | #define CP_FLAG_STATUS_IDLE 1 | ||
52 | #define CP_FLAG_AUTO_SAVE ((2 * 32) + 4) | ||
53 | #define CP_FLAG_AUTO_SAVE_NOT_PENDING 0 | ||
54 | #define CP_FLAG_AUTO_SAVE_PENDING 1 | ||
55 | #define CP_FLAG_AUTO_LOAD ((2 * 32) + 5) | ||
56 | #define CP_FLAG_AUTO_LOAD_NOT_PENDING 0 | ||
57 | #define CP_FLAG_AUTO_LOAD_PENDING 1 | ||
58 | #define CP_FLAG_XFER ((2 * 32) + 11) | ||
59 | #define CP_FLAG_XFER_IDLE 0 | ||
60 | #define CP_FLAG_XFER_BUSY 1 | ||
61 | #define CP_FLAG_NEWCTX ((2 * 32) + 12) | ||
62 | #define CP_FLAG_NEWCTX_BUSY 0 | ||
63 | #define CP_FLAG_NEWCTX_DONE 1 | ||
64 | #define CP_FLAG_ALWAYS ((2 * 32) + 13) | ||
65 | #define CP_FLAG_ALWAYS_FALSE 0 | ||
66 | #define CP_FLAG_ALWAYS_TRUE 1 | ||
67 | |||
68 | #define CP_CTX 0x00100000 | ||
69 | #define CP_CTX_COUNT 0x000f0000 | ||
70 | #define CP_CTX_COUNT_SHIFT 16 | ||
71 | #define CP_CTX_REG 0x00003fff | ||
72 | #define CP_LOAD_SR 0x00200000 | ||
73 | #define CP_LOAD_SR_VALUE 0x000fffff | ||
74 | #define CP_BRA 0x00400000 | ||
75 | #define CP_BRA_IP 0x0001ff00 | ||
76 | #define CP_BRA_IP_SHIFT 8 | ||
77 | #define CP_BRA_IF_CLEAR 0x00000080 | ||
78 | #define CP_BRA_FLAG 0x0000007f | ||
79 | #define CP_WAIT 0x00500000 | ||
80 | #define CP_WAIT_SET 0x00000080 | ||
81 | #define CP_WAIT_FLAG 0x0000007f | ||
82 | #define CP_SET 0x00700000 | ||
83 | #define CP_SET_1 0x00000080 | ||
84 | #define CP_SET_FLAG 0x0000007f | ||
85 | #define CP_NEWCTX 0x00600004 | ||
86 | #define CP_NEXT_TO_SWAP 0x00600005 | ||
87 | #define CP_SET_CONTEXT_POINTER 0x00600006 | ||
88 | #define CP_SET_XFER_POINTER 0x00600007 | ||
89 | #define CP_ENABLE 0x00600009 | ||
90 | #define CP_END 0x0060000c | ||
91 | #define CP_NEXT_TO_CURRENT 0x0060000d | ||
92 | #define CP_DISABLE1 0x0090ffff | ||
93 | #define CP_DISABLE2 0x0091ffff | ||
94 | #define CP_XFER_1 0x008000ff | ||
95 | #define CP_XFER_2 0x008800ff | ||
96 | #define CP_SEEK_1 0x00c000ff | ||
97 | #define CP_SEEK_2 0x00c800ff | ||
98 | |||
99 | #include "drmP.h" | ||
100 | #include "nouveau_drv.h" | ||
101 | #include "nouveau_grctx.h" | ||
102 | |||
103 | /* | ||
104 | * This code deals with PGRAPH contexts on NV50 family cards. Like NV40, it's | ||
105 | * the GPU itself that does context-switching, but it needs a special | ||
106 | * microcode to do it. And it's the driver's task to supply this microcode, | ||
107 | * further known as ctxprog, as well as the initial context values, known | ||
108 | * as ctxvals. | ||
109 | * | ||
110 | * Without ctxprog, you cannot switch contexts. Not even in software, since | ||
111 | * the majority of context [xfer strands] isn't accessible directly. You're | ||
112 | * stuck with a single channel, and you also suffer all the problems resulting | ||
113 | * from missing ctxvals, since you cannot load them. | ||
114 | * | ||
115 | * Without ctxvals, you're stuck with PGRAPH's default context. It's enough to | ||
116 | * run 2d operations, but trying to utilise 3d or CUDA will just lock you up, | ||
117 | * since you don't have... some sort of needed setup. | ||
118 | * | ||
119 | * Nouveau will just disable acceleration if not given ctxprog + ctxvals, since | ||
120 | * it's too much hassle to handle no-ctxprog as a special case. | ||
121 | */ | ||
122 | |||
123 | /* | ||
124 | * How ctxprogs work. | ||
125 | * | ||
126 | * The ctxprog is written in its own kind of microcode, with very small and | ||
127 | * crappy set of available commands. You upload it to a small [512 insns] | ||
128 | * area of memory on PGRAPH, and it'll be run when PFIFO wants PGRAPH to | ||
129 | * switch channel. or when the driver explicitely requests it. Stuff visible | ||
130 | * to ctxprog consists of: PGRAPH MMIO registers, PGRAPH context strands, | ||
131 | * the per-channel context save area in VRAM [known as ctxvals or grctx], | ||
132 | * 4 flags registers, a scratch register, two grctx pointers, plus many | ||
133 | * random poorly-understood details. | ||
134 | * | ||
135 | * When ctxprog runs, it's supposed to check what operations are asked of it, | ||
136 | * save old context if requested, optionally reset PGRAPH and switch to the | ||
137 | * new channel, and load the new context. Context consists of three major | ||
138 | * parts: subset of MMIO registers and two "xfer areas". | ||
139 | */ | ||
140 | |||
141 | /* TODO: | ||
142 | * - document unimplemented bits compared to nvidia | ||
143 | * - NVAx: make a TP subroutine, use it. | ||
144 | * - use 0x4008fc instead of 0x1540? | ||
145 | */ | ||
146 | |||
147 | enum cp_label { | ||
148 | cp_check_load = 1, | ||
149 | cp_setup_auto_load, | ||
150 | cp_setup_load, | ||
151 | cp_setup_save, | ||
152 | cp_swap_state, | ||
153 | cp_prepare_exit, | ||
154 | cp_exit, | ||
155 | }; | ||
156 | |||
157 | static void nv50_graph_construct_mmio(struct nouveau_grctx *ctx); | ||
158 | static void nv50_graph_construct_xfer1(struct nouveau_grctx *ctx); | ||
159 | static void nv50_graph_construct_xfer2(struct nouveau_grctx *ctx); | ||
160 | |||
161 | /* Main function: construct the ctxprog skeleton, call the other functions. */ | ||
162 | |||
163 | int | ||
164 | nv50_grctx_init(struct nouveau_grctx *ctx) | ||
165 | { | ||
166 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
167 | |||
168 | switch (dev_priv->chipset) { | ||
169 | case 0x50: | ||
170 | case 0x84: | ||
171 | case 0x86: | ||
172 | case 0x92: | ||
173 | case 0x94: | ||
174 | case 0x96: | ||
175 | case 0x98: | ||
176 | case 0xa0: | ||
177 | case 0xa5: | ||
178 | case 0xa8: | ||
179 | case 0xaa: | ||
180 | case 0xac: | ||
181 | break; | ||
182 | default: | ||
183 | NV_ERROR(ctx->dev, "I don't know how to make a ctxprog for " | ||
184 | "your NV%x card.\n", dev_priv->chipset); | ||
185 | NV_ERROR(ctx->dev, "Disabling acceleration. Please contact " | ||
186 | "the devs.\n"); | ||
187 | return -ENOSYS; | ||
188 | } | ||
189 | /* decide whether we're loading/unloading the context */ | ||
190 | cp_bra (ctx, AUTO_SAVE, PENDING, cp_setup_save); | ||
191 | cp_bra (ctx, USER_SAVE, PENDING, cp_setup_save); | ||
192 | |||
193 | cp_name(ctx, cp_check_load); | ||
194 | cp_bra (ctx, AUTO_LOAD, PENDING, cp_setup_auto_load); | ||
195 | cp_bra (ctx, USER_LOAD, PENDING, cp_setup_load); | ||
196 | cp_bra (ctx, ALWAYS, TRUE, cp_exit); | ||
197 | |||
198 | /* setup for context load */ | ||
199 | cp_name(ctx, cp_setup_auto_load); | ||
200 | cp_out (ctx, CP_DISABLE1); | ||
201 | cp_out (ctx, CP_DISABLE2); | ||
202 | cp_out (ctx, CP_ENABLE); | ||
203 | cp_out (ctx, CP_NEXT_TO_SWAP); | ||
204 | cp_set (ctx, UNK01, SET); | ||
205 | cp_name(ctx, cp_setup_load); | ||
206 | cp_out (ctx, CP_NEWCTX); | ||
207 | cp_wait(ctx, NEWCTX, BUSY); | ||
208 | cp_set (ctx, UNK1D, CLEAR); | ||
209 | cp_set (ctx, SWAP_DIRECTION, LOAD); | ||
210 | cp_bra (ctx, UNK0B, SET, cp_prepare_exit); | ||
211 | cp_bra (ctx, ALWAYS, TRUE, cp_swap_state); | ||
212 | |||
213 | /* setup for context save */ | ||
214 | cp_name(ctx, cp_setup_save); | ||
215 | cp_set (ctx, UNK1D, SET); | ||
216 | cp_wait(ctx, STATUS, BUSY); | ||
217 | cp_set (ctx, UNK01, SET); | ||
218 | cp_set (ctx, SWAP_DIRECTION, SAVE); | ||
219 | |||
220 | /* general PGRAPH state */ | ||
221 | cp_name(ctx, cp_swap_state); | ||
222 | cp_set (ctx, UNK03, SET); | ||
223 | cp_pos (ctx, 0x00004/4); | ||
224 | cp_ctx (ctx, 0x400828, 1); /* needed. otherwise, flickering happens. */ | ||
225 | cp_pos (ctx, 0x00100/4); | ||
226 | nv50_graph_construct_mmio(ctx); | ||
227 | nv50_graph_construct_xfer1(ctx); | ||
228 | nv50_graph_construct_xfer2(ctx); | ||
229 | |||
230 | cp_bra (ctx, SWAP_DIRECTION, SAVE, cp_check_load); | ||
231 | |||
232 | cp_set (ctx, UNK20, SET); | ||
233 | cp_set (ctx, SWAP_DIRECTION, SAVE); /* no idea why this is needed, but fixes at least one lockup. */ | ||
234 | cp_lsr (ctx, ctx->ctxvals_base); | ||
235 | cp_out (ctx, CP_SET_XFER_POINTER); | ||
236 | cp_lsr (ctx, 4); | ||
237 | cp_out (ctx, CP_SEEK_1); | ||
238 | cp_out (ctx, CP_XFER_1); | ||
239 | cp_wait(ctx, XFER, BUSY); | ||
240 | |||
241 | /* pre-exit state updates */ | ||
242 | cp_name(ctx, cp_prepare_exit); | ||
243 | cp_set (ctx, UNK01, CLEAR); | ||
244 | cp_set (ctx, UNK03, CLEAR); | ||
245 | cp_set (ctx, UNK1D, CLEAR); | ||
246 | |||
247 | cp_bra (ctx, USER_SAVE, PENDING, cp_exit); | ||
248 | cp_out (ctx, CP_NEXT_TO_CURRENT); | ||
249 | |||
250 | cp_name(ctx, cp_exit); | ||
251 | cp_set (ctx, USER_SAVE, NOT_PENDING); | ||
252 | cp_set (ctx, USER_LOAD, NOT_PENDING); | ||
253 | cp_out (ctx, CP_END); | ||
254 | ctx->ctxvals_pos += 0x400; /* padding... no idea why you need it */ | ||
255 | |||
256 | return 0; | ||
257 | } | ||
258 | |||
259 | /* | ||
260 | * Constructs MMIO part of ctxprog and ctxvals. Just a matter of knowing which | ||
261 | * registers to save/restore and the default values for them. | ||
262 | */ | ||
263 | |||
264 | static void | ||
265 | nv50_graph_construct_mmio(struct nouveau_grctx *ctx) | ||
266 | { | ||
267 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
268 | int i, j; | ||
269 | int offset, base; | ||
270 | uint32_t units = nv_rd32 (ctx->dev, 0x1540); | ||
271 | |||
272 | /* 0800 */ | ||
273 | cp_ctx(ctx, 0x400808, 7); | ||
274 | gr_def(ctx, 0x400814, 0x00000030); | ||
275 | cp_ctx(ctx, 0x400834, 0x32); | ||
276 | if (dev_priv->chipset == 0x50) { | ||
277 | gr_def(ctx, 0x400834, 0xff400040); | ||
278 | gr_def(ctx, 0x400838, 0xfff00080); | ||
279 | gr_def(ctx, 0x40083c, 0xfff70090); | ||
280 | gr_def(ctx, 0x400840, 0xffe806a8); | ||
281 | } | ||
282 | gr_def(ctx, 0x400844, 0x00000002); | ||
283 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
284 | gr_def(ctx, 0x400894, 0x00001000); | ||
285 | gr_def(ctx, 0x4008e8, 0x00000003); | ||
286 | gr_def(ctx, 0x4008ec, 0x00001000); | ||
287 | if (dev_priv->chipset == 0x50) | ||
288 | cp_ctx(ctx, 0x400908, 0xb); | ||
289 | else if (dev_priv->chipset < 0xa0) | ||
290 | cp_ctx(ctx, 0x400908, 0xc); | ||
291 | else | ||
292 | cp_ctx(ctx, 0x400908, 0xe); | ||
293 | |||
294 | if (dev_priv->chipset >= 0xa0) | ||
295 | cp_ctx(ctx, 0x400b00, 0x1); | ||
296 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
297 | cp_ctx(ctx, 0x400b10, 0x1); | ||
298 | gr_def(ctx, 0x400b10, 0x0001629d); | ||
299 | cp_ctx(ctx, 0x400b20, 0x1); | ||
300 | gr_def(ctx, 0x400b20, 0x0001629d); | ||
301 | } | ||
302 | |||
303 | /* 0C00 */ | ||
304 | cp_ctx(ctx, 0x400c08, 0x2); | ||
305 | gr_def(ctx, 0x400c08, 0x0000fe0c); | ||
306 | |||
307 | /* 1000 */ | ||
308 | if (dev_priv->chipset < 0xa0) { | ||
309 | cp_ctx(ctx, 0x401008, 0x4); | ||
310 | gr_def(ctx, 0x401014, 0x00001000); | ||
311 | } else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) { | ||
312 | cp_ctx(ctx, 0x401008, 0x5); | ||
313 | gr_def(ctx, 0x401018, 0x00001000); | ||
314 | } else { | ||
315 | cp_ctx(ctx, 0x401008, 0x5); | ||
316 | gr_def(ctx, 0x401018, 0x00004000); | ||
317 | } | ||
318 | |||
319 | /* 1400 */ | ||
320 | cp_ctx(ctx, 0x401400, 0x8); | ||
321 | cp_ctx(ctx, 0x401424, 0x3); | ||
322 | if (dev_priv->chipset == 0x50) | ||
323 | gr_def(ctx, 0x40142c, 0x0001fd87); | ||
324 | else | ||
325 | gr_def(ctx, 0x40142c, 0x00000187); | ||
326 | cp_ctx(ctx, 0x401540, 0x5); | ||
327 | gr_def(ctx, 0x401550, 0x00001018); | ||
328 | |||
329 | /* 1800 */ | ||
330 | cp_ctx(ctx, 0x401814, 0x1); | ||
331 | gr_def(ctx, 0x401814, 0x000000ff); | ||
332 | if (dev_priv->chipset == 0x50) { | ||
333 | cp_ctx(ctx, 0x40181c, 0xe); | ||
334 | gr_def(ctx, 0x401850, 0x00000004); | ||
335 | } else if (dev_priv->chipset < 0xa0) { | ||
336 | cp_ctx(ctx, 0x40181c, 0xf); | ||
337 | gr_def(ctx, 0x401854, 0x00000004); | ||
338 | } else { | ||
339 | cp_ctx(ctx, 0x40181c, 0x13); | ||
340 | gr_def(ctx, 0x401864, 0x00000004); | ||
341 | } | ||
342 | |||
343 | /* 1C00 */ | ||
344 | cp_ctx(ctx, 0x401c00, 0x1); | ||
345 | switch (dev_priv->chipset) { | ||
346 | case 0x50: | ||
347 | gr_def(ctx, 0x401c00, 0x0001005f); | ||
348 | break; | ||
349 | case 0x84: | ||
350 | case 0x86: | ||
351 | case 0x94: | ||
352 | gr_def(ctx, 0x401c00, 0x044d00df); | ||
353 | break; | ||
354 | case 0x92: | ||
355 | case 0x96: | ||
356 | case 0x98: | ||
357 | case 0xa0: | ||
358 | case 0xaa: | ||
359 | case 0xac: | ||
360 | gr_def(ctx, 0x401c00, 0x042500df); | ||
361 | break; | ||
362 | case 0xa5: | ||
363 | case 0xa8: | ||
364 | gr_def(ctx, 0x401c00, 0x142500df); | ||
365 | break; | ||
366 | } | ||
367 | |||
368 | /* 2400 */ | ||
369 | cp_ctx(ctx, 0x402400, 0x1); | ||
370 | if (dev_priv->chipset == 0x50) | ||
371 | cp_ctx(ctx, 0x402408, 0x1); | ||
372 | else | ||
373 | cp_ctx(ctx, 0x402408, 0x2); | ||
374 | gr_def(ctx, 0x402408, 0x00000600); | ||
375 | |||
376 | /* 2800 */ | ||
377 | cp_ctx(ctx, 0x402800, 0x1); | ||
378 | if (dev_priv->chipset == 0x50) | ||
379 | gr_def(ctx, 0x402800, 0x00000006); | ||
380 | |||
381 | /* 2C00 */ | ||
382 | cp_ctx(ctx, 0x402c08, 0x6); | ||
383 | if (dev_priv->chipset != 0x50) | ||
384 | gr_def(ctx, 0x402c14, 0x01000000); | ||
385 | gr_def(ctx, 0x402c18, 0x000000ff); | ||
386 | if (dev_priv->chipset == 0x50) | ||
387 | cp_ctx(ctx, 0x402ca0, 0x1); | ||
388 | else | ||
389 | cp_ctx(ctx, 0x402ca0, 0x2); | ||
390 | if (dev_priv->chipset < 0xa0) | ||
391 | gr_def(ctx, 0x402ca0, 0x00000400); | ||
392 | else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) | ||
393 | gr_def(ctx, 0x402ca0, 0x00000800); | ||
394 | else | ||
395 | gr_def(ctx, 0x402ca0, 0x00000400); | ||
396 | cp_ctx(ctx, 0x402cac, 0x4); | ||
397 | |||
398 | /* 3000 */ | ||
399 | cp_ctx(ctx, 0x403004, 0x1); | ||
400 | gr_def(ctx, 0x403004, 0x00000001); | ||
401 | |||
402 | /* 3404 */ | ||
403 | if (dev_priv->chipset >= 0xa0) { | ||
404 | cp_ctx(ctx, 0x403404, 0x1); | ||
405 | gr_def(ctx, 0x403404, 0x00000001); | ||
406 | } | ||
407 | |||
408 | /* 5000 */ | ||
409 | cp_ctx(ctx, 0x405000, 0x1); | ||
410 | switch (dev_priv->chipset) { | ||
411 | case 0x50: | ||
412 | gr_def(ctx, 0x405000, 0x00300080); | ||
413 | break; | ||
414 | case 0x84: | ||
415 | case 0xa0: | ||
416 | case 0xa5: | ||
417 | case 0xa8: | ||
418 | case 0xaa: | ||
419 | case 0xac: | ||
420 | gr_def(ctx, 0x405000, 0x000e0080); | ||
421 | break; | ||
422 | case 0x86: | ||
423 | case 0x92: | ||
424 | case 0x94: | ||
425 | case 0x96: | ||
426 | case 0x98: | ||
427 | gr_def(ctx, 0x405000, 0x00000080); | ||
428 | break; | ||
429 | } | ||
430 | cp_ctx(ctx, 0x405014, 0x1); | ||
431 | gr_def(ctx, 0x405014, 0x00000004); | ||
432 | cp_ctx(ctx, 0x40501c, 0x1); | ||
433 | cp_ctx(ctx, 0x405024, 0x1); | ||
434 | cp_ctx(ctx, 0x40502c, 0x1); | ||
435 | |||
436 | /* 5400 or maybe 4800 */ | ||
437 | if (dev_priv->chipset == 0x50) { | ||
438 | offset = 0x405400; | ||
439 | cp_ctx(ctx, 0x405400, 0xea); | ||
440 | } else if (dev_priv->chipset < 0x94) { | ||
441 | offset = 0x405400; | ||
442 | cp_ctx(ctx, 0x405400, 0xcb); | ||
443 | } else if (dev_priv->chipset < 0xa0) { | ||
444 | offset = 0x405400; | ||
445 | cp_ctx(ctx, 0x405400, 0xcc); | ||
446 | } else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
447 | offset = 0x404800; | ||
448 | cp_ctx(ctx, 0x404800, 0xda); | ||
449 | } else { | ||
450 | offset = 0x405400; | ||
451 | cp_ctx(ctx, 0x405400, 0xd4); | ||
452 | } | ||
453 | gr_def(ctx, offset + 0x0c, 0x00000002); | ||
454 | gr_def(ctx, offset + 0x10, 0x00000001); | ||
455 | if (dev_priv->chipset >= 0x94) | ||
456 | offset += 4; | ||
457 | gr_def(ctx, offset + 0x1c, 0x00000001); | ||
458 | gr_def(ctx, offset + 0x20, 0x00000100); | ||
459 | gr_def(ctx, offset + 0x38, 0x00000002); | ||
460 | gr_def(ctx, offset + 0x3c, 0x00000001); | ||
461 | gr_def(ctx, offset + 0x40, 0x00000001); | ||
462 | gr_def(ctx, offset + 0x50, 0x00000001); | ||
463 | gr_def(ctx, offset + 0x54, 0x003fffff); | ||
464 | gr_def(ctx, offset + 0x58, 0x00001fff); | ||
465 | gr_def(ctx, offset + 0x60, 0x00000001); | ||
466 | gr_def(ctx, offset + 0x64, 0x00000001); | ||
467 | gr_def(ctx, offset + 0x6c, 0x00000001); | ||
468 | gr_def(ctx, offset + 0x70, 0x00000001); | ||
469 | gr_def(ctx, offset + 0x74, 0x00000001); | ||
470 | gr_def(ctx, offset + 0x78, 0x00000004); | ||
471 | gr_def(ctx, offset + 0x7c, 0x00000001); | ||
472 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
473 | offset += 4; | ||
474 | gr_def(ctx, offset + 0x80, 0x00000001); | ||
475 | gr_def(ctx, offset + 0x84, 0x00000001); | ||
476 | gr_def(ctx, offset + 0x88, 0x00000007); | ||
477 | gr_def(ctx, offset + 0x8c, 0x00000001); | ||
478 | gr_def(ctx, offset + 0x90, 0x00000007); | ||
479 | gr_def(ctx, offset + 0x94, 0x00000001); | ||
480 | gr_def(ctx, offset + 0x98, 0x00000001); | ||
481 | gr_def(ctx, offset + 0x9c, 0x00000001); | ||
482 | if (dev_priv->chipset == 0x50) { | ||
483 | gr_def(ctx, offset + 0xb0, 0x00000001); | ||
484 | gr_def(ctx, offset + 0xb4, 0x00000001); | ||
485 | gr_def(ctx, offset + 0xbc, 0x00000001); | ||
486 | gr_def(ctx, offset + 0xc0, 0x0000000a); | ||
487 | gr_def(ctx, offset + 0xd0, 0x00000040); | ||
488 | gr_def(ctx, offset + 0xd8, 0x00000002); | ||
489 | gr_def(ctx, offset + 0xdc, 0x00000100); | ||
490 | gr_def(ctx, offset + 0xe0, 0x00000001); | ||
491 | gr_def(ctx, offset + 0xe4, 0x00000100); | ||
492 | gr_def(ctx, offset + 0x100, 0x00000001); | ||
493 | gr_def(ctx, offset + 0x124, 0x00000004); | ||
494 | gr_def(ctx, offset + 0x13c, 0x00000001); | ||
495 | gr_def(ctx, offset + 0x140, 0x00000100); | ||
496 | gr_def(ctx, offset + 0x148, 0x00000001); | ||
497 | gr_def(ctx, offset + 0x154, 0x00000100); | ||
498 | gr_def(ctx, offset + 0x158, 0x00000001); | ||
499 | gr_def(ctx, offset + 0x15c, 0x00000100); | ||
500 | gr_def(ctx, offset + 0x164, 0x00000001); | ||
501 | gr_def(ctx, offset + 0x170, 0x00000100); | ||
502 | gr_def(ctx, offset + 0x174, 0x00000001); | ||
503 | gr_def(ctx, offset + 0x17c, 0x00000001); | ||
504 | gr_def(ctx, offset + 0x188, 0x00000002); | ||
505 | gr_def(ctx, offset + 0x190, 0x00000001); | ||
506 | gr_def(ctx, offset + 0x198, 0x00000001); | ||
507 | gr_def(ctx, offset + 0x1ac, 0x00000003); | ||
508 | offset += 0xd0; | ||
509 | } else { | ||
510 | gr_def(ctx, offset + 0xb0, 0x00000001); | ||
511 | gr_def(ctx, offset + 0xb4, 0x00000100); | ||
512 | gr_def(ctx, offset + 0xbc, 0x00000001); | ||
513 | gr_def(ctx, offset + 0xc8, 0x00000100); | ||
514 | gr_def(ctx, offset + 0xcc, 0x00000001); | ||
515 | gr_def(ctx, offset + 0xd0, 0x00000100); | ||
516 | gr_def(ctx, offset + 0xd8, 0x00000001); | ||
517 | gr_def(ctx, offset + 0xe4, 0x00000100); | ||
518 | } | ||
519 | gr_def(ctx, offset + 0xf8, 0x00000004); | ||
520 | gr_def(ctx, offset + 0xfc, 0x00000070); | ||
521 | gr_def(ctx, offset + 0x100, 0x00000080); | ||
522 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
523 | offset += 4; | ||
524 | gr_def(ctx, offset + 0x114, 0x0000000c); | ||
525 | if (dev_priv->chipset == 0x50) | ||
526 | offset -= 4; | ||
527 | gr_def(ctx, offset + 0x11c, 0x00000008); | ||
528 | gr_def(ctx, offset + 0x120, 0x00000014); | ||
529 | if (dev_priv->chipset == 0x50) { | ||
530 | gr_def(ctx, offset + 0x124, 0x00000026); | ||
531 | offset -= 0x18; | ||
532 | } else { | ||
533 | gr_def(ctx, offset + 0x128, 0x00000029); | ||
534 | gr_def(ctx, offset + 0x12c, 0x00000027); | ||
535 | gr_def(ctx, offset + 0x130, 0x00000026); | ||
536 | gr_def(ctx, offset + 0x134, 0x00000008); | ||
537 | gr_def(ctx, offset + 0x138, 0x00000004); | ||
538 | gr_def(ctx, offset + 0x13c, 0x00000027); | ||
539 | } | ||
540 | gr_def(ctx, offset + 0x148, 0x00000001); | ||
541 | gr_def(ctx, offset + 0x14c, 0x00000002); | ||
542 | gr_def(ctx, offset + 0x150, 0x00000003); | ||
543 | gr_def(ctx, offset + 0x154, 0x00000004); | ||
544 | gr_def(ctx, offset + 0x158, 0x00000005); | ||
545 | gr_def(ctx, offset + 0x15c, 0x00000006); | ||
546 | gr_def(ctx, offset + 0x160, 0x00000007); | ||
547 | gr_def(ctx, offset + 0x164, 0x00000001); | ||
548 | gr_def(ctx, offset + 0x1a8, 0x000000cf); | ||
549 | if (dev_priv->chipset == 0x50) | ||
550 | offset -= 4; | ||
551 | gr_def(ctx, offset + 0x1d8, 0x00000080); | ||
552 | gr_def(ctx, offset + 0x1dc, 0x00000004); | ||
553 | gr_def(ctx, offset + 0x1e0, 0x00000004); | ||
554 | if (dev_priv->chipset == 0x50) | ||
555 | offset -= 4; | ||
556 | else | ||
557 | gr_def(ctx, offset + 0x1e4, 0x00000003); | ||
558 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
559 | gr_def(ctx, offset + 0x1ec, 0x00000003); | ||
560 | offset += 8; | ||
561 | } | ||
562 | gr_def(ctx, offset + 0x1e8, 0x00000001); | ||
563 | if (dev_priv->chipset == 0x50) | ||
564 | offset -= 4; | ||
565 | gr_def(ctx, offset + 0x1f4, 0x00000012); | ||
566 | gr_def(ctx, offset + 0x1f8, 0x00000010); | ||
567 | gr_def(ctx, offset + 0x1fc, 0x0000000c); | ||
568 | gr_def(ctx, offset + 0x200, 0x00000001); | ||
569 | gr_def(ctx, offset + 0x210, 0x00000004); | ||
570 | gr_def(ctx, offset + 0x214, 0x00000002); | ||
571 | gr_def(ctx, offset + 0x218, 0x00000004); | ||
572 | if (dev_priv->chipset >= 0xa0) | ||
573 | offset += 4; | ||
574 | gr_def(ctx, offset + 0x224, 0x003fffff); | ||
575 | gr_def(ctx, offset + 0x228, 0x00001fff); | ||
576 | if (dev_priv->chipset == 0x50) | ||
577 | offset -= 0x20; | ||
578 | else if (dev_priv->chipset >= 0xa0) { | ||
579 | gr_def(ctx, offset + 0x250, 0x00000001); | ||
580 | gr_def(ctx, offset + 0x254, 0x00000001); | ||
581 | gr_def(ctx, offset + 0x258, 0x00000002); | ||
582 | offset += 0x10; | ||
583 | } | ||
584 | gr_def(ctx, offset + 0x250, 0x00000004); | ||
585 | gr_def(ctx, offset + 0x254, 0x00000014); | ||
586 | gr_def(ctx, offset + 0x258, 0x00000001); | ||
587 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
588 | offset += 4; | ||
589 | gr_def(ctx, offset + 0x264, 0x00000002); | ||
590 | if (dev_priv->chipset >= 0xa0) | ||
591 | offset += 8; | ||
592 | gr_def(ctx, offset + 0x270, 0x00000001); | ||
593 | gr_def(ctx, offset + 0x278, 0x00000002); | ||
594 | gr_def(ctx, offset + 0x27c, 0x00001000); | ||
595 | if (dev_priv->chipset == 0x50) | ||
596 | offset -= 0xc; | ||
597 | else { | ||
598 | gr_def(ctx, offset + 0x280, 0x00000e00); | ||
599 | gr_def(ctx, offset + 0x284, 0x00001000); | ||
600 | gr_def(ctx, offset + 0x288, 0x00001e00); | ||
601 | } | ||
602 | gr_def(ctx, offset + 0x290, 0x00000001); | ||
603 | gr_def(ctx, offset + 0x294, 0x00000001); | ||
604 | gr_def(ctx, offset + 0x298, 0x00000001); | ||
605 | gr_def(ctx, offset + 0x29c, 0x00000001); | ||
606 | gr_def(ctx, offset + 0x2a0, 0x00000001); | ||
607 | gr_def(ctx, offset + 0x2b0, 0x00000200); | ||
608 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
609 | gr_def(ctx, offset + 0x2b4, 0x00000200); | ||
610 | offset += 4; | ||
611 | } | ||
612 | if (dev_priv->chipset < 0xa0) { | ||
613 | gr_def(ctx, offset + 0x2b8, 0x00000001); | ||
614 | gr_def(ctx, offset + 0x2bc, 0x00000070); | ||
615 | gr_def(ctx, offset + 0x2c0, 0x00000080); | ||
616 | gr_def(ctx, offset + 0x2cc, 0x00000001); | ||
617 | gr_def(ctx, offset + 0x2d0, 0x00000070); | ||
618 | gr_def(ctx, offset + 0x2d4, 0x00000080); | ||
619 | } else { | ||
620 | gr_def(ctx, offset + 0x2b8, 0x00000001); | ||
621 | gr_def(ctx, offset + 0x2bc, 0x000000f0); | ||
622 | gr_def(ctx, offset + 0x2c0, 0x000000ff); | ||
623 | gr_def(ctx, offset + 0x2cc, 0x00000001); | ||
624 | gr_def(ctx, offset + 0x2d0, 0x000000f0); | ||
625 | gr_def(ctx, offset + 0x2d4, 0x000000ff); | ||
626 | gr_def(ctx, offset + 0x2dc, 0x00000009); | ||
627 | offset += 4; | ||
628 | } | ||
629 | gr_def(ctx, offset + 0x2e4, 0x00000001); | ||
630 | gr_def(ctx, offset + 0x2e8, 0x000000cf); | ||
631 | gr_def(ctx, offset + 0x2f0, 0x00000001); | ||
632 | gr_def(ctx, offset + 0x300, 0x000000cf); | ||
633 | gr_def(ctx, offset + 0x308, 0x00000002); | ||
634 | gr_def(ctx, offset + 0x310, 0x00000001); | ||
635 | gr_def(ctx, offset + 0x318, 0x00000001); | ||
636 | gr_def(ctx, offset + 0x320, 0x000000cf); | ||
637 | gr_def(ctx, offset + 0x324, 0x000000cf); | ||
638 | gr_def(ctx, offset + 0x328, 0x00000001); | ||
639 | |||
640 | /* 6000? */ | ||
641 | if (dev_priv->chipset == 0x50) | ||
642 | cp_ctx(ctx, 0x4063e0, 0x1); | ||
643 | |||
644 | /* 6800 */ | ||
645 | if (dev_priv->chipset < 0x90) { | ||
646 | cp_ctx(ctx, 0x406814, 0x2b); | ||
647 | gr_def(ctx, 0x406818, 0x00000f80); | ||
648 | gr_def(ctx, 0x406860, 0x007f0080); | ||
649 | gr_def(ctx, 0x40689c, 0x007f0080); | ||
650 | } else { | ||
651 | cp_ctx(ctx, 0x406814, 0x4); | ||
652 | if (dev_priv->chipset == 0x98) | ||
653 | gr_def(ctx, 0x406818, 0x00000f80); | ||
654 | else | ||
655 | gr_def(ctx, 0x406818, 0x00001f80); | ||
656 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
657 | gr_def(ctx, 0x40681c, 0x00000030); | ||
658 | cp_ctx(ctx, 0x406830, 0x3); | ||
659 | } | ||
660 | |||
661 | /* 7000: per-ROP group state */ | ||
662 | for (i = 0; i < 8; i++) { | ||
663 | if (units & (1<<(i+16))) { | ||
664 | cp_ctx(ctx, 0x407000 + (i<<8), 3); | ||
665 | if (dev_priv->chipset == 0x50) | ||
666 | gr_def(ctx, 0x407000 + (i<<8), 0x1b74f820); | ||
667 | else if (dev_priv->chipset != 0xa5) | ||
668 | gr_def(ctx, 0x407000 + (i<<8), 0x3b74f821); | ||
669 | else | ||
670 | gr_def(ctx, 0x407000 + (i<<8), 0x7b74f821); | ||
671 | gr_def(ctx, 0x407004 + (i<<8), 0x89058001); | ||
672 | |||
673 | if (dev_priv->chipset == 0x50) { | ||
674 | cp_ctx(ctx, 0x407010 + (i<<8), 1); | ||
675 | } else if (dev_priv->chipset < 0xa0) { | ||
676 | cp_ctx(ctx, 0x407010 + (i<<8), 2); | ||
677 | gr_def(ctx, 0x407010 + (i<<8), 0x00001000); | ||
678 | gr_def(ctx, 0x407014 + (i<<8), 0x0000001f); | ||
679 | } else { | ||
680 | cp_ctx(ctx, 0x407010 + (i<<8), 3); | ||
681 | gr_def(ctx, 0x407010 + (i<<8), 0x00001000); | ||
682 | if (dev_priv->chipset != 0xa5) | ||
683 | gr_def(ctx, 0x407014 + (i<<8), 0x000000ff); | ||
684 | else | ||
685 | gr_def(ctx, 0x407014 + (i<<8), 0x000001ff); | ||
686 | } | ||
687 | |||
688 | cp_ctx(ctx, 0x407080 + (i<<8), 4); | ||
689 | if (dev_priv->chipset != 0xa5) | ||
690 | gr_def(ctx, 0x407080 + (i<<8), 0x027c10fa); | ||
691 | else | ||
692 | gr_def(ctx, 0x407080 + (i<<8), 0x827c10fa); | ||
693 | if (dev_priv->chipset == 0x50) | ||
694 | gr_def(ctx, 0x407084 + (i<<8), 0x000000c0); | ||
695 | else | ||
696 | gr_def(ctx, 0x407084 + (i<<8), 0x400000c0); | ||
697 | gr_def(ctx, 0x407088 + (i<<8), 0xb7892080); | ||
698 | |||
699 | if (dev_priv->chipset < 0xa0) | ||
700 | cp_ctx(ctx, 0x407094 + (i<<8), 1); | ||
701 | else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) | ||
702 | cp_ctx(ctx, 0x407094 + (i<<8), 3); | ||
703 | else { | ||
704 | cp_ctx(ctx, 0x407094 + (i<<8), 4); | ||
705 | gr_def(ctx, 0x4070a0 + (i<<8), 1); | ||
706 | } | ||
707 | } | ||
708 | } | ||
709 | |||
710 | cp_ctx(ctx, 0x407c00, 0x3); | ||
711 | if (dev_priv->chipset < 0x90) | ||
712 | gr_def(ctx, 0x407c00, 0x00010040); | ||
713 | else if (dev_priv->chipset < 0xa0) | ||
714 | gr_def(ctx, 0x407c00, 0x00390040); | ||
715 | else | ||
716 | gr_def(ctx, 0x407c00, 0x003d0040); | ||
717 | gr_def(ctx, 0x407c08, 0x00000022); | ||
718 | if (dev_priv->chipset >= 0xa0) { | ||
719 | cp_ctx(ctx, 0x407c10, 0x3); | ||
720 | cp_ctx(ctx, 0x407c20, 0x1); | ||
721 | cp_ctx(ctx, 0x407c2c, 0x1); | ||
722 | } | ||
723 | |||
724 | if (dev_priv->chipset < 0xa0) { | ||
725 | cp_ctx(ctx, 0x407d00, 0x9); | ||
726 | } else { | ||
727 | cp_ctx(ctx, 0x407d00, 0x15); | ||
728 | } | ||
729 | if (dev_priv->chipset == 0x98) | ||
730 | gr_def(ctx, 0x407d08, 0x00380040); | ||
731 | else { | ||
732 | if (dev_priv->chipset < 0x90) | ||
733 | gr_def(ctx, 0x407d08, 0x00010040); | ||
734 | else if (dev_priv->chipset < 0xa0) | ||
735 | gr_def(ctx, 0x407d08, 0x00390040); | ||
736 | else | ||
737 | gr_def(ctx, 0x407d08, 0x003d0040); | ||
738 | gr_def(ctx, 0x407d0c, 0x00000022); | ||
739 | } | ||
740 | |||
741 | /* 8000+: per-TP state */ | ||
742 | for (i = 0; i < 10; i++) { | ||
743 | if (units & (1<<i)) { | ||
744 | if (dev_priv->chipset < 0xa0) | ||
745 | base = 0x408000 + (i<<12); | ||
746 | else | ||
747 | base = 0x408000 + (i<<11); | ||
748 | if (dev_priv->chipset < 0xa0) | ||
749 | offset = base + 0xc00; | ||
750 | else | ||
751 | offset = base + 0x80; | ||
752 | cp_ctx(ctx, offset + 0x00, 1); | ||
753 | gr_def(ctx, offset + 0x00, 0x0000ff0a); | ||
754 | cp_ctx(ctx, offset + 0x08, 1); | ||
755 | |||
756 | /* per-MP state */ | ||
757 | for (j = 0; j < (dev_priv->chipset < 0xa0 ? 2 : 4); j++) { | ||
758 | if (!(units & (1 << (j+24)))) continue; | ||
759 | if (dev_priv->chipset < 0xa0) | ||
760 | offset = base + 0x200 + (j<<7); | ||
761 | else | ||
762 | offset = base + 0x100 + (j<<7); | ||
763 | cp_ctx(ctx, offset, 0x20); | ||
764 | gr_def(ctx, offset + 0x00, 0x01800000); | ||
765 | gr_def(ctx, offset + 0x04, 0x00160000); | ||
766 | gr_def(ctx, offset + 0x08, 0x01800000); | ||
767 | gr_def(ctx, offset + 0x18, 0x0003ffff); | ||
768 | switch (dev_priv->chipset) { | ||
769 | case 0x50: | ||
770 | gr_def(ctx, offset + 0x1c, 0x00080000); | ||
771 | break; | ||
772 | case 0x84: | ||
773 | gr_def(ctx, offset + 0x1c, 0x00880000); | ||
774 | break; | ||
775 | case 0x86: | ||
776 | gr_def(ctx, offset + 0x1c, 0x008c0000); | ||
777 | break; | ||
778 | case 0x92: | ||
779 | case 0x96: | ||
780 | case 0x98: | ||
781 | gr_def(ctx, offset + 0x1c, 0x118c0000); | ||
782 | break; | ||
783 | case 0x94: | ||
784 | gr_def(ctx, offset + 0x1c, 0x10880000); | ||
785 | break; | ||
786 | case 0xa0: | ||
787 | case 0xa5: | ||
788 | gr_def(ctx, offset + 0x1c, 0x310c0000); | ||
789 | break; | ||
790 | case 0xa8: | ||
791 | case 0xaa: | ||
792 | case 0xac: | ||
793 | gr_def(ctx, offset + 0x1c, 0x300c0000); | ||
794 | break; | ||
795 | } | ||
796 | gr_def(ctx, offset + 0x40, 0x00010401); | ||
797 | if (dev_priv->chipset == 0x50) | ||
798 | gr_def(ctx, offset + 0x48, 0x00000040); | ||
799 | else | ||
800 | gr_def(ctx, offset + 0x48, 0x00000078); | ||
801 | gr_def(ctx, offset + 0x50, 0x000000bf); | ||
802 | gr_def(ctx, offset + 0x58, 0x00001210); | ||
803 | if (dev_priv->chipset == 0x50) | ||
804 | gr_def(ctx, offset + 0x5c, 0x00000080); | ||
805 | else | ||
806 | gr_def(ctx, offset + 0x5c, 0x08000080); | ||
807 | if (dev_priv->chipset >= 0xa0) | ||
808 | gr_def(ctx, offset + 0x68, 0x0000003e); | ||
809 | } | ||
810 | |||
811 | if (dev_priv->chipset < 0xa0) | ||
812 | cp_ctx(ctx, base + 0x300, 0x4); | ||
813 | else | ||
814 | cp_ctx(ctx, base + 0x300, 0x5); | ||
815 | if (dev_priv->chipset == 0x50) | ||
816 | gr_def(ctx, base + 0x304, 0x00007070); | ||
817 | else if (dev_priv->chipset < 0xa0) | ||
818 | gr_def(ctx, base + 0x304, 0x00027070); | ||
819 | else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) | ||
820 | gr_def(ctx, base + 0x304, 0x01127070); | ||
821 | else | ||
822 | gr_def(ctx, base + 0x304, 0x05127070); | ||
823 | |||
824 | if (dev_priv->chipset < 0xa0) | ||
825 | cp_ctx(ctx, base + 0x318, 1); | ||
826 | else | ||
827 | cp_ctx(ctx, base + 0x320, 1); | ||
828 | if (dev_priv->chipset == 0x50) | ||
829 | gr_def(ctx, base + 0x318, 0x0003ffff); | ||
830 | else if (dev_priv->chipset < 0xa0) | ||
831 | gr_def(ctx, base + 0x318, 0x03ffffff); | ||
832 | else | ||
833 | gr_def(ctx, base + 0x320, 0x07ffffff); | ||
834 | |||
835 | if (dev_priv->chipset < 0xa0) | ||
836 | cp_ctx(ctx, base + 0x324, 5); | ||
837 | else | ||
838 | cp_ctx(ctx, base + 0x328, 4); | ||
839 | |||
840 | if (dev_priv->chipset < 0xa0) { | ||
841 | cp_ctx(ctx, base + 0x340, 9); | ||
842 | offset = base + 0x340; | ||
843 | } else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) { | ||
844 | cp_ctx(ctx, base + 0x33c, 0xb); | ||
845 | offset = base + 0x344; | ||
846 | } else { | ||
847 | cp_ctx(ctx, base + 0x33c, 0xd); | ||
848 | offset = base + 0x344; | ||
849 | } | ||
850 | gr_def(ctx, offset + 0x0, 0x00120407); | ||
851 | gr_def(ctx, offset + 0x4, 0x05091507); | ||
852 | if (dev_priv->chipset == 0x84) | ||
853 | gr_def(ctx, offset + 0x8, 0x05100202); | ||
854 | else | ||
855 | gr_def(ctx, offset + 0x8, 0x05010202); | ||
856 | gr_def(ctx, offset + 0xc, 0x00030201); | ||
857 | |||
858 | cp_ctx(ctx, base + 0x400, 2); | ||
859 | gr_def(ctx, base + 0x404, 0x00000040); | ||
860 | cp_ctx(ctx, base + 0x40c, 2); | ||
861 | gr_def(ctx, base + 0x40c, 0x0d0c0b0a); | ||
862 | gr_def(ctx, base + 0x410, 0x00141210); | ||
863 | |||
864 | if (dev_priv->chipset < 0xa0) | ||
865 | offset = base + 0x800; | ||
866 | else | ||
867 | offset = base + 0x500; | ||
868 | cp_ctx(ctx, offset, 6); | ||
869 | gr_def(ctx, offset + 0x0, 0x000001f0); | ||
870 | gr_def(ctx, offset + 0x4, 0x00000001); | ||
871 | gr_def(ctx, offset + 0x8, 0x00000003); | ||
872 | if (dev_priv->chipset == 0x50 || dev_priv->chipset >= 0xaa) | ||
873 | gr_def(ctx, offset + 0xc, 0x00008000); | ||
874 | gr_def(ctx, offset + 0x14, 0x00039e00); | ||
875 | cp_ctx(ctx, offset + 0x1c, 2); | ||
876 | if (dev_priv->chipset == 0x50) | ||
877 | gr_def(ctx, offset + 0x1c, 0x00000040); | ||
878 | else | ||
879 | gr_def(ctx, offset + 0x1c, 0x00000100); | ||
880 | gr_def(ctx, offset + 0x20, 0x00003800); | ||
881 | |||
882 | if (dev_priv->chipset >= 0xa0) { | ||
883 | cp_ctx(ctx, base + 0x54c, 2); | ||
884 | if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) | ||
885 | gr_def(ctx, base + 0x54c, 0x003fe006); | ||
886 | else | ||
887 | gr_def(ctx, base + 0x54c, 0x003fe007); | ||
888 | gr_def(ctx, base + 0x550, 0x003fe000); | ||
889 | } | ||
890 | |||
891 | if (dev_priv->chipset < 0xa0) | ||
892 | offset = base + 0xa00; | ||
893 | else | ||
894 | offset = base + 0x680; | ||
895 | cp_ctx(ctx, offset, 1); | ||
896 | gr_def(ctx, offset, 0x00404040); | ||
897 | |||
898 | if (dev_priv->chipset < 0xa0) | ||
899 | offset = base + 0xe00; | ||
900 | else | ||
901 | offset = base + 0x700; | ||
902 | cp_ctx(ctx, offset, 2); | ||
903 | if (dev_priv->chipset < 0xa0) | ||
904 | gr_def(ctx, offset, 0x0077f005); | ||
905 | else if (dev_priv->chipset == 0xa5) | ||
906 | gr_def(ctx, offset, 0x6cf7f007); | ||
907 | else if (dev_priv->chipset == 0xa8) | ||
908 | gr_def(ctx, offset, 0x6cfff007); | ||
909 | else if (dev_priv->chipset == 0xac) | ||
910 | gr_def(ctx, offset, 0x0cfff007); | ||
911 | else | ||
912 | gr_def(ctx, offset, 0x0cf7f007); | ||
913 | if (dev_priv->chipset == 0x50) | ||
914 | gr_def(ctx, offset + 0x4, 0x00007fff); | ||
915 | else if (dev_priv->chipset < 0xa0) | ||
916 | gr_def(ctx, offset + 0x4, 0x003f7fff); | ||
917 | else | ||
918 | gr_def(ctx, offset + 0x4, 0x02bf7fff); | ||
919 | cp_ctx(ctx, offset + 0x2c, 1); | ||
920 | if (dev_priv->chipset == 0x50) { | ||
921 | cp_ctx(ctx, offset + 0x50, 9); | ||
922 | gr_def(ctx, offset + 0x54, 0x000003ff); | ||
923 | gr_def(ctx, offset + 0x58, 0x00000003); | ||
924 | gr_def(ctx, offset + 0x5c, 0x00000003); | ||
925 | gr_def(ctx, offset + 0x60, 0x000001ff); | ||
926 | gr_def(ctx, offset + 0x64, 0x0000001f); | ||
927 | gr_def(ctx, offset + 0x68, 0x0000000f); | ||
928 | gr_def(ctx, offset + 0x6c, 0x0000000f); | ||
929 | } else if(dev_priv->chipset < 0xa0) { | ||
930 | cp_ctx(ctx, offset + 0x50, 1); | ||
931 | cp_ctx(ctx, offset + 0x70, 1); | ||
932 | } else { | ||
933 | cp_ctx(ctx, offset + 0x50, 1); | ||
934 | cp_ctx(ctx, offset + 0x60, 5); | ||
935 | } | ||
936 | } | ||
937 | } | ||
938 | } | ||
939 | |||
940 | /* | ||
941 | * xfer areas. These are a pain. | ||
942 | * | ||
943 | * There are 2 xfer areas: the first one is big and contains all sorts of | ||
944 | * stuff, the second is small and contains some per-TP context. | ||
945 | * | ||
946 | * Each area is split into 8 "strands". The areas, when saved to grctx, | ||
947 | * are made of 8-word blocks. Each block contains a single word from | ||
948 | * each strand. The strands are independent of each other, their | ||
949 | * addresses are unrelated to each other, and data in them is closely | ||
950 | * packed together. The strand layout varies a bit between cards: here | ||
951 | * and there, a single word is thrown out in the middle and the whole | ||
952 | * strand is offset by a bit from corresponding one on another chipset. | ||
953 | * For this reason, addresses of stuff in strands are almost useless. | ||
954 | * Knowing sequence of stuff and size of gaps between them is much more | ||
955 | * useful, and that's how we build the strands in our generator. | ||
956 | * | ||
957 | * NVA0 takes this mess to a whole new level by cutting the old strands | ||
958 | * into a few dozen pieces [known as genes], rearranging them randomly, | ||
959 | * and putting them back together to make new strands. Hopefully these | ||
960 | * genes correspond more or less directly to the same PGRAPH subunits | ||
961 | * as in 400040 register. | ||
962 | * | ||
963 | * The most common value in default context is 0, and when the genes | ||
964 | * are separated by 0's, gene bounduaries are quite speculative... | ||
965 | * some of them can be clearly deduced, others can be guessed, and yet | ||
966 | * others won't be resolved without figuring out the real meaning of | ||
967 | * given ctxval. For the same reason, ending point of each strand | ||
968 | * is unknown. Except for strand 0, which is the longest strand and | ||
969 | * its end corresponds to end of the whole xfer. | ||
970 | * | ||
971 | * An unsolved mystery is the seek instruction: it takes an argument | ||
972 | * in bits 8-18, and that argument is clearly the place in strands to | ||
973 | * seek to... but the offsets don't seem to correspond to offsets as | ||
974 | * seen in grctx. Perhaps there's another, real, not randomly-changing | ||
975 | * addressing in strands, and the xfer insn just happens to skip over | ||
976 | * the unused bits? NV10-NV30 PIPE comes to mind... | ||
977 | * | ||
978 | * As far as I know, there's no way to access the xfer areas directly | ||
979 | * without the help of ctxprog. | ||
980 | */ | ||
981 | |||
982 | static inline void | ||
983 | xf_emit(struct nouveau_grctx *ctx, int num, uint32_t val) { | ||
984 | int i; | ||
985 | if (val && ctx->mode == NOUVEAU_GRCTX_VALS) | ||
986 | for (i = 0; i < num; i++) | ||
987 | nv_wo32(ctx->dev, ctx->data, ctx->ctxvals_pos + (i << 3), val); | ||
988 | ctx->ctxvals_pos += num << 3; | ||
989 | } | ||
990 | |||
991 | /* Gene declarations... */ | ||
992 | |||
993 | static void nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx); | ||
994 | static void nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx); | ||
995 | static void nv50_graph_construct_gene_unk2(struct nouveau_grctx *ctx); | ||
996 | static void nv50_graph_construct_gene_unk3(struct nouveau_grctx *ctx); | ||
997 | static void nv50_graph_construct_gene_unk4(struct nouveau_grctx *ctx); | ||
998 | static void nv50_graph_construct_gene_unk5(struct nouveau_grctx *ctx); | ||
999 | static void nv50_graph_construct_gene_unk6(struct nouveau_grctx *ctx); | ||
1000 | static void nv50_graph_construct_gene_unk7(struct nouveau_grctx *ctx); | ||
1001 | static void nv50_graph_construct_gene_unk8(struct nouveau_grctx *ctx); | ||
1002 | static void nv50_graph_construct_gene_unk9(struct nouveau_grctx *ctx); | ||
1003 | static void nv50_graph_construct_gene_unk10(struct nouveau_grctx *ctx); | ||
1004 | static void nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx); | ||
1005 | static void nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx); | ||
1006 | |||
1007 | static void | ||
1008 | nv50_graph_construct_xfer1(struct nouveau_grctx *ctx) | ||
1009 | { | ||
1010 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1011 | int i; | ||
1012 | int offset; | ||
1013 | int size = 0; | ||
1014 | uint32_t units = nv_rd32 (ctx->dev, 0x1540); | ||
1015 | |||
1016 | offset = (ctx->ctxvals_pos+0x3f)&~0x3f; | ||
1017 | ctx->ctxvals_base = offset; | ||
1018 | |||
1019 | if (dev_priv->chipset < 0xa0) { | ||
1020 | /* Strand 0 */ | ||
1021 | ctx->ctxvals_pos = offset; | ||
1022 | switch (dev_priv->chipset) { | ||
1023 | case 0x50: | ||
1024 | xf_emit(ctx, 0x99, 0); | ||
1025 | break; | ||
1026 | case 0x84: | ||
1027 | case 0x86: | ||
1028 | xf_emit(ctx, 0x384, 0); | ||
1029 | break; | ||
1030 | case 0x92: | ||
1031 | case 0x94: | ||
1032 | case 0x96: | ||
1033 | case 0x98: | ||
1034 | xf_emit(ctx, 0x380, 0); | ||
1035 | break; | ||
1036 | } | ||
1037 | nv50_graph_construct_gene_m2mf (ctx); | ||
1038 | switch (dev_priv->chipset) { | ||
1039 | case 0x50: | ||
1040 | case 0x84: | ||
1041 | case 0x86: | ||
1042 | case 0x98: | ||
1043 | xf_emit(ctx, 0x4c4, 0); | ||
1044 | break; | ||
1045 | case 0x92: | ||
1046 | case 0x94: | ||
1047 | case 0x96: | ||
1048 | xf_emit(ctx, 0x984, 0); | ||
1049 | break; | ||
1050 | } | ||
1051 | nv50_graph_construct_gene_unk5(ctx); | ||
1052 | if (dev_priv->chipset == 0x50) | ||
1053 | xf_emit(ctx, 0xa, 0); | ||
1054 | else | ||
1055 | xf_emit(ctx, 0xb, 0); | ||
1056 | nv50_graph_construct_gene_unk4(ctx); | ||
1057 | nv50_graph_construct_gene_unk3(ctx); | ||
1058 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1059 | size = (ctx->ctxvals_pos-offset)/8; | ||
1060 | |||
1061 | /* Strand 1 */ | ||
1062 | ctx->ctxvals_pos = offset + 0x1; | ||
1063 | nv50_graph_construct_gene_unk6(ctx); | ||
1064 | nv50_graph_construct_gene_unk7(ctx); | ||
1065 | nv50_graph_construct_gene_unk8(ctx); | ||
1066 | switch (dev_priv->chipset) { | ||
1067 | case 0x50: | ||
1068 | case 0x92: | ||
1069 | xf_emit(ctx, 0xfb, 0); | ||
1070 | break; | ||
1071 | case 0x84: | ||
1072 | xf_emit(ctx, 0xd3, 0); | ||
1073 | break; | ||
1074 | case 0x94: | ||
1075 | case 0x96: | ||
1076 | xf_emit(ctx, 0xab, 0); | ||
1077 | break; | ||
1078 | case 0x86: | ||
1079 | case 0x98: | ||
1080 | xf_emit(ctx, 0x6b, 0); | ||
1081 | break; | ||
1082 | } | ||
1083 | xf_emit(ctx, 2, 0x4e3bfdf); | ||
1084 | xf_emit(ctx, 4, 0); | ||
1085 | xf_emit(ctx, 1, 0x0fac6881); | ||
1086 | xf_emit(ctx, 0xb, 0); | ||
1087 | xf_emit(ctx, 2, 0x4e3bfdf); | ||
1088 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1089 | size = (ctx->ctxvals_pos-offset)/8; | ||
1090 | |||
1091 | /* Strand 2 */ | ||
1092 | ctx->ctxvals_pos = offset + 0x2; | ||
1093 | switch (dev_priv->chipset) { | ||
1094 | case 0x50: | ||
1095 | case 0x92: | ||
1096 | xf_emit(ctx, 0xa80, 0); | ||
1097 | break; | ||
1098 | case 0x84: | ||
1099 | xf_emit(ctx, 0xa7e, 0); | ||
1100 | break; | ||
1101 | case 0x94: | ||
1102 | case 0x96: | ||
1103 | xf_emit(ctx, 0xa7c, 0); | ||
1104 | break; | ||
1105 | case 0x86: | ||
1106 | case 0x98: | ||
1107 | xf_emit(ctx, 0xa7a, 0); | ||
1108 | break; | ||
1109 | } | ||
1110 | xf_emit(ctx, 1, 0x3fffff); | ||
1111 | xf_emit(ctx, 2, 0); | ||
1112 | xf_emit(ctx, 1, 0x1fff); | ||
1113 | xf_emit(ctx, 0xe, 0); | ||
1114 | nv50_graph_construct_gene_unk9(ctx); | ||
1115 | nv50_graph_construct_gene_unk2(ctx); | ||
1116 | nv50_graph_construct_gene_unk1(ctx); | ||
1117 | nv50_graph_construct_gene_unk10(ctx); | ||
1118 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1119 | size = (ctx->ctxvals_pos-offset)/8; | ||
1120 | |||
1121 | /* Strand 3: per-ROP group state */ | ||
1122 | ctx->ctxvals_pos = offset + 3; | ||
1123 | for (i = 0; i < 6; i++) | ||
1124 | if (units & (1 << (i + 16))) | ||
1125 | nv50_graph_construct_gene_ropc(ctx); | ||
1126 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1127 | size = (ctx->ctxvals_pos-offset)/8; | ||
1128 | |||
1129 | /* Strands 4-7: per-TP state */ | ||
1130 | for (i = 0; i < 4; i++) { | ||
1131 | ctx->ctxvals_pos = offset + 4 + i; | ||
1132 | if (units & (1 << (2 * i))) | ||
1133 | nv50_graph_construct_xfer_tp(ctx); | ||
1134 | if (units & (1 << (2 * i + 1))) | ||
1135 | nv50_graph_construct_xfer_tp(ctx); | ||
1136 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1137 | size = (ctx->ctxvals_pos-offset)/8; | ||
1138 | } | ||
1139 | } else { | ||
1140 | /* Strand 0 */ | ||
1141 | ctx->ctxvals_pos = offset; | ||
1142 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1143 | xf_emit(ctx, 0x385, 0); | ||
1144 | else | ||
1145 | xf_emit(ctx, 0x384, 0); | ||
1146 | nv50_graph_construct_gene_m2mf(ctx); | ||
1147 | xf_emit(ctx, 0x950, 0); | ||
1148 | nv50_graph_construct_gene_unk10(ctx); | ||
1149 | xf_emit(ctx, 1, 0x0fac6881); | ||
1150 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
1151 | xf_emit(ctx, 1, 1); | ||
1152 | xf_emit(ctx, 3, 0); | ||
1153 | } | ||
1154 | nv50_graph_construct_gene_unk8(ctx); | ||
1155 | if (dev_priv->chipset == 0xa0) | ||
1156 | xf_emit(ctx, 0x189, 0); | ||
1157 | else if (dev_priv->chipset < 0xa8) | ||
1158 | xf_emit(ctx, 0x99, 0); | ||
1159 | else if (dev_priv->chipset == 0xaa) | ||
1160 | xf_emit(ctx, 0x65, 0); | ||
1161 | else | ||
1162 | xf_emit(ctx, 0x6d, 0); | ||
1163 | nv50_graph_construct_gene_unk9(ctx); | ||
1164 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1165 | size = (ctx->ctxvals_pos-offset)/8; | ||
1166 | |||
1167 | /* Strand 1 */ | ||
1168 | ctx->ctxvals_pos = offset + 1; | ||
1169 | nv50_graph_construct_gene_unk1(ctx); | ||
1170 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1171 | size = (ctx->ctxvals_pos-offset)/8; | ||
1172 | |||
1173 | /* Strand 2 */ | ||
1174 | ctx->ctxvals_pos = offset + 2; | ||
1175 | if (dev_priv->chipset == 0xa0) { | ||
1176 | nv50_graph_construct_gene_unk2(ctx); | ||
1177 | } | ||
1178 | xf_emit(ctx, 0x36, 0); | ||
1179 | nv50_graph_construct_gene_unk5(ctx); | ||
1180 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1181 | size = (ctx->ctxvals_pos-offset)/8; | ||
1182 | |||
1183 | /* Strand 3 */ | ||
1184 | ctx->ctxvals_pos = offset + 3; | ||
1185 | xf_emit(ctx, 1, 0); | ||
1186 | xf_emit(ctx, 1, 1); | ||
1187 | nv50_graph_construct_gene_unk6(ctx); | ||
1188 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1189 | size = (ctx->ctxvals_pos-offset)/8; | ||
1190 | |||
1191 | /* Strand 4 */ | ||
1192 | ctx->ctxvals_pos = offset + 4; | ||
1193 | if (dev_priv->chipset == 0xa0) | ||
1194 | xf_emit(ctx, 0xa80, 0); | ||
1195 | else | ||
1196 | xf_emit(ctx, 0xa7a, 0); | ||
1197 | xf_emit(ctx, 1, 0x3fffff); | ||
1198 | xf_emit(ctx, 2, 0); | ||
1199 | xf_emit(ctx, 1, 0x1fff); | ||
1200 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1201 | size = (ctx->ctxvals_pos-offset)/8; | ||
1202 | |||
1203 | /* Strand 5 */ | ||
1204 | ctx->ctxvals_pos = offset + 5; | ||
1205 | xf_emit(ctx, 1, 0); | ||
1206 | xf_emit(ctx, 1, 0x0fac6881); | ||
1207 | xf_emit(ctx, 0xb, 0); | ||
1208 | xf_emit(ctx, 2, 0x4e3bfdf); | ||
1209 | xf_emit(ctx, 3, 0); | ||
1210 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1211 | xf_emit(ctx, 1, 0x11); | ||
1212 | xf_emit(ctx, 1, 0); | ||
1213 | xf_emit(ctx, 2, 0x4e3bfdf); | ||
1214 | xf_emit(ctx, 2, 0); | ||
1215 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1216 | xf_emit(ctx, 1, 0x11); | ||
1217 | xf_emit(ctx, 1, 0); | ||
1218 | for (i = 0; i < 8; i++) | ||
1219 | if (units & (1<<(i+16))) | ||
1220 | nv50_graph_construct_gene_ropc(ctx); | ||
1221 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1222 | size = (ctx->ctxvals_pos-offset)/8; | ||
1223 | |||
1224 | /* Strand 6 */ | ||
1225 | ctx->ctxvals_pos = offset + 6; | ||
1226 | nv50_graph_construct_gene_unk3(ctx); | ||
1227 | xf_emit(ctx, 0xb, 0); | ||
1228 | nv50_graph_construct_gene_unk4(ctx); | ||
1229 | nv50_graph_construct_gene_unk7(ctx); | ||
1230 | if (units & (1 << 0)) | ||
1231 | nv50_graph_construct_xfer_tp(ctx); | ||
1232 | if (units & (1 << 1)) | ||
1233 | nv50_graph_construct_xfer_tp(ctx); | ||
1234 | if (units & (1 << 2)) | ||
1235 | nv50_graph_construct_xfer_tp(ctx); | ||
1236 | if (units & (1 << 3)) | ||
1237 | nv50_graph_construct_xfer_tp(ctx); | ||
1238 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1239 | size = (ctx->ctxvals_pos-offset)/8; | ||
1240 | |||
1241 | /* Strand 7 */ | ||
1242 | ctx->ctxvals_pos = offset + 7; | ||
1243 | if (dev_priv->chipset == 0xa0) { | ||
1244 | if (units & (1 << 4)) | ||
1245 | nv50_graph_construct_xfer_tp(ctx); | ||
1246 | if (units & (1 << 5)) | ||
1247 | nv50_graph_construct_xfer_tp(ctx); | ||
1248 | if (units & (1 << 6)) | ||
1249 | nv50_graph_construct_xfer_tp(ctx); | ||
1250 | if (units & (1 << 7)) | ||
1251 | nv50_graph_construct_xfer_tp(ctx); | ||
1252 | if (units & (1 << 8)) | ||
1253 | nv50_graph_construct_xfer_tp(ctx); | ||
1254 | if (units & (1 << 9)) | ||
1255 | nv50_graph_construct_xfer_tp(ctx); | ||
1256 | } else { | ||
1257 | nv50_graph_construct_gene_unk2(ctx); | ||
1258 | } | ||
1259 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
1260 | size = (ctx->ctxvals_pos-offset)/8; | ||
1261 | } | ||
1262 | |||
1263 | ctx->ctxvals_pos = offset + size * 8; | ||
1264 | ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f; | ||
1265 | cp_lsr (ctx, offset); | ||
1266 | cp_out (ctx, CP_SET_XFER_POINTER); | ||
1267 | cp_lsr (ctx, size); | ||
1268 | cp_out (ctx, CP_SEEK_1); | ||
1269 | cp_out (ctx, CP_XFER_1); | ||
1270 | cp_wait(ctx, XFER, BUSY); | ||
1271 | } | ||
1272 | |||
1273 | /* | ||
1274 | * non-trivial demagiced parts of ctx init go here | ||
1275 | */ | ||
1276 | |||
1277 | static void | ||
1278 | nv50_graph_construct_gene_m2mf(struct nouveau_grctx *ctx) | ||
1279 | { | ||
1280 | /* m2mf state */ | ||
1281 | xf_emit (ctx, 1, 0); /* DMA_NOTIFY instance >> 4 */ | ||
1282 | xf_emit (ctx, 1, 0); /* DMA_BUFFER_IN instance >> 4 */ | ||
1283 | xf_emit (ctx, 1, 0); /* DMA_BUFFER_OUT instance >> 4 */ | ||
1284 | xf_emit (ctx, 1, 0); /* OFFSET_IN */ | ||
1285 | xf_emit (ctx, 1, 0); /* OFFSET_OUT */ | ||
1286 | xf_emit (ctx, 1, 0); /* PITCH_IN */ | ||
1287 | xf_emit (ctx, 1, 0); /* PITCH_OUT */ | ||
1288 | xf_emit (ctx, 1, 0); /* LINE_LENGTH */ | ||
1289 | xf_emit (ctx, 1, 0); /* LINE_COUNT */ | ||
1290 | xf_emit (ctx, 1, 0x21); /* FORMAT: bits 0-4 INPUT_INC, bits 5-9 OUTPUT_INC */ | ||
1291 | xf_emit (ctx, 1, 1); /* LINEAR_IN */ | ||
1292 | xf_emit (ctx, 1, 0x2); /* TILING_MODE_IN: bits 0-2 y tiling, bits 3-5 z tiling */ | ||
1293 | xf_emit (ctx, 1, 0x100); /* TILING_PITCH_IN */ | ||
1294 | xf_emit (ctx, 1, 0x100); /* TILING_HEIGHT_IN */ | ||
1295 | xf_emit (ctx, 1, 1); /* TILING_DEPTH_IN */ | ||
1296 | xf_emit (ctx, 1, 0); /* TILING_POSITION_IN_Z */ | ||
1297 | xf_emit (ctx, 1, 0); /* TILING_POSITION_IN */ | ||
1298 | xf_emit (ctx, 1, 1); /* LINEAR_OUT */ | ||
1299 | xf_emit (ctx, 1, 0x2); /* TILING_MODE_OUT: bits 0-2 y tiling, bits 3-5 z tiling */ | ||
1300 | xf_emit (ctx, 1, 0x100); /* TILING_PITCH_OUT */ | ||
1301 | xf_emit (ctx, 1, 0x100); /* TILING_HEIGHT_OUT */ | ||
1302 | xf_emit (ctx, 1, 1); /* TILING_DEPTH_OUT */ | ||
1303 | xf_emit (ctx, 1, 0); /* TILING_POSITION_OUT_Z */ | ||
1304 | xf_emit (ctx, 1, 0); /* TILING_POSITION_OUT */ | ||
1305 | xf_emit (ctx, 1, 0); /* OFFSET_IN_HIGH */ | ||
1306 | xf_emit (ctx, 1, 0); /* OFFSET_OUT_HIGH */ | ||
1307 | } | ||
1308 | |||
1309 | static void | ||
1310 | nv50_graph_construct_gene_unk1(struct nouveau_grctx *ctx) | ||
1311 | { | ||
1312 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1313 | /* end of area 2 on pre-NVA0, area 1 on NVAx */ | ||
1314 | xf_emit(ctx, 2, 4); | ||
1315 | xf_emit(ctx, 1, 0); | ||
1316 | xf_emit(ctx, 1, 0x80); | ||
1317 | xf_emit(ctx, 1, 4); | ||
1318 | xf_emit(ctx, 1, 0x80c14); | ||
1319 | xf_emit(ctx, 1, 0); | ||
1320 | if (dev_priv->chipset == 0x50) | ||
1321 | xf_emit(ctx, 1, 0x3ff); | ||
1322 | else | ||
1323 | xf_emit(ctx, 1, 0x7ff); | ||
1324 | switch (dev_priv->chipset) { | ||
1325 | case 0x50: | ||
1326 | case 0x86: | ||
1327 | case 0x98: | ||
1328 | case 0xaa: | ||
1329 | case 0xac: | ||
1330 | xf_emit(ctx, 0x542, 0); | ||
1331 | break; | ||
1332 | case 0x84: | ||
1333 | case 0x92: | ||
1334 | case 0x94: | ||
1335 | case 0x96: | ||
1336 | xf_emit(ctx, 0x942, 0); | ||
1337 | break; | ||
1338 | case 0xa0: | ||
1339 | xf_emit(ctx, 0x2042, 0); | ||
1340 | break; | ||
1341 | case 0xa5: | ||
1342 | case 0xa8: | ||
1343 | xf_emit(ctx, 0x842, 0); | ||
1344 | break; | ||
1345 | } | ||
1346 | xf_emit(ctx, 2, 4); | ||
1347 | xf_emit(ctx, 1, 0); | ||
1348 | xf_emit(ctx, 1, 0x80); | ||
1349 | xf_emit(ctx, 1, 4); | ||
1350 | xf_emit(ctx, 1, 1); | ||
1351 | xf_emit(ctx, 1, 0); | ||
1352 | xf_emit(ctx, 1, 0x27); | ||
1353 | xf_emit(ctx, 1, 0); | ||
1354 | xf_emit(ctx, 1, 0x26); | ||
1355 | xf_emit(ctx, 3, 0); | ||
1356 | } | ||
1357 | |||
1358 | static void | ||
1359 | nv50_graph_construct_gene_unk10(struct nouveau_grctx *ctx) | ||
1360 | { | ||
1361 | /* end of area 2 on pre-NVA0, area 1 on NVAx */ | ||
1362 | xf_emit(ctx, 0x10, 0x04000000); | ||
1363 | xf_emit(ctx, 0x24, 0); | ||
1364 | xf_emit(ctx, 2, 0x04e3bfdf); | ||
1365 | xf_emit(ctx, 2, 0); | ||
1366 | xf_emit(ctx, 1, 0x1fe21); | ||
1367 | } | ||
1368 | |||
1369 | static void | ||
1370 | nv50_graph_construct_gene_unk2(struct nouveau_grctx *ctx) | ||
1371 | { | ||
1372 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1373 | /* middle of area 2 on pre-NVA0, beginning of area 2 on NVA0, area 7 on >NVA0 */ | ||
1374 | if (dev_priv->chipset != 0x50) { | ||
1375 | xf_emit(ctx, 5, 0); | ||
1376 | xf_emit(ctx, 1, 0x80c14); | ||
1377 | xf_emit(ctx, 2, 0); | ||
1378 | xf_emit(ctx, 1, 0x804); | ||
1379 | xf_emit(ctx, 1, 0); | ||
1380 | xf_emit(ctx, 2, 4); | ||
1381 | xf_emit(ctx, 1, 0x8100c12); | ||
1382 | } | ||
1383 | xf_emit(ctx, 1, 0); | ||
1384 | xf_emit(ctx, 2, 4); | ||
1385 | xf_emit(ctx, 1, 0); | ||
1386 | xf_emit(ctx, 1, 0x10); | ||
1387 | if (dev_priv->chipset == 0x50) | ||
1388 | xf_emit(ctx, 3, 0); | ||
1389 | else | ||
1390 | xf_emit(ctx, 4, 0); | ||
1391 | xf_emit(ctx, 1, 0x804); | ||
1392 | xf_emit(ctx, 1, 1); | ||
1393 | xf_emit(ctx, 1, 0x1a); | ||
1394 | if (dev_priv->chipset != 0x50) | ||
1395 | xf_emit(ctx, 1, 0x7f); | ||
1396 | xf_emit(ctx, 1, 0); | ||
1397 | xf_emit(ctx, 1, 1); | ||
1398 | xf_emit(ctx, 1, 0x80c14); | ||
1399 | xf_emit(ctx, 1, 0); | ||
1400 | xf_emit(ctx, 1, 0x8100c12); | ||
1401 | xf_emit(ctx, 2, 4); | ||
1402 | xf_emit(ctx, 1, 0); | ||
1403 | xf_emit(ctx, 1, 0x10); | ||
1404 | xf_emit(ctx, 3, 0); | ||
1405 | xf_emit(ctx, 1, 1); | ||
1406 | xf_emit(ctx, 1, 0x8100c12); | ||
1407 | xf_emit(ctx, 6, 0); | ||
1408 | if (dev_priv->chipset == 0x50) | ||
1409 | xf_emit(ctx, 1, 0x3ff); | ||
1410 | else | ||
1411 | xf_emit(ctx, 1, 0x7ff); | ||
1412 | xf_emit(ctx, 1, 0x80c14); | ||
1413 | xf_emit(ctx, 0x38, 0); | ||
1414 | xf_emit(ctx, 1, 1); | ||
1415 | xf_emit(ctx, 2, 0); | ||
1416 | xf_emit(ctx, 1, 0x10); | ||
1417 | xf_emit(ctx, 0x38, 0); | ||
1418 | xf_emit(ctx, 2, 0x88); | ||
1419 | xf_emit(ctx, 2, 0); | ||
1420 | xf_emit(ctx, 1, 4); | ||
1421 | xf_emit(ctx, 0x16, 0); | ||
1422 | xf_emit(ctx, 1, 0x26); | ||
1423 | xf_emit(ctx, 2, 0); | ||
1424 | xf_emit(ctx, 1, 0x3f800000); | ||
1425 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1426 | xf_emit(ctx, 4, 0); | ||
1427 | else | ||
1428 | xf_emit(ctx, 3, 0); | ||
1429 | xf_emit(ctx, 1, 0x1a); | ||
1430 | xf_emit(ctx, 1, 0x10); | ||
1431 | if (dev_priv->chipset != 0x50) | ||
1432 | xf_emit(ctx, 0x28, 0); | ||
1433 | else | ||
1434 | xf_emit(ctx, 0x25, 0); | ||
1435 | xf_emit(ctx, 1, 0x52); | ||
1436 | xf_emit(ctx, 1, 0); | ||
1437 | xf_emit(ctx, 1, 0x26); | ||
1438 | xf_emit(ctx, 1, 0); | ||
1439 | xf_emit(ctx, 2, 4); | ||
1440 | xf_emit(ctx, 1, 0); | ||
1441 | xf_emit(ctx, 1, 0x1a); | ||
1442 | xf_emit(ctx, 2, 0); | ||
1443 | xf_emit(ctx, 1, 0x00ffff00); | ||
1444 | xf_emit(ctx, 1, 0); | ||
1445 | } | ||
1446 | |||
1447 | static void | ||
1448 | nv50_graph_construct_gene_unk3(struct nouveau_grctx *ctx) | ||
1449 | { | ||
1450 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1451 | /* end of area 0 on pre-NVA0, beginning of area 6 on NVAx */ | ||
1452 | xf_emit(ctx, 1, 0x3f); | ||
1453 | xf_emit(ctx, 0xa, 0); | ||
1454 | xf_emit(ctx, 1, 2); | ||
1455 | xf_emit(ctx, 2, 0x04000000); | ||
1456 | xf_emit(ctx, 8, 0); | ||
1457 | xf_emit(ctx, 1, 4); | ||
1458 | xf_emit(ctx, 3, 0); | ||
1459 | xf_emit(ctx, 1, 4); | ||
1460 | if (dev_priv->chipset == 0x50) | ||
1461 | xf_emit(ctx, 0x10, 0); | ||
1462 | else | ||
1463 | xf_emit(ctx, 0x11, 0); | ||
1464 | xf_emit(ctx, 1, 1); | ||
1465 | xf_emit(ctx, 1, 0x1001); | ||
1466 | xf_emit(ctx, 4, 0xffff); | ||
1467 | xf_emit(ctx, 0x20, 0); | ||
1468 | xf_emit(ctx, 0x10, 0x3f800000); | ||
1469 | xf_emit(ctx, 1, 0x10); | ||
1470 | if (dev_priv->chipset == 0x50) | ||
1471 | xf_emit(ctx, 1, 0); | ||
1472 | else | ||
1473 | xf_emit(ctx, 2, 0); | ||
1474 | xf_emit(ctx, 1, 3); | ||
1475 | xf_emit(ctx, 2, 0); | ||
1476 | } | ||
1477 | |||
1478 | static void | ||
1479 | nv50_graph_construct_gene_unk4(struct nouveau_grctx *ctx) | ||
1480 | { | ||
1481 | /* middle of area 0 on pre-NVA0, middle of area 6 on NVAx */ | ||
1482 | xf_emit(ctx, 2, 0x04000000); | ||
1483 | xf_emit(ctx, 1, 0); | ||
1484 | xf_emit(ctx, 1, 0x80); | ||
1485 | xf_emit(ctx, 3, 0); | ||
1486 | xf_emit(ctx, 1, 0x80); | ||
1487 | xf_emit(ctx, 1, 0); | ||
1488 | } | ||
1489 | |||
1490 | static void | ||
1491 | nv50_graph_construct_gene_unk5(struct nouveau_grctx *ctx) | ||
1492 | { | ||
1493 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1494 | /* middle of area 0 on pre-NVA0 [after m2mf], end of area 2 on NVAx */ | ||
1495 | xf_emit(ctx, 2, 4); | ||
1496 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1497 | xf_emit(ctx, 0x1c4d, 0); | ||
1498 | else | ||
1499 | xf_emit(ctx, 0x1c4b, 0); | ||
1500 | xf_emit(ctx, 2, 4); | ||
1501 | xf_emit(ctx, 1, 0x8100c12); | ||
1502 | if (dev_priv->chipset != 0x50) | ||
1503 | xf_emit(ctx, 1, 3); | ||
1504 | xf_emit(ctx, 1, 0); | ||
1505 | xf_emit(ctx, 1, 0x8100c12); | ||
1506 | xf_emit(ctx, 1, 0); | ||
1507 | xf_emit(ctx, 1, 0x80c14); | ||
1508 | xf_emit(ctx, 1, 1); | ||
1509 | if (dev_priv->chipset >= 0xa0) | ||
1510 | xf_emit(ctx, 2, 4); | ||
1511 | xf_emit(ctx, 1, 0x80c14); | ||
1512 | xf_emit(ctx, 2, 0); | ||
1513 | xf_emit(ctx, 1, 0x8100c12); | ||
1514 | xf_emit(ctx, 1, 0x27); | ||
1515 | xf_emit(ctx, 2, 0); | ||
1516 | xf_emit(ctx, 1, 1); | ||
1517 | xf_emit(ctx, 0x3c1, 0); | ||
1518 | xf_emit(ctx, 1, 1); | ||
1519 | xf_emit(ctx, 0x16, 0); | ||
1520 | xf_emit(ctx, 1, 0x8100c12); | ||
1521 | xf_emit(ctx, 1, 0); | ||
1522 | } | ||
1523 | |||
1524 | static void | ||
1525 | nv50_graph_construct_gene_unk6(struct nouveau_grctx *ctx) | ||
1526 | { | ||
1527 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1528 | /* beginning of area 1 on pre-NVA0 [after m2mf], area 3 on NVAx */ | ||
1529 | xf_emit(ctx, 4, 0); | ||
1530 | xf_emit(ctx, 1, 0xf); | ||
1531 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1532 | xf_emit(ctx, 8, 0); | ||
1533 | else | ||
1534 | xf_emit(ctx, 4, 0); | ||
1535 | xf_emit(ctx, 1, 0x20); | ||
1536 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1537 | xf_emit(ctx, 0x11, 0); | ||
1538 | else if (dev_priv->chipset >= 0xa0) | ||
1539 | xf_emit(ctx, 0xf, 0); | ||
1540 | else | ||
1541 | xf_emit(ctx, 0xe, 0); | ||
1542 | xf_emit(ctx, 1, 0x1a); | ||
1543 | xf_emit(ctx, 0xd, 0); | ||
1544 | xf_emit(ctx, 2, 4); | ||
1545 | xf_emit(ctx, 1, 0); | ||
1546 | xf_emit(ctx, 1, 4); | ||
1547 | xf_emit(ctx, 1, 8); | ||
1548 | xf_emit(ctx, 1, 0); | ||
1549 | if (dev_priv->chipset == 0x50) | ||
1550 | xf_emit(ctx, 1, 0x3ff); | ||
1551 | else | ||
1552 | xf_emit(ctx, 1, 0x7ff); | ||
1553 | if (dev_priv->chipset == 0xa8) | ||
1554 | xf_emit(ctx, 1, 0x1e00); | ||
1555 | xf_emit(ctx, 0xc, 0); | ||
1556 | xf_emit(ctx, 1, 0xf); | ||
1557 | if (dev_priv->chipset == 0x50) | ||
1558 | xf_emit(ctx, 0x125, 0); | ||
1559 | else if (dev_priv->chipset < 0xa0) | ||
1560 | xf_emit(ctx, 0x126, 0); | ||
1561 | else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) | ||
1562 | xf_emit(ctx, 0x124, 0); | ||
1563 | else | ||
1564 | xf_emit(ctx, 0x1f7, 0); | ||
1565 | xf_emit(ctx, 1, 0xf); | ||
1566 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1567 | xf_emit(ctx, 3, 0); | ||
1568 | else | ||
1569 | xf_emit(ctx, 1, 0); | ||
1570 | xf_emit(ctx, 1, 1); | ||
1571 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1572 | xf_emit(ctx, 0xa1, 0); | ||
1573 | else | ||
1574 | xf_emit(ctx, 0x5a, 0); | ||
1575 | xf_emit(ctx, 1, 0xf); | ||
1576 | if (dev_priv->chipset < 0xa0) | ||
1577 | xf_emit(ctx, 0x834, 0); | ||
1578 | else if (dev_priv->chipset == 0xa0) | ||
1579 | xf_emit(ctx, 0x1873, 0); | ||
1580 | else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1581 | xf_emit(ctx, 0x8ba, 0); | ||
1582 | else | ||
1583 | xf_emit(ctx, 0x833, 0); | ||
1584 | xf_emit(ctx, 1, 0xf); | ||
1585 | xf_emit(ctx, 0xf, 0); | ||
1586 | } | ||
1587 | |||
1588 | static void | ||
1589 | nv50_graph_construct_gene_unk7(struct nouveau_grctx *ctx) | ||
1590 | { | ||
1591 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1592 | /* middle of area 1 on pre-NVA0 [after m2mf], middle of area 6 on NVAx */ | ||
1593 | xf_emit(ctx, 2, 0); | ||
1594 | if (dev_priv->chipset == 0x50) | ||
1595 | xf_emit(ctx, 2, 1); | ||
1596 | else | ||
1597 | xf_emit(ctx, 2, 0); | ||
1598 | xf_emit(ctx, 1, 0); | ||
1599 | xf_emit(ctx, 1, 1); | ||
1600 | xf_emit(ctx, 2, 0x100); | ||
1601 | xf_emit(ctx, 1, 0x11); | ||
1602 | xf_emit(ctx, 1, 0); | ||
1603 | xf_emit(ctx, 1, 8); | ||
1604 | xf_emit(ctx, 5, 0); | ||
1605 | xf_emit(ctx, 1, 1); | ||
1606 | xf_emit(ctx, 1, 0); | ||
1607 | xf_emit(ctx, 3, 1); | ||
1608 | xf_emit(ctx, 1, 0xcf); | ||
1609 | xf_emit(ctx, 1, 2); | ||
1610 | xf_emit(ctx, 6, 0); | ||
1611 | xf_emit(ctx, 1, 1); | ||
1612 | xf_emit(ctx, 1, 0); | ||
1613 | xf_emit(ctx, 3, 1); | ||
1614 | xf_emit(ctx, 4, 0); | ||
1615 | xf_emit(ctx, 1, 4); | ||
1616 | xf_emit(ctx, 1, 0); | ||
1617 | xf_emit(ctx, 1, 1); | ||
1618 | xf_emit(ctx, 1, 0x15); | ||
1619 | xf_emit(ctx, 3, 0); | ||
1620 | xf_emit(ctx, 1, 0x4444480); | ||
1621 | xf_emit(ctx, 0x37, 0); | ||
1622 | } | ||
1623 | |||
1624 | static void | ||
1625 | nv50_graph_construct_gene_unk8(struct nouveau_grctx *ctx) | ||
1626 | { | ||
1627 | /* middle of area 1 on pre-NVA0 [after m2mf], middle of area 0 on NVAx */ | ||
1628 | xf_emit(ctx, 4, 0); | ||
1629 | xf_emit(ctx, 1, 0x8100c12); | ||
1630 | xf_emit(ctx, 4, 0); | ||
1631 | xf_emit(ctx, 1, 0x100); | ||
1632 | xf_emit(ctx, 2, 0); | ||
1633 | xf_emit(ctx, 1, 0x10001); | ||
1634 | xf_emit(ctx, 1, 0); | ||
1635 | xf_emit(ctx, 1, 0x10001); | ||
1636 | xf_emit(ctx, 1, 1); | ||
1637 | xf_emit(ctx, 1, 0x10001); | ||
1638 | xf_emit(ctx, 1, 1); | ||
1639 | xf_emit(ctx, 1, 4); | ||
1640 | xf_emit(ctx, 1, 2); | ||
1641 | } | ||
1642 | |||
1643 | static void | ||
1644 | nv50_graph_construct_gene_unk9(struct nouveau_grctx *ctx) | ||
1645 | { | ||
1646 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1647 | /* middle of area 2 on pre-NVA0 [after m2mf], end of area 0 on NVAx */ | ||
1648 | xf_emit(ctx, 1, 0x3f800000); | ||
1649 | xf_emit(ctx, 6, 0); | ||
1650 | xf_emit(ctx, 1, 4); | ||
1651 | xf_emit(ctx, 1, 0x1a); | ||
1652 | xf_emit(ctx, 2, 0); | ||
1653 | xf_emit(ctx, 1, 1); | ||
1654 | xf_emit(ctx, 0x12, 0); | ||
1655 | xf_emit(ctx, 1, 0x00ffff00); | ||
1656 | xf_emit(ctx, 6, 0); | ||
1657 | xf_emit(ctx, 1, 0xf); | ||
1658 | xf_emit(ctx, 7, 0); | ||
1659 | xf_emit(ctx, 1, 0x0fac6881); | ||
1660 | xf_emit(ctx, 1, 0x11); | ||
1661 | xf_emit(ctx, 0xf, 0); | ||
1662 | xf_emit(ctx, 1, 4); | ||
1663 | xf_emit(ctx, 2, 0); | ||
1664 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1665 | xf_emit(ctx, 1, 3); | ||
1666 | else if (dev_priv->chipset >= 0xa0) | ||
1667 | xf_emit(ctx, 1, 1); | ||
1668 | xf_emit(ctx, 2, 0); | ||
1669 | xf_emit(ctx, 1, 2); | ||
1670 | xf_emit(ctx, 2, 0x04000000); | ||
1671 | xf_emit(ctx, 3, 0); | ||
1672 | xf_emit(ctx, 1, 5); | ||
1673 | xf_emit(ctx, 1, 0x52); | ||
1674 | if (dev_priv->chipset == 0x50) { | ||
1675 | xf_emit(ctx, 0x13, 0); | ||
1676 | } else { | ||
1677 | xf_emit(ctx, 4, 0); | ||
1678 | xf_emit(ctx, 1, 1); | ||
1679 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1680 | xf_emit(ctx, 0x11, 0); | ||
1681 | else | ||
1682 | xf_emit(ctx, 0x10, 0); | ||
1683 | } | ||
1684 | xf_emit(ctx, 0x10, 0x3f800000); | ||
1685 | xf_emit(ctx, 1, 0x10); | ||
1686 | xf_emit(ctx, 0x26, 0); | ||
1687 | xf_emit(ctx, 1, 0x8100c12); | ||
1688 | xf_emit(ctx, 1, 5); | ||
1689 | xf_emit(ctx, 2, 0); | ||
1690 | xf_emit(ctx, 1, 1); | ||
1691 | xf_emit(ctx, 1, 0); | ||
1692 | xf_emit(ctx, 4, 0xffff); | ||
1693 | if (dev_priv->chipset != 0x50) | ||
1694 | xf_emit(ctx, 1, 3); | ||
1695 | if (dev_priv->chipset < 0xa0) | ||
1696 | xf_emit(ctx, 0x1f, 0); | ||
1697 | else if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1698 | xf_emit(ctx, 0xc, 0); | ||
1699 | else | ||
1700 | xf_emit(ctx, 3, 0); | ||
1701 | xf_emit(ctx, 1, 0x00ffff00); | ||
1702 | xf_emit(ctx, 1, 0x1a); | ||
1703 | if (dev_priv->chipset != 0x50) { | ||
1704 | xf_emit(ctx, 1, 0); | ||
1705 | xf_emit(ctx, 1, 3); | ||
1706 | } | ||
1707 | if (dev_priv->chipset < 0xa0) | ||
1708 | xf_emit(ctx, 0x26, 0); | ||
1709 | else | ||
1710 | xf_emit(ctx, 0x3c, 0); | ||
1711 | xf_emit(ctx, 1, 0x102); | ||
1712 | xf_emit(ctx, 1, 0); | ||
1713 | xf_emit(ctx, 4, 4); | ||
1714 | if (dev_priv->chipset >= 0xa0) | ||
1715 | xf_emit(ctx, 8, 0); | ||
1716 | xf_emit(ctx, 2, 4); | ||
1717 | xf_emit(ctx, 1, 0); | ||
1718 | if (dev_priv->chipset == 0x50) | ||
1719 | xf_emit(ctx, 1, 0x3ff); | ||
1720 | else | ||
1721 | xf_emit(ctx, 1, 0x7ff); | ||
1722 | xf_emit(ctx, 1, 0); | ||
1723 | xf_emit(ctx, 1, 0x102); | ||
1724 | xf_emit(ctx, 9, 0); | ||
1725 | xf_emit(ctx, 4, 4); | ||
1726 | xf_emit(ctx, 0x2c, 0); | ||
1727 | } | ||
1728 | |||
1729 | static void | ||
1730 | nv50_graph_construct_gene_ropc(struct nouveau_grctx *ctx) | ||
1731 | { | ||
1732 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1733 | int magic2; | ||
1734 | if (dev_priv->chipset == 0x50) { | ||
1735 | magic2 = 0x00003e60; | ||
1736 | } else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) { | ||
1737 | magic2 = 0x001ffe67; | ||
1738 | } else { | ||
1739 | magic2 = 0x00087e67; | ||
1740 | } | ||
1741 | xf_emit(ctx, 8, 0); | ||
1742 | xf_emit(ctx, 1, 2); | ||
1743 | xf_emit(ctx, 1, 0); | ||
1744 | xf_emit(ctx, 1, magic2); | ||
1745 | xf_emit(ctx, 4, 0); | ||
1746 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1747 | xf_emit(ctx, 1, 1); | ||
1748 | xf_emit(ctx, 7, 0); | ||
1749 | if (dev_priv->chipset >= 0xa0 && dev_priv->chipset < 0xaa) | ||
1750 | xf_emit(ctx, 1, 0x15); | ||
1751 | xf_emit(ctx, 1, 0); | ||
1752 | xf_emit(ctx, 1, 1); | ||
1753 | xf_emit(ctx, 1, 0x10); | ||
1754 | xf_emit(ctx, 2, 0); | ||
1755 | xf_emit(ctx, 1, 1); | ||
1756 | xf_emit(ctx, 4, 0); | ||
1757 | if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x92 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa0) { | ||
1758 | xf_emit(ctx, 1, 4); | ||
1759 | xf_emit(ctx, 1, 0x400); | ||
1760 | xf_emit(ctx, 1, 0x300); | ||
1761 | xf_emit(ctx, 1, 0x1001); | ||
1762 | if (dev_priv->chipset != 0xa0) { | ||
1763 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1764 | xf_emit(ctx, 1, 0); | ||
1765 | else | ||
1766 | xf_emit(ctx, 1, 0x15); | ||
1767 | } | ||
1768 | xf_emit(ctx, 3, 0); | ||
1769 | } | ||
1770 | xf_emit(ctx, 2, 0); | ||
1771 | xf_emit(ctx, 1, 2); | ||
1772 | xf_emit(ctx, 8, 0); | ||
1773 | xf_emit(ctx, 1, 1); | ||
1774 | xf_emit(ctx, 1, 0x10); | ||
1775 | xf_emit(ctx, 1, 0); | ||
1776 | xf_emit(ctx, 1, 1); | ||
1777 | xf_emit(ctx, 0x13, 0); | ||
1778 | xf_emit(ctx, 1, 0x10); | ||
1779 | xf_emit(ctx, 0x10, 0); | ||
1780 | xf_emit(ctx, 0x10, 0x3f800000); | ||
1781 | xf_emit(ctx, 0x19, 0); | ||
1782 | xf_emit(ctx, 1, 0x10); | ||
1783 | xf_emit(ctx, 1, 0); | ||
1784 | xf_emit(ctx, 1, 0x3f); | ||
1785 | xf_emit(ctx, 6, 0); | ||
1786 | xf_emit(ctx, 1, 1); | ||
1787 | xf_emit(ctx, 1, 0); | ||
1788 | xf_emit(ctx, 1, 1); | ||
1789 | xf_emit(ctx, 1, 0); | ||
1790 | xf_emit(ctx, 1, 1); | ||
1791 | if (dev_priv->chipset >= 0xa0) { | ||
1792 | xf_emit(ctx, 2, 0); | ||
1793 | xf_emit(ctx, 1, 0x1001); | ||
1794 | xf_emit(ctx, 0xb, 0); | ||
1795 | } else { | ||
1796 | xf_emit(ctx, 0xc, 0); | ||
1797 | } | ||
1798 | xf_emit(ctx, 1, 0x11); | ||
1799 | xf_emit(ctx, 7, 0); | ||
1800 | xf_emit(ctx, 1, 0xf); | ||
1801 | xf_emit(ctx, 7, 0); | ||
1802 | xf_emit(ctx, 1, 0x11); | ||
1803 | if (dev_priv->chipset == 0x50) | ||
1804 | xf_emit(ctx, 4, 0); | ||
1805 | else | ||
1806 | xf_emit(ctx, 6, 0); | ||
1807 | xf_emit(ctx, 3, 1); | ||
1808 | xf_emit(ctx, 1, 2); | ||
1809 | xf_emit(ctx, 1, 1); | ||
1810 | xf_emit(ctx, 1, 2); | ||
1811 | xf_emit(ctx, 1, 1); | ||
1812 | xf_emit(ctx, 1, 0); | ||
1813 | xf_emit(ctx, 1, magic2); | ||
1814 | xf_emit(ctx, 1, 0); | ||
1815 | xf_emit(ctx, 1, 0x0fac6881); | ||
1816 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
1817 | xf_emit(ctx, 1, 0); | ||
1818 | xf_emit(ctx, 0x18, 1); | ||
1819 | xf_emit(ctx, 8, 2); | ||
1820 | xf_emit(ctx, 8, 1); | ||
1821 | xf_emit(ctx, 8, 2); | ||
1822 | xf_emit(ctx, 8, 1); | ||
1823 | xf_emit(ctx, 3, 0); | ||
1824 | xf_emit(ctx, 1, 1); | ||
1825 | xf_emit(ctx, 5, 0); | ||
1826 | xf_emit(ctx, 1, 1); | ||
1827 | xf_emit(ctx, 0x16, 0); | ||
1828 | } else { | ||
1829 | if (dev_priv->chipset >= 0xa0) | ||
1830 | xf_emit(ctx, 0x1b, 0); | ||
1831 | else | ||
1832 | xf_emit(ctx, 0x15, 0); | ||
1833 | } | ||
1834 | xf_emit(ctx, 1, 1); | ||
1835 | xf_emit(ctx, 1, 2); | ||
1836 | xf_emit(ctx, 2, 1); | ||
1837 | xf_emit(ctx, 1, 2); | ||
1838 | xf_emit(ctx, 2, 1); | ||
1839 | if (dev_priv->chipset >= 0xa0) | ||
1840 | xf_emit(ctx, 4, 0); | ||
1841 | else | ||
1842 | xf_emit(ctx, 3, 0); | ||
1843 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
1844 | xf_emit(ctx, 0x10, 1); | ||
1845 | xf_emit(ctx, 8, 2); | ||
1846 | xf_emit(ctx, 0x10, 1); | ||
1847 | xf_emit(ctx, 8, 2); | ||
1848 | xf_emit(ctx, 8, 1); | ||
1849 | xf_emit(ctx, 3, 0); | ||
1850 | } | ||
1851 | xf_emit(ctx, 1, 0x11); | ||
1852 | xf_emit(ctx, 1, 1); | ||
1853 | xf_emit(ctx, 0x5b, 0); | ||
1854 | } | ||
1855 | |||
1856 | static void | ||
1857 | nv50_graph_construct_xfer_tp_x1(struct nouveau_grctx *ctx) | ||
1858 | { | ||
1859 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1860 | int magic3; | ||
1861 | if (dev_priv->chipset == 0x50) | ||
1862 | magic3 = 0x1000; | ||
1863 | else if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa8) | ||
1864 | magic3 = 0x1e00; | ||
1865 | else | ||
1866 | magic3 = 0; | ||
1867 | xf_emit(ctx, 1, 0); | ||
1868 | xf_emit(ctx, 1, 4); | ||
1869 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1870 | xf_emit(ctx, 0x24, 0); | ||
1871 | else if (dev_priv->chipset >= 0xa0) | ||
1872 | xf_emit(ctx, 0x14, 0); | ||
1873 | else | ||
1874 | xf_emit(ctx, 0x15, 0); | ||
1875 | xf_emit(ctx, 2, 4); | ||
1876 | if (dev_priv->chipset >= 0xa0) | ||
1877 | xf_emit(ctx, 1, 0x03020100); | ||
1878 | else | ||
1879 | xf_emit(ctx, 1, 0x00608080); | ||
1880 | xf_emit(ctx, 4, 0); | ||
1881 | xf_emit(ctx, 1, 4); | ||
1882 | xf_emit(ctx, 2, 0); | ||
1883 | xf_emit(ctx, 2, 4); | ||
1884 | xf_emit(ctx, 1, 0x80); | ||
1885 | if (magic3) | ||
1886 | xf_emit(ctx, 1, magic3); | ||
1887 | xf_emit(ctx, 1, 4); | ||
1888 | xf_emit(ctx, 0x24, 0); | ||
1889 | xf_emit(ctx, 1, 4); | ||
1890 | xf_emit(ctx, 1, 0x80); | ||
1891 | xf_emit(ctx, 1, 4); | ||
1892 | xf_emit(ctx, 1, 0x03020100); | ||
1893 | xf_emit(ctx, 1, 3); | ||
1894 | if (magic3) | ||
1895 | xf_emit(ctx, 1, magic3); | ||
1896 | xf_emit(ctx, 1, 4); | ||
1897 | xf_emit(ctx, 4, 0); | ||
1898 | xf_emit(ctx, 1, 4); | ||
1899 | xf_emit(ctx, 1, 3); | ||
1900 | xf_emit(ctx, 3, 0); | ||
1901 | xf_emit(ctx, 1, 4); | ||
1902 | if (dev_priv->chipset == 0x94 || dev_priv->chipset == 0x96) | ||
1903 | xf_emit(ctx, 0x1024, 0); | ||
1904 | else if (dev_priv->chipset < 0xa0) | ||
1905 | xf_emit(ctx, 0xa24, 0); | ||
1906 | else if (dev_priv->chipset == 0xa0 || dev_priv->chipset >= 0xaa) | ||
1907 | xf_emit(ctx, 0x214, 0); | ||
1908 | else | ||
1909 | xf_emit(ctx, 0x414, 0); | ||
1910 | xf_emit(ctx, 1, 4); | ||
1911 | xf_emit(ctx, 1, 3); | ||
1912 | xf_emit(ctx, 2, 0); | ||
1913 | } | ||
1914 | |||
1915 | static void | ||
1916 | nv50_graph_construct_xfer_tp_x2(struct nouveau_grctx *ctx) | ||
1917 | { | ||
1918 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
1919 | int magic1, magic2; | ||
1920 | if (dev_priv->chipset == 0x50) { | ||
1921 | magic1 = 0x3ff; | ||
1922 | magic2 = 0x00003e60; | ||
1923 | } else if (dev_priv->chipset <= 0xa0 || dev_priv->chipset >= 0xaa) { | ||
1924 | magic1 = 0x7ff; | ||
1925 | magic2 = 0x001ffe67; | ||
1926 | } else { | ||
1927 | magic1 = 0x7ff; | ||
1928 | magic2 = 0x00087e67; | ||
1929 | } | ||
1930 | xf_emit(ctx, 3, 0); | ||
1931 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1932 | xf_emit(ctx, 1, 1); | ||
1933 | xf_emit(ctx, 0xc, 0); | ||
1934 | xf_emit(ctx, 1, 0xf); | ||
1935 | xf_emit(ctx, 0xb, 0); | ||
1936 | xf_emit(ctx, 1, 4); | ||
1937 | xf_emit(ctx, 4, 0xffff); | ||
1938 | xf_emit(ctx, 8, 0); | ||
1939 | xf_emit(ctx, 1, 1); | ||
1940 | xf_emit(ctx, 3, 0); | ||
1941 | xf_emit(ctx, 1, 1); | ||
1942 | xf_emit(ctx, 5, 0); | ||
1943 | xf_emit(ctx, 1, 1); | ||
1944 | xf_emit(ctx, 2, 0); | ||
1945 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
1946 | xf_emit(ctx, 1, 3); | ||
1947 | xf_emit(ctx, 1, 0); | ||
1948 | } else if (dev_priv->chipset >= 0xa0) | ||
1949 | xf_emit(ctx, 1, 1); | ||
1950 | xf_emit(ctx, 0xa, 0); | ||
1951 | xf_emit(ctx, 2, 1); | ||
1952 | xf_emit(ctx, 1, 2); | ||
1953 | xf_emit(ctx, 2, 1); | ||
1954 | xf_emit(ctx, 1, 2); | ||
1955 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
1956 | xf_emit(ctx, 1, 0); | ||
1957 | xf_emit(ctx, 0x18, 1); | ||
1958 | xf_emit(ctx, 8, 2); | ||
1959 | xf_emit(ctx, 8, 1); | ||
1960 | xf_emit(ctx, 8, 2); | ||
1961 | xf_emit(ctx, 8, 1); | ||
1962 | xf_emit(ctx, 1, 0); | ||
1963 | } | ||
1964 | xf_emit(ctx, 1, 1); | ||
1965 | xf_emit(ctx, 1, 0); | ||
1966 | xf_emit(ctx, 1, 0x11); | ||
1967 | xf_emit(ctx, 7, 0); | ||
1968 | xf_emit(ctx, 1, 0x0fac6881); | ||
1969 | xf_emit(ctx, 2, 0); | ||
1970 | xf_emit(ctx, 1, 4); | ||
1971 | xf_emit(ctx, 3, 0); | ||
1972 | xf_emit(ctx, 1, 0x11); | ||
1973 | xf_emit(ctx, 1, 1); | ||
1974 | xf_emit(ctx, 1, 0); | ||
1975 | xf_emit(ctx, 3, 0xcf); | ||
1976 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1977 | xf_emit(ctx, 1, 1); | ||
1978 | xf_emit(ctx, 0xa, 0); | ||
1979 | xf_emit(ctx, 2, 1); | ||
1980 | xf_emit(ctx, 1, 2); | ||
1981 | xf_emit(ctx, 2, 1); | ||
1982 | xf_emit(ctx, 1, 2); | ||
1983 | xf_emit(ctx, 1, 1); | ||
1984 | xf_emit(ctx, 1, 0); | ||
1985 | xf_emit(ctx, 8, 1); | ||
1986 | xf_emit(ctx, 1, 0x11); | ||
1987 | xf_emit(ctx, 7, 0); | ||
1988 | xf_emit(ctx, 1, 0x0fac6881); | ||
1989 | xf_emit(ctx, 1, 0xf); | ||
1990 | xf_emit(ctx, 7, 0); | ||
1991 | xf_emit(ctx, 1, magic2); | ||
1992 | xf_emit(ctx, 2, 0); | ||
1993 | xf_emit(ctx, 1, 0x11); | ||
1994 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
1995 | xf_emit(ctx, 2, 1); | ||
1996 | else | ||
1997 | xf_emit(ctx, 1, 1); | ||
1998 | if(dev_priv->chipset == 0x50) | ||
1999 | xf_emit(ctx, 1, 0); | ||
2000 | else | ||
2001 | xf_emit(ctx, 3, 0); | ||
2002 | xf_emit(ctx, 1, 4); | ||
2003 | xf_emit(ctx, 5, 0); | ||
2004 | xf_emit(ctx, 1, 1); | ||
2005 | xf_emit(ctx, 4, 0); | ||
2006 | xf_emit(ctx, 1, 0x11); | ||
2007 | xf_emit(ctx, 7, 0); | ||
2008 | xf_emit(ctx, 1, 0x0fac6881); | ||
2009 | xf_emit(ctx, 3, 0); | ||
2010 | xf_emit(ctx, 1, 0x11); | ||
2011 | xf_emit(ctx, 1, 1); | ||
2012 | xf_emit(ctx, 1, 0); | ||
2013 | xf_emit(ctx, 1, 1); | ||
2014 | xf_emit(ctx, 1, 0); | ||
2015 | xf_emit(ctx, 1, 1); | ||
2016 | xf_emit(ctx, 1, 0); | ||
2017 | xf_emit(ctx, 1, magic1); | ||
2018 | xf_emit(ctx, 1, 0); | ||
2019 | xf_emit(ctx, 1, 1); | ||
2020 | xf_emit(ctx, 1, 0); | ||
2021 | xf_emit(ctx, 1, 1); | ||
2022 | xf_emit(ctx, 2, 0); | ||
2023 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2024 | xf_emit(ctx, 1, 1); | ||
2025 | xf_emit(ctx, 0x28, 0); | ||
2026 | xf_emit(ctx, 8, 8); | ||
2027 | xf_emit(ctx, 1, 0x11); | ||
2028 | xf_emit(ctx, 7, 0); | ||
2029 | xf_emit(ctx, 1, 0x0fac6881); | ||
2030 | xf_emit(ctx, 8, 0x400); | ||
2031 | xf_emit(ctx, 8, 0x300); | ||
2032 | xf_emit(ctx, 1, 1); | ||
2033 | xf_emit(ctx, 1, 0xf); | ||
2034 | xf_emit(ctx, 7, 0); | ||
2035 | xf_emit(ctx, 1, 0x20); | ||
2036 | xf_emit(ctx, 1, 0x11); | ||
2037 | xf_emit(ctx, 1, 0x100); | ||
2038 | xf_emit(ctx, 1, 0); | ||
2039 | xf_emit(ctx, 1, 1); | ||
2040 | xf_emit(ctx, 2, 0); | ||
2041 | xf_emit(ctx, 1, 0x40); | ||
2042 | xf_emit(ctx, 1, 0x100); | ||
2043 | xf_emit(ctx, 1, 0); | ||
2044 | xf_emit(ctx, 1, 3); | ||
2045 | xf_emit(ctx, 4, 0); | ||
2046 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2047 | xf_emit(ctx, 1, 1); | ||
2048 | xf_emit(ctx, 1, magic2); | ||
2049 | xf_emit(ctx, 3, 0); | ||
2050 | xf_emit(ctx, 1, 2); | ||
2051 | xf_emit(ctx, 1, 0x0fac6881); | ||
2052 | xf_emit(ctx, 9, 0); | ||
2053 | xf_emit(ctx, 1, 1); | ||
2054 | xf_emit(ctx, 4, 0); | ||
2055 | xf_emit(ctx, 1, 4); | ||
2056 | xf_emit(ctx, 1, 0); | ||
2057 | xf_emit(ctx, 1, 1); | ||
2058 | xf_emit(ctx, 1, 0x400); | ||
2059 | xf_emit(ctx, 1, 0x300); | ||
2060 | xf_emit(ctx, 1, 0x1001); | ||
2061 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2062 | xf_emit(ctx, 4, 0); | ||
2063 | else | ||
2064 | xf_emit(ctx, 3, 0); | ||
2065 | xf_emit(ctx, 1, 0x11); | ||
2066 | xf_emit(ctx, 7, 0); | ||
2067 | xf_emit(ctx, 1, 0x0fac6881); | ||
2068 | xf_emit(ctx, 1, 0xf); | ||
2069 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
2070 | xf_emit(ctx, 0x15, 0); | ||
2071 | xf_emit(ctx, 1, 1); | ||
2072 | xf_emit(ctx, 3, 0); | ||
2073 | } else | ||
2074 | xf_emit(ctx, 0x17, 0); | ||
2075 | if (dev_priv->chipset >= 0xa0) | ||
2076 | xf_emit(ctx, 1, 0x0fac6881); | ||
2077 | xf_emit(ctx, 1, magic2); | ||
2078 | xf_emit(ctx, 3, 0); | ||
2079 | xf_emit(ctx, 1, 0x11); | ||
2080 | xf_emit(ctx, 2, 0); | ||
2081 | xf_emit(ctx, 1, 4); | ||
2082 | xf_emit(ctx, 1, 0); | ||
2083 | xf_emit(ctx, 2, 1); | ||
2084 | xf_emit(ctx, 3, 0); | ||
2085 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2086 | xf_emit(ctx, 2, 1); | ||
2087 | else | ||
2088 | xf_emit(ctx, 1, 1); | ||
2089 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2090 | xf_emit(ctx, 2, 0); | ||
2091 | else if (dev_priv->chipset != 0x50) | ||
2092 | xf_emit(ctx, 1, 0); | ||
2093 | } | ||
2094 | |||
2095 | static void | ||
2096 | nv50_graph_construct_xfer_tp_x3(struct nouveau_grctx *ctx) | ||
2097 | { | ||
2098 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
2099 | xf_emit(ctx, 3, 0); | ||
2100 | xf_emit(ctx, 1, 1); | ||
2101 | xf_emit(ctx, 1, 0); | ||
2102 | xf_emit(ctx, 1, 1); | ||
2103 | if (dev_priv->chipset == 0x50) | ||
2104 | xf_emit(ctx, 2, 0); | ||
2105 | else | ||
2106 | xf_emit(ctx, 3, 0); | ||
2107 | xf_emit(ctx, 1, 0x2a712488); | ||
2108 | xf_emit(ctx, 1, 0); | ||
2109 | xf_emit(ctx, 1, 0x4085c000); | ||
2110 | xf_emit(ctx, 1, 0x40); | ||
2111 | xf_emit(ctx, 1, 0x100); | ||
2112 | xf_emit(ctx, 1, 0x10100); | ||
2113 | xf_emit(ctx, 1, 0x02800000); | ||
2114 | } | ||
2115 | |||
2116 | static void | ||
2117 | nv50_graph_construct_xfer_tp_x4(struct nouveau_grctx *ctx) | ||
2118 | { | ||
2119 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
2120 | xf_emit(ctx, 2, 0x04e3bfdf); | ||
2121 | xf_emit(ctx, 1, 1); | ||
2122 | xf_emit(ctx, 1, 0); | ||
2123 | xf_emit(ctx, 1, 0x00ffff00); | ||
2124 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2125 | xf_emit(ctx, 2, 1); | ||
2126 | else | ||
2127 | xf_emit(ctx, 1, 1); | ||
2128 | xf_emit(ctx, 2, 0); | ||
2129 | xf_emit(ctx, 1, 0x00ffff00); | ||
2130 | xf_emit(ctx, 8, 0); | ||
2131 | xf_emit(ctx, 1, 1); | ||
2132 | xf_emit(ctx, 1, 0); | ||
2133 | xf_emit(ctx, 1, 1); | ||
2134 | xf_emit(ctx, 1, 0x30201000); | ||
2135 | xf_emit(ctx, 1, 0x70605040); | ||
2136 | xf_emit(ctx, 1, 0xb8a89888); | ||
2137 | xf_emit(ctx, 1, 0xf8e8d8c8); | ||
2138 | xf_emit(ctx, 1, 0); | ||
2139 | xf_emit(ctx, 1, 0x1a); | ||
2140 | } | ||
2141 | |||
2142 | static void | ||
2143 | nv50_graph_construct_xfer_tp_x5(struct nouveau_grctx *ctx) | ||
2144 | { | ||
2145 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
2146 | xf_emit(ctx, 3, 0); | ||
2147 | xf_emit(ctx, 1, 0xfac6881); | ||
2148 | xf_emit(ctx, 4, 0); | ||
2149 | xf_emit(ctx, 1, 4); | ||
2150 | xf_emit(ctx, 1, 0); | ||
2151 | xf_emit(ctx, 2, 1); | ||
2152 | xf_emit(ctx, 2, 0); | ||
2153 | xf_emit(ctx, 1, 1); | ||
2154 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2155 | xf_emit(ctx, 0xb, 0); | ||
2156 | else | ||
2157 | xf_emit(ctx, 0xa, 0); | ||
2158 | xf_emit(ctx, 8, 1); | ||
2159 | xf_emit(ctx, 1, 0x11); | ||
2160 | xf_emit(ctx, 7, 0); | ||
2161 | xf_emit(ctx, 1, 0xfac6881); | ||
2162 | xf_emit(ctx, 1, 0xf); | ||
2163 | xf_emit(ctx, 7, 0); | ||
2164 | xf_emit(ctx, 1, 0x11); | ||
2165 | xf_emit(ctx, 1, 1); | ||
2166 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
2167 | xf_emit(ctx, 6, 0); | ||
2168 | xf_emit(ctx, 1, 1); | ||
2169 | xf_emit(ctx, 6, 0); | ||
2170 | } else { | ||
2171 | xf_emit(ctx, 0xb, 0); | ||
2172 | } | ||
2173 | } | ||
2174 | |||
2175 | static void | ||
2176 | nv50_graph_construct_xfer_tp(struct nouveau_grctx *ctx) | ||
2177 | { | ||
2178 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
2179 | if (dev_priv->chipset < 0xa0) { | ||
2180 | nv50_graph_construct_xfer_tp_x1(ctx); | ||
2181 | nv50_graph_construct_xfer_tp_x2(ctx); | ||
2182 | nv50_graph_construct_xfer_tp_x3(ctx); | ||
2183 | if (dev_priv->chipset == 0x50) | ||
2184 | xf_emit(ctx, 0xf, 0); | ||
2185 | else | ||
2186 | xf_emit(ctx, 0x12, 0); | ||
2187 | nv50_graph_construct_xfer_tp_x4(ctx); | ||
2188 | } else { | ||
2189 | nv50_graph_construct_xfer_tp_x3(ctx); | ||
2190 | if (dev_priv->chipset < 0xaa) | ||
2191 | xf_emit(ctx, 0xc, 0); | ||
2192 | else | ||
2193 | xf_emit(ctx, 0xa, 0); | ||
2194 | nv50_graph_construct_xfer_tp_x2(ctx); | ||
2195 | nv50_graph_construct_xfer_tp_x5(ctx); | ||
2196 | nv50_graph_construct_xfer_tp_x4(ctx); | ||
2197 | nv50_graph_construct_xfer_tp_x1(ctx); | ||
2198 | } | ||
2199 | } | ||
2200 | |||
2201 | static void | ||
2202 | nv50_graph_construct_xfer_tp2(struct nouveau_grctx *ctx) | ||
2203 | { | ||
2204 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
2205 | int i, mpcnt; | ||
2206 | if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa) | ||
2207 | mpcnt = 1; | ||
2208 | else if (dev_priv->chipset < 0xa0 || dev_priv->chipset >= 0xa8) | ||
2209 | mpcnt = 2; | ||
2210 | else | ||
2211 | mpcnt = 3; | ||
2212 | for (i = 0; i < mpcnt; i++) { | ||
2213 | xf_emit(ctx, 1, 0); | ||
2214 | xf_emit(ctx, 1, 0x80); | ||
2215 | xf_emit(ctx, 1, 0x80007004); | ||
2216 | xf_emit(ctx, 1, 0x04000400); | ||
2217 | if (dev_priv->chipset >= 0xa0) | ||
2218 | xf_emit(ctx, 1, 0xc0); | ||
2219 | xf_emit(ctx, 1, 0x1000); | ||
2220 | xf_emit(ctx, 2, 0); | ||
2221 | if (dev_priv->chipset == 0x86 || dev_priv->chipset == 0x98 || dev_priv->chipset >= 0xa8) { | ||
2222 | xf_emit(ctx, 1, 0xe00); | ||
2223 | xf_emit(ctx, 1, 0x1e00); | ||
2224 | } | ||
2225 | xf_emit(ctx, 1, 1); | ||
2226 | xf_emit(ctx, 2, 0); | ||
2227 | if (dev_priv->chipset == 0x50) | ||
2228 | xf_emit(ctx, 2, 0x1000); | ||
2229 | xf_emit(ctx, 1, 1); | ||
2230 | xf_emit(ctx, 1, 0); | ||
2231 | xf_emit(ctx, 1, 4); | ||
2232 | xf_emit(ctx, 1, 2); | ||
2233 | if (dev_priv->chipset >= 0xaa) | ||
2234 | xf_emit(ctx, 0xb, 0); | ||
2235 | else if (dev_priv->chipset >= 0xa0) | ||
2236 | xf_emit(ctx, 0xc, 0); | ||
2237 | else | ||
2238 | xf_emit(ctx, 0xa, 0); | ||
2239 | } | ||
2240 | xf_emit(ctx, 1, 0x08100c12); | ||
2241 | xf_emit(ctx, 1, 0); | ||
2242 | if (dev_priv->chipset >= 0xa0) { | ||
2243 | xf_emit(ctx, 1, 0x1fe21); | ||
2244 | } | ||
2245 | xf_emit(ctx, 5, 0); | ||
2246 | xf_emit(ctx, 4, 0xffff); | ||
2247 | xf_emit(ctx, 1, 1); | ||
2248 | xf_emit(ctx, 2, 0x10001); | ||
2249 | xf_emit(ctx, 1, 1); | ||
2250 | xf_emit(ctx, 1, 0); | ||
2251 | xf_emit(ctx, 1, 0x1fe21); | ||
2252 | xf_emit(ctx, 1, 0); | ||
2253 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2254 | xf_emit(ctx, 1, 1); | ||
2255 | xf_emit(ctx, 4, 0); | ||
2256 | xf_emit(ctx, 1, 0x08100c12); | ||
2257 | xf_emit(ctx, 1, 4); | ||
2258 | xf_emit(ctx, 1, 0); | ||
2259 | xf_emit(ctx, 1, 2); | ||
2260 | xf_emit(ctx, 1, 0x11); | ||
2261 | xf_emit(ctx, 8, 0); | ||
2262 | xf_emit(ctx, 1, 0xfac6881); | ||
2263 | xf_emit(ctx, 1, 0); | ||
2264 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) | ||
2265 | xf_emit(ctx, 1, 3); | ||
2266 | xf_emit(ctx, 3, 0); | ||
2267 | xf_emit(ctx, 1, 4); | ||
2268 | xf_emit(ctx, 9, 0); | ||
2269 | xf_emit(ctx, 1, 2); | ||
2270 | xf_emit(ctx, 2, 1); | ||
2271 | xf_emit(ctx, 1, 2); | ||
2272 | xf_emit(ctx, 3, 1); | ||
2273 | xf_emit(ctx, 1, 0); | ||
2274 | if (dev_priv->chipset > 0xa0 && dev_priv->chipset < 0xaa) { | ||
2275 | xf_emit(ctx, 8, 2); | ||
2276 | xf_emit(ctx, 0x10, 1); | ||
2277 | xf_emit(ctx, 8, 2); | ||
2278 | xf_emit(ctx, 0x18, 1); | ||
2279 | xf_emit(ctx, 3, 0); | ||
2280 | } | ||
2281 | xf_emit(ctx, 1, 4); | ||
2282 | if (dev_priv->chipset == 0x50) | ||
2283 | xf_emit(ctx, 0x3a0, 0); | ||
2284 | else if (dev_priv->chipset < 0x94) | ||
2285 | xf_emit(ctx, 0x3a2, 0); | ||
2286 | else if (dev_priv->chipset == 0x98 || dev_priv->chipset == 0xaa) | ||
2287 | xf_emit(ctx, 0x39f, 0); | ||
2288 | else | ||
2289 | xf_emit(ctx, 0x3a3, 0); | ||
2290 | xf_emit(ctx, 1, 0x11); | ||
2291 | xf_emit(ctx, 1, 0); | ||
2292 | xf_emit(ctx, 1, 1); | ||
2293 | xf_emit(ctx, 0x2d, 0); | ||
2294 | } | ||
2295 | |||
2296 | static void | ||
2297 | nv50_graph_construct_xfer2(struct nouveau_grctx *ctx) | ||
2298 | { | ||
2299 | struct drm_nouveau_private *dev_priv = ctx->dev->dev_private; | ||
2300 | int i; | ||
2301 | uint32_t offset; | ||
2302 | uint32_t units = nv_rd32 (ctx->dev, 0x1540); | ||
2303 | int size = 0; | ||
2304 | |||
2305 | offset = (ctx->ctxvals_pos+0x3f)&~0x3f; | ||
2306 | |||
2307 | if (dev_priv->chipset < 0xa0) { | ||
2308 | for (i = 0; i < 8; i++) { | ||
2309 | ctx->ctxvals_pos = offset + i; | ||
2310 | if (i == 0) | ||
2311 | xf_emit(ctx, 1, 0x08100c12); | ||
2312 | if (units & (1 << i)) | ||
2313 | nv50_graph_construct_xfer_tp2(ctx); | ||
2314 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
2315 | size = (ctx->ctxvals_pos-offset)/8; | ||
2316 | } | ||
2317 | } else { | ||
2318 | /* Strand 0: TPs 0, 1 */ | ||
2319 | ctx->ctxvals_pos = offset; | ||
2320 | xf_emit(ctx, 1, 0x08100c12); | ||
2321 | if (units & (1 << 0)) | ||
2322 | nv50_graph_construct_xfer_tp2(ctx); | ||
2323 | if (units & (1 << 1)) | ||
2324 | nv50_graph_construct_xfer_tp2(ctx); | ||
2325 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
2326 | size = (ctx->ctxvals_pos-offset)/8; | ||
2327 | |||
2328 | /* Strand 0: TPs 2, 3 */ | ||
2329 | ctx->ctxvals_pos = offset + 1; | ||
2330 | if (units & (1 << 2)) | ||
2331 | nv50_graph_construct_xfer_tp2(ctx); | ||
2332 | if (units & (1 << 3)) | ||
2333 | nv50_graph_construct_xfer_tp2(ctx); | ||
2334 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
2335 | size = (ctx->ctxvals_pos-offset)/8; | ||
2336 | |||
2337 | /* Strand 0: TPs 4, 5, 6 */ | ||
2338 | ctx->ctxvals_pos = offset + 2; | ||
2339 | if (units & (1 << 4)) | ||
2340 | nv50_graph_construct_xfer_tp2(ctx); | ||
2341 | if (units & (1 << 5)) | ||
2342 | nv50_graph_construct_xfer_tp2(ctx); | ||
2343 | if (units & (1 << 6)) | ||
2344 | nv50_graph_construct_xfer_tp2(ctx); | ||
2345 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
2346 | size = (ctx->ctxvals_pos-offset)/8; | ||
2347 | |||
2348 | /* Strand 0: TPs 7, 8, 9 */ | ||
2349 | ctx->ctxvals_pos = offset + 3; | ||
2350 | if (units & (1 << 7)) | ||
2351 | nv50_graph_construct_xfer_tp2(ctx); | ||
2352 | if (units & (1 << 8)) | ||
2353 | nv50_graph_construct_xfer_tp2(ctx); | ||
2354 | if (units & (1 << 9)) | ||
2355 | nv50_graph_construct_xfer_tp2(ctx); | ||
2356 | if ((ctx->ctxvals_pos-offset)/8 > size) | ||
2357 | size = (ctx->ctxvals_pos-offset)/8; | ||
2358 | } | ||
2359 | ctx->ctxvals_pos = offset + size * 8; | ||
2360 | ctx->ctxvals_pos = (ctx->ctxvals_pos+0x3f)&~0x3f; | ||
2361 | cp_lsr (ctx, offset); | ||
2362 | cp_out (ctx, CP_SET_XFER_POINTER); | ||
2363 | cp_lsr (ctx, size); | ||
2364 | cp_out (ctx, CP_SEEK_2); | ||
2365 | cp_out (ctx, CP_XFER_2); | ||
2366 | cp_wait(ctx, XFER, BUSY); | ||
2367 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index f0dc4e36ef05..de1f5b0062c5 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
@@ -390,7 +390,7 @@ nv50_instmem_populate(struct drm_device *dev, struct nouveau_gpuobj *gpuobj, | |||
390 | if (gpuobj->im_backing) | 390 | if (gpuobj->im_backing) |
391 | return -EINVAL; | 391 | return -EINVAL; |
392 | 392 | ||
393 | *sz = (*sz + (NV50_INSTMEM_PAGE_SIZE-1)) & ~(NV50_INSTMEM_PAGE_SIZE-1); | 393 | *sz = ALIGN(*sz, NV50_INSTMEM_PAGE_SIZE); |
394 | if (*sz == 0) | 394 | if (*sz == 0) |
395 | return -EINVAL; | 395 | return -EINVAL; |
396 | 396 | ||