Pull drm fixes from Dave Airlie: "Regression fixers for the big 3: - nouveau: hdmi audio, dac load detect, s/r regressions fixed - radeon: long standing system hang fixed, hdmi audio and rs780 fast fb fixes - intel: one old regression, a WARN removal, and a stop X dying fix Otherwise one mgag200 fix, a couple of arm build fixes, and a core use after free fix." * 'drm-fixes' of git://people.freedesktop.org/~airlied/linux: drm/nv50/kms: use dac loadval from vbios, where it's available drm/nv50/disp: force dac power state during load detect drm/nv50-nv84/fifo: fix resume regression introduced by playlist race fix drm/nv84/disp: Fix HDMI audio regression drm/i915/sdvo: Use &intel_sdvo->ddc instead of intel_sdvo->i2c for DDC. drm/radeon: don't allow audio on DCE6 drm/radeon: Use direct mapping for fast fb access on RS780/RS880 (v2) radeon: Fix system hang issue when using KMS with older cards drm/i915: no lvds quirk for hp t5740 drm/i915: Quirk the pipe A quirk in the modeset state checker drm/i915: Fix spurious -EIO/SIGBUS on wedged gpus drm/mgag200: Add missing write to index before accessing data register drm/nouveau: use mdelay instead of large udelay constants drm/tilcd: select BACKLIGHT_LCD_SUPPORT drm: fix a use-after-free when GPU acceleration disabled
Unified · Split
| @@ -1054,7 +1054,7 @@ EXPORT_SYMBOL(drm_vblank_off); · 1053 unmodified lines | ||
| 1054 | 1054 | */ |
| 1055 | 1055 | void drm_vblank_pre_modeset(struct drm_device *dev, int crtc) |
| 1056 | 1056 | { |
| 1057 | − /* vblank is not initialized (IRQ not installed ?) */ | |
| 1057 | + /* vblank is not initialized (IRQ not installed ?), or has been freed */ | |
| 1058 | 1058 | if (!dev->num_crtcs) |
| 1059 | 1059 | return; |
| 1060 | 1060 | /* |
| @@ -1076,6 +1076,10 @@ void drm_vblank_post_modeset(struct drm_device *dev, int crtc) · 15 unmodified lines | ||
| 1076 | 1076 | { |
| 1077 | 1077 | unsigned long irqflags; |
| 1078 | 1078 | |
| 1079 | + /* vblank is not initialized (IRQ not installed ?), or has been freed */ | |
| 1080 | + if (!dev->num_crtcs) | |
| 1081 | + return; | |
| 1082 | + | |
| 1079 | 1083 | if (dev->vblank_inmodeset[crtc]) { |
| 1080 | 1084 | spin_lock_irqsave(&dev->vbl_lock, irqflags); |
| 1081 | 1085 | dev->vblank_disable_allowed = 1; |
| @@ -91,14 +91,11 @@ i915_gem_wait_for_error(struct i915_gpu_error *error) · 90 unmodified lines | ||
| 91 | 91 | { |
| 92 | 92 | int ret; |
| 93 | 93 | |
| 94 | −#define EXIT_COND (!i915_reset_in_progress(error)) | |
| 94 | +#define EXIT_COND (!i915_reset_in_progress(error) || \ | |
| 95 | + i915_terminally_wedged(error)) | |
| 95 | 96 | if (EXIT_COND) |
| 96 | 97 | return 0; |
| 97 | 98 | |
| 98 | − /* GPU is already declared terminally dead, give up. */ | |
| 99 | − if (i915_terminally_wedged(error)) | |
| 100 | − return -EIO; | |
| 101 | − | |
| 102 | 99 | /* |
| 103 | 100 | * Only wait 10 seconds for the gpu reset to complete to avoid hanging |
| 104 | 101 | * userspace. If it takes that long something really bad is going on and |
| @@ -7937,6 +7937,11 @@ intel_modeset_check_state(struct drm_device *dev) · 7936 unmodified lines | ||
| 7937 | 7937 | memset(&pipe_config, 0, sizeof(pipe_config)); |
| 7938 | 7938 | active = dev_priv->display.get_pipe_config(crtc, |
| 7939 | 7939 | &pipe_config); |
| 7940 | + | |
| 7941 | + /* hw state is inconsistent with the pipe A quirk */ | |
| 7942 | + if (crtc->pipe == PIPE_A && dev_priv->quirks & QUIRK_PIPEA_FORCE) | |
| 7943 | + active = crtc->active; | |
| 7944 | + | |
| 7940 | 7945 | WARN(crtc->active != active, |
| 7941 | 7946 | "crtc active state doesn't match with hw state " |
| 7942 | 7947 | "(expected %i, found %i)\n", crtc->active, active); |
| @@ -815,10 +815,10 @@ static const struct dmi_system_id intel_no_lvds[] = { · 814 unmodified lines | ||
| 815 | 815 | }, |
| 816 | 816 | { |
| 817 | 817 | .callback = intel_no_lvds_dmi_callback, |
| 818 | − .ident = "Hewlett-Packard HP t5740e Thin Client", | |
| 818 | + .ident = "Hewlett-Packard HP t5740", | |
| 819 | 819 | .matches = { |
| 820 | 820 | DMI_MATCH(DMI_BOARD_VENDOR, "Hewlett-Packard"), |
| 821 | − DMI_MATCH(DMI_PRODUCT_NAME, "HP t5740e Thin Client"), | |
| 821 | + DMI_MATCH(DMI_PRODUCT_NAME, " t5740"), | |
| 822 | 822 | }, |
| 823 | 823 | }, |
| 824 | 824 | { |
| @@ -1776,7 +1776,7 @@ static void intel_sdvo_get_lvds_modes(struct drm_connector *connector) · 1775 unmodified lines | ||
| 1776 | 1776 | * Assume that the preferred modes are |
| 1777 | 1777 | * arranged in priority order. |
| 1778 | 1778 | */ |
| 1779 | − intel_ddc_get_modes(connector, intel_sdvo->i2c); | |
| 1779 | + intel_ddc_get_modes(connector, &intel_sdvo->ddc); | |
| 1780 | 1780 | if (list_empty(&connector->probed_modes) == false) |
| 1781 | 1781 | goto end; |
| 1782 | 1782 | |
| @@ -1034,13 +1034,14 @@ static int mga_crtc_mode_set(struct drm_crtc *crtc, · 1033 unmodified lines | ||
| 1034 | 1034 | else |
| 1035 | 1035 | hi_pri_lvl = 5; |
| 1036 | 1036 | |
| 1037 | − WREG8(0x1fde, 0x06); | |
| 1038 | − WREG8(0x1fdf, hi_pri_lvl); | |
| 1037 | + WREG8(MGAREG_CRTCEXT_INDEX, 0x06); | |
| 1038 | + WREG8(MGAREG_CRTCEXT_DATA, hi_pri_lvl); | |
| 1039 | 1039 | } else { |
| 1040 | + WREG8(MGAREG_CRTCEXT_INDEX, 0x06); | |
| 1040 | 1041 | if (mdev->reg_1e24 >= 0x01) |
| 1041 | − WREG8(0x1fdf, 0x03); | |
| 1042 | + WREG8(MGAREG_CRTCEXT_DATA, 0x03); | |
| 1042 | 1043 | else |
| 1043 | − WREG8(0x1fdf, 0x04); | |
| 1044 | + WREG8(MGAREG_CRTCEXT_DATA, 0x04); | |
| 1044 | 1045 | } |
| 1045 | 1046 | } |
| 1046 | 1047 | return 0; |
| @@ -50,11 +50,16 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) · 49 unmodified lines | ||
| 50 | 50 | { |
| 51 | 51 | const u32 doff = (or * 0x800); |
| 52 | 52 | int load = -EINVAL; |
| 53 | + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); | |
| 54 | + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); | |
| 53 | 55 | nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); |
| 54 | − udelay(9500); | |
| 56 | + mdelay(9); | |
| 57 | + udelay(500); | |
| 55 | 58 | nv_wr32(priv, 0x61a00c + doff, 0x80000000); |
| 56 | 59 | load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; |
| 57 | 60 | nv_wr32(priv, 0x61a00c + doff, 0x00000000); |
| 61 | + nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); | |
| 62 | + nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); | |
| 58 | 63 | return load; |
| 59 | 64 | } |
| 60 | 65 | |
| @@ -55,6 +55,10 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) · 54 unmodified lines | ||
| 55 | 55 | nv_wr32(priv, 0x616510 + hoff, 0x00000000); |
| 56 | 56 | nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000001); |
| 57 | 57 | |
| 58 | + nv_mask(priv, 0x6165d0 + hoff, 0x00070001, 0x00010001); /* SPARE, HW_CTS */ | |
| 59 | + nv_mask(priv, 0x616568 + hoff, 0x00010101, 0x00000000); /* ACR_CTRL, ?? */ | |
| 60 | + nv_mask(priv, 0x616578 + hoff, 0x80000000, 0x80000000); /* ACR_0441_ENABLE */ | |
| 61 | + | |
| 58 | 62 | /* ??? */ |
| 59 | 63 | nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */ |
| 60 | 64 | nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */ |
| @@ -40,14 +40,13 @@ · 39 unmodified lines | ||
| 40 | 40 | * FIFO channel objects |
| 41 | 41 | ******************************************************************************/ |
| 42 | 42 | |
| 43 | −void | |
| 44 | −nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) | |
| 43 | +static void | |
| 44 | +nv50_fifo_playlist_update_locked(struct nv50_fifo_priv *priv) | |
| 45 | 45 | { |
| 46 | 46 | struct nouveau_bar *bar = nouveau_bar(priv); |
| 47 | 47 | struct nouveau_gpuobj *cur; |
| 48 | 48 | int i, p; |
| 49 | 49 | |
| 50 | − mutex_lock(&nv_subdev(priv)->mutex); | |
| 51 | 50 | cur = priv->playlist[priv->cur_playlist]; |
| 52 | 51 | priv->cur_playlist = !priv->cur_playlist; |
| 53 | 52 | |
| @@ -61,6 +60,13 @@ nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) · 7 unmodified lines | ||
| 61 | 60 | nv_wr32(priv, 0x0032f4, cur->addr >> 12); |
| 62 | 61 | nv_wr32(priv, 0x0032ec, p); |
| 63 | 62 | nv_wr32(priv, 0x002500, 0x00000101); |
| 63 | +} | |
| 64 | + | |
| 65 | +void | |
| 66 | +nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) | |
| 67 | +{ | |
| 68 | + mutex_lock(&nv_subdev(priv)->mutex); | |
| 69 | + nv50_fifo_playlist_update_locked(priv); | |
| 64 | 70 | mutex_unlock(&nv_subdev(priv)->mutex); |
| 65 | 71 | } |
| 66 | 72 | |
| @@ -489,7 +495,7 @@ nv50_fifo_init(struct nouveau_object *object) · 422 unmodified lines | ||
| 489 | 495 | |
| 490 | 496 | for (i = 0; i < 128; i++) |
| 491 | 497 | nv_wr32(priv, 0x002600 + (i * 4), 0x00000000); |
| 492 | − nv50_fifo_playlist_update(priv); | |
| 498 | + nv50_fifo_playlist_update_locked(priv); | |
| 493 | 499 | |
| 494 | 500 | nv_wr32(priv, 0x003200, 0x00000001); |
| 495 | 501 | nv_wr32(priv, 0x003250, 0x00000001); |
| @@ -218,7 +218,7 @@ struct nv04_display_class { · 217 unmodified lines | ||
| 218 | 218 | #define NV50_DISP_DAC_PWR_STATE 0x00000040 |
| 219 | 219 | #define NV50_DISP_DAC_PWR_STATE_ON 0x00000000 |
| 220 | 220 | #define NV50_DISP_DAC_PWR_STATE_OFF 0x00000040 |
| 221 | −#define NV50_DISP_DAC_LOAD 0x0002000c | |
| 221 | +#define NV50_DISP_DAC_LOAD 0x00020100 | |
| 222 | 222 | #define NV50_DISP_DAC_LOAD_VALUE 0x00000007 |
| 223 | 223 | |
| 224 | 224 | #define NV50_DISP_PIOR_MTHD 0x00030000 |
| @@ -1554,7 +1554,9 @@ nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) · 1553 unmodified lines | ||
| 1554 | 1554 | { |
| 1555 | 1555 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
| 1556 | 1556 | int ret, or = nouveau_encoder(encoder)->or; |
| 1557 | − u32 load = 0; | |
| 1557 | + u32 load = nouveau_drm(encoder->dev)->vbios.dactestval; | |
| 1558 | + if (load == 0) | |
| 1559 | + load = 340; | |
| 1558 | 1560 | |
| 1559 | 1561 | ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); |
| 1560 | 1562 | if (ret || load != 7) |
| @@ -667,6 +667,8 @@ atombios_digital_setup(struct drm_encoder *encoder, int action) · 666 unmodified lines | ||
| 667 | 667 | int |
| 668 | 668 | atombios_get_encoder_mode(struct drm_encoder *encoder) |
| 669 | 669 | { |
| 670 | + struct drm_device *dev = encoder->dev; | |
| 671 | + struct radeon_device *rdev = dev->dev_private; | |
| 670 | 672 | struct radeon_encoder *radeon_encoder = to_radeon_encoder(encoder); |
| 671 | 673 | struct drm_connector *connector; |
| 672 | 674 | struct radeon_connector *radeon_connector; |
| @@ -693,7 +695,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) · 20 unmodified lines | ||
| 693 | 695 | case DRM_MODE_CONNECTOR_DVII: |
| 694 | 696 | case DRM_MODE_CONNECTOR_HDMIB: /* HDMI-B is basically DL-DVI; analog works fine */ |
| 695 | 697 | if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
| 696 | − radeon_audio) | |
| 698 | + radeon_audio && | |
| 699 | + !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ | |
| 697 | 700 | return ATOM_ENCODER_MODE_HDMI; |
| 698 | 701 | else if (radeon_connector->use_digital) |
| 699 | 702 | return ATOM_ENCODER_MODE_DVI; |
| @@ -704,7 +707,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) · 4 unmodified lines | ||
| 704 | 707 | case DRM_MODE_CONNECTOR_HDMIA: |
| 705 | 708 | default: |
| 706 | 709 | if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
| 707 | − radeon_audio) | |
| 710 | + radeon_audio && | |
| 711 | + !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ | |
| 708 | 712 | return ATOM_ENCODER_MODE_HDMI; |
| 709 | 713 | else |
| 710 | 714 | return ATOM_ENCODER_MODE_DVI; |
| @@ -718,7 +722,8 @@ atombios_get_encoder_mode(struct drm_encoder *encoder) · 7 unmodified lines | ||
| 718 | 722 | (dig_connector->dp_sink_type == CONNECTOR_OBJECT_ID_eDP)) |
| 719 | 723 | return ATOM_ENCODER_MODE_DP; |
| 720 | 724 | else if (drm_detect_hdmi_monitor(radeon_connector->edid) && |
| 721 | − radeon_audio) | |
| 725 | + radeon_audio && | |
| 726 | + !ASIC_IS_DCE6(rdev)) /* remove once we support DCE6 */ | |
| 722 | 727 | return ATOM_ENCODER_MODE_HDMI; |
| 723 | 728 | else |
| 724 | 729 | return ATOM_ENCODER_MODE_DVI; |
| @@ -4754,6 +4754,12 @@ static int evergreen_startup(struct radeon_device *rdev) · 4753 unmodified lines | ||
| 4754 | 4754 | rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; |
| 4755 | 4755 | |
| 4756 | 4756 | /* Enable IRQ */ |
| 4757 | + if (!rdev->irq.installed) { | |
| 4758 | + r = radeon_irq_kms_init(rdev); | |
| 4759 | + if (r) | |
| 4760 | + return r; | |
| 4761 | + } | |
| 4762 | + | |
| 4757 | 4763 | r = r600_irq_init(rdev); |
| 4758 | 4764 | if (r) { |
| 4759 | 4765 | DRM_ERROR("radeon: IH init failed (%d).\n", r); |
| @@ -4923,10 +4929,6 @@ int evergreen_init(struct radeon_device *rdev) · 163 unmodified lines | ||
| 4923 | 4929 | if (r) |
| 4924 | 4930 | return r; |
| 4925 | 4931 | |
| 4926 | − r = radeon_irq_kms_init(rdev); | |
| 4927 | − if (r) | |
| 4928 | − return r; | |
| 4929 | − | |
| 4930 | 4932 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; |
| 4931 | 4933 | r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); |
| 4932 | 4934 | |
| @@ -2025,6 +2025,12 @@ static int cayman_startup(struct radeon_device *rdev) · 2024 unmodified lines | ||
| 2025 | 2025 | } |
| 2026 | 2026 | |
| 2027 | 2027 | /* Enable IRQ */ |
| 2028 | + if (!rdev->irq.installed) { | |
| 2029 | + r = radeon_irq_kms_init(rdev); | |
| 2030 | + if (r) | |
| 2031 | + return r; | |
| 2032 | + } | |
| 2033 | + | |
| 2028 | 2034 | r = r600_irq_init(rdev); |
| 2029 | 2035 | if (r) { |
| 2030 | 2036 | DRM_ERROR("radeon: IH init failed (%d).\n", r); |
| @@ -2190,10 +2196,6 @@ int cayman_init(struct radeon_device *rdev) · 159 unmodified lines | ||
| 2190 | 2196 | if (r) |
| 2191 | 2197 | return r; |
| 2192 | 2198 | |
| 2193 | − r = radeon_irq_kms_init(rdev); | |
| 2194 | − if (r) | |
| 2195 | − return r; | |
| 2196 | − | |
| 2197 | 2199 | ring->ring_obj = NULL; |
| 2198 | 2200 | r600_ring_init(rdev, ring, 1024 * 1024); |
| 2199 | 2201 | |
| @@ -3869,6 +3869,12 @@ static int r100_startup(struct radeon_device *rdev) · 3868 unmodified lines | ||
| 3869 | 3869 | } |
| 3870 | 3870 | |
| 3871 | 3871 | /* Enable IRQ */ |
| 3872 | + if (!rdev->irq.installed) { | |
| 3873 | + r = radeon_irq_kms_init(rdev); | |
| 3874 | + if (r) | |
| 3875 | + return r; | |
| 3876 | + } | |
| 3877 | + | |
| 3872 | 3878 | r100_irq_set(rdev); |
| 3873 | 3879 | rdev->config.r100.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 3874 | 3880 | /* 1M ring buffer */ |
| @@ -4022,9 +4028,6 @@ int r100_init(struct radeon_device *rdev) · 147 unmodified lines | ||
| 4022 | 4028 | r100_mc_init(rdev); |
| 4023 | 4029 | /* Fence driver */ |
| 4024 | 4030 | r = radeon_fence_driver_init(rdev); |
| 4025 | − if (r) | |
| 4026 | − return r; | |
| 4027 | − r = radeon_irq_kms_init(rdev); | |
| 4028 | 4031 | if (r) |
| 4029 | 4032 | return r; |
| 4030 | 4033 | /* Memory manager */ |
| @@ -1382,6 +1382,12 @@ static int r300_startup(struct radeon_device *rdev) · 1381 unmodified lines | ||
| 1382 | 1382 | } |
| 1383 | 1383 | |
| 1384 | 1384 | /* Enable IRQ */ |
| 1385 | + if (!rdev->irq.installed) { | |
| 1386 | + r = radeon_irq_kms_init(rdev); | |
| 1387 | + if (r) | |
| 1388 | + return r; | |
| 1389 | + } | |
| 1390 | + | |
| 1385 | 1391 | r100_irq_set(rdev); |
| 1386 | 1392 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 1387 | 1393 | /* 1M ring buffer */ |
| @@ -1514,9 +1520,6 @@ int r300_init(struct radeon_device *rdev) · 126 unmodified lines | ||
| 1514 | 1520 | r300_mc_init(rdev); |
| 1515 | 1521 | /* Fence driver */ |
| 1516 | 1522 | r = radeon_fence_driver_init(rdev); |
| 1517 | − if (r) | |
| 1518 | − return r; | |
| 1519 | − r = radeon_irq_kms_init(rdev); | |
| 1520 | 1523 | if (r) |
| 1521 | 1524 | return r; |
| 1522 | 1525 | /* Memory manager */ |
| @@ -265,6 +265,12 @@ static int r420_startup(struct radeon_device *rdev) · 264 unmodified lines | ||
| 265 | 265 | } |
| 266 | 266 | |
| 267 | 267 | /* Enable IRQ */ |
| 268 | + if (!rdev->irq.installed) { | |
| 269 | + r = radeon_irq_kms_init(rdev); | |
| 270 | + if (r) | |
| 271 | + return r; | |
| 272 | + } | |
| 273 | + | |
| 268 | 274 | r100_irq_set(rdev); |
| 269 | 275 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 270 | 276 | /* 1M ring buffer */ |
| @@ -411,10 +417,6 @@ int r420_init(struct radeon_device *rdev) · 140 unmodified lines | ||
| 411 | 417 | if (r) { |
| 412 | 418 | return r; |
| 413 | 419 | } |
| 414 | − r = radeon_irq_kms_init(rdev); | |
| 415 | − if (r) { | |
| 416 | − return r; | |
| 417 | − } | |
| 418 | 420 | /* Memory manager */ |
| 419 | 421 | r = radeon_bo_init(rdev); |
| 420 | 422 | if (r) { |
| @@ -194,6 +194,12 @@ static int r520_startup(struct radeon_device *rdev) · 193 unmodified lines | ||
| 194 | 194 | } |
| 195 | 195 | |
| 196 | 196 | /* Enable IRQ */ |
| 197 | + if (!rdev->irq.installed) { | |
| 198 | + r = radeon_irq_kms_init(rdev); | |
| 199 | + if (r) | |
| 200 | + return r; | |
| 201 | + } | |
| 202 | + | |
| 197 | 203 | rs600_irq_set(rdev); |
| 198 | 204 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 199 | 205 | /* 1M ring buffer */ |
| @@ -295,9 +301,6 @@ int r520_init(struct radeon_device *rdev) · 95 unmodified lines | ||
| 295 | 301 | rv515_debugfs(rdev); |
| 296 | 302 | /* Fence driver */ |
| 297 | 303 | r = radeon_fence_driver_init(rdev); |
| 298 | − if (r) | |
| 299 | − return r; | |
| 300 | − r = radeon_irq_kms_init(rdev); | |
| 301 | 304 | if (r) |
| 302 | 305 | return r; |
| 303 | 306 | /* Memory manager */ |
| @@ -1046,6 +1046,24 @@ int r600_mc_wait_for_idle(struct radeon_device *rdev) · 1045 unmodified lines | ||
| 1046 | 1046 | return -1; |
| 1047 | 1047 | } |
| 1048 | 1048 | |
| 1049 | +uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg) | |
| 1050 | +{ | |
| 1051 | + uint32_t r; | |
| 1052 | + | |
| 1053 | + WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg)); | |
| 1054 | + r = RREG32(R_0028FC_MC_DATA); | |
| 1055 | + WREG32(R_0028F8_MC_INDEX, ~C_0028F8_MC_IND_ADDR); | |
| 1056 | + return r; | |
| 1057 | +} | |
| 1058 | + | |
| 1059 | +void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v) | |
| 1060 | +{ | |
| 1061 | + WREG32(R_0028F8_MC_INDEX, S_0028F8_MC_IND_ADDR(reg) | | |
| 1062 | + S_0028F8_MC_IND_WR_EN(1)); | |
| 1063 | + WREG32(R_0028FC_MC_DATA, v); | |
| 1064 | + WREG32(R_0028F8_MC_INDEX, 0x7F); | |
| 1065 | +} | |
| 1066 | + | |
| 1049 | 1067 | static void r600_mc_program(struct radeon_device *rdev) |
| 1050 | 1068 | { |
| 1051 | 1069 | struct rv515_mc_save save; |
| @@ -1181,6 +1199,8 @@ static int r600_mc_init(struct radeon_device *rdev) · 129 unmodified lines | ||
| 1181 | 1199 | { |
| 1182 | 1200 | u32 tmp; |
| 1183 | 1201 | int chansize, numchan; |
| 1202 | + uint32_t h_addr, l_addr; | |
| 1203 | + unsigned long long k8_addr; | |
| 1184 | 1204 | |
| 1185 | 1205 | /* Get VRAM informations */ |
| 1186 | 1206 | rdev->mc.vram_is_ddr = true; |
| @@ -1221,7 +1241,30 @@ static int r600_mc_init(struct radeon_device *rdev) · 34 unmodified lines | ||
| 1221 | 1241 | if (rdev->flags & RADEON_IS_IGP) { |
| 1222 | 1242 | rs690_pm_info(rdev); |
| 1223 | 1243 | rdev->mc.igp_sideport_enabled = radeon_atombios_sideport_present(rdev); |
| 1244 | + | |
| 1245 | + if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { | |
| 1246 | + /* Use K8 direct mapping for fast fb access. */ | |
| 1247 | + rdev->fastfb_working = false; | |
| 1248 | + h_addr = G_000012_K8_ADDR_EXT(RREG32_MC(R_000012_MC_MISC_UMA_CNTL)); | |
| 1249 | + l_addr = RREG32_MC(R_000011_K8_FB_LOCATION); | |
| 1250 | + k8_addr = ((unsigned long long)h_addr) << 32 | l_addr; | |
| 1251 | +#if defined(CONFIG_X86_32) && !defined(CONFIG_X86_PAE) | |
| 1252 | + if (k8_addr + rdev->mc.visible_vram_size < 0x100000000ULL) | |
| 1253 | +#endif | |
| 1254 | + { | |
| 1255 | + /* FastFB shall be used with UMA memory. Here it is simply disabled when sideport | |
| 1256 | + * memory is present. | |
| 1257 | + */ | |
| 1258 | + if (rdev->mc.igp_sideport_enabled == false && radeon_fastfb == 1) { | |
| 1259 | + DRM_INFO("Direct mapping: aper base at 0x%llx, replaced by direct mapping base 0x%llx.\n", | |
| 1260 | + (unsigned long long)rdev->mc.aper_base, k8_addr); | |
| 1261 | + rdev->mc.aper_base = (resource_size_t)k8_addr; | |
| 1262 | + rdev->fastfb_working = true; | |
| 1263 | + } | |
| 1264 | + } | |
| 1265 | + } | |
| 1224 | 1266 | } |
| 1267 | + | |
| 1225 | 1268 | radeon_update_bandwidth_info(rdev); |
| 1226 | 1269 | return 0; |
| 1227 | 1270 | } |
| @@ -3202,6 +3245,12 @@ static int r600_startup(struct radeon_device *rdev) · 1974 unmodified lines | ||
| 3202 | 3245 | } |
| 3203 | 3246 | |
| 3204 | 3247 | /* Enable IRQ */ |
| 3248 | + if (!rdev->irq.installed) { | |
| 3249 | + r = radeon_irq_kms_init(rdev); | |
| 3250 | + if (r) | |
| 3251 | + return r; | |
| 3252 | + } | |
| 3253 | + | |
| 3205 | 3254 | r = r600_irq_init(rdev); |
| 3206 | 3255 | if (r) { |
| 3207 | 3256 | DRM_ERROR("radeon: IH init failed (%d).\n", r); |
| @@ -3356,10 +3405,6 @@ int r600_init(struct radeon_device *rdev) · 148 unmodified lines | ||
| 3356 | 3405 | if (r) |
| 3357 | 3406 | return r; |
| 3358 | 3407 | |
| 3359 | − r = radeon_irq_kms_init(rdev); | |
| 3360 | − if (r) | |
| 3361 | − return r; | |
| 3362 | − | |
| 3363 | 3408 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; |
| 3364 | 3409 | r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); |
| 3365 | 3410 | |
| @@ -1342,6 +1342,14 @@ · 1341 unmodified lines | ||
| 1342 | 1342 | #define PACKET3_STRMOUT_BASE_UPDATE 0x72 /* r7xx */ |
| 1343 | 1343 | #define PACKET3_SURFACE_BASE_UPDATE 0x73 |
| 1344 | 1344 | |
| 1345 | +#define R_000011_K8_FB_LOCATION 0x11 | |
| 1346 | +#define R_000012_MC_MISC_UMA_CNTL 0x12 | |
| 1347 | +#define G_000012_K8_ADDR_EXT(x) (((x) >> 0) & 0xFF) | |
| 1348 | +#define R_0028F8_MC_INDEX 0x28F8 | |
| 1349 | +#define S_0028F8_MC_IND_ADDR(x) (((x) & 0x1FF) << 0) | |
| 1350 | +#define C_0028F8_MC_IND_ADDR 0xFFFFFE00 | |
| 1351 | +#define S_0028F8_MC_IND_WR_EN(x) (((x) & 0x1) << 9) | |
| 1352 | +#define R_0028FC_MC_DATA 0x28FC | |
| 1345 | 1353 | |
| 1346 | 1354 | #define R_008020_GRBM_SOFT_RESET 0x8020 |
| 1347 | 1355 | #define S_008020_SOFT_RESET_CP(x) (((x) & 1) << 0) |
| @@ -122,6 +122,10 @@ static void radeon_register_accessor_init(struct radeon_device *rdev) · 121 unmodified lines | ||
| 122 | 122 | rdev->mc_rreg = &rs600_mc_rreg; |
| 123 | 123 | rdev->mc_wreg = &rs600_mc_wreg; |
| 124 | 124 | } |
| 125 | + if (rdev->family == CHIP_RS780 || rdev->family == CHIP_RS880) { | |
| 126 | + rdev->mc_rreg = &rs780_mc_rreg; | |
| 127 | + rdev->mc_wreg = &rs780_mc_wreg; | |
| 128 | + } | |
| 125 | 129 | if (rdev->family >= CHIP_R600) { |
| 126 | 130 | rdev->pciep_rreg = &r600_pciep_rreg; |
| 127 | 131 | rdev->pciep_wreg = &r600_pciep_wreg; |
| @@ -347,6 +347,8 @@ extern bool r600_gui_idle(struct radeon_device *rdev); · 346 unmodified lines | ||
| 347 | 347 | extern void r600_pm_misc(struct radeon_device *rdev); |
| 348 | 348 | extern void r600_pm_init_profile(struct radeon_device *rdev); |
| 349 | 349 | extern void rs780_pm_init_profile(struct radeon_device *rdev); |
| 350 | +extern uint32_t rs780_mc_rreg(struct radeon_device *rdev, uint32_t reg); | |
| 351 | +extern void rs780_mc_wreg(struct radeon_device *rdev, uint32_t reg, uint32_t v); | |
| 350 | 352 | extern void r600_pm_get_dynpm_state(struct radeon_device *rdev); |
| 351 | 353 | extern void r600_set_pcie_lanes(struct radeon_device *rdev, int lanes); |
| 352 | 354 | extern int r600_get_pcie_lanes(struct radeon_device *rdev); |
| @@ -417,6 +417,12 @@ static int rs400_startup(struct radeon_device *rdev) · 416 unmodified lines | ||
| 417 | 417 | } |
| 418 | 418 | |
| 419 | 419 | /* Enable IRQ */ |
| 420 | + if (!rdev->irq.installed) { | |
| 421 | + r = radeon_irq_kms_init(rdev); | |
| 422 | + if (r) | |
| 423 | + return r; | |
| 424 | + } | |
| 425 | + | |
| 420 | 426 | r100_irq_set(rdev); |
| 421 | 427 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 422 | 428 | /* 1M ring buffer */ |
| @@ -533,9 +539,6 @@ int rs400_init(struct radeon_device *rdev) · 110 unmodified lines | ||
| 533 | 539 | rs400_mc_init(rdev); |
| 534 | 540 | /* Fence driver */ |
| 535 | 541 | r = radeon_fence_driver_init(rdev); |
| 536 | − if (r) | |
| 537 | − return r; | |
| 538 | − r = radeon_irq_kms_init(rdev); | |
| 539 | 542 | if (r) |
| 540 | 543 | return r; |
| 541 | 544 | /* Memory manager */ |
| @@ -923,6 +923,12 @@ static int rs600_startup(struct radeon_device *rdev) · 922 unmodified lines | ||
| 923 | 923 | } |
| 924 | 924 | |
| 925 | 925 | /* Enable IRQ */ |
| 926 | + if (!rdev->irq.installed) { | |
| 927 | + r = radeon_irq_kms_init(rdev); | |
| 928 | + if (r) | |
| 929 | + return r; | |
| 930 | + } | |
| 931 | + | |
| 926 | 932 | rs600_irq_set(rdev); |
| 927 | 933 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 928 | 934 | /* 1M ring buffer */ |
| @@ -1045,9 +1051,6 @@ int rs600_init(struct radeon_device *rdev) · 116 unmodified lines | ||
| 1045 | 1051 | rs600_debugfs(rdev); |
| 1046 | 1052 | /* Fence driver */ |
| 1047 | 1053 | r = radeon_fence_driver_init(rdev); |
| 1048 | − if (r) | |
| 1049 | − return r; | |
| 1050 | − r = radeon_irq_kms_init(rdev); | |
| 1051 | 1054 | if (r) |
| 1052 | 1055 | return r; |
| 1053 | 1056 | /* Memory manager */ |
| @@ -651,6 +651,12 @@ static int rs690_startup(struct radeon_device *rdev) · 650 unmodified lines | ||
| 651 | 651 | } |
| 652 | 652 | |
| 653 | 653 | /* Enable IRQ */ |
| 654 | + if (!rdev->irq.installed) { | |
| 655 | + r = radeon_irq_kms_init(rdev); | |
| 656 | + if (r) | |
| 657 | + return r; | |
| 658 | + } | |
| 659 | + | |
| 654 | 660 | rs600_irq_set(rdev); |
| 655 | 661 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 656 | 662 | /* 1M ring buffer */ |
| @@ -774,9 +780,6 @@ int rs690_init(struct radeon_device *rdev) · 117 unmodified lines | ||
| 774 | 780 | rv515_debugfs(rdev); |
| 775 | 781 | /* Fence driver */ |
| 776 | 782 | r = radeon_fence_driver_init(rdev); |
| 777 | − if (r) | |
| 778 | − return r; | |
| 779 | − r = radeon_irq_kms_init(rdev); | |
| 780 | 783 | if (r) |
| 781 | 784 | return r; |
| 782 | 785 | /* Memory manager */ |
| @@ -532,6 +532,12 @@ static int rv515_startup(struct radeon_device *rdev) · 531 unmodified lines | ||
| 532 | 532 | } |
| 533 | 533 | |
| 534 | 534 | /* Enable IRQ */ |
| 535 | + if (!rdev->irq.installed) { | |
| 536 | + r = radeon_irq_kms_init(rdev); | |
| 537 | + if (r) | |
| 538 | + return r; | |
| 539 | + } | |
| 540 | + | |
| 535 | 541 | rs600_irq_set(rdev); |
| 536 | 542 | rdev->config.r300.hdp_cntl = RREG32(RADEON_HOST_PATH_CNTL); |
| 537 | 543 | /* 1M ring buffer */ |
| @@ -660,9 +666,6 @@ int rv515_init(struct radeon_device *rdev) · 122 unmodified lines | ||
| 660 | 666 | rv515_debugfs(rdev); |
| 661 | 667 | /* Fence driver */ |
| 662 | 668 | r = radeon_fence_driver_init(rdev); |
| 663 | − if (r) | |
| 664 | − return r; | |
| 665 | − r = radeon_irq_kms_init(rdev); | |
| 666 | 669 | if (r) |
| 667 | 670 | return r; |
| 668 | 671 | /* Memory manager */ |
| @@ -1887,6 +1887,12 @@ static int rv770_startup(struct radeon_device *rdev) · 1886 unmodified lines | ||
| 1887 | 1887 | rdev->ring[R600_RING_TYPE_UVD_INDEX].ring_size = 0; |
| 1888 | 1888 | |
| 1889 | 1889 | /* Enable IRQ */ |
| 1890 | + if (!rdev->irq.installed) { | |
| 1891 | + r = radeon_irq_kms_init(rdev); | |
| 1892 | + if (r) | |
| 1893 | + return r; | |
| 1894 | + } | |
| 1895 | + | |
| 1890 | 1896 | r = r600_irq_init(rdev); |
| 1891 | 1897 | if (r) { |
| 1892 | 1898 | DRM_ERROR("radeon: IH init failed (%d).\n", r); |
| @@ -2045,10 +2051,6 @@ int rv770_init(struct radeon_device *rdev) · 152 unmodified lines | ||
| 2045 | 2051 | if (r) |
| 2046 | 2052 | return r; |
| 2047 | 2053 | |
| 2048 | − r = radeon_irq_kms_init(rdev); | |
| 2049 | − if (r) | |
| 2050 | − return r; | |
| 2051 | − | |
| 2052 | 2054 | rdev->ring[RADEON_RING_TYPE_GFX_INDEX].ring_obj = NULL; |
| 2053 | 2055 | r600_ring_init(rdev, &rdev->ring[RADEON_RING_TYPE_GFX_INDEX], 1024 * 1024); |
| 2054 | 2056 | |
| @@ -5350,6 +5350,12 @@ static int si_startup(struct radeon_device *rdev) · 5349 unmodified lines | ||
| 5350 | 5350 | } |
| 5351 | 5351 | |
| 5352 | 5352 | /* Enable IRQ */ |
| 5353 | + if (!rdev->irq.installed) { | |
| 5354 | + r = radeon_irq_kms_init(rdev); | |
| 5355 | + if (r) | |
| 5356 | + return r; | |
| 5357 | + } | |
| 5358 | + | |
| 5353 | 5359 | r = si_irq_init(rdev); |
| 5354 | 5360 | if (r) { |
| 5355 | 5361 | DRM_ERROR("radeon: IH init failed (%d).\n", r); |
| @@ -5533,10 +5539,6 @@ int si_init(struct radeon_device *rdev) · 177 unmodified lines | ||
| 5533 | 5539 | if (r) |
| 5534 | 5540 | return r; |
| 5535 | 5541 | |
| 5536 | − r = radeon_irq_kms_init(rdev); | |
| 5537 | − if (r) | |
| 5538 | − return r; | |
| 5539 | − | |
| 5540 | 5542 | ring = &rdev->ring[RADEON_RING_TYPE_GFX_INDEX]; |
| 5541 | 5543 | ring->ring_obj = NULL; |
| 5542 | 5544 | r600_ring_init(rdev, ring, 1024 * 1024); |
| @@ -6,6 +6,7 @@ config DRM_TILCDC · 5 unmodified lines | ||
| 6 | 6 | select DRM_GEM_CMA_HELPER |
| 7 | 7 | select VIDEOMODE_HELPERS |
| 8 | 8 | select BACKLIGHT_CLASS_DEVICE |
| 9 | + select BACKLIGHT_LCD_SUPPORT | |
| 9 | 10 | help |
| 10 | 11 | Choose this option if you have an TI SoC with LCDC display |
| 11 | 12 | controller, for example AM33xx in beagle-bone, DA8xx, or |