aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c50
2 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
index e237910e7895..51d5076333ec 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
@@ -5,6 +5,7 @@
5 5
6struct nv50_devinit_priv { 6struct nv50_devinit_priv {
7 struct nouveau_devinit base; 7 struct nouveau_devinit base;
8 u32 r001540;
8}; 9};
9 10
10int nv50_devinit_ctor(struct nouveau_object *, struct nouveau_object *, 11int nv50_devinit_ctor(struct nouveau_object *, struct nouveau_object *,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
index 6dedf1dad7f7..006cf348bda7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
@@ -81,6 +81,55 @@ nva3_devinit_disable(struct nouveau_devinit *devinit)
81 return disable; 81 return disable;
82} 82}
83 83
84static u32
85nva3_devinit_mmio_part[] = {
86 0x100720, 0x1008bc, 4,
87 0x100a20, 0x100adc, 4,
88 0x100d80, 0x100ddc, 4,
89 0x110000, 0x110f9c, 4,
90 0x111000, 0x11103c, 8,
91 0x111080, 0x1110fc, 4,
92 0x111120, 0x1111fc, 4,
93 0x111300, 0x1114bc, 4,
94 0,
95};
96
97static u32
98nva3_devinit_mmio(struct nouveau_devinit *devinit, u32 addr)
99{
100 struct nv50_devinit_priv *priv = (void *)devinit;
101 u32 *mmio = nva3_devinit_mmio_part;
102
103 /* the init tables on some boards have INIT_RAM_RESTRICT_ZM_REG_GROUP
104 * instructions which touch registers that may not even exist on
105 * some configurations (Quadro 400), which causes the register
106 * interface to screw up for some amount of time after attempting to
107 * write to one of these, and results in all sorts of things going
108 * horribly wrong.
109 *
110 * the binary driver avoids touching these registers at all, however,
111 * the video bios doesn't care and does what the scripts say. it's
112 * presumed that the io-port access to priv registers isn't effected
113 * by the screw-up bug mentioned above.
114 *
115 * really, a new opcode should've been invented to handle these
116 * requirements, but whatever, it's too late for that now.
117 */
118 while (mmio[0]) {
119 if (addr >= mmio[0] && addr <= mmio[1]) {
120 u32 part = (addr / mmio[2]) & 7;
121 if (!priv->r001540)
122 priv->r001540 = nv_rd32(priv, 0x001540);
123 if (part >= hweight8((priv->r001540 >> 16) & 0xff))
124 return ~0;
125 return addr;
126 }
127 mmio += 3;
128 }
129
130 return addr;
131}
132
84struct nouveau_oclass * 133struct nouveau_oclass *
85nva3_devinit_oclass = &(struct nouveau_devinit_impl) { 134nva3_devinit_oclass = &(struct nouveau_devinit_impl) {
86 .base.handle = NV_SUBDEV(DEVINIT, 0xa3), 135 .base.handle = NV_SUBDEV(DEVINIT, 0xa3),
@@ -92,4 +141,5 @@ nva3_devinit_oclass = &(struct nouveau_devinit_impl) {
92 }, 141 },
93 .pll_set = nva3_devinit_pll_set, 142 .pll_set = nva3_devinit_pll_set,
94 .disable = nva3_devinit_disable, 143 .disable = nva3_devinit_disable,
144 .mmio = nva3_devinit_mmio,
95}.base; 145}.base;