diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-11-08 18:38:06 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-11-28 18:57:50 -0500 |
commit | 7ebb38b556485449bfaa506a196439f6a6fd6ebd (patch) | |
tree | 05d7dd2db64a7c4def70207d3ee6750246fd4b02 /drivers | |
parent | ef22c8bb7b3fac45919b7fde412d36d1a8367d51 (diff) |
drm/nv50/disp: call into core for dac load detection
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c | 6 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | 4 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv84.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nv94.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nva0.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | 1 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nv50_dac.c | 56 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nvd0_display.c | 2 |
9 files changed, 22 insertions, 51 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c index 18ba339c1625..d0817d94454c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/dacnv50.c | |||
@@ -46,11 +46,11 @@ nv50_dac_power(struct nv50_disp_priv *priv, int or, u32 data) | |||
46 | } | 46 | } |
47 | 47 | ||
48 | int | 48 | int |
49 | nv50_dac_sense(struct nv50_disp_priv *priv, int or) | 49 | nv50_dac_sense(struct nv50_disp_priv *priv, int or, u32 loadval) |
50 | { | 50 | { |
51 | const u32 doff = (or * 0x800); | 51 | const u32 doff = (or * 0x800); |
52 | int load = -EINVAL; | 52 | int load = -EINVAL; |
53 | nv_wr32(priv, 0x61a00c + doff, 0x00100000); | 53 | nv_wr32(priv, 0x61a00c + doff, 0x00100000 | loadval); |
54 | udelay(9500); | 54 | udelay(9500); |
55 | nv_wr32(priv, 0x61a00c + doff, 0x80000000); | 55 | nv_wr32(priv, 0x61a00c + doff, 0x80000000); |
56 | load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; | 56 | load = (nv_rd32(priv, 0x61a00c + doff) & 0x38000000) >> 27; |
@@ -74,7 +74,7 @@ nv50_dac_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) | |||
74 | ret = priv->dac.power(priv, or, data[0]); | 74 | ret = priv->dac.power(priv, or, data[0]); |
75 | break; | 75 | break; |
76 | case NV50_DISP_DAC_LOAD: | 76 | case NV50_DISP_DAC_LOAD: |
77 | ret = priv->dac.sense(priv, or); | 77 | ret = priv->dac.sense(priv, or, data[0]); |
78 | if (ret >= 0) { | 78 | if (ret >= 0) { |
79 | data[0] = ret; | 79 | data[0] = ret; |
80 | ret = 0; | 80 | ret = 0; |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c index 37cf70fe30b2..bc397bc38ac7 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c | |||
@@ -807,6 +807,7 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
807 | priv->dac.nr = 3; | 807 | priv->dac.nr = 3; |
808 | priv->sor.nr = 2; | 808 | priv->sor.nr = 2; |
809 | priv->dac.power = nv50_dac_power; | 809 | priv->dac.power = nv50_dac_power; |
810 | priv->dac.sense = nv50_dac_sense; | ||
810 | priv->sor.power = nv50_sor_power; | 811 | priv->sor.power = nv50_sor_power; |
811 | 812 | ||
812 | INIT_LIST_HEAD(&priv->base.vblank.list); | 813 | INIT_LIST_HEAD(&priv->base.vblank.list); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h index 01eb830e18da..72cefd24ea02 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h | |||
@@ -19,7 +19,7 @@ struct nv50_disp_priv { | |||
19 | struct { | 19 | struct { |
20 | int nr; | 20 | int nr; |
21 | int (*power)(struct nv50_disp_priv *, int dac, u32 data); | 21 | int (*power)(struct nv50_disp_priv *, int dac, u32 data); |
22 | int (*sense)(struct nv50_disp_priv *, int dac); | 22 | int (*sense)(struct nv50_disp_priv *, int dac, u32 load); |
23 | } dac; | 23 | } dac; |
24 | struct { | 24 | struct { |
25 | int nr; | 25 | int nr; |
@@ -42,7 +42,7 @@ struct nv50_disp_priv { | |||
42 | 42 | ||
43 | int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32); | 43 | int nv50_dac_mthd(struct nouveau_object *, u32, void *, u32); |
44 | int nv50_dac_power(struct nv50_disp_priv *, int, u32); | 44 | int nv50_dac_power(struct nv50_disp_priv *, int, u32); |
45 | int nv50_dac_sense(struct nv50_disp_priv *, int); | 45 | int nv50_dac_sense(struct nv50_disp_priv *, int, u32); |
46 | 46 | ||
47 | #define SOR_MTHD(n) (n), (n) + 0x3f | 47 | #define SOR_MTHD(n) (n), (n) + 0x3f |
48 | 48 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c index 69dff21076d5..4a52cb7a718c 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c | |||
@@ -76,6 +76,7 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
76 | priv->dac.nr = 3; | 76 | priv->dac.nr = 3; |
77 | priv->sor.nr = 2; | 77 | priv->sor.nr = 2; |
78 | priv->dac.power = nv50_dac_power; | 78 | priv->dac.power = nv50_dac_power; |
79 | priv->dac.sense = nv50_dac_sense; | ||
79 | priv->sor.power = nv50_sor_power; | 80 | priv->sor.power = nv50_sor_power; |
80 | 81 | ||
81 | INIT_LIST_HEAD(&priv->base.vblank.list); | 82 | INIT_LIST_HEAD(&priv->base.vblank.list); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c index 8dd8f8546dc3..36eb89c0f835 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c | |||
@@ -82,6 +82,7 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
82 | priv->dac.nr = 3; | 82 | priv->dac.nr = 3; |
83 | priv->sor.nr = 4; | 83 | priv->sor.nr = 4; |
84 | priv->dac.power = nv50_dac_power; | 84 | priv->dac.power = nv50_dac_power; |
85 | priv->dac.sense = nv50_dac_sense; | ||
85 | priv->sor.power = nv50_sor_power; | 86 | priv->sor.power = nv50_sor_power; |
86 | 87 | ||
87 | INIT_LIST_HEAD(&priv->base.vblank.list); | 88 | INIT_LIST_HEAD(&priv->base.vblank.list); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c index 9f0e354c5af6..7f247580db3a 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c | |||
@@ -67,6 +67,7 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
67 | priv->dac.nr = 3; | 67 | priv->dac.nr = 3; |
68 | priv->sor.nr = 2; | 68 | priv->sor.nr = 2; |
69 | priv->dac.power = nv50_dac_power; | 69 | priv->dac.power = nv50_dac_power; |
70 | priv->dac.sense = nv50_dac_sense; | ||
70 | priv->sor.power = nv50_sor_power; | 71 | priv->sor.power = nv50_sor_power; |
71 | 72 | ||
72 | INIT_LIST_HEAD(&priv->base.vblank.list); | 73 | INIT_LIST_HEAD(&priv->base.vblank.list); |
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c index 7aee31fb5dc5..398bb87db031 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c | |||
@@ -83,6 +83,7 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine, | |||
83 | priv->dac.nr = 3; | 83 | priv->dac.nr = 3; |
84 | priv->sor.nr = 4; | 84 | priv->sor.nr = 4; |
85 | priv->dac.power = nv50_dac_power; | 85 | priv->dac.power = nv50_dac_power; |
86 | priv->dac.sense = nv50_dac_sense; | ||
86 | priv->sor.power = nv50_sor_power; | 87 | priv->sor.power = nv50_sor_power; |
87 | 88 | ||
88 | INIT_LIST_HEAD(&priv->base.vblank.list); | 89 | INIT_LIST_HEAD(&priv->base.vblank.list); |
diff --git a/drivers/gpu/drm/nouveau/nv50_dac.c b/drivers/gpu/drm/nouveau/nv50_dac.c index 34abb588b482..622f0f9879ab 100644 --- a/drivers/gpu/drm/nouveau/nv50_dac.c +++ b/drivers/gpu/drm/nouveau/nv50_dac.c | |||
@@ -71,56 +71,22 @@ nv50_dac_disconnect(struct drm_encoder *encoder) | |||
71 | static enum drm_connector_status | 71 | static enum drm_connector_status |
72 | nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | 72 | nv50_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) |
73 | { | 73 | { |
74 | struct nv50_display *priv = nv50_display(encoder->dev); | ||
74 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); | 75 | struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); |
75 | struct nouveau_device *device = nouveau_dev(encoder->dev); | ||
76 | struct nouveau_drm *drm = nouveau_drm(encoder->dev); | 76 | struct nouveau_drm *drm = nouveau_drm(encoder->dev); |
77 | enum drm_connector_status status = connector_status_disconnected; | 77 | int or = nv_encoder->or, ret; |
78 | uint32_t dpms_state, load_pattern, load_state; | 78 | u32 load; |
79 | int or = nv_encoder->or; | ||
80 | |||
81 | nv_wr32(device, NV50_PDISPLAY_DAC_CLK_CTRL1(or), 0x00000001); | ||
82 | dpms_state = nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or)); | ||
83 | |||
84 | nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), | ||
85 | 0x00150000 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); | ||
86 | if (!nv_wait(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), | ||
87 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING, 0)) { | ||
88 | NV_ERROR(drm, "timeout: DAC_DPMS_CTRL_PENDING(%d) == 0\n", or); | ||
89 | NV_ERROR(drm, "DAC_DPMS_CTRL(%d) = 0x%08x\n", or, | ||
90 | nv_rd32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or))); | ||
91 | return status; | ||
92 | } | ||
93 | |||
94 | /* Use bios provided value if possible. */ | ||
95 | if (drm->vbios.dactestval) { | ||
96 | load_pattern = drm->vbios.dactestval; | ||
97 | NV_DEBUG(drm, "Using bios provided load_pattern of %d\n", | ||
98 | load_pattern); | ||
99 | } else { | ||
100 | load_pattern = 340; | ||
101 | NV_DEBUG(drm, "Using default load_pattern of %d\n", | ||
102 | load_pattern); | ||
103 | } | ||
104 | |||
105 | nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or), | ||
106 | NV50_PDISPLAY_DAC_LOAD_CTRL_ACTIVE | load_pattern); | ||
107 | mdelay(45); /* give it some time to process */ | ||
108 | load_state = nv_rd32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or)); | ||
109 | |||
110 | nv_wr32(device, NV50_PDISPLAY_DAC_LOAD_CTRL(or), 0); | ||
111 | nv_wr32(device, NV50_PDISPLAY_DAC_DPMS_CTRL(or), dpms_state | | ||
112 | NV50_PDISPLAY_DAC_DPMS_CTRL_PENDING); | ||
113 | 79 | ||
114 | if ((load_state & NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) == | 80 | if (drm->vbios.dactestval) |
115 | NV50_PDISPLAY_DAC_LOAD_CTRL_PRESENT) | 81 | load = drm->vbios.dactestval; |
116 | status = connector_status_connected; | ||
117 | |||
118 | if (status == connector_status_connected) | ||
119 | NV_DEBUG(drm, "Load was detected on output with or %d\n", or); | ||
120 | else | 82 | else |
121 | NV_DEBUG(drm, "Load was not detected on output with or %d\n", or); | 83 | load = 340; |
84 | |||
85 | ret = nv_exec(priv->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); | ||
86 | if (ret || load != 7) | ||
87 | return connector_status_disconnected; | ||
122 | 88 | ||
123 | return status; | 89 | return connector_status_connected; |
124 | } | 90 | } |
125 | 91 | ||
126 | static void | 92 | static void |
diff --git a/drivers/gpu/drm/nouveau/nvd0_display.c b/drivers/gpu/drm/nouveau/nvd0_display.c index 9bb28b030f4b..758daf709a99 100644 --- a/drivers/gpu/drm/nouveau/nvd0_display.c +++ b/drivers/gpu/drm/nouveau/nvd0_display.c | |||
@@ -1176,7 +1176,7 @@ nvd0_dac_detect(struct drm_encoder *encoder, struct drm_connector *connector) | |||
1176 | { | 1176 | { |
1177 | struct nvd0_disp *disp = nvd0_disp(encoder->dev); | 1177 | struct nvd0_disp *disp = nvd0_disp(encoder->dev); |
1178 | int ret, or = nouveau_encoder(encoder)->or; | 1178 | int ret, or = nouveau_encoder(encoder)->or; |
1179 | u32 load; | 1179 | u32 load = 0; |
1180 | 1180 | ||
1181 | ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); | 1181 | ret = nv_exec(disp->core, NV50_DISP_DAC_LOAD + or, &load, sizeof(load)); |
1182 | if (ret || load != 7) | 1182 | if (ret || load != 7) |