From 3219adc29ccb1706de4f1453d0386c5a2487ab14 Mon Sep 17 00:00:00 2001 From: Ben Skeggs Date: Wed, 19 Mar 2014 02:56:29 +1000 Subject: [PATCH] drm/nouveau/devinit: add interface to check if a mmio access by scripts is ok Signed-off-by: Ben Skeggs --- drivers/gpu/drm/nouveau/core/include/subdev/devinit.h | 1 + drivers/gpu/drm/nouveau/core/subdev/bios/init.c | 11 ++++++++--- drivers/gpu/drm/nouveau/core/subdev/devinit/base.c | 1 + drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h | 1 + 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 413bc54071c8..e292271a84e4 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 a29c18617c57..acaeaf79e3f0 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 8fa34e8152c2..239acfe876c3 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 822a2fbf44a5..f0e8683ad840 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) \ -- 2.20.1