30 #define NOUVEAU_DMA_DEBUG (nouveau_reg_debug & NOUVEAU_REG_DEBUG_EVO)
45 static const u8 nvaf[] = { 24, 16, 8, 0 };
46 static const u8 nv50[] = { 16, 8, 0, 24 };
47 if (nv_device(drm->
device)->chipset == 0xaf)
62 u8 lane,
u8 swing,
u8 preem)
67 u32 shift = nv50_sor_dp_lane_map(dev, dcb, lane);
72 if (!table || (table[0] != 0x20 && table[0] != 0x21)) {
73 NV_ERROR(drm,
"PDISP: unsupported DP table for chipset\n");
77 config = entry + table[4];
78 while (config[0] != swing || config[1] != preem) {
80 if (config >= entry + table[4] + entry[4] * table[5])
91 int link_nr,
u32 link_bw,
bool enhframe)
97 u32 clksor = nv_rd32(device, 0x614300 + (or * 0x800)) & ~0x000c0000;
102 if (!table || (table[0] != 0x20 && table[0] != 0x21)) {
103 NV_ERROR(drm,
"PDISP: unsupported DP table for chipset\n");
107 entry =
ROMPTR(dev, entry[10]);
109 while (link_bw <
ROM16(entry[0]) * 10)
112 nouveau_bios_run_init_table(dev,
ROM16(entry[2]), dcb, crtc);
115 dpctrl |= ((1 << link_nr) - 1) << 16;
117 dpctrl |= 0x00004000;
119 if (link_bw > 162000)
120 clksor |= 0x00040000;
122 nv_wr32(device, 0x614300 + (or * 0x800), clksor);
126 for (i = 0; i < link_nr; i++)
127 mask |= 1 << (nv50_sor_dp_lane_map(dev, dcb, i) >> 3);
136 u32 clksor = nv_rd32(device, 0x614300 + (or * 0x800));
137 if (clksor & 0x000c0000)
142 if (dpctrl > 0x00030000) *nr = 4;
143 else if (dpctrl > 0x00010000) *nr = 2;
153 int bestTU = 0, bestVTUi = 0, bestVTUf = 0, bestVTUa = 0;
154 int TU, VTUi, VTUf, VTUa;
155 u64 link_data_rate, link_ratio,
unk;
156 u32 best_diff = 64 * symbol;
157 u32 link_nr, link_bw,
r;
160 nv50_sor_dp_link_get(dev, or, link, &link_nr, &link_bw);
161 link_data_rate = (clk * bpp / 8) / link_nr;
164 link_ratio = link_data_rate * symbol;
165 r =
do_div(link_ratio, link_bw);
167 for (TU = 64; TU >= 32; TU--) {
169 u32 tu_valid = link_ratio * TU;
173 VTUi = tu_valid / symbol;
174 calc = VTUi * symbol;
175 diff = tu_valid - calc;
177 if (diff >= (symbol / 2)) {
178 VTUf = symbol / (symbol - diff);
179 if (symbol - (VTUf * diff))
184 calc += symbol - (symbol / VTUf);
192 VTUf =
min((
int)(symbol / diff), 15);
193 calc += symbol / VTUf;
196 diff = calc - tu_valid;
207 if (diff < best_diff) {
219 NV_ERROR(drm,
"DP: unable to find suitable config\n");
224 unk = (symbol - link_ratio) * bestTU;
245 if (!nv_encoder->
crtc)
249 NV_DEBUG(drm,
"Disconnecting SOR %d\n", nv_encoder->
or);
251 ret = RING_SPACE(evo, 4);
253 NV_ERROR(drm,
"no space while disconnecting SOR\n");
276 int or = nv_encoder->
or;
278 NV_DEBUG(drm,
"or %d type %d mode %d\n", or, nv_encoder->
dcb->type, mode);
284 if (nvenc == nv_encoder ||
288 nvenc->
dcb->or != nv_encoder->
dcb->or)
298 NV_ERROR(drm,
"timeout: SOR_DPMS_CTRL_PENDING(%d) == 0\n", or);
299 NV_ERROR(drm,
"SOR_DPMS_CTRL(%d) = 0x%08x\n", or,
314 NV_ERROR(drm,
"timeout: SOR_DPMS_STATE_WAIT(%d) == 0\n", or);
315 NV_ERROR(drm,
"SOR_DPMS_STATE(%d) = 0x%08x\n", or,
321 .link_set = nv50_sor_dp_link_set,
322 .train_set = nv50_sor_dp_train_set,
323 .train_adj = nv50_sor_dp_train_adj
357 NV_ERROR(drm,
"Encoder has no connector\n");
372 nv50_sor_disconnect(encoder);
396 NV_DEBUG(drm,
"or %d type %d -> crtc %d\n",
397 nv_encoder->
or, nv_encoder->
dcb->type, crtc->
index);
400 switch (nv_encoder->
dcb->type) {
402 if (nv_encoder->
dcb->sorconf.link & 1) {
403 if (mode->
clock < 165000)
414 if (nv_connector && nv_connector->
base.display_info.bpc == 6) {
415 nv_encoder->
dp.datarate = mode->
clock * 18 / 8;
416 mode_ctl |= 0x00020000;
418 nv_encoder->
dp.datarate = mode->
clock * 24 / 8;
419 mode_ctl |= 0x00050000;
422 if (nv_encoder->
dcb->sorconf.link & 1)
423 mode_ctl |= 0x00000800;
425 mode_ctl |= 0x00000900;
431 if (crtc->
index == 1)
444 ret = RING_SPACE(evo, 2);
446 NV_ERROR(drm,
"no space while connecting SOR\n");
461 .dpms = nv50_sor_dpms,
462 .save = nv50_sor_save,
463 .restore = nv50_sor_restore,
464 .mode_fixup = nv50_sor_mode_fixup,
465 .prepare = nv50_sor_prepare,
466 .commit = nv50_sor_commit,
467 .mode_set = nv50_sor_mode_set,
468 .get_crtc = nv50_sor_crtc_get,
470 .disable = nv50_sor_disconnect
487 .destroy = nv50_sor_destroy,
501 switch (entry->
type) {
513 nv_encoder = kzalloc(
sizeof(*nv_encoder),
GFP_KERNEL);
516 encoder = to_drm_encoder(nv_encoder);
519 nv_encoder->
or =
ffs(entry->
or) - 1;
523 drm_encoder_helper_add(encoder, &nv50_sor_helper_funcs);