diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-11-07 23:22:28 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-11-28 18:57:47 -0500 |
commit | 1c30cd09e37e0804f604f3932c695da13e9d442f (patch) | |
tree | 7c6cf35ae87539d757bef6438e8e695e346cce72 | |
parent | 0a9e2b959f2a1673ca9315df8e0b6dec1069060e (diff) |
drm/nvd0/disp: move HDMI control to core
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/Makefile | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c | 62 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nve0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | 3 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/include/core/class.h | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 37 |
9 files changed, 86 insertions, 29 deletions
diff --git a/drivers/gpu/drm/nouveau/Makefile b/drivers/gpu/drm/nouveau/Makefile index ac9d9281609..01132dd0910 100644 --- a/drivers/gpu/drm/nouveau/Makefile +++ b/drivers/gpu/drm/nouveau/Makefile | |||
@@ -139,6 +139,7 @@ nouveau-y += core/engine/disp/nvd0.o | |||
139 | nouveau-y += core/engine/disp/nve0.o | 139 | nouveau-y += core/engine/disp/nve0.o |
140 | nouveau-y += core/engine/disp/dacnv50.o | 140 | nouveau-y += core/engine/disp/dacnv50.o |
141 | nouveau-y += core/engine/disp/hdanvd0.o | 141 | nouveau-y += core/engine/disp/hdanvd0.o |
142 | nouveau-y += core/engine/disp/hdminvd0.o | ||
142 | nouveau-y += core/engine/disp/sornv50.o | 143 | nouveau-y += core/engine/disp/sornv50.o |
143 | nouveau-y += core/engine/disp/sornvd0.o | 144 | nouveau-y += core/engine/disp/sornvd0.o |
144 | nouveau-y += core/engine/disp/vga.o | 145 | nouveau-y += core/engine/disp/vga.o |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c new file mode 100644 index 00000000000..5151bb26183 --- /dev/null +++ b/drivers/gpu/drm/nouveau/core/engine/disp/hdminvd0.c | |||
@@ -0,0 +1,62 @@ | |||
1 | /* | ||
2 | * Copyright 2012 Red Hat Inc. | ||
3 | * | ||
4 | * Permission is hereby granted, free of charge, to any person obtaining a | ||
5 | * copy of this software and associated documentation files (the "Software"), | ||
6 | * to deal in the Software without restriction, including without limitation | ||
7 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, | ||
8 | * and/or sell copies of the Software, and to permit persons to whom the | ||
9 | * Software is furnished to do so, subject to the following conditions: | ||
10 | * | ||
11 | * The above copyright notice and this permission notice shall be included in | ||
12 | * all copies or substantial portions of the Software. | ||
13 | * | ||
14 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR | ||
15 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, | ||
16 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL | ||
17 | * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR | ||
18 | * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, | ||
19 | * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | ||
20 | * OTHER DEALINGS IN THE SOFTWARE. | ||
21 | * | ||
22 | * Authors: Ben Skeggs | ||
23 | */ | ||
24 | |||
25 | #include <core/os.h> | ||
26 | #include <core/class.h> | ||
27 | |||
28 | #include "nv50.h" | ||
29 | |||
30 | int | ||
31 | nvd0_hdmi_ctrl(struct nv50_disp_priv *priv, int head, int or, u32 data) | ||
32 | { | ||
33 | const u32 hoff = (head * 0x800); | ||
34 | |||
35 | if (!(data & NV84_DISP_SOR_HDMI_PWR_STATE_ON)) { | ||
36 | nv_mask(priv, 0x616798 + hoff, 0x40000000, 0x00000000); | ||
37 | nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000); | ||
38 | nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000); | ||
39 | return 0; | ||
40 | } | ||
41 | |||
42 | /* AVI InfoFrame */ | ||
43 | nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000000); | ||
44 | nv_wr32(priv, 0x61671c + hoff, 0x000d0282); | ||
45 | nv_wr32(priv, 0x616720 + hoff, 0x0000006f); | ||
46 | nv_wr32(priv, 0x616724 + hoff, 0x00000000); | ||
47 | nv_wr32(priv, 0x616728 + hoff, 0x00000000); | ||
48 | nv_wr32(priv, 0x61672c + hoff, 0x00000000); | ||
49 | nv_mask(priv, 0x616714 + hoff, 0x00000001, 0x00000001); | ||
50 | |||
51 | /* ??? InfoFrame? */ | ||
52 | nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000000); | ||
53 | nv_wr32(priv, 0x6167ac + hoff, 0x00000010); | ||
54 | nv_mask(priv, 0x6167a4 + hoff, 0x00000001, 0x00000001); | ||
55 | |||
56 | /* HDMI_CTRL */ | ||
57 | nv_mask(priv, 0x616798 + hoff, 0x401f007f, data); | ||
58 | |||
59 | /* NFI, audio doesn't work without it though.. */ | ||
60 | nv_mask(priv, 0x616548 + hoff, 0x00000070, 0x00000000); | ||
61 | return 0; | ||
62 | } | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index 78934c54d22..48e3f0d58cb 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | |||
@@ -25,6 +25,7 @@ struct nv50_disp_priv { | |||
25 | int nr; | 25 | int nr; |
26 | int (*power)(struct nv50_disp_priv *, int sor, u32 data); | 26 | int (*power)(struct nv50_disp_priv *, int sor, u32 data); |
27 | int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32); | 27 | int (*hda_eld)(struct nv50_disp_priv *, int sor, u8 *, u32); |
28 | int (*hdmi)(struct nv50_disp_priv *, int head, int sor, u32); | ||
28 | int (*dp_train)(struct nv50_disp_priv *, int sor, int link, | 29 | int (*dp_train)(struct nv50_disp_priv *, int sor, int link, |
29 | u16 type, u16 mask, u32 data, | 30 | u16 type, u16 mask, u32 data, |
30 | struct dcb_output *); | 31 | struct dcb_output *); |
@@ -52,6 +53,8 @@ int nv50_sor_power(struct nv50_disp_priv *, int, u32); | |||
52 | 53 | ||
53 | int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); | 54 | int nvd0_hda_eld(struct nv50_disp_priv *, int, u8 *, u32); |
54 | 55 | ||
56 | int nvd0_hdmi_ctrl(struct nv50_disp_priv *, int, int, u32); | ||
57 | |||
55 | int nvd0_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32, | 58 | int nvd0_sor_dp_train(struct nv50_disp_priv *, int, int, u16, u16, u32, |
56 | struct dcb_output *); | 59 | struct dcb_output *); |
57 | int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, | 60 | int nvd0_sor_dp_lnkctl(struct nv50_disp_priv *, int, int, int, u16, u16, u32, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index ced4c81fee1..b557108b2f3 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | |||
@@ -43,6 +43,7 @@ struct nouveau_omthds | |||
43 | nva3_disp_base_omthds[] = { | 43 | nva3_disp_base_omthds[] = { |
44 | { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, | 44 | { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, |
45 | { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, | 45 | { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, |
46 | { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, | ||
46 | { SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd }, | 47 | { SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd }, |
47 | { SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd }, | 48 | { SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd }, |
48 | { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, | 49 | { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c index cc2c3a4c31a..8589b953b28 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c | |||
@@ -900,6 +900,7 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
900 | priv->dac.sense = nv50_dac_sense; | 900 | priv->dac.sense = nv50_dac_sense; |
901 | priv->sor.power = nv50_sor_power; | 901 | priv->sor.power = nv50_sor_power; |
902 | priv->sor.hda_eld = nvd0_hda_eld; | 902 | priv->sor.hda_eld = nvd0_hda_eld; |
903 | priv->sor.hdmi = nvd0_hdmi_ctrl; | ||
903 | priv->sor.dp_train = nvd0_sor_dp_train; | 904 | priv->sor.dp_train = nvd0_sor_dp_train; |
904 | priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; | 905 | priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; |
905 | priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; | 906 | priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c index 4a7ebe496de..9b83a70091f 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c | |||
@@ -70,6 +70,7 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
70 | priv->dac.sense = nv50_dac_sense; | 70 | priv->dac.sense = nv50_dac_sense; |
71 | priv->sor.power = nv50_sor_power; | 71 | priv->sor.power = nv50_sor_power; |
72 | priv->sor.hda_eld = nvd0_hda_eld; | 72 | priv->sor.hda_eld = nvd0_hda_eld; |
73 | priv->sor.hdmi = nvd0_hdmi_ctrl; | ||
73 | priv->sor.dp_train = nvd0_sor_dp_train; | 74 | priv->sor.dp_train = nvd0_sor_dp_train; |
74 | priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; | 75 | priv->sor.dp_lnkctl = nvd0_sor_dp_lnkctl; |
75 | priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; | 76 | priv->sor.dp_drvctl = nvd0_sor_dp_drvctl; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c index 21d7761a556..4a8117d33f5 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv50.c | |||
@@ -91,6 +91,9 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | |||
91 | case NVA3_DISP_SOR_HDA_ELD: | 91 | case NVA3_DISP_SOR_HDA_ELD: |
92 | ret = priv->sor.hda_eld(priv, or, args, size); | 92 | ret = priv->sor.hda_eld(priv, or, args, size); |
93 | break; | 93 | break; |
94 | case NV84_DISP_SOR_HDMI_PWR: | ||
95 | ret = priv->sor.hdmi(priv, head, or, data); | ||
96 | break; | ||
94 | case NV94_DISP_SOR_DP_TRAIN: | 97 | case NV94_DISP_SOR_DP_TRAIN: |
95 | ret = priv->sor.dp_train(priv, or, link, type, mask, data, &outp); | 98 | ret = priv->sor.dp_train(priv, or, link, type, mask, data, &outp); |
96 | break; | 99 | break; |
diff --git a/drivers/gpu/drm/nouveau/core/include/core/class.h b/drivers/gpu/drm/nouveau/core/include/core/class.h index cc725945dab..de3ce108221 100644 --- a/drivers/gpu/drm/nouveau/core/include/core/class.h +++ b/drivers/gpu/drm/nouveau/core/include/core/class.h | |||
@@ -182,6 +182,12 @@ struct nve0_channel_ind_class { | |||
182 | #define NV50_DISP_SOR_PWR_STATE_ON 0x00000001 | 182 | #define NV50_DISP_SOR_PWR_STATE_ON 0x00000001 |
183 | #define NV50_DISP_SOR_PWR_STATE_OFF 0x00000000 | 183 | #define NV50_DISP_SOR_PWR_STATE_OFF 0x00000000 |
184 | #define NVA3_DISP_SOR_HDA_ELD 0x00010100 | 184 | #define NVA3_DISP_SOR_HDA_ELD 0x00010100 |
185 | #define NV84_DISP_SOR_HDMI_PWR 0x00012000 | ||
186 | #define NV84_DISP_SOR_HDMI_PWR_STATE 0x40000000 | ||
187 | #define NV84_DISP_SOR_HDMI_PWR_STATE_OFF 0x00000000 | ||
188 | #define NV84_DISP_SOR_HDMI_PWR_STATE_ON 0x40000000 | ||
189 | #define NV84_DISP_SOR_HDMI_PWR_MAX_AC_PACKET 0x001f0000 | ||
190 | #define NV84_DISP_SOR_HDMI_PWR_REKEY 0x0000007f | ||
185 | #define NV94_DISP_SOR_DP_TRAIN 0x00016000 | 191 | #define NV94_DISP_SOR_DP_TRAIN 0x00016000 |
186 | #define NV94_DISP_SOR_DP_TRAIN_PATTERN 0x00000003 | 192 | #define NV94_DISP_SOR_DP_TRAIN_PATTERN 0x00000003 |
187 | #define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED 0x00000000 | 193 | #define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED 0x00000000 |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 0620b786d7b..9acf4a0c5d9 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -1269,9 +1269,8 @@ nvd0_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
1269 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1269 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1270 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); | 1270 | struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); |
1271 | struct nouveau_connector *nv_connector; | 1271 | struct nouveau_connector *nv_connector; |
1272 | struct drm_device *dev = encoder->dev; | 1272 | struct nvd0_disp *disp = nvd0_disp(encoder->dev); |
1273 | struct nouveau_device *device = nouveau_dev(dev); | 1273 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; |
1274 | int head = nv_crtc->index * 0x800; | ||
1275 | u32 rekey = 56; /* binary driver, and tegra constant */ | 1274 | u32 rekey = 56; /* binary driver, and tegra constant */ |
1276 | u32 max_ac_packet; | 1275 | u32 max_ac_packet; |
1277 | 1276 | ||
@@ -1284,26 +1283,9 @@ nvd0_hdmi_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode) | |||
1284 | max_ac_packet -= 18; /* constant from tegra */ | 1283 | max_ac_packet -= 18; /* constant from tegra */ |
1285 | max_ac_packet /= 32; | 1284 | max_ac_packet /= 32; |
1286 | 1285 | ||
1287 | /* AVI InfoFrame */ | 1286 | nv_call(disp->core, NV84_DISP_SOR_HDMI_PWR + moff, |
1288 | nv_mask(device, 0x616714 + head, 0x00000001, 0x00000000); | 1287 | NV84_DISP_SOR_HDMI_PWR_STATE_ON | |
1289 | nv_wr32(device, 0x61671c + head, 0x000d0282); | 1288 | (max_ac_packet << 16) | rekey); |
1290 | nv_wr32(device, 0x616720 + head, 0x0000006f); | ||
1291 | nv_wr32(device, 0x616724 + head, 0x00000000); | ||
1292 | nv_wr32(device, 0x616728 + head, 0x00000000); | ||
1293 | nv_wr32(device, 0x61672c + head, 0x00000000); | ||
1294 | nv_mask(device, 0x616714 + head, 0x00000001, 0x00000001); | ||
1295 | |||
1296 | /* ??? InfoFrame? */ | ||
1297 | nv_mask(device, 0x6167a4 + head, 0x00000001, 0x00000000); | ||
1298 | nv_wr32(device, 0x6167ac + head, 0x00000010); | ||
1299 | nv_mask(device, 0x6167a4 + head, 0x00000001, 0x00000001); | ||
1300 | |||
1301 | /* HDMI_CTRL */ | ||
1302 | nv_mask(device, 0x616798 + head, 0x401f007f, 0x40000000 | rekey | | ||
1303 | max_ac_packet << 16); | ||
1304 | |||
1305 | /* NFI, audio doesn't work without it though.. */ | ||
1306 | nv_mask(device, 0x616548 + head, 0x00000070, 0x00000000); | ||
1307 | 1289 | ||
1308 | nvd0_audio_mode_set(encoder, mode); | 1290 | nvd0_audio_mode_set(encoder, mode); |
1309 | } | 1291 | } |
@@ -1313,15 +1295,12 @@ nvd0_hdmi_disconnect(struct drm_encoder *encoder) | |||
1313 | { | 1295 | { |
1314 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 1296 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
1315 | struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); | 1297 | struct nouveau_crtc *nv_crtc = nouveau_crtc(nv_encoder->crtc); |
1316 | struct drm_device *dev = encoder->dev; | 1298 | struct nvd0_disp *disp = nvd0_disp(encoder->dev); |
1317 | struct nouveau_device *device = nouveau_dev(dev); | 1299 | const u32 moff = (nv_crtc->index << 3) | nv_encoder->or; |
1318 | int head = nv_crtc->index * 0x800; | ||
1319 | 1300 | ||
1320 | nvd0_audio_disconnect(encoder); | 1301 | nvd0_audio_disconnect(encoder); |
1321 | 1302 | ||
1322 | nv_mask(device, 0x616798 + head, 0x40000000, 0x00000000); | 1303 | nv_call(disp->core, NV84_DISP_SOR_HDMI_PWR + moff, 0x00000000); |
1323 | nv_mask(device, 0x6167a4 + head, 0x00000001, 0x00000000); | ||
1324 | nv_mask(device, 0x616714 + head, 0x00000001, 0x00000000); | ||
1325 | } | 1304 | } |
1326 | 1305 | ||
1327 | /****************************************************************************** | 1306 | /****************************************************************************** |