aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBen Skeggs <bskeggs@redhat.com>2017-05-19 09:59:35 -0400
committerBen Skeggs <bskeggs@redhat.com>2017-06-16 00:04:58 -0400
commit9648da5a71c25e17d14feb0d7dc9ee73319e8a24 (patch)
treea1697de0d6eb9b8ad6e7b307545d11c73acc9c48
parent6c22ea3747fd36409ce4a1e1a0cbac40f93e1e71 (diff)
drm/nouveau/disp/dp: determine link bandwidth requirements from head state
Training/Untraining will be hooked up to the routing logic, which doesn't allow us to pass in a data rate. Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c14
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h6
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c13
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c1
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h2
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c27
-rw-r--r--drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c1
7 files changed, 62 insertions, 2 deletions
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
index 0f1c223cc7a8..4ad31302aaf4 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/dp.c
@@ -23,6 +23,7 @@
23 */ 23 */
24#include "dp.h" 24#include "dp.h"
25#include "conn.h" 25#include "conn.h"
26#include "head.h"
26#include "ior.h" 27#include "ior.h"
27 28
28#include <subdev/bios.h> 29#include <subdev/bios.h>
@@ -419,19 +420,28 @@ nvkm_dp_train(struct nvkm_dp *dp, u32 dataKBps)
419} 420}
420 421
421int 422int
422nvkm_output_dp_train(struct nvkm_outp *outp, u32 datakbps) 423nvkm_output_dp_train(struct nvkm_outp *outp, u32 unused)
423{ 424{
424 struct nvkm_dp *dp = nvkm_dp(outp); 425 struct nvkm_dp *dp = nvkm_dp(outp);
425 struct nvkm_ior *ior = dp->outp.ior; 426 struct nvkm_ior *ior = dp->outp.ior;
427 struct nvkm_head *head;
426 bool retrain = true; 428 bool retrain = true;
427 u32 linkKBps; 429 u32 datakbps = 0;
428 u32 dataKBps; 430 u32 dataKBps;
431 u32 linkKBps;
429 u8 stat[3]; 432 u8 stat[3];
430 int ret, i; 433 int ret, i;
431 434
432 mutex_lock(&dp->mutex); 435 mutex_lock(&dp->mutex);
433 436
434 /* Check that link configuration meets current requirements. */ 437 /* Check that link configuration meets current requirements. */
438 list_for_each_entry(head, &outp->disp->head, head) {
439 if (ior->asy.head & (1 << head->id)) {
440 u32 khz = (head->asy.hz >> ior->asy.rgdiv) / 1000;
441 datakbps += khz * head->asy.or.depth;
442 }
443 }
444
435 linkKBps = ior->dp.bw * 27000 * ior->dp.nr; 445 linkKBps = ior->dp.bw * 27000 * ior->dp.nr;
436 dataKBps = DIV_ROUND_UP(datakbps, 8); 446 dataKBps = DIV_ROUND_UP(datakbps, 8);
437 OUTP_DBG(&dp->outp, "data %d KB/s link %d KB/s mst %d->%d", 447 OUTP_DBG(&dp->outp, "data %d KB/s link %d KB/s mst %d->%d",
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
index 94f5cb7596a0..829a0a8cfb2e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/head.h
@@ -18,6 +18,12 @@ struct nvkm_head {
18 u16 vsynce; 18 u16 vsynce;
19 u16 vblanke; 19 u16 vblanke;
20 u16 vblanks; 20 u16 vblanks;
21 u32 hz;
22
23 /* Prior to GF119, these are set by the OR. */
24 struct {
25 u8 depth;
26 } or;
21 } arm, asy; 27 } arm, asy;
22}; 28};
23 29
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
index 8e7acc57d31d..d2bd6bb4a621 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headgf119.c
@@ -58,6 +58,19 @@ gf119_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
58 data = nvkm_rd32(device, 0x640420 + hoff); 58 data = nvkm_rd32(device, 0x640420 + hoff);
59 state->vblanks = (data & 0xffff0000) >> 16; 59 state->vblanks = (data & 0xffff0000) >> 16;
60 state->hblanks = (data & 0x0000ffff); 60 state->hblanks = (data & 0x0000ffff);
61 state->hz = nvkm_rd32(device, 0x640450 + hoff);
62
63 data = nvkm_rd32(device, 0x640404 + hoff);
64 switch ((data & 0x000003c0) >> 6) {
65 case 6: state->or.depth = 30; break;
66 case 5: state->or.depth = 24; break;
67 case 2: state->or.depth = 18; break;
68 case 0: state->or.depth = 18; break; /*XXX: "default" */
69 default:
70 state->or.depth = 18;
71 WARN_ON(1);
72 break;
73 }
61} 74}
62 75
63static const struct nvkm_head_func 76static const struct nvkm_head_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c
index 3cccda2cb09e..d4a9879f0d0a 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/headnv50.c
@@ -66,6 +66,7 @@ nv50_head_state(struct nvkm_head *head, struct nvkm_head_state *state)
66 data = nvkm_rd32(device, 0x610b00 + hoff); 66 data = nvkm_rd32(device, 0x610b00 + hoff);
67 state->vsynce = (data & 0xffff0000) >> 16; 67 state->vsynce = (data & 0xffff0000) >> 16;
68 state->hsynce = (data & 0x0000ffff); 68 state->hsynce = (data & 0x0000ffff);
69 state->hz = (nvkm_rd32(device, 0x610ad0 + hoff) & 0x003fffff) * 1000;
69} 70}
70 71
71static const struct nvkm_head_func 72static const struct nvkm_head_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
index a2e38d4780b1..3a6e01f5a0e5 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/ior.h
@@ -89,6 +89,8 @@ nv50_ior_base(struct nvkm_ior *ior)
89void nv50_dac_power(struct nvkm_ior *, bool, bool, bool, bool, bool); 89void nv50_dac_power(struct nvkm_ior *, bool, bool, bool, bool, bool);
90int nv50_dac_sense(struct nvkm_ior *, u32); 90int nv50_dac_sense(struct nvkm_ior *, u32);
91 91
92void nv50_pior_depth(struct nvkm_ior *, struct nvkm_ior_state *, u32 ctrl);
93
92static inline u32 94static inline u32
93nv50_sor_link(struct nvkm_ior *ior) 95nv50_sor_link(struct nvkm_ior *ior)
94{ 96{
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
index f66beda1ae11..dc59c319377e 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/piornv50.c
@@ -22,6 +22,7 @@
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 */ 23 */
24#include "ior.h" 24#include "ior.h"
25#include "head.h"
25 26
26#include <subdev/i2c.h> 27#include <subdev/i2c.h>
27#include <subdev/timer.h> 28#include <subdev/timer.h>
@@ -60,6 +61,31 @@ nv50_pior_power(struct nvkm_ior *pior, bool normal, bool pu,
60 nv50_pior_power_wait(device, poff); 61 nv50_pior_power_wait(device, poff);
61} 62}
62 63
64void
65nv50_pior_depth(struct nvkm_ior *ior, struct nvkm_ior_state *state, u32 ctrl)
66{
67 /* GF119 moves this information to per-head methods, which is
68 * a lot more convenient, and where our shared code expect it.
69 */
70 if (state->head && state == &ior->asy) {
71 struct nvkm_head *head =
72 nvkm_head_find(ior->disp, __ffs(state->head));
73 if (!WARN_ON(!head)) {
74 struct nvkm_head_state *state = &head->asy;
75 switch ((ctrl & 0x000f0000) >> 16) {
76 case 6: state->or.depth = 30; break;
77 case 5: state->or.depth = 24; break;
78 case 2: state->or.depth = 18; break;
79 case 0: state->or.depth = 18; break; /*XXX*/
80 default:
81 state->or.depth = 18;
82 WARN_ON(1);
83 break;
84 }
85 }
86 }
87}
88
63static void 89static void
64nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state) 90nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state)
65{ 91{
@@ -77,6 +103,7 @@ nv50_pior_state(struct nvkm_ior *pior, struct nvkm_ior_state *state)
77 } 103 }
78 104
79 state->head = ctrl & 0x00000003; 105 state->head = ctrl & 0x00000003;
106 nv50_pior_depth(pior, state, ctrl);
80} 107}
81 108
82static const struct nvkm_ior_func 109static const struct nvkm_ior_func
diff --git a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
index bfc7b0e053a4..5abf563b0e84 100644
--- a/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
+++ b/drivers/gpu/drm/nouveau/nvkm/engine/disp/sorg94.c
@@ -238,6 +238,7 @@ g94_sor_state(struct nvkm_ior *sor, struct nvkm_ior_state *state)
238 } 238 }
239 239
240 state->head = ctrl & 0x00000003; 240 state->head = ctrl & 0x00000003;
241 nv50_pior_depth(sor, state, ctrl);
241} 242}
242 243
243static const struct nvkm_ior_func 244static const struct nvkm_ior_func