diff options
| author | Dave Airlie <airlied@redhat.com> | 2010-03-01 00:41:15 -0500 |
|---|---|---|
| committer | Dave Airlie <airlied@redhat.com> | 2010-03-01 00:41:15 -0500 |
| commit | aa71fa3cd5b7b4f669cd74c5a16de57d2938cd85 (patch) | |
| tree | d6dac4b9a73b7c3fc4a62bddfd8622e067cbdcdf | |
| parent | 79fa9eb7396238233c327668185d28bb47fb0796 (diff) | |
| parent | 3bfc7d22d0400e85a93e835d4398dcbe0af68b0b (diff) | |
Merge remote branch 'nouveau/for-airlied' into drm-next-stage
* nouveau/for-airlied: (25 commits)
drm/nouveau: use ALIGN instead of open coding it
drm/nouveau: report unknown connector state if lid closed
drm/nouveau: support version 0x20 displayport tables
drm/nouveau: Fix noaccel/nofbaccel option descriptions.
drm/nv50: Implement ctxprog/state generation.
drm/nouveau: use dcb connector types throughout the driver
drm/nv50: enable hpd on any connector we know the gpio line for
drm/nouveau: use dcb connector table for creating drm connectors
drm/nouveau: construct a connector table for cards that lack a real one
drm/nouveau: check for known dcb connector types
drm/nouveau: parse dcb gpio/connector tables after encoders
drm/nouveau: reorganise bios header, add dcb connector type enums
drm/nouveau: merge nvbios and nouveau_bios_info
drm/nouveau: merge parsed_dcb and bios_parsed_dcb into dcb_table
drm/nouveau: rename parsed_dcb_gpio to dcb_gpio_table
drm/nouveau: allow retrieval of vbios image from debugfs
drm/nouveau: fix missing spin_unlock in failure path
drm/nouveau: fix i2ctable bounds checking
drm/nouveau: fix nouveau_i2c_find bounds checking
drm/nouveau: fix pramdac_table range checking
...
Conflicts:
drivers/gpu/drm/nouveau/nouveau_gem.c
33 files changed, 3235 insertions, 833 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 | ||
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index f745948b61e4..a6a9f4af5ebd 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h | |||
| @@ -25,13 +25,14 @@ | |||
| 25 | #ifndef __NOUVEAU_DRM_H__ | 25 | #ifndef __NOUVEAU_DRM_H__ |
| 26 | #define __NOUVEAU_DRM_H__ | 26 | #define __NOUVEAU_DRM_H__ |
| 27 | 27 | ||
| 28 | #define NOUVEAU_DRM_HEADER_PATCHLEVEL 15 | 28 | #define NOUVEAU_DRM_HEADER_PATCHLEVEL 16 |
| 29 | 29 | ||
| 30 | struct drm_nouveau_channel_alloc { | 30 | struct drm_nouveau_channel_alloc { |
| 31 | uint32_t fb_ctxdma_handle; | 31 | uint32_t fb_ctxdma_handle; |
| 32 | uint32_t tt_ctxdma_handle; | 32 | uint32_t tt_ctxdma_handle; |
| 33 | 33 | ||
| 34 | int channel; | 34 | int channel; |
| 35 | uint32_t pushbuf_domains; | ||
| 35 | 36 | ||
| 36 | /* Notifier memory */ | 37 | /* Notifier memory */ |
| 37 | uint32_t notifier_handle; | 38 | uint32_t notifier_handle; |
| @@ -109,68 +110,58 @@ struct drm_nouveau_gem_new { | |||
| 109 | uint32_t align; | 110 | uint32_t align; |
| 110 | }; | 111 | }; |
| 111 | 112 | ||
| 113 | #define NOUVEAU_GEM_MAX_BUFFERS 1024 | ||
| 114 | struct drm_nouveau_gem_pushbuf_bo_presumed { | ||
| 115 | uint32_t valid; | ||
| 116 | uint32_t domain; | ||
| 117 | uint64_t offset; | ||
| 118 | }; | ||
| 119 | |||
| 112 | struct drm_nouveau_gem_pushbuf_bo { | 120 | struct drm_nouveau_gem_pushbuf_bo { |
| 113 | uint64_t user_priv; | 121 | uint64_t user_priv; |
| 114 | uint32_t handle; | 122 | uint32_t handle; |
| 115 | uint32_t read_domains; | 123 | uint32_t read_domains; |
| 116 | uint32_t write_domains; | 124 | uint32_t write_domains; |
| 117 | uint32_t valid_domains; | 125 | uint32_t valid_domains; |
| 118 | uint32_t presumed_ok; | 126 | struct drm_nouveau_gem_pushbuf_bo_presumed presumed; |
| 119 | uint32_t presumed_domain; | ||
| 120 | uint64_t presumed_offset; | ||
| 121 | }; | 127 | }; |
| 122 | 128 | ||
| 123 | #define NOUVEAU_GEM_RELOC_LOW (1 << 0) | 129 | #define NOUVEAU_GEM_RELOC_LOW (1 << 0) |
| 124 | #define NOUVEAU_GEM_RELOC_HIGH (1 << 1) | 130 | #define NOUVEAU_GEM_RELOC_HIGH (1 << 1) |
| 125 | #define NOUVEAU_GEM_RELOC_OR (1 << 2) | 131 | #define NOUVEAU_GEM_RELOC_OR (1 << 2) |
| 132 | #define NOUVEAU_GEM_MAX_RELOCS 1024 | ||
| 126 | struct drm_nouveau_gem_pushbuf_reloc { | 133 | struct drm_nouveau_gem_pushbuf_reloc { |
| 134 | uint32_t reloc_bo_index; | ||
| 135 | uint32_t reloc_bo_offset; | ||
| 127 | uint32_t bo_index; | 136 | uint32_t bo_index; |
| 128 | uint32_t reloc_index; | ||
| 129 | uint32_t flags; | 137 | uint32_t flags; |
| 130 | uint32_t data; | 138 | uint32_t data; |
| 131 | uint32_t vor; | 139 | uint32_t vor; |
| 132 | uint32_t tor; | 140 | uint32_t tor; |
| 133 | }; | 141 | }; |
| 134 | 142 | ||
| 135 | #define NOUVEAU_GEM_MAX_BUFFERS 1024 | 143 | #define NOUVEAU_GEM_MAX_PUSH 512 |
| 136 | #define NOUVEAU_GEM_MAX_RELOCS 1024 | 144 | struct drm_nouveau_gem_pushbuf_push { |
| 145 | uint32_t bo_index; | ||
| 146 | uint32_t pad; | ||
| 147 | uint64_t offset; | ||
| 148 | uint64_t length; | ||
| 149 | }; | ||
| 137 | 150 | ||
| 138 | struct drm_nouveau_gem_pushbuf { | 151 | struct drm_nouveau_gem_pushbuf { |
| 139 | uint32_t channel; | 152 | uint32_t channel; |
| 140 | uint32_t nr_dwords; | ||
| 141 | uint32_t nr_buffers; | 153 | uint32_t nr_buffers; |
| 142 | uint32_t nr_relocs; | ||
| 143 | uint64_t dwords; | ||
| 144 | uint64_t buffers; | 154 | uint64_t buffers; |
| 145 | uint64_t relocs; | ||
| 146 | }; | ||
| 147 | |||
| 148 | struct drm_nouveau_gem_pushbuf_call { | ||
| 149 | uint32_t channel; | ||
| 150 | uint32_t handle; | ||
| 151 | uint32_t offset; | ||
| 152 | uint32_t nr_buffers; | ||
| 153 | uint32_t nr_relocs; | 155 | uint32_t nr_relocs; |
| 154 | uint32_t nr_dwords; | 156 | uint32_t nr_push; |
| 155 | uint64_t buffers; | ||
| 156 | uint64_t relocs; | 157 | uint64_t relocs; |
| 158 | uint64_t push; | ||
| 157 | uint32_t suffix0; | 159 | uint32_t suffix0; |
| 158 | uint32_t suffix1; | 160 | uint32_t suffix1; |
| 159 | /* below only accessed for CALL2 */ | ||
| 160 | uint64_t vram_available; | 161 | uint64_t vram_available; |
| 161 | uint64_t gart_available; | 162 | uint64_t gart_available; |
| 162 | }; | 163 | }; |
| 163 | 164 | ||
| 164 | struct drm_nouveau_gem_pin { | ||
| 165 | uint32_t handle; | ||
| 166 | uint32_t domain; | ||
| 167 | uint64_t offset; | ||
| 168 | }; | ||
| 169 | |||
| 170 | struct drm_nouveau_gem_unpin { | ||
| 171 | uint32_t handle; | ||
| 172 | }; | ||
| 173 | |||
| 174 | #define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001 | 165 | #define NOUVEAU_GEM_CPU_PREP_NOWAIT 0x00000001 |
| 175 | #define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002 | 166 | #define NOUVEAU_GEM_CPU_PREP_NOBLOCK 0x00000002 |
| 176 | #define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004 | 167 | #define NOUVEAU_GEM_CPU_PREP_WRITE 0x00000004 |
| @@ -183,14 +174,6 @@ struct drm_nouveau_gem_cpu_fini { | |||
| 183 | uint32_t handle; | 174 | uint32_t handle; |
| 184 | }; | 175 | }; |
| 185 | 176 | ||
| 186 | struct drm_nouveau_gem_tile { | ||
| 187 | uint32_t handle; | ||
| 188 | uint32_t offset; | ||
| 189 | uint32_t size; | ||
| 190 | uint32_t tile_mode; | ||
| 191 | uint32_t tile_flags; | ||
| 192 | }; | ||
| 193 | |||
| 194 | enum nouveau_bus_type { | 177 | enum nouveau_bus_type { |
| 195 | NV_AGP = 0, | 178 | NV_AGP = 0, |
| 196 | NV_PCI = 1, | 179 | NV_PCI = 1, |
| @@ -200,22 +183,17 @@ enum nouveau_bus_type { | |||
| 200 | struct drm_nouveau_sarea { | 183 | struct drm_nouveau_sarea { |
| 201 | }; | 184 | }; |
| 202 | 185 | ||
| 203 | #define DRM_NOUVEAU_CARD_INIT 0x00 | 186 | #define DRM_NOUVEAU_GETPARAM 0x00 |
| 204 | #define DRM_NOUVEAU_GETPARAM 0x01 | 187 | #define DRM_NOUVEAU_SETPARAM 0x01 |
| 205 | #define DRM_NOUVEAU_SETPARAM 0x02 | 188 | #define DRM_NOUVEAU_CHANNEL_ALLOC 0x02 |
| 206 | #define DRM_NOUVEAU_CHANNEL_ALLOC 0x03 | 189 | #define DRM_NOUVEAU_CHANNEL_FREE 0x03 |
| 207 | #define DRM_NOUVEAU_CHANNEL_FREE 0x04 | 190 | #define DRM_NOUVEAU_GROBJ_ALLOC 0x04 |
| 208 | #define DRM_NOUVEAU_GROBJ_ALLOC 0x05 | 191 | #define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x05 |
| 209 | #define DRM_NOUVEAU_NOTIFIEROBJ_ALLOC 0x06 | 192 | #define DRM_NOUVEAU_GPUOBJ_FREE 0x06 |
| 210 | #define DRM_NOUVEAU_GPUOBJ_FREE 0x07 | ||
| 211 | #define DRM_NOUVEAU_GEM_NEW 0x40 | 193 | #define DRM_NOUVEAU_GEM_NEW 0x40 |
| 212 | #define DRM_NOUVEAU_GEM_PUSHBUF 0x41 | 194 | #define DRM_NOUVEAU_GEM_PUSHBUF 0x41 |
| 213 | #define DRM_NOUVEAU_GEM_PUSHBUF_CALL 0x42 | 195 | #define DRM_NOUVEAU_GEM_CPU_PREP 0x42 |
| 214 | #define DRM_NOUVEAU_GEM_PIN 0x43 /* !KMS only */ | 196 | #define DRM_NOUVEAU_GEM_CPU_FINI 0x43 |
| 215 | #define DRM_NOUVEAU_GEM_UNPIN 0x44 /* !KMS only */ | 197 | #define DRM_NOUVEAU_GEM_INFO 0x44 |
| 216 | #define DRM_NOUVEAU_GEM_CPU_PREP 0x45 | ||
| 217 | #define DRM_NOUVEAU_GEM_CPU_FINI 0x46 | ||
| 218 | #define DRM_NOUVEAU_GEM_INFO 0x47 | ||
| 219 | #define DRM_NOUVEAU_GEM_PUSHBUF_CALL2 0x48 | ||
| 220 | 198 | ||
| 221 | #endif /* __NOUVEAU_DRM_H__ */ | 199 | #endif /* __NOUVEAU_DRM_H__ */ |
