diff options
29 files changed, 391 insertions, 223 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_backlight.c b/drivers/gpu/drm/nouveau/nouveau_backlight.c index 406228f4a2a0..b14c81110575 100644 --- a/drivers/gpu/drm/nouveau/nouveau_backlight.c +++ b/drivers/gpu/drm/nouveau/nouveau_backlight.c | |||
| @@ -31,6 +31,7 @@ | |||
| 31 | */ | 31 | */ |
| 32 | 32 | ||
| 33 | #include <linux/backlight.h> | 33 | #include <linux/backlight.h> |
| 34 | #include <linux/acpi.h> | ||
| 34 | 35 | ||
| 35 | #include "drmP.h" | 36 | #include "drmP.h" |
| 36 | #include "nouveau_drv.h" | 37 | #include "nouveau_drv.h" |
| @@ -136,6 +137,14 @@ int nouveau_backlight_init(struct drm_device *dev) | |||
| 136 | { | 137 | { |
| 137 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 138 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 138 | 139 | ||
| 140 | #ifdef CONFIG_ACPI | ||
| 141 | if (acpi_video_backlight_support()) { | ||
| 142 | NV_INFO(dev, "ACPI backlight interface available, " | ||
| 143 | "not registering our own\n"); | ||
| 144 | return 0; | ||
| 145 | } | ||
| 146 | #endif | ||
| 147 | |||
| 139 | switch (dev_priv->card_type) { | 148 | switch (dev_priv->card_type) { |
| 140 | case NV_40: | 149 | case NV_40: |
| 141 | return nouveau_nv40_backlight_init(dev); | 150 | return nouveau_nv40_backlight_init(dev); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 5f21030a293b..b2293576f278 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
| @@ -6829,7 +6829,7 @@ nouveau_bios_posted(struct drm_device *dev) | |||
| 6829 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6829 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 6830 | unsigned htotal; | 6830 | unsigned htotal; |
| 6831 | 6831 | ||
| 6832 | if (dev_priv->chipset >= NV_50) { | 6832 | if (dev_priv->card_type >= NV_50) { |
| 6833 | if (NVReadVgaCrtc(dev, 0, 0x00) == 0 && | 6833 | if (NVReadVgaCrtc(dev, 0, 0x00) == 0 && |
| 6834 | NVReadVgaCrtc(dev, 0, 0x1a) == 0) | 6834 | NVReadVgaCrtc(dev, 0, 0x1a) == 0) |
| 6835 | return false; | 6835 | return false; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c b/drivers/gpu/drm/nouveau/nouveau_bo.c index 80353e2b8409..c41e1c200ef5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bo.c +++ b/drivers/gpu/drm/nouveau/nouveau_bo.c | |||
| @@ -143,8 +143,10 @@ nouveau_bo_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
| 143 | nvbo->no_vm = no_vm; | 143 | nvbo->no_vm = no_vm; |
| 144 | nvbo->tile_mode = tile_mode; | 144 | nvbo->tile_mode = tile_mode; |
| 145 | nvbo->tile_flags = tile_flags; | 145 | nvbo->tile_flags = tile_flags; |
| 146 | nvbo->bo.bdev = &dev_priv->ttm.bdev; | ||
| 146 | 147 | ||
| 147 | nouveau_bo_fixup_align(dev, tile_mode, tile_flags, &align, &size); | 148 | nouveau_bo_fixup_align(dev, tile_mode, nouveau_bo_tile_layout(nvbo), |
| 149 | &align, &size); | ||
| 148 | align >>= PAGE_SHIFT; | 150 | align >>= PAGE_SHIFT; |
| 149 | 151 | ||
| 150 | nouveau_bo_placement_set(nvbo, flags, 0); | 152 | nouveau_bo_placement_set(nvbo, flags, 0); |
| @@ -176,6 +178,31 @@ set_placement_list(uint32_t *pl, unsigned *n, uint32_t type, uint32_t flags) | |||
| 176 | pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags; | 178 | pl[(*n)++] = TTM_PL_FLAG_SYSTEM | flags; |
| 177 | } | 179 | } |
| 178 | 180 | ||
| 181 | static void | ||
| 182 | set_placement_range(struct nouveau_bo *nvbo, uint32_t type) | ||
| 183 | { | ||
| 184 | struct drm_nouveau_private *dev_priv = nouveau_bdev(nvbo->bo.bdev); | ||
| 185 | |||
| 186 | if (dev_priv->card_type == NV_10 && | ||
| 187 | nvbo->tile_mode && (type & TTM_PL_FLAG_VRAM)) { | ||
| 188 | /* | ||
| 189 | * Make sure that the color and depth buffers are handled | ||
| 190 | * by independent memory controller units. Up to a 9x | ||
| 191 | * speed up when alpha-blending and depth-test are enabled | ||
| 192 | * at the same time. | ||
| 193 | */ | ||
| 194 | int vram_pages = dev_priv->vram_size >> PAGE_SHIFT; | ||
| 195 | |||
| 196 | if (nvbo->tile_flags & NOUVEAU_GEM_TILE_ZETA) { | ||
| 197 | nvbo->placement.fpfn = vram_pages / 2; | ||
| 198 | nvbo->placement.lpfn = ~0; | ||
| 199 | } else { | ||
| 200 | nvbo->placement.fpfn = 0; | ||
| 201 | nvbo->placement.lpfn = vram_pages / 2; | ||
| 202 | } | ||
| 203 | } | ||
| 204 | } | ||
| 205 | |||
| 179 | void | 206 | void |
| 180 | nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) | 207 | nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) |
| 181 | { | 208 | { |
| @@ -190,6 +217,8 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, uint32_t type, uint32_t busy) | |||
| 190 | pl->busy_placement = nvbo->busy_placements; | 217 | pl->busy_placement = nvbo->busy_placements; |
| 191 | set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, | 218 | set_placement_list(nvbo->busy_placements, &pl->num_busy_placement, |
| 192 | type | busy, flags); | 219 | type | busy, flags); |
| 220 | |||
| 221 | set_placement_range(nvbo, type); | ||
| 193 | } | 222 | } |
| 194 | 223 | ||
| 195 | int | 224 | int |
| @@ -525,7 +554,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, | |||
| 525 | stride = 16 * 4; | 554 | stride = 16 * 4; |
| 526 | height = amount / stride; | 555 | height = amount / stride; |
| 527 | 556 | ||
| 528 | if (new_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) { | 557 | if (new_mem->mem_type == TTM_PL_VRAM && |
| 558 | nouveau_bo_tile_layout(nvbo)) { | ||
| 529 | ret = RING_SPACE(chan, 8); | 559 | ret = RING_SPACE(chan, 8); |
| 530 | if (ret) | 560 | if (ret) |
| 531 | return ret; | 561 | return ret; |
| @@ -546,7 +576,8 @@ nv50_bo_move_m2mf(struct nouveau_channel *chan, struct ttm_buffer_object *bo, | |||
| 546 | BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); | 576 | BEGIN_RING(chan, NvSubM2MF, 0x0200, 1); |
| 547 | OUT_RING (chan, 1); | 577 | OUT_RING (chan, 1); |
| 548 | } | 578 | } |
| 549 | if (old_mem->mem_type == TTM_PL_VRAM && nvbo->tile_flags) { | 579 | if (old_mem->mem_type == TTM_PL_VRAM && |
| 580 | nouveau_bo_tile_layout(nvbo)) { | ||
| 550 | ret = RING_SPACE(chan, 8); | 581 | ret = RING_SPACE(chan, 8); |
| 551 | if (ret) | 582 | if (ret) |
| 552 | return ret; | 583 | return ret; |
| @@ -753,7 +784,8 @@ nouveau_bo_vm_bind(struct ttm_buffer_object *bo, struct ttm_mem_reg *new_mem, | |||
| 753 | if (dev_priv->card_type == NV_50) { | 784 | if (dev_priv->card_type == NV_50) { |
| 754 | ret = nv50_mem_vm_bind_linear(dev, | 785 | ret = nv50_mem_vm_bind_linear(dev, |
| 755 | offset + dev_priv->vm_vram_base, | 786 | offset + dev_priv->vm_vram_base, |
| 756 | new_mem->size, nvbo->tile_flags, | 787 | new_mem->size, |
| 788 | nouveau_bo_tile_layout(nvbo), | ||
| 757 | offset); | 789 | offset); |
| 758 | if (ret) | 790 | if (ret) |
| 759 | return ret; | 791 | return ret; |
| @@ -894,7 +926,8 @@ nouveau_ttm_fault_reserve_notify(struct ttm_buffer_object *bo) | |||
| 894 | * nothing to do here. | 926 | * nothing to do here. |
| 895 | */ | 927 | */ |
| 896 | if (bo->mem.mem_type != TTM_PL_VRAM) { | 928 | if (bo->mem.mem_type != TTM_PL_VRAM) { |
| 897 | if (dev_priv->card_type < NV_50 || !nvbo->tile_flags) | 929 | if (dev_priv->card_type < NV_50 || |
| 930 | !nouveau_bo_tile_layout(nvbo)) | ||
| 898 | return 0; | 931 | return 0; |
| 899 | } | 932 | } |
| 900 | 933 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.c b/drivers/gpu/drm/nouveau/nouveau_connector.c index 0871495096fa..52c356e9a3d1 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.c +++ b/drivers/gpu/drm/nouveau/nouveau_connector.c | |||
| @@ -281,7 +281,7 @@ detect_analog: | |||
| 281 | nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); | 281 | nv_encoder = find_encoder_by_type(connector, OUTPUT_ANALOG); |
| 282 | if (!nv_encoder && !nouveau_tv_disable) | 282 | if (!nv_encoder && !nouveau_tv_disable) |
| 283 | nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); | 283 | nv_encoder = find_encoder_by_type(connector, OUTPUT_TV); |
| 284 | if (nv_encoder) { | 284 | if (nv_encoder && force) { |
| 285 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); | 285 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); |
| 286 | struct drm_encoder_helper_funcs *helper = | 286 | struct drm_encoder_helper_funcs *helper = |
| 287 | encoder->helper_private; | 287 | encoder->helper_private; |
| @@ -641,11 +641,28 @@ nouveau_connector_get_modes(struct drm_connector *connector) | |||
| 641 | return ret; | 641 | return ret; |
| 642 | } | 642 | } |
| 643 | 643 | ||
| 644 | static unsigned | ||
| 645 | get_tmds_link_bandwidth(struct drm_connector *connector) | ||
| 646 | { | ||
| 647 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | ||
| 648 | struct drm_nouveau_private *dev_priv = connector->dev->dev_private; | ||
| 649 | struct dcb_entry *dcb = nv_connector->detected_encoder->dcb; | ||
| 650 | |||
| 651 | if (dcb->location != DCB_LOC_ON_CHIP || | ||
| 652 | dev_priv->chipset >= 0x46) | ||
| 653 | return 165000; | ||
| 654 | else if (dev_priv->chipset >= 0x40) | ||
| 655 | return 155000; | ||
| 656 | else if (dev_priv->chipset >= 0x18) | ||
| 657 | return 135000; | ||
| 658 | else | ||
| 659 | return 112000; | ||
| 660 | } | ||
| 661 | |||
| 644 | static int | 662 | static int |
| 645 | nouveau_connector_mode_valid(struct drm_connector *connector, | 663 | nouveau_connector_mode_valid(struct drm_connector *connector, |
| 646 | struct drm_display_mode *mode) | 664 | struct drm_display_mode *mode) |
| 647 | { | 665 | { |
| 648 | struct drm_nouveau_private *dev_priv = connector->dev->dev_private; | ||
| 649 | struct nouveau_connector *nv_connector = nouveau_connector(connector); | 666 | struct nouveau_connector *nv_connector = nouveau_connector(connector); |
| 650 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; | 667 | struct nouveau_encoder *nv_encoder = nv_connector->detected_encoder; |
| 651 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); | 668 | struct drm_encoder *encoder = to_drm_encoder(nv_encoder); |
| @@ -663,11 +680,9 @@ nouveau_connector_mode_valid(struct drm_connector *connector, | |||
| 663 | max_clock = 400000; | 680 | max_clock = 400000; |
| 664 | break; | 681 | break; |
| 665 | case OUTPUT_TMDS: | 682 | case OUTPUT_TMDS: |
| 666 | if ((dev_priv->card_type >= NV_50 && !nouveau_duallink) || | 683 | max_clock = get_tmds_link_bandwidth(connector); |
| 667 | !nv_encoder->dcb->duallink_possible) | 684 | if (nouveau_duallink && nv_encoder->dcb->duallink_possible) |
| 668 | max_clock = 165000; | 685 | max_clock *= 2; |
| 669 | else | ||
| 670 | max_clock = 330000; | ||
| 671 | break; | 686 | break; |
| 672 | case OUTPUT_ANALOG: | 687 | case OUTPUT_ANALOG: |
| 673 | max_clock = nv_encoder->dcb->crtconf.maxfreq; | 688 | max_clock = nv_encoder->dcb->crtconf.maxfreq; |
| @@ -709,44 +724,6 @@ nouveau_connector_best_encoder(struct drm_connector *connector) | |||
| 709 | return NULL; | 724 | return NULL; |
| 710 | } | 725 | } |
| 711 | 726 | ||
| 712 | void | ||
| 713 | nouveau_connector_set_polling(struct drm_connector *connector) | ||
| 714 | { | ||
| 715 | struct drm_device *dev = connector->dev; | ||
| 716 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 717 | struct drm_crtc *crtc; | ||
| 718 | bool spare_crtc = false; | ||
| 719 | |||
| 720 | list_for_each_entry(crtc, &dev->mode_config.crtc_list, head) | ||
| 721 | spare_crtc |= !crtc->enabled; | ||
| 722 | |||
| 723 | connector->polled = 0; | ||
| 724 | |||
| 725 | switch (connector->connector_type) { | ||
| 726 | case DRM_MODE_CONNECTOR_VGA: | ||
| 727 | case DRM_MODE_CONNECTOR_TV: | ||
| 728 | if (dev_priv->card_type >= NV_50 || | ||
| 729 | (nv_gf4_disp_arch(dev) && spare_crtc)) | ||
| 730 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
| 731 | break; | ||
| 732 | |||
| 733 | case DRM_MODE_CONNECTOR_DVII: | ||
| 734 | case DRM_MODE_CONNECTOR_DVID: | ||
| 735 | case DRM_MODE_CONNECTOR_HDMIA: | ||
| 736 | case DRM_MODE_CONNECTOR_DisplayPort: | ||
| 737 | case DRM_MODE_CONNECTOR_eDP: | ||
| 738 | if (dev_priv->card_type >= NV_50) | ||
| 739 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
| 740 | else if (connector->connector_type == DRM_MODE_CONNECTOR_DVID || | ||
| 741 | spare_crtc) | ||
| 742 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
| 743 | break; | ||
| 744 | |||
| 745 | default: | ||
| 746 | break; | ||
| 747 | } | ||
| 748 | } | ||
| 749 | |||
| 750 | static const struct drm_connector_helper_funcs | 727 | static const struct drm_connector_helper_funcs |
| 751 | nouveau_connector_helper_funcs = { | 728 | nouveau_connector_helper_funcs = { |
| 752 | .get_modes = nouveau_connector_get_modes, | 729 | .get_modes = nouveau_connector_get_modes, |
| @@ -872,6 +849,7 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
| 872 | dev->mode_config.scaling_mode_property, | 849 | dev->mode_config.scaling_mode_property, |
| 873 | nv_connector->scaling_mode); | 850 | nv_connector->scaling_mode); |
| 874 | } | 851 | } |
| 852 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
| 875 | /* fall-through */ | 853 | /* fall-through */ |
| 876 | case DCB_CONNECTOR_TV_0: | 854 | case DCB_CONNECTOR_TV_0: |
| 877 | case DCB_CONNECTOR_TV_1: | 855 | case DCB_CONNECTOR_TV_1: |
| @@ -888,11 +866,16 @@ nouveau_connector_create(struct drm_device *dev, int index) | |||
| 888 | dev->mode_config.dithering_mode_property, | 866 | dev->mode_config.dithering_mode_property, |
| 889 | nv_connector->use_dithering ? | 867 | nv_connector->use_dithering ? |
| 890 | DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); | 868 | DRM_MODE_DITHERING_ON : DRM_MODE_DITHERING_OFF); |
| 869 | |||
| 870 | if (dcb->type != DCB_CONNECTOR_LVDS) { | ||
| 871 | if (dev_priv->card_type >= NV_50) | ||
| 872 | connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
| 873 | else | ||
| 874 | connector->polled = DRM_CONNECTOR_POLL_CONNECT; | ||
| 875 | } | ||
| 891 | break; | 876 | break; |
| 892 | } | 877 | } |
| 893 | 878 | ||
| 894 | nouveau_connector_set_polling(connector); | ||
| 895 | |||
| 896 | drm_sysfs_connector_add(connector); | 879 | drm_sysfs_connector_add(connector); |
| 897 | dcb->drm = connector; | 880 | dcb->drm = connector; |
| 898 | return dcb->drm; | 881 | return dcb->drm; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_connector.h b/drivers/gpu/drm/nouveau/nouveau_connector.h index c21ed6b16f88..711b1e9203af 100644 --- a/drivers/gpu/drm/nouveau/nouveau_connector.h +++ b/drivers/gpu/drm/nouveau/nouveau_connector.h | |||
| @@ -52,9 +52,6 @@ static inline struct nouveau_connector *nouveau_connector( | |||
| 52 | struct drm_connector * | 52 | struct drm_connector * |
| 53 | nouveau_connector_create(struct drm_device *, int index); | 53 | nouveau_connector_create(struct drm_device *, int index); |
| 54 | 54 | ||
| 55 | void | ||
| 56 | nouveau_connector_set_polling(struct drm_connector *); | ||
| 57 | |||
| 58 | int | 55 | int |
| 59 | nouveau_connector_bpp(struct drm_connector *); | 56 | nouveau_connector_bpp(struct drm_connector *); |
| 60 | 57 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_drv.h b/drivers/gpu/drm/nouveau/nouveau_drv.h index 3a07e580d27a..1c7db64c03bf 100644 --- a/drivers/gpu/drm/nouveau/nouveau_drv.h +++ b/drivers/gpu/drm/nouveau/nouveau_drv.h | |||
| @@ -100,6 +100,9 @@ struct nouveau_bo { | |||
| 100 | int pin_refcnt; | 100 | int pin_refcnt; |
| 101 | }; | 101 | }; |
| 102 | 102 | ||
| 103 | #define nouveau_bo_tile_layout(nvbo) \ | ||
| 104 | ((nvbo)->tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) | ||
| 105 | |||
| 103 | static inline struct nouveau_bo * | 106 | static inline struct nouveau_bo * |
| 104 | nouveau_bo(struct ttm_buffer_object *bo) | 107 | nouveau_bo(struct ttm_buffer_object *bo) |
| 105 | { | 108 | { |
| @@ -304,6 +307,7 @@ struct nouveau_fifo_engine { | |||
| 304 | void (*destroy_context)(struct nouveau_channel *); | 307 | void (*destroy_context)(struct nouveau_channel *); |
| 305 | int (*load_context)(struct nouveau_channel *); | 308 | int (*load_context)(struct nouveau_channel *); |
| 306 | int (*unload_context)(struct drm_device *); | 309 | int (*unload_context)(struct drm_device *); |
| 310 | void (*tlb_flush)(struct drm_device *dev); | ||
| 307 | }; | 311 | }; |
| 308 | 312 | ||
| 309 | struct nouveau_pgraph_object_method { | 313 | struct nouveau_pgraph_object_method { |
| @@ -336,6 +340,7 @@ struct nouveau_pgraph_engine { | |||
| 336 | void (*destroy_context)(struct nouveau_channel *); | 340 | void (*destroy_context)(struct nouveau_channel *); |
| 337 | int (*load_context)(struct nouveau_channel *); | 341 | int (*load_context)(struct nouveau_channel *); |
| 338 | int (*unload_context)(struct drm_device *); | 342 | int (*unload_context)(struct drm_device *); |
| 343 | void (*tlb_flush)(struct drm_device *dev); | ||
| 339 | 344 | ||
| 340 | void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, | 345 | void (*set_region_tiling)(struct drm_device *dev, int i, uint32_t addr, |
| 341 | uint32_t size, uint32_t pitch); | 346 | uint32_t size, uint32_t pitch); |
| @@ -485,13 +490,13 @@ enum nv04_fp_display_regs { | |||
| 485 | }; | 490 | }; |
| 486 | 491 | ||
| 487 | struct nv04_crtc_reg { | 492 | struct nv04_crtc_reg { |
| 488 | unsigned char MiscOutReg; /* */ | 493 | unsigned char MiscOutReg; |
| 489 | uint8_t CRTC[0xa0]; | 494 | uint8_t CRTC[0xa0]; |
| 490 | uint8_t CR58[0x10]; | 495 | uint8_t CR58[0x10]; |
| 491 | uint8_t Sequencer[5]; | 496 | uint8_t Sequencer[5]; |
| 492 | uint8_t Graphics[9]; | 497 | uint8_t Graphics[9]; |
| 493 | uint8_t Attribute[21]; | 498 | uint8_t Attribute[21]; |
| 494 | unsigned char DAC[768]; /* Internal Colorlookuptable */ | 499 | unsigned char DAC[768]; |
| 495 | 500 | ||
| 496 | /* PCRTC regs */ | 501 | /* PCRTC regs */ |
| 497 | uint32_t fb_start; | 502 | uint32_t fb_start; |
| @@ -539,43 +544,9 @@ struct nv04_output_reg { | |||
| 539 | }; | 544 | }; |
| 540 | 545 | ||
| 541 | struct nv04_mode_state { | 546 | struct nv04_mode_state { |
| 542 | uint32_t bpp; | 547 | struct nv04_crtc_reg crtc_reg[2]; |
| 543 | uint32_t width; | ||
| 544 | uint32_t height; | ||
| 545 | uint32_t interlace; | ||
| 546 | uint32_t repaint0; | ||
| 547 | uint32_t repaint1; | ||
| 548 | uint32_t screen; | ||
| 549 | uint32_t scale; | ||
| 550 | uint32_t dither; | ||
| 551 | uint32_t extra; | ||
| 552 | uint32_t fifo; | ||
| 553 | uint32_t pixel; | ||
| 554 | uint32_t horiz; | ||
| 555 | int arbitration0; | ||
| 556 | int arbitration1; | ||
| 557 | uint32_t pll; | ||
| 558 | uint32_t pllB; | ||
| 559 | uint32_t vpll; | ||
| 560 | uint32_t vpll2; | ||
| 561 | uint32_t vpllB; | ||
| 562 | uint32_t vpll2B; | ||
| 563 | uint32_t pllsel; | 548 | uint32_t pllsel; |
| 564 | uint32_t sel_clk; | 549 | uint32_t sel_clk; |
| 565 | uint32_t general; | ||
| 566 | uint32_t crtcOwner; | ||
| 567 | uint32_t head; | ||
| 568 | uint32_t head2; | ||
| 569 | uint32_t cursorConfig; | ||
| 570 | uint32_t cursor0; | ||
| 571 | uint32_t cursor1; | ||
| 572 | uint32_t cursor2; | ||
| 573 | uint32_t timingH; | ||
| 574 | uint32_t timingV; | ||
| 575 | uint32_t displayV; | ||
| 576 | uint32_t crtcSync; | ||
| 577 | |||
| 578 | struct nv04_crtc_reg crtc_reg[2]; | ||
| 579 | }; | 550 | }; |
| 580 | 551 | ||
| 581 | enum nouveau_card_type { | 552 | enum nouveau_card_type { |
| @@ -613,6 +584,12 @@ struct drm_nouveau_private { | |||
| 613 | struct work_struct irq_work; | 584 | struct work_struct irq_work; |
| 614 | struct work_struct hpd_work; | 585 | struct work_struct hpd_work; |
| 615 | 586 | ||
| 587 | struct { | ||
| 588 | spinlock_t lock; | ||
| 589 | uint32_t hpd0_bits; | ||
| 590 | uint32_t hpd1_bits; | ||
| 591 | } hpd_state; | ||
| 592 | |||
| 616 | struct list_head vbl_waiting; | 593 | struct list_head vbl_waiting; |
| 617 | 594 | ||
| 618 | struct { | 595 | struct { |
| @@ -1045,6 +1022,7 @@ extern int nv50_fifo_create_context(struct nouveau_channel *); | |||
| 1045 | extern void nv50_fifo_destroy_context(struct nouveau_channel *); | 1022 | extern void nv50_fifo_destroy_context(struct nouveau_channel *); |
| 1046 | extern int nv50_fifo_load_context(struct nouveau_channel *); | 1023 | extern int nv50_fifo_load_context(struct nouveau_channel *); |
| 1047 | extern int nv50_fifo_unload_context(struct drm_device *); | 1024 | extern int nv50_fifo_unload_context(struct drm_device *); |
| 1025 | extern void nv50_fifo_tlb_flush(struct drm_device *dev); | ||
| 1048 | 1026 | ||
| 1049 | /* nvc0_fifo.c */ | 1027 | /* nvc0_fifo.c */ |
| 1050 | extern int nvc0_fifo_init(struct drm_device *); | 1028 | extern int nvc0_fifo_init(struct drm_device *); |
| @@ -1122,6 +1100,8 @@ extern int nv50_graph_load_context(struct nouveau_channel *); | |||
| 1122 | extern int nv50_graph_unload_context(struct drm_device *); | 1100 | extern int nv50_graph_unload_context(struct drm_device *); |
| 1123 | extern void nv50_graph_context_switch(struct drm_device *); | 1101 | extern void nv50_graph_context_switch(struct drm_device *); |
| 1124 | extern int nv50_grctx_init(struct nouveau_grctx *); | 1102 | extern int nv50_grctx_init(struct nouveau_grctx *); |
| 1103 | extern void nv50_graph_tlb_flush(struct drm_device *dev); | ||
| 1104 | extern void nv86_graph_tlb_flush(struct drm_device *dev); | ||
| 1125 | 1105 | ||
| 1126 | /* nvc0_graph.c */ | 1106 | /* nvc0_graph.c */ |
| 1127 | extern int nvc0_graph_init(struct drm_device *); | 1107 | extern int nvc0_graph_init(struct drm_device *); |
| @@ -1239,7 +1219,6 @@ extern u16 nouveau_bo_rd16(struct nouveau_bo *nvbo, unsigned index); | |||
| 1239 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); | 1219 | extern void nouveau_bo_wr16(struct nouveau_bo *nvbo, unsigned index, u16 val); |
| 1240 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); | 1220 | extern u32 nouveau_bo_rd32(struct nouveau_bo *nvbo, unsigned index); |
| 1241 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); | 1221 | extern void nouveau_bo_wr32(struct nouveau_bo *nvbo, unsigned index, u32 val); |
| 1242 | extern int nouveau_bo_sync_gpu(struct nouveau_bo *, struct nouveau_channel *); | ||
| 1243 | 1222 | ||
| 1244 | /* nouveau_fence.c */ | 1223 | /* nouveau_fence.c */ |
| 1245 | struct nouveau_fence; | 1224 | struct nouveau_fence; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_fence.c b/drivers/gpu/drm/nouveau/nouveau_fence.c index 441b12420bb1..ab1bbfbf266e 100644 --- a/drivers/gpu/drm/nouveau/nouveau_fence.c +++ b/drivers/gpu/drm/nouveau/nouveau_fence.c | |||
| @@ -249,6 +249,7 @@ alloc_semaphore(struct drm_device *dev) | |||
| 249 | { | 249 | { |
| 250 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 250 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 251 | struct nouveau_semaphore *sema; | 251 | struct nouveau_semaphore *sema; |
| 252 | int ret; | ||
| 252 | 253 | ||
| 253 | if (!USE_SEMA(dev)) | 254 | if (!USE_SEMA(dev)) |
| 254 | return NULL; | 255 | return NULL; |
| @@ -257,10 +258,14 @@ alloc_semaphore(struct drm_device *dev) | |||
| 257 | if (!sema) | 258 | if (!sema) |
| 258 | goto fail; | 259 | goto fail; |
| 259 | 260 | ||
| 261 | ret = drm_mm_pre_get(&dev_priv->fence.heap); | ||
| 262 | if (ret) | ||
| 263 | goto fail; | ||
| 264 | |||
| 260 | spin_lock(&dev_priv->fence.lock); | 265 | spin_lock(&dev_priv->fence.lock); |
| 261 | sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0); | 266 | sema->mem = drm_mm_search_free(&dev_priv->fence.heap, 4, 0, 0); |
| 262 | if (sema->mem) | 267 | if (sema->mem) |
| 263 | sema->mem = drm_mm_get_block(sema->mem, 4, 0); | 268 | sema->mem = drm_mm_get_block_atomic(sema->mem, 4, 0); |
| 264 | spin_unlock(&dev_priv->fence.lock); | 269 | spin_unlock(&dev_priv->fence.lock); |
| 265 | 270 | ||
| 266 | if (!sema->mem) | 271 | if (!sema->mem) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_gem.c b/drivers/gpu/drm/nouveau/nouveau_gem.c index 5c4c929d7f74..9a1fdcf400c2 100644 --- a/drivers/gpu/drm/nouveau/nouveau_gem.c +++ b/drivers/gpu/drm/nouveau/nouveau_gem.c | |||
| @@ -107,23 +107,29 @@ nouveau_gem_info(struct drm_gem_object *gem, struct drm_nouveau_gem_info *rep) | |||
| 107 | } | 107 | } |
| 108 | 108 | ||
| 109 | static bool | 109 | static bool |
| 110 | nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) { | 110 | nouveau_gem_tile_flags_valid(struct drm_device *dev, uint32_t tile_flags) |
| 111 | switch (tile_flags) { | 111 | { |
| 112 | case 0x0000: | 112 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 113 | case 0x1800: | 113 | |
| 114 | case 0x2800: | 114 | if (dev_priv->card_type >= NV_50) { |
| 115 | case 0x4800: | 115 | switch (tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK) { |
| 116 | case 0x7000: | 116 | case 0x0000: |
| 117 | case 0x7400: | 117 | case 0x1800: |
| 118 | case 0x7a00: | 118 | case 0x2800: |
| 119 | case 0xe000: | 119 | case 0x4800: |
| 120 | break; | 120 | case 0x7000: |
| 121 | default: | 121 | case 0x7400: |
| 122 | NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags); | 122 | case 0x7a00: |
| 123 | return false; | 123 | case 0xe000: |
| 124 | return true; | ||
| 125 | } | ||
| 126 | } else { | ||
| 127 | if (!(tile_flags & NOUVEAU_GEM_TILE_LAYOUT_MASK)) | ||
| 128 | return true; | ||
| 124 | } | 129 | } |
| 125 | 130 | ||
| 126 | return true; | 131 | NV_ERROR(dev, "bad page flags: 0x%08x\n", tile_flags); |
| 132 | return false; | ||
| 127 | } | 133 | } |
| 128 | 134 | ||
| 129 | int | 135 | int |
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.c b/drivers/gpu/drm/nouveau/nouveau_hw.c index bed669a54a2d..b9672a05c411 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.c +++ b/drivers/gpu/drm/nouveau/nouveau_hw.c | |||
| @@ -519,11 +519,11 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head) | |||
| 519 | 519 | ||
| 520 | struct pll_lims pll_lim; | 520 | struct pll_lims pll_lim; |
| 521 | struct nouveau_pll_vals pv; | 521 | struct nouveau_pll_vals pv; |
| 522 | uint32_t pllreg = head ? NV_RAMDAC_VPLL2 : NV_PRAMDAC_VPLL_COEFF; | 522 | enum pll_types pll = head ? PLL_VPLL1 : PLL_VPLL0; |
| 523 | 523 | ||
| 524 | if (get_pll_limits(dev, pllreg, &pll_lim)) | 524 | if (get_pll_limits(dev, pll, &pll_lim)) |
| 525 | return; | 525 | return; |
| 526 | nouveau_hw_get_pllvals(dev, pllreg, &pv); | 526 | nouveau_hw_get_pllvals(dev, pll, &pv); |
| 527 | 527 | ||
| 528 | if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m && | 528 | if (pv.M1 >= pll_lim.vco1.min_m && pv.M1 <= pll_lim.vco1.max_m && |
| 529 | pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n && | 529 | pv.N1 >= pll_lim.vco1.min_n && pv.N1 <= pll_lim.vco1.max_n && |
| @@ -536,7 +536,7 @@ nouveau_hw_fix_bad_vpll(struct drm_device *dev, int head) | |||
| 536 | pv.M1 = pll_lim.vco1.max_m; | 536 | pv.M1 = pll_lim.vco1.max_m; |
| 537 | pv.N1 = pll_lim.vco1.min_n; | 537 | pv.N1 = pll_lim.vco1.min_n; |
| 538 | pv.log2P = pll_lim.max_usable_log2p; | 538 | pv.log2P = pll_lim.max_usable_log2p; |
| 539 | nouveau_hw_setpll(dev, pllreg, &pv); | 539 | nouveau_hw_setpll(dev, pll_lim.reg, &pv); |
| 540 | } | 540 | } |
| 541 | 541 | ||
| 542 | /* | 542 | /* |
diff --git a/drivers/gpu/drm/nouveau/nouveau_hw.h b/drivers/gpu/drm/nouveau/nouveau_hw.h index 869130f83602..2989090b9434 100644 --- a/drivers/gpu/drm/nouveau/nouveau_hw.h +++ b/drivers/gpu/drm/nouveau/nouveau_hw.h | |||
| @@ -416,6 +416,25 @@ nv_fix_nv40_hw_cursor(struct drm_device *dev, int head) | |||
| 416 | } | 416 | } |
| 417 | 417 | ||
| 418 | static inline void | 418 | static inline void |
| 419 | nv_set_crtc_base(struct drm_device *dev, int head, uint32_t offset) | ||
| 420 | { | ||
| 421 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 422 | |||
| 423 | NVWriteCRTC(dev, head, NV_PCRTC_START, offset); | ||
| 424 | |||
| 425 | if (dev_priv->card_type == NV_04) { | ||
| 426 | /* | ||
| 427 | * Hilarious, the 24th bit doesn't want to stick to | ||
| 428 | * PCRTC_START... | ||
| 429 | */ | ||
| 430 | int cre_heb = NVReadVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX); | ||
| 431 | |||
| 432 | NVWriteVgaCrtc(dev, head, NV_CIO_CRE_HEB__INDEX, | ||
| 433 | (cre_heb & ~0x40) | ((offset >> 18) & 0x40)); | ||
| 434 | } | ||
| 435 | } | ||
| 436 | |||
| 437 | static inline void | ||
| 419 | nv_show_cursor(struct drm_device *dev, int head, bool show) | 438 | nv_show_cursor(struct drm_device *dev, int head, bool show) |
| 420 | { | 439 | { |
| 421 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 440 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_i2c.c b/drivers/gpu/drm/nouveau/nouveau_i2c.c index fdd7e3de79c8..cb389d014326 100644 --- a/drivers/gpu/drm/nouveau/nouveau_i2c.c +++ b/drivers/gpu/drm/nouveau/nouveau_i2c.c | |||
| @@ -256,7 +256,7 @@ nouveau_i2c_find(struct drm_device *dev, int index) | |||
| 256 | if (index >= DCB_MAX_NUM_I2C_ENTRIES) | 256 | if (index >= DCB_MAX_NUM_I2C_ENTRIES) |
| 257 | return NULL; | 257 | return NULL; |
| 258 | 258 | ||
| 259 | if (dev_priv->chipset >= NV_50 && (i2c->entry & 0x00000100)) { | 259 | if (dev_priv->card_type >= NV_50 && (i2c->entry & 0x00000100)) { |
| 260 | uint32_t reg = 0xe500, val; | 260 | uint32_t reg = 0xe500, val; |
| 261 | 261 | ||
| 262 | if (i2c->port_type == 6) { | 262 | if (i2c->port_type == 6) { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_irq.c b/drivers/gpu/drm/nouveau/nouveau_irq.c index 6fd51a51c608..7bfd9e6c9d67 100644 --- a/drivers/gpu/drm/nouveau/nouveau_irq.c +++ b/drivers/gpu/drm/nouveau/nouveau_irq.c | |||
| @@ -42,6 +42,13 @@ | |||
| 42 | #include "nouveau_connector.h" | 42 | #include "nouveau_connector.h" |
| 43 | #include "nv50_display.h" | 43 | #include "nv50_display.h" |
| 44 | 44 | ||
| 45 | static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); | ||
| 46 | |||
| 47 | static int nouveau_ratelimit(void) | ||
| 48 | { | ||
| 49 | return __ratelimit(&nouveau_ratelimit_state); | ||
| 50 | } | ||
| 51 | |||
| 45 | void | 52 | void |
| 46 | nouveau_irq_preinstall(struct drm_device *dev) | 53 | nouveau_irq_preinstall(struct drm_device *dev) |
| 47 | { | 54 | { |
| @@ -53,6 +60,7 @@ nouveau_irq_preinstall(struct drm_device *dev) | |||
| 53 | if (dev_priv->card_type >= NV_50) { | 60 | if (dev_priv->card_type >= NV_50) { |
| 54 | INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); | 61 | INIT_WORK(&dev_priv->irq_work, nv50_display_irq_handler_bh); |
| 55 | INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); | 62 | INIT_WORK(&dev_priv->hpd_work, nv50_display_irq_hotplug_bh); |
| 63 | spin_lock_init(&dev_priv->hpd_state.lock); | ||
| 56 | INIT_LIST_HEAD(&dev_priv->vbl_waiting); | 64 | INIT_LIST_HEAD(&dev_priv->vbl_waiting); |
| 57 | } | 65 | } |
| 58 | } | 66 | } |
| @@ -202,8 +210,8 @@ nouveau_fifo_irq_handler(struct drm_device *dev) | |||
| 202 | } | 210 | } |
| 203 | 211 | ||
| 204 | if (status & NV_PFIFO_INTR_DMA_PUSHER) { | 212 | if (status & NV_PFIFO_INTR_DMA_PUSHER) { |
| 205 | u32 get = nv_rd32(dev, 0x003244); | 213 | u32 dma_get = nv_rd32(dev, 0x003244); |
| 206 | u32 put = nv_rd32(dev, 0x003240); | 214 | u32 dma_put = nv_rd32(dev, 0x003240); |
| 207 | u32 push = nv_rd32(dev, 0x003220); | 215 | u32 push = nv_rd32(dev, 0x003220); |
| 208 | u32 state = nv_rd32(dev, 0x003228); | 216 | u32 state = nv_rd32(dev, 0x003228); |
| 209 | 217 | ||
| @@ -213,16 +221,18 @@ nouveau_fifo_irq_handler(struct drm_device *dev) | |||
| 213 | u32 ib_get = nv_rd32(dev, 0x003334); | 221 | u32 ib_get = nv_rd32(dev, 0x003334); |
| 214 | u32 ib_put = nv_rd32(dev, 0x003330); | 222 | u32 ib_put = nv_rd32(dev, 0x003330); |
| 215 | 223 | ||
| 216 | NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " | 224 | if (nouveau_ratelimit()) |
| 225 | NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%02x%08x " | ||
| 217 | "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " | 226 | "Put 0x%02x%08x IbGet 0x%08x IbPut 0x%08x " |
| 218 | "State 0x%08x Push 0x%08x\n", | 227 | "State 0x%08x Push 0x%08x\n", |
| 219 | chid, ho_get, get, ho_put, put, ib_get, ib_put, | 228 | chid, ho_get, dma_get, ho_put, |
| 220 | state, push); | 229 | dma_put, ib_get, ib_put, state, |
| 230 | push); | ||
| 221 | 231 | ||
| 222 | /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ | 232 | /* METHOD_COUNT, in DMA_STATE on earlier chipsets */ |
| 223 | nv_wr32(dev, 0x003364, 0x00000000); | 233 | nv_wr32(dev, 0x003364, 0x00000000); |
| 224 | if (get != put || ho_get != ho_put) { | 234 | if (dma_get != dma_put || ho_get != ho_put) { |
| 225 | nv_wr32(dev, 0x003244, put); | 235 | nv_wr32(dev, 0x003244, dma_put); |
| 226 | nv_wr32(dev, 0x003328, ho_put); | 236 | nv_wr32(dev, 0x003328, ho_put); |
| 227 | } else | 237 | } else |
| 228 | if (ib_get != ib_put) { | 238 | if (ib_get != ib_put) { |
| @@ -231,10 +241,10 @@ nouveau_fifo_irq_handler(struct drm_device *dev) | |||
| 231 | } else { | 241 | } else { |
| 232 | NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " | 242 | NV_INFO(dev, "PFIFO_DMA_PUSHER - Ch %d Get 0x%08x " |
| 233 | "Put 0x%08x State 0x%08x Push 0x%08x\n", | 243 | "Put 0x%08x State 0x%08x Push 0x%08x\n", |
| 234 | chid, get, put, state, push); | 244 | chid, dma_get, dma_put, state, push); |
| 235 | 245 | ||
| 236 | if (get != put) | 246 | if (dma_get != dma_put) |
| 237 | nv_wr32(dev, 0x003244, put); | 247 | nv_wr32(dev, 0x003244, dma_put); |
| 238 | } | 248 | } |
| 239 | 249 | ||
| 240 | nv_wr32(dev, 0x003228, 0x00000000); | 250 | nv_wr32(dev, 0x003228, 0x00000000); |
| @@ -266,8 +276,9 @@ nouveau_fifo_irq_handler(struct drm_device *dev) | |||
| 266 | } | 276 | } |
| 267 | 277 | ||
| 268 | if (status) { | 278 | if (status) { |
| 269 | NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", | 279 | if (nouveau_ratelimit()) |
| 270 | status, chid); | 280 | NV_INFO(dev, "PFIFO_INTR 0x%08x - Ch %d\n", |
| 281 | status, chid); | ||
| 271 | nv_wr32(dev, NV03_PFIFO_INTR_0, status); | 282 | nv_wr32(dev, NV03_PFIFO_INTR_0, status); |
| 272 | status = 0; | 283 | status = 0; |
| 273 | } | 284 | } |
| @@ -544,13 +555,6 @@ nouveau_pgraph_intr_notify(struct drm_device *dev, uint32_t nsource) | |||
| 544 | nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); | 555 | nouveau_graph_dump_trap_info(dev, "PGRAPH_NOTIFY", &trap); |
| 545 | } | 556 | } |
| 546 | 557 | ||
| 547 | static DEFINE_RATELIMIT_STATE(nouveau_ratelimit_state, 3 * HZ, 20); | ||
| 548 | |||
| 549 | static int nouveau_ratelimit(void) | ||
| 550 | { | ||
| 551 | return __ratelimit(&nouveau_ratelimit_state); | ||
| 552 | } | ||
| 553 | |||
| 554 | 558 | ||
| 555 | static inline void | 559 | static inline void |
| 556 | nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) | 560 | nouveau_pgraph_intr_error(struct drm_device *dev, uint32_t nsource) |
diff --git a/drivers/gpu/drm/nouveau/nouveau_mem.c b/drivers/gpu/drm/nouveau/nouveau_mem.c index a163c7c612e7..fe4a30dc4b42 100644 --- a/drivers/gpu/drm/nouveau/nouveau_mem.c +++ b/drivers/gpu/drm/nouveau/nouveau_mem.c | |||
| @@ -33,9 +33,9 @@ | |||
| 33 | #include "drmP.h" | 33 | #include "drmP.h" |
| 34 | #include "drm.h" | 34 | #include "drm.h" |
| 35 | #include "drm_sarea.h" | 35 | #include "drm_sarea.h" |
| 36 | #include "nouveau_drv.h" | ||
| 37 | 36 | ||
| 38 | #define MIN(a,b) a < b ? a : b | 37 | #include "nouveau_drv.h" |
| 38 | #include "nouveau_pm.h" | ||
| 39 | 39 | ||
| 40 | /* | 40 | /* |
| 41 | * NV10-NV40 tiling helpers | 41 | * NV10-NV40 tiling helpers |
| @@ -175,11 +175,10 @@ nv50_mem_vm_bind_linear(struct drm_device *dev, uint64_t virt, uint32_t size, | |||
| 175 | } | 175 | } |
| 176 | } | 176 | } |
| 177 | } | 177 | } |
| 178 | dev_priv->engine.instmem.flush(dev); | ||
| 179 | 178 | ||
| 180 | nv50_vm_flush(dev, 5); | 179 | dev_priv->engine.instmem.flush(dev); |
| 181 | nv50_vm_flush(dev, 0); | 180 | dev_priv->engine.fifo.tlb_flush(dev); |
| 182 | nv50_vm_flush(dev, 4); | 181 | dev_priv->engine.graph.tlb_flush(dev); |
| 183 | nv50_vm_flush(dev, 6); | 182 | nv50_vm_flush(dev, 6); |
| 184 | return 0; | 183 | return 0; |
| 185 | } | 184 | } |
| @@ -209,11 +208,10 @@ nv50_mem_vm_unbind(struct drm_device *dev, uint64_t virt, uint32_t size) | |||
| 209 | pte++; | 208 | pte++; |
| 210 | } | 209 | } |
| 211 | } | 210 | } |
| 212 | dev_priv->engine.instmem.flush(dev); | ||
| 213 | 211 | ||
| 214 | nv50_vm_flush(dev, 5); | 212 | dev_priv->engine.instmem.flush(dev); |
| 215 | nv50_vm_flush(dev, 0); | 213 | dev_priv->engine.fifo.tlb_flush(dev); |
| 216 | nv50_vm_flush(dev, 4); | 214 | dev_priv->engine.graph.tlb_flush(dev); |
| 217 | nv50_vm_flush(dev, 6); | 215 | nv50_vm_flush(dev, 6); |
| 218 | } | 216 | } |
| 219 | 217 | ||
| @@ -653,6 +651,7 @@ nouveau_mem_gart_init(struct drm_device *dev) | |||
| 653 | void | 651 | void |
| 654 | nouveau_mem_timing_init(struct drm_device *dev) | 652 | nouveau_mem_timing_init(struct drm_device *dev) |
| 655 | { | 653 | { |
| 654 | /* cards < NVC0 only */ | ||
| 656 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 655 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 657 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | 656 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; |
| 658 | struct nouveau_pm_memtimings *memtimings = &pm->memtimings; | 657 | struct nouveau_pm_memtimings *memtimings = &pm->memtimings; |
| @@ -719,14 +718,14 @@ nouveau_mem_timing_init(struct drm_device *dev) | |||
| 719 | tUNK_19 = 1; | 718 | tUNK_19 = 1; |
| 720 | tUNK_20 = 0; | 719 | tUNK_20 = 0; |
| 721 | tUNK_21 = 0; | 720 | tUNK_21 = 0; |
| 722 | switch (MIN(recordlen,21)) { | 721 | switch (min(recordlen, 22)) { |
| 723 | case 21: | 722 | case 22: |
| 724 | tUNK_21 = entry[21]; | 723 | tUNK_21 = entry[21]; |
| 725 | case 20: | 724 | case 21: |
| 726 | tUNK_20 = entry[20]; | 725 | tUNK_20 = entry[20]; |
| 727 | case 19: | 726 | case 20: |
| 728 | tUNK_19 = entry[19]; | 727 | tUNK_19 = entry[19]; |
| 729 | case 18: | 728 | case 19: |
| 730 | tUNK_18 = entry[18]; | 729 | tUNK_18 = entry[18]; |
| 731 | default: | 730 | default: |
| 732 | tUNK_0 = entry[0]; | 731 | tUNK_0 = entry[0]; |
| @@ -756,24 +755,30 @@ nouveau_mem_timing_init(struct drm_device *dev) | |||
| 756 | timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); | 755 | timing->reg_100228 = (tUNK_12 << 16 | tUNK_11 << 8 | tUNK_10); |
| 757 | if(recordlen > 19) { | 756 | if(recordlen > 19) { |
| 758 | timing->reg_100228 += (tUNK_19 - 1) << 24; | 757 | timing->reg_100228 += (tUNK_19 - 1) << 24; |
| 759 | } else { | 758 | }/* I cannot back-up this else-statement right now |
| 759 | else { | ||
| 760 | timing->reg_100228 += tUNK_12 << 24; | 760 | timing->reg_100228 += tUNK_12 << 24; |
| 761 | } | 761 | }*/ |
| 762 | 762 | ||
| 763 | /* XXX: reg_10022c */ | 763 | /* XXX: reg_10022c */ |
| 764 | timing->reg_10022c = tUNK_2 - 1; | ||
| 764 | 765 | ||
| 765 | timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | | 766 | timing->reg_100230 = (tUNK_20 << 24 | tUNK_21 << 16 | |
| 766 | tUNK_13 << 8 | tUNK_13); | 767 | tUNK_13 << 8 | tUNK_13); |
| 767 | 768 | ||
| 768 | /* XXX: +6? */ | 769 | /* XXX: +6? */ |
| 769 | timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC); | 770 | timing->reg_100234 = (tRAS << 24 | (tUNK_19 + 6) << 8 | tRC); |
| 770 | if(tUNK_10 > tUNK_11) { | 771 | timing->reg_100234 += max(tUNK_10,tUNK_11) << 16; |
| 771 | timing->reg_100234 += tUNK_10 << 16; | 772 | |
| 772 | } else { | 773 | /* XXX; reg_100238, reg_10023c |
| 773 | timing->reg_100234 += tUNK_11 << 16; | 774 | * reg: 0x00?????? |
| 775 | * reg_10023c: | ||
| 776 | * 0 for pre-NV50 cards | ||
| 777 | * 0x????0202 for NV50+ cards (empirical evidence) */ | ||
| 778 | if(dev_priv->card_type >= NV_50) { | ||
| 779 | timing->reg_10023c = 0x202; | ||
| 774 | } | 780 | } |
| 775 | 781 | ||
| 776 | /* XXX; reg_100238, reg_10023c */ | ||
| 777 | NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, | 782 | NV_DEBUG(dev, "Entry %d: 220: %08x %08x %08x %08x\n", i, |
| 778 | timing->reg_100220, timing->reg_100224, | 783 | timing->reg_100220, timing->reg_100224, |
| 779 | timing->reg_100228, timing->reg_10022c); | 784 | timing->reg_100228, timing->reg_10022c); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_object.c b/drivers/gpu/drm/nouveau/nouveau_object.c index 896cf8634144..dd572adca02a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_object.c +++ b/drivers/gpu/drm/nouveau/nouveau_object.c | |||
| @@ -129,7 +129,7 @@ nouveau_gpuobj_new(struct drm_device *dev, struct nouveau_channel *chan, | |||
| 129 | if (ramin == NULL) { | 129 | if (ramin == NULL) { |
| 130 | spin_unlock(&dev_priv->ramin_lock); | 130 | spin_unlock(&dev_priv->ramin_lock); |
| 131 | nouveau_gpuobj_ref(NULL, &gpuobj); | 131 | nouveau_gpuobj_ref(NULL, &gpuobj); |
| 132 | return ret; | 132 | return -ENOMEM; |
| 133 | } | 133 | } |
| 134 | 134 | ||
| 135 | ramin = drm_mm_get_block_atomic(ramin, size, align); | 135 | ramin = drm_mm_get_block_atomic(ramin, size, align); |
diff --git a/drivers/gpu/drm/nouveau/nouveau_pm.c b/drivers/gpu/drm/nouveau/nouveau_pm.c index 1c99c55d6d46..9f7b158f5825 100644 --- a/drivers/gpu/drm/nouveau/nouveau_pm.c +++ b/drivers/gpu/drm/nouveau/nouveau_pm.c | |||
| @@ -284,6 +284,7 @@ nouveau_sysfs_fini(struct drm_device *dev) | |||
| 284 | } | 284 | } |
| 285 | } | 285 | } |
| 286 | 286 | ||
| 287 | #ifdef CONFIG_HWMON | ||
| 287 | static ssize_t | 288 | static ssize_t |
| 288 | nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) | 289 | nouveau_hwmon_show_temp(struct device *d, struct device_attribute *a, char *buf) |
| 289 | { | 290 | { |
| @@ -395,10 +396,12 @@ static struct attribute *hwmon_attributes[] = { | |||
| 395 | static const struct attribute_group hwmon_attrgroup = { | 396 | static const struct attribute_group hwmon_attrgroup = { |
| 396 | .attrs = hwmon_attributes, | 397 | .attrs = hwmon_attributes, |
| 397 | }; | 398 | }; |
| 399 | #endif | ||
| 398 | 400 | ||
| 399 | static int | 401 | static int |
| 400 | nouveau_hwmon_init(struct drm_device *dev) | 402 | nouveau_hwmon_init(struct drm_device *dev) |
| 401 | { | 403 | { |
| 404 | #ifdef CONFIG_HWMON | ||
| 402 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 405 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 403 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | 406 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; |
| 404 | struct device *hwmon_dev; | 407 | struct device *hwmon_dev; |
| @@ -425,13 +428,14 @@ nouveau_hwmon_init(struct drm_device *dev) | |||
| 425 | } | 428 | } |
| 426 | 429 | ||
| 427 | pm->hwmon = hwmon_dev; | 430 | pm->hwmon = hwmon_dev; |
| 428 | 431 | #endif | |
| 429 | return 0; | 432 | return 0; |
| 430 | } | 433 | } |
| 431 | 434 | ||
| 432 | static void | 435 | static void |
| 433 | nouveau_hwmon_fini(struct drm_device *dev) | 436 | nouveau_hwmon_fini(struct drm_device *dev) |
| 434 | { | 437 | { |
| 438 | #ifdef CONFIG_HWMON | ||
| 435 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 439 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 436 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; | 440 | struct nouveau_pm_engine *pm = &dev_priv->engine.pm; |
| 437 | 441 | ||
| @@ -439,6 +443,7 @@ nouveau_hwmon_fini(struct drm_device *dev) | |||
| 439 | sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup); | 443 | sysfs_remove_group(&pm->hwmon->kobj, &hwmon_attrgroup); |
| 440 | hwmon_device_unregister(pm->hwmon); | 444 | hwmon_device_unregister(pm->hwmon); |
| 441 | } | 445 | } |
| 446 | #endif | ||
| 442 | } | 447 | } |
| 443 | 448 | ||
| 444 | int | 449 | int |
diff --git a/drivers/gpu/drm/nouveau/nouveau_ramht.c b/drivers/gpu/drm/nouveau/nouveau_ramht.c index 7f16697cc96c..2d8580927ca4 100644 --- a/drivers/gpu/drm/nouveau/nouveau_ramht.c +++ b/drivers/gpu/drm/nouveau/nouveau_ramht.c | |||
| @@ -153,26 +153,42 @@ nouveau_ramht_insert(struct nouveau_channel *chan, u32 handle, | |||
| 153 | return -ENOMEM; | 153 | return -ENOMEM; |
| 154 | } | 154 | } |
| 155 | 155 | ||
| 156 | static struct nouveau_ramht_entry * | ||
| 157 | nouveau_ramht_remove_entry(struct nouveau_channel *chan, u32 handle) | ||
| 158 | { | ||
| 159 | struct nouveau_ramht *ramht = chan ? chan->ramht : NULL; | ||
| 160 | struct nouveau_ramht_entry *entry; | ||
| 161 | unsigned long flags; | ||
| 162 | |||
| 163 | if (!ramht) | ||
| 164 | return NULL; | ||
| 165 | |||
| 166 | spin_lock_irqsave(&ramht->lock, flags); | ||
| 167 | list_for_each_entry(entry, &ramht->entries, head) { | ||
| 168 | if (entry->channel == chan && | ||
| 169 | (!handle || entry->handle == handle)) { | ||
| 170 | list_del(&entry->head); | ||
| 171 | spin_unlock_irqrestore(&ramht->lock, flags); | ||
| 172 | |||
| 173 | return entry; | ||
| 174 | } | ||
| 175 | } | ||
| 176 | spin_unlock_irqrestore(&ramht->lock, flags); | ||
| 177 | |||
| 178 | return NULL; | ||
| 179 | } | ||
| 180 | |||
| 156 | static void | 181 | static void |
| 157 | nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle) | 182 | nouveau_ramht_remove_hash(struct nouveau_channel *chan, u32 handle) |
| 158 | { | 183 | { |
| 159 | struct drm_device *dev = chan->dev; | 184 | struct drm_device *dev = chan->dev; |
| 160 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 185 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
| 161 | struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; | 186 | struct nouveau_instmem_engine *instmem = &dev_priv->engine.instmem; |
| 162 | struct nouveau_gpuobj *ramht = chan->ramht->gpuobj; | 187 | struct nouveau_gpuobj *ramht = chan->ramht->gpuobj; |
| 163 | struct nouveau_ramht_entry *entry, *tmp; | 188 | unsigned long flags; |
| 164 | u32 co, ho; | 189 | u32 co, ho; |
| 165 | 190 | ||
| 166 | list_for_each_entry_safe(entry, tmp, &chan->ramht->entries, head) { | 191 | spin_lock_irqsave(&chan->ramht->lock, flags); |
| 167 | if (entry->channel != chan || entry->handle != handle) | ||
| 168 | continue; | ||
| 169 | |||
| 170 | nouveau_gpuobj_ref(NULL, &entry->gpuobj); | ||
| 171 | list_del(&entry->head); | ||
| 172 | kfree(entry); | ||
| 173 | break; | ||
| 174 | } | ||
| 175 | |||
| 176 | co = ho = nouveau_ramht_hash_handle(chan, handle); | 192 | co = ho = nouveau_ramht_hash_handle(chan, handle); |
| 177 | do { | 193 | do { |
| 178 | if (nouveau_ramht_entry_valid(dev, ramht, co) && | 194 | if (nouveau_ramht_entry_valid(dev, ramht, co) && |
| @@ -184,7 +200,7 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle) | |||
| 184 | nv_wo32(ramht, co + 0, 0x00000000); | 200 | nv_wo32(ramht, co + 0, 0x00000000); |
| 185 | nv_wo32(ramht, co + 4, 0x00000000); | 201 | nv_wo32(ramht, co + 4, 0x00000000); |
| 186 | instmem->flush(dev); | 202 | instmem->flush(dev); |
| 187 | return; | 203 | goto out; |
| 188 | } | 204 | } |
| 189 | 205 | ||
| 190 | co += 8; | 206 | co += 8; |
| @@ -194,17 +210,22 @@ nouveau_ramht_remove_locked(struct nouveau_channel *chan, u32 handle) | |||
| 194 | 210 | ||
| 195 | NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", | 211 | NV_ERROR(dev, "RAMHT entry not found. ch=%d, handle=0x%08x\n", |
| 196 | chan->id, handle); | 212 | chan->id, handle); |
| 213 | out: | ||
| 214 | spin_unlock_irqrestore(&chan->ramht->lock, flags); | ||
| 197 | } | 215 | } |
| 198 | 216 | ||
| 199 | void | 217 | void |
| 200 | nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle) | 218 | nouveau_ramht_remove(struct nouveau_channel *chan, u32 handle) |
| 201 | { | 219 | { |
| 202 | struct nouveau_ramht *ramht = chan->ramht; | 220 | struct nouveau_ramht_entry *entry; |
| 203 | unsigned long flags; | ||
| 204 | 221 | ||
| 205 | spin_lock_irqsave(&ramht->lock, flags); | 222 | entry = nouveau_ramht_remove_entry(chan, handle); |
| 206 | nouveau_ramht_remove_locked(chan, handle); | 223 | if (!entry) |
| 207 | spin_unlock_irqrestore(&ramht->lock, flags); | 224 | return; |
| 225 | |||
| 226 | nouveau_ramht_remove_hash(chan, entry->handle); | ||
| 227 | nouveau_gpuobj_ref(NULL, &entry->gpuobj); | ||
| 228 | kfree(entry); | ||
| 208 | } | 229 | } |
| 209 | 230 | ||
| 210 | struct nouveau_gpuobj * | 231 | struct nouveau_gpuobj * |
| @@ -265,23 +286,19 @@ void | |||
| 265 | nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr, | 286 | nouveau_ramht_ref(struct nouveau_ramht *ref, struct nouveau_ramht **ptr, |
| 266 | struct nouveau_channel *chan) | 287 | struct nouveau_channel *chan) |
| 267 | { | 288 | { |
| 268 | struct nouveau_ramht_entry *entry, *tmp; | 289 | struct nouveau_ramht_entry *entry; |
| 269 | struct nouveau_ramht *ramht; | 290 | struct nouveau_ramht *ramht; |
| 270 | unsigned long flags; | ||
| 271 | 291 | ||
| 272 | if (ref) | 292 | if (ref) |
| 273 | kref_get(&ref->refcount); | 293 | kref_get(&ref->refcount); |
| 274 | 294 | ||
| 275 | ramht = *ptr; | 295 | ramht = *ptr; |
| 276 | if (ramht) { | 296 | if (ramht) { |
| 277 | spin_lock_irqsave(&ramht->lock, flags); | 297 | while ((entry = nouveau_ramht_remove_entry(chan, 0))) { |
| 278 | list_for_each_entry_safe(entry, tmp, &ramht->entries, head) { | 298 | nouveau_ramht_remove_hash(chan, entry->handle); |
| 279 | if (entry->channel != chan) | 299 | nouveau_gpuobj_ref(NULL, &entry->gpuobj); |
| 280 | continue; | 300 | kfree(entry); |
| 281 | |||
| 282 | nouveau_ramht_remove_locked(chan, entry->handle); | ||
| 283 | } | 301 | } |
| 284 | spin_unlock_irqrestore(&ramht->lock, flags); | ||
| 285 | 302 | ||
| 286 | kref_put(&ramht->refcount, nouveau_ramht_del); | 303 | kref_put(&ramht->refcount, nouveau_ramht_del); |
| 287 | } | 304 | } |
diff --git a/drivers/gpu/drm/nouveau/nouveau_sgdma.c b/drivers/gpu/drm/nouveau/nouveau_sgdma.c index 288bacac7e5a..d4ac97007038 100644 --- a/drivers/gpu/drm/nouveau/nouveau_sgdma.c +++ b/drivers/gpu/drm/nouveau/nouveau_sgdma.c | |||
| @@ -120,8 +120,8 @@ nouveau_sgdma_bind(struct ttm_backend *be, struct ttm_mem_reg *mem) | |||
| 120 | dev_priv->engine.instmem.flush(nvbe->dev); | 120 | dev_priv->engine.instmem.flush(nvbe->dev); |
| 121 | 121 | ||
| 122 | if (dev_priv->card_type == NV_50) { | 122 | if (dev_priv->card_type == NV_50) { |
| 123 | nv50_vm_flush(dev, 5); /* PGRAPH */ | 123 | dev_priv->engine.fifo.tlb_flush(dev); |
| 124 | nv50_vm_flush(dev, 0); /* PFIFO */ | 124 | dev_priv->engine.graph.tlb_flush(dev); |
| 125 | } | 125 | } |
| 126 | 126 | ||
| 127 | nvbe->bound = true; | 127 | nvbe->bound = true; |
| @@ -162,8 +162,8 @@ nouveau_sgdma_unbind(struct ttm_backend *be) | |||
| 162 | dev_priv->engine.instmem.flush(nvbe->dev); | 162 | dev_priv->engine.instmem.flush(nvbe->dev); |
| 163 | 163 | ||
| 164 | if (dev_priv->card_type == NV_50) { | 164 | if (dev_priv->card_type == NV_50) { |
| 165 | nv50_vm_flush(dev, 5); | 165 | dev_priv->engine.fifo.tlb_flush(dev); |
| 166 | nv50_vm_flush(dev, 0); | 166 | dev_priv->engine.graph.tlb_flush(dev); |
| 167 | } | 167 | } |
| 168 | 168 | ||
| 169 | nvbe->bound = false; | 169 | nvbe->bound = false; |
| @@ -224,7 +224,11 @@ nouveau_sgdma_init(struct drm_device *dev) | |||
| 224 | int i, ret; | 224 | int i, ret; |
| 225 | 225 | ||
| 226 | if (dev_priv->card_type < NV_50) { | 226 | if (dev_priv->card_type < NV_50) { |
| 227 | aper_size = (64 * 1024 * 1024); | 227 | if(dev_priv->ramin_rsvd_vram < 2 * 1024 * 1024) |
| 228 | aper_size = 64 * 1024 * 1024; | ||
| 229 | else | ||
| 230 | aper_size = 512 * 1024 * 1024; | ||
| 231 | |||
| 228 | obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; | 232 | obj_size = (aper_size >> NV_CTXDMA_PAGE_SHIFT) * 4; |
| 229 | obj_size += 8; /* ctxdma header */ | 233 | obj_size += 8; /* ctxdma header */ |
| 230 | } else { | 234 | } else { |
diff --git a/drivers/gpu/drm/nouveau/nouveau_state.c b/drivers/gpu/drm/nouveau/nouveau_state.c index ed7757f14083..049f755567e5 100644 --- a/drivers/gpu/drm/nouveau/nouveau_state.c +++ b/drivers/gpu/drm/nouveau/nouveau_state.c | |||
| @@ -354,6 +354,15 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
| 354 | engine->graph.destroy_context = nv50_graph_destroy_context; | 354 | engine->graph.destroy_context = nv50_graph_destroy_context; |
| 355 | engine->graph.load_context = nv50_graph_load_context; | 355 | engine->graph.load_context = nv50_graph_load_context; |
| 356 | engine->graph.unload_context = nv50_graph_unload_context; | 356 | engine->graph.unload_context = nv50_graph_unload_context; |
| 357 | if (dev_priv->chipset != 0x86) | ||
| 358 | engine->graph.tlb_flush = nv50_graph_tlb_flush; | ||
| 359 | else { | ||
| 360 | /* from what i can see nvidia do this on every | ||
| 361 | * pre-NVA3 board except NVAC, but, we've only | ||
| 362 | * ever seen problems on NV86 | ||
| 363 | */ | ||
| 364 | engine->graph.tlb_flush = nv86_graph_tlb_flush; | ||
| 365 | } | ||
| 357 | engine->fifo.channels = 128; | 366 | engine->fifo.channels = 128; |
| 358 | engine->fifo.init = nv50_fifo_init; | 367 | engine->fifo.init = nv50_fifo_init; |
| 359 | engine->fifo.takedown = nv50_fifo_takedown; | 368 | engine->fifo.takedown = nv50_fifo_takedown; |
| @@ -365,6 +374,7 @@ static int nouveau_init_engine_ptrs(struct drm_device *dev) | |||
| 365 | engine->fifo.destroy_context = nv50_fifo_destroy_context; | 374 | engine->fifo.destroy_context = nv50_fifo_destroy_context; |
| 366 | engine->fifo.load_context = nv50_fifo_load_context; | 375 | engine->fifo.load_context = nv50_fifo_load_context; |
| 367 | engine->fifo.unload_context = nv50_fifo_unload_context; | 376 | engine->fifo.unload_context = nv50_fifo_unload_context; |
| 377 | engine->fifo.tlb_flush = nv50_fifo_tlb_flush; | ||
| 368 | engine->display.early_init = nv50_display_early_init; | 378 | engine->display.early_init = nv50_display_early_init; |
| 369 | engine->display.late_takedown = nv50_display_late_takedown; | 379 | engine->display.late_takedown = nv50_display_late_takedown; |
| 370 | engine->display.create = nv50_display_create; | 380 | engine->display.create = nv50_display_create; |
| @@ -1041,6 +1051,9 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | |||
| 1041 | case NOUVEAU_GETPARAM_PTIMER_TIME: | 1051 | case NOUVEAU_GETPARAM_PTIMER_TIME: |
| 1042 | getparam->value = dev_priv->engine.timer.read(dev); | 1052 | getparam->value = dev_priv->engine.timer.read(dev); |
| 1043 | break; | 1053 | break; |
| 1054 | case NOUVEAU_GETPARAM_HAS_BO_USAGE: | ||
| 1055 | getparam->value = 1; | ||
| 1056 | break; | ||
| 1044 | case NOUVEAU_GETPARAM_GRAPH_UNITS: | 1057 | case NOUVEAU_GETPARAM_GRAPH_UNITS: |
| 1045 | /* NV40 and NV50 versions are quite different, but register | 1058 | /* NV40 and NV50 versions are quite different, but register |
| 1046 | * address is the same. User is supposed to know the card | 1059 | * address is the same. User is supposed to know the card |
| @@ -1051,7 +1064,7 @@ int nouveau_ioctl_getparam(struct drm_device *dev, void *data, | |||
| 1051 | } | 1064 | } |
| 1052 | /* FALLTHRU */ | 1065 | /* FALLTHRU */ |
| 1053 | default: | 1066 | default: |
| 1054 | NV_ERROR(dev, "unknown parameter %lld\n", getparam->param); | 1067 | NV_DEBUG(dev, "unknown parameter %lld\n", getparam->param); |
| 1055 | return -EINVAL; | 1068 | return -EINVAL; |
| 1056 | } | 1069 | } |
| 1057 | 1070 | ||
| @@ -1066,7 +1079,7 @@ nouveau_ioctl_setparam(struct drm_device *dev, void *data, | |||
| 1066 | 1079 | ||
| 1067 | switch (setparam->param) { | 1080 | switch (setparam->param) { |
| 1068 | default: | 1081 | default: |
| 1069 | NV_ERROR(dev, "unknown parameter %lld\n", setparam->param); | 1082 | NV_DEBUG(dev, "unknown parameter %lld\n", setparam->param); |
| 1070 | return -EINVAL; | 1083 | return -EINVAL; |
| 1071 | } | 1084 | } |
| 1072 | 1085 | ||
diff --git a/drivers/gpu/drm/nouveau/nouveau_temp.c b/drivers/gpu/drm/nouveau/nouveau_temp.c index 16bbbf1eff63..7ecc4adc1e45 100644 --- a/drivers/gpu/drm/nouveau/nouveau_temp.c +++ b/drivers/gpu/drm/nouveau/nouveau_temp.c | |||
| @@ -191,7 +191,7 @@ nv40_temp_get(struct drm_device *dev) | |||
| 191 | int offset = sensor->offset_mult / sensor->offset_div; | 191 | int offset = sensor->offset_mult / sensor->offset_div; |
| 192 | int core_temp; | 192 | int core_temp; |
| 193 | 193 | ||
| 194 | if (dev_priv->chipset >= 0x50) { | 194 | if (dev_priv->card_type >= NV_50) { |
| 195 | core_temp = nv_rd32(dev, 0x20008); | 195 | core_temp = nv_rd32(dev, 0x20008); |
| 196 | } else { | 196 | } else { |
| 197 | core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff; | 197 | core_temp = nv_rd32(dev, 0x0015b4) & 0x1fff; |
diff --git a/drivers/gpu/drm/nouveau/nv04_crtc.c b/drivers/gpu/drm/nouveau/nv04_crtc.c index c71abc2a34d5..40e180741629 100644 --- a/drivers/gpu/drm/nouveau/nv04_crtc.c +++ b/drivers/gpu/drm/nouveau/nv04_crtc.c | |||
| @@ -158,7 +158,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 158 | { | 158 | { |
| 159 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); | 159 | struct nouveau_crtc *nv_crtc = nouveau_crtc(crtc); |
| 160 | struct drm_device *dev = crtc->dev; | 160 | struct drm_device *dev = crtc->dev; |
| 161 | struct drm_connector *connector; | ||
| 162 | unsigned char seq1 = 0, crtc17 = 0; | 161 | unsigned char seq1 = 0, crtc17 = 0; |
| 163 | unsigned char crtc1A; | 162 | unsigned char crtc1A; |
| 164 | 163 | ||
| @@ -213,10 +212,6 @@ nv_crtc_dpms(struct drm_crtc *crtc, int mode) | |||
| 213 | NVVgaSeqReset(dev, nv_crtc->index, false); | 212 | NVVgaSeqReset(dev, nv_crtc->index, false); |
| 214 | 213 | ||
| 215 | NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); | 214 | NVWriteVgaCrtc(dev, nv_crtc->index, NV_CIO_CRE_RPC1_INDEX, crtc1A); |
| 216 | |||
| 217 | /* Update connector polling modes */ | ||
| 218 | list_for_each_entry(connector, &dev->mode_config.connector_list, head) | ||
| 219 | nouveau_connector_set_polling(connector); | ||
| 220 | } | 215 | } |
| 221 | 216 | ||
| 222 | static bool | 217 | static bool |
| @@ -831,7 +826,7 @@ nv04_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
| 831 | /* Update the framebuffer location. */ | 826 | /* Update the framebuffer location. */ |
| 832 | regp->fb_start = nv_crtc->fb.offset & ~3; | 827 | regp->fb_start = nv_crtc->fb.offset & ~3; |
| 833 | regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8); | 828 | regp->fb_start += (y * drm_fb->pitch) + (x * drm_fb->bits_per_pixel / 8); |
| 834 | NVWriteCRTC(dev, nv_crtc->index, NV_PCRTC_START, regp->fb_start); | 829 | nv_set_crtc_base(dev, nv_crtc->index, regp->fb_start); |
| 835 | 830 | ||
| 836 | /* Update the arbitration parameters. */ | 831 | /* Update the arbitration parameters. */ |
| 837 | nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel, | 832 | nouveau_calc_arb(dev, crtc->mode.clock, drm_fb->bits_per_pixel, |
diff --git a/drivers/gpu/drm/nouveau/nv04_dfp.c b/drivers/gpu/drm/nouveau/nv04_dfp.c index c936403b26e2..ef23550407b5 100644 --- a/drivers/gpu/drm/nouveau/nv04_dfp.c +++ b/drivers/gpu/drm/nouveau/nv04_dfp.c | |||
| @@ -185,14 +185,15 @@ static bool nv04_dfp_mode_fixup(struct drm_encoder *encoder, | |||
| 185 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 185 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
| 186 | struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); | 186 | struct nouveau_connector *nv_connector = nouveau_encoder_connector_get(nv_encoder); |
| 187 | 187 | ||
| 188 | /* For internal panels and gpu scaling on DVI we need the native mode */ | 188 | if (!nv_connector->native_mode || |
| 189 | if (nv_connector->scaling_mode != DRM_MODE_SCALE_NONE) { | 189 | nv_connector->scaling_mode == DRM_MODE_SCALE_NONE || |
| 190 | if (!nv_connector->native_mode) | 190 | mode->hdisplay > nv_connector->native_mode->hdisplay || |
| 191 | return false; | 191 | mode->vdisplay > nv_connector->native_mode->vdisplay) { |
| 192 | nv_encoder->mode = *adjusted_mode; | ||
| 193 | |||
| 194 | } else { | ||
| 192 | nv_encoder->mode = *nv_connector->native_mode; | 195 | nv_encoder->mode = *nv_connector->native_mode; |
| 193 | adjusted_mode->clock = nv_connector->native_mode->clock; | 196 | adjusted_mode->clock = nv_connector->native_mode->clock; |
| 194 | } else { | ||
| 195 | nv_encoder->mode = *adjusted_mode; | ||
| 196 | } | 197 | } |
| 197 | 198 | ||
| 198 | return true; | 199 | return true; |
diff --git a/drivers/gpu/drm/nouveau/nv04_pm.c b/drivers/gpu/drm/nouveau/nv04_pm.c index 6a6eb697d38e..eb1c70dd82ed 100644 --- a/drivers/gpu/drm/nouveau/nv04_pm.c +++ b/drivers/gpu/drm/nouveau/nv04_pm.c | |||
| @@ -76,6 +76,15 @@ nv04_pm_clock_set(struct drm_device *dev, void *pre_state) | |||
| 76 | reg += 4; | 76 | reg += 4; |
| 77 | 77 | ||
| 78 | nouveau_hw_setpll(dev, reg, &state->calc); | 78 | nouveau_hw_setpll(dev, reg, &state->calc); |
| 79 | |||
| 80 | if (dev_priv->card_type < NV_30 && reg == NV_PRAMDAC_MPLL_COEFF) { | ||
| 81 | if (dev_priv->card_type == NV_20) | ||
| 82 | nv_mask(dev, 0x1002c4, 0, 1 << 20); | ||
| 83 | |||
| 84 | /* Reset the DLLs */ | ||
| 85 | nv_mask(dev, 0x1002c0, 0, 1 << 8); | ||
| 86 | } | ||
| 87 | |||
| 79 | kfree(state); | 88 | kfree(state); |
| 80 | } | 89 | } |
| 81 | 90 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_calc.c b/drivers/gpu/drm/nouveau/nv50_calc.c index 2cdc2bfe7179..de81151648f8 100644 --- a/drivers/gpu/drm/nouveau/nv50_calc.c +++ b/drivers/gpu/drm/nouveau/nv50_calc.c | |||
| @@ -51,24 +51,28 @@ nv50_calc_pll2(struct drm_device *dev, struct pll_lims *pll, int clk, | |||
| 51 | int *N, int *fN, int *M, int *P) | 51 | int *N, int *fN, int *M, int *P) |
| 52 | { | 52 | { |
| 53 | fixed20_12 fb_div, a, b; | 53 | fixed20_12 fb_div, a, b; |
| 54 | u32 refclk = pll->refclk / 10; | ||
| 55 | u32 max_vco_freq = pll->vco1.maxfreq / 10; | ||
| 56 | u32 max_vco_inputfreq = pll->vco1.max_inputfreq / 10; | ||
| 57 | clk /= 10; | ||
| 54 | 58 | ||
| 55 | *P = pll->vco1.maxfreq / clk; | 59 | *P = max_vco_freq / clk; |
| 56 | if (*P > pll->max_p) | 60 | if (*P > pll->max_p) |
| 57 | *P = pll->max_p; | 61 | *P = pll->max_p; |
| 58 | if (*P < pll->min_p) | 62 | if (*P < pll->min_p) |
| 59 | *P = pll->min_p; | 63 | *P = pll->min_p; |
| 60 | 64 | ||
| 61 | /* *M = ceil(refclk / pll->vco.max_inputfreq); */ | 65 | /* *M = floor((refclk + max_vco_inputfreq) / max_vco_inputfreq); */ |
| 62 | a.full = dfixed_const(pll->refclk); | 66 | a.full = dfixed_const(refclk + max_vco_inputfreq); |
| 63 | b.full = dfixed_const(pll->vco1.max_inputfreq); | 67 | b.full = dfixed_const(max_vco_inputfreq); |
| 64 | a.full = dfixed_div(a, b); | 68 | a.full = dfixed_div(a, b); |
| 65 | a.full = dfixed_ceil(a); | 69 | a.full = dfixed_floor(a); |
| 66 | *M = dfixed_trunc(a); | 70 | *M = dfixed_trunc(a); |
| 67 | 71 | ||
| 68 | /* fb_div = (vco * *M) / refclk; */ | 72 | /* fb_div = (vco * *M) / refclk; */ |
| 69 | fb_div.full = dfixed_const(clk * *P); | 73 | fb_div.full = dfixed_const(clk * *P); |
| 70 | fb_div.full = dfixed_mul(fb_div, a); | 74 | fb_div.full = dfixed_mul(fb_div, a); |
| 71 | a.full = dfixed_const(pll->refclk); | 75 | a.full = dfixed_const(refclk); |
| 72 | fb_div.full = dfixed_div(fb_div, a); | 76 | fb_div.full = dfixed_div(fb_div, a); |
| 73 | 77 | ||
| 74 | /* *N = floor(fb_div); */ | 78 | /* *N = floor(fb_div); */ |
diff --git a/drivers/gpu/drm/nouveau/nv50_crtc.c b/drivers/gpu/drm/nouveau/nv50_crtc.c index 16380d52cd88..56476d0c6de8 100644 --- a/drivers/gpu/drm/nouveau/nv50_crtc.c +++ b/drivers/gpu/drm/nouveau/nv50_crtc.c | |||
| @@ -546,7 +546,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
| 546 | } | 546 | } |
| 547 | 547 | ||
| 548 | nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; | 548 | nv_crtc->fb.offset = fb->nvbo->bo.offset - dev_priv->vm_vram_base; |
| 549 | nv_crtc->fb.tile_flags = fb->nvbo->tile_flags; | 549 | nv_crtc->fb.tile_flags = nouveau_bo_tile_layout(fb->nvbo); |
| 550 | nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; | 550 | nv_crtc->fb.cpp = drm_fb->bits_per_pixel / 8; |
| 551 | if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) { | 551 | if (!nv_crtc->fb.blanked && dev_priv->chipset != 0x50) { |
| 552 | ret = RING_SPACE(evo, 2); | 552 | ret = RING_SPACE(evo, 2); |
| @@ -578,7 +578,7 @@ nv50_crtc_do_mode_set_base(struct drm_crtc *crtc, | |||
| 578 | fb->nvbo->tile_mode); | 578 | fb->nvbo->tile_mode); |
| 579 | } | 579 | } |
| 580 | if (dev_priv->chipset == 0x50) | 580 | if (dev_priv->chipset == 0x50) |
| 581 | OUT_RING(evo, (fb->nvbo->tile_flags << 8) | format); | 581 | OUT_RING(evo, (nv_crtc->fb.tile_flags << 8) | format); |
| 582 | else | 582 | else |
| 583 | OUT_RING(evo, format); | 583 | OUT_RING(evo, format); |
| 584 | 584 | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_display.c b/drivers/gpu/drm/nouveau/nv50_display.c index 55c9663ef2bf..f624c611ddea 100644 --- a/drivers/gpu/drm/nouveau/nv50_display.c +++ b/drivers/gpu/drm/nouveau/nv50_display.c | |||
| @@ -1032,11 +1032,18 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) | |||
| 1032 | struct drm_connector *connector; | 1032 | struct drm_connector *connector; |
| 1033 | const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; | 1033 | const uint32_t gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; |
| 1034 | uint32_t unplug_mask, plug_mask, change_mask; | 1034 | uint32_t unplug_mask, plug_mask, change_mask; |
| 1035 | uint32_t hpd0, hpd1 = 0; | 1035 | uint32_t hpd0, hpd1; |
| 1036 | 1036 | ||
| 1037 | hpd0 = nv_rd32(dev, 0xe054) & nv_rd32(dev, 0xe050); | 1037 | spin_lock_irq(&dev_priv->hpd_state.lock); |
| 1038 | hpd0 = dev_priv->hpd_state.hpd0_bits; | ||
| 1039 | dev_priv->hpd_state.hpd0_bits = 0; | ||
| 1040 | hpd1 = dev_priv->hpd_state.hpd1_bits; | ||
| 1041 | dev_priv->hpd_state.hpd1_bits = 0; | ||
| 1042 | spin_unlock_irq(&dev_priv->hpd_state.lock); | ||
| 1043 | |||
| 1044 | hpd0 &= nv_rd32(dev, 0xe050); | ||
| 1038 | if (dev_priv->chipset >= 0x90) | 1045 | if (dev_priv->chipset >= 0x90) |
| 1039 | hpd1 = nv_rd32(dev, 0xe074) & nv_rd32(dev, 0xe070); | 1046 | hpd1 &= nv_rd32(dev, 0xe070); |
| 1040 | 1047 | ||
| 1041 | plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16); | 1048 | plug_mask = (hpd0 & 0x0000ffff) | (hpd1 << 16); |
| 1042 | unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000); | 1049 | unplug_mask = (hpd0 >> 16) | (hpd1 & 0xffff0000); |
| @@ -1078,10 +1085,6 @@ nv50_display_irq_hotplug_bh(struct work_struct *work) | |||
| 1078 | helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF); | 1085 | helper->dpms(connector->encoder, DRM_MODE_DPMS_OFF); |
| 1079 | } | 1086 | } |
| 1080 | 1087 | ||
| 1081 | nv_wr32(dev, 0xe054, nv_rd32(dev, 0xe054)); | ||
| 1082 | if (dev_priv->chipset >= 0x90) | ||
| 1083 | nv_wr32(dev, 0xe074, nv_rd32(dev, 0xe074)); | ||
| 1084 | |||
| 1085 | drm_helper_hpd_irq_event(dev); | 1088 | drm_helper_hpd_irq_event(dev); |
| 1086 | } | 1089 | } |
| 1087 | 1090 | ||
| @@ -1092,8 +1095,22 @@ nv50_display_irq_handler(struct drm_device *dev) | |||
| 1092 | uint32_t delayed = 0; | 1095 | uint32_t delayed = 0; |
| 1093 | 1096 | ||
| 1094 | if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { | 1097 | if (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_HOTPLUG) { |
| 1095 | if (!work_pending(&dev_priv->hpd_work)) | 1098 | uint32_t hpd0_bits, hpd1_bits = 0; |
| 1096 | queue_work(dev_priv->wq, &dev_priv->hpd_work); | 1099 | |
| 1100 | hpd0_bits = nv_rd32(dev, 0xe054); | ||
| 1101 | nv_wr32(dev, 0xe054, hpd0_bits); | ||
| 1102 | |||
| 1103 | if (dev_priv->chipset >= 0x90) { | ||
| 1104 | hpd1_bits = nv_rd32(dev, 0xe074); | ||
| 1105 | nv_wr32(dev, 0xe074, hpd1_bits); | ||
| 1106 | } | ||
| 1107 | |||
| 1108 | spin_lock(&dev_priv->hpd_state.lock); | ||
| 1109 | dev_priv->hpd_state.hpd0_bits |= hpd0_bits; | ||
| 1110 | dev_priv->hpd_state.hpd1_bits |= hpd1_bits; | ||
| 1111 | spin_unlock(&dev_priv->hpd_state.lock); | ||
| 1112 | |||
| 1113 | queue_work(dev_priv->wq, &dev_priv->hpd_work); | ||
| 1097 | } | 1114 | } |
| 1098 | 1115 | ||
| 1099 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { | 1116 | while (nv_rd32(dev, NV50_PMC_INTR_0) & NV50_PMC_INTR_0_DISPLAY) { |
diff --git a/drivers/gpu/drm/nouveau/nv50_fifo.c b/drivers/gpu/drm/nouveau/nv50_fifo.c index a46a961102f3..1da65bd60c10 100644 --- a/drivers/gpu/drm/nouveau/nv50_fifo.c +++ b/drivers/gpu/drm/nouveau/nv50_fifo.c | |||
| @@ -464,3 +464,8 @@ nv50_fifo_unload_context(struct drm_device *dev) | |||
| 464 | return 0; | 464 | return 0; |
| 465 | } | 465 | } |
| 466 | 466 | ||
| 467 | void | ||
| 468 | nv50_fifo_tlb_flush(struct drm_device *dev) | ||
| 469 | { | ||
| 470 | nv50_vm_flush(dev, 5); | ||
| 471 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_graph.c b/drivers/gpu/drm/nouveau/nv50_graph.c index cbf5ae2f67d4..8b669d0af610 100644 --- a/drivers/gpu/drm/nouveau/nv50_graph.c +++ b/drivers/gpu/drm/nouveau/nv50_graph.c | |||
| @@ -402,3 +402,55 @@ struct nouveau_pgraph_object_class nv50_graph_grclass[] = { | |||
| 402 | { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */ | 402 | { 0x8597, false, NULL }, /* tesla (nva3, nva5, nva8) */ |
| 403 | {} | 403 | {} |
| 404 | }; | 404 | }; |
| 405 | |||
| 406 | void | ||
| 407 | nv50_graph_tlb_flush(struct drm_device *dev) | ||
| 408 | { | ||
| 409 | nv50_vm_flush(dev, 0); | ||
| 410 | } | ||
| 411 | |||
| 412 | void | ||
| 413 | nv86_graph_tlb_flush(struct drm_device *dev) | ||
| 414 | { | ||
| 415 | struct drm_nouveau_private *dev_priv = dev->dev_private; | ||
| 416 | struct nouveau_timer_engine *ptimer = &dev_priv->engine.timer; | ||
| 417 | bool idle, timeout = false; | ||
| 418 | unsigned long flags; | ||
| 419 | u64 start; | ||
| 420 | u32 tmp; | ||
| 421 | |||
| 422 | spin_lock_irqsave(&dev_priv->context_switch_lock, flags); | ||
| 423 | nv_mask(dev, 0x400500, 0x00000001, 0x00000000); | ||
| 424 | |||
| 425 | start = ptimer->read(dev); | ||
| 426 | do { | ||
| 427 | idle = true; | ||
| 428 | |||
| 429 | for (tmp = nv_rd32(dev, 0x400380); tmp && idle; tmp >>= 3) { | ||
| 430 | if ((tmp & 7) == 1) | ||
| 431 | idle = false; | ||
| 432 | } | ||
| 433 | |||
| 434 | for (tmp = nv_rd32(dev, 0x400384); tmp && idle; tmp >>= 3) { | ||
| 435 | if ((tmp & 7) == 1) | ||
| 436 | idle = false; | ||
| 437 | } | ||
| 438 | |||
| 439 | for (tmp = nv_rd32(dev, 0x400388); tmp && idle; tmp >>= 3) { | ||
| 440 | if ((tmp & 7) == 1) | ||
| 441 | idle = false; | ||
| 442 | } | ||
| 443 | } while (!idle && !(timeout = ptimer->read(dev) - start > 2000000000)); | ||
| 444 | |||
| 445 | if (timeout) { | ||
| 446 | NV_ERROR(dev, "PGRAPH TLB flush idle timeout fail: " | ||
| 447 | "0x%08x 0x%08x 0x%08x 0x%08x\n", | ||
| 448 | nv_rd32(dev, 0x400700), nv_rd32(dev, 0x400380), | ||
| 449 | nv_rd32(dev, 0x400384), nv_rd32(dev, 0x400388)); | ||
| 450 | } | ||
| 451 | |||
| 452 | nv50_vm_flush(dev, 0); | ||
| 453 | |||
| 454 | nv_mask(dev, 0x400500, 0x00000001, 0x00000001); | ||
| 455 | spin_unlock_irqrestore(&dev_priv->context_switch_lock, flags); | ||
| 456 | } | ||
diff --git a/drivers/gpu/drm/nouveau/nv50_instmem.c b/drivers/gpu/drm/nouveau/nv50_instmem.c index a53fc974332b..b773229b7647 100644 --- a/drivers/gpu/drm/nouveau/nv50_instmem.c +++ b/drivers/gpu/drm/nouveau/nv50_instmem.c | |||
| @@ -402,7 +402,6 @@ nv50_instmem_bind(struct drm_device *dev, struct nouveau_gpuobj *gpuobj) | |||
| 402 | } | 402 | } |
| 403 | dev_priv->engine.instmem.flush(dev); | 403 | dev_priv->engine.instmem.flush(dev); |
| 404 | 404 | ||
| 405 | nv50_vm_flush(dev, 4); | ||
| 406 | nv50_vm_flush(dev, 6); | 405 | nv50_vm_flush(dev, 6); |
| 407 | 406 | ||
| 408 | gpuobj->im_bound = 1; | 407 | gpuobj->im_bound = 1; |
diff --git a/include/drm/nouveau_drm.h b/include/drm/nouveau_drm.h index 01a714119506..bc5590b1a1ac 100644 --- a/include/drm/nouveau_drm.h +++ b/include/drm/nouveau_drm.h | |||
| @@ -80,6 +80,7 @@ struct drm_nouveau_gpuobj_free { | |||
| 80 | #define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 | 80 | #define NOUVEAU_GETPARAM_VM_VRAM_BASE 12 |
| 81 | #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 | 81 | #define NOUVEAU_GETPARAM_GRAPH_UNITS 13 |
| 82 | #define NOUVEAU_GETPARAM_PTIMER_TIME 14 | 82 | #define NOUVEAU_GETPARAM_PTIMER_TIME 14 |
| 83 | #define NOUVEAU_GETPARAM_HAS_BO_USAGE 15 | ||
| 83 | struct drm_nouveau_getparam { | 84 | struct drm_nouveau_getparam { |
| 84 | uint64_t param; | 85 | uint64_t param; |
| 85 | uint64_t value; | 86 | uint64_t value; |
| @@ -95,6 +96,12 @@ struct drm_nouveau_setparam { | |||
| 95 | #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) | 96 | #define NOUVEAU_GEM_DOMAIN_GART (1 << 2) |
| 96 | #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) | 97 | #define NOUVEAU_GEM_DOMAIN_MAPPABLE (1 << 3) |
| 97 | 98 | ||
| 99 | #define NOUVEAU_GEM_TILE_LAYOUT_MASK 0x0000ff00 | ||
| 100 | #define NOUVEAU_GEM_TILE_16BPP 0x00000001 | ||
| 101 | #define NOUVEAU_GEM_TILE_32BPP 0x00000002 | ||
| 102 | #define NOUVEAU_GEM_TILE_ZETA 0x00000004 | ||
| 103 | #define NOUVEAU_GEM_TILE_NONCONTIG 0x00000008 | ||
| 104 | |||
| 98 | struct drm_nouveau_gem_info { | 105 | struct drm_nouveau_gem_info { |
| 99 | uint32_t handle; | 106 | uint32_t handle; |
| 100 | uint32_t domain; | 107 | uint32_t domain; |
