diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-06-02 22:47:31 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-06-11 02:11:18 -0400 |
commit | 7a14bc783edbc7fecdb7031e3a2b816a339d24ee (patch) | |
tree | 7ce43f9bb95692002e34a63bd9bfd83f72f7a876 /drivers/gpu/drm/nouveau | |
parent | 4874322e78d505d38c8d4481118af5c9f0e8306d (diff) |
drm/nouveau/bios/dp: parse lane postcursor data
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
4 files changed, 27 insertions, 24 deletions
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c index 834ee0e185ca..d4dfcde0a95d 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornv94.c | |||
@@ -128,9 +128,9 @@ nv94_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc) | |||
128 | data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); | 128 | data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); |
129 | data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); | 129 | data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); |
130 | data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); | 130 | data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); |
131 | nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift)); | 131 | nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.dc << shift)); |
132 | nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift)); | 132 | nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pe << shift)); |
133 | nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8)); | 133 | nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.tx_pu << 8)); |
134 | return 0; | 134 | return 0; |
135 | } | 135 | } |
136 | 136 | ||
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c index 07cc2d527564..0055f869c507 100644 --- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c +++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c | |||
@@ -87,7 +87,7 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc) | |||
87 | struct nouveau_bios *bios = nouveau_bios(priv); | 87 | struct nouveau_bios *bios = nouveau_bios(priv); |
88 | const u32 shift = nvd0_sor_dp_lane_map(priv, ln); | 88 | const u32 shift = nvd0_sor_dp_lane_map(priv, ln); |
89 | const u32 loff = nvd0_sor_loff(outp); | 89 | const u32 loff = nvd0_sor_loff(outp); |
90 | u32 addr, data[3]; | 90 | u32 addr, data[4]; |
91 | u8 ver, hdr, cnt, len; | 91 | u8 ver, hdr, cnt, len; |
92 | struct nvbios_dpout info; | 92 | struct nvbios_dpout info; |
93 | struct nvbios_dpcfg ocfg; | 93 | struct nvbios_dpcfg ocfg; |
@@ -98,7 +98,7 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc) | |||
98 | if (!addr) | 98 | if (!addr) |
99 | return -ENODEV; | 99 | return -ENODEV; |
100 | 100 | ||
101 | addr = nvbios_dpcfg_match(bios, addr, 0, vs, pe, | 101 | addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe, |
102 | &ver, &hdr, &cnt, &len, &ocfg); | 102 | &ver, &hdr, &cnt, &len, &ocfg); |
103 | if (!addr) | 103 | if (!addr) |
104 | return -EINVAL; | 104 | return -EINVAL; |
@@ -106,10 +106,11 @@ nvd0_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc) | |||
106 | data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); | 106 | data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift); |
107 | data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); | 107 | data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift); |
108 | data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); | 108 | data[2] = nv_rd32(priv, 0x61c130 + loff) & ~(0x0000ff00); |
109 | nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.drv << shift)); | 109 | nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.dc << shift)); |
110 | nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pre << shift)); | 110 | nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pe << shift)); |
111 | nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.unk << 8)); | 111 | nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.tx_pu << 8)); |
112 | nv_mask(priv, 0x61c13c + loff, 0x00000000, 0x00000000); | 112 | data[3] = nv_rd32(priv, 0x61c13c + loff) & ~(0x000000ff << shift); |
113 | nv_wr32(priv, 0x61c13c + loff, data[3] | (ocfg.pc << shift)); | ||
113 | return 0; | 114 | return 0; |
114 | } | 115 | } |
115 | 116 | ||
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h index 6e54218b55fc..728206e21777 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/dp.h | |||
@@ -17,9 +17,10 @@ u16 nvbios_dpout_match(struct nouveau_bios *, u16 type, u16 mask, | |||
17 | struct nvbios_dpout *); | 17 | struct nvbios_dpout *); |
18 | 18 | ||
19 | struct nvbios_dpcfg { | 19 | struct nvbios_dpcfg { |
20 | u8 drv; | 20 | u8 pc; |
21 | u8 pre; | 21 | u8 dc; |
22 | u8 unk; | 22 | u8 pe; |
23 | u8 tx_pu; | ||
23 | }; | 24 | }; |
24 | 25 | ||
25 | u16 | 26 | u16 |
@@ -27,7 +28,7 @@ nvbios_dpcfg_parse(struct nouveau_bios *, u16 outp, u8 idx, | |||
27 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, | 28 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, |
28 | struct nvbios_dpcfg *); | 29 | struct nvbios_dpcfg *); |
29 | u16 | 30 | u16 |
30 | nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 un, u8 vs, u8 pe, | 31 | nvbios_dpcfg_match(struct nouveau_bios *, u16 outp, u8 pc, u8 vs, u8 pe, |
31 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, | 32 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, |
32 | struct nvbios_dpcfg *); | 33 | struct nvbios_dpcfg *); |
33 | 34 | ||
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c index 7628fe759220..f309dd657250 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c | |||
@@ -162,18 +162,20 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx, | |||
162 | struct nvbios_dpcfg *info) | 162 | struct nvbios_dpcfg *info) |
163 | { | 163 | { |
164 | u16 data = nvbios_dpcfg_entry(bios, outp, idx, ver, hdr, cnt, len); | 164 | u16 data = nvbios_dpcfg_entry(bios, outp, idx, ver, hdr, cnt, len); |
165 | memset(info, 0x00, sizeof(*info)); | ||
165 | if (data) { | 166 | if (data) { |
166 | switch (*ver) { | 167 | switch (*ver) { |
167 | case 0x21: | 168 | case 0x21: |
168 | info->drv = nv_ro08(bios, data + 0x02); | 169 | info->dc = nv_ro08(bios, data + 0x02); |
169 | info->pre = nv_ro08(bios, data + 0x03); | 170 | info->pe = nv_ro08(bios, data + 0x03); |
170 | info->unk = nv_ro08(bios, data + 0x04); | 171 | info->tx_pu = nv_ro08(bios, data + 0x04); |
171 | break; | 172 | break; |
172 | case 0x30: | 173 | case 0x30: |
173 | case 0x40: | 174 | case 0x40: |
174 | info->drv = nv_ro08(bios, data + 0x01); | 175 | info->pc = nv_ro08(bios, data + 0x00); |
175 | info->pre = nv_ro08(bios, data + 0x02); | 176 | info->dc = nv_ro08(bios, data + 0x01); |
176 | info->unk = nv_ro08(bios, data + 0x03); | 177 | info->pe = nv_ro08(bios, data + 0x02); |
178 | info->tx_pu = nv_ro08(bios, data + 0x03); | ||
177 | break; | 179 | break; |
178 | default: | 180 | default: |
179 | data = 0x0000; | 181 | data = 0x0000; |
@@ -184,7 +186,7 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx, | |||
184 | } | 186 | } |
185 | 187 | ||
186 | u16 | 188 | u16 |
187 | nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe, | 189 | nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe, |
188 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, | 190 | u8 *ver, u8 *hdr, u8 *cnt, u8 *len, |
189 | struct nvbios_dpcfg *info) | 191 | struct nvbios_dpcfg *info) |
190 | { | 192 | { |
@@ -193,16 +195,15 @@ nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 un, u8 vs, u8 pe, | |||
193 | 195 | ||
194 | if (*ver >= 0x30) { | 196 | if (*ver >= 0x30) { |
195 | const u8 vsoff[] = { 0, 4, 7, 9 }; | 197 | const u8 vsoff[] = { 0, 4, 7, 9 }; |
196 | idx = (un * 10) + vsoff[vs] + pe; | 198 | idx = (pc * 10) + vsoff[vs] + pe; |
197 | } else { | 199 | } else { |
198 | while ((data = nvbios_dpcfg_entry(bios, outp, idx, | 200 | while ((data = nvbios_dpcfg_entry(bios, outp, ++idx, |
199 | ver, hdr, cnt, len))) { | 201 | ver, hdr, cnt, len))) { |
200 | if (nv_ro08(bios, data + 0x00) == vs && | 202 | if (nv_ro08(bios, data + 0x00) == vs && |
201 | nv_ro08(bios, data + 0x01) == pe) | 203 | nv_ro08(bios, data + 0x01) == pe) |
202 | break; | 204 | break; |
203 | idx++; | ||
204 | } | 205 | } |
205 | } | 206 | } |
206 | 207 | ||
207 | return nvbios_dpcfg_parse(bios, outp, pe, ver, hdr, cnt, len, info); | 208 | return nvbios_dpcfg_parse(bios, outp, idx, ver, hdr, cnt, len, info); |
208 | } | 209 | } |