diff options
author | Ben Skeggs <bskeggs@redhat.com> | 2012-02-02 00:07:13 -0500 |
---|---|---|
committer | Ben Skeggs <bskeggs@redhat.com> | 2012-05-24 02:31:21 -0400 |
commit | 001a3990f6f767d364edab3c4b01a9ce4dde9cda (patch) | |
tree | 556152e15c279871b4aaefb01a5df1033d57eafe /drivers/gpu/drm/nouveau/nva3_pm.c | |
parent | 4719b55be5d43420b29e48c17208ec3db66e730f (diff) |
drm/nva3/pm: attempt to bash a few 0x100200 bits correctly
Signed-off-by: Ben Skeggs <bskeggs@redhat.com>
Diffstat (limited to 'drivers/gpu/drm/nouveau/nva3_pm.c')
-rw-r--r-- | drivers/gpu/drm/nouveau/nva3_pm.c | 66 |
1 files changed, 46 insertions, 20 deletions
diff --git a/drivers/gpu/drm/nouveau/nva3_pm.c b/drivers/gpu/drm/nouveau/nva3_pm.c index c9a1f63d1c93..0ab6d436fbd1 100644 --- a/drivers/gpu/drm/nouveau/nva3_pm.c +++ b/drivers/gpu/drm/nouveau/nva3_pm.c | |||
@@ -236,17 +236,25 @@ nva3_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl) | |||
236 | 236 | ||
237 | struct nva3_pm_state { | 237 | struct nva3_pm_state { |
238 | struct nouveau_pm_level *perflvl; | 238 | struct nouveau_pm_level *perflvl; |
239 | |||
239 | struct creg nclk; | 240 | struct creg nclk; |
240 | struct creg sclk; | 241 | struct creg sclk; |
241 | struct creg mclk; | ||
242 | struct creg vdec; | 242 | struct creg vdec; |
243 | struct creg unka0; | 243 | struct creg unka0; |
244 | |||
245 | struct creg mclk; | ||
246 | u8 *rammap; | ||
247 | u8 rammap_ver; | ||
248 | u8 rammap_len; | ||
249 | u8 *ramcfg; | ||
250 | u8 ramcfg_len; | ||
244 | }; | 251 | }; |
245 | 252 | ||
246 | void * | 253 | void * |
247 | nva3_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) | 254 | nva3_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) |
248 | { | 255 | { |
249 | struct nva3_pm_state *info; | 256 | struct nva3_pm_state *info; |
257 | u8 ramcfg_cnt; | ||
250 | int ret; | 258 | int ret; |
251 | 259 | ||
252 | info = kzalloc(sizeof(*info), GFP_KERNEL); | 260 | info = kzalloc(sizeof(*info), GFP_KERNEL); |
@@ -273,6 +281,19 @@ nva3_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl) | |||
273 | if (ret < 0) | 281 | if (ret < 0) |
274 | goto out; | 282 | goto out; |
275 | 283 | ||
284 | info->rammap = nouveau_perf_rammap(dev, perflvl->memory, | ||
285 | &info->rammap_ver, | ||
286 | &info->rammap_len, | ||
287 | &ramcfg_cnt, &info->ramcfg_len); | ||
288 | if (info->rammap_ver != 0x10 || info->rammap_len < 5) | ||
289 | info->rammap = NULL; | ||
290 | |||
291 | info->ramcfg = nouveau_perf_ramcfg(dev, perflvl->memory, | ||
292 | &info->rammap_ver, | ||
293 | &info->ramcfg_len); | ||
294 | if (info->rammap_ver != 0x10) | ||
295 | info->ramcfg = NULL; | ||
296 | |||
276 | info->perflvl = perflvl; | 297 | info->perflvl = perflvl; |
277 | out: | 298 | out: |
278 | if (ret < 0) { | 299 | if (ret < 0) { |
@@ -356,9 +377,6 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) | |||
356 | { | 377 | { |
357 | struct drm_device *dev = exec->dev; | 378 | struct drm_device *dev = exec->dev; |
358 | struct nva3_pm_state *info = exec->priv; | 379 | struct nva3_pm_state *info = exec->priv; |
359 | struct nouveau_pm_level *perflvl = info->perflvl; | ||
360 | u32 freq = perflvl->memory; | ||
361 | u8 *rammap, *ramcfg, ver, hdr, cnt, len; | ||
362 | 380 | ||
363 | if (!info->mclk.pll) { | 381 | if (!info->mclk.pll) { |
364 | nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk); | 382 | nv_mask(dev, 0x004168, 0x003f3040, info->mclk.clk); |
@@ -367,15 +385,14 @@ mclk_clock_set(struct nouveau_mem_exec_func *exec) | |||
367 | nv_wr32(dev, 0x004018, 0x1000d000); /*XXX*/ | 385 | nv_wr32(dev, 0x004018, 0x1000d000); /*XXX*/ |
368 | } | 386 | } |
369 | 387 | ||
370 | rammap = nouveau_perf_rammap(dev, freq, &ver, &hdr, &cnt, &len); | 388 | if (info->rammap) { |
371 | if (rammap && ver == 0x10 && hdr >= 5) { | 389 | if (info->ramcfg && (info->rammap[4] & 0x08)) { |
372 | ramcfg = nouveau_perf_ramcfg(dev, freq, &ver, &len); | 390 | u32 unk5a0 = (ROM16(info->ramcfg[5]) << 8) | |
373 | if (ramcfg && (rammap[4] & 0x08)) { | 391 | info->ramcfg[5]; |
374 | u32 unk5a0 = (ROM16(ramcfg[5]) << 8) | ramcfg[5]; | 392 | u32 unk5a4 = ROM16(info->ramcfg[7]); |
375 | u32 unk5a4 = ROM16(ramcfg[7]); | 393 | u32 unk804 = (info->ramcfg[9] & 0xf0) << 16 | |
376 | u32 unk804 = (ramcfg[9] & 0xf0) << 16 | | 394 | (info->ramcfg[3] & 0x0f) << 16 | |
377 | (ramcfg[3] & 0x0f) << 16 | | 395 | (info->ramcfg[9] & 0x0f) | |
378 | (ramcfg[9] & 0x0f) | | ||
379 | 0x80000000; | 396 | 0x80000000; |
380 | nv_wr32(dev, 0x1005a0, unk5a0); | 397 | nv_wr32(dev, 0x1005a0, unk5a0); |
381 | nv_wr32(dev, 0x1005a4, unk5a4); | 398 | nv_wr32(dev, 0x1005a4, unk5a4); |
@@ -399,28 +416,31 @@ mclk_timing_set(struct nouveau_mem_exec_func *exec) | |||
399 | struct drm_device *dev = exec->dev; | 416 | struct drm_device *dev = exec->dev; |
400 | struct nva3_pm_state *info = exec->priv; | 417 | struct nva3_pm_state *info = exec->priv; |
401 | struct nouveau_pm_level *perflvl = info->perflvl; | 418 | struct nouveau_pm_level *perflvl = info->perflvl; |
402 | u8 *ramcfg, ver, len; | ||
403 | int i; | 419 | int i; |
404 | 420 | ||
405 | for (i = 0; i < 9; i++) | 421 | for (i = 0; i < 9; i++) |
406 | nv_wr32(dev, 0x100220 + (i * 4), perflvl->timing.reg[i]); | 422 | nv_wr32(dev, 0x100220 + (i * 4), perflvl->timing.reg[i]); |
407 | 423 | ||
408 | ramcfg = nouveau_perf_ramcfg(dev, perflvl->memory, &ver, &len); | 424 | if (info->ramcfg) { |
409 | if (ramcfg) { | 425 | u32 data = (info->ramcfg[2] & 0x08) ? 0x00000000 : 0x00001000; |
426 | nv_mask(dev, 0x100200, 0x00001000, data); | ||
427 | } | ||
428 | |||
429 | if (info->ramcfg) { | ||
410 | u32 unk714 = nv_rd32(dev, 0x100714) & ~0xf0000010; | 430 | u32 unk714 = nv_rd32(dev, 0x100714) & ~0xf0000010; |
411 | u32 unk718 = nv_rd32(dev, 0x100718) & ~0x00000100; | 431 | u32 unk718 = nv_rd32(dev, 0x100718) & ~0x00000100; |
412 | u32 unk71c = nv_rd32(dev, 0x10071c) & ~0x00000100; | 432 | u32 unk71c = nv_rd32(dev, 0x10071c) & ~0x00000100; |
413 | if ( (ramcfg[2] & 0x20)) | 433 | if ( (info->ramcfg[2] & 0x20)) |
414 | unk714 |= 0xf0000000; | 434 | unk714 |= 0xf0000000; |
415 | if (!(ramcfg[2] & 0x04)) | 435 | if (!(info->ramcfg[2] & 0x04)) |
416 | unk714 |= 0x00000010; | 436 | unk714 |= 0x00000010; |
417 | nv_wr32(dev, 0x100714, unk714); | 437 | nv_wr32(dev, 0x100714, unk714); |
418 | 438 | ||
419 | if (ramcfg[2] & 0x01) | 439 | if (info->ramcfg[2] & 0x01) |
420 | unk71c |= 0x00000100; | 440 | unk71c |= 0x00000100; |
421 | nv_wr32(dev, 0x10071c, unk71c); | 441 | nv_wr32(dev, 0x10071c, unk71c); |
422 | 442 | ||
423 | if (ramcfg[2] & 0x02) | 443 | if (info->ramcfg[2] & 0x02) |
424 | unk718 |= 0x00000100; | 444 | unk718 |= 0x00000100; |
425 | nv_wr32(dev, 0x100718, unk718); | 445 | nv_wr32(dev, 0x100718, unk718); |
426 | } | 446 | } |
@@ -463,9 +483,15 @@ prog_mem(struct drm_device *dev, struct nva3_pm_state *info) | |||
463 | } | 483 | } |
464 | } | 484 | } |
465 | 485 | ||
486 | if (info->rammap && !(info->rammap[4] & 0x02)) | ||
487 | nv_mask(dev, 0x100200, 0x00000800, 0x00000000); | ||
466 | nv_wr32(dev, 0x611200, 0x00003300); | 488 | nv_wr32(dev, 0x611200, 0x00003300); |
489 | |||
467 | nouveau_mem_exec(&exec, info->perflvl); | 490 | nouveau_mem_exec(&exec, info->perflvl); |
491 | |||
468 | nv_wr32(dev, 0x611200, 0x00003330); | 492 | nv_wr32(dev, 0x611200, 0x00003330); |
493 | if (info->rammap && (info->rammap[4] & 0x02)) | ||
494 | nv_mask(dev, 0x100200, 0x00000800, 0x00000800); | ||
469 | 495 | ||
470 | if (info->mclk.pll) { | 496 | if (info->mclk.pll) { |
471 | nv_mask(dev, 0x004168, 0x00000001, 0x00000000); | 497 | nv_mask(dev, 0x004168, 0x00000001, 0x00000000); |