diff options
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c | 50 |
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 | ||
| 6 | struct nv50_devinit_priv { | 6 | struct nv50_devinit_priv { |
| 7 | struct nouveau_devinit base; | 7 | struct nouveau_devinit base; |
| 8 | u32 r001540; | ||
| 8 | }; | 9 | }; |
| 9 | 10 | ||
| 10 | int nv50_devinit_ctor(struct nouveau_object *, struct nouveau_object *, | 11 | int 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 | ||
| 84 | static u32 | ||
| 85 | nva3_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 | |||
| 97 | static u32 | ||
| 98 | nva3_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 | |||
| 84 | struct nouveau_oclass * | 133 | struct nouveau_oclass * |
| 85 | nva3_devinit_oclass = &(struct nouveau_devinit_impl) { | 134 | nva3_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; |
