Commit 4a230fa6 authored by Ben Skeggs's avatar Ben Skeggs

drm/nvd0/disp: calculate U script id in supervisor interrupt

This is like we do on nv50:nvd9 already.  There's been no problems seen
yet with using this *seemingly* scratch register to store the value, but
we won't be able to do this anymore once nv50's code is merged.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent 8e9e3d2d
...@@ -656,6 +656,7 @@ nv50_disp_base_ofuncs = { ...@@ -656,6 +656,7 @@ nv50_disp_base_ofuncs = {
static struct nouveau_omthds static struct nouveau_omthds
nv50_disp_base_omthds[] = { nv50_disp_base_omthds[] = {
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
{}, {},
......
...@@ -35,6 +35,7 @@ struct nv50_disp_priv { ...@@ -35,6 +35,7 @@ struct nv50_disp_priv {
int (*dp_drvctl)(struct nv50_disp_priv *, int sor, int link, int (*dp_drvctl)(struct nv50_disp_priv *, int sor, int link,
int lane, u16 type, u16 mask, u32 data, int lane, u16 type, u16 mask, u32 data,
struct dcb_output *); struct dcb_output *);
u32 lvdsconf;
} sor; } sor;
}; };
......
...@@ -43,6 +43,7 @@ struct nouveau_omthds ...@@ -43,6 +43,7 @@ struct nouveau_omthds
nv84_disp_base_omthds[] = { nv84_disp_base_omthds[] = {
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
{ DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_PWR) , nv50_dac_mthd },
{ DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd }, { DAC_MTHD(NV50_DISP_DAC_LOAD) , nv50_dac_mthd },
{}, {},
......
...@@ -43,6 +43,7 @@ static struct nouveau_omthds ...@@ -43,6 +43,7 @@ static struct nouveau_omthds
nv94_disp_base_omthds[] = { nv94_disp_base_omthds[] = {
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
{ SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd },
{ SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd },
{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd },
......
...@@ -44,6 +44,7 @@ nva3_disp_base_omthds[] = { ...@@ -44,6 +44,7 @@ nva3_disp_base_omthds[] = {
{ SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV50_DISP_SOR_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd }, { SOR_MTHD(NVA3_DISP_SOR_HDA_ELD) , nv50_sor_mthd },
{ SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd }, { SOR_MTHD(NV84_DISP_SOR_HDMI_PWR) , nv50_sor_mthd },
{ SOR_MTHD(NV50_DISP_SOR_LVDS_SCRIPT) , nv50_sor_mthd },
{ SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_TRAIN) , nv50_sor_mthd },
{ SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_LNKCTL) , nv50_sor_mthd },
{ SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd }, { SOR_MTHD(NV94_DISP_SOR_DP_DRVCTL(0)), nv50_sor_mthd },
......
...@@ -634,38 +634,59 @@ exec_script(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, int id) ...@@ -634,38 +634,59 @@ exec_script(struct nv50_disp_priv *priv, int head, int outp, u32 ctrl, int id)
return false; return false;
} }
static bool static u32
exec_clkcmp(struct nv50_disp_priv *priv, int head, int outp, exec_clkcmp(struct nv50_disp_priv *priv, int head, int outp,
u32 ctrl, u32 conf, int id, u32 pclk) u32 ctrl, int id, u32 pclk)
{ {
struct nouveau_bios *bios = nouveau_bios(priv); struct nouveau_bios *bios = nouveau_bios(priv);
struct nvbios_outp info1; struct nvbios_outp info1;
struct nvbios_ocfg info2; struct nvbios_ocfg info2;
struct dcb_output dcb; struct dcb_output dcb;
u8 ver, hdr, cnt, len; u8 ver, hdr, cnt, len;
u16 data; u16 data, conf;
data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info1); data = exec_lookup(priv, head, outp, ctrl, &dcb, &ver, &hdr, &cnt, &len, &info1);
if (data == 0x0000)
return false;
switch (dcb.type) {
case DCB_OUTPUT_TMDS:
conf = (ctrl & 0x00000f00) >> 8;
if (pclk >= 165000)
conf |= 0x0100;
break;
case DCB_OUTPUT_LVDS:
conf = priv->sor.lvdsconf;
break;
case DCB_OUTPUT_DP:
conf = (ctrl & 0x00000f00) >> 8;
break;
case DCB_OUTPUT_ANALOG:
default:
conf = 0x00ff;
break;
}
data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2);
if (data) { if (data) {
data = nvbios_ocfg_match(bios, data, conf, &ver, &hdr, &cnt, &len, &info2); data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk);
if (data) { if (data) {
data = nvbios_oclk_match(bios, info2.clkcmp[id], pclk); struct nvbios_init init = {
if (data) { .subdev = nv_subdev(priv),
struct nvbios_init init = { .bios = bios,
.subdev = nv_subdev(priv), .offset = data,
.bios = bios, .outp = &dcb,
.offset = data, .crtc = head,
.outp = &dcb, .execute = 1,
.crtc = head, };
.execute = 1,
}; if (nvbios_exec(&init))
return 0x0000;
return nvbios_exec(&init) == 0; return conf;
}
} }
} }
return false; return 0x0000;
} }
static void static void
...@@ -747,10 +768,9 @@ nvd0_display_unk2_handler(struct nv50_disp_priv *priv, u32 head, u32 mask) ...@@ -747,10 +768,9 @@ nvd0_display_unk2_handler(struct nv50_disp_priv *priv, u32 head, u32 mask)
nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000); nv_wr32(priv, 0x612200 + (head * 0x800), 0x00000000);
for (i = 0; mask && i < 8; i++) { for (i = 0; mask && i < 8; i++) {
u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20)); u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20)), cfg;
u32 cfg = nv_rd32(priv, 0x660184 + (i * 0x20));
if (mcp & (1 << head)) { if (mcp & (1 << head)) {
if (exec_clkcmp(priv, head, i, mcp, cfg, 0, pclk)) { if ((cfg = exec_clkcmp(priv, head, i, mcp, 0, pclk))) {
u32 addr, mask, data = 0x00000000; u32 addr, mask, data = 0x00000000;
if (i < 4) { if (i < 4) {
addr = 0x612280 + ((i - 0) * 0x800); addr = 0x612280 + ((i - 0) * 0x800);
...@@ -790,9 +810,8 @@ nvd0_display_unk4_handler(struct nv50_disp_priv *priv, u32 head, u32 mask) ...@@ -790,9 +810,8 @@ nvd0_display_unk4_handler(struct nv50_disp_priv *priv, u32 head, u32 mask)
for (i = 0; mask && i < 8; i++) { for (i = 0; mask && i < 8; i++) {
u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20)); u32 mcp = nv_rd32(priv, 0x660180 + (i * 0x20));
u32 cfg = nv_rd32(priv, 0x660184 + (i * 0x20));
if (mcp & (1 << head)) if (mcp & (1 << head))
exec_clkcmp(priv, head, i, mcp, cfg, 1, pclk); exec_clkcmp(priv, head, i, mcp, 1, pclk);
} }
nv_wr32(priv, 0x6101d4, 0x00000000); nv_wr32(priv, 0x6101d4, 0x00000000);
......
...@@ -75,6 +75,10 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size) ...@@ -75,6 +75,10 @@ nv50_sor_mthd(struct nouveau_object *object, u32 mthd, void *args, u32 size)
case NV84_DISP_SOR_HDMI_PWR: case NV84_DISP_SOR_HDMI_PWR:
ret = priv->sor.hdmi(priv, head, or, data); ret = priv->sor.hdmi(priv, head, or, data);
break; break;
case NV50_DISP_SOR_LVDS_SCRIPT:
priv->sor.lvdsconf = data & NV50_DISP_SOR_LVDS_SCRIPT_ID;
ret = 0;
break;
case NV94_DISP_SOR_DP_TRAIN: case NV94_DISP_SOR_DP_TRAIN:
ret = priv->sor.dp_train(priv, or, link, type, mask, data, &outp); ret = priv->sor.dp_train(priv, or, link, type, mask, data, &outp);
break; break;
......
...@@ -188,6 +188,8 @@ struct nve0_channel_ind_class { ...@@ -188,6 +188,8 @@ struct nve0_channel_ind_class {
#define NV84_DISP_SOR_HDMI_PWR_STATE_ON 0x40000000 #define NV84_DISP_SOR_HDMI_PWR_STATE_ON 0x40000000
#define NV84_DISP_SOR_HDMI_PWR_MAX_AC_PACKET 0x001f0000 #define NV84_DISP_SOR_HDMI_PWR_MAX_AC_PACKET 0x001f0000
#define NV84_DISP_SOR_HDMI_PWR_REKEY 0x0000007f #define NV84_DISP_SOR_HDMI_PWR_REKEY 0x0000007f
#define NV50_DISP_SOR_LVDS_SCRIPT 0x00013000
#define NV50_DISP_SOR_LVDS_SCRIPT_ID 0x0000ffff
#define NV94_DISP_SOR_DP_TRAIN 0x00016000 #define NV94_DISP_SOR_DP_TRAIN 0x00016000
#define NV94_DISP_SOR_DP_TRAIN_PATTERN 0x00000003 #define NV94_DISP_SOR_DP_TRAIN_PATTERN 0x00000003
#define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED 0x00000000 #define NV94_DISP_SOR_DP_TRAIN_PATTERN_DISABLED 0x00000000
......
...@@ -1139,9 +1139,8 @@ nvd0_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode, ...@@ -1139,9 +1139,8 @@ nvd0_dac_mode_set(struct drm_encoder *encoder, struct drm_display_mode *mode,
evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2);
evo_data(push, syncs); evo_data(push, syncs);
evo_data(push, magic); evo_data(push, magic);
evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 2); evo_mthd(push, 0x0180 + (nv_encoder->or * 0x020), 1);
evo_data(push, 1 << nv_crtc->index); evo_data(push, 1 << nv_crtc->index);
evo_data(push, 0x00ff);
evo_kick(push, nvd0_mast(encoder->dev)); evo_kick(push, nvd0_mast(encoder->dev));
} }
...@@ -1440,12 +1439,14 @@ static void ...@@ -1440,12 +1439,14 @@ static void
nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
struct drm_display_mode *mode) struct drm_display_mode *mode)
{ {
struct nvd0_disp *disp = nvd0_disp(encoder->dev);
struct drm_device *dev = encoder->dev; struct drm_device *dev = encoder->dev;
struct nouveau_drm *drm = nouveau_drm(dev); struct nouveau_drm *drm = nouveau_drm(dev);
struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder); struct nouveau_encoder *nv_encoder = nouveau_encoder(encoder);
struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc); struct nouveau_crtc *nv_crtc = nouveau_crtc(encoder->crtc);
struct nouveau_connector *nv_connector; struct nouveau_connector *nv_connector;
struct nvbios *bios = &drm->vbios; struct nvbios *bios = &drm->vbios;
int or = nv_encoder->or;
u32 mode_ctrl = (1 << nv_crtc->index); u32 mode_ctrl = (1 << nv_crtc->index);
u32 syncs, magic, *push; u32 syncs, magic, *push;
u32 or_config; u32 or_config;
...@@ -1472,10 +1473,6 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, ...@@ -1472,10 +1473,6 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
mode_ctrl |= 0x00000200; mode_ctrl |= 0x00000200;
} }
or_config = (mode_ctrl & 0x00000f00) >> 8;
if (mode->clock >= 165000)
or_config |= 0x0100;
nvd0_hdmi_mode_set(encoder, mode); nvd0_hdmi_mode_set(encoder, mode);
break; break;
case DCB_OUTPUT_LVDS: case DCB_OUTPUT_LVDS:
...@@ -1504,8 +1501,9 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, ...@@ -1504,8 +1501,9 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
if (nv_connector->base.display_info.bpc == 8) if (nv_connector->base.display_info.bpc == 8)
or_config |= 0x0200; or_config |= 0x0200;
} }
nv_call(disp->core, NV50_DISP_SOR_LVDS_SCRIPT + or, or_config);
break; break;
case DCB_OUTPUT_DP: case DCB_OUTPUT_DP:
if (nv_connector->base.display_info.bpc == 6) { if (nv_connector->base.display_info.bpc == 6) {
...@@ -1520,8 +1518,6 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, ...@@ -1520,8 +1518,6 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
mode_ctrl |= 0x00000800; mode_ctrl |= 0x00000800;
else else
mode_ctrl |= 0x00000900; mode_ctrl |= 0x00000900;
or_config = (mode_ctrl & 0x00000f00) >> 8;
break; break;
default: default:
BUG_ON(1); BUG_ON(1);
...@@ -1535,9 +1531,8 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode, ...@@ -1535,9 +1531,8 @@ nvd0_sor_mode_set(struct drm_encoder *encoder, struct drm_display_mode *umode,
evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2); evo_mthd(push, 0x0404 + (nv_crtc->index * 0x300), 2);
evo_data(push, syncs); evo_data(push, syncs);
evo_data(push, magic); evo_data(push, magic);
evo_mthd(push, 0x0200 + (nv_encoder->or * 0x020), 2); evo_mthd(push, 0x0200 + (nv_encoder->or * 0x020), 1);
evo_data(push, mode_ctrl); evo_data(push, mode_ctrl);
evo_data(push, or_config);
evo_kick(push, nvd0_mast(dev)); evo_kick(push, nvd0_mast(dev));
} }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment