diff options
author | Francisco Jerez <currojerez@riseup.net> | 2010-07-13 09:59:50 -0400 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2010-07-25 21:42:21 -0400 |
commit | 67eda20e6b7a757ed45f6b5a8a4d30c2a0d47c7a (patch) | |
tree | 919b3abb20f61a9e222083cb399f24a9131a6b33 | |
parent | 3c7066bca990a440b512663f89680bd1c1cae6c1 (diff) |
drm/nv04-nv3x: Implement init-compute-mem.
Init-compute-mem was the last piece missing for nv0x-nv3x card
cold-booting. This implementation is somewhat lacking but it's been
reported to work on most chipsets it was tested in. Let me know if it
breaks suspend to RAM for you.
Signed-off-by: Francisco Jerez <currojerez@riseup.net>
Tested-by: Patrice Mandin <patmandin@gmail.com>
Tested-by: Ben Skeggs <bskeggs@redhat.com>
Tested-by: Xavier Chantry <chantry.xavier@gmail.com>
Tested-by: Marcin KoĆcielnicki <koriakin@0x04.net>
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.c | 418 | ||||
-rw-r--r-- | drivers/gpu/drm/nouveau/nouveau_bios.h | 2 |
2 files changed, 359 insertions, 61 deletions
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.c b/drivers/gpu/drm/nouveau/nouveau_bios.c index 382977cc2e4f..665f0d64f2c6 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.c +++ b/drivers/gpu/drm/nouveau/nouveau_bios.c | |||
@@ -28,6 +28,8 @@ | |||
28 | #include "nouveau_hw.h" | 28 | #include "nouveau_hw.h" |
29 | #include "nouveau_encoder.h" | 29 | #include "nouveau_encoder.h" |
30 | 30 | ||
31 | #include <linux/io-mapping.h> | ||
32 | |||
31 | /* these defines are made up */ | 33 | /* these defines are made up */ |
32 | #define NV_CIO_CRE_44_HEADA 0x0 | 34 | #define NV_CIO_CRE_44_HEADA 0x0 |
33 | #define NV_CIO_CRE_44_HEADB 0x3 | 35 | #define NV_CIO_CRE_44_HEADB 0x3 |
@@ -2067,6 +2069,323 @@ init_zm_index_io(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2067 | return 5; | 2069 | return 5; |
2068 | } | 2070 | } |
2069 | 2071 | ||
2072 | static inline void | ||
2073 | bios_md32(struct nvbios *bios, uint32_t reg, | ||
2074 | uint32_t mask, uint32_t val) | ||
2075 | { | ||
2076 | bios_wr32(bios, reg, (bios_rd32(bios, reg) & ~mask) | val); | ||
2077 | } | ||
2078 | |||
2079 | static uint32_t | ||
2080 | peek_fb(struct drm_device *dev, struct io_mapping *fb, | ||
2081 | uint32_t off) | ||
2082 | { | ||
2083 | uint32_t val = 0; | ||
2084 | |||
2085 | if (off < pci_resource_len(dev->pdev, 1)) { | ||
2086 | uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); | ||
2087 | |||
2088 | val = ioread32(p); | ||
2089 | |||
2090 | io_mapping_unmap_atomic(p); | ||
2091 | } | ||
2092 | |||
2093 | return val; | ||
2094 | } | ||
2095 | |||
2096 | static void | ||
2097 | poke_fb(struct drm_device *dev, struct io_mapping *fb, | ||
2098 | uint32_t off, uint32_t val) | ||
2099 | { | ||
2100 | if (off < pci_resource_len(dev->pdev, 1)) { | ||
2101 | uint32_t __iomem *p = io_mapping_map_atomic_wc(fb, off); | ||
2102 | |||
2103 | iowrite32(val, p); | ||
2104 | wmb(); | ||
2105 | |||
2106 | io_mapping_unmap_atomic(p); | ||
2107 | } | ||
2108 | } | ||
2109 | |||
2110 | static inline bool | ||
2111 | read_back_fb(struct drm_device *dev, struct io_mapping *fb, | ||
2112 | uint32_t off, uint32_t val) | ||
2113 | { | ||
2114 | poke_fb(dev, fb, off, val); | ||
2115 | return val == peek_fb(dev, fb, off); | ||
2116 | } | ||
2117 | |||
2118 | static int | ||
2119 | nv04_init_compute_mem(struct nvbios *bios) | ||
2120 | { | ||
2121 | struct drm_device *dev = bios->dev; | ||
2122 | uint32_t patt = 0xdeadbeef; | ||
2123 | struct io_mapping *fb; | ||
2124 | int i; | ||
2125 | |||
2126 | /* Map the framebuffer aperture */ | ||
2127 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2128 | pci_resource_len(dev->pdev, 1)); | ||
2129 | if (!fb) | ||
2130 | return -ENOMEM; | ||
2131 | |||
2132 | /* Sequencer and refresh off */ | ||
2133 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); | ||
2134 | bios_md32(bios, NV04_PFB_DEBUG_0, 0, NV04_PFB_DEBUG_0_REFRESH_OFF); | ||
2135 | |||
2136 | bios_md32(bios, NV04_PFB_BOOT_0, ~0, | ||
2137 | NV04_PFB_BOOT_0_RAM_AMOUNT_16MB | | ||
2138 | NV04_PFB_BOOT_0_RAM_WIDTH_128 | | ||
2139 | NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_16MBIT); | ||
2140 | |||
2141 | for (i = 0; i < 4; i++) | ||
2142 | poke_fb(dev, fb, 4 * i, patt); | ||
2143 | |||
2144 | poke_fb(dev, fb, 0x400000, patt + 1); | ||
2145 | |||
2146 | if (peek_fb(dev, fb, 0) == patt + 1) { | ||
2147 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, | ||
2148 | NV04_PFB_BOOT_0_RAM_TYPE_SDRAM_16MBIT); | ||
2149 | bios_md32(bios, NV04_PFB_DEBUG_0, | ||
2150 | NV04_PFB_DEBUG_0_REFRESH_OFF, 0); | ||
2151 | |||
2152 | for (i = 0; i < 4; i++) | ||
2153 | poke_fb(dev, fb, 4 * i, patt); | ||
2154 | |||
2155 | if ((peek_fb(dev, fb, 0xc) & 0xffff) != (patt & 0xffff)) | ||
2156 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2157 | NV04_PFB_BOOT_0_RAM_WIDTH_128 | | ||
2158 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2159 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2160 | |||
2161 | } else if ((peek_fb(dev, fb, 0xc) & 0xffff0000) != | ||
2162 | (patt & 0xffff0000)) { | ||
2163 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2164 | NV04_PFB_BOOT_0_RAM_WIDTH_128 | | ||
2165 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2166 | NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); | ||
2167 | |||
2168 | } else if (peek_fb(dev, fb, 0) == patt) { | ||
2169 | if (read_back_fb(dev, fb, 0x800000, patt)) | ||
2170 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2171 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2172 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2173 | else | ||
2174 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2175 | NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2176 | NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); | ||
2177 | |||
2178 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_TYPE, | ||
2179 | NV04_PFB_BOOT_0_RAM_TYPE_SGRAM_8MBIT); | ||
2180 | |||
2181 | } else if (!read_back_fb(dev, fb, 0x800000, patt)) { | ||
2182 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2183 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2184 | |||
2185 | } | ||
2186 | |||
2187 | /* Refresh on, sequencer on */ | ||
2188 | bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); | ||
2189 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); | ||
2190 | |||
2191 | io_mapping_free(fb); | ||
2192 | return 0; | ||
2193 | } | ||
2194 | |||
2195 | static const uint8_t * | ||
2196 | nv05_memory_config(struct nvbios *bios) | ||
2197 | { | ||
2198 | /* Defaults for BIOSes lacking a memory config table */ | ||
2199 | static const uint8_t default_config_tab[][2] = { | ||
2200 | { 0x24, 0x00 }, | ||
2201 | { 0x28, 0x00 }, | ||
2202 | { 0x24, 0x01 }, | ||
2203 | { 0x1f, 0x00 }, | ||
2204 | { 0x0f, 0x00 }, | ||
2205 | { 0x17, 0x00 }, | ||
2206 | { 0x06, 0x00 }, | ||
2207 | { 0x00, 0x00 } | ||
2208 | }; | ||
2209 | int i = (bios_rd32(bios, NV_PEXTDEV_BOOT_0) & | ||
2210 | NV_PEXTDEV_BOOT_0_RAMCFG) >> 2; | ||
2211 | |||
2212 | if (bios->legacy.mem_init_tbl_ptr) | ||
2213 | return &bios->data[bios->legacy.mem_init_tbl_ptr + 2 * i]; | ||
2214 | else | ||
2215 | return default_config_tab[i]; | ||
2216 | } | ||
2217 | |||
2218 | static int | ||
2219 | nv05_init_compute_mem(struct nvbios *bios) | ||
2220 | { | ||
2221 | struct drm_device *dev = bios->dev; | ||
2222 | const uint8_t *ramcfg = nv05_memory_config(bios); | ||
2223 | uint32_t patt = 0xdeadbeef; | ||
2224 | struct io_mapping *fb; | ||
2225 | int i, v; | ||
2226 | |||
2227 | /* Map the framebuffer aperture */ | ||
2228 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2229 | pci_resource_len(dev->pdev, 1)); | ||
2230 | if (!fb) | ||
2231 | return -ENOMEM; | ||
2232 | |||
2233 | /* Sequencer off */ | ||
2234 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) | 0x20); | ||
2235 | |||
2236 | if (bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_UMA_ENABLE) | ||
2237 | goto out; | ||
2238 | |||
2239 | bios_md32(bios, NV04_PFB_DEBUG_0, NV04_PFB_DEBUG_0_REFRESH_OFF, 0); | ||
2240 | |||
2241 | /* If present load the hardcoded scrambling table */ | ||
2242 | if (bios->legacy.mem_init_tbl_ptr) { | ||
2243 | uint32_t *scramble_tab = (uint32_t *)&bios->data[ | ||
2244 | bios->legacy.mem_init_tbl_ptr + 0x10]; | ||
2245 | |||
2246 | for (i = 0; i < 8; i++) | ||
2247 | bios_wr32(bios, NV04_PFB_SCRAMBLE(i), | ||
2248 | ROM32(scramble_tab[i])); | ||
2249 | } | ||
2250 | |||
2251 | /* Set memory type/width/length defaults depending on the straps */ | ||
2252 | bios_md32(bios, NV04_PFB_BOOT_0, 0x3f, ramcfg[0]); | ||
2253 | |||
2254 | if (ramcfg[1] & 0x80) | ||
2255 | bios_md32(bios, NV04_PFB_CFG0, 0, NV04_PFB_CFG0_SCRAMBLE); | ||
2256 | |||
2257 | bios_md32(bios, NV04_PFB_CFG1, 0x700001, (ramcfg[1] & 1) << 20); | ||
2258 | bios_md32(bios, NV04_PFB_CFG1, 0, 1); | ||
2259 | |||
2260 | /* Probe memory bus width */ | ||
2261 | for (i = 0; i < 4; i++) | ||
2262 | poke_fb(dev, fb, 4 * i, patt); | ||
2263 | |||
2264 | if (peek_fb(dev, fb, 0xc) != patt) | ||
2265 | bios_md32(bios, NV04_PFB_BOOT_0, | ||
2266 | NV04_PFB_BOOT_0_RAM_WIDTH_128, 0); | ||
2267 | |||
2268 | /* Probe memory length */ | ||
2269 | v = bios_rd32(bios, NV04_PFB_BOOT_0) & NV04_PFB_BOOT_0_RAM_AMOUNT; | ||
2270 | |||
2271 | if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_32MB && | ||
2272 | (!read_back_fb(dev, fb, 0x1000000, ++patt) || | ||
2273 | !read_back_fb(dev, fb, 0, ++patt))) | ||
2274 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2275 | NV04_PFB_BOOT_0_RAM_AMOUNT_16MB); | ||
2276 | |||
2277 | if (v == NV04_PFB_BOOT_0_RAM_AMOUNT_16MB && | ||
2278 | !read_back_fb(dev, fb, 0x800000, ++patt)) | ||
2279 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2280 | NV04_PFB_BOOT_0_RAM_AMOUNT_8MB); | ||
2281 | |||
2282 | if (!read_back_fb(dev, fb, 0x400000, ++patt)) | ||
2283 | bios_md32(bios, NV04_PFB_BOOT_0, NV04_PFB_BOOT_0_RAM_AMOUNT, | ||
2284 | NV04_PFB_BOOT_0_RAM_AMOUNT_4MB); | ||
2285 | |||
2286 | out: | ||
2287 | /* Sequencer on */ | ||
2288 | NVWriteVgaSeq(dev, 0, 1, NVReadVgaSeq(dev, 0, 1) & ~0x20); | ||
2289 | |||
2290 | io_mapping_free(fb); | ||
2291 | return 0; | ||
2292 | } | ||
2293 | |||
2294 | static int | ||
2295 | nv10_init_compute_mem(struct nvbios *bios) | ||
2296 | { | ||
2297 | struct drm_device *dev = bios->dev; | ||
2298 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | ||
2299 | const int mem_width[] = { 0x10, 0x00, 0x20 }; | ||
2300 | const int mem_width_count = (dev_priv->chipset >= 0x17 ? 3 : 2); | ||
2301 | uint32_t patt = 0xdeadbeef; | ||
2302 | struct io_mapping *fb; | ||
2303 | int i, j, k; | ||
2304 | |||
2305 | /* Map the framebuffer aperture */ | ||
2306 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2307 | pci_resource_len(dev->pdev, 1)); | ||
2308 | if (!fb) | ||
2309 | return -ENOMEM; | ||
2310 | |||
2311 | bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); | ||
2312 | |||
2313 | /* Probe memory bus width */ | ||
2314 | for (i = 0; i < mem_width_count; i++) { | ||
2315 | bios_md32(bios, NV04_PFB_CFG0, 0x30, mem_width[i]); | ||
2316 | |||
2317 | for (j = 0; j < 4; j++) { | ||
2318 | for (k = 0; k < 4; k++) | ||
2319 | poke_fb(dev, fb, 0x1c, 0); | ||
2320 | |||
2321 | poke_fb(dev, fb, 0x1c, patt); | ||
2322 | poke_fb(dev, fb, 0x3c, 0); | ||
2323 | |||
2324 | if (peek_fb(dev, fb, 0x1c) == patt) | ||
2325 | goto mem_width_found; | ||
2326 | } | ||
2327 | } | ||
2328 | |||
2329 | mem_width_found: | ||
2330 | patt <<= 1; | ||
2331 | |||
2332 | /* Probe amount of installed memory */ | ||
2333 | for (i = 0; i < 4; i++) { | ||
2334 | int off = bios_rd32(bios, NV04_PFB_FIFO_DATA) - 0x100000; | ||
2335 | |||
2336 | poke_fb(dev, fb, off, patt); | ||
2337 | poke_fb(dev, fb, 0, 0); | ||
2338 | |||
2339 | peek_fb(dev, fb, 0); | ||
2340 | peek_fb(dev, fb, 0); | ||
2341 | peek_fb(dev, fb, 0); | ||
2342 | peek_fb(dev, fb, 0); | ||
2343 | |||
2344 | if (peek_fb(dev, fb, off) == patt) | ||
2345 | goto amount_found; | ||
2346 | } | ||
2347 | |||
2348 | /* IC missing - disable the upper half memory space. */ | ||
2349 | bios_md32(bios, NV04_PFB_CFG0, 0x1000, 0); | ||
2350 | |||
2351 | amount_found: | ||
2352 | io_mapping_free(fb); | ||
2353 | return 0; | ||
2354 | } | ||
2355 | |||
2356 | static int | ||
2357 | nv20_init_compute_mem(struct nvbios *bios) | ||
2358 | { | ||
2359 | struct drm_device *dev = bios->dev; | ||
2360 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | ||
2361 | uint32_t mask = (dev_priv->chipset >= 0x25 ? 0x300 : 0x900); | ||
2362 | uint32_t amount, off; | ||
2363 | struct io_mapping *fb; | ||
2364 | |||
2365 | /* Map the framebuffer aperture */ | ||
2366 | fb = io_mapping_create_wc(pci_resource_start(dev->pdev, 1), | ||
2367 | pci_resource_len(dev->pdev, 1)); | ||
2368 | if (!fb) | ||
2369 | return -ENOMEM; | ||
2370 | |||
2371 | bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); | ||
2372 | |||
2373 | /* Allow full addressing */ | ||
2374 | bios_md32(bios, NV04_PFB_CFG0, 0, mask); | ||
2375 | |||
2376 | amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); | ||
2377 | for (off = amount; off > 0x2000000; off -= 0x2000000) | ||
2378 | poke_fb(dev, fb, off - 4, off); | ||
2379 | |||
2380 | amount = bios_rd32(bios, NV04_PFB_FIFO_DATA); | ||
2381 | if (amount != peek_fb(dev, fb, amount - 4)) | ||
2382 | /* IC missing - disable the upper half memory space. */ | ||
2383 | bios_md32(bios, NV04_PFB_CFG0, mask, 0); | ||
2384 | |||
2385 | io_mapping_free(fb); | ||
2386 | return 0; | ||
2387 | } | ||
2388 | |||
2070 | static int | 2389 | static int |
2071 | init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | 2390 | init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) |
2072 | { | 2391 | { |
@@ -2075,64 +2394,57 @@ init_compute_mem(struct nvbios *bios, uint16_t offset, struct init_exec *iexec) | |||
2075 | * | 2394 | * |
2076 | * offset (8 bit): opcode | 2395 | * offset (8 bit): opcode |
2077 | * | 2396 | * |
2078 | * This opcode is meant to set NV_PFB_CFG0 (0x100200) appropriately so | 2397 | * This opcode is meant to set the PFB memory config registers |
2079 | * that the hardware can correctly calculate how much VRAM it has | 2398 | * appropriately so that we can correctly calculate how much VRAM it |
2080 | * (and subsequently report that value in NV_PFB_CSTATUS (0x10020C)) | 2399 | * has (on nv10 and better chipsets the amount of installed VRAM is |
2400 | * subsequently reported in NV_PFB_CSTATUS (0x10020C)). | ||
2081 | * | 2401 | * |
2082 | * The implementation of this opcode in general consists of two parts: | 2402 | * The implementation of this opcode in general consists of several |
2083 | * 1) determination of the memory bus width | 2403 | * parts: |
2084 | * 2) determination of how many of the card's RAM pads have ICs attached | ||
2085 | * | 2404 | * |
2086 | * 1) is done by a cunning combination of writes to offsets 0x1c and | 2405 | * 1) Determination of memory type and density. Only necessary for |
2087 | * 0x3c in the framebuffer, and seeing whether the written values are | 2406 | * really old chipsets, the memory type reported by the strap bits |
2088 | * read back correctly. This then affects bits 4-7 of NV_PFB_CFG0 | 2407 | * (0x101000) is assumed to be accurate on nv05 and newer. |
2089 | * | 2408 | * |
2090 | * 2) is done by a cunning combination of writes to an offset slightly | 2409 | * 2) Determination of the memory bus width. Usually done by a cunning |
2091 | * less than the maximum memory reported by NV_PFB_CSTATUS, then seeing | 2410 | * combination of writes to offsets 0x1c and 0x3c in the fb, and |
2092 | * if the test pattern can be read back. This then affects bits 12-15 of | 2411 | * seeing whether the written values are read back correctly. |
2093 | * NV_PFB_CFG0 | ||
2094 | * | 2412 | * |
2095 | * In this context a "cunning combination" may include multiple reads | 2413 | * Only necessary on nv0x-nv1x and nv34, on the other cards we can |
2096 | * and writes to varying locations, often alternating the test pattern | 2414 | * trust the straps. |
2097 | * and 0, doubtless to make sure buffers are filled, residual charges | ||
2098 | * on tracks are removed etc. | ||
2099 | * | 2415 | * |
2100 | * Unfortunately, the "cunning combination"s mentioned above, and the | 2416 | * 3) Determination of how many of the card's RAM pads have ICs |
2101 | * changes to the bits in NV_PFB_CFG0 differ with nearly every bios | 2417 | * attached, usually done by a cunning combination of writes to an |
2102 | * trace I have. | 2418 | * offset slightly less than the maximum memory reported by |
2419 | * NV_PFB_CSTATUS, then seeing if the test pattern can be read back. | ||
2103 | * | 2420 | * |
2104 | * Therefore, we cheat and assume the value of NV_PFB_CFG0 with which | 2421 | * This appears to be a NOP on IGPs and NV4x or newer chipsets, both io |
2105 | * we started was correct, and use that instead | 2422 | * logs of the VBIOS and kmmio traces of the binary driver POSTing the |
2423 | * card show nothing being done for this opcode. Why is it still listed | ||
2424 | * in the table?! | ||
2106 | */ | 2425 | */ |
2107 | 2426 | ||
2108 | /* no iexec->execute check by design */ | 2427 | /* no iexec->execute check by design */ |
2109 | 2428 | ||
2110 | /* | ||
2111 | * This appears to be a NOP on G8x chipsets, both io logs of the VBIOS | ||
2112 | * and kmmio traces of the binary driver POSTing the card show nothing | ||
2113 | * being done for this opcode. why is it still listed in the table?! | ||
2114 | */ | ||
2115 | |||
2116 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; | 2429 | struct drm_nouveau_private *dev_priv = bios->dev->dev_private; |
2430 | int ret; | ||
2117 | 2431 | ||
2118 | if (dev_priv->card_type >= NV_40) | 2432 | if (dev_priv->chipset >= 0x40 || |
2119 | return 1; | 2433 | dev_priv->chipset == 0x1a || |
2120 | 2434 | dev_priv->chipset == 0x1f) | |
2121 | /* | 2435 | ret = 0; |
2122 | * On every card I've seen, this step gets done for us earlier in | 2436 | else if (dev_priv->chipset >= 0x20 && |
2123 | * the init scripts | 2437 | dev_priv->chipset != 0x34) |
2124 | uint8_t crdata = bios_idxprt_rd(dev, NV_VIO_SRX, 0x01); | 2438 | ret = nv20_init_compute_mem(bios); |
2125 | bios_idxprt_wr(dev, NV_VIO_SRX, 0x01, crdata | 0x20); | 2439 | else if (dev_priv->chipset >= 0x10) |
2126 | */ | 2440 | ret = nv10_init_compute_mem(bios); |
2127 | 2441 | else if (dev_priv->chipset >= 0x5) | |
2128 | /* | 2442 | ret = nv05_init_compute_mem(bios); |
2129 | * This also has probably been done in the scripts, but an mmio trace of | 2443 | else |
2130 | * s3 resume shows nvidia doing it anyway (unlike the NV_VIO_SRX write) | 2444 | ret = nv04_init_compute_mem(bios); |
2131 | */ | ||
2132 | bios_wr32(bios, NV10_PFB_REFCTRL, NV10_PFB_REFCTRL_VALID_1); | ||
2133 | 2445 | ||
2134 | /* write back the saved configuration value */ | 2446 | if (ret) |
2135 | bios_wr32(bios, NV04_PFB_CFG0, bios->state.saved_nv_pfb_cfg0); | 2447 | return ret; |
2136 | 2448 | ||
2137 | return 1; | 2449 | return 1; |
2138 | } | 2450 | } |
@@ -6320,7 +6632,6 @@ nouveau_bios_init(struct drm_device *dev) | |||
6320 | { | 6632 | { |
6321 | struct drm_nouveau_private *dev_priv = dev->dev_private; | 6633 | struct drm_nouveau_private *dev_priv = dev->dev_private; |
6322 | struct nvbios *bios = &dev_priv->vbios; | 6634 | struct nvbios *bios = &dev_priv->vbios; |
6323 | uint32_t saved_nv_pextdev_boot_0; | ||
6324 | bool was_locked; | 6635 | bool was_locked; |
6325 | int ret; | 6636 | int ret; |
6326 | 6637 | ||
@@ -6341,27 +6652,16 @@ nouveau_bios_init(struct drm_device *dev) | |||
6341 | if (!bios->major_version) /* we don't run version 0 bios */ | 6652 | if (!bios->major_version) /* we don't run version 0 bios */ |
6342 | return 0; | 6653 | return 0; |
6343 | 6654 | ||
6344 | /* these will need remembering across a suspend */ | ||
6345 | saved_nv_pextdev_boot_0 = bios_rd32(bios, NV_PEXTDEV_BOOT_0); | ||
6346 | bios->state.saved_nv_pfb_cfg0 = bios_rd32(bios, NV04_PFB_CFG0); | ||
6347 | |||
6348 | /* init script execution disabled */ | 6655 | /* init script execution disabled */ |
6349 | bios->execute = false; | 6656 | bios->execute = false; |
6350 | 6657 | ||
6351 | /* ... unless card isn't POSTed already */ | 6658 | /* ... unless card isn't POSTed already */ |
6352 | if (!nouveau_bios_posted(dev)) { | 6659 | if (!nouveau_bios_posted(dev)) { |
6353 | NV_INFO(dev, "Adaptor not initialised\n"); | 6660 | NV_INFO(dev, "Adaptor not initialised, " |
6354 | if (dev_priv->card_type < NV_40) { | 6661 | "running VBIOS init tables.\n"); |
6355 | NV_ERROR(dev, "Unable to POST this chipset\n"); | ||
6356 | return -ENODEV; | ||
6357 | } | ||
6358 | |||
6359 | NV_INFO(dev, "Running VBIOS init tables\n"); | ||
6360 | bios->execute = true; | 6662 | bios->execute = true; |
6361 | } | 6663 | } |
6362 | 6664 | ||
6363 | bios_wr32(bios, NV_PEXTDEV_BOOT_0, saved_nv_pextdev_boot_0); | ||
6364 | |||
6365 | ret = nouveau_run_vbios_init(dev); | 6665 | ret = nouveau_run_vbios_init(dev); |
6366 | if (ret) | 6666 | if (ret) |
6367 | return ret; | 6667 | return ret; |
diff --git a/drivers/gpu/drm/nouveau/nouveau_bios.h b/drivers/gpu/drm/nouveau/nouveau_bios.h index cc52aec33691..024458a8d060 100644 --- a/drivers/gpu/drm/nouveau/nouveau_bios.h +++ b/drivers/gpu/drm/nouveau/nouveau_bios.h | |||
@@ -251,8 +251,6 @@ struct nvbios { | |||
251 | 251 | ||
252 | struct { | 252 | struct { |
253 | int crtchead; | 253 | int crtchead; |
254 | /* these need remembering across suspend */ | ||
255 | uint32_t saved_nv_pfb_cfg0; | ||
256 | } state; | 254 | } state; |
257 | 255 | ||
258 | struct { | 256 | struct { |