Commit 1ecee1cd authored by Ben Skeggs's avatar Ben Skeggs

drm/nouveau/disp/dp: split link config/power into two steps

We want to be able to power down the lanes for DPMS off.
Signed-off-by: default avatarBen Skeggs <bskeggs@redhat.com>
parent b17932c0
...@@ -94,6 +94,8 @@ dp_set_link_config(struct dp_state *dp) ...@@ -94,6 +94,8 @@ dp_set_link_config(struct dp_state *dp)
return ret; return ret;
} }
impl->lnk_pwr(outp, dp->link_nr);
/* set desired link configuration on the sink */ /* set desired link configuration on the sink */
sink[0] = dp->link_bw / 27000; sink[0] = dp->link_bw / 27000;
sink[1] = dp->link_nr; sink[1] = dp->link_nr;
......
...@@ -203,6 +203,7 @@ extern struct nvkm_output_dp_impl nv50_pior_dp_impl; ...@@ -203,6 +203,7 @@ extern struct nvkm_output_dp_impl nv50_pior_dp_impl;
extern struct nouveau_oclass *nv50_disp_outp_sclass[]; extern struct nouveau_oclass *nv50_disp_outp_sclass[];
extern struct nvkm_output_dp_impl nv94_sor_dp_impl; extern struct nvkm_output_dp_impl nv94_sor_dp_impl;
int nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int);
extern struct nouveau_oclass *nv94_disp_outp_sclass[]; extern struct nouveau_oclass *nv94_disp_outp_sclass[];
extern struct nvkm_output_dp_impl nvd0_sor_dp_impl; extern struct nvkm_output_dp_impl nvd0_sor_dp_impl;
......
...@@ -49,6 +49,7 @@ int _nvkm_output_dp_fini(struct nouveau_object *, bool); ...@@ -49,6 +49,7 @@ int _nvkm_output_dp_fini(struct nouveau_object *, bool);
struct nvkm_output_dp_impl { struct nvkm_output_dp_impl {
struct nvkm_output_impl base; struct nvkm_output_impl base;
int (*pattern)(struct nvkm_output_dp *, int); int (*pattern)(struct nvkm_output_dp *, int);
int (*lnk_pwr)(struct nvkm_output_dp *, int nr);
int (*lnk_ctl)(struct nvkm_output_dp *, int nr, int bw, bool ef); int (*lnk_ctl)(struct nvkm_output_dp *, int nr, int bw, bool ef);
int (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc); int (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc);
}; };
......
...@@ -79,6 +79,12 @@ nv50_pior_dp_pattern(struct nvkm_output_dp *outp, int pattern) ...@@ -79,6 +79,12 @@ nv50_pior_dp_pattern(struct nvkm_output_dp *outp, int pattern)
return port ? 0 : -ENODEV; return port ? 0 : -ENODEV;
} }
static int
nv50_pior_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
{
return 0;
}
static int static int
nv50_pior_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) nv50_pior_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
{ {
...@@ -127,6 +133,7 @@ nv50_pior_dp_impl = { ...@@ -127,6 +133,7 @@ nv50_pior_dp_impl = {
.fini = _nvkm_output_dp_fini, .fini = _nvkm_output_dp_fini,
}, },
.pattern = nv50_pior_dp_pattern, .pattern = nv50_pior_dp_pattern,
.lnk_pwr = nv50_pior_dp_lnk_pwr,
.lnk_ctl = nv50_pior_dp_lnk_ctl, .lnk_ctl = nv50_pior_dp_lnk_ctl,
.drv_ctl = nv50_pior_dp_drv_ctl, .drv_ctl = nv50_pior_dp_drv_ctl,
}; };
......
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h> #include <subdev/bios/dp.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
#include <subdev/timer.h>
#include "nv50.h" #include "nv50.h"
#include "outpdp.h" #include "outpdp.h"
...@@ -64,6 +65,20 @@ nv94_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) ...@@ -64,6 +65,20 @@ nv94_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
return 0; return 0;
} }
int
nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
{
struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
const u32 loff = nv94_sor_loff(outp);
u32 mask = 0, i;
for (i = 0; i < nr; i++)
mask |= 1 << (nv94_sor_dp_lane_map(priv, i) >> 3);
nv_mask(priv, 0x61c130 + loff, 0x0000000f, mask);
return 0;
}
static int static int
nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
{ {
...@@ -72,8 +87,6 @@ nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) ...@@ -72,8 +87,6 @@ nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
const u32 loff = nv94_sor_loff(outp); const u32 loff = nv94_sor_loff(outp);
u32 dpctrl = 0x00000000; u32 dpctrl = 0x00000000;
u32 clksor = 0x00000000; u32 clksor = 0x00000000;
u32 lane = 0;
int i;
dpctrl |= ((1 << nr) - 1) << 16; dpctrl |= ((1 << nr) - 1) << 16;
if (ef) if (ef)
...@@ -81,12 +94,8 @@ nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) ...@@ -81,12 +94,8 @@ nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
if (bw > 0x06) if (bw > 0x06)
clksor |= 0x00040000; clksor |= 0x00040000;
for (i = 0; i < nr; i++)
lane |= 1 << (nv94_sor_dp_lane_map(priv, i) >> 3);
nv_mask(priv, 0x614300 + soff, 0x000c0000, clksor); nv_mask(priv, 0x614300 + soff, 0x000c0000, clksor);
nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl); nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl);
nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane);
return 0; return 0;
} }
...@@ -132,6 +141,7 @@ nv94_sor_dp_impl = { ...@@ -132,6 +141,7 @@ nv94_sor_dp_impl = {
.fini = _nvkm_output_dp_fini, .fini = _nvkm_output_dp_fini,
}, },
.pattern = nv94_sor_dp_pattern, .pattern = nv94_sor_dp_pattern,
.lnk_pwr = nv94_sor_dp_lnk_pwr,
.lnk_ctl = nv94_sor_dp_lnk_ctl, .lnk_ctl = nv94_sor_dp_lnk_ctl,
.drv_ctl = nv94_sor_dp_drv_ctl, .drv_ctl = nv94_sor_dp_drv_ctl,
}; };
...@@ -29,6 +29,7 @@ ...@@ -29,6 +29,7 @@
#include <subdev/bios/dcb.h> #include <subdev/bios/dcb.h>
#include <subdev/bios/dp.h> #include <subdev/bios/dp.h>
#include <subdev/bios/init.h> #include <subdev/bios/init.h>
#include <subdev/timer.h>
#include "nv50.h" #include "nv50.h"
...@@ -68,20 +69,14 @@ nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) ...@@ -68,20 +69,14 @@ nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
const u32 loff = nvd0_sor_loff(outp); const u32 loff = nvd0_sor_loff(outp);
u32 dpctrl = 0x00000000; u32 dpctrl = 0x00000000;
u32 clksor = 0x00000000; u32 clksor = 0x00000000;
u32 lane = 0;
int i;
clksor |= bw << 18; clksor |= bw << 18;
dpctrl |= ((1 << nr) - 1) << 16; dpctrl |= ((1 << nr) - 1) << 16;
if (ef) if (ef)
dpctrl |= 0x00004000; dpctrl |= 0x00004000;
for (i = 0; i < nr; i++)
lane |= 1 << (nvd0_sor_dp_lane_map(priv, i) >> 3);
nv_mask(priv, 0x612300 + soff, 0x007c0000, clksor); nv_mask(priv, 0x612300 + soff, 0x007c0000, clksor);
nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl); nv_mask(priv, 0x61c10c + loff, 0x001f4000, dpctrl);
nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane);
return 0; return 0;
} }
...@@ -128,6 +123,7 @@ nvd0_sor_dp_impl = { ...@@ -128,6 +123,7 @@ nvd0_sor_dp_impl = {
.fini = _nvkm_output_dp_fini, .fini = _nvkm_output_dp_fini,
}, },
.pattern = nvd0_sor_dp_pattern, .pattern = nvd0_sor_dp_pattern,
.lnk_pwr = nv94_sor_dp_lnk_pwr,
.lnk_ctl = nvd0_sor_dp_lnk_ctl, .lnk_ctl = nvd0_sor_dp_lnk_ctl,
.drv_ctl = nvd0_sor_dp_drv_ctl, .drv_ctl = nvd0_sor_dp_drv_ctl,
}; };
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