diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-11-15 03:56:02 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-11-28 18:57:53 -0500 |
commit | 6c8e4633d351f6f794c8a5c03f19e8d5a25f9639 (patch) | |
tree | c7a834aed353c7dfc2e34e71c4dda40a51b48318 | |
parent | b6e4ad200a726a32c7083f491383713bc8680f86 (diff) |
drm/nouveau/dp: move core link training calls to common code
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_dp.c | 34 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_encoder.h | 2 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_sor.c | 44 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 44 |
4 files changed, 30 insertions, 94 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_dp.c b/drivers/gpu/drm/nouveau/nouveau_dp.c index 978a108ba7a1..e3f6550ae772 100644 --- a/drivers/gpu/drm/nouveau/nouveau_dp.c +++ b/drivers/gpu/drm/nouveau/nouveau_dp.c | |||
@@ -30,6 +30,8 @@ | |||
30 | #include "nouveau_encoder.h" | 30 | #include "nouveau_encoder.h" |
31 | #include "nouveau_crtc.h" | 31 | #include "nouveau_crtc.h" |
32 | 32 | ||
33 | #include <core/class.h> | ||
34 | |||
33 | #include <subdev/gpio.h> | 35 | #include <subdev/gpio.h> |
34 | #include <subdev/i2c.h> | 36 | #include <subdev/i2c.h> |
35 | 37 | ||
@@ -83,7 +85,7 @@ nouveau_dp_bios_data(struct drm_device *dev, struct dcb_output *dcb, u8 **entry) | |||
83 | *****************************************************************************/ | 85 | *****************************************************************************/ |
84 | struct dp_state { | 86 | struct dp_state { |
85 | struct nouveau_i2c_port *auxch; | 87 | struct nouveau_i2c_port *auxch; |
86 | struct dp_train_func *func; | 88 | struct nouveau_object *core; |
87 | struct dcb_output *dcb; | 89 | struct dcb_output *dcb; |
88 | int crtc; | 90 | int crtc; |
89 | u8 *dpcd; | 91 | u8 *dpcd; |
@@ -97,13 +99,20 @@ static void | |||
97 | dp_set_link_config(struct drm_device *dev, struct dp_state *dp) | 99 | dp_set_link_config(struct drm_device *dev, struct dp_state *dp) |
98 | { | 100 | { |
99 | struct nouveau_drm *drm = nouveau_drm(dev); | 101 | struct nouveau_drm *drm = nouveau_drm(dev); |
102 | struct dcb_output *dcb = dp->dcb; | ||
103 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
104 | const u32 moff = (dp->crtc << 3) | (link << 2) | or; | ||
100 | u8 sink[2]; | 105 | u8 sink[2]; |
106 | u32 data; | ||
101 | 107 | ||
102 | NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); | 108 | NV_DEBUG(drm, "%d lanes at %d KB/s\n", dp->link_nr, dp->link_bw); |
103 | 109 | ||
104 | /* set desired link configuration on the source */ | 110 | /* set desired link configuration on the source */ |
105 | dp->func->link_set(dev, dp->dcb, dp->crtc, dp->link_nr, dp->link_bw, | 111 | data = ((dp->link_bw / 27000) << 8) | dp->link_nr; |
106 | dp->dpcd[2] & DP_ENHANCED_FRAME_CAP); | 112 | if (dp->dpcd[2] & DP_ENHANCED_FRAME_CAP) |
113 | data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH; | ||
114 | |||
115 | nv_call(dp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data); | ||
107 | 116 | ||
108 | /* inform the sink of the new configuration */ | 117 | /* inform the sink of the new configuration */ |
109 | sink[0] = dp->link_bw / 27000; | 118 | sink[0] = dp->link_bw / 27000; |
@@ -118,11 +127,14 @@ static void | |||
118 | dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) | 127 | dp_set_training_pattern(struct drm_device *dev, struct dp_state *dp, u8 pattern) |
119 | { | 128 | { |
120 | struct nouveau_drm *drm = nouveau_drm(dev); | 129 | struct nouveau_drm *drm = nouveau_drm(dev); |
130 | struct dcb_output *dcb = dp->dcb; | ||
131 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
132 | const u32 moff = (dp->crtc << 3) | (link << 2) | or; | ||
121 | u8 sink_tp; | 133 | u8 sink_tp; |
122 | 134 | ||
123 | NV_DEBUG(drm, "training pattern %d\n", pattern); | 135 | NV_DEBUG(drm, "training pattern %d\n", pattern); |
124 | 136 | ||
125 | dp->func->train_set(dev, dp->dcb, pattern); | 137 | nv_call(dp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern); |
126 | 138 | ||
127 | nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); | 139 | nv_rdaux(dp->auxch, DP_TRAINING_PATTERN_SET, &sink_tp, 1); |
128 | sink_tp &= ~DP_TRAINING_PATTERN_MASK; | 140 | sink_tp &= ~DP_TRAINING_PATTERN_MASK; |
@@ -134,6 +146,9 @@ static int | |||
134 | dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) | 146 | dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) |
135 | { | 147 | { |
136 | struct nouveau_drm *drm = nouveau_drm(dev); | 148 | struct nouveau_drm *drm = nouveau_drm(dev); |
149 | struct dcb_output *dcb = dp->dcb; | ||
150 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
151 | const u32 moff = (dp->crtc << 3) | (link << 2) | or; | ||
137 | int i; | 152 | int i; |
138 | 153 | ||
139 | for (i = 0; i < dp->link_nr; i++) { | 154 | for (i = 0; i < dp->link_nr; i++) { |
@@ -148,7 +163,8 @@ dp_link_train_commit(struct drm_device *dev, struct dp_state *dp) | |||
148 | dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; | 163 | dp->conf[i] |= DP_TRAIN_MAX_PRE_EMPHASIS_REACHED; |
149 | 164 | ||
150 | NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]); | 165 | NV_DEBUG(drm, "config lane %d %02x\n", i, dp->conf[i]); |
151 | dp->func->train_adj(dev, dp->dcb, i, lvsw, lpre); | 166 | |
167 | nv_call(dp->core, NV94_DISP_SOR_DP_DRVCTL(i) + moff, (lvsw << 8) | lpre); | ||
152 | } | 168 | } |
153 | 169 | ||
154 | return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4); | 170 | return nv_wraux(dp->auxch, DP_TRAINING_LANE0_SET, dp->conf, 4); |
@@ -286,7 +302,7 @@ dp_link_train_fini(struct drm_device *dev, struct dp_state *dp) | |||
286 | 302 | ||
287 | static bool | 303 | static bool |
288 | nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, | 304 | nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, |
289 | struct dp_train_func *func) | 305 | struct nouveau_object *core) |
290 | { | 306 | { |
291 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 307 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
292 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 308 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
@@ -304,7 +320,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, | |||
304 | if (!dp.auxch) | 320 | if (!dp.auxch) |
305 | return false; | 321 | return false; |
306 | 322 | ||
307 | dp.func = func; | 323 | dp.core = core; |
308 | dp.dcb = nv_encoder->dcb; | 324 | dp.dcb = nv_encoder->dcb; |
309 | dp.crtc = nv_crtc->index; | 325 | dp.crtc = nv_crtc->index; |
310 | dp.dpcd = nv_encoder->dp.dpcd; | 326 | dp.dpcd = nv_encoder->dp.dpcd; |
@@ -365,7 +381,7 @@ nouveau_dp_link_train(struct drm_encoder *encoder, u32 datarate, | |||
365 | 381 | ||
366 | void | 382 | void |
367 | nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, | 383 | nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, |
368 | struct dp_train_func *func) | 384 | struct nouveau_object *core) |
369 | { | 385 | { |
370 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 386 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
371 | struct nouveau_drm *drm = nouveau_drm(encoder->dev); | 387 | struct nouveau_drm *drm = nouveau_drm(encoder->dev); |
@@ -385,7 +401,7 @@ nouveau_dp_dpms(struct drm_encoder *encoder, int mode, u32 datarate, | |||
385 | nv_wraux(auxch, DP_SET_POWER, &status, 1); | 401 | nv_wraux(auxch, DP_SET_POWER, &status, 1); |
386 | 402 | ||
387 | if (mode == DRM_MODE_DPMS_ON) | 403 | if (mode == DRM_MODE_DPMS_ON) |
388 | nouveau_dp_link_train(encoder, datarate, func); | 404 | nouveau_dp_link_train(encoder, datarate, core); |
389 | } | 405 | } |
390 | 406 | ||
391 | static void | 407 | static void |
diff --git a/drivers/gpu/drm/nouveau/nouveau_encoder.h b/drivers/gpu/drm/nouveau/nouveau_encoder.h index 6a17bf2ba9a4..06c1bb3a2f2a 100644 --- a/drivers/gpu/drm/nouveau/nouveau_encoder.h +++ b/drivers/gpu/drm/nouveau/nouveau_encoder.h | |||
@@ -93,7 +93,7 @@ get_slave_funcs(struct drm_encoder *enc) | |||
93 | /* nouveau_dp.c */ | 93 | /* nouveau_dp.c */ |
94 | bool nouveau_dp_detect(struct drm_encoder *); | 94 | bool nouveau_dp_detect(struct drm_encoder *); |
95 | void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate, | 95 | void nouveau_dp_dpms(struct drm_encoder *, int mode, u32 datarate, |
96 | struct dp_train_func *); | 96 | struct nouveau_object *); |
97 | u8 *nouveau_dp_bios_data(struct drm_device *, struct dcb_output *, u8 **); | 97 | u8 *nouveau_dp_bios_data(struct drm_device *, struct dcb_output *, u8 **); |
98 | 98 | ||
99 | struct nouveau_connector * | 99 | struct nouveau_connector * |
diff --git a/drivers/gpu/drm/nouveau/nv50_sor.c b/drivers/gpu/drm/nouveau/nv50_sor.c index ae4f24a0a54c..5499c23cb795 100644 --- a/drivers/gpu/drm/nouveau/nv50_sor.c +++ b/drivers/gpu/drm/nouveau/nv50_sor.c | |||
@@ -41,39 +41,6 @@ | |||
41 | #include <subdev/timer.h> | 41 | #include <subdev/timer.h> |
42 | 42 | ||
43 | static void | 43 | static void |
44 | nv50_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern) | ||
45 | { | ||
46 | struct nv50_display *disp = nv50_display(dev); | ||
47 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
48 | const u32 moff = (link << 2) | or; | ||
49 | nv_call(disp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern); | ||
50 | } | ||
51 | |||
52 | static void | ||
53 | nv50_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb, | ||
54 | u8 lane, u8 swing, u8 preem) | ||
55 | { | ||
56 | struct nv50_display *disp = nv50_display(dev); | ||
57 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
58 | const u32 moff = (link << 2) | or; | ||
59 | const u32 data = (swing << 8) | preem; | ||
60 | nv_call(disp->core, NV94_DISP_SOR_DP_DRVCTL(lane) + moff, data); | ||
61 | } | ||
62 | |||
63 | static void | ||
64 | nv50_sor_dp_link_set(struct drm_device *dev, struct dcb_output *dcb, int crtc, | ||
65 | int link_nr, u32 link_bw, bool enhframe) | ||
66 | { | ||
67 | struct nv50_display *disp = nv50_display(dev); | ||
68 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
69 | const u32 moff = (crtc << 3) | (link << 2) | or; | ||
70 | u32 data = ((link_bw / 27000) << 8) | link_nr; | ||
71 | if (enhframe) | ||
72 | data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH; | ||
73 | nv_call(disp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data); | ||
74 | } | ||
75 | |||
76 | static void | ||
77 | nv50_sor_disconnect(struct drm_encoder *encoder) | 44 | nv50_sor_disconnect(struct drm_encoder *encoder) |
78 | { | 45 | { |
79 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 46 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
@@ -133,15 +100,8 @@ nv50_sor_dpms(struct drm_encoder *encoder, int mode) | |||
133 | 100 | ||
134 | nv_call(priv->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); | 101 | nv_call(priv->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); |
135 | 102 | ||
136 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { | 103 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) |
137 | struct dp_train_func func = { | 104 | nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, priv->core); |
138 | .link_set = nv50_sor_dp_link_set, | ||
139 | .train_set = nv50_sor_dp_train_set, | ||
140 | .train_adj = nv50_sor_dp_train_adj | ||
141 | }; | ||
142 | |||
143 | nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func); | ||
144 | } | ||
145 | } | 105 | } |
146 | 106 | ||
147 | static void | 107 | static void |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 518f1a5342aa..98c93513189d 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -1306,39 +1306,6 @@ nvd0_hdmi_disconnect(struct drm_encoder *encoder) | |||
1306 | * SOR | 1306 | * SOR |
1307 | *****************************************************************************/ | 1307 | *****************************************************************************/ |
1308 | static void | 1308 | static void |
1309 | nvd0_sor_dp_train_set(struct drm_device *dev, struct dcb_output *dcb, u8 pattern) | ||
1310 | { | ||
1311 | struct nvd0_disp *disp = nvd0_disp(dev); | ||
1312 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
1313 | const u32 moff = (link << 2) | or; | ||
1314 | nv_call(disp->core, NV94_DISP_SOR_DP_TRAIN + moff, pattern); | ||
1315 | } | ||
1316 | |||
1317 | static void | ||
1318 | nvd0_sor_dp_train_adj(struct drm_device *dev, struct dcb_output *dcb, | ||
1319 | u8 lane, u8 swing, u8 preem) | ||
1320 | { | ||
1321 | struct nvd0_disp *disp = nvd0_disp(dev); | ||
1322 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
1323 | const u32 moff = (link << 2) | or; | ||
1324 | const u32 data = (swing << 8) | preem; | ||
1325 | nv_call(disp->core, NV94_DISP_SOR_DP_DRVCTL(lane) + moff, data); | ||
1326 | } | ||
1327 | |||
1328 | static void | ||
1329 | nvd0_sor_dp_link_set(struct drm_device *dev, struct dcb_output *dcb, int crtc, | ||
1330 | int link_nr, u32 link_bw, bool enhframe) | ||
1331 | { | ||
1332 | struct nvd0_disp *disp = nvd0_disp(dev); | ||
1333 | const u32 or = ffs(dcb->or) - 1, link = !(dcb->sorconf.link & 1); | ||
1334 | const u32 moff = (crtc << 3) | (link << 2) | or; | ||
1335 | u32 data = ((link_bw / 27000) << 8) | link_nr; | ||
1336 | if (enhframe) | ||
1337 | data |= NV94_DISP_SOR_DP_LNKCTL_FRAME_ENH; | ||
1338 | nv_call(disp->core, NV94_DISP_SOR_DP_LNKCTL + moff, data); | ||
1339 | } | ||
1340 | |||
1341 | static void | ||
1342 | nvd0_sor_dpms(struct drm_encoder *encoder, int mode) | 1309 | nvd0_sor_dpms(struct drm_encoder *encoder, int mode) |
1343 | { | 1310 | { |
1344 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1311 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
@@ -1365,15 +1332,8 @@ nvd0_sor_dpms(struct drm_encoder *encoder, int mode) | |||
1365 | 1332 | ||
1366 | nv_call(disp->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); | 1333 | nv_call(disp->core, NV50_DISP_SOR_PWR + or, (mode == DRM_MODE_DPMS_ON)); |
1367 | 1334 | ||
1368 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) { | 1335 | if (nv_encoder->dcb->type == DCB_OUTPUT_DP) |
1369 | struct dp_train_func func = { | 1336 | nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, disp->core); |
1370 | .link_set = nvd0_sor_dp_link_set, | ||
1371 | .train_set = nvd0_sor_dp_train_set, | ||
1372 | .train_adj = nvd0_sor_dp_train_adj | ||
1373 | }; | ||
1374 | |||
1375 | nouveau_dp_dpms(encoder, mode, nv_encoder->dp.datarate, &func); | ||
1376 | } | ||
1377 | } | 1337 | } |
1378 | 1338 | ||
1379 | static bool | 1339 | static bool |