diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2014-03-19 02:56:29 +1000 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2014-03-26 14:08:19 +1000 |
commit | 3219adc29ccb1706de4f1453d0386c5a2487ab14 (patch) | |
tree | 4aec385652f284f90bcaf7e8b4f9d3e1928ae7e8 /drivers/gpu/drm/nouveau | |
parent | 0a8649f1c607d444b658061151ae5cdf648adcf2 (diff) |
drm/nouveau/devinit: add interface to check if a mmio access by scripts is ok
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau')
4 files changed, 11 insertions, 3 deletions
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h index 413bc54071c..e292271a84e 100644 --- a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h +++ b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h @@ -9,6 +9,7 @@ struct nouveau_devinit { bool post; void (*meminit)(struct nouveau_devinit *); int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq); + u32 (*mmio)(struct nouveau_devinit *, u32 addr); }; static inline struct nouveau_devinit * diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c index a29c18617c5..acaeaf79e3f 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c +++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c @@ -118,6 +118,8 @@ init_conn(struct nvbios_init *init) static inline u32 init_nvreg(struct nvbios_init *init, u32 reg) { + struct nouveau_devinit *devinit = nouveau_devinit(init->bios); + /* C51 (at least) sometimes has the lower bits set which the VBIOS * interprets to mean that access needs to go through certain IO * ports instead. The NVIDIA binary driver has been seen to access @@ -147,6 +149,9 @@ init_nvreg(struct nvbios_init *init, u32 reg) if (reg & ~0x00fffffc) warn("unknown bits in register 0x%08x\n", reg); + + if (devinit->mmio) + reg = devinit->mmio(devinit, reg); return reg; } @@ -154,7 +159,7 @@ static u32 init_rd32(struct nvbios_init *init, u32 reg) { reg = init_nvreg(init, reg); - if (init_exec(init)) + if (reg != ~0 && init_exec(init)) return nv_rd32(init->subdev, reg); return 0x00000000; } @@ -163,7 +168,7 @@ static void init_wr32(struct nvbios_init *init, u32 reg, u32 val) { reg = init_nvreg(init, reg); - if (init_exec(init)) + if (reg != ~0 && init_exec(init)) nv_wr32(init->subdev, reg, val); } @@ -171,7 +176,7 @@ static u32 init_mask(struct nvbios_init *init, u32 reg, u32 mask, u32 val) { reg = init_nvreg(init, reg); - if (init_exec(init)) { + if (reg != ~0 && init_exec(init)) { u32 tmp = nv_rd32(init->subdev, reg); nv_wr32(init->subdev, reg, (tmp & ~mask) | val); return tmp; diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c index 8fa34e8152c..239acfe876c 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c @@ -96,5 +96,6 @@ nouveau_devinit_create_(struct nouveau_object *parent, devinit->post = nouveau_boolopt(device->cfgopt, "NvForcePost", false); devinit->meminit = impl->meminit; devinit->pll_set = impl->pll_set; + devinit->mmio = impl->mmio; return 0; } diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h index 822a2fbf44a..f0e8683ad84 100644 --- a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h +++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h @@ -11,6 +11,7 @@ struct nouveau_devinit_impl { void (*meminit)(struct nouveau_devinit *); int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq); u64 (*disable)(struct nouveau_devinit *); + u32 (*mmio)(struct nouveau_devinit *, u32); }; #define nouveau_devinit_create(p,e,o,d) \ |