if (!data)
continue;
- ior->func->dp.drive(ior, i, ocfg.pc, ocfg.dc, ocfg.pe, ocfg.tx_pu);
+ ior->func->dp->drive(ior, i, ocfg.pc, ocfg.dc, ocfg.pe, ocfg.tx_pu);
}
if (lt->repeater)
u8 sink_tp;
OUTP_TRACE(outp, "training pattern %d", pattern);
- outp->ior->func->dp.pattern(outp->ior, pattern);
+ outp->ior->func->dp->pattern(outp->ior, pattern);
if (lt->repeater)
addr = DPCD_LTTPR_PATTERN_SET(lt->repeater);
);
}
- ret = ior->func->dp.links(ior, outp->dp.aux);
+ ret = ior->func->dp->links(ior, outp->dp.aux);
if (ret) {
if (ret < 0) {
OUTP_ERR(outp, "train failed with %d", ret);
return 0;
}
- ior->func->dp.power(ior, ior->dp.nr);
+ ior->func->dp->power(ior, ior->dp.nr);
/* Select LTTPR non-transparent mode if we have a valid configuration,
* use transparent mode otherwise.
{
struct nvkm_device *device = sor->disp->engine.subdev.device;
const u32 loff = nv50_sor_link(sor);
- const u32 shift = sor->func->dp.lanes[ln] * 8;
+ const u32 shift = sor->func->dp->lanes[ln] * 8;
u32 data[3];
data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
u32 mask = 0, i;
for (i = 0; i < nr; i++)
- mask |= 1 << sor->func->dp.lanes[i];
+ mask |= 1 << sor->func->dp->lanes[i];
nvkm_mask(device, 0x61c130 + loff, 0x0000000f, mask);
nvkm_mask(device, 0x61c034 + soff, 0x80000000, 0x80000000);
return 0;
}
+const struct nvkm_ior_func_dp
+g94_sor_dp = {
+ .lanes = { 2, 1, 0, 3},
+ .links = g94_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = g94_sor_dp_pattern,
+ .drive = g94_sor_dp_drive,
+ .audio_sym = g94_sor_dp_audio_sym,
+ .activesym = g94_sor_dp_activesym,
+ .watermark = g94_sor_dp_watermark,
+};
+
static bool
g94_sor_war_needed(struct nvkm_ior *sor)
{
.clock = nv50_sor_clock,
.war_2 = g94_sor_war_2,
.war_3 = g94_sor_war_3,
- .dp = {
- .lanes = { 2, 1, 0, 3},
- .links = g94_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = g94_sor_dp_pattern,
- .drive = g94_sor_dp_drive,
- .audio_sym = g94_sor_dp_audio_sym,
- .activesym = g94_sor_dp_activesym,
- .watermark = g94_sor_dp_watermark,
- },
+ .dp = &g94_sor_dp,
};
static int
return 0;
}
+static const struct nvkm_ior_func_dp
+ga102_sor_dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = ga102_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = tu102_sor_dp_vcpi,
+ .audio = gv100_sor_dp_audio,
+ .audio_sym = gv100_sor_dp_audio_sym,
+ .watermark = gv100_sor_dp_watermark,
+};
+
static void
ga102_sor_clock(struct nvkm_ior *sor)
{
.ctrl = gv100_sor_hdmi_ctrl,
.scdc = gm200_sor_hdmi_scdc,
},
- .dp = {
- .lanes = { 0, 1, 2, 3 },
- .links = ga102_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gm107_sor_dp_pattern,
- .drive = gm200_sor_dp_drive,
- .vcpi = tu102_sor_dp_vcpi,
- .audio = gv100_sor_dp_audio,
- .audio_sym = gv100_sor_dp_audio_sym,
- .watermark = gv100_sor_dp_watermark,
- },
+ .dp = &ga102_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,
{
struct nvkm_device *device = sor->disp->engine.subdev.device;
const u32 loff = nv50_sor_link(sor);
- const u32 shift = sor->func->dp.lanes[ln] * 8;
+ const u32 shift = sor->func->dp->lanes[ln] * 8;
u32 data[4];
data[0] = nvkm_rd32(device, 0x61c118 + loff) & ~(0x000000ff << shift);
nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
}
-void
+static void
gf119_sor_dp_pattern(struct nvkm_ior *sor, int pattern)
{
struct nvkm_device *device = sor->disp->engine.subdev.device;
return 0;
}
+const struct nvkm_ior_func_dp
+gf119_sor_dp = {
+ .lanes = { 2, 1, 0, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gf119_sor_dp_pattern,
+ .drive = gf119_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+};
+
static void
gf119_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
.hdmi = {
.ctrl = gf119_sor_hdmi_ctrl,
},
- .dp = {
- .lanes = { 2, 1, 0, 3 },
- .links = gf119_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gf119_sor_dp_pattern,
- .drive = gf119_sor_dp_drive,
- .vcpi = gf119_sor_dp_vcpi,
- .audio = gf119_sor_dp_audio,
- .audio_sym = gf119_sor_dp_audio_sym,
- .watermark = gf119_sor_dp_watermark,
- },
+ .dp = &gf119_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,
.hdmi = {
.ctrl = gk104_sor_hdmi_ctrl,
},
- .dp = {
- .lanes = { 2, 1, 0, 3 },
- .links = gf119_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gf119_sor_dp_pattern,
- .drive = gf119_sor_dp_drive,
- .vcpi = gf119_sor_dp_vcpi,
- .audio = gf119_sor_dp_audio,
- .audio_sym = gf119_sor_dp_audio_sym,
- .watermark = gf119_sor_dp_watermark,
- },
+ .dp = &gf119_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,
nvkm_mask(device, 0x61c12c + soff, mask, data);
}
+static const struct nvkm_ior_func_dp
+gm107_sor_dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gf119_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+};
+
static const struct nvkm_ior_func
gm107_sor = {
.state = gf119_sor_state,
.hdmi = {
.ctrl = gk104_sor_hdmi_ctrl,
},
- .dp = {
- .lanes = { 0, 1, 2, 3 },
- .links = gf119_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gm107_sor_dp_pattern,
- .drive = gf119_sor_dp_drive,
- .vcpi = gf119_sor_dp_vcpi,
- .audio = gf119_sor_dp_audio,
- .audio_sym = gf119_sor_dp_audio_sym,
- .watermark = gf119_sor_dp_watermark,
- },
+ .dp = &gm107_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,
{
struct nvkm_device *device = sor->disp->engine.subdev.device;
const u32 loff = nv50_sor_link(sor);
- const u32 shift = sor->func->dp.lanes[ln] * 8;
+ const u32 shift = sor->func->dp->lanes[ln] * 8;
u32 data[4];
pu &= 0x0f;
nvkm_wr32(device, 0x61c13c + loff, data[3] | (pc << shift));
}
+const struct nvkm_ior_func_dp
+gm200_sor_dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = gf119_sor_dp_vcpi,
+ .audio = gf119_sor_dp_audio,
+ .audio_sym = gf119_sor_dp_audio_sym,
+ .watermark = gf119_sor_dp_watermark,
+};
+
void
gm200_sor_hdmi_scdc(struct nvkm_ior *ior, u8 scdc)
{
.ctrl = gk104_sor_hdmi_ctrl,
.scdc = gm200_sor_hdmi_scdc,
},
- .dp = {
- .lanes = { 0, 1, 2, 3 },
- .links = gf119_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gm107_sor_dp_pattern,
- .drive = gm200_sor_dp_drive,
- .vcpi = gf119_sor_dp_vcpi,
- .audio = gf119_sor_dp_audio,
- .audio_sym = gf119_sor_dp_audio_sym,
- .watermark = gf119_sor_dp_watermark,
- },
+ .dp = &gm200_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,
.ctrl = gk104_sor_hdmi_ctrl,
.scdc = gm200_sor_hdmi_scdc,
},
- .dp = {
- .lanes = { 0, 1, 2, 3 },
- .links = gf119_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gm107_sor_dp_pattern,
- .drive = gm200_sor_dp_drive,
- .vcpi = gf119_sor_dp_vcpi,
- .audio = gf119_sor_dp_audio,
- .audio_sym = gf119_sor_dp_audio_sym,
- .watermark = gf119_sor_dp_watermark,
- },
+ .dp = &gm200_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,
);
}
+static const struct nvkm_ior_func_dp
+gt215_sor_dp = {
+ .lanes = { 2, 1, 0, 3 },
+ .links = g94_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = g94_sor_dp_pattern,
+ .drive = g94_sor_dp_drive,
+ .audio = gt215_sor_dp_audio,
+ .audio_sym = g94_sor_dp_audio_sym,
+ .activesym = g94_sor_dp_activesym,
+ .watermark = g94_sor_dp_watermark,
+};
+
void
gt215_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
.hdmi = {
.ctrl = gt215_sor_hdmi_ctrl,
},
- .dp = {
- .lanes = { 2, 1, 0, 3 },
- .links = g94_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = g94_sor_dp_pattern,
- .drive = g94_sor_dp_drive,
- .audio = gt215_sor_dp_audio,
- .audio_sym = g94_sor_dp_audio_sym,
- .activesym = g94_sor_dp_activesym,
- .watermark = g94_sor_dp_watermark,
- },
+ .dp = >215_sor_dp,
.hda = {
.hpd = gt215_sor_hda_hpd,
.eld = gt215_sor_hda_eld,
);
}
+static const struct nvkm_ior_func_dp
+gv100_sor_dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = gf119_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .audio = gv100_sor_dp_audio,
+ .audio_sym = gv100_sor_dp_audio_sym,
+ .watermark = gv100_sor_dp_watermark,
+};
+
void
gv100_sor_hdmi_ctrl(struct nvkm_ior *ior, int head, bool enable, u8 max_ac_packet,
u8 rekey, u8 *avi, u8 avi_size, u8 *vendor, u8 vendor_size)
.ctrl = gv100_sor_hdmi_ctrl,
.scdc = gm200_sor_hdmi_scdc,
},
- .dp = {
- .lanes = { 0, 1, 2, 3 },
- .links = gf119_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gm107_sor_dp_pattern,
- .drive = gm200_sor_dp_drive,
- .audio = gv100_sor_dp_audio,
- .audio_sym = gv100_sor_dp_audio_sym,
- .watermark = gv100_sor_dp_watermark,
- },
+ .dp = &gv100_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,
void (*scdc)(struct nvkm_ior *, u8 scdc);
} hdmi;
- struct {
+ const struct nvkm_ior_func_dp {
u8 lanes[4];
int (*links)(struct nvkm_ior *, struct nvkm_i2c_aux *);
void (*power)(struct nvkm_ior *, int nr);
void (*activesym)(struct nvkm_ior *, int head,
u8 TU, u8 VTUa, u8 VTUf, u8 VTUi);
void (*watermark)(struct nvkm_ior *, int head, u8 watermark);
- } dp;
+ } *dp;
struct {
void (*hpd)(struct nvkm_ior *, int head, bool present);
int g94_sor_cnt(struct nvkm_disp *, unsigned long *);
void g94_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
+extern const struct nvkm_ior_func_dp g94_sor_dp;
int g94_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *);
void g94_sor_dp_power(struct nvkm_ior *, int);
void g94_sor_dp_pattern(struct nvkm_ior *, int);
int gf119_sor_cnt(struct nvkm_disp *, unsigned long *);
void gf119_sor_state(struct nvkm_ior *, struct nvkm_ior_state *);
void gf119_sor_clock(struct nvkm_ior *);
+extern const struct nvkm_ior_func_dp gf119_sor_dp;
int gf119_sor_dp_links(struct nvkm_ior *, struct nvkm_i2c_aux *);
-void gf119_sor_dp_pattern(struct nvkm_ior *, int);
void gf119_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int);
void gf119_sor_dp_vcpi(struct nvkm_ior *, int, u8, u8, u16, u16);
void gf119_sor_dp_audio(struct nvkm_ior *, int, bool);
void gm200_sor_route_set(struct nvkm_outp *, struct nvkm_ior *);
int gm200_sor_route_get(struct nvkm_outp *, int *);
void gm200_sor_hdmi_scdc(struct nvkm_ior *, u8);
+extern const struct nvkm_ior_func_dp gm200_sor_dp;
void gm200_sor_dp_drive(struct nvkm_ior *, int, int, int, int, int);
int gp100_sor_new(struct nvkm_disp *, int);
.hdmi = {
.ctrl = g84_sor_hdmi_ctrl,
},
- .dp = {
- .lanes = { 2, 1, 0, 3},
- .links = g94_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = g94_sor_dp_pattern,
- .drive = g94_sor_dp_drive,
- .audio_sym = g94_sor_dp_audio_sym,
- .activesym = g94_sor_dp_activesym,
- .watermark = g94_sor_dp_watermark,
- },
+ .dp = &g94_sor_dp,
};
static int
#include <nvif/class.h>
+static const struct nvkm_ior_func_dp
+mcp89_sor_dp = {
+ .lanes = { 3, 2, 1, 0 },
+ .links = g94_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = g94_sor_dp_pattern,
+ .drive = g94_sor_dp_drive,
+ .audio = gt215_sor_dp_audio,
+ .audio_sym = g94_sor_dp_audio_sym,
+ .activesym = g94_sor_dp_activesym,
+ .watermark = g94_sor_dp_watermark,
+};
+
static const struct nvkm_ior_func
mcp89_sor = {
.state = g94_sor_state,
.hdmi = {
.ctrl = gt215_sor_hdmi_ctrl,
},
- .dp = {
- .lanes = { 3, 2, 1, 0 },
- .links = g94_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = g94_sor_dp_pattern,
- .drive = g94_sor_dp_drive,
- .audio = gt215_sor_dp_audio,
- .audio_sym = g94_sor_dp_audio_sym,
- .activesym = g94_sor_dp_activesym,
- .watermark = g94_sor_dp_watermark,
- },
+ .dp = &mcp89_sor_dp,
.hda = {
.hpd = gt215_sor_hda_hpd,
.eld = gt215_sor_hda_eld,
return 1;
}
+static const struct nvkm_ior_func_dp
+nv50_pior_dp = {
+ .links = nv50_pior_dp_links,
+};
+
static void
nv50_pior_power_wait(struct nvkm_device *device, u32 poff)
{
.state = nv50_pior_state,
.power = nv50_pior_power,
.clock = nv50_pior_clock,
- .dp = {
- .links = nv50_pior_dp_links,
- },
+ .dp = &nv50_pior_dp,
};
int
do_div(v, khz);
v = v - ((36 / ior->dp.nr) + 3) - 1;
- ior->func->dp.audio_sym(ior, head->id, h, v);
+ ior->func->dp->audio_sym(ior, head->id, h, v);
/* watermark / activesym */
link_data_rate = (khz * head->asy.or.depth / 8) / ior->dp.nr;
link_ratio = link_data_rate * symbol;
do_div(link_ratio, linkKBps);
- for (TU = 64; ior->func->dp.activesym && TU >= 32; TU--) {
+ for (TU = 64; ior->func->dp->activesym && TU >= 32; TU--) {
/* calculate average number of valid symbols in each TU */
u32 tu_valid = link_ratio * TU;
u32 calc, diff;
}
}
- if (ior->func->dp.activesym) {
+ if (ior->func->dp->activesym) {
if (!bestTU) {
nvkm_error(subdev, "unable to determine dp config\n");
return;
}
- ior->func->dp.activesym(ior, head->id, bestTU,
- bestVTUa, bestVTUf, bestVTUi);
+
+ ior->func->dp->activesym(ior, head->id, bestTU, bestVTUa, bestVTUf, bestVTUi);
} else {
bestTU = 64;
}
do_div(unk, symbol);
unk += 6;
- ior->func->dp.watermark(ior, head->id, unk);
+ ior->func->dp->watermark(ior, head->id, unk);
}
void
if (size && args->v0.data[0]) {
if (outp->info.type == DCB_OUTPUT_DP)
- ior->func->dp.audio(ior, hidx, true);
+ ior->func->dp->audio(ior, hidx, true);
ior->func->hda.hpd(ior, hidx, true);
ior->func->hda.eld(ior, hidx, data, size);
} else {
if (outp->info.type == DCB_OUTPUT_DP)
- ior->func->dp.audio(ior, hidx, false);
+ ior->func->dp->audio(ior, hidx, false);
ior->func->hda.hpd(ior, hidx, false);
}
args->v0.version, args->v0.start_slot,
args->v0.num_slots, args->v0.pbn,
args->v0.aligned_pbn);
- if (!outp->ior->func->dp.vcpi)
+ if (!outp->ior->func->dp->vcpi)
return -ENODEV;
- outp->ior->func->dp.vcpi(outp->ior, hidx,
+ outp->ior->func->dp->vcpi(outp->ior, hidx,
args->v0.start_slot,
args->v0.num_slots,
args->v0.pbn,
return 0;
}
+static const struct nvkm_ior_func_dp
+tu102_sor_dp = {
+ .lanes = { 0, 1, 2, 3 },
+ .links = tu102_sor_dp_links,
+ .power = g94_sor_dp_power,
+ .pattern = gm107_sor_dp_pattern,
+ .drive = gm200_sor_dp_drive,
+ .vcpi = tu102_sor_dp_vcpi,
+ .audio = gv100_sor_dp_audio,
+ .audio_sym = gv100_sor_dp_audio_sym,
+ .watermark = gv100_sor_dp_watermark,
+};
+
static const struct nvkm_ior_func
tu102_sor = {
.route = {
.ctrl = gv100_sor_hdmi_ctrl,
.scdc = gm200_sor_hdmi_scdc,
},
- .dp = {
- .lanes = { 0, 1, 2, 3 },
- .links = tu102_sor_dp_links,
- .power = g94_sor_dp_power,
- .pattern = gm107_sor_dp_pattern,
- .drive = gm200_sor_dp_drive,
- .vcpi = tu102_sor_dp_vcpi,
- .audio = gv100_sor_dp_audio,
- .audio_sym = gv100_sor_dp_audio_sym,
- .watermark = gv100_sor_dp_watermark,
- },
+ .dp = &tu102_sor_dp,
.hda = {
.hpd = gf119_sor_hda_hpd,
.eld = gf119_sor_hda_eld,