diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-05-26 11:57:57 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-06-11 16:02:09 +1000 |
commit | cca2e9b7ce23bf9475f0885fc158112c42b3c4a1 (patch) | |
tree | 7a15e1da1fc8d772c44436521670ddac5d2a9ec0 /nvkm/engine/disp | |
parent | 1a71aeab0905261c014ecb7f833105ff98fe9360 (diff) | |
download | nouveau-cca2e9b7ce23bf9475f0885fc158112c42b3c4a1.tar.gz |
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: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'nvkm/engine/disp')
-rw-r--r-- | nvkm/engine/disp/dport.c | 2 | ||||
-rw-r--r-- | nvkm/engine/disp/nv50.h | 1 | ||||
-rw-r--r-- | nvkm/engine/disp/outpdp.h | 1 | ||||
-rw-r--r-- | nvkm/engine/disp/piornv50.c | 7 | ||||
-rw-r--r-- | nvkm/engine/disp/sornv94.c | 22 | ||||
-rw-r--r-- | nvkm/engine/disp/sornvd0.c | 8 |
6 files changed, 29 insertions, 12 deletions
diff --git a/nvkm/engine/disp/dport.c b/nvkm/engine/disp/dport.c index efccbabca..5d4b03480 100644 --- a/nvkm/engine/disp/dport.c +++ b/nvkm/engine/disp/dport.c @@ -94,6 +94,8 @@ dp_set_link_config(struct dp_state *dp) return ret; } + impl->lnk_pwr(outp, dp->link_nr); + /* set desired link configuration on the sink */ sink[0] = dp->link_bw / 27000; sink[1] = dp->link_nr; diff --git a/nvkm/engine/disp/nv50.h b/nvkm/engine/disp/nv50.h index 67ad3f1f8..1a886472b 100644 --- a/nvkm/engine/disp/nv50.h +++ b/nvkm/engine/disp/nv50.h @@ -203,6 +203,7 @@ extern struct nvkm_output_dp_impl nv50_pior_dp_impl; extern struct nouveau_oclass *nv50_disp_outp_sclass[]; 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 nvkm_output_dp_impl nvd0_sor_dp_impl; diff --git a/nvkm/engine/disp/outpdp.h b/nvkm/engine/disp/outpdp.h index ab328dcad..4c32cf534 100644 --- a/nvkm/engine/disp/outpdp.h +++ b/nvkm/engine/disp/outpdp.h @@ -49,6 +49,7 @@ int _nvkm_output_dp_fini(struct nouveau_object *, bool); struct nvkm_output_dp_impl { struct nvkm_output_impl base; 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 (*drv_ctl)(struct nvkm_output_dp *, int ln, int vs, int pe, int pc); }; diff --git a/nvkm/engine/disp/piornv50.c b/nvkm/engine/disp/piornv50.c index 491e4d83b..fe0f256f1 100644 --- a/nvkm/engine/disp/piornv50.c +++ b/nvkm/engine/disp/piornv50.c @@ -80,6 +80,12 @@ nv50_pior_dp_pattern(struct nvkm_output_dp *outp, int pattern) } static int +nv50_pior_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr) +{ + return 0; +} + +static int nv50_pior_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) { struct nouveau_i2c_port *port = outp->base.edid; @@ -127,6 +133,7 @@ nv50_pior_dp_impl = { .fini = _nvkm_output_dp_fini, }, .pattern = nv50_pior_dp_pattern, + .lnk_pwr = nv50_pior_dp_lnk_pwr, .lnk_ctl = nv50_pior_dp_lnk_ctl, .drv_ctl = nv50_pior_dp_drv_ctl, }; diff --git a/nvkm/engine/disp/sornv94.c b/nvkm/engine/disp/sornv94.c index 5ee9a12be..95d8c53d3 100644 --- a/nvkm/engine/disp/sornv94.c +++ b/nvkm/engine/disp/sornv94.c @@ -29,6 +29,7 @@ #include <subdev/bios/dcb.h> #include <subdev/bios/dp.h> #include <subdev/bios/init.h> +#include <subdev/timer.h> #include "nv50.h" #include "outpdp.h" @@ -64,6 +65,20 @@ nv94_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern) 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 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); u32 dpctrl = 0x00000000; u32 clksor = 0x00000000; - u32 lane = 0; - int i; dpctrl |= ((1 << nr) - 1) << 16; if (ef) @@ -81,12 +94,8 @@ nv94_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) if (bw > 0x06) 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, 0x61c10c + loff, 0x001f4000, dpctrl); - nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane); return 0; } @@ -132,6 +141,7 @@ nv94_sor_dp_impl = { .fini = _nvkm_output_dp_fini, }, .pattern = nv94_sor_dp_pattern, + .lnk_pwr = nv94_sor_dp_lnk_pwr, .lnk_ctl = nv94_sor_dp_lnk_ctl, .drv_ctl = nv94_sor_dp_drv_ctl, }; diff --git a/nvkm/engine/disp/sornvd0.c b/nvkm/engine/disp/sornvd0.c index c3120a762..07cc2d527 100644 --- a/nvkm/engine/disp/sornvd0.c +++ b/nvkm/engine/disp/sornvd0.c @@ -29,6 +29,7 @@ #include <subdev/bios/dcb.h> #include <subdev/bios/dp.h> #include <subdev/bios/init.h> +#include <subdev/timer.h> #include "nv50.h" @@ -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); u32 dpctrl = 0x00000000; u32 clksor = 0x00000000; - u32 lane = 0; - int i; clksor |= bw << 18; dpctrl |= ((1 << nr) - 1) << 16; if (ef) 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, 0x61c10c + loff, 0x001f4000, dpctrl); - nv_mask(priv, 0x61c130 + loff, 0x0000000f, lane); return 0; } @@ -128,6 +123,7 @@ nvd0_sor_dp_impl = { .fini = _nvkm_output_dp_fini, }, .pattern = nvd0_sor_dp_pattern, + .lnk_pwr = nv94_sor_dp_lnk_pwr, .lnk_ctl = nvd0_sor_dp_lnk_ctl, .drv_ctl = nvd0_sor_dp_drv_ctl, }; |