Multiple nouveau regression fixes, hdmi audio, s/r and dac load detection * 'drm-nouveau-fixes-3.10' of git://anongit.freedesktop.org/git/nouveau/linux-2.6: 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
Unified · Split
| @@ -50,12 +50,16 @@ nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) · 49 unmodified lines | |||
| 50 | { | 50 | { |
| 51 | const u32 doff = (or * 0x800); | 51 | const u32 doff = (or * 0x800); |
| 52 | int load = -EINVAL; | 52 | int load = -EINVAL; |
| 53 | nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80150000); | ||
| 54 | nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); | ||
| 53 | nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); | 55 | nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); |
| 54 | mdelay(9); | 56 | mdelay(9); |
| 55 | udelay(500); | 57 | udelay(500); |
| 56 | nv_wr32(priv, 0x61a00c + doff, 0x80000000); | 58 | nv_wr32(priv, 0x61a00c + doff, 0x80000000); |
| 57 | load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; | 59 | load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; |
| 58 | nv_wr32(priv, 0x61a00c + doff, 0x00000000); | 60 | nv_wr32(priv, 0x61a00c + doff, 0x00000000); |
| 61 | nv_mask(priv, 0x61a004 + doff, 0x807f0000, 0x80550000); | ||
| 62 | nv_wait(priv, 0x61a004 + doff, 0x80000000, 0x00000000); | ||
| 59 | return load; | 63 | return load; |
| 60 | } | 64 | } |
| 61 | 65 | ||
| @@ -55,6 +55,10 @@ nv84_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) · 54 unmodified lines | |||
| 55 | nv_wr32(priv, 0x616510 + hoff, 0x00000000); | 55 | nv_wr32(priv, 0x616510 + hoff, 0x00000000); |
| 56 | nv_mask(priv, 0x616500 + hoff, 0x00000001, 0x00000001); | 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 | nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */ | 63 | nv_mask(priv, 0x61733c, 0x00100000, 0x00100000); /* RESETF */ |
| 60 | nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */ | 64 | nv_mask(priv, 0x61733c, 0x10000000, 0x10000000); /* LOOKUP_EN */ |
| @@ -40,14 +40,13 @@ · 39 unmodified lines | |||
| 40 | * FIFO channel objects | 40 | * FIFO channel objects |
| 41 | ******************************************************************************/ | 41 | ******************************************************************************/ |
| 42 | 42 | ||
| 43 | void | 43 | static void |
| 44 | nv50_fifo_playlist_update(struct nv50_fifo_priv *priv) | 44 | nv50_fifo_playlist_update_locked(struct nv50_fifo_priv *priv) |
| 45 | { | 45 | { |
| 46 | struct nouveau_bar *bar = nouveau_bar(priv); | 46 | struct nouveau_bar *bar = nouveau_bar(priv); |
| 47 | struct nouveau_gpuobj *cur; | 47 | struct nouveau_gpuobj *cur; |
| 48 | int i, p; | 48 | int i, p; |
| 49 | 49 | ||
| 50 | mutex_lock(&nv_subdev(priv)->mutex); | ||
| 51 | cur = priv->playlist[priv->cur_playlist]; | 50 | cur = priv->playlist[priv->cur_playlist]; |
| 52 | priv->cur_playlist = !priv->cur_playlist; | 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 | nv_wr32(priv, 0x0032f4, cur->addr >> 12); | 60 | nv_wr32(priv, 0x0032f4, cur->addr >> 12); |
| 62 | nv_wr32(priv, 0x0032ec, p); | 61 | nv_wr32(priv, 0x0032ec, p); |
| 63 | nv_wr32(priv, 0x002500, 0x00000101); | 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 | mutex_unlock(&nv_subdev(priv)->mutex); | 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 | for (i = 0; i < 128; i++) | 496 | for (i = 0; i < 128; i++) |
| 491 | nv_wr32(priv, 0x002600 + (i * 4), 0x00000000); | 497 | nv_wr32(priv, 0x002600 + (i * 4), 0x00000000); |
| 492 | nv50_fifo_playlist_update(priv); | 498 | nv50_fifo_playlist_update_locked(priv); |
| 493 | 499 | ||
| 494 | nv_wr32(priv, 0x003200, 0x00000001); | 500 | nv_wr32(priv, 0x003200, 0x00000001); |
| 495 | nv_wr32(priv, 0x003250, 0x00000001); | 501 | nv_wr32(priv, 0x003250, 0x00000001); |
| @@ -218,7 +218,7 @@ struct nv04_display_class { · 217 unmodified lines | |||
| 218 | #define NV50_DISP_DAC_PWR_STATE 0x00000040 | 218 | #define NV50_DISP_DAC_PWR_STATE 0x00000040 |
| 219 | #define NV50_DISP_DAC_PWR_STATE_ON 0x00000000 | 219 | #define NV50_DISP_DAC_PWR_STATE_ON 0x00000000 |
| 220 | #define NV50_DISP_DAC_PWR_STATE_OFF 0x00000040 | 220 | #define NV50_DISP_DAC_PWR_STATE_OFF 0x00000040 |
| 221 | #define NV50_DISP_DAC_LOAD 0x0002000c | 221 | #define NV50_DISP_DAC_LOAD 0x00020100 |
| 222 | #define NV50_DISP_DAC_LOAD_VALUE 0x00000007 | 222 | #define NV50_DISP_DAC_LOAD_VALUE 0x00000007 |
| 223 | 223 | ||
| 224 | #define NV50_DISP_PIOR_MTHD 0x00030000 | 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 | struct nv50_disp *disp = nv50_disp(encoder->dev); | 1555 | struct nv50_disp *disp = nv50_disp(encoder->dev); |
| 1556 | int ret, or = nouveau_encoder(encoder)->or; | 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 | ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); | 1561 | ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); |
| 1560 | if (ret || load != 7) | 1562 | if (ret || load != 7) |