aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/gpu/drm/nouveau/core
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2014-12-15 18:52:01 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2014-12-15 18:52:01 -0500
commit988adfdffdd43cfd841df734664727993076d7cb (patch)
tree6794f7bba8f595500c2b7d33376ad6614adcfaf2 /drivers/gpu/drm/nouveau/core
parent26178ec11ef3c6c814bf16a0a2b9c2f7242e3c64 (diff)
parent4e0cd68115620bc3236ff4e58e4c073948629b41 (diff)
Merge branch 'drm-next' of git://people.freedesktop.org/~airlied/linux
Pull drm updates from Dave Airlie: "Highlights: - AMD KFD driver merge This is the AMD HSA interface for exposing a lowlevel interface for GPGPU use. They have an open source userspace built on top of this interface, and the code looks as good as it was going to get out of tree. - Initial atomic modesetting work The need for an atomic modesetting interface to allow userspace to try and send a complete set of modesetting state to the driver has arisen, and been suffering from neglect this past year. No more, the start of the common code and changes for msm driver to use it are in this tree. Ongoing work to get the userspace ioctl finished and the code clean will probably wait until next kernel. - DisplayID 1.3 and tiled monitor exposed to userspace. Tiled monitor property is now exposed for userspace to make use of. - Rockchip drm driver merged. - imx gpu driver moved out of staging Other stuff: - core: panel - MIPI DSI + new panels. expose suggested x/y properties for virtual GPUs - i915: Initial Skylake (SKL) support gen3/4 reset work start of dri1/ums removal infoframe tracking fixes for lots of things. - nouveau: tegra k1 voltage support GM204 modesetting support GT21x memory reclocking work - radeon: CI dpm fixes GPUVM improvements Initial DPM fan control - rcar-du: HDMI support added removed some support for old boards slave encoder driver for Analog Devices adv7511 - exynos: Exynos4415 SoC support - msm: a4xx gpu support atomic helper conversion - tegra: iommu support universal plane support ganged-mode DSI support - sti: HDMI i2c improvements - vmwgfx: some late fixes. - qxl: use suggested x/y properties" * 'drm-next' of git://people.freedesktop.org/~airlied/linux: (969 commits) drm: sti: fix module compilation issue drm/i915: save/restore GMBUS freq across suspend/resume on gen4 drm: sti: correctly cleanup CRTC and planes drm: sti: add HQVDP plane drm: sti: add cursor plane drm: sti: enable auxiliary CRTC drm: sti: fix delay in VTG programming drm: sti: prepare sti_tvout to support auxiliary crtc drm: sti: use drm_crtc_vblank_{on/off} instead of drm_vblank_{on/off} drm: sti: fix hdmi avi infoframe drm: sti: remove event lock while disabling vblank drm: sti: simplify gdp code drm: sti: clear all mixer control drm: sti: remove gpio for HDMI hot plug detection drm: sti: allow to change hdmi ddc i2c adapter drm/doc: Document drm_add_modes_noedid() usage drm/i915: Remove '& 0xffff' from the mask given to WA_REG() drm/i915: Invert the mask and val arguments in wa_add() and WA_REG() drm: Zero out DRM object memory upon cleanup drm/i915/bdw: Fix the write setting up the WIZ hashing mode ...
Diffstat (limited to 'drivers/gpu/drm/nouveau/core')
-rw-r--r--drivers/gpu/drm/nouveau/core/core/handle.c113
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/base.c14
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/gm100.c43
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/device/nve0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/dport.c9
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/gm107.c16
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/gm204.c114
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.c94
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv50.h63
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv84.c40
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nv94.c30
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nva0.c16
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nva3.c16
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c99
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nve0.c30
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c16
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/outp.c5
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c144
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c48
-rw-r--r--drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/device.h9
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/handle.h5
-rw-r--r--drivers/gpu/drm/nouveau/core/include/core/object.h17
-rw-r--r--drivers/gpu/drm/nouveau/core/include/engine/disp.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h31
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h14
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h13
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h12
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h18
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h37
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h23
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/devinit.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/i2c.h3
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/pwr.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/include/subdev/volt.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/os.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c129
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/base.c369
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c27
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/disp.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/dp.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c45
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/image.c78
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/init.c56
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/npde.c59
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c69
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c135
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/priv.h25
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c13
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c270
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c111
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c71
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c108
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c112
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c69
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/timing.c42
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c17
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/base.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c3
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c173
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/base.c37
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c117
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/priv.h1
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h16
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c813
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c2
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/base.c97
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c221
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c13
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c6
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c86
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h4
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc111
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h738
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h863
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h828
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h754
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h5
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c37
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/volt/base.c67
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c199
103 files changed, 5799 insertions, 2361 deletions
diff --git a/drivers/gpu/drm/nouveau/core/core/handle.c b/drivers/gpu/drm/nouveau/core/core/handle.c
index a490b805d7e3..13f816cb08bd 100644
--- a/drivers/gpu/drm/nouveau/core/core/handle.c
+++ b/drivers/gpu/drm/nouveau/core/core/handle.c
@@ -222,116 +222,3 @@ nouveau_handle_put(struct nouveau_handle *handle)
222 if (handle) 222 if (handle)
223 nouveau_namedb_put(handle); 223 nouveau_namedb_put(handle);
224} 224}
225
226int
227nouveau_handle_new(struct nouveau_object *client, u32 _parent, u32 _handle,
228 u16 _oclass, void *data, u32 size,
229 struct nouveau_object **pobject)
230{
231 struct nouveau_object *parent = NULL;
232 struct nouveau_object *engctx = NULL;
233 struct nouveau_object *object = NULL;
234 struct nouveau_object *engine;
235 struct nouveau_oclass *oclass;
236 struct nouveau_handle *handle;
237 int ret;
238
239 /* lookup parent object and ensure it *is* a parent */
240 parent = nouveau_handle_ref(client, _parent);
241 if (!parent) {
242 nv_error(client, "parent 0x%08x not found\n", _parent);
243 return -ENOENT;
244 }
245
246 if (!nv_iclass(parent, NV_PARENT_CLASS)) {
247 nv_error(parent, "cannot have children\n");
248 ret = -EINVAL;
249 goto fail_class;
250 }
251
252 /* check that parent supports the requested subclass */
253 ret = nouveau_parent_sclass(parent, _oclass, &engine, &oclass);
254 if (ret) {
255 nv_debug(parent, "illegal class 0x%04x\n", _oclass);
256 goto fail_class;
257 }
258
259 /* make sure engine init has been completed *before* any objects
260 * it controls are created - the constructors may depend on
261 * state calculated at init (ie. default context construction)
262 */
263 if (engine) {
264 ret = nouveau_object_inc(engine);
265 if (ret)
266 goto fail_class;
267 }
268
269 /* if engine requires it, create a context object to insert
270 * between the parent and its children (eg. PGRAPH context)
271 */
272 if (engine && nv_engine(engine)->cclass) {
273 ret = nouveau_object_ctor(parent, engine,
274 nv_engine(engine)->cclass,
275 data, size, &engctx);
276 if (ret)
277 goto fail_engctx;
278 } else {
279 nouveau_object_ref(parent, &engctx);
280 }
281
282 /* finally, create new object and bind it to its handle */
283 ret = nouveau_object_ctor(engctx, engine, oclass, data, size, &object);
284 *pobject = object;
285 if (ret)
286 goto fail_ctor;
287
288 ret = nouveau_object_inc(object);
289 if (ret)
290 goto fail_init;
291
292 ret = nouveau_handle_create(parent, _parent, _handle, object, &handle);
293 if (ret)
294 goto fail_handle;
295
296 ret = nouveau_handle_init(handle);
297 if (ret)
298 nouveau_handle_destroy(handle);
299
300fail_handle:
301 nouveau_object_dec(object, false);
302fail_init:
303 nouveau_object_ref(NULL, &object);
304fail_ctor:
305 nouveau_object_ref(NULL, &engctx);
306fail_engctx:
307 if (engine)
308 nouveau_object_dec(engine, false);
309fail_class:
310 nouveau_object_ref(NULL, &parent);
311 return ret;
312}
313
314int
315nouveau_handle_del(struct nouveau_object *client, u32 _parent, u32 _handle)
316{
317 struct nouveau_object *parent = NULL;
318 struct nouveau_object *namedb = NULL;
319 struct nouveau_handle *handle = NULL;
320
321 parent = nouveau_handle_ref(client, _parent);
322 if (!parent)
323 return -ENOENT;
324
325 namedb = nv_pclass(parent, NV_NAMEDB_CLASS);
326 if (namedb) {
327 handle = nouveau_namedb_get(nv_namedb(namedb), _handle);
328 if (handle) {
329 nouveau_namedb_put(handle);
330 nouveau_handle_fini(handle, false);
331 nouveau_handle_destroy(handle);
332 }
333 }
334
335 nouveau_object_ref(NULL, &parent);
336 return handle ? 0 : -EINVAL;
337}
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/base.c b/drivers/gpu/drm/nouveau/core/engine/device/base.c
index 0ef5a5713182..137e0b0faeae 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/base.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/base.c
@@ -29,6 +29,7 @@
29#include <nvif/unpack.h> 29#include <nvif/unpack.h>
30#include <nvif/class.h> 30#include <nvif/class.h>
31 31
32#include <subdev/bios.h>
32#include <subdev/fb.h> 33#include <subdev/fb.h>
33#include <subdev/instmem.h> 34#include <subdev/instmem.h>
34 35
@@ -138,7 +139,7 @@ nouveau_devobj_info(struct nouveau_object *object, void *data, u32 size)
138 } 139 }
139 140
140 args->v0.chipset = device->chipset; 141 args->v0.chipset = device->chipset;
141 args->v0.revision = device->chipset >= 0x10 ? nv_rd32(device, 0) : 0x00; 142 args->v0.revision = device->chiprev;
142 if (pfb) args->v0.ram_size = args->v0.ram_user = pfb->ram->size; 143 if (pfb) args->v0.ram_size = args->v0.ram_user = pfb->ram->size;
143 else args->v0.ram_size = args->v0.ram_user = 0; 144 else args->v0.ram_size = args->v0.ram_user = 0;
144 if (imem) args->v0.ram_user = args->v0.ram_user - imem->reserved; 145 if (imem) args->v0.ram_user = args->v0.ram_user - imem->reserved;
@@ -222,6 +223,7 @@ static const u64 disable_map[] = {
222 [NVDEV_SUBDEV_VOLT] = NV_DEVICE_V0_DISABLE_CORE, 223 [NVDEV_SUBDEV_VOLT] = NV_DEVICE_V0_DISABLE_CORE,
223 [NVDEV_SUBDEV_THERM] = NV_DEVICE_V0_DISABLE_CORE, 224 [NVDEV_SUBDEV_THERM] = NV_DEVICE_V0_DISABLE_CORE,
224 [NVDEV_SUBDEV_PWR] = NV_DEVICE_V0_DISABLE_CORE, 225 [NVDEV_SUBDEV_PWR] = NV_DEVICE_V0_DISABLE_CORE,
226 [NVDEV_SUBDEV_FUSE] = NV_DEVICE_V0_DISABLE_CORE,
225 [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_V0_DISABLE_CORE, 227 [NVDEV_ENGINE_DMAOBJ] = NV_DEVICE_V0_DISABLE_CORE,
226 [NVDEV_ENGINE_PERFMON] = NV_DEVICE_V0_DISABLE_CORE, 228 [NVDEV_ENGINE_PERFMON] = NV_DEVICE_V0_DISABLE_CORE,
227 [NVDEV_ENGINE_FIFO] = NV_DEVICE_V0_DISABLE_FIFO, 229 [NVDEV_ENGINE_FIFO] = NV_DEVICE_V0_DISABLE_FIFO,
@@ -235,6 +237,7 @@ static const u64 disable_map[] = {
235 [NVDEV_ENGINE_PPP] = NV_DEVICE_V0_DISABLE_PPP, 237 [NVDEV_ENGINE_PPP] = NV_DEVICE_V0_DISABLE_PPP,
236 [NVDEV_ENGINE_COPY0] = NV_DEVICE_V0_DISABLE_COPY0, 238 [NVDEV_ENGINE_COPY0] = NV_DEVICE_V0_DISABLE_COPY0,
237 [NVDEV_ENGINE_COPY1] = NV_DEVICE_V0_DISABLE_COPY1, 239 [NVDEV_ENGINE_COPY1] = NV_DEVICE_V0_DISABLE_COPY1,
240 [NVDEV_ENGINE_COPY2] = NV_DEVICE_V0_DISABLE_COPY1,
238 [NVDEV_ENGINE_VIC] = NV_DEVICE_V0_DISABLE_VIC, 241 [NVDEV_ENGINE_VIC] = NV_DEVICE_V0_DISABLE_VIC,
239 [NVDEV_ENGINE_VENC] = NV_DEVICE_V0_DISABLE_VENC, 242 [NVDEV_ENGINE_VENC] = NV_DEVICE_V0_DISABLE_VENC,
240 [NVDEV_ENGINE_DISP] = NV_DEVICE_V0_DISABLE_DISP, 243 [NVDEV_ENGINE_DISP] = NV_DEVICE_V0_DISABLE_DISP,
@@ -352,12 +355,14 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
352 /* determine chipset and derive architecture from it */ 355 /* determine chipset and derive architecture from it */
353 if ((boot0 & 0x1f000000) > 0) { 356 if ((boot0 & 0x1f000000) > 0) {
354 device->chipset = (boot0 & 0x1ff00000) >> 20; 357 device->chipset = (boot0 & 0x1ff00000) >> 20;
358 device->chiprev = (boot0 & 0x000000ff);
355 switch (device->chipset & 0x1f0) { 359 switch (device->chipset & 0x1f0) {
356 case 0x010: { 360 case 0x010: {
357 if (0x461 & (1 << (device->chipset & 0xf))) 361 if (0x461 & (1 << (device->chipset & 0xf)))
358 device->card_type = NV_10; 362 device->card_type = NV_10;
359 else 363 else
360 device->card_type = NV_11; 364 device->card_type = NV_11;
365 device->chiprev = 0x00;
361 break; 366 break;
362 } 367 }
363 case 0x020: device->card_type = NV_20; break; 368 case 0x020: device->card_type = NV_20; break;
@@ -373,7 +378,8 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
373 case 0x0e0: 378 case 0x0e0:
374 case 0x0f0: 379 case 0x0f0:
375 case 0x100: device->card_type = NV_E0; break; 380 case 0x100: device->card_type = NV_E0; break;
376 case 0x110: device->card_type = GM100; break; 381 case 0x110:
382 case 0x120: device->card_type = GM100; break;
377 default: 383 default:
378 break; 384 break;
379 } 385 }
@@ -427,6 +433,10 @@ nouveau_devobj_ctor(struct nouveau_object *parent,
427 } 433 }
428 434
429 nv_debug(device, "crystal freq: %dKHz\n", device->crystal); 435 nv_debug(device, "crystal freq: %dKHz\n", device->crystal);
436 } else
437 if ( (args->v0.disable & NV_DEVICE_V0_DISABLE_IDENTIFY)) {
438 device->cname = "NULL";
439 device->oclass[NVDEV_SUBDEV_VBIOS] = &nouveau_bios_oclass;
430 } 440 }
431 441
432 if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_MMIO) && 442 if (!(args->v0.disable & NV_DEVICE_V0_DISABLE_MMIO) &&
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c
index 6295668e29a5..4e74a3376de8 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/gm100.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/gm100.c
@@ -98,6 +98,49 @@ gm100_identify(struct nouveau_device *device)
98 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass; 98 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
99#endif 99#endif
100 break; 100 break;
101 case 0x124:
102 device->cname = "GM204";
103 device->oclass[NVDEV_SUBDEV_VBIOS ] = &nouveau_bios_oclass;
104 device->oclass[NVDEV_SUBDEV_GPIO ] = nve0_gpio_oclass;
105 device->oclass[NVDEV_SUBDEV_I2C ] = gm204_i2c_oclass;
106 device->oclass[NVDEV_SUBDEV_FUSE ] = &gm107_fuse_oclass;
107#if 0
108 /* looks to be some non-trivial changes */
109 device->oclass[NVDEV_SUBDEV_CLOCK ] = &nve0_clock_oclass;
110 /* priv ring says no to 0x10eb14 writes */
111 device->oclass[NVDEV_SUBDEV_THERM ] = &gm107_therm_oclass;
112#endif
113 device->oclass[NVDEV_SUBDEV_MXM ] = &nv50_mxm_oclass;
114 device->oclass[NVDEV_SUBDEV_DEVINIT] = gm204_devinit_oclass;
115 device->oclass[NVDEV_SUBDEV_MC ] = gk20a_mc_oclass;
116 device->oclass[NVDEV_SUBDEV_BUS ] = nvc0_bus_oclass;
117 device->oclass[NVDEV_SUBDEV_TIMER ] = &gk20a_timer_oclass;
118 device->oclass[NVDEV_SUBDEV_FB ] = gm107_fb_oclass;
119 device->oclass[NVDEV_SUBDEV_LTC ] = gm107_ltc_oclass;
120 device->oclass[NVDEV_SUBDEV_IBUS ] = &nve0_ibus_oclass;
121 device->oclass[NVDEV_SUBDEV_INSTMEM] = nv50_instmem_oclass;
122 device->oclass[NVDEV_SUBDEV_VM ] = &nvc0_vmmgr_oclass;
123 device->oclass[NVDEV_SUBDEV_BAR ] = &nvc0_bar_oclass;
124 device->oclass[NVDEV_SUBDEV_PWR ] = nv108_pwr_oclass;
125#if 0
126 device->oclass[NVDEV_SUBDEV_VOLT ] = &nv40_volt_oclass;
127#endif
128 device->oclass[NVDEV_ENGINE_DMAOBJ ] = nvd0_dmaeng_oclass;
129#if 0
130 device->oclass[NVDEV_ENGINE_FIFO ] = nv108_fifo_oclass;
131 device->oclass[NVDEV_ENGINE_SW ] = nvc0_software_oclass;
132 device->oclass[NVDEV_ENGINE_GR ] = gm107_graph_oclass;
133#endif
134 device->oclass[NVDEV_ENGINE_DISP ] = gm204_disp_oclass;
135#if 0
136 device->oclass[NVDEV_ENGINE_COPY0 ] = &gm204_copy0_oclass;
137 device->oclass[NVDEV_ENGINE_COPY1 ] = &gm204_copy1_oclass;
138 device->oclass[NVDEV_ENGINE_COPY2 ] = &gm204_copy2_oclass;
139 device->oclass[NVDEV_ENGINE_BSP ] = &nve0_bsp_oclass;
140 device->oclass[NVDEV_ENGINE_VP ] = &nve0_vp_oclass;
141 device->oclass[NVDEV_ENGINE_PPP ] = &nvc0_ppp_oclass;
142#endif
143 break;
101 default: 144 default:
102 nv_fatal(device, "unknown Maxwell chipset\n"); 145 nv_fatal(device, "unknown Maxwell chipset\n");
103 return -EINVAL; 146 return -EINVAL;
diff --git a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
index b1b2e484ecfa..674da1f095b2 100644
--- a/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/device/nve0.c
@@ -179,6 +179,7 @@ nve0_identify(struct nouveau_device *device)
179 device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass; 179 device->oclass[NVDEV_ENGINE_GR ] = gk20a_graph_oclass;
180 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass; 180 device->oclass[NVDEV_ENGINE_COPY2 ] = &nve0_copy2_oclass;
181 device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass; 181 device->oclass[NVDEV_ENGINE_PERFMON] = &nve0_perfmon_oclass;
182 device->oclass[NVDEV_SUBDEV_VOLT ] = &gk20a_volt_oclass;
182 break; 183 break;
183 case 0xf0: 184 case 0xf0:
184 device->cname = "GK110"; 185 device->cname = "GK110";
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
index 39890221b91c..16db08dfba6e 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/dport.c
@@ -28,7 +28,7 @@
28#include <subdev/bios/init.h> 28#include <subdev/bios/init.h>
29#include <subdev/i2c.h> 29#include <subdev/i2c.h>
30 30
31#include <engine/disp.h> 31#include "nv50.h"
32 32
33#include <nvif/class.h> 33#include <nvif/class.h>
34 34
@@ -326,7 +326,7 @@ void
326nouveau_dp_train(struct work_struct *w) 326nouveau_dp_train(struct work_struct *w)
327{ 327{
328 struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work); 328 struct nvkm_output_dp *outp = container_of(w, typeof(*outp), lt.work);
329 struct nouveau_disp *disp = nouveau_disp(outp); 329 struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
330 const struct dp_rates *cfg = nouveau_dp_rates; 330 const struct dp_rates *cfg = nouveau_dp_rates;
331 struct dp_state _dp = { 331 struct dp_state _dp = {
332 .outp = outp, 332 .outp = outp,
@@ -334,8 +334,11 @@ nouveau_dp_train(struct work_struct *w)
334 u32 datarate = 0; 334 u32 datarate = 0;
335 int ret; 335 int ret;
336 336
337 if (!outp->base.info.location && priv->sor.magic)
338 priv->sor.magic(&outp->base);
339
337 /* bring capabilities within encoder limits */ 340 /* bring capabilities within encoder limits */
338 if (nv_mclass(disp) < GF110_DISP) 341 if (nv_mclass(priv) < GF110_DISP)
339 outp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED; 342 outp->dpcd[2] &= ~DPCD_RC02_TPS3_SUPPORTED;
340 if ((outp->dpcd[2] & 0x1f) > outp->base.info.dpconf.link_nr) { 343 if ((outp->dpcd[2] & 0x1f) > outp->base.info.dpconf.link_nr) {
341 outp->dpcd[2] &= ~DPCD_RC02_MAX_LANE_COUNT; 344 outp->dpcd[2] &= ~DPCD_RC02_MAX_LANE_COUNT;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c b/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
index b3df3fe2dc09..e2ad0543fb31 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/gm107.c
@@ -35,8 +35,8 @@
35 35
36static struct nouveau_oclass 36static struct nouveau_oclass
37gm107_disp_sclass[] = { 37gm107_disp_sclass[] = {
38 { GM107_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, 38 { GM107_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
39 { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, 39 { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
40 { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, 40 { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
41 { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, 41 { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
42 { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, 42 { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
@@ -44,8 +44,8 @@ gm107_disp_sclass[] = {
44}; 44};
45 45
46static struct nouveau_oclass 46static struct nouveau_oclass
47gm107_disp_base_oclass[] = { 47gm107_disp_main_oclass[] = {
48 { GM107_DISP, &nvd0_disp_base_ofuncs }, 48 { GM107_DISP, &nvd0_disp_main_ofuncs },
49 {} 49 {}
50}; 50};
51 51
@@ -72,7 +72,7 @@ gm107_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
72 if (ret) 72 if (ret)
73 return ret; 73 return ret;
74 74
75 nv_engine(priv)->sclass = gm107_disp_base_oclass; 75 nv_engine(priv)->sclass = gm107_disp_main_oclass;
76 nv_engine(priv)->cclass = &nv50_disp_cclass; 76 nv_engine(priv)->cclass = &nv50_disp_cclass;
77 nv_subdev(priv)->intr = nvd0_disp_intr; 77 nv_subdev(priv)->intr = nvd0_disp_intr;
78 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor); 78 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
@@ -99,9 +99,9 @@ gm107_disp_oclass = &(struct nv50_disp_impl) {
99 }, 99 },
100 .base.vblank = &nvd0_disp_vblank_func, 100 .base.vblank = &nvd0_disp_vblank_func,
101 .base.outp = nvd0_disp_outp_sclass, 101 .base.outp = nvd0_disp_outp_sclass,
102 .mthd.core = &nve0_disp_mast_mthd_chan, 102 .mthd.core = &nve0_disp_core_mthd_chan,
103 .mthd.base = &nvd0_disp_sync_mthd_chan, 103 .mthd.base = &nvd0_disp_base_mthd_chan,
104 .mthd.ovly = &nve0_disp_ovly_mthd_chan, 104 .mthd.ovly = &nve0_disp_ovly_mthd_chan,
105 .mthd.prev = -0x020000, 105 .mthd.prev = -0x020000,
106 .head.scanoutpos = nvd0_disp_base_scanoutpos, 106 .head.scanoutpos = nvd0_disp_main_scanoutpos,
107}.base.base; 107}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/gm204.c b/drivers/gpu/drm/nouveau/core/engine/disp/gm204.c
new file mode 100644
index 000000000000..672ded79b2a9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/gm204.c
@@ -0,0 +1,114 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include <engine/software.h>
26#include <engine/disp.h>
27
28#include <nvif/class.h>
29
30#include "nv50.h"
31
32/*******************************************************************************
33 * Base display object
34 ******************************************************************************/
35
36static struct nouveau_oclass
37gm204_disp_sclass[] = {
38 { GM204_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
39 { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
40 { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
41 { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
42 { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
43 {}
44};
45
46static struct nouveau_oclass
47gm204_disp_main_oclass[] = {
48 { GM204_DISP, &nvd0_disp_main_ofuncs },
49 {}
50};
51
52/*******************************************************************************
53 * Display engine implementation
54 ******************************************************************************/
55
56static int
57gm204_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
58 struct nouveau_oclass *oclass, void *data, u32 size,
59 struct nouveau_object **pobject)
60{
61 struct nv50_disp_priv *priv;
62 int heads = nv_rd32(parent, 0x022448);
63 int ret;
64
65 ret = nouveau_disp_create(parent, engine, oclass, heads,
66 "PDISP", "display", &priv);
67 *pobject = nv_object(priv);
68 if (ret)
69 return ret;
70
71 ret = nvkm_event_init(&nvd0_disp_chan_uevent, 1, 17, &priv->uevent);
72 if (ret)
73 return ret;
74
75 nv_engine(priv)->sclass = gm204_disp_main_oclass;
76 nv_engine(priv)->cclass = &nv50_disp_cclass;
77 nv_subdev(priv)->intr = nvd0_disp_intr;
78 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
79 priv->sclass = gm204_disp_sclass;
80 priv->head.nr = heads;
81 priv->dac.nr = 3;
82 priv->sor.nr = 4;
83 priv->dac.power = nv50_dac_power;
84 priv->dac.sense = nv50_dac_sense;
85 priv->sor.power = nv50_sor_power;
86 priv->sor.hda_eld = nvd0_hda_eld;
87 priv->sor.hdmi = nvd0_hdmi_ctrl;
88 priv->sor.magic = gm204_sor_magic;
89 return 0;
90}
91
92struct nouveau_oclass *
93gm204_disp_outp_sclass[] = {
94 &gm204_sor_dp_impl.base.base,
95 NULL
96};
97
98struct nouveau_oclass *
99gm204_disp_oclass = &(struct nv50_disp_impl) {
100 .base.base.handle = NV_ENGINE(DISP, 0x07),
101 .base.base.ofuncs = &(struct nouveau_ofuncs) {
102 .ctor = gm204_disp_ctor,
103 .dtor = _nouveau_disp_dtor,
104 .init = _nouveau_disp_init,
105 .fini = _nouveau_disp_fini,
106 },
107 .base.vblank = &nvd0_disp_vblank_func,
108 .base.outp = gm204_disp_outp_sclass,
109 .mthd.core = &nve0_disp_core_mthd_chan,
110 .mthd.base = &nvd0_disp_base_mthd_chan,
111 .mthd.ovly = &nve0_disp_ovly_mthd_chan,
112 .mthd.prev = -0x020000,
113 .head.scanoutpos = nvd0_disp_main_scanoutpos,
114}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
index 2df3a937037d..44a8290aaea5 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.c
@@ -88,12 +88,14 @@ nv50_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
88{ 88{
89 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent); 89 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
90 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000000 << index); 90 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000000 << index);
91 nv_wr32(priv, 0x610020, 0x00000001 << index);
91} 92}
92 93
93static void 94static void
94nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index) 95nv50_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
95{ 96{
96 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent); 97 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
98 nv_wr32(priv, 0x610020, 0x00000001 << index);
97 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000001 << index); 99 nv_mask(priv, 0x610028, 0x00000001 << index, 0x00000001 << index);
98} 100}
99 101
@@ -374,7 +376,7 @@ nv50_disp_mthd_chan(struct nv50_disp_priv *priv, int debug, int head,
374} 376}
375 377
376const struct nv50_disp_mthd_list 378const struct nv50_disp_mthd_list
377nv50_disp_mast_mthd_base = { 379nv50_disp_core_mthd_base = {
378 .mthd = 0x0000, 380 .mthd = 0x0000,
379 .addr = 0x000000, 381 .addr = 0x000000,
380 .data = { 382 .data = {
@@ -387,7 +389,7 @@ nv50_disp_mast_mthd_base = {
387}; 389};
388 390
389static const struct nv50_disp_mthd_list 391static const struct nv50_disp_mthd_list
390nv50_disp_mast_mthd_dac = { 392nv50_disp_core_mthd_dac = {
391 .mthd = 0x0080, 393 .mthd = 0x0080,
392 .addr = 0x000008, 394 .addr = 0x000008,
393 .data = { 395 .data = {
@@ -399,7 +401,7 @@ nv50_disp_mast_mthd_dac = {
399}; 401};
400 402
401const struct nv50_disp_mthd_list 403const struct nv50_disp_mthd_list
402nv50_disp_mast_mthd_sor = { 404nv50_disp_core_mthd_sor = {
403 .mthd = 0x0040, 405 .mthd = 0x0040,
404 .addr = 0x000008, 406 .addr = 0x000008,
405 .data = { 407 .data = {
@@ -409,7 +411,7 @@ nv50_disp_mast_mthd_sor = {
409}; 411};
410 412
411const struct nv50_disp_mthd_list 413const struct nv50_disp_mthd_list
412nv50_disp_mast_mthd_pior = { 414nv50_disp_core_mthd_pior = {
413 .mthd = 0x0040, 415 .mthd = 0x0040,
414 .addr = 0x000008, 416 .addr = 0x000008,
415 .data = { 417 .data = {
@@ -419,7 +421,7 @@ nv50_disp_mast_mthd_pior = {
419}; 421};
420 422
421static const struct nv50_disp_mthd_list 423static const struct nv50_disp_mthd_list
422nv50_disp_mast_mthd_head = { 424nv50_disp_core_mthd_head = {
423 .mthd = 0x0400, 425 .mthd = 0x0400,
424 .addr = 0x000540, 426 .addr = 0x000540,
425 .data = { 427 .data = {
@@ -466,21 +468,21 @@ nv50_disp_mast_mthd_head = {
466}; 468};
467 469
468static const struct nv50_disp_mthd_chan 470static const struct nv50_disp_mthd_chan
469nv50_disp_mast_mthd_chan = { 471nv50_disp_core_mthd_chan = {
470 .name = "Core", 472 .name = "Core",
471 .addr = 0x000000, 473 .addr = 0x000000,
472 .data = { 474 .data = {
473 { "Global", 1, &nv50_disp_mast_mthd_base }, 475 { "Global", 1, &nv50_disp_core_mthd_base },
474 { "DAC", 3, &nv50_disp_mast_mthd_dac }, 476 { "DAC", 3, &nv50_disp_core_mthd_dac },
475 { "SOR", 2, &nv50_disp_mast_mthd_sor }, 477 { "SOR", 2, &nv50_disp_core_mthd_sor },
476 { "PIOR", 3, &nv50_disp_mast_mthd_pior }, 478 { "PIOR", 3, &nv50_disp_core_mthd_pior },
477 { "HEAD", 2, &nv50_disp_mast_mthd_head }, 479 { "HEAD", 2, &nv50_disp_core_mthd_head },
478 {} 480 {}
479 } 481 }
480}; 482};
481 483
482int 484int
483nv50_disp_mast_ctor(struct nouveau_object *parent, 485nv50_disp_core_ctor(struct nouveau_object *parent,
484 struct nouveau_object *engine, 486 struct nouveau_object *engine,
485 struct nouveau_oclass *oclass, void *data, u32 size, 487 struct nouveau_oclass *oclass, void *data, u32 size,
486 struct nouveau_object **pobject) 488 struct nouveau_object **pobject)
@@ -509,7 +511,7 @@ nv50_disp_mast_ctor(struct nouveau_object *parent,
509} 511}
510 512
511static int 513static int
512nv50_disp_mast_init(struct nouveau_object *object) 514nv50_disp_core_init(struct nouveau_object *object)
513{ 515{
514 struct nv50_disp_priv *priv = (void *)object->engine; 516 struct nv50_disp_priv *priv = (void *)object->engine;
515 struct nv50_disp_dmac *mast = (void *)object; 517 struct nv50_disp_dmac *mast = (void *)object;
@@ -546,7 +548,7 @@ nv50_disp_mast_init(struct nouveau_object *object)
546} 548}
547 549
548static int 550static int
549nv50_disp_mast_fini(struct nouveau_object *object, bool suspend) 551nv50_disp_core_fini(struct nouveau_object *object, bool suspend)
550{ 552{
551 struct nv50_disp_priv *priv = (void *)object->engine; 553 struct nv50_disp_priv *priv = (void *)object->engine;
552 struct nv50_disp_dmac *mast = (void *)object; 554 struct nv50_disp_dmac *mast = (void *)object;
@@ -567,11 +569,11 @@ nv50_disp_mast_fini(struct nouveau_object *object, bool suspend)
567} 569}
568 570
569struct nv50_disp_chan_impl 571struct nv50_disp_chan_impl
570nv50_disp_mast_ofuncs = { 572nv50_disp_core_ofuncs = {
571 .base.ctor = nv50_disp_mast_ctor, 573 .base.ctor = nv50_disp_core_ctor,
572 .base.dtor = nv50_disp_dmac_dtor, 574 .base.dtor = nv50_disp_dmac_dtor,
573 .base.init = nv50_disp_mast_init, 575 .base.init = nv50_disp_core_init,
574 .base.fini = nv50_disp_mast_fini, 576 .base.fini = nv50_disp_core_fini,
575 .base.map = nv50_disp_chan_map, 577 .base.map = nv50_disp_chan_map,
576 .base.ntfy = nv50_disp_chan_ntfy, 578 .base.ntfy = nv50_disp_chan_ntfy,
577 .base.rd32 = nv50_disp_chan_rd32, 579 .base.rd32 = nv50_disp_chan_rd32,
@@ -586,7 +588,7 @@ nv50_disp_mast_ofuncs = {
586 ******************************************************************************/ 588 ******************************************************************************/
587 589
588static const struct nv50_disp_mthd_list 590static const struct nv50_disp_mthd_list
589nv50_disp_sync_mthd_base = { 591nv50_disp_base_mthd_base = {
590 .mthd = 0x0000, 592 .mthd = 0x0000,
591 .addr = 0x000000, 593 .addr = 0x000000,
592 .data = { 594 .data = {
@@ -611,7 +613,7 @@ nv50_disp_sync_mthd_base = {
611}; 613};
612 614
613const struct nv50_disp_mthd_list 615const struct nv50_disp_mthd_list
614nv50_disp_sync_mthd_image = { 616nv50_disp_base_mthd_image = {
615 .mthd = 0x0400, 617 .mthd = 0x0400,
616 .addr = 0x000000, 618 .addr = 0x000000,
617 .data = { 619 .data = {
@@ -625,18 +627,18 @@ nv50_disp_sync_mthd_image = {
625}; 627};
626 628
627static const struct nv50_disp_mthd_chan 629static const struct nv50_disp_mthd_chan
628nv50_disp_sync_mthd_chan = { 630nv50_disp_base_mthd_chan = {
629 .name = "Base", 631 .name = "Base",
630 .addr = 0x000540, 632 .addr = 0x000540,
631 .data = { 633 .data = {
632 { "Global", 1, &nv50_disp_sync_mthd_base }, 634 { "Global", 1, &nv50_disp_base_mthd_base },
633 { "Image", 2, &nv50_disp_sync_mthd_image }, 635 { "Image", 2, &nv50_disp_base_mthd_image },
634 {} 636 {}
635 } 637 }
636}; 638};
637 639
638int 640int
639nv50_disp_sync_ctor(struct nouveau_object *parent, 641nv50_disp_base_ctor(struct nouveau_object *parent,
640 struct nouveau_object *engine, 642 struct nouveau_object *engine,
641 struct nouveau_oclass *oclass, void *data, u32 size, 643 struct nouveau_oclass *oclass, void *data, u32 size,
642 struct nouveau_object **pobject) 644 struct nouveau_object **pobject)
@@ -669,8 +671,8 @@ nv50_disp_sync_ctor(struct nouveau_object *parent,
669} 671}
670 672
671struct nv50_disp_chan_impl 673struct nv50_disp_chan_impl
672nv50_disp_sync_ofuncs = { 674nv50_disp_base_ofuncs = {
673 .base.ctor = nv50_disp_sync_ctor, 675 .base.ctor = nv50_disp_base_ctor,
674 .base.dtor = nv50_disp_dmac_dtor, 676 .base.dtor = nv50_disp_dmac_dtor,
675 .base.init = nv50_disp_dmac_init, 677 .base.init = nv50_disp_dmac_init,
676 .base.fini = nv50_disp_dmac_fini, 678 .base.fini = nv50_disp_dmac_fini,
@@ -942,7 +944,7 @@ nv50_disp_curs_ofuncs = {
942 ******************************************************************************/ 944 ******************************************************************************/
943 945
944int 946int
945nv50_disp_base_scanoutpos(NV50_DISP_MTHD_V0) 947nv50_disp_main_scanoutpos(NV50_DISP_MTHD_V0)
946{ 948{
947 const u32 blanke = nv_rd32(priv, 0x610aec + (head * 0x540)); 949 const u32 blanke = nv_rd32(priv, 0x610aec + (head * 0x540));
948 const u32 blanks = nv_rd32(priv, 0x610af4 + (head * 0x540)); 950 const u32 blanks = nv_rd32(priv, 0x610af4 + (head * 0x540));
@@ -974,7 +976,7 @@ nv50_disp_base_scanoutpos(NV50_DISP_MTHD_V0)
974} 976}
975 977
976int 978int
977nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd, 979nv50_disp_main_mthd(struct nouveau_object *object, u32 mthd,
978 void *data, u32 size) 980 void *data, u32 size)
979{ 981{
980 const struct nv50_disp_impl *impl = (void *)nv_oclass(object->engine); 982 const struct nv50_disp_impl *impl = (void *)nv_oclass(object->engine);
@@ -1098,7 +1100,7 @@ nv50_disp_base_mthd(struct nouveau_object *object, u32 mthd,
1098} 1100}
1099 1101
1100int 1102int
1101nv50_disp_base_ctor(struct nouveau_object *parent, 1103nv50_disp_main_ctor(struct nouveau_object *parent,
1102 struct nouveau_object *engine, 1104 struct nouveau_object *engine,
1103 struct nouveau_oclass *oclass, void *data, u32 size, 1105 struct nouveau_oclass *oclass, void *data, u32 size,
1104 struct nouveau_object **pobject) 1106 struct nouveau_object **pobject)
@@ -1118,7 +1120,7 @@ nv50_disp_base_ctor(struct nouveau_object *parent,
1118} 1120}
1119 1121
1120void 1122void
1121nv50_disp_base_dtor(struct nouveau_object *object) 1123nv50_disp_main_dtor(struct nouveau_object *object)
1122{ 1124{
1123 struct nv50_disp_base *base = (void *)object; 1125 struct nv50_disp_base *base = (void *)object;
1124 nouveau_ramht_ref(NULL, &base->ramht); 1126 nouveau_ramht_ref(NULL, &base->ramht);
@@ -1126,7 +1128,7 @@ nv50_disp_base_dtor(struct nouveau_object *object)
1126} 1128}
1127 1129
1128static int 1130static int
1129nv50_disp_base_init(struct nouveau_object *object) 1131nv50_disp_main_init(struct nouveau_object *object)
1130{ 1132{
1131 struct nv50_disp_priv *priv = (void *)object->engine; 1133 struct nv50_disp_priv *priv = (void *)object->engine;
1132 struct nv50_disp_base *base = (void *)object; 1134 struct nv50_disp_base *base = (void *)object;
@@ -1194,7 +1196,7 @@ nv50_disp_base_init(struct nouveau_object *object)
1194} 1196}
1195 1197
1196static int 1198static int
1197nv50_disp_base_fini(struct nouveau_object *object, bool suspend) 1199nv50_disp_main_fini(struct nouveau_object *object, bool suspend)
1198{ 1200{
1199 struct nv50_disp_priv *priv = (void *)object->engine; 1201 struct nv50_disp_priv *priv = (void *)object->engine;
1200 struct nv50_disp_base *base = (void *)object; 1202 struct nv50_disp_base *base = (void *)object;
@@ -1207,25 +1209,25 @@ nv50_disp_base_fini(struct nouveau_object *object, bool suspend)
1207} 1209}
1208 1210
1209struct nouveau_ofuncs 1211struct nouveau_ofuncs
1210nv50_disp_base_ofuncs = { 1212nv50_disp_main_ofuncs = {
1211 .ctor = nv50_disp_base_ctor, 1213 .ctor = nv50_disp_main_ctor,
1212 .dtor = nv50_disp_base_dtor, 1214 .dtor = nv50_disp_main_dtor,
1213 .init = nv50_disp_base_init, 1215 .init = nv50_disp_main_init,
1214 .fini = nv50_disp_base_fini, 1216 .fini = nv50_disp_main_fini,
1215 .mthd = nv50_disp_base_mthd, 1217 .mthd = nv50_disp_main_mthd,
1216 .ntfy = nouveau_disp_ntfy, 1218 .ntfy = nouveau_disp_ntfy,
1217}; 1219};
1218 1220
1219static struct nouveau_oclass 1221static struct nouveau_oclass
1220nv50_disp_base_oclass[] = { 1222nv50_disp_main_oclass[] = {
1221 { NV50_DISP, &nv50_disp_base_ofuncs }, 1223 { NV50_DISP, &nv50_disp_main_ofuncs },
1222 {} 1224 {}
1223}; 1225};
1224 1226
1225static struct nouveau_oclass 1227static struct nouveau_oclass
1226nv50_disp_sclass[] = { 1228nv50_disp_sclass[] = {
1227 { NV50_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, 1229 { NV50_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
1228 { NV50_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, 1230 { NV50_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
1229 { NV50_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, 1231 { NV50_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
1230 { NV50_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, 1232 { NV50_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
1231 { NV50_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, 1233 { NV50_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
@@ -1974,7 +1976,7 @@ nv50_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1974 if (ret) 1976 if (ret)
1975 return ret; 1977 return ret;
1976 1978
1977 nv_engine(priv)->sclass = nv50_disp_base_oclass; 1979 nv_engine(priv)->sclass = nv50_disp_main_oclass;
1978 nv_engine(priv)->cclass = &nv50_disp_cclass; 1980 nv_engine(priv)->cclass = &nv50_disp_cclass;
1979 nv_subdev(priv)->intr = nv50_disp_intr; 1981 nv_subdev(priv)->intr = nv50_disp_intr;
1980 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); 1982 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
@@ -2007,9 +2009,9 @@ nv50_disp_oclass = &(struct nv50_disp_impl) {
2007 }, 2009 },
2008 .base.vblank = &nv50_disp_vblank_func, 2010 .base.vblank = &nv50_disp_vblank_func,
2009 .base.outp = nv50_disp_outp_sclass, 2011 .base.outp = nv50_disp_outp_sclass,
2010 .mthd.core = &nv50_disp_mast_mthd_chan, 2012 .mthd.core = &nv50_disp_core_mthd_chan,
2011 .mthd.base = &nv50_disp_sync_mthd_chan, 2013 .mthd.base = &nv50_disp_base_mthd_chan,
2012 .mthd.ovly = &nv50_disp_ovly_mthd_chan, 2014 .mthd.ovly = &nv50_disp_ovly_mthd_chan,
2013 .mthd.prev = 0x000004, 2015 .mthd.prev = 0x000004,
2014 .head.scanoutpos = nv50_disp_base_scanoutpos, 2016 .head.scanoutpos = nv50_disp_main_scanoutpos,
2015}.base.base; 2017}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
index 5279feefec06..7f08078ee925 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv50.h
@@ -42,6 +42,7 @@ struct nv50_disp_priv {
42 int (*hda_eld)(NV50_DISP_MTHD_V1); 42 int (*hda_eld)(NV50_DISP_MTHD_V1);
43 int (*hdmi)(NV50_DISP_MTHD_V1); 43 int (*hdmi)(NV50_DISP_MTHD_V1);
44 u32 lvdsconf; 44 u32 lvdsconf;
45 void (*magic)(struct nvkm_output *);
45 } sor; 46 } sor;
46 struct { 47 struct {
47 int nr; 48 int nr;
@@ -63,10 +64,10 @@ struct nv50_disp_impl {
63 } head; 64 } head;
64}; 65};
65 66
66int nv50_disp_base_scanoutpos(NV50_DISP_MTHD_V0); 67int nv50_disp_main_scanoutpos(NV50_DISP_MTHD_V0);
67int nv50_disp_base_mthd(struct nouveau_object *, u32, void *, u32); 68int nv50_disp_main_mthd(struct nouveau_object *, u32, void *, u32);
68 69
69int nvd0_disp_base_scanoutpos(NV50_DISP_MTHD_V0); 70int nvd0_disp_main_scanoutpos(NV50_DISP_MTHD_V0);
70 71
71int nv50_dac_power(NV50_DISP_MTHD_V1); 72int nv50_dac_power(NV50_DISP_MTHD_V1);
72int nv50_dac_sense(NV50_DISP_MTHD_V1); 73int nv50_dac_sense(NV50_DISP_MTHD_V1);
@@ -169,18 +170,18 @@ struct nv50_disp_mthd_chan {
169 } data[]; 170 } data[];
170}; 171};
171 172
172extern struct nv50_disp_chan_impl nv50_disp_mast_ofuncs; 173extern struct nv50_disp_chan_impl nv50_disp_core_ofuncs;
173int nv50_disp_mast_ctor(struct nouveau_object *, struct nouveau_object *, 174int nv50_disp_core_ctor(struct nouveau_object *, struct nouveau_object *,
174 struct nouveau_oclass *, void *, u32, 175 struct nouveau_oclass *, void *, u32,
175 struct nouveau_object **); 176 struct nouveau_object **);
176extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_base; 177extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_base;
177extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_sor; 178extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_sor;
178extern const struct nv50_disp_mthd_list nv50_disp_mast_mthd_pior; 179extern const struct nv50_disp_mthd_list nv50_disp_core_mthd_pior;
179extern struct nv50_disp_chan_impl nv50_disp_sync_ofuncs; 180extern struct nv50_disp_chan_impl nv50_disp_base_ofuncs;
180int nv50_disp_sync_ctor(struct nouveau_object *, struct nouveau_object *, 181int nv50_disp_base_ctor(struct nouveau_object *, struct nouveau_object *,
181 struct nouveau_oclass *, void *, u32, 182 struct nouveau_oclass *, void *, u32,
182 struct nouveau_object **); 183 struct nouveau_object **);
183extern const struct nv50_disp_mthd_list nv50_disp_sync_mthd_image; 184extern const struct nv50_disp_mthd_list nv50_disp_base_mthd_image;
184extern struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs; 185extern struct nv50_disp_chan_impl nv50_disp_ovly_ofuncs;
185int nv50_disp_ovly_ctor(struct nouveau_object *, struct nouveau_object *, 186int nv50_disp_ovly_ctor(struct nouveau_object *, struct nouveau_object *,
186 struct nouveau_oclass *, void *, u32, 187 struct nouveau_oclass *, void *, u32,
@@ -194,12 +195,12 @@ extern struct nv50_disp_chan_impl nv50_disp_curs_ofuncs;
194int nv50_disp_curs_ctor(struct nouveau_object *, struct nouveau_object *, 195int nv50_disp_curs_ctor(struct nouveau_object *, struct nouveau_object *,
195 struct nouveau_oclass *, void *, u32, 196 struct nouveau_oclass *, void *, u32,
196 struct nouveau_object **); 197 struct nouveau_object **);
197extern struct nouveau_ofuncs nv50_disp_base_ofuncs; 198extern struct nouveau_ofuncs nv50_disp_main_ofuncs;
198int nv50_disp_base_ctor(struct nouveau_object *, struct nouveau_object *, 199int nv50_disp_main_ctor(struct nouveau_object *, struct nouveau_object *,
199 struct nouveau_oclass *, void *, u32, 200 struct nouveau_oclass *, void *, u32,
200 struct nouveau_object **); 201 struct nouveau_object **);
201void nv50_disp_base_dtor(struct nouveau_object *); 202void nv50_disp_main_dtor(struct nouveau_object *);
202extern struct nouveau_omthds nv50_disp_base_omthds[]; 203extern struct nouveau_omthds nv50_disp_main_omthds[];
203extern struct nouveau_oclass nv50_disp_cclass; 204extern struct nouveau_oclass nv50_disp_cclass;
204void nv50_disp_mthd_chan(struct nv50_disp_priv *, int debug, int head, 205void nv50_disp_mthd_chan(struct nv50_disp_priv *, int debug, int head,
205 const struct nv50_disp_mthd_chan *); 206 const struct nv50_disp_mthd_chan *);
@@ -207,31 +208,31 @@ void nv50_disp_intr_supervisor(struct work_struct *);
207void nv50_disp_intr(struct nouveau_subdev *); 208void nv50_disp_intr(struct nouveau_subdev *);
208extern const struct nvkm_event_func nv50_disp_vblank_func; 209extern const struct nvkm_event_func nv50_disp_vblank_func;
209 210
210extern const struct nv50_disp_mthd_chan nv84_disp_mast_mthd_chan; 211extern const struct nv50_disp_mthd_chan nv84_disp_core_mthd_chan;
211extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_dac; 212extern const struct nv50_disp_mthd_list nv84_disp_core_mthd_dac;
212extern const struct nv50_disp_mthd_list nv84_disp_mast_mthd_head; 213extern const struct nv50_disp_mthd_list nv84_disp_core_mthd_head;
213extern const struct nv50_disp_mthd_chan nv84_disp_sync_mthd_chan; 214extern const struct nv50_disp_mthd_chan nv84_disp_base_mthd_chan;
214extern const struct nv50_disp_mthd_chan nv84_disp_ovly_mthd_chan; 215extern const struct nv50_disp_mthd_chan nv84_disp_ovly_mthd_chan;
215 216
216extern const struct nv50_disp_mthd_chan nv94_disp_mast_mthd_chan; 217extern const struct nv50_disp_mthd_chan nv94_disp_core_mthd_chan;
217 218
218extern struct nv50_disp_chan_impl nvd0_disp_mast_ofuncs; 219extern struct nv50_disp_chan_impl nvd0_disp_core_ofuncs;
219extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_base; 220extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_base;
220extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_dac; 221extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_dac;
221extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_sor; 222extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_sor;
222extern const struct nv50_disp_mthd_list nvd0_disp_mast_mthd_pior; 223extern const struct nv50_disp_mthd_list nvd0_disp_core_mthd_pior;
223extern struct nv50_disp_chan_impl nvd0_disp_sync_ofuncs; 224extern struct nv50_disp_chan_impl nvd0_disp_base_ofuncs;
224extern struct nv50_disp_chan_impl nvd0_disp_ovly_ofuncs; 225extern struct nv50_disp_chan_impl nvd0_disp_ovly_ofuncs;
225extern const struct nv50_disp_mthd_chan nvd0_disp_sync_mthd_chan; 226extern const struct nv50_disp_mthd_chan nvd0_disp_base_mthd_chan;
226extern struct nv50_disp_chan_impl nvd0_disp_oimm_ofuncs; 227extern struct nv50_disp_chan_impl nvd0_disp_oimm_ofuncs;
227extern struct nv50_disp_chan_impl nvd0_disp_curs_ofuncs; 228extern struct nv50_disp_chan_impl nvd0_disp_curs_ofuncs;
228extern struct nouveau_ofuncs nvd0_disp_base_ofuncs; 229extern struct nouveau_ofuncs nvd0_disp_main_ofuncs;
229extern struct nouveau_oclass nvd0_disp_cclass; 230extern struct nouveau_oclass nvd0_disp_cclass;
230void nvd0_disp_intr_supervisor(struct work_struct *); 231void nvd0_disp_intr_supervisor(struct work_struct *);
231void nvd0_disp_intr(struct nouveau_subdev *); 232void nvd0_disp_intr(struct nouveau_subdev *);
232extern const struct nvkm_event_func nvd0_disp_vblank_func; 233extern const struct nvkm_event_func nvd0_disp_vblank_func;
233 234
234extern const struct nv50_disp_mthd_chan nve0_disp_mast_mthd_chan; 235extern const struct nv50_disp_mthd_chan nve0_disp_core_mthd_chan;
235extern const struct nv50_disp_mthd_chan nve0_disp_ovly_mthd_chan; 236extern const struct nv50_disp_mthd_chan nve0_disp_ovly_mthd_chan;
236 237
237extern struct nvkm_output_dp_impl nv50_pior_dp_impl; 238extern struct nvkm_output_dp_impl nv50_pior_dp_impl;
@@ -242,6 +243,10 @@ int nv94_sor_dp_lnk_pwr(struct nvkm_output_dp *, int);
242extern struct nouveau_oclass *nv94_disp_outp_sclass[]; 243extern struct nouveau_oclass *nv94_disp_outp_sclass[];
243 244
244extern struct nvkm_output_dp_impl nvd0_sor_dp_impl; 245extern struct nvkm_output_dp_impl nvd0_sor_dp_impl;
246int nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *, int, int, bool);
245extern struct nouveau_oclass *nvd0_disp_outp_sclass[]; 247extern struct nouveau_oclass *nvd0_disp_outp_sclass[];
246 248
249void gm204_sor_magic(struct nvkm_output *outp);
250extern struct nvkm_output_dp_impl gm204_sor_dp_impl;
251
247#endif 252#endif
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
index d36284715b2a..13eff5e4ee51 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv84.c
@@ -34,7 +34,7 @@
34 ******************************************************************************/ 34 ******************************************************************************/
35 35
36const struct nv50_disp_mthd_list 36const struct nv50_disp_mthd_list
37nv84_disp_mast_mthd_dac = { 37nv84_disp_core_mthd_dac = {
38 .mthd = 0x0080, 38 .mthd = 0x0080,
39 .addr = 0x000008, 39 .addr = 0x000008,
40 .data = { 40 .data = {
@@ -46,7 +46,7 @@ nv84_disp_mast_mthd_dac = {
46}; 46};
47 47
48const struct nv50_disp_mthd_list 48const struct nv50_disp_mthd_list
49nv84_disp_mast_mthd_head = { 49nv84_disp_core_mthd_head = {
50 .mthd = 0x0400, 50 .mthd = 0x0400,
51 .addr = 0x000540, 51 .addr = 0x000540,
52 .data = { 52 .data = {
@@ -98,15 +98,15 @@ nv84_disp_mast_mthd_head = {
98}; 98};
99 99
100const struct nv50_disp_mthd_chan 100const struct nv50_disp_mthd_chan
101nv84_disp_mast_mthd_chan = { 101nv84_disp_core_mthd_chan = {
102 .name = "Core", 102 .name = "Core",
103 .addr = 0x000000, 103 .addr = 0x000000,
104 .data = { 104 .data = {
105 { "Global", 1, &nv50_disp_mast_mthd_base }, 105 { "Global", 1, &nv50_disp_core_mthd_base },
106 { "DAC", 3, &nv84_disp_mast_mthd_dac }, 106 { "DAC", 3, &nv84_disp_core_mthd_dac },
107 { "SOR", 2, &nv50_disp_mast_mthd_sor }, 107 { "SOR", 2, &nv50_disp_core_mthd_sor },
108 { "PIOR", 3, &nv50_disp_mast_mthd_pior }, 108 { "PIOR", 3, &nv50_disp_core_mthd_pior },
109 { "HEAD", 2, &nv84_disp_mast_mthd_head }, 109 { "HEAD", 2, &nv84_disp_core_mthd_head },
110 {} 110 {}
111 } 111 }
112}; 112};
@@ -116,7 +116,7 @@ nv84_disp_mast_mthd_chan = {
116 ******************************************************************************/ 116 ******************************************************************************/
117 117
118static const struct nv50_disp_mthd_list 118static const struct nv50_disp_mthd_list
119nv84_disp_sync_mthd_base = { 119nv84_disp_base_mthd_base = {
120 .mthd = 0x0000, 120 .mthd = 0x0000,
121 .addr = 0x000000, 121 .addr = 0x000000,
122 .data = { 122 .data = {
@@ -146,12 +146,12 @@ nv84_disp_sync_mthd_base = {
146}; 146};
147 147
148const struct nv50_disp_mthd_chan 148const struct nv50_disp_mthd_chan
149nv84_disp_sync_mthd_chan = { 149nv84_disp_base_mthd_chan = {
150 .name = "Base", 150 .name = "Base",
151 .addr = 0x000540, 151 .addr = 0x000540,
152 .data = { 152 .data = {
153 { "Global", 1, &nv84_disp_sync_mthd_base }, 153 { "Global", 1, &nv84_disp_base_mthd_base },
154 { "Image", 2, &nv50_disp_sync_mthd_image }, 154 { "Image", 2, &nv50_disp_base_mthd_image },
155 {} 155 {}
156 } 156 }
157}; 157};
@@ -204,8 +204,8 @@ nv84_disp_ovly_mthd_chan = {
204 204
205static struct nouveau_oclass 205static struct nouveau_oclass
206nv84_disp_sclass[] = { 206nv84_disp_sclass[] = {
207 { G82_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, 207 { G82_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
208 { G82_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, 208 { G82_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
209 { G82_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, 209 { G82_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
210 { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, 210 { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
211 { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, 211 { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
@@ -213,8 +213,8 @@ nv84_disp_sclass[] = {
213}; 213};
214 214
215static struct nouveau_oclass 215static struct nouveau_oclass
216nv84_disp_base_oclass[] = { 216nv84_disp_main_oclass[] = {
217 { G82_DISP, &nv50_disp_base_ofuncs }, 217 { G82_DISP, &nv50_disp_main_ofuncs },
218 {} 218 {}
219}; 219};
220 220
@@ -240,7 +240,7 @@ nv84_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
240 if (ret) 240 if (ret)
241 return ret; 241 return ret;
242 242
243 nv_engine(priv)->sclass = nv84_disp_base_oclass; 243 nv_engine(priv)->sclass = nv84_disp_main_oclass;
244 nv_engine(priv)->cclass = &nv50_disp_cclass; 244 nv_engine(priv)->cclass = &nv50_disp_cclass;
245 nv_subdev(priv)->intr = nv50_disp_intr; 245 nv_subdev(priv)->intr = nv50_disp_intr;
246 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); 246 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
@@ -268,9 +268,9 @@ nv84_disp_oclass = &(struct nv50_disp_impl) {
268 }, 268 },
269 .base.vblank = &nv50_disp_vblank_func, 269 .base.vblank = &nv50_disp_vblank_func,
270 .base.outp = nv50_disp_outp_sclass, 270 .base.outp = nv50_disp_outp_sclass,
271 .mthd.core = &nv84_disp_mast_mthd_chan, 271 .mthd.core = &nv84_disp_core_mthd_chan,
272 .mthd.base = &nv84_disp_sync_mthd_chan, 272 .mthd.base = &nv84_disp_base_mthd_chan,
273 .mthd.ovly = &nv84_disp_ovly_mthd_chan, 273 .mthd.ovly = &nv84_disp_ovly_mthd_chan,
274 .mthd.prev = 0x000004, 274 .mthd.prev = 0x000004,
275 .head.scanoutpos = nv50_disp_base_scanoutpos, 275 .head.scanoutpos = nv50_disp_main_scanoutpos,
276}.base.base; 276}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
index a117064002b1..2bb7ac5cd0e6 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nv94.c
@@ -34,7 +34,7 @@
34 ******************************************************************************/ 34 ******************************************************************************/
35 35
36const struct nv50_disp_mthd_list 36const struct nv50_disp_mthd_list
37nv94_disp_mast_mthd_sor = { 37nv94_disp_core_mthd_sor = {
38 .mthd = 0x0040, 38 .mthd = 0x0040,
39 .addr = 0x000008, 39 .addr = 0x000008,
40 .data = { 40 .data = {
@@ -44,15 +44,15 @@ nv94_disp_mast_mthd_sor = {
44}; 44};
45 45
46const struct nv50_disp_mthd_chan 46const struct nv50_disp_mthd_chan
47nv94_disp_mast_mthd_chan = { 47nv94_disp_core_mthd_chan = {
48 .name = "Core", 48 .name = "Core",
49 .addr = 0x000000, 49 .addr = 0x000000,
50 .data = { 50 .data = {
51 { "Global", 1, &nv50_disp_mast_mthd_base }, 51 { "Global", 1, &nv50_disp_core_mthd_base },
52 { "DAC", 3, &nv84_disp_mast_mthd_dac }, 52 { "DAC", 3, &nv84_disp_core_mthd_dac },
53 { "SOR", 4, &nv94_disp_mast_mthd_sor }, 53 { "SOR", 4, &nv94_disp_core_mthd_sor },
54 { "PIOR", 3, &nv50_disp_mast_mthd_pior }, 54 { "PIOR", 3, &nv50_disp_core_mthd_pior },
55 { "HEAD", 2, &nv84_disp_mast_mthd_head }, 55 { "HEAD", 2, &nv84_disp_core_mthd_head },
56 {} 56 {}
57 } 57 }
58}; 58};
@@ -63,8 +63,8 @@ nv94_disp_mast_mthd_chan = {
63 63
64static struct nouveau_oclass 64static struct nouveau_oclass
65nv94_disp_sclass[] = { 65nv94_disp_sclass[] = {
66 { GT206_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, 66 { GT206_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
67 { GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, 67 { GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
68 { GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, 68 { GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
69 { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, 69 { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
70 { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, 70 { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
@@ -72,8 +72,8 @@ nv94_disp_sclass[] = {
72}; 72};
73 73
74static struct nouveau_oclass 74static struct nouveau_oclass
75nv94_disp_base_oclass[] = { 75nv94_disp_main_oclass[] = {
76 { GT206_DISP, &nv50_disp_base_ofuncs }, 76 { GT206_DISP, &nv50_disp_main_ofuncs },
77 {} 77 {}
78}; 78};
79 79
@@ -99,7 +99,7 @@ nv94_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
99 if (ret) 99 if (ret)
100 return ret; 100 return ret;
101 101
102 nv_engine(priv)->sclass = nv94_disp_base_oclass; 102 nv_engine(priv)->sclass = nv94_disp_main_oclass;
103 nv_engine(priv)->cclass = &nv50_disp_cclass; 103 nv_engine(priv)->cclass = &nv50_disp_cclass;
104 nv_subdev(priv)->intr = nv50_disp_intr; 104 nv_subdev(priv)->intr = nv50_disp_intr;
105 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); 105 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
@@ -134,9 +134,9 @@ nv94_disp_oclass = &(struct nv50_disp_impl) {
134 }, 134 },
135 .base.vblank = &nv50_disp_vblank_func, 135 .base.vblank = &nv50_disp_vblank_func,
136 .base.outp = nv94_disp_outp_sclass, 136 .base.outp = nv94_disp_outp_sclass,
137 .mthd.core = &nv94_disp_mast_mthd_chan, 137 .mthd.core = &nv94_disp_core_mthd_chan,
138 .mthd.base = &nv84_disp_sync_mthd_chan, 138 .mthd.base = &nv84_disp_base_mthd_chan,
139 .mthd.ovly = &nv84_disp_ovly_mthd_chan, 139 .mthd.ovly = &nv84_disp_ovly_mthd_chan,
140 .mthd.prev = 0x000004, 140 .mthd.prev = 0x000004,
141 .head.scanoutpos = nv50_disp_base_scanoutpos, 141 .head.scanoutpos = nv50_disp_main_scanoutpos,
142}.base.base; 142}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
index c67e68aadd45..b32456c9494f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva0.c
@@ -80,8 +80,8 @@ nva0_disp_ovly_mthd_chan = {
80 80
81static struct nouveau_oclass 81static struct nouveau_oclass
82nva0_disp_sclass[] = { 82nva0_disp_sclass[] = {
83 { GT200_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, 83 { GT200_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
84 { GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, 84 { GT200_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
85 { GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, 85 { GT200_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
86 { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, 86 { G82_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
87 { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, 87 { G82_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
@@ -89,8 +89,8 @@ nva0_disp_sclass[] = {
89}; 89};
90 90
91static struct nouveau_oclass 91static struct nouveau_oclass
92nva0_disp_base_oclass[] = { 92nva0_disp_main_oclass[] = {
93 { GT200_DISP, &nv50_disp_base_ofuncs }, 93 { GT200_DISP, &nv50_disp_main_ofuncs },
94 {} 94 {}
95}; 95};
96 96
@@ -116,7 +116,7 @@ nva0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
116 if (ret) 116 if (ret)
117 return ret; 117 return ret;
118 118
119 nv_engine(priv)->sclass = nva0_disp_base_oclass; 119 nv_engine(priv)->sclass = nva0_disp_main_oclass;
120 nv_engine(priv)->cclass = &nv50_disp_cclass; 120 nv_engine(priv)->cclass = &nv50_disp_cclass;
121 nv_subdev(priv)->intr = nv50_disp_intr; 121 nv_subdev(priv)->intr = nv50_disp_intr;
122 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); 122 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
@@ -144,9 +144,9 @@ nva0_disp_oclass = &(struct nv50_disp_impl) {
144 }, 144 },
145 .base.vblank = &nv50_disp_vblank_func, 145 .base.vblank = &nv50_disp_vblank_func,
146 .base.outp = nv50_disp_outp_sclass, 146 .base.outp = nv50_disp_outp_sclass,
147 .mthd.core = &nv84_disp_mast_mthd_chan, 147 .mthd.core = &nv84_disp_core_mthd_chan,
148 .mthd.base = &nv84_disp_sync_mthd_chan, 148 .mthd.base = &nv84_disp_base_mthd_chan,
149 .mthd.ovly = &nva0_disp_ovly_mthd_chan, 149 .mthd.ovly = &nva0_disp_ovly_mthd_chan,
150 .mthd.prev = 0x000004, 150 .mthd.prev = 0x000004,
151 .head.scanoutpos = nv50_disp_base_scanoutpos, 151 .head.scanoutpos = nv50_disp_main_scanoutpos,
152}.base.base; 152}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
index 22969f355aae..951d79f9b781 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nva3.c
@@ -35,8 +35,8 @@
35 35
36static struct nouveau_oclass 36static struct nouveau_oclass
37nva3_disp_sclass[] = { 37nva3_disp_sclass[] = {
38 { GT214_DISP_CORE_CHANNEL_DMA, &nv50_disp_mast_ofuncs.base }, 38 { GT214_DISP_CORE_CHANNEL_DMA, &nv50_disp_core_ofuncs.base },
39 { GT214_DISP_BASE_CHANNEL_DMA, &nv50_disp_sync_ofuncs.base }, 39 { GT214_DISP_BASE_CHANNEL_DMA, &nv50_disp_base_ofuncs.base },
40 { GT214_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base }, 40 { GT214_DISP_OVERLAY_CHANNEL_DMA, &nv50_disp_ovly_ofuncs.base },
41 { GT214_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base }, 41 { GT214_DISP_OVERLAY, &nv50_disp_oimm_ofuncs.base },
42 { GT214_DISP_CURSOR, &nv50_disp_curs_ofuncs.base }, 42 { GT214_DISP_CURSOR, &nv50_disp_curs_ofuncs.base },
@@ -44,8 +44,8 @@ nva3_disp_sclass[] = {
44}; 44};
45 45
46static struct nouveau_oclass 46static struct nouveau_oclass
47nva3_disp_base_oclass[] = { 47nva3_disp_main_oclass[] = {
48 { GT214_DISP, &nv50_disp_base_ofuncs }, 48 { GT214_DISP, &nv50_disp_main_ofuncs },
49 {} 49 {}
50}; 50};
51 51
@@ -71,7 +71,7 @@ nva3_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
71 if (ret) 71 if (ret)
72 return ret; 72 return ret;
73 73
74 nv_engine(priv)->sclass = nva3_disp_base_oclass; 74 nv_engine(priv)->sclass = nva3_disp_main_oclass;
75 nv_engine(priv)->cclass = &nv50_disp_cclass; 75 nv_engine(priv)->cclass = &nv50_disp_cclass;
76 nv_subdev(priv)->intr = nv50_disp_intr; 76 nv_subdev(priv)->intr = nv50_disp_intr;
77 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor); 77 INIT_WORK(&priv->supervisor, nv50_disp_intr_supervisor);
@@ -100,9 +100,9 @@ nva3_disp_oclass = &(struct nv50_disp_impl) {
100 }, 100 },
101 .base.vblank = &nv50_disp_vblank_func, 101 .base.vblank = &nv50_disp_vblank_func,
102 .base.outp = nv94_disp_outp_sclass, 102 .base.outp = nv94_disp_outp_sclass,
103 .mthd.core = &nv94_disp_mast_mthd_chan, 103 .mthd.core = &nv94_disp_core_mthd_chan,
104 .mthd.base = &nv84_disp_sync_mthd_chan, 104 .mthd.base = &nv84_disp_base_mthd_chan,
105 .mthd.ovly = &nv84_disp_ovly_mthd_chan, 105 .mthd.ovly = &nv84_disp_ovly_mthd_chan,
106 .mthd.prev = 0x000004, 106 .mthd.prev = 0x000004,
107 .head.scanoutpos = nv50_disp_base_scanoutpos, 107 .head.scanoutpos = nv50_disp_main_scanoutpos,
108}.base.base; 108}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
index 747e64bb9c06..181a2d57e356 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvd0.c
@@ -51,12 +51,14 @@ nvd0_disp_chan_uevent_fini(struct nvkm_event *event, int type, int index)
51{ 51{
52 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent); 52 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
53 nv_mask(priv, 0x610090, 0x00000001 << index, 0x00000000 << index); 53 nv_mask(priv, 0x610090, 0x00000001 << index, 0x00000000 << index);
54 nv_wr32(priv, 0x61008c, 0x00000001 << index);
54} 55}
55 56
56static void 57static void
57nvd0_disp_chan_uevent_init(struct nvkm_event *event, int types, int index) 58nvd0_disp_chan_uevent_init(struct nvkm_event *event, int types, int index)
58{ 59{
59 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent); 60 struct nv50_disp_priv *priv = container_of(event, typeof(*priv), uevent);
61 nv_wr32(priv, 0x61008c, 0x00000001 << index);
60 nv_mask(priv, 0x610090, 0x00000001 << index, 0x00000001 << index); 62 nv_mask(priv, 0x610090, 0x00000001 << index, 0x00000001 << index);
61} 63}
62 64
@@ -151,7 +153,7 @@ nvd0_disp_dmac_fini(struct nouveau_object *object, bool suspend)
151 ******************************************************************************/ 153 ******************************************************************************/
152 154
153const struct nv50_disp_mthd_list 155const struct nv50_disp_mthd_list
154nvd0_disp_mast_mthd_base = { 156nvd0_disp_core_mthd_base = {
155 .mthd = 0x0000, 157 .mthd = 0x0000,
156 .addr = 0x000000, 158 .addr = 0x000000,
157 .data = { 159 .data = {
@@ -164,7 +166,7 @@ nvd0_disp_mast_mthd_base = {
164}; 166};
165 167
166const struct nv50_disp_mthd_list 168const struct nv50_disp_mthd_list
167nvd0_disp_mast_mthd_dac = { 169nvd0_disp_core_mthd_dac = {
168 .mthd = 0x0020, 170 .mthd = 0x0020,
169 .addr = 0x000020, 171 .addr = 0x000020,
170 .data = { 172 .data = {
@@ -177,7 +179,7 @@ nvd0_disp_mast_mthd_dac = {
177}; 179};
178 180
179const struct nv50_disp_mthd_list 181const struct nv50_disp_mthd_list
180nvd0_disp_mast_mthd_sor = { 182nvd0_disp_core_mthd_sor = {
181 .mthd = 0x0020, 183 .mthd = 0x0020,
182 .addr = 0x000020, 184 .addr = 0x000020,
183 .data = { 185 .data = {
@@ -190,7 +192,7 @@ nvd0_disp_mast_mthd_sor = {
190}; 192};
191 193
192const struct nv50_disp_mthd_list 194const struct nv50_disp_mthd_list
193nvd0_disp_mast_mthd_pior = { 195nvd0_disp_core_mthd_pior = {
194 .mthd = 0x0020, 196 .mthd = 0x0020,
195 .addr = 0x000020, 197 .addr = 0x000020,
196 .data = { 198 .data = {
@@ -203,7 +205,7 @@ nvd0_disp_mast_mthd_pior = {
203}; 205};
204 206
205static const struct nv50_disp_mthd_list 207static const struct nv50_disp_mthd_list
206nvd0_disp_mast_mthd_head = { 208nvd0_disp_core_mthd_head = {
207 .mthd = 0x0300, 209 .mthd = 0x0300,
208 .addr = 0x000300, 210 .addr = 0x000300,
209 .data = { 211 .data = {
@@ -277,21 +279,21 @@ nvd0_disp_mast_mthd_head = {
277}; 279};
278 280
279static const struct nv50_disp_mthd_chan 281static const struct nv50_disp_mthd_chan
280nvd0_disp_mast_mthd_chan = { 282nvd0_disp_core_mthd_chan = {
281 .name = "Core", 283 .name = "Core",
282 .addr = 0x000000, 284 .addr = 0x000000,
283 .data = { 285 .data = {
284 { "Global", 1, &nvd0_disp_mast_mthd_base }, 286 { "Global", 1, &nvd0_disp_core_mthd_base },
285 { "DAC", 3, &nvd0_disp_mast_mthd_dac }, 287 { "DAC", 3, &nvd0_disp_core_mthd_dac },
286 { "SOR", 8, &nvd0_disp_mast_mthd_sor }, 288 { "SOR", 8, &nvd0_disp_core_mthd_sor },
287 { "PIOR", 4, &nvd0_disp_mast_mthd_pior }, 289 { "PIOR", 4, &nvd0_disp_core_mthd_pior },
288 { "HEAD", 4, &nvd0_disp_mast_mthd_head }, 290 { "HEAD", 4, &nvd0_disp_core_mthd_head },
289 {} 291 {}
290 } 292 }
291}; 293};
292 294
293static int 295static int
294nvd0_disp_mast_init(struct nouveau_object *object) 296nvd0_disp_core_init(struct nouveau_object *object)
295{ 297{
296 struct nv50_disp_priv *priv = (void *)object->engine; 298 struct nv50_disp_priv *priv = (void *)object->engine;
297 struct nv50_disp_dmac *mast = (void *)object; 299 struct nv50_disp_dmac *mast = (void *)object;
@@ -322,7 +324,7 @@ nvd0_disp_mast_init(struct nouveau_object *object)
322} 324}
323 325
324static int 326static int
325nvd0_disp_mast_fini(struct nouveau_object *object, bool suspend) 327nvd0_disp_core_fini(struct nouveau_object *object, bool suspend)
326{ 328{
327 struct nv50_disp_priv *priv = (void *)object->engine; 329 struct nv50_disp_priv *priv = (void *)object->engine;
328 struct nv50_disp_dmac *mast = (void *)object; 330 struct nv50_disp_dmac *mast = (void *)object;
@@ -344,11 +346,11 @@ nvd0_disp_mast_fini(struct nouveau_object *object, bool suspend)
344} 346}
345 347
346struct nv50_disp_chan_impl 348struct nv50_disp_chan_impl
347nvd0_disp_mast_ofuncs = { 349nvd0_disp_core_ofuncs = {
348 .base.ctor = nv50_disp_mast_ctor, 350 .base.ctor = nv50_disp_core_ctor,
349 .base.dtor = nv50_disp_dmac_dtor, 351 .base.dtor = nv50_disp_dmac_dtor,
350 .base.init = nvd0_disp_mast_init, 352 .base.init = nvd0_disp_core_init,
351 .base.fini = nvd0_disp_mast_fini, 353 .base.fini = nvd0_disp_core_fini,
352 .base.ntfy = nv50_disp_chan_ntfy, 354 .base.ntfy = nv50_disp_chan_ntfy,
353 .base.map = nv50_disp_chan_map, 355 .base.map = nv50_disp_chan_map,
354 .base.rd32 = nv50_disp_chan_rd32, 356 .base.rd32 = nv50_disp_chan_rd32,
@@ -363,7 +365,7 @@ nvd0_disp_mast_ofuncs = {
363 ******************************************************************************/ 365 ******************************************************************************/
364 366
365static const struct nv50_disp_mthd_list 367static const struct nv50_disp_mthd_list
366nvd0_disp_sync_mthd_base = { 368nvd0_disp_base_mthd_base = {
367 .mthd = 0x0000, 369 .mthd = 0x0000,
368 .addr = 0x000000, 370 .addr = 0x000000,
369 .data = { 371 .data = {
@@ -413,7 +415,7 @@ nvd0_disp_sync_mthd_base = {
413}; 415};
414 416
415static const struct nv50_disp_mthd_list 417static const struct nv50_disp_mthd_list
416nvd0_disp_sync_mthd_image = { 418nvd0_disp_base_mthd_image = {
417 .mthd = 0x0400, 419 .mthd = 0x0400,
418 .addr = 0x000400, 420 .addr = 0x000400,
419 .data = { 421 .data = {
@@ -427,19 +429,19 @@ nvd0_disp_sync_mthd_image = {
427}; 429};
428 430
429const struct nv50_disp_mthd_chan 431const struct nv50_disp_mthd_chan
430nvd0_disp_sync_mthd_chan = { 432nvd0_disp_base_mthd_chan = {
431 .name = "Base", 433 .name = "Base",
432 .addr = 0x001000, 434 .addr = 0x001000,
433 .data = { 435 .data = {
434 { "Global", 1, &nvd0_disp_sync_mthd_base }, 436 { "Global", 1, &nvd0_disp_base_mthd_base },
435 { "Image", 2, &nvd0_disp_sync_mthd_image }, 437 { "Image", 2, &nvd0_disp_base_mthd_image },
436 {} 438 {}
437 } 439 }
438}; 440};
439 441
440struct nv50_disp_chan_impl 442struct nv50_disp_chan_impl
441nvd0_disp_sync_ofuncs = { 443nvd0_disp_base_ofuncs = {
442 .base.ctor = nv50_disp_sync_ctor, 444 .base.ctor = nv50_disp_base_ctor,
443 .base.dtor = nv50_disp_dmac_dtor, 445 .base.dtor = nv50_disp_dmac_dtor,
444 .base.init = nvd0_disp_dmac_init, 446 .base.init = nvd0_disp_dmac_init,
445 .base.fini = nvd0_disp_dmac_fini, 447 .base.fini = nvd0_disp_dmac_fini,
@@ -624,7 +626,7 @@ nvd0_disp_curs_ofuncs = {
624 ******************************************************************************/ 626 ******************************************************************************/
625 627
626int 628int
627nvd0_disp_base_scanoutpos(NV50_DISP_MTHD_V0) 629nvd0_disp_main_scanoutpos(NV50_DISP_MTHD_V0)
628{ 630{
629 const u32 total = nv_rd32(priv, 0x640414 + (head * 0x300)); 631 const u32 total = nv_rd32(priv, 0x640414 + (head * 0x300));
630 const u32 blanke = nv_rd32(priv, 0x64041c + (head * 0x300)); 632 const u32 blanke = nv_rd32(priv, 0x64041c + (head * 0x300));
@@ -656,7 +658,7 @@ nvd0_disp_base_scanoutpos(NV50_DISP_MTHD_V0)
656} 658}
657 659
658static int 660static int
659nvd0_disp_base_init(struct nouveau_object *object) 661nvd0_disp_main_init(struct nouveau_object *object)
660{ 662{
661 struct nv50_disp_priv *priv = (void *)object->engine; 663 struct nv50_disp_priv *priv = (void *)object->engine;
662 struct nv50_disp_base *base = (void *)object; 664 struct nv50_disp_base *base = (void *)object;
@@ -725,7 +727,7 @@ nvd0_disp_base_init(struct nouveau_object *object)
725} 727}
726 728
727static int 729static int
728nvd0_disp_base_fini(struct nouveau_object *object, bool suspend) 730nvd0_disp_main_fini(struct nouveau_object *object, bool suspend)
729{ 731{
730 struct nv50_disp_priv *priv = (void *)object->engine; 732 struct nv50_disp_priv *priv = (void *)object->engine;
731 struct nv50_disp_base *base = (void *)object; 733 struct nv50_disp_base *base = (void *)object;
@@ -737,25 +739,25 @@ nvd0_disp_base_fini(struct nouveau_object *object, bool suspend)
737} 739}
738 740
739struct nouveau_ofuncs 741struct nouveau_ofuncs
740nvd0_disp_base_ofuncs = { 742nvd0_disp_main_ofuncs = {
741 .ctor = nv50_disp_base_ctor, 743 .ctor = nv50_disp_main_ctor,
742 .dtor = nv50_disp_base_dtor, 744 .dtor = nv50_disp_main_dtor,
743 .init = nvd0_disp_base_init, 745 .init = nvd0_disp_main_init,
744 .fini = nvd0_disp_base_fini, 746 .fini = nvd0_disp_main_fini,
745 .mthd = nv50_disp_base_mthd, 747 .mthd = nv50_disp_main_mthd,
746 .ntfy = nouveau_disp_ntfy, 748 .ntfy = nouveau_disp_ntfy,
747}; 749};
748 750
749static struct nouveau_oclass 751static struct nouveau_oclass
750nvd0_disp_base_oclass[] = { 752nvd0_disp_main_oclass[] = {
751 { GF110_DISP, &nvd0_disp_base_ofuncs }, 753 { GF110_DISP, &nvd0_disp_main_ofuncs },
752 {} 754 {}
753}; 755};
754 756
755static struct nouveau_oclass 757static struct nouveau_oclass
756nvd0_disp_sclass[] = { 758nvd0_disp_sclass[] = {
757 { GF110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, 759 { GF110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
758 { GF110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, 760 { GF110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
759 { GF110_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, 761 { GF110_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
760 { GF110_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, 762 { GF110_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
761 { GF110_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, 763 { GF110_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
@@ -1055,6 +1057,9 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
1055 1057
1056 if (nvkm_output_dp_train(outp, pclk, true)) 1058 if (nvkm_output_dp_train(outp, pclk, true))
1057 ERR("link not trained before attach\n"); 1059 ERR("link not trained before attach\n");
1060 } else {
1061 if (priv->sor.magic)
1062 priv->sor.magic(outp);
1058 } 1063 }
1059 1064
1060 exec_clkcmp(priv, head, 0, pclk, &conf); 1065 exec_clkcmp(priv, head, 0, pclk, &conf);
@@ -1063,10 +1068,18 @@ nvd0_disp_intr_unk2_2(struct nv50_disp_priv *priv, int head)
1063 addr = 0x612280 + (ffs(outp->info.or) - 1) * 0x800; 1068 addr = 0x612280 + (ffs(outp->info.or) - 1) * 0x800;
1064 data = 0x00000000; 1069 data = 0x00000000;
1065 } else { 1070 } else {
1066 if (outp->info.type == DCB_OUTPUT_DP)
1067 nvd0_disp_intr_unk2_2_tu(priv, head, &outp->info);
1068 addr = 0x612300 + (ffs(outp->info.or) - 1) * 0x800; 1071 addr = 0x612300 + (ffs(outp->info.or) - 1) * 0x800;
1069 data = (conf & 0x0100) ? 0x00000101 : 0x00000000; 1072 data = (conf & 0x0100) ? 0x00000101 : 0x00000000;
1073 switch (outp->info.type) {
1074 case DCB_OUTPUT_TMDS:
1075 nv_mask(priv, addr, 0x007c0000, 0x00280000);
1076 break;
1077 case DCB_OUTPUT_DP:
1078 nvd0_disp_intr_unk2_2_tu(priv, head, &outp->info);
1079 break;
1080 default:
1081 break;
1082 }
1070 } 1083 }
1071 1084
1072 nv_mask(priv, addr, 0x00000707, data); 1085 nv_mask(priv, addr, 0x00000707, data);
@@ -1259,7 +1272,7 @@ nvd0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1259 if (ret) 1272 if (ret)
1260 return ret; 1273 return ret;
1261 1274
1262 nv_engine(priv)->sclass = nvd0_disp_base_oclass; 1275 nv_engine(priv)->sclass = nvd0_disp_main_oclass;
1263 nv_engine(priv)->cclass = &nv50_disp_cclass; 1276 nv_engine(priv)->cclass = &nv50_disp_cclass;
1264 nv_subdev(priv)->intr = nvd0_disp_intr; 1277 nv_subdev(priv)->intr = nvd0_disp_intr;
1265 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor); 1278 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
@@ -1292,9 +1305,9 @@ nvd0_disp_oclass = &(struct nv50_disp_impl) {
1292 }, 1305 },
1293 .base.vblank = &nvd0_disp_vblank_func, 1306 .base.vblank = &nvd0_disp_vblank_func,
1294 .base.outp = nvd0_disp_outp_sclass, 1307 .base.outp = nvd0_disp_outp_sclass,
1295 .mthd.core = &nvd0_disp_mast_mthd_chan, 1308 .mthd.core = &nvd0_disp_core_mthd_chan,
1296 .mthd.base = &nvd0_disp_sync_mthd_chan, 1309 .mthd.base = &nvd0_disp_base_mthd_chan,
1297 .mthd.ovly = &nvd0_disp_ovly_mthd_chan, 1310 .mthd.ovly = &nvd0_disp_ovly_mthd_chan,
1298 .mthd.prev = -0x020000, 1311 .mthd.prev = -0x020000,
1299 .head.scanoutpos = nvd0_disp_base_scanoutpos, 1312 .head.scanoutpos = nvd0_disp_main_scanoutpos,
1300}.base.base; 1313}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
index db144b2cf06b..55debec7e68f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nve0.c
@@ -34,7 +34,7 @@
34 ******************************************************************************/ 34 ******************************************************************************/
35 35
36static const struct nv50_disp_mthd_list 36static const struct nv50_disp_mthd_list
37nve0_disp_mast_mthd_head = { 37nve0_disp_core_mthd_head = {
38 .mthd = 0x0300, 38 .mthd = 0x0300,
39 .addr = 0x000300, 39 .addr = 0x000300,
40 .data = { 40 .data = {
@@ -113,15 +113,15 @@ nve0_disp_mast_mthd_head = {
113}; 113};
114 114
115const struct nv50_disp_mthd_chan 115const struct nv50_disp_mthd_chan
116nve0_disp_mast_mthd_chan = { 116nve0_disp_core_mthd_chan = {
117 .name = "Core", 117 .name = "Core",
118 .addr = 0x000000, 118 .addr = 0x000000,
119 .data = { 119 .data = {
120 { "Global", 1, &nvd0_disp_mast_mthd_base }, 120 { "Global", 1, &nvd0_disp_core_mthd_base },
121 { "DAC", 3, &nvd0_disp_mast_mthd_dac }, 121 { "DAC", 3, &nvd0_disp_core_mthd_dac },
122 { "SOR", 8, &nvd0_disp_mast_mthd_sor }, 122 { "SOR", 8, &nvd0_disp_core_mthd_sor },
123 { "PIOR", 4, &nvd0_disp_mast_mthd_pior }, 123 { "PIOR", 4, &nvd0_disp_core_mthd_pior },
124 { "HEAD", 4, &nve0_disp_mast_mthd_head }, 124 { "HEAD", 4, &nve0_disp_core_mthd_head },
125 {} 125 {}
126 } 126 }
127}; 127};
@@ -200,8 +200,8 @@ nve0_disp_ovly_mthd_chan = {
200 200
201static struct nouveau_oclass 201static struct nouveau_oclass
202nve0_disp_sclass[] = { 202nve0_disp_sclass[] = {
203 { GK104_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, 203 { GK104_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
204 { GK104_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, 204 { GK104_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
205 { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, 205 { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
206 { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, 206 { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
207 { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, 207 { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
@@ -209,8 +209,8 @@ nve0_disp_sclass[] = {
209}; 209};
210 210
211static struct nouveau_oclass 211static struct nouveau_oclass
212nve0_disp_base_oclass[] = { 212nve0_disp_main_oclass[] = {
213 { GK104_DISP, &nvd0_disp_base_ofuncs }, 213 { GK104_DISP, &nvd0_disp_main_ofuncs },
214 {} 214 {}
215}; 215};
216 216
@@ -237,7 +237,7 @@ nve0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
237 if (ret) 237 if (ret)
238 return ret; 238 return ret;
239 239
240 nv_engine(priv)->sclass = nve0_disp_base_oclass; 240 nv_engine(priv)->sclass = nve0_disp_main_oclass;
241 nv_engine(priv)->cclass = &nv50_disp_cclass; 241 nv_engine(priv)->cclass = &nv50_disp_cclass;
242 nv_subdev(priv)->intr = nvd0_disp_intr; 242 nv_subdev(priv)->intr = nvd0_disp_intr;
243 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor); 243 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
@@ -264,9 +264,9 @@ nve0_disp_oclass = &(struct nv50_disp_impl) {
264 }, 264 },
265 .base.vblank = &nvd0_disp_vblank_func, 265 .base.vblank = &nvd0_disp_vblank_func,
266 .base.outp = nvd0_disp_outp_sclass, 266 .base.outp = nvd0_disp_outp_sclass,
267 .mthd.core = &nve0_disp_mast_mthd_chan, 267 .mthd.core = &nve0_disp_core_mthd_chan,
268 .mthd.base = &nvd0_disp_sync_mthd_chan, 268 .mthd.base = &nvd0_disp_base_mthd_chan,
269 .mthd.ovly = &nve0_disp_ovly_mthd_chan, 269 .mthd.ovly = &nve0_disp_ovly_mthd_chan,
270 .mthd.prev = -0x020000, 270 .mthd.prev = -0x020000,
271 .head.scanoutpos = nvd0_disp_base_scanoutpos, 271 .head.scanoutpos = nvd0_disp_main_scanoutpos,
272}.base.base; 272}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c b/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
index 402d7d67d806..3e7e2d28744c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/nvf0.c
@@ -35,8 +35,8 @@
35 35
36static struct nouveau_oclass 36static struct nouveau_oclass
37nvf0_disp_sclass[] = { 37nvf0_disp_sclass[] = {
38 { GK110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_mast_ofuncs.base }, 38 { GK110_DISP_CORE_CHANNEL_DMA, &nvd0_disp_core_ofuncs.base },
39 { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_sync_ofuncs.base }, 39 { GK110_DISP_BASE_CHANNEL_DMA, &nvd0_disp_base_ofuncs.base },
40 { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base }, 40 { GK104_DISP_OVERLAY_CONTROL_DMA, &nvd0_disp_ovly_ofuncs.base },
41 { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base }, 41 { GK104_DISP_OVERLAY, &nvd0_disp_oimm_ofuncs.base },
42 { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base }, 42 { GK104_DISP_CURSOR, &nvd0_disp_curs_ofuncs.base },
@@ -44,8 +44,8 @@ nvf0_disp_sclass[] = {
44}; 44};
45 45
46static struct nouveau_oclass 46static struct nouveau_oclass
47nvf0_disp_base_oclass[] = { 47nvf0_disp_main_oclass[] = {
48 { GK110_DISP, &nvd0_disp_base_ofuncs }, 48 { GK110_DISP, &nvd0_disp_main_ofuncs },
49 {} 49 {}
50}; 50};
51 51
@@ -72,7 +72,7 @@ nvf0_disp_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
72 if (ret) 72 if (ret)
73 return ret; 73 return ret;
74 74
75 nv_engine(priv)->sclass = nvf0_disp_base_oclass; 75 nv_engine(priv)->sclass = nvf0_disp_main_oclass;
76 nv_engine(priv)->cclass = &nv50_disp_cclass; 76 nv_engine(priv)->cclass = &nv50_disp_cclass;
77 nv_subdev(priv)->intr = nvd0_disp_intr; 77 nv_subdev(priv)->intr = nvd0_disp_intr;
78 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor); 78 INIT_WORK(&priv->supervisor, nvd0_disp_intr_supervisor);
@@ -99,9 +99,9 @@ nvf0_disp_oclass = &(struct nv50_disp_impl) {
99 }, 99 },
100 .base.vblank = &nvd0_disp_vblank_func, 100 .base.vblank = &nvd0_disp_vblank_func,
101 .base.outp = nvd0_disp_outp_sclass, 101 .base.outp = nvd0_disp_outp_sclass,
102 .mthd.core = &nve0_disp_mast_mthd_chan, 102 .mthd.core = &nve0_disp_core_mthd_chan,
103 .mthd.base = &nvd0_disp_sync_mthd_chan, 103 .mthd.base = &nvd0_disp_base_mthd_chan,
104 .mthd.ovly = &nve0_disp_ovly_mthd_chan, 104 .mthd.ovly = &nve0_disp_ovly_mthd_chan,
105 .mthd.prev = -0x020000, 105 .mthd.prev = -0x020000,
106 .head.scanoutpos = nvd0_disp_base_scanoutpos, 106 .head.scanoutpos = nvd0_disp_main_scanoutpos,
107}.base.base; 107}.base.base;
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/outp.c b/drivers/gpu/drm/nouveau/core/engine/disp/outp.c
index a5ff00a9cedc..bbd9b6fdc90f 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/outp.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/outp.c
@@ -85,7 +85,10 @@ nvkm_output_create_(struct nouveau_object *parent,
85 dcbE->sorconf.link : 0, dcbE->connector, dcbE->i2c_index, 85 dcbE->sorconf.link : 0, dcbE->connector, dcbE->i2c_index,
86 dcbE->bus, dcbE->heads); 86 dcbE->bus, dcbE->heads);
87 87
88 outp->port = i2c->find(i2c, outp->info.i2c_index); 88 if (outp->info.type != DCB_OUTPUT_DP)
89 outp->port = i2c->find(i2c, NV_I2C_PORT(outp->info.i2c_index));
90 else
91 outp->port = i2c->find(i2c, NV_I2C_AUX(outp->info.i2c_index));
89 outp->edid = outp->port; 92 outp->edid = outp->port;
90 93
91 data = nvbios_connEp(bios, outp->info.connector, &ver, &hdr, &connE); 94 data = nvbios_connEp(bios, outp->info.connector, &ver, &hdr, &connE);
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c b/drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c
new file mode 100644
index 000000000000..0b4fad39e9a6
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/sorgm204.c
@@ -0,0 +1,144 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include <core/os.h>
26
27#include <subdev/bios.h>
28#include <subdev/bios/dcb.h>
29#include <subdev/bios/dp.h>
30#include <subdev/bios/init.h>
31#include <subdev/timer.h>
32
33#include "nv50.h"
34
35static inline u32
36gm204_sor_soff(struct nvkm_output_dp *outp)
37{
38 return (ffs(outp->base.info.or) - 1) * 0x800;
39}
40
41static inline u32
42gm204_sor_loff(struct nvkm_output_dp *outp)
43{
44 return gm204_sor_soff(outp) + !(outp->base.info.sorconf.link & 1) * 0x80;
45}
46
47void
48gm204_sor_magic(struct nvkm_output *outp)
49{
50 struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
51 const u32 soff = outp->or * 0x100;
52 const u32 data = outp->or + 1;
53 if (outp->info.sorconf.link & 1)
54 nv_mask(priv, 0x612308 + soff, 0x0000001f, 0x00000000 | data);
55 if (outp->info.sorconf.link & 2)
56 nv_mask(priv, 0x612388 + soff, 0x0000001f, 0x00000010 | data);
57}
58
59static inline u32
60gm204_sor_dp_lane_map(struct nv50_disp_priv *priv, u8 lane)
61{
62 return lane * 0x08;
63}
64
65static int
66gm204_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
67{
68 struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
69 const u32 soff = gm204_sor_soff(outp);
70 const u32 data = 0x01010101 * pattern;
71 if (outp->base.info.sorconf.link & 1)
72 nv_mask(priv, 0x61c110 + soff, 0x0f0f0f0f, data);
73 else
74 nv_mask(priv, 0x61c12c + soff, 0x0f0f0f0f, data);
75 return 0;
76}
77
78static int
79gm204_sor_dp_lnk_pwr(struct nvkm_output_dp *outp, int nr)
80{
81 struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
82 const u32 soff = gm204_sor_soff(outp);
83 const u32 loff = gm204_sor_loff(outp);
84 u32 mask = 0, i;
85
86 for (i = 0; i < nr; i++)
87 mask |= 1 << (gm204_sor_dp_lane_map(priv, i) >> 3);
88
89 nv_mask(priv, 0x61c130 + loff, 0x0000000f, mask);
90 nv_mask(priv, 0x61c034 + soff, 0x80000000, 0x80000000);
91 nv_wait(priv, 0x61c034 + soff, 0x80000000, 0x00000000);
92 return 0;
93}
94
95static int
96gm204_sor_dp_drv_ctl(struct nvkm_output_dp *outp, int ln, int vs, int pe, int pc)
97{
98 struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
99 struct nouveau_bios *bios = nouveau_bios(priv);
100 const u32 shift = gm204_sor_dp_lane_map(priv, ln);
101 const u32 loff = gm204_sor_loff(outp);
102 u32 addr, data[4];
103 u8 ver, hdr, cnt, len;
104 struct nvbios_dpout info;
105 struct nvbios_dpcfg ocfg;
106
107 addr = nvbios_dpout_match(bios, outp->base.info.hasht,
108 outp->base.info.hashm,
109 &ver, &hdr, &cnt, &len, &info);
110 if (!addr)
111 return -ENODEV;
112
113 addr = nvbios_dpcfg_match(bios, addr, pc, vs, pe,
114 &ver, &hdr, &cnt, &len, &ocfg);
115 if (!addr)
116 return -EINVAL;
117
118 data[0] = nv_rd32(priv, 0x61c118 + loff) & ~(0x000000ff << shift);
119 data[1] = nv_rd32(priv, 0x61c120 + loff) & ~(0x000000ff << shift);
120 data[2] = nv_rd32(priv, 0x61c130 + loff);
121 if ((data[2] & 0x0000ff00) < (ocfg.tx_pu << 8) || ln == 0)
122 data[2] = (data[2] & ~0x0000ff00) | (ocfg.tx_pu << 8);
123 nv_wr32(priv, 0x61c118 + loff, data[0] | (ocfg.dc << shift));
124 nv_wr32(priv, 0x61c120 + loff, data[1] | (ocfg.pe << shift));
125 nv_wr32(priv, 0x61c130 + loff, data[2] | (ocfg.tx_pu << 8));
126 data[3] = nv_rd32(priv, 0x61c13c + loff) & ~(0x000000ff << shift);
127 nv_wr32(priv, 0x61c13c + loff, data[3] | (ocfg.pc << shift));
128 return 0;
129}
130
131struct nvkm_output_dp_impl
132gm204_sor_dp_impl = {
133 .base.base.handle = DCB_OUTPUT_DP,
134 .base.base.ofuncs = &(struct nouveau_ofuncs) {
135 .ctor = _nvkm_output_dp_ctor,
136 .dtor = _nvkm_output_dp_dtor,
137 .init = _nvkm_output_dp_init,
138 .fini = _nvkm_output_dp_fini,
139 },
140 .pattern = gm204_sor_dp_pattern,
141 .lnk_pwr = gm204_sor_dp_lnk_pwr,
142 .lnk_ctl = nvd0_sor_dp_lnk_ctl,
143 .drv_ctl = gm204_sor_dp_drv_ctl,
144};
diff --git a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
index 7b7bbc3e459e..fdab2939070c 100644
--- a/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/disp/sornvd0.c
@@ -60,7 +60,7 @@ nvd0_sor_dp_pattern(struct nvkm_output_dp *outp, int pattern)
60 return 0; 60 return 0;
61} 61}
62 62
63static int 63int
64nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef) 64nvd0_sor_dp_lnk_ctl(struct nvkm_output_dp *outp, int nr, int bw, bool ef)
65{ 65{
66 struct nv50_disp_priv *priv = (void *)nouveau_disp(outp); 66 struct nv50_disp_priv *priv = (void *)nouveau_disp(outp);
diff --git a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
index 3fc4f0b0eaca..19f5f6522962 100644
--- a/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/dmaobj/nvd0.c
@@ -51,6 +51,7 @@ nvd0_dmaobj_bind(struct nouveau_dmaobj *dmaobj,
51 case GK104_DISP_CORE_CHANNEL_DMA: 51 case GK104_DISP_CORE_CHANNEL_DMA:
52 case GK110_DISP_CORE_CHANNEL_DMA: 52 case GK110_DISP_CORE_CHANNEL_DMA:
53 case GM107_DISP_CORE_CHANNEL_DMA: 53 case GM107_DISP_CORE_CHANNEL_DMA:
54 case GM204_DISP_CORE_CHANNEL_DMA:
54 case GF110_DISP_BASE_CHANNEL_DMA: 55 case GF110_DISP_BASE_CHANNEL_DMA:
55 case GK104_DISP_BASE_CHANNEL_DMA: 56 case GK104_DISP_BASE_CHANNEL_DMA:
56 case GK110_DISP_BASE_CHANNEL_DMA: 57 case GK110_DISP_BASE_CHANNEL_DMA:
diff --git a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
index f8734eb74eaa..6a8db7c80bd1 100644
--- a/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/fifo/nve0.c
@@ -792,7 +792,7 @@ nve0_fifo_intr_fault(struct nve0_fifo_priv *priv, int unit)
792 nouveau_engctx_put(engctx); 792 nouveau_engctx_put(engctx);
793} 793}
794 794
795static const struct nouveau_bitfield nve0_fifo_pbdma_intr[] = { 795static const struct nouveau_bitfield nve0_fifo_pbdma_intr_0[] = {
796 { 0x00000001, "MEMREQ" }, 796 { 0x00000001, "MEMREQ" },
797 { 0x00000002, "MEMACK_TIMEOUT" }, 797 { 0x00000002, "MEMACK_TIMEOUT" },
798 { 0x00000004, "MEMACK_EXTRA" }, 798 { 0x00000004, "MEMACK_EXTRA" },
@@ -827,9 +827,10 @@ static const struct nouveau_bitfield nve0_fifo_pbdma_intr[] = {
827}; 827};
828 828
829static void 829static void
830nve0_fifo_intr_pbdma(struct nve0_fifo_priv *priv, int unit) 830nve0_fifo_intr_pbdma_0(struct nve0_fifo_priv *priv, int unit)
831{ 831{
832 u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000)); 832 u32 mask = nv_rd32(priv, 0x04010c + (unit * 0x2000));
833 u32 stat = nv_rd32(priv, 0x040108 + (unit * 0x2000)) & mask;
833 u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000)); 834 u32 addr = nv_rd32(priv, 0x0400c0 + (unit * 0x2000));
834 u32 data = nv_rd32(priv, 0x0400c4 + (unit * 0x2000)); 835 u32 data = nv_rd32(priv, 0x0400c4 + (unit * 0x2000));
835 u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0xfff; 836 u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0xfff;
@@ -840,11 +841,12 @@ nve0_fifo_intr_pbdma(struct nve0_fifo_priv *priv, int unit)
840 if (stat & 0x00800000) { 841 if (stat & 0x00800000) {
841 if (!nve0_fifo_swmthd(priv, chid, mthd, data)) 842 if (!nve0_fifo_swmthd(priv, chid, mthd, data))
842 show &= ~0x00800000; 843 show &= ~0x00800000;
844 nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008);
843 } 845 }
844 846
845 if (show) { 847 if (show) {
846 nv_error(priv, "PBDMA%d:", unit); 848 nv_error(priv, "PBDMA%d:", unit);
847 nouveau_bitfield_print(nve0_fifo_pbdma_intr, show); 849 nouveau_bitfield_print(nve0_fifo_pbdma_intr_0, show);
848 pr_cont("\n"); 850 pr_cont("\n");
849 nv_error(priv, 851 nv_error(priv,
850 "PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n", 852 "PBDMA%d: ch %d [%s] subc %d mthd 0x%04x data 0x%08x\n",
@@ -853,10 +855,37 @@ nve0_fifo_intr_pbdma(struct nve0_fifo_priv *priv, int unit)
853 subc, mthd, data); 855 subc, mthd, data);
854 } 856 }
855 857
856 nv_wr32(priv, 0x0400c0 + (unit * 0x2000), 0x80600008);
857 nv_wr32(priv, 0x040108 + (unit * 0x2000), stat); 858 nv_wr32(priv, 0x040108 + (unit * 0x2000), stat);
858} 859}
859 860
861static const struct nouveau_bitfield nve0_fifo_pbdma_intr_1[] = {
862 { 0x00000001, "HCE_RE_ILLEGAL_OP" },
863 { 0x00000002, "HCE_RE_ALIGNB" },
864 { 0x00000004, "HCE_PRIV" },
865 { 0x00000008, "HCE_ILLEGAL_MTHD" },
866 { 0x00000010, "HCE_ILLEGAL_CLASS" },
867 {}
868};
869
870static void
871nve0_fifo_intr_pbdma_1(struct nve0_fifo_priv *priv, int unit)
872{
873 u32 mask = nv_rd32(priv, 0x04014c + (unit * 0x2000));
874 u32 stat = nv_rd32(priv, 0x040148 + (unit * 0x2000)) & mask;
875 u32 chid = nv_rd32(priv, 0x040120 + (unit * 0x2000)) & 0xfff;
876
877 if (stat) {
878 nv_error(priv, "PBDMA%d:", unit);
879 nouveau_bitfield_print(nve0_fifo_pbdma_intr_1, stat);
880 pr_cont("\n");
881 nv_error(priv, "PBDMA%d: ch %d %08x %08x\n", unit, chid,
882 nv_rd32(priv, 0x040150 + (unit * 0x2000)),
883 nv_rd32(priv, 0x040154 + (unit * 0x2000)));
884 }
885
886 nv_wr32(priv, 0x040148 + (unit * 0x2000), stat);
887}
888
860static void 889static void
861nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv) 890nve0_fifo_intr_runlist(struct nve0_fifo_priv *priv)
862{ 891{
@@ -939,7 +968,8 @@ nve0_fifo_intr(struct nouveau_subdev *subdev)
939 u32 mask = nv_rd32(priv, 0x0025a0); 968 u32 mask = nv_rd32(priv, 0x0025a0);
940 while (mask) { 969 while (mask) {
941 u32 unit = __ffs(mask); 970 u32 unit = __ffs(mask);
942 nve0_fifo_intr_pbdma(priv, unit); 971 nve0_fifo_intr_pbdma_0(priv, unit);
972 nve0_fifo_intr_pbdma_1(priv, unit);
943 nv_wr32(priv, 0x0025a0, (1 << unit)); 973 nv_wr32(priv, 0x0025a0, (1 << unit));
944 mask &= ~(1 << unit); 974 mask &= ~(1 << unit);
945 } 975 }
@@ -1022,6 +1052,12 @@ nve0_fifo_init(struct nouveau_object *object)
1022 nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */ 1052 nv_wr32(priv, 0x04010c + (i * 0x2000), 0xfffffeff); /* INTREN */
1023 } 1053 }
1024 1054
1055 /* PBDMA[n].HCE */
1056 for (i = 0; i < priv->spoon_nr; i++) {
1057 nv_wr32(priv, 0x040148 + (i * 0x2000), 0xffffffff); /* INTR */
1058 nv_wr32(priv, 0x04014c + (i * 0x2000), 0xffffffff); /* INTREN */
1059 }
1060
1025 nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12); 1061 nv_wr32(priv, 0x002254, 0x10000000 | priv->user.bar.offset >> 12);
1026 1062
1027 nv_wr32(priv, 0x002100, 0xffffffff); 1063 nv_wr32(priv, 0x002100, 0xffffffff);
diff --git a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
index 30fd1dc64f93..17251e4b9e86 100644
--- a/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/engine/graph/nvc0.c
@@ -1557,7 +1557,7 @@ nvc0_graph_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
1557 nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) || 1557 nvc0_graph_ctor_fw(priv, "fuc409d", &priv->fuc409d) ||
1558 nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) || 1558 nvc0_graph_ctor_fw(priv, "fuc41ac", &priv->fuc41ac) ||
1559 nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad)) 1559 nvc0_graph_ctor_fw(priv, "fuc41ad", &priv->fuc41ad))
1560 return -EINVAL; 1560 return -ENODEV;
1561 priv->firmware = true; 1561 priv->firmware = true;
1562 } 1562 }
1563 1563
diff --git a/drivers/gpu/drm/nouveau/core/include/core/device.h b/drivers/gpu/drm/nouveau/core/include/core/device.h
index 1d9d893929bb..2ec2e50d3676 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/device.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/device.h
@@ -16,6 +16,7 @@ enum nv_subdev_type {
16 * to during POST. 16 * to during POST.
17 */ 17 */
18 NVDEV_SUBDEV_DEVINIT, 18 NVDEV_SUBDEV_DEVINIT,
19 NVDEV_SUBDEV_IBUS,
19 NVDEV_SUBDEV_GPIO, 20 NVDEV_SUBDEV_GPIO,
20 NVDEV_SUBDEV_I2C, 21 NVDEV_SUBDEV_I2C,
21 NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_I2C, 22 NVDEV_SUBDEV_DEVINIT_LAST = NVDEV_SUBDEV_I2C,
@@ -31,7 +32,6 @@ enum nv_subdev_type {
31 NVDEV_SUBDEV_TIMER, 32 NVDEV_SUBDEV_TIMER,
32 NVDEV_SUBDEV_FB, 33 NVDEV_SUBDEV_FB,
33 NVDEV_SUBDEV_LTC, 34 NVDEV_SUBDEV_LTC,
34 NVDEV_SUBDEV_IBUS,
35 NVDEV_SUBDEV_INSTMEM, 35 NVDEV_SUBDEV_INSTMEM,
36 NVDEV_SUBDEV_VM, 36 NVDEV_SUBDEV_VM,
37 NVDEV_SUBDEV_BAR, 37 NVDEV_SUBDEV_BAR,
@@ -92,6 +92,7 @@ struct nouveau_device {
92 GM100 = 0x110, 92 GM100 = 0x110,
93 } card_type; 93 } card_type;
94 u32 chipset; 94 u32 chipset;
95 u8 chiprev;
95 u32 crystal; 96 u32 crystal;
96 97
97 struct nouveau_oclass *oclass[NVDEV_SUBDEV_NR]; 98 struct nouveau_oclass *oclass[NVDEV_SUBDEV_NR];
@@ -158,6 +159,12 @@ nv_device_is_pci(struct nouveau_device *device)
158 return device->pdev != NULL; 159 return device->pdev != NULL;
159} 160}
160 161
162static inline bool
163nv_device_is_cpu_coherent(struct nouveau_device *device)
164{
165 return (!IS_ENABLED(CONFIG_ARM) && nv_device_is_pci(device));
166}
167
161static inline struct device * 168static inline struct device *
162nv_device_base(struct nouveau_device *device) 169nv_device_base(struct nouveau_device *device)
163{ 170{
diff --git a/drivers/gpu/drm/nouveau/core/include/core/handle.h b/drivers/gpu/drm/nouveau/core/include/core/handle.h
index ceb67d770875..d22a59138a9b 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/handle.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/handle.h
@@ -23,11 +23,6 @@ void nouveau_handle_destroy(struct nouveau_handle *);
23int nouveau_handle_init(struct nouveau_handle *); 23int nouveau_handle_init(struct nouveau_handle *);
24int nouveau_handle_fini(struct nouveau_handle *, bool suspend); 24int nouveau_handle_fini(struct nouveau_handle *, bool suspend);
25 25
26int nouveau_handle_new(struct nouveau_object *, u32 parent, u32 handle,
27 u16 oclass, void *data, u32 size,
28 struct nouveau_object **);
29int nouveau_handle_del(struct nouveau_object *, u32 parent, u32 handle);
30
31struct nouveau_object * 26struct nouveau_object *
32nouveau_handle_ref(struct nouveau_object *, u32 name); 27nouveau_handle_ref(struct nouveau_object *, u32 name);
33 28
diff --git a/drivers/gpu/drm/nouveau/core/include/core/object.h b/drivers/gpu/drm/nouveau/core/include/core/object.h
index d7039482d6fd..2e2afa502c99 100644
--- a/drivers/gpu/drm/nouveau/core/include/core/object.h
+++ b/drivers/gpu/drm/nouveau/core/include/core/object.h
@@ -203,21 +203,4 @@ nv_memcmp(void *obj, u32 addr, const char *str, u32 len)
203 return 0; 203 return 0;
204} 204}
205 205
206#include <core/handle.h>
207
208static inline int
209nouveau_object_new(struct nouveau_object *client, u32 parent, u32 handle,
210 u16 oclass, void *data, u32 size,
211 struct nouveau_object **pobject)
212{
213 return nouveau_handle_new(client, parent, handle, oclass,
214 data, size, pobject);
215}
216
217static inline int
218nouveau_object_del(struct nouveau_object *client, u32 parent, u32 handle)
219{
220 return nouveau_handle_del(client, parent, handle);
221}
222
223#endif 206#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/engine/disp.h b/drivers/gpu/drm/nouveau/core/include/engine/disp.h
index 7a64f347b385..fc307f1317ff 100644
--- a/drivers/gpu/drm/nouveau/core/include/engine/disp.h
+++ b/drivers/gpu/drm/nouveau/core/include/engine/disp.h
@@ -31,5 +31,6 @@ extern struct nouveau_oclass *nvd0_disp_oclass;
31extern struct nouveau_oclass *nve0_disp_oclass; 31extern struct nouveau_oclass *nve0_disp_oclass;
32extern struct nouveau_oclass *nvf0_disp_oclass; 32extern struct nouveau_oclass *nvf0_disp_oclass;
33extern struct nouveau_oclass *gm107_disp_oclass; 33extern struct nouveau_oclass *gm107_disp_oclass;
34extern struct nouveau_oclass *gm204_disp_oclass;
34 35
35#endif 36#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h
new file mode 100644
index 000000000000..1f84d3612dd8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/M0203.h
@@ -0,0 +1,31 @@
1#ifndef __NVBIOS_M0203_H__
2#define __NVBIOS_M0203_H__
3
4struct nvbios_M0203T {
5#define M0203T_TYPE_RAMCFG 0x00
6 u8 type;
7 u16 pointer;
8};
9
10u32 nvbios_M0203Te(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
11u32 nvbios_M0203Tp(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
12 struct nvbios_M0203T *);
13
14struct nvbios_M0203E {
15#define M0203E_TYPE_DDR2 0x0
16#define M0203E_TYPE_DDR3 0x1
17#define M0203E_TYPE_GDDR3 0x2
18#define M0203E_TYPE_GDDR5 0x3
19#define M0203E_TYPE_SKIP 0xf
20 u8 type;
21 u8 strap;
22 u8 group;
23};
24
25u32 nvbios_M0203Ee(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
26u32 nvbios_M0203Ep(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
27 struct nvbios_M0203E *);
28u32 nvbios_M0203Em(struct nouveau_bios *, u8 ramcfg, u8 *ver, u8 *hdr,
29 struct nvbios_M0203E *);
30
31#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h
index 10b57a19a7de..c9bb112895af 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/i2c.h
@@ -4,11 +4,14 @@
4struct nouveau_bios; 4struct nouveau_bios;
5 5
6enum dcb_i2c_type { 6enum dcb_i2c_type {
7 DCB_I2C_NV04_BIT = 0, 7 /* matches bios type field prior to ccb 4.1 */
8 DCB_I2C_NV4E_BIT = 4, 8 DCB_I2C_NV04_BIT = 0x00,
9 DCB_I2C_NVIO_BIT = 5, 9 DCB_I2C_NV4E_BIT = 0x04,
10 DCB_I2C_NVIO_AUX = 6, 10 DCB_I2C_NVIO_BIT = 0x05,
11 DCB_I2C_UNUSED = 0xff 11 DCB_I2C_NVIO_AUX = 0x06,
12 /* made up - mostly */
13 DCB_I2C_PMGR = 0x80,
14 DCB_I2C_UNUSED = 0xff
12}; 15};
13 16
14struct dcb_i2c_entry { 17struct dcb_i2c_entry {
@@ -16,6 +19,7 @@ struct dcb_i2c_entry {
16 u8 drive; 19 u8 drive;
17 u8 sense; 20 u8 sense;
18 u8 share; 21 u8 share;
22 u8 auxch;
19}; 23};
20 24
21u16 dcb_i2c_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len); 25u16 dcb_i2c_table(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h
new file mode 100644
index 000000000000..3348b4580843
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/image.h
@@ -0,0 +1,13 @@
1#ifndef __NVBIOS_IMAGE_H__
2#define __NVBIOS_IMAGE_H__
3
4struct nvbios_image {
5 u32 base;
6 u32 size;
7 u8 type;
8 bool last;
9};
10
11bool nvbios_image(struct nouveau_bios *, int, struct nvbios_image *);
12
13#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h
new file mode 100644
index 000000000000..b18413d951e5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/npde.h
@@ -0,0 +1,12 @@
1#ifndef __NVBIOS_NPDE_H__
2#define __NVBIOS_NPDE_H__
3
4struct nvbios_npdeT {
5 u32 image_size;
6 bool last;
7};
8
9u32 nvbios_npdeTe(struct nouveau_bios *, u32);
10u32 nvbios_npdeTp(struct nouveau_bios *, u32, struct nvbios_npdeT *);
11
12#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h
new file mode 100644
index 000000000000..3d634a06dca1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pcir.h
@@ -0,0 +1,18 @@
1#ifndef __NVBIOS_PCIR_H__
2#define __NVBIOS_PCIR_H__
3
4struct nvbios_pcirT {
5 u16 vendor_id;
6 u16 device_id;
7 u8 class_code[3];
8 u32 image_size;
9 u16 image_rev;
10 u8 image_type;
11 bool last;
12};
13
14u32 nvbios_pcirTe(struct nouveau_bios *, u32, u8 *ver, u16 *hdr);
15u32 nvbios_pcirTp(struct nouveau_bios *, u32, u8 *ver, u16 *hdr,
16 struct nvbios_pcirT *);
17
18#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h
new file mode 100644
index 000000000000..9de593deaea8
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/pmu.h
@@ -0,0 +1,37 @@
1#ifndef __NVBIOS_PMU_H__
2#define __NVBIOS_PMU_H__
3
4struct nvbios_pmuT {
5};
6
7u32 nvbios_pmuTe(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len);
8u32 nvbios_pmuTp(struct nouveau_bios *, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
9 struct nvbios_pmuT *);
10
11struct nvbios_pmuE {
12 u8 type;
13 u32 data;
14};
15
16u32 nvbios_pmuEe(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr);
17u32 nvbios_pmuEp(struct nouveau_bios *, int idx, u8 *ver, u8 *hdr,
18 struct nvbios_pmuE *);
19
20struct nvbios_pmuR {
21 u32 boot_addr_pmu;
22 u32 boot_addr;
23 u32 boot_size;
24 u32 code_addr_pmu;
25 u32 code_addr;
26 u32 code_size;
27 u32 init_addr_pmu;
28
29 u32 data_addr_pmu;
30 u32 data_addr;
31 u32 data_size;
32 u32 args_addr_pmu;
33};
34
35bool nvbios_pmuRm(struct nouveau_bios *, u8 type, struct nvbios_pmuR *);
36
37#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h b/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h
index a685bbd04568..4a0e0ceb41ba 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/bios/ramcfg.h
@@ -43,8 +43,9 @@ struct nvbios_ramcfg {
43 unsigned ramcfg_10_02_08:1; 43 unsigned ramcfg_10_02_08:1;
44 unsigned ramcfg_10_02_10:1; 44 unsigned ramcfg_10_02_10:1;
45 unsigned ramcfg_10_02_20:1; 45 unsigned ramcfg_10_02_20:1;
46 unsigned ramcfg_10_02_40:1; 46 unsigned ramcfg_10_DLLoff:1;
47 unsigned ramcfg_10_03_0f:4; 47 unsigned ramcfg_10_03_0f:4;
48 unsigned ramcfg_10_04_01:1;
48 unsigned ramcfg_10_05:8; 49 unsigned ramcfg_10_05:8;
49 unsigned ramcfg_10_06:8; 50 unsigned ramcfg_10_06:8;
50 unsigned ramcfg_10_07:8; 51 unsigned ramcfg_10_07:8;
@@ -95,9 +96,29 @@ struct nvbios_ramcfg {
95 union { 96 union {
96 struct { 97 struct {
97 unsigned timing_10_WR:8; 98 unsigned timing_10_WR:8;
99 unsigned timing_10_WTR:8;
98 unsigned timing_10_CL:8; 100 unsigned timing_10_CL:8;
101 unsigned timing_10_RC:8;
102 /*empty: 4 */
103 unsigned timing_10_RFC:8; /* Byte 5 */
104 /*empty: 6 */
105 unsigned timing_10_RAS:8; /* Byte 7 */
106 /*empty: 8 */
107 unsigned timing_10_RP:8; /* Byte 9 */
108 unsigned timing_10_RCDRD:8;
109 unsigned timing_10_RCDWR:8;
110 unsigned timing_10_RRD:8;
111 unsigned timing_10_13:8;
99 unsigned timing_10_ODT:3; 112 unsigned timing_10_ODT:3;
113 /* empty: 15 */
114 unsigned timing_10_16:8;
115 /* empty: 17 */
116 unsigned timing_10_18:8;
100 unsigned timing_10_CWL:8; 117 unsigned timing_10_CWL:8;
118 unsigned timing_10_20:8;
119 unsigned timing_10_21:8;
120 /* empty: 22, 23 */
121 unsigned timing_10_24:8;
101 }; 122 };
102 struct { 123 struct {
103 unsigned timing_20_2e_03:2; 124 unsigned timing_20_2e_03:2;
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
index e292271a84e4..e007a9d44683 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/devinit.h
@@ -30,5 +30,6 @@ extern struct nouveau_oclass *nva3_devinit_oclass;
30extern struct nouveau_oclass *nvaf_devinit_oclass; 30extern struct nouveau_oclass *nvaf_devinit_oclass;
31extern struct nouveau_oclass *nvc0_devinit_oclass; 31extern struct nouveau_oclass *nvc0_devinit_oclass;
32extern struct nouveau_oclass *gm107_devinit_oclass; 32extern struct nouveau_oclass *gm107_devinit_oclass;
33extern struct nouveau_oclass *gm204_devinit_oclass;
33 34
34#endif 35#endif
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
index 1b937c2c25ae..d94ccacb40bf 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/i2c.h
@@ -8,6 +8,8 @@
8#include <subdev/bios/i2c.h> 8#include <subdev/bios/i2c.h>
9 9
10#define NV_I2C_PORT(n) (0x00 + (n)) 10#define NV_I2C_PORT(n) (0x00 + (n))
11#define NV_I2C_AUX(n) (0x10 + (n))
12#define NV_I2C_EXT(n) (0x20 + (n))
11#define NV_I2C_DEFAULT(n) (0x80 + (n)) 13#define NV_I2C_DEFAULT(n) (0x80 + (n))
12 14
13#define NV_I2C_TYPE_DCBI2C(n) (0x0000 | (n)) 15#define NV_I2C_TYPE_DCBI2C(n) (0x0000 | (n))
@@ -89,6 +91,7 @@ extern struct nouveau_oclass *nv94_i2c_oclass;
89extern struct nouveau_oclass *nvd0_i2c_oclass; 91extern struct nouveau_oclass *nvd0_i2c_oclass;
90extern struct nouveau_oclass *gf117_i2c_oclass; 92extern struct nouveau_oclass *gf117_i2c_oclass;
91extern struct nouveau_oclass *nve0_i2c_oclass; 93extern struct nouveau_oclass *nve0_i2c_oclass;
94extern struct nouveau_oclass *gm204_i2c_oclass;
92 95
93static inline int 96static inline int
94nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg) 97nv_rdi2cr(struct nouveau_i2c_port *port, u8 addr, u8 reg)
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
index bf3d1f611333..f2427bf5aeed 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/pwr.h
@@ -48,6 +48,8 @@ void nouveau_memx_wait(struct nouveau_memx *,
48 u32 addr, u32 mask, u32 data, u32 nsec); 48 u32 addr, u32 mask, u32 data, u32 nsec);
49void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec); 49void nouveau_memx_nsec(struct nouveau_memx *, u32 nsec);
50void nouveau_memx_wait_vblank(struct nouveau_memx *); 50void nouveau_memx_wait_vblank(struct nouveau_memx *);
51void nouveau_memx_train(struct nouveau_memx *);
52int nouveau_memx_train_result(struct nouveau_pwr *, u32 *, int);
51void nouveau_memx_block(struct nouveau_memx *); 53void nouveau_memx_block(struct nouveau_memx *);
52void nouveau_memx_unblock(struct nouveau_memx *); 54void nouveau_memx_unblock(struct nouveau_memx *);
53 55
diff --git a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h b/drivers/gpu/drm/nouveau/core/include/subdev/volt.h
index 820b62ffd75b..67db5e58880d 100644
--- a/drivers/gpu/drm/nouveau/core/include/subdev/volt.h
+++ b/drivers/gpu/drm/nouveau/core/include/subdev/volt.h
@@ -52,6 +52,7 @@ int _nouveau_volt_init(struct nouveau_object *);
52#define _nouveau_volt_fini _nouveau_subdev_fini 52#define _nouveau_volt_fini _nouveau_subdev_fini
53 53
54extern struct nouveau_oclass nv40_volt_oclass; 54extern struct nouveau_oclass nv40_volt_oclass;
55extern struct nouveau_oclass gk20a_volt_oclass;
55 56
56int nouveau_voltgpio_init(struct nouveau_volt *); 57int nouveau_voltgpio_init(struct nouveau_volt *);
57int nouveau_voltgpio_get(struct nouveau_volt *); 58int nouveau_voltgpio_get(struct nouveau_volt *);
diff --git a/drivers/gpu/drm/nouveau/core/os.h b/drivers/gpu/drm/nouveau/core/os.h
index ccfa21d72ddc..bdd05ee7ec72 100644
--- a/drivers/gpu/drm/nouveau/core/os.h
+++ b/drivers/gpu/drm/nouveau/core/os.h
@@ -23,6 +23,7 @@
23#include <linux/pm_runtime.h> 23#include <linux/pm_runtime.h>
24#include <linux/power_supply.h> 24#include <linux/power_supply.h>
25#include <linux/clk.h> 25#include <linux/clk.h>
26#include <linux/regulator/consumer.h>
26 27
27#include <asm/unaligned.h> 28#include <asm/unaligned.h>
28 29
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c b/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c
new file mode 100644
index 000000000000..28906b16d4e5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/M0203.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include <subdev/bios.h>
26#include <subdev/bios/bit.h>
27#include <subdev/bios/M0203.h>
28
29u32
30nvbios_M0203Te(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
31{
32 struct bit_entry bit_M;
33 u32 data = 0x00000000;
34
35 if (!bit_entry(bios, 'M', &bit_M)) {
36 if (bit_M.version == 2 && bit_M.length > 0x04)
37 data = nv_ro16(bios, bit_M.offset + 0x03);
38 if (data) {
39 *ver = nv_ro08(bios, data + 0x00);
40 switch (*ver) {
41 case 0x10:
42 *hdr = nv_ro08(bios, data + 0x01);
43 *len = nv_ro08(bios, data + 0x02);
44 *cnt = nv_ro08(bios, data + 0x03);
45 return data;
46 default:
47 break;
48 }
49 }
50 }
51
52 return 0x00000000;
53}
54
55u32
56nvbios_M0203Tp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
57 struct nvbios_M0203T *info)
58{
59 u32 data = nvbios_M0203Te(bios, ver, hdr, cnt, len);
60 memset(info, 0x00, sizeof(*info));
61 switch (!!data * *ver) {
62 case 0x10:
63 info->type = nv_ro08(bios, data + 0x04);
64 info->pointer = nv_ro16(bios, data + 0x05);
65 break;
66 default:
67 break;
68 }
69 return data;
70}
71
72u32
73nvbios_M0203Ee(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
74{
75 u8 cnt, len;
76 u32 data = nvbios_M0203Te(bios, ver, hdr, &cnt, &len);
77 if (data && idx < cnt) {
78 data = data + *hdr + idx * len;
79 *hdr = len;
80 return data;
81 }
82 return 0x00000000;
83}
84
85u32
86nvbios_M0203Ep(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
87 struct nvbios_M0203E *info)
88{
89 u32 data = nvbios_M0203Ee(bios, idx, ver, hdr);
90 memset(info, 0x00, sizeof(*info));
91 switch (!!data * *ver) {
92 case 0x10:
93 info->type = (nv_ro08(bios, data + 0x00) & 0x0f) >> 0;
94 info->strap = (nv_ro08(bios, data + 0x00) & 0xf0) >> 4;
95 info->group = (nv_ro08(bios, data + 0x01) & 0x0f) >> 0;
96 return data;
97 default:
98 break;
99 }
100 return 0x00000000;
101}
102
103u32
104nvbios_M0203Em(struct nouveau_bios *bios, u8 ramcfg, u8 *ver, u8 *hdr,
105 struct nvbios_M0203E *info)
106{
107 struct nvbios_M0203T M0203T;
108 u8 cnt, len, idx = 0xff;
109 u32 data;
110
111 if (!nvbios_M0203Tp(bios, ver, hdr, &cnt, &len, &M0203T)) {
112 nv_warn(bios, "M0203T not found\n");
113 return 0x00000000;
114 }
115
116 while ((data = nvbios_M0203Ep(bios, ++idx, ver, hdr, info))) {
117 switch (M0203T.type) {
118 case M0203T_TYPE_RAMCFG:
119 if (info->strap != ramcfg)
120 continue;
121 return data;
122 default:
123 nv_warn(bios, "M0203T type %02x\n", M0203T.type);
124 return 0x00000000;
125 }
126 }
127
128 return data;
129}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index d45704a2c2df..7df3a273553d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -31,6 +31,8 @@
31#include <subdev/bios/bmp.h> 31#include <subdev/bios/bmp.h>
32#include <subdev/bios/bit.h> 32#include <subdev/bios/bit.h>
33 33
34#include "priv.h"
35
34u8 36u8
35nvbios_checksum(const u8 *data, int size) 37nvbios_checksum(const u8 *data, int size)
36{ 38{
@@ -56,362 +58,21 @@ nvbios_findstr(const u8 *data, int size, const char *str, int len)
56 return 0; 58 return 0;
57} 59}
58 60
59#if defined(__powerpc__) 61int
60static void 62nvbios_extend(struct nouveau_bios *bios, u32 length)
61nouveau_bios_shadow_of(struct nouveau_bios *bios)
62{ 63{
63 struct pci_dev *pdev = nv_device(bios)->pdev; 64 if (bios->size < length) {
64 struct device_node *dn; 65 u8 *prev = bios->data;
65 const u32 *data; 66 if (!(bios->data = kmalloc(length, GFP_KERNEL))) {
66 int size; 67 bios->data = prev;
67 68 return -ENOMEM;
68 dn = pci_device_to_OF_node(pdev);
69 if (!dn) {
70 nv_info(bios, "Unable to get the OF node\n");
71 return;
72 }
73
74 data = of_get_property(dn, "NVDA,BMP", &size);
75 if (data && size) {
76 bios->size = size;
77 bios->data = kmalloc(bios->size, GFP_KERNEL);
78 if (bios->data)
79 memcpy(bios->data, data, size);
80 }
81}
82#endif
83
84static void
85nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
86{
87 struct nouveau_device *device = nv_device(bios);
88 u64 addr = 0;
89 u32 bar0 = 0;
90 int i;
91
92 if (device->card_type >= NV_50) {
93 if (device->card_type >= NV_C0 && device->card_type < GM100) {
94 if (nv_rd32(bios, 0x022500) & 0x00000001)
95 return;
96 } else
97 if (device->card_type >= GM100) {
98 if (nv_rd32(bios, 0x021c04) & 0x00000001)
99 return;
100 }
101
102 addr = nv_rd32(bios, 0x619f04);
103 if (!(addr & 0x00000008)) {
104 nv_debug(bios, "... not enabled\n");
105 return;
106 } 69 }
107 if ( (addr & 0x00000003) != 1) { 70 memcpy(bios->data, prev, bios->size);
108 nv_debug(bios, "... not in vram\n"); 71 bios->size = length;
109 return; 72 kfree(prev);
110 } 73 return 1;
111
112 addr = (addr & 0xffffff00) << 8;
113 if (!addr) {
114 addr = (u64)nv_rd32(bios, 0x001700) << 16;
115 addr += 0xf0000;
116 }
117
118 bar0 = nv_mask(bios, 0x001700, 0xffffffff, addr >> 16);
119 }
120
121 /* bail if no rom signature */
122 if (nv_rd08(bios, 0x700000) != 0x55 ||
123 nv_rd08(bios, 0x700001) != 0xaa)
124 goto out;
125
126 bios->size = nv_rd08(bios, 0x700002) * 512;
127 if (!bios->size)
128 goto out;
129
130 bios->data = kmalloc(bios->size, GFP_KERNEL);
131 if (bios->data) {
132 for (i = 0; i < bios->size; i++)
133 nv_wo08(bios, i, nv_rd08(bios, 0x700000 + i));
134 }
135
136out:
137 if (device->card_type >= NV_50)
138 nv_wr32(bios, 0x001700, bar0);
139}
140
141static void
142nouveau_bios_shadow_prom(struct nouveau_bios *bios)
143{
144 struct nouveau_device *device = nv_device(bios);
145 u32 pcireg, access;
146 u16 pcir;
147 int i;
148
149 /* there is no prom on nv4x IGP's */
150 if (device->card_type == NV_40 && device->chipset >= 0x4c)
151 return;
152
153 /* enable access to rom */
154 if (device->card_type >= NV_50)
155 pcireg = 0x088050;
156 else
157 pcireg = 0x001850;
158 access = nv_mask(bios, pcireg, 0x00000001, 0x00000000);
159
160 /* WARNING: PROM accesses should always be 32-bits aligned. Other
161 * accesses work on most chipset but do not on Kepler chipsets
162 */
163
164 /* bail if no rom signature, with a workaround for a PROM reading
165 * issue on some chipsets. the first read after a period of
166 * inactivity returns the wrong result, so retry the first header
167 * byte a few times before giving up as a workaround
168 */
169 i = 16;
170 do {
171 u32 data = le32_to_cpu(nv_rd32(bios, 0x300000)) & 0xffff;
172 if (data == 0xaa55)
173 break;
174 } while (i--);
175
176 if (!i)
177 goto out;
178
179 /* read entire bios image to system memory */
180 bios->size = (le32_to_cpu(nv_rd32(bios, 0x300000)) >> 16) & 0xff;
181 bios->size = bios->size * 512;
182 if (!bios->size)
183 goto out;
184
185 bios->data = kmalloc(bios->size, GFP_KERNEL);
186 if (!bios->data)
187 goto out;
188
189 for (i = 0; i < bios->size; i += 4)
190 ((u32 *)bios->data)[i/4] = nv_rd32(bios, 0x300000 + i);
191
192 /* check the PCI record header */
193 pcir = nv_ro16(bios, 0x0018);
194 if (bios->data[pcir + 0] != 'P' ||
195 bios->data[pcir + 1] != 'C' ||
196 bios->data[pcir + 2] != 'I' ||
197 bios->data[pcir + 3] != 'R') {
198 bios->size = 0;
199 kfree(bios->data);
200 }
201
202out:
203 /* disable access to rom */
204 nv_wr32(bios, pcireg, access);
205}
206
207#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
208int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
209bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
210#else
211static inline bool
212nouveau_acpi_rom_supported(struct pci_dev *pdev) {
213 return false;
214}
215
216static inline int
217nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len) {
218 return -EINVAL;
219}
220#endif
221
222static void
223nouveau_bios_shadow_acpi(struct nouveau_bios *bios)
224{
225 struct pci_dev *pdev = nv_device(bios)->pdev;
226 int ret, cnt, i;
227
228 if (!nouveau_acpi_rom_supported(pdev)) {
229 bios->data = NULL;
230 return;
231 }
232
233 bios->size = 0;
234 bios->data = kmalloc(4096, GFP_KERNEL);
235 if (bios->data) {
236 if (nouveau_acpi_get_bios_chunk(bios->data, 0, 4096) == 4096)
237 bios->size = bios->data[2] * 512;
238 kfree(bios->data);
239 } 74 }
240 75 return 0;
241 if (!bios->size)
242 return;
243
244 bios->data = kmalloc(bios->size, GFP_KERNEL);
245 if (bios->data) {
246 /* disobey the acpi spec - much faster on at least w530 ... */
247 ret = nouveau_acpi_get_bios_chunk(bios->data, 0, bios->size);
248 if (ret != bios->size ||
249 nvbios_checksum(bios->data, bios->size)) {
250 /* ... that didn't work, ok, i'll be good now */
251 for (i = 0; i < bios->size; i += cnt) {
252 cnt = min((bios->size - i), (u32)4096);
253 ret = nouveau_acpi_get_bios_chunk(bios->data, i, cnt);
254 if (ret != cnt)
255 break;
256 }
257 }
258 }
259}
260
261static void
262nouveau_bios_shadow_pci(struct nouveau_bios *bios)
263{
264 struct pci_dev *pdev = nv_device(bios)->pdev;
265 size_t size;
266
267 if (!pci_enable_rom(pdev)) {
268 void __iomem *rom = pci_map_rom(pdev, &size);
269 if (rom && size) {
270 bios->data = kmalloc(size, GFP_KERNEL);
271 if (bios->data) {
272 memcpy_fromio(bios->data, rom, size);
273 bios->size = size;
274 }
275 }
276 if (rom)
277 pci_unmap_rom(pdev, rom);
278
279 pci_disable_rom(pdev);
280 }
281}
282
283static void
284nouveau_bios_shadow_platform(struct nouveau_bios *bios)
285{
286 struct pci_dev *pdev = nv_device(bios)->pdev;
287 size_t size;
288
289 void __iomem *rom = pci_platform_rom(pdev, &size);
290 if (rom && size) {
291 bios->data = kmalloc(size, GFP_KERNEL);
292 if (bios->data) {
293 memcpy_fromio(bios->data, rom, size);
294 bios->size = size;
295 }
296 }
297}
298
299static int
300nouveau_bios_score(struct nouveau_bios *bios, const bool writeable)
301{
302 if (bios->size < 3 || !bios->data || bios->data[0] != 0x55 ||
303 bios->data[1] != 0xAA) {
304 nv_info(bios, "... signature not found\n");
305 return 0;
306 }
307
308 if (nvbios_checksum(bios->data,
309 min_t(u32, bios->data[2] * 512, bios->size))) {
310 nv_info(bios, "... checksum invalid\n");
311 /* if a ro image is somewhat bad, it's probably all rubbish */
312 return writeable ? 2 : 1;
313 }
314
315 nv_info(bios, "... appears to be valid\n");
316 return 3;
317}
318
319struct methods {
320 const char desc[16];
321 void (*shadow)(struct nouveau_bios *);
322 const bool rw;
323 int score;
324 u32 size;
325 u8 *data;
326};
327
328static int
329nouveau_bios_shadow(struct nouveau_bios *bios)
330{
331 struct methods shadow_methods[] = {
332#if defined(__powerpc__)
333 { "OpenFirmware", nouveau_bios_shadow_of, true, 0, 0, NULL },
334#endif
335 { "PRAMIN", nouveau_bios_shadow_pramin, true, 0, 0, NULL },
336 { "PROM", nouveau_bios_shadow_prom, false, 0, 0, NULL },
337 { "ACPI", nouveau_bios_shadow_acpi, true, 0, 0, NULL },
338 { "PCIROM", nouveau_bios_shadow_pci, true, 0, 0, NULL },
339 { "PLATFORM", nouveau_bios_shadow_platform, true, 0, 0, NULL },
340 {}
341 };
342 struct methods *mthd, *best;
343 const struct firmware *fw;
344 const char *optarg;
345 int optlen, ret;
346 char *source;
347
348 optarg = nouveau_stropt(nv_device(bios)->cfgopt, "NvBios", &optlen);
349 source = optarg ? kstrndup(optarg, optlen, GFP_KERNEL) : NULL;
350 if (source) {
351 /* try to match one of the built-in methods */
352 mthd = shadow_methods;
353 do {
354 if (strcasecmp(source, mthd->desc))
355 continue;
356 nv_info(bios, "source: %s\n", mthd->desc);
357
358 mthd->shadow(bios);
359 mthd->score = nouveau_bios_score(bios, mthd->rw);
360 if (mthd->score) {
361 kfree(source);
362 return 0;
363 }
364 } while ((++mthd)->shadow);
365
366 /* attempt to load firmware image */
367 ret = request_firmware(&fw, source, &nv_device(bios)->pdev->dev);
368 if (ret == 0) {
369 bios->size = fw->size;
370 bios->data = kmemdup(fw->data, fw->size, GFP_KERNEL);
371 release_firmware(fw);
372
373 nv_info(bios, "image: %s\n", source);
374 if (nouveau_bios_score(bios, 1)) {
375 kfree(source);
376 return 0;
377 }
378
379 kfree(bios->data);
380 bios->data = NULL;
381 }
382
383 nv_error(bios, "source \'%s\' invalid\n", source);
384 kfree(source);
385 }
386
387 mthd = shadow_methods;
388 do {
389 nv_info(bios, "checking %s for image...\n", mthd->desc);
390 mthd->shadow(bios);
391 mthd->score = nouveau_bios_score(bios, mthd->rw);
392 mthd->size = bios->size;
393 mthd->data = bios->data;
394 bios->data = NULL;
395 } while (mthd->score != 3 && (++mthd)->shadow);
396
397 mthd = shadow_methods;
398 best = mthd;
399 do {
400 if (mthd->score > best->score) {
401 kfree(best->data);
402 best = mthd;
403 }
404 } while ((++mthd)->shadow);
405
406 if (best->score) {
407 nv_info(bios, "using image from %s\n", best->desc);
408 bios->size = best->size;
409 bios->data = best->data;
410 return 0;
411 }
412
413 nv_error(bios, "unable to locate usable image\n");
414 return -EINVAL;
415} 76}
416 77
417static u8 78static u8
@@ -472,7 +133,7 @@ nouveau_bios_ctor(struct nouveau_object *parent,
472 if (ret) 133 if (ret)
473 return ret; 134 return ret;
474 135
475 ret = nouveau_bios_shadow(bios); 136 ret = nvbios_shadow(bios);
476 if (ret) 137 if (ret)
477 return ret; 138 return ret;
478 139
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
index bd8d348385b3..96099aff8b41 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dcb.c
@@ -42,7 +42,7 @@ dcb_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
42 42
43 *ver = nv_ro08(bios, dcb); 43 *ver = nv_ro08(bios, dcb);
44 44
45 if (*ver >= 0x41) { 45 if (*ver >= 0x42) {
46 nv_warn(bios, "DCB version 0x%02x unknown\n", *ver); 46 nv_warn(bios, "DCB version 0x%02x unknown\n", *ver);
47 return 0x0000; 47 return 0x0000;
48 } else 48 } else
@@ -157,17 +157,20 @@ dcb_outp_parse(struct nouveau_bios *bios, u8 idx, u8 *ver, u8 *len,
157 break; 157 break;
158 } 158 }
159 159
160 switch (conf & 0x0f000000) { 160 outp->dpconf.link_nr = (conf & 0x0f000000) >> 24;
161 case 0x0f000000: 161 if (*ver < 0x41) {
162 outp->dpconf.link_nr = 4; 162 switch (outp->dpconf.link_nr) {
163 break; 163 case 0x0f:
164 case 0x03000000: 164 outp->dpconf.link_nr = 4;
165 outp->dpconf.link_nr = 2; 165 break;
166 break; 166 case 0x03:
167 case 0x01000000: 167 outp->dpconf.link_nr = 2;
168 default: 168 break;
169 outp->dpconf.link_nr = 1; 169 case 0x01:
170 break; 170 default:
171 outp->dpconf.link_nr = 1;
172 break;
173 }
171 } 174 }
172 175
173 /* fall-through... */ 176 /* fall-through... */
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/disp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/disp.c
index 7f16e52d9bea..51f355599694 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/disp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/disp.c
@@ -40,6 +40,7 @@ nvbios_disp_table(struct nouveau_bios *bios,
40 switch (*ver) { 40 switch (*ver) {
41 case 0x20: 41 case 0x20:
42 case 0x21: 42 case 0x21:
43 case 0x22:
43 *hdr = nv_ro08(bios, data + 0x01); 44 *hdr = nv_ro08(bios, data + 0x01);
44 *len = nv_ro08(bios, data + 0x02); 45 *len = nv_ro08(bios, data + 0x02);
45 *cnt = nv_ro08(bios, data + 0x03); 46 *cnt = nv_ro08(bios, data + 0x03);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
index f309dd657250..cef53f81f12b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/dp.c
@@ -41,6 +41,7 @@ nvbios_dp_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
41 case 0x21: 41 case 0x21:
42 case 0x30: 42 case 0x30:
43 case 0x40: 43 case 0x40:
44 case 0x41:
44 *hdr = nv_ro08(bios, data + 0x01); 45 *hdr = nv_ro08(bios, data + 0x01);
45 *len = nv_ro08(bios, data + 0x02); 46 *len = nv_ro08(bios, data + 0x02);
46 *cnt = nv_ro08(bios, data + 0x03); 47 *cnt = nv_ro08(bios, data + 0x03);
@@ -70,6 +71,7 @@ nvbios_dpout_entry(struct nouveau_bios *bios, u8 idx,
70 *cnt = nv_ro08(bios, outp + 0x04); 71 *cnt = nv_ro08(bios, outp + 0x04);
71 break; 72 break;
72 case 0x40: 73 case 0x40:
74 case 0x41:
73 *hdr = nv_ro08(bios, data + 0x04); 75 *hdr = nv_ro08(bios, data + 0x04);
74 *cnt = 0; 76 *cnt = 0;
75 *len = 0; 77 *len = 0;
@@ -108,6 +110,7 @@ nvbios_dpout_parse(struct nouveau_bios *bios, u8 idx,
108 info->script[4] = nv_ro16(bios, data + 0x10); 110 info->script[4] = nv_ro16(bios, data + 0x10);
109 break; 111 break;
110 case 0x40: 112 case 0x40:
113 case 0x41:
111 info->flags = nv_ro08(bios, data + 0x04); 114 info->flags = nv_ro08(bios, data + 0x04);
112 info->script[0] = nv_ro16(bios, data + 0x05); 115 info->script[0] = nv_ro16(bios, data + 0x05);
113 info->script[1] = nv_ro16(bios, data + 0x07); 116 info->script[1] = nv_ro16(bios, data + 0x07);
@@ -172,10 +175,11 @@ nvbios_dpcfg_parse(struct nouveau_bios *bios, u16 outp, u8 idx,
172 break; 175 break;
173 case 0x30: 176 case 0x30:
174 case 0x40: 177 case 0x40:
178 case 0x41:
175 info->pc = nv_ro08(bios, data + 0x00); 179 info->pc = nv_ro08(bios, data + 0x00);
176 info->dc = nv_ro08(bios, data + 0x01); 180 info->dc = nv_ro08(bios, data + 0x01);
177 info->pe = nv_ro08(bios, data + 0x02); 181 info->pe = nv_ro08(bios, data + 0x02);
178 info->tx_pu = nv_ro08(bios, data + 0x03); 182 info->tx_pu = nv_ro08(bios, data + 0x03) & 0x0f;
179 break; 183 break;
180 default: 184 default:
181 data = 0x0000; 185 data = 0x0000;
@@ -194,6 +198,10 @@ nvbios_dpcfg_match(struct nouveau_bios *bios, u16 outp, u8 pc, u8 vs, u8 pe,
194 u16 data; 198 u16 data;
195 199
196 if (*ver >= 0x30) { 200 if (*ver >= 0x30) {
201 /*XXX: there's a second set of these on at least 4.1, that
202 * i've witnessed nvidia using instead of the first
203 * on gm204. figure out what/why
204 */
197 const u8 vsoff[] = { 0, 4, 7, 9 }; 205 const u8 vsoff[] = { 0, 4, 7, 9 };
198 idx = (pc * 10) + vsoff[vs] + pe; 206 idx = (pc * 10) + vsoff[vs] + pe;
199 } else { 207 } else {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c b/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c
index b2a676e53580..49285d4f7ca5 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/extdev.c
@@ -90,7 +90,7 @@ nvbios_extdev_find(struct nouveau_bios *bios, enum nvbios_extdev_type type,
90 u16 entry; 90 u16 entry;
91 91
92 i = 0; 92 i = 0;
93 while (!(entry = nvbios_extdev_entry(bios, i++, &ver, &len))) { 93 while ((entry = nvbios_extdev_entry(bios, i++, &ver, &len))) {
94 extdev_parse_entry(bios, entry, func); 94 extdev_parse_entry(bios, entry, func);
95 if (func->type == type) 95 if (func->type == type)
96 return 0; 96 return 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c b/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c
index cfb9288c6d28..282320ba9264 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/i2c.c
@@ -39,6 +39,11 @@ dcb_i2c_table(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
39 i2c = nv_ro16(bios, dcb + 4); 39 i2c = nv_ro16(bios, dcb + 4);
40 } 40 }
41 41
42 if (i2c && *ver >= 0x42) {
43 nv_warn(bios, "ccb %02x not supported\n", *ver);
44 return 0x0000;
45 }
46
42 if (i2c && *ver >= 0x30) { 47 if (i2c && *ver >= 0x30) {
43 *ver = nv_ro08(bios, i2c + 0); 48 *ver = nv_ro08(bios, i2c + 0);
44 *hdr = nv_ro08(bios, i2c + 1); 49 *hdr = nv_ro08(bios, i2c + 1);
@@ -70,14 +75,25 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
70 u8 ver, len; 75 u8 ver, len;
71 u16 ent = dcb_i2c_entry(bios, idx, &ver, &len); 76 u16 ent = dcb_i2c_entry(bios, idx, &ver, &len);
72 if (ent) { 77 if (ent) {
73 info->type = nv_ro08(bios, ent + 3); 78 if (ver >= 0x41) {
74 info->share = DCB_I2C_UNUSED; 79 if (!(nv_ro32(bios, ent) & 0x80000000))
75 if (ver < 0x30) { 80 info->type = DCB_I2C_UNUSED;
76 info->type &= 0x07; 81 else
82 info->type = DCB_I2C_PMGR;
83 } else
84 if (ver >= 0x30) {
85 info->type = nv_ro08(bios, ent + 0x03);
86 } else {
87 info->type = nv_ro08(bios, ent + 0x03) & 0x07;
77 if (info->type == 0x07) 88 if (info->type == 0x07)
78 info->type = DCB_I2C_UNUSED; 89 info->type = DCB_I2C_UNUSED;
79 } 90 }
80 91
92 info->drive = DCB_I2C_UNUSED;
93 info->sense = DCB_I2C_UNUSED;
94 info->share = DCB_I2C_UNUSED;
95 info->auxch = DCB_I2C_UNUSED;
96
81 switch (info->type) { 97 switch (info->type) {
82 case DCB_I2C_NV04_BIT: 98 case DCB_I2C_NV04_BIT:
83 info->drive = nv_ro08(bios, ent + 0); 99 info->drive = nv_ro08(bios, ent + 0);
@@ -87,12 +103,23 @@ dcb_i2c_parse(struct nouveau_bios *bios, u8 idx, struct dcb_i2c_entry *info)
87 info->drive = nv_ro08(bios, ent + 1); 103 info->drive = nv_ro08(bios, ent + 1);
88 return 0; 104 return 0;
89 case DCB_I2C_NVIO_BIT: 105 case DCB_I2C_NVIO_BIT:
90 case DCB_I2C_NVIO_AUX:
91 info->drive = nv_ro08(bios, ent + 0) & 0x0f; 106 info->drive = nv_ro08(bios, ent + 0) & 0x0f;
92 if (nv_ro08(bios, ent + 1) & 0x01) { 107 if (nv_ro08(bios, ent + 1) & 0x01)
93 info->share = nv_ro08(bios, ent + 1) >> 1; 108 info->share = nv_ro08(bios, ent + 1) >> 1;
94 info->share &= 0x0f; 109 return 0;
95 } 110 case DCB_I2C_NVIO_AUX:
111 info->auxch = nv_ro08(bios, ent + 0) & 0x0f;
112 if (nv_ro08(bios, ent + 1) & 0x01)
113 info->share = info->auxch;
114 return 0;
115 case DCB_I2C_PMGR:
116 info->drive = (nv_ro16(bios, ent + 0) & 0x01f) >> 0;
117 if (info->drive == 0x1f)
118 info->drive = DCB_I2C_UNUSED;
119 info->auxch = (nv_ro16(bios, ent + 0) & 0x3e0) >> 5;
120 if (info->auxch == 0x1f)
121 info->auxch = DCB_I2C_UNUSED;
122 info->share = info->auxch;
96 return 0; 123 return 0;
97 case DCB_I2C_UNUSED: 124 case DCB_I2C_UNUSED:
98 return 0; 125 return 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/image.c b/drivers/gpu/drm/nouveau/core/subdev/bios/image.c
new file mode 100644
index 000000000000..373f9a564ac9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/image.c
@@ -0,0 +1,78 @@
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include <subdev/bios.h>
26#include <subdev/bios/image.h>
27#include <subdev/bios/pcir.h>
28#include <subdev/bios/npde.h>
29
30static bool
31nvbios_imagen(struct nouveau_bios *bios, struct nvbios_image *image)
32{
33 struct nvbios_pcirT pcir;
34 struct nvbios_npdeT npde;
35 u8 ver;
36 u16 hdr;
37 u32 data;
38
39 switch ((data = nv_ro16(bios, image->base + 0x00))) {
40 case 0xaa55:
41 case 0xbb77:
42 case 0x4e56: /* NV */
43 break;
44 default:
45 nv_debug(bios, "%08x: ROM signature (%04x) unknown\n",
46 image->base, data);
47 return false;
48 }
49
50 if (!(data = nvbios_pcirTp(bios, image->base, &ver, &hdr, &pcir)))
51 return false;
52 image->size = pcir.image_size;
53 image->type = pcir.image_type;
54 image->last = pcir.last;
55
56 if (image->type != 0x70) {
57 if (!(data = nvbios_npdeTp(bios, image->base, &npde)))
58 return true;
59 image->size = npde.image_size;
60 image->last = npde.last;
61 } else {
62 image->last = true;
63 }
64
65 return true;
66}
67
68bool
69nvbios_image(struct nouveau_bios *bios, int idx, struct nvbios_image *image)
70{
71 memset(image, 0x00, sizeof(*image));
72 do {
73 image->base += image->size;
74 if (image->last || !nvbios_imagen(bios, image))
75 return false;
76 } while(idx--);
77 return true;
78}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
index 626380f9e4c0..c6579ef32cd1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/init.c
@@ -255,6 +255,8 @@ init_i2c(struct nvbios_init *init, int index)
255 } 255 }
256 256
257 index = init->outp->i2c_index; 257 index = init->outp->i2c_index;
258 if (init->outp->type == DCB_OUTPUT_DP)
259 index += NV_I2C_AUX(0);
258 } 260 }
259 261
260 return i2c->find(i2c, index); 262 return i2c->find(i2c, index);
@@ -278,7 +280,7 @@ init_wri2cr(struct nvbios_init *init, u8 index, u8 addr, u8 reg, u8 val)
278 return -ENODEV; 280 return -ENODEV;
279} 281}
280 282
281static int 283static u8
282init_rdauxr(struct nvbios_init *init, u32 addr) 284init_rdauxr(struct nvbios_init *init, u32 addr)
283{ 285{
284 struct nouveau_i2c_port *port = init_i2c(init, -2); 286 struct nouveau_i2c_port *port = init_i2c(init, -2);
@@ -286,20 +288,24 @@ init_rdauxr(struct nvbios_init *init, u32 addr)
286 288
287 if (port && init_exec(init)) { 289 if (port && init_exec(init)) {
288 int ret = nv_rdaux(port, addr, &data, 1); 290 int ret = nv_rdaux(port, addr, &data, 1);
289 if (ret) 291 if (ret == 0)
290 return ret; 292 return data;
291 return data; 293 trace("auxch read failed with %d\n", ret);
292 } 294 }
293 295
294 return -ENODEV; 296 return 0x00;
295} 297}
296 298
297static int 299static int
298init_wrauxr(struct nvbios_init *init, u32 addr, u8 data) 300init_wrauxr(struct nvbios_init *init, u32 addr, u8 data)
299{ 301{
300 struct nouveau_i2c_port *port = init_i2c(init, -2); 302 struct nouveau_i2c_port *port = init_i2c(init, -2);
301 if (port && init_exec(init)) 303 if (port && init_exec(init)) {
302 return nv_wraux(port, addr, &data, 1); 304 int ret = nv_wraux(port, addr, &data, 1);
305 if (ret)
306 trace("auxch write failed with %d\n", ret);
307 return ret;
308 }
303 return -ENODEV; 309 return -ENODEV;
304} 310}
305 311
@@ -838,6 +844,40 @@ init_io_or(struct nvbios_init *init)
838} 844}
839 845
840/** 846/**
847 * INIT_ANDN_REG - opcode 0x47
848 *
849 */
850static void
851init_andn_reg(struct nvbios_init *init)
852{
853 struct nouveau_bios *bios = init->bios;
854 u32 reg = nv_ro32(bios, init->offset + 1);
855 u32 mask = nv_ro32(bios, init->offset + 5);
856
857 trace("ANDN_REG\tR[0x%06x] &= ~0x%08x\n", reg, mask);
858 init->offset += 9;
859
860 init_mask(init, reg, mask, 0);
861}
862
863/**
864 * INIT_OR_REG - opcode 0x48
865 *
866 */
867static void
868init_or_reg(struct nvbios_init *init)
869{
870 struct nouveau_bios *bios = init->bios;
871 u32 reg = nv_ro32(bios, init->offset + 1);
872 u32 mask = nv_ro32(bios, init->offset + 5);
873
874 trace("OR_REG\tR[0x%06x] |= 0x%08x\n", reg, mask);
875 init->offset += 9;
876
877 init_mask(init, reg, 0, mask);
878}
879
880/**
841 * INIT_INDEX_ADDRESS_LATCHED - opcode 0x49 881 * INIT_INDEX_ADDRESS_LATCHED - opcode 0x49
842 * 882 *
843 */ 883 */
@@ -2068,6 +2108,8 @@ static struct nvbios_init_opcode {
2068 [0x3a] = { init_dp_condition }, 2108 [0x3a] = { init_dp_condition },
2069 [0x3b] = { init_io_mask_or }, 2109 [0x3b] = { init_io_mask_or },
2070 [0x3c] = { init_io_or }, 2110 [0x3c] = { init_io_or },
2111 [0x47] = { init_andn_reg },
2112 [0x48] = { init_or_reg },
2071 [0x49] = { init_idx_addr_latched }, 2113 [0x49] = { init_idx_addr_latched },
2072 [0x4a] = { init_io_restrict_pll2 }, 2114 [0x4a] = { init_io_restrict_pll2 },
2073 [0x4b] = { init_pll2 }, 2115 [0x4b] = { init_pll2 },
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/npde.c b/drivers/gpu/drm/nouveau/core/subdev/bios/npde.c
new file mode 100644
index 000000000000..d694716a166c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/npde.c
@@ -0,0 +1,59 @@
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include <subdev/bios.h>
26#include <subdev/bios/npde.h>
27#include <subdev/bios/pcir.h>
28
29u32
30nvbios_npdeTe(struct nouveau_bios *bios, u32 base)
31{
32 struct nvbios_pcirT pcir;
33 u8 ver; u16 hdr;
34 u32 data = nvbios_pcirTp(bios, base, &ver, &hdr, &pcir);
35 if (data = (data + hdr + 0x0f) & ~0x0f, data) {
36 switch (nv_ro32(bios, data + 0x00)) {
37 case 0x4544504e: /* NPDE */
38 break;
39 default:
40 nv_debug(bios, "%08x: NPDE signature (%08x) unknown\n",
41 data, nv_ro32(bios, data + 0x00));
42 data = 0;
43 break;
44 }
45 }
46 return data;
47}
48
49u32
50nvbios_npdeTp(struct nouveau_bios *bios, u32 base, struct nvbios_npdeT *info)
51{
52 u32 data = nvbios_npdeTe(bios, base);
53 memset(info, 0x00, sizeof(*info));
54 if (data) {
55 info->image_size = nv_ro16(bios, data + 0x08) * 512;
56 info->last = nv_ro08(bios, data + 0x0a) & 0x80;
57 }
58 return data;
59}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c
new file mode 100644
index 000000000000..91dae26bc50f
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pcir.c
@@ -0,0 +1,69 @@
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include <subdev/bios.h>
26#include <subdev/bios/pcir.h>
27
28u32
29nvbios_pcirTe(struct nouveau_bios *bios, u32 base, u8 *ver, u16 *hdr)
30{
31 u32 data = nv_ro16(bios, base + 0x18);
32 if (data) {
33 data += base;
34 switch (nv_ro32(bios, data + 0x00)) {
35 case 0x52494350: /* PCIR */
36 case 0x53494752: /* RGIS */
37 case 0x5344504e: /* NPDS */
38 *hdr = nv_ro16(bios, data + 0x0a);
39 *ver = nv_ro08(bios, data + 0x0c);
40 break;
41 default:
42 nv_debug(bios, "%08x: PCIR signature (%08x) unknown\n",
43 data, nv_ro32(bios, data + 0x00));
44 data = 0;
45 break;
46 }
47 }
48 return data;
49}
50
51u32
52nvbios_pcirTp(struct nouveau_bios *bios, u32 base, u8 *ver, u16 *hdr,
53 struct nvbios_pcirT *info)
54{
55 u32 data = nvbios_pcirTe(bios, base, ver, hdr);
56 memset(info, 0x00, sizeof(*info));
57 if (data) {
58 info->vendor_id = nv_ro16(bios, data + 0x04);
59 info->device_id = nv_ro16(bios, data + 0x06);
60 info->class_code[0] = nv_ro08(bios, data + 0x0d);
61 info->class_code[1] = nv_ro08(bios, data + 0x0e);
62 info->class_code[2] = nv_ro08(bios, data + 0x0f);
63 info->image_size = nv_ro16(bios, data + 0x10) * 512;
64 info->image_rev = nv_ro16(bios, data + 0x12);
65 info->image_type = nv_ro08(bios, data + 0x14);
66 info->last = nv_ro08(bios, data + 0x15) & 0x80;
67 }
68 return data;
69}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c b/drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c
new file mode 100644
index 000000000000..66c56ba07d1b
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/pmu.c
@@ -0,0 +1,135 @@
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include <subdev/bios.h>
26#include <subdev/bios/bit.h>
27#include <subdev/bios/image.h>
28#include <subdev/bios/pmu.h>
29
30static u32
31weirdo_pointer(struct nouveau_bios *bios, u32 data)
32{
33 struct nvbios_image image;
34 int idx = 0;
35 if (nvbios_image(bios, idx++, &image)) {
36 data -= image.size;
37 while (nvbios_image(bios, idx++, &image)) {
38 if (image.type == 0xe0)
39 return image.base + data;
40 }
41 }
42 return 0;
43}
44
45u32
46nvbios_pmuTe(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len)
47{
48 struct bit_entry bit_p;
49 u32 data = 0;
50
51 if (!bit_entry(bios, 'p', &bit_p)) {
52 if (bit_p.version == 2 && bit_p.length >= 4)
53 data = nv_ro32(bios, bit_p.offset + 0x00);
54 if ((data = weirdo_pointer(bios, data))) {
55 *ver = nv_ro08(bios, data + 0x00); /* maybe? */
56 *hdr = nv_ro08(bios, data + 0x01);
57 *len = nv_ro08(bios, data + 0x02);
58 *cnt = nv_ro08(bios, data + 0x03);
59 }
60 }
61
62 return data;
63}
64
65u32
66nvbios_pmuTp(struct nouveau_bios *bios, u8 *ver, u8 *hdr, u8 *cnt, u8 *len,
67 struct nvbios_pmuT *info)
68{
69 u32 data = nvbios_pmuTe(bios, ver, hdr, cnt, len);
70 memset(info, 0x00, sizeof(*info));
71 switch (!!data * *ver) {
72 default:
73 break;
74 }
75 return data;
76}
77
78u32
79nvbios_pmuEe(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr)
80{
81 u8 cnt, len;
82 u32 data = nvbios_pmuTe(bios, ver, hdr, &cnt, &len);
83 if (data && idx < cnt) {
84 data = data + *hdr + (idx * len);
85 *hdr = len;
86 return data;
87 }
88 return 0;
89}
90
91u32
92nvbios_pmuEp(struct nouveau_bios *bios, int idx, u8 *ver, u8 *hdr,
93 struct nvbios_pmuE *info)
94{
95 u32 data = nvbios_pmuEe(bios, idx, ver, hdr);
96 memset(info, 0x00, sizeof(*info));
97 switch (!!data * *ver) {
98 default:
99 info->type = nv_ro08(bios, data + 0x00);
100 info->data = nv_ro32(bios, data + 0x02);
101 break;
102 }
103 return data;
104}
105
106bool
107nvbios_pmuRm(struct nouveau_bios *bios, u8 type, struct nvbios_pmuR *info)
108{
109 struct nvbios_pmuE pmuE;
110 u8 ver, hdr, idx = 0;
111 u32 data;
112 memset(info, 0x00, sizeof(*info));
113 while ((data = nvbios_pmuEp(bios, idx++, &ver, &hdr, &pmuE))) {
114 if ( pmuE.type == type &&
115 (data = weirdo_pointer(bios, pmuE.data))) {
116 info->init_addr_pmu = nv_ro32(bios, data + 0x08);
117 info->args_addr_pmu = nv_ro32(bios, data + 0x0c);
118 info->boot_addr = data + 0x30;
119 info->boot_addr_pmu = nv_ro32(bios, data + 0x10) +
120 nv_ro32(bios, data + 0x18);
121 info->boot_size = nv_ro32(bios, data + 0x1c) -
122 nv_ro32(bios, data + 0x18);
123 info->code_addr = info->boot_addr + info->boot_size;
124 info->code_addr_pmu = info->boot_addr_pmu +
125 info->boot_size;
126 info->code_size = nv_ro32(bios, data + 0x20);
127 info->data_addr = data + 0x30 +
128 nv_ro32(bios, data + 0x24);
129 info->data_addr_pmu = nv_ro32(bios, data + 0x28);
130 info->data_size = nv_ro32(bios, data + 0x2c);
131 return true;
132 }
133 }
134 return false;
135}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/priv.h b/drivers/gpu/drm/nouveau/core/subdev/bios/priv.h
new file mode 100644
index 000000000000..187d225bd1e9
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/priv.h
@@ -0,0 +1,25 @@
1#ifndef __NVKM_BIOS_PRIV_H__
2#define __NVKM_BIOS_PRIV_H__
3
4#include <subdev/bios.h>
5
6struct nvbios_source {
7 const char *name;
8 void *(*init)(struct nouveau_bios *, const char *);
9 void (*fini)(void *);
10 u32 (*read)(void *, u32 offset, u32 length, struct nouveau_bios *);
11 bool rw;
12};
13
14int nvbios_extend(struct nouveau_bios *, u32 length);
15int nvbios_shadow(struct nouveau_bios *);
16
17extern const struct nvbios_source nvbios_rom;
18extern const struct nvbios_source nvbios_ramin;
19extern const struct nvbios_source nvbios_acpi_fast;
20extern const struct nvbios_source nvbios_acpi_slow;
21extern const struct nvbios_source nvbios_pcirom;
22extern const struct nvbios_source nvbios_platform;
23extern const struct nvbios_source nvbios_of;
24
25#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c b/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c
index 6c401f70ab99..1623c8dfe797 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/ramcfg.c
@@ -25,6 +25,7 @@
25#include <subdev/bios.h> 25#include <subdev/bios.h>
26#include <subdev/bios/bit.h> 26#include <subdev/bios/bit.h>
27#include <subdev/bios/ramcfg.h> 27#include <subdev/bios/ramcfg.h>
28#include <subdev/bios/M0203.h>
28 29
29static u8 30static u8
30nvbios_ramcfg_strap(struct nouveau_subdev *subdev) 31nvbios_ramcfg_strap(struct nouveau_subdev *subdev)
@@ -54,12 +55,22 @@ nvbios_ramcfg_index(struct nouveau_subdev *subdev)
54 u8 strap = nvbios_ramcfg_strap(subdev); 55 u8 strap = nvbios_ramcfg_strap(subdev);
55 u32 xlat = 0x00000000; 56 u32 xlat = 0x00000000;
56 struct bit_entry bit_M; 57 struct bit_entry bit_M;
58 struct nvbios_M0203E M0203E;
59 u8 ver, hdr;
57 60
58 if (!bit_entry(bios, 'M', &bit_M)) { 61 if (!bit_entry(bios, 'M', &bit_M)) {
59 if (bit_M.version == 1 && bit_M.length >= 5) 62 if (bit_M.version == 1 && bit_M.length >= 5)
60 xlat = nv_ro16(bios, bit_M.offset + 3); 63 xlat = nv_ro16(bios, bit_M.offset + 3);
61 if (bit_M.version == 2 && bit_M.length >= 3) 64 if (bit_M.version == 2 && bit_M.length >= 3) {
65 /*XXX: is M ever shorter than this?
66 * if not - what is xlat used for now?
67 * also - sigh..
68 */
69 if (bit_M.length >= 7 &&
70 nvbios_M0203Em(bios, strap, &ver, &hdr, &M0203E))
71 return M0203E.group;
62 xlat = nv_ro16(bios, bit_M.offset + 1); 72 xlat = nv_ro16(bios, bit_M.offset + 1);
73 }
63 } 74 }
64 75
65 if (xlat) 76 if (xlat)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c b/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c
index 585e69331ccc..c5685228c322 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/rammap.c
@@ -162,8 +162,9 @@ nvbios_rammapSp(struct nouveau_bios *bios, u32 data,
162 p->ramcfg_10_02_08 = (nv_ro08(bios, data + 0x02) & 0x08) >> 3; 162 p->ramcfg_10_02_08 = (nv_ro08(bios, data + 0x02) & 0x08) >> 3;
163 p->ramcfg_10_02_10 = (nv_ro08(bios, data + 0x02) & 0x10) >> 4; 163 p->ramcfg_10_02_10 = (nv_ro08(bios, data + 0x02) & 0x10) >> 4;
164 p->ramcfg_10_02_20 = (nv_ro08(bios, data + 0x02) & 0x20) >> 5; 164 p->ramcfg_10_02_20 = (nv_ro08(bios, data + 0x02) & 0x20) >> 5;
165 p->ramcfg_10_02_40 = (nv_ro08(bios, data + 0x02) & 0x40) >> 6; 165 p->ramcfg_10_DLLoff = (nv_ro08(bios, data + 0x02) & 0x40) >> 6;
166 p->ramcfg_10_03_0f = (nv_ro08(bios, data + 0x03) & 0x0f) >> 0; 166 p->ramcfg_10_03_0f = (nv_ro08(bios, data + 0x03) & 0x0f) >> 0;
167 p->ramcfg_10_04_01 = (nv_ro08(bios, data + 0x04) & 0x01) >> 0;
167 p->ramcfg_10_05 = (nv_ro08(bios, data + 0x05) & 0xff) >> 0; 168 p->ramcfg_10_05 = (nv_ro08(bios, data + 0x05) & 0xff) >> 0;
168 p->ramcfg_10_06 = (nv_ro08(bios, data + 0x06) & 0xff) >> 0; 169 p->ramcfg_10_06 = (nv_ro08(bios, data + 0x06) & 0xff) >> 0;
169 p->ramcfg_10_07 = (nv_ro08(bios, data + 0x07) & 0xff) >> 0; 170 p->ramcfg_10_07 = (nv_ro08(bios, data + 0x07) & 0xff) >> 0;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c
new file mode 100644
index 000000000000..bb9e0018d936
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadow.c
@@ -0,0 +1,270 @@
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 */
24
25#include "priv.h"
26#include <core/option.h>
27#include <subdev/bios/image.h>
28
29struct shadow {
30 struct nouveau_oclass base;
31 u32 skip;
32 const struct nvbios_source *func;
33 void *data;
34 u32 size;
35 int score;
36};
37
38static bool
39shadow_fetch(struct nouveau_bios *bios, u32 upto)
40{
41 struct shadow *mthd = (void *)nv_object(bios)->oclass;
42 const u32 limit = (upto + 3) & ~3;
43 const u32 start = bios->size;
44 void *data = mthd->data;
45 if (nvbios_extend(bios, limit) > 0) {
46 u32 read = mthd->func->read(data, start, limit - start, bios);
47 bios->size = start + read;
48 }
49 return bios->size >= limit;
50}
51
52static u8
53shadow_rd08(struct nouveau_object *object, u64 addr)
54{
55 struct nouveau_bios *bios = (void *)object;
56 if (shadow_fetch(bios, addr + 1))
57 return bios->data[addr];
58 return 0x00;
59}
60
61static u16
62shadow_rd16(struct nouveau_object *object, u64 addr)
63{
64 struct nouveau_bios *bios = (void *)object;
65 if (shadow_fetch(bios, addr + 2))
66 return get_unaligned_le16(&bios->data[addr]);
67 return 0x0000;
68}
69
70static u32
71shadow_rd32(struct nouveau_object *object, u64 addr)
72{
73 struct nouveau_bios *bios = (void *)object;
74 if (shadow_fetch(bios, addr + 4))
75 return get_unaligned_le32(&bios->data[addr]);
76 return 0x00000000;
77}
78
79static struct nouveau_oclass
80shadow_class = {
81 .handle = NV_SUBDEV(VBIOS, 0x00),
82 .ofuncs = &(struct nouveau_ofuncs) {
83 .rd08 = shadow_rd08,
84 .rd16 = shadow_rd16,
85 .rd32 = shadow_rd32,
86 },
87};
88
89static int
90shadow_image(struct nouveau_bios *bios, int idx, struct shadow *mthd)
91{
92 struct nvbios_image image;
93 int score = 1;
94
95 if (!nvbios_image(bios, idx, &image)) {
96 nv_debug(bios, "image %d invalid\n", idx);
97 return 0;
98 }
99 nv_debug(bios, "%08x: type %02x, %d bytes\n",
100 image.base, image.type, image.size);
101
102 if (!shadow_fetch(bios, image.size)) {
103 nv_debug(bios, "%08x: fetch failed\n", image.base);
104 return 0;
105 }
106
107 switch (image.type) {
108 case 0x00:
109 if (nvbios_checksum(&bios->data[image.base], image.size)) {
110 nv_debug(bios, "%08x: checksum failed\n", image.base);
111 if (mthd->func->rw)
112 score += 1;
113 score += 1;
114 } else {
115 score += 3;
116 }
117 break;
118 default:
119 score += 3;
120 break;
121 }
122
123 if (!image.last)
124 score += shadow_image(bios, idx + 1, mthd);
125 return score;
126}
127
128static int
129shadow_score(struct nouveau_bios *bios, struct shadow *mthd)
130{
131 struct nouveau_oclass *oclass = nv_object(bios)->oclass;
132 int score;
133 nv_object(bios)->oclass = &mthd->base;
134 score = shadow_image(bios, 0, mthd);
135 nv_object(bios)->oclass = oclass;
136 return score;
137
138}
139
140static int
141shadow_method(struct nouveau_bios *bios, struct shadow *mthd, const char *name)
142{
143 const struct nvbios_source *func = mthd->func;
144 if (func->name) {
145 nv_debug(bios, "trying %s...\n", name ? name : func->name);
146 if (func->init) {
147 mthd->data = func->init(bios, name);
148 if (IS_ERR(mthd->data)) {
149 mthd->data = NULL;
150 return 0;
151 }
152 }
153 mthd->score = shadow_score(bios, mthd);
154 if (func->fini)
155 func->fini(mthd->data);
156 nv_debug(bios, "scored %d\n", mthd->score);
157 mthd->data = bios->data;
158 mthd->size = bios->size;
159 bios->data = NULL;
160 bios->size = 0;
161 }
162 return mthd->score;
163}
164
165static u32
166shadow_fw_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
167{
168 const struct firmware *fw = data;
169 if (offset + length <= fw->size) {
170 memcpy(bios->data + offset, fw->data + offset, length);
171 return length;
172 }
173 return 0;
174}
175
176static void *
177shadow_fw_init(struct nouveau_bios *bios, const char *name)
178{
179 struct device *dev = &nv_device(bios)->pdev->dev;
180 const struct firmware *fw;
181 int ret = request_firmware(&fw, name, dev);
182 if (ret)
183 return ERR_PTR(-ENOENT);
184 return (void *)fw;
185}
186
187static const struct nvbios_source
188shadow_fw = {
189 .name = "firmware",
190 .init = shadow_fw_init,
191 .fini = (void(*)(void *))release_firmware,
192 .read = shadow_fw_read,
193 .rw = false,
194};
195
196int
197nvbios_shadow(struct nouveau_bios *bios)
198{
199 struct shadow mthds[] = {
200 { shadow_class, 0, &nvbios_of },
201 { shadow_class, 0, &nvbios_ramin },
202 { shadow_class, 0, &nvbios_rom },
203 { shadow_class, 0, &nvbios_acpi_fast },
204 { shadow_class, 4, &nvbios_acpi_slow },
205 { shadow_class, 1, &nvbios_pcirom },
206 { shadow_class, 1, &nvbios_platform },
207 { shadow_class }
208 }, *mthd = mthds, *best = NULL;
209 const char *optarg;
210 char *source;
211 int optlen;
212
213 /* handle user-specified bios source */
214 optarg = nouveau_stropt(nv_device(bios)->cfgopt, "NvBios", &optlen);
215 source = optarg ? kstrndup(optarg, optlen, GFP_KERNEL) : NULL;
216 if (source) {
217 /* try to match one of the built-in methods */
218 for (mthd = mthds; mthd->func; mthd++) {
219 if (mthd->func->name &&
220 !strcasecmp(source, mthd->func->name)) {
221 best = mthd;
222 if (shadow_method(bios, mthd, NULL))
223 break;
224 }
225 }
226
227 /* otherwise, attempt to load as firmware */
228 if (!best && (best = mthd)) {
229 mthd->func = &shadow_fw;
230 shadow_method(bios, mthd, source);
231 mthd->func = NULL;
232 }
233
234 if (!best->score) {
235 nv_error(bios, "%s invalid\n", source);
236 kfree(source);
237 source = NULL;
238 }
239 }
240
241 /* scan all potential bios sources, looking for best image */
242 if (!best || !best->score) {
243 for (mthd = mthds, best = mthd; mthd->func; mthd++) {
244 if (!mthd->skip || best->score < mthd->skip) {
245 if (shadow_method(bios, mthd, NULL)) {
246 if (mthd->score > best->score)
247 best = mthd;
248 }
249 }
250 }
251 }
252
253 /* cleanup the ones we didn't use */
254 for (mthd = mthds; mthd->func; mthd++) {
255 if (mthd != best)
256 kfree(mthd->data);
257 }
258
259 if (!best->score) {
260 nv_fatal(bios, "unable to locate usable image\n");
261 return -EINVAL;
262 }
263
264 nv_info(bios, "using image from %s\n", best->func ?
265 best->func->name : source);
266 bios->data = best->data;
267 bios->size = best->size;
268 kfree(source);
269 return 0;
270}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c
new file mode 100644
index 000000000000..bc130c12ec06
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowacpi.c
@@ -0,0 +1,111 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "priv.h"
25
26#if defined(CONFIG_ACPI) && defined(CONFIG_X86)
27int nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len);
28bool nouveau_acpi_rom_supported(struct pci_dev *pdev);
29#else
30static inline bool
31nouveau_acpi_rom_supported(struct pci_dev *pdev)
32{
33 return false;
34}
35
36static inline int
37nouveau_acpi_get_bios_chunk(uint8_t *bios, int offset, int len)
38{
39 return -EINVAL;
40}
41#endif
42
43/* This version of the shadow function disobeys the ACPI spec and tries
44 * to fetch in units of more than 4KiB at a time. This is a LOT faster
45 * on some systems, such as Lenovo W530.
46 */
47static u32
48acpi_read_fast(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
49{
50 u32 limit = (offset + length + 0xfff) & ~0xfff;
51 u32 start = offset & ~0x00000fff;
52 u32 fetch = limit - start;
53
54 if (nvbios_extend(bios, limit) > 0) {
55 int ret = nouveau_acpi_get_bios_chunk(bios->data, start, fetch);
56 if (ret == fetch)
57 return fetch;
58 }
59
60 return 0;
61}
62
63/* Other systems, such as the one in fdo#55948, will report a success
64 * but only return 4KiB of data. The common bios fetching logic will
65 * detect an invalid image, and fall back to this version of the read
66 * function.
67 */
68static u32
69acpi_read_slow(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
70{
71 u32 limit = (offset + length + 0xfff) & ~0xfff;
72 u32 start = offset & ~0xfff;
73 u32 fetch = 0;
74
75 if (nvbios_extend(bios, limit) > 0) {
76 while (start + fetch < limit) {
77 int ret = nouveau_acpi_get_bios_chunk(bios->data,
78 start + fetch,
79 0x1000);
80 if (ret != 0x1000)
81 break;
82 fetch += 0x1000;
83 }
84 }
85
86 return fetch;
87}
88
89static void *
90acpi_init(struct nouveau_bios *bios, const char *name)
91{
92 if (!nouveau_acpi_rom_supported(nv_device(bios)->pdev))
93 return ERR_PTR(-ENODEV);
94 return NULL;
95}
96
97const struct nvbios_source
98nvbios_acpi_fast = {
99 .name = "ACPI",
100 .init = acpi_init,
101 .read = acpi_read_fast,
102 .rw = false,
103};
104
105const struct nvbios_source
106nvbios_acpi_slow = {
107 .name = "ACPI",
108 .init = acpi_init,
109 .read = acpi_read_slow,
110 .rw = false,
111};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c
new file mode 100644
index 000000000000..3abe487a6025
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowof.c
@@ -0,0 +1,71 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "priv.h"
25
26#if defined(__powerpc__)
27struct priv {
28 const void __iomem *data;
29 int size;
30};
31
32static u32
33of_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
34{
35 struct priv *priv = data;
36 if (offset + length <= priv->size) {
37 memcpy_fromio(bios->data + offset, priv->data + offset, length);
38 return length;
39 }
40 return 0;
41}
42
43static void *
44of_init(struct nouveau_bios *bios, const char *name)
45{
46 struct pci_dev *pdev = nv_device(bios)->pdev;
47 struct device_node *dn;
48 struct priv *priv;
49 if (!(dn = pci_device_to_OF_node(pdev)))
50 return ERR_PTR(-ENODEV);
51 if (!(priv = kzalloc(sizeof(*priv), GFP_KERNEL)))
52 return ERR_PTR(-ENOMEM);
53 if ((priv->data = of_get_property(dn, "NVDA,BMP", &priv->size)))
54 return priv;
55 kfree(priv);
56 return ERR_PTR(-EINVAL);
57}
58
59const struct nvbios_source
60nvbios_of = {
61 .name = "OpenFirmware",
62 .init = of_init,
63 .fini = (void(*)(void *))kfree,
64 .read = of_read,
65 .rw = false,
66};
67#else
68const struct nvbios_source
69nvbios_of = {
70};
71#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c
new file mode 100644
index 000000000000..1d0389c0abef
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowpci.c
@@ -0,0 +1,108 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "priv.h"
25
26struct priv {
27 struct pci_dev *pdev;
28 void __iomem *rom;
29 size_t size;
30};
31
32static u32
33pcirom_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
34{
35 struct priv *priv = data;
36 if (offset + length <= priv->size) {
37 memcpy_fromio(bios->data + offset, priv->rom + offset, length);
38 return length;
39 }
40 return 0;
41}
42
43static void
44pcirom_fini(void *data)
45{
46 struct priv *priv = data;
47 pci_unmap_rom(priv->pdev, priv->rom);
48 pci_disable_rom(priv->pdev);
49 kfree(priv);
50}
51
52static void *
53pcirom_init(struct nouveau_bios *bios, const char *name)
54{
55 struct pci_dev *pdev = nv_device(bios)->pdev;
56 struct priv *priv = NULL;
57 int ret;
58
59 if (!(ret = pci_enable_rom(pdev))) {
60 if (ret = -ENOMEM,
61 (priv = kmalloc(sizeof(*priv), GFP_KERNEL))) {
62 if (ret = -EFAULT,
63 (priv->rom = pci_map_rom(pdev, &priv->size))) {
64 priv->pdev = pdev;
65 return priv;
66 }
67 kfree(priv);
68 }
69 pci_disable_rom(pdev);
70 }
71
72 return ERR_PTR(ret);
73}
74
75const struct nvbios_source
76nvbios_pcirom = {
77 .name = "PCIROM",
78 .init = pcirom_init,
79 .fini = pcirom_fini,
80 .read = pcirom_read,
81 .rw = true,
82};
83
84static void *
85platform_init(struct nouveau_bios *bios, const char *name)
86{
87 struct pci_dev *pdev = nv_device(bios)->pdev;
88 struct priv *priv;
89 int ret = -ENOMEM;
90
91 if ((priv = kmalloc(sizeof(*priv), GFP_KERNEL))) {
92 if (ret = -ENODEV,
93 (priv->rom = pci_platform_rom(pdev, &priv->size)))
94 return priv;
95 kfree(priv);
96 }
97
98 return ERR_PTR(ret);
99}
100
101const struct nvbios_source
102nvbios_platform = {
103 .name = "PLATFORM",
104 .init = platform_init,
105 .fini = (void(*)(void *))kfree,
106 .read = pcirom_read,
107 .rw = true,
108};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c
new file mode 100644
index 000000000000..5e58bba0dd5c
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowramin.c
@@ -0,0 +1,112 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "priv.h"
25
26struct priv {
27 struct nouveau_bios *bios;
28 u32 bar0;
29};
30
31static u32
32pramin_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
33{
34 u32 i;
35 if (offset + length <= 0x00100000) {
36 for (i = offset; i < offset + length; i += 4)
37 *(u32 *)&bios->data[i] = nv_rd32(bios, 0x700000 + i);
38 return length;
39 }
40 return 0;
41}
42
43static void
44pramin_fini(void *data)
45{
46 struct priv *priv = data;
47 nv_wr32(priv->bios, 0x001700, priv->bar0);
48 kfree(priv);
49}
50
51static void *
52pramin_init(struct nouveau_bios *bios, const char *name)
53{
54 struct priv *priv = NULL;
55 u64 addr = 0;
56
57 /* PRAMIN always potentially available prior to nv50 */
58 if (nv_device(bios)->card_type < NV_50)
59 return NULL;
60
61 /* we can't get the bios image pointer without PDISP */
62 if (nv_device(bios)->card_type >= GM100)
63 addr = nv_rd32(bios, 0x021c04);
64 else
65 if (nv_device(bios)->card_type >= NV_C0)
66 addr = nv_rd32(bios, 0x022500);
67 if (addr & 0x00000001) {
68 nv_debug(bios, "... display disabled\n");
69 return ERR_PTR(-ENODEV);
70 }
71
72 /* check that the window is enabled and in vram, particularly
73 * important as we don't want to be touching vram on an
74 * uninitialised board
75 */
76 addr = nv_rd32(bios, 0x619f04);
77 if (!(addr & 0x00000008)) {
78 nv_debug(bios, "... not enabled\n");
79 return ERR_PTR(-ENODEV);
80 }
81 if ( (addr & 0x00000003) != 1) {
82 nv_debug(bios, "... not in vram\n");
83 return ERR_PTR(-ENODEV);
84 }
85
86 /* some alternate method inherited from xf86-video-nv... */
87 addr = (addr & 0xffffff00) << 8;
88 if (!addr) {
89 addr = (u64)nv_rd32(bios, 0x001700) << 16;
90 addr += 0xf0000;
91 }
92
93 /* modify bar0 PRAMIN window to cover the bios image */
94 if (!(priv = kmalloc(sizeof(*priv), GFP_KERNEL))) {
95 nv_error(bios, "... out of memory\n");
96 return ERR_PTR(-ENOMEM);
97 }
98
99 priv->bios = bios;
100 priv->bar0 = nv_rd32(bios, 0x001700);
101 nv_wr32(bios, 0x001700, addr >> 16);
102 return priv;
103}
104
105const struct nvbios_source
106nvbios_ramin = {
107 .name = "PRAMIN",
108 .init = pramin_init,
109 .fini = pramin_fini,
110 .read = pramin_read,
111 .rw = true,
112};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c
new file mode 100644
index 000000000000..b7992bc3ffa5
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/shadowrom.c
@@ -0,0 +1,69 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 */
23
24#include "priv.h"
25
26static u32
27prom_read(void *data, u32 offset, u32 length, struct nouveau_bios *bios)
28{
29 u32 i;
30 if (offset + length <= 0x00100000) {
31 for (i = offset; i < offset + length; i += 4)
32 *(u32 *)&bios->data[i] = nv_rd32(bios, 0x300000 + i);
33 return length;
34 }
35 return 0;
36}
37
38static void
39prom_fini(void *data)
40{
41 struct nouveau_bios *bios = data;
42 if (nv_device(bios)->card_type < NV_50)
43 nv_mask(bios, 0x001850, 0x00000001, 0x00000001);
44 else
45 nv_mask(bios, 0x088050, 0x00000001, 0x00000001);
46}
47
48static void *
49prom_init(struct nouveau_bios *bios, const char *name)
50{
51 if (nv_device(bios)->card_type < NV_50) {
52 if (nv_device(bios)->card_type == NV_40 &&
53 nv_device(bios)->chipset >= 0x4c)
54 return ERR_PTR(-ENODEV);
55 nv_mask(bios, 0x001850, 0x00000001, 0x00000000);
56 } else {
57 nv_mask(bios, 0x088050, 0x00000001, 0x00000000);
58 }
59 return bios;
60}
61
62const struct nvbios_source
63nvbios_rom = {
64 .name = "PROM",
65 .init = prom_init,
66 .fini = prom_fini,
67 .read = prom_read,
68 .rw = false,
69};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c b/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c
index 46d955eb51eb..8521eca1ed9c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/timing.c
@@ -93,10 +93,44 @@ nvbios_timingEp(struct nouveau_bios *bios, int idx,
93 p->timing_hdr = *hdr; 93 p->timing_hdr = *hdr;
94 switch (!!data * *ver) { 94 switch (!!data * *ver) {
95 case 0x10: 95 case 0x10:
96 p->timing_10_WR = nv_ro08(bios, data + 0x00); 96 p->timing_10_WR = nv_ro08(bios, data + 0x00);
97 p->timing_10_CL = nv_ro08(bios, data + 0x02); 97 p->timing_10_WTR = nv_ro08(bios, data + 0x01);
98 p->timing_10_ODT = nv_ro08(bios, data + 0x0e) & 0x07; 98 p->timing_10_CL = nv_ro08(bios, data + 0x02);
99 p->timing_10_CWL = nv_ro08(bios, data + 0x13); 99 p->timing_10_RC = nv_ro08(bios, data + 0x03);
100 p->timing_10_RFC = nv_ro08(bios, data + 0x05);
101 p->timing_10_RAS = nv_ro08(bios, data + 0x07);
102 p->timing_10_RP = nv_ro08(bios, data + 0x09);
103 p->timing_10_RCDRD = nv_ro08(bios, data + 0x0a);
104 p->timing_10_RCDWR = nv_ro08(bios, data + 0x0b);
105 p->timing_10_RRD = nv_ro08(bios, data + 0x0c);
106 p->timing_10_13 = nv_ro08(bios, data + 0x0d);
107 p->timing_10_ODT = nv_ro08(bios, data + 0x0e) & 0x07;
108
109 p->timing_10_24 = 0xff;
110 p->timing_10_21 = 0;
111 p->timing_10_20 = 0;
112 p->timing_10_CWL = 0;
113 p->timing_10_18 = 0;
114 p->timing_10_16 = 0;
115
116 switch (min_t(u8, *hdr, 25)) {
117 case 25:
118 p->timing_10_24 = nv_ro08(bios, data + 0x18);
119 case 24:
120 case 23:
121 case 22:
122 p->timing_10_21 = nv_ro08(bios, data + 0x15);
123 case 21:
124 p->timing_10_20 = nv_ro08(bios, data + 0x14);
125 case 20:
126 p->timing_10_CWL = nv_ro08(bios, data + 0x13);
127 case 19:
128 p->timing_10_18 = nv_ro08(bios, data + 0x12);
129 case 18:
130 case 17:
131 p->timing_10_16 = nv_ro08(bios, data + 0x10);
132 }
133
100 break; 134 break;
101 case 0x20: 135 case 0x20:
102 p->timing[0] = nv_ro32(bios, data + 0x00); 136 p->timing[0] = nv_ro32(bios, data + 0x00);
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c
index 425a8d5e9129..fb4fad374bdd 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/gk20a.c
@@ -109,7 +109,7 @@ struct gk20a_clk_pllg_params {
109}; 109};
110 110
111static const struct gk20a_clk_pllg_params gk20a_pllg_params = { 111static const struct gk20a_clk_pllg_params gk20a_pllg_params = {
112 .min_vco = 1000, .max_vco = 1700, 112 .min_vco = 1000, .max_vco = 2064,
113 .min_u = 12, .max_u = 38, 113 .min_u = 12, .max_u = 38,
114 .min_m = 1, .max_m = 255, 114 .min_m = 1, .max_m = 255,
115 .min_n = 8, .max_n = 255, 115 .min_n = 8, .max_n = 255,
@@ -470,76 +470,91 @@ gk20a_pstates[] = {
470 { 470 {
471 .base = { 471 .base = {
472 .domain[nv_clk_src_gpc] = 72000, 472 .domain[nv_clk_src_gpc] = 72000,
473 .voltage = 0,
473 }, 474 },
474 }, 475 },
475 { 476 {
476 .base = { 477 .base = {
477 .domain[nv_clk_src_gpc] = 108000, 478 .domain[nv_clk_src_gpc] = 108000,
479 .voltage = 1,
478 }, 480 },
479 }, 481 },
480 { 482 {
481 .base = { 483 .base = {
482 .domain[nv_clk_src_gpc] = 180000, 484 .domain[nv_clk_src_gpc] = 180000,
485 .voltage = 2,
483 }, 486 },
484 }, 487 },
485 { 488 {
486 .base = { 489 .base = {
487 .domain[nv_clk_src_gpc] = 252000, 490 .domain[nv_clk_src_gpc] = 252000,
491 .voltage = 3,
488 }, 492 },
489 }, 493 },
490 { 494 {
491 .base = { 495 .base = {
492 .domain[nv_clk_src_gpc] = 324000, 496 .domain[nv_clk_src_gpc] = 324000,
497 .voltage = 4,
493 }, 498 },
494 }, 499 },
495 { 500 {
496 .base = { 501 .base = {
497 .domain[nv_clk_src_gpc] = 396000, 502 .domain[nv_clk_src_gpc] = 396000,
503 .voltage = 5,
498 }, 504 },
499 }, 505 },
500 { 506 {
501 .base = { 507 .base = {
502 .domain[nv_clk_src_gpc] = 468000, 508 .domain[nv_clk_src_gpc] = 468000,
509 .voltage = 6,
503 }, 510 },
504 }, 511 },
505 { 512 {
506 .base = { 513 .base = {
507 .domain[nv_clk_src_gpc] = 540000, 514 .domain[nv_clk_src_gpc] = 540000,
515 .voltage = 7,
508 }, 516 },
509 }, 517 },
510 { 518 {
511 .base = { 519 .base = {
512 .domain[nv_clk_src_gpc] = 612000, 520 .domain[nv_clk_src_gpc] = 612000,
521 .voltage = 8,
513 }, 522 },
514 }, 523 },
515 { 524 {
516 .base = { 525 .base = {
517 .domain[nv_clk_src_gpc] = 648000, 526 .domain[nv_clk_src_gpc] = 648000,
527 .voltage = 9,
518 }, 528 },
519 }, 529 },
520 { 530 {
521 .base = { 531 .base = {
522 .domain[nv_clk_src_gpc] = 684000, 532 .domain[nv_clk_src_gpc] = 684000,
533 .voltage = 10,
523 }, 534 },
524 }, 535 },
525 { 536 {
526 .base = { 537 .base = {
527 .domain[nv_clk_src_gpc] = 708000, 538 .domain[nv_clk_src_gpc] = 708000,
539 .voltage = 11,
528 }, 540 },
529 }, 541 },
530 { 542 {
531 .base = { 543 .base = {
532 .domain[nv_clk_src_gpc] = 756000, 544 .domain[nv_clk_src_gpc] = 756000,
545 .voltage = 12,
533 }, 546 },
534 }, 547 },
535 { 548 {
536 .base = { 549 .base = {
537 .domain[nv_clk_src_gpc] = 804000, 550 .domain[nv_clk_src_gpc] = 804000,
551 .voltage = 13,
538 }, 552 },
539 }, 553 },
540 { 554 {
541 .base = { 555 .base = {
542 .domain[nv_clk_src_gpc] = 852000, 556 .domain[nv_clk_src_gpc] = 852000,
557 .voltage = 14,
543 }, 558 },
544 }, 559 },
545}; 560};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
index 094551d8ad9b..07ad01247675 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/clock/nva3.c
@@ -510,7 +510,7 @@ nva3_clock_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
510 int ret; 510 int ret;
511 511
512 ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, NULL, 0, 512 ret = nouveau_clock_create(parent, engine, oclass, nva3_domain, NULL, 0,
513 false, &priv); 513 true, &priv);
514 *pobject = nv_object(priv); 514 *pobject = nv_object(priv);
515 if (ret) 515 if (ret)
516 return ret; 516 return ret;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
index 239acfe876c3..0e45cee82463 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/base.c
@@ -24,8 +24,6 @@
24 24
25#include <core/option.h> 25#include <core/option.h>
26 26
27#include <subdev/bios.h>
28#include <subdev/bios/init.h>
29#include <subdev/vga.h> 27#include <subdev/vga.h>
30 28
31#include "priv.h" 29#include "priv.h"
@@ -56,7 +54,7 @@ _nouveau_devinit_init(struct nouveau_object *object)
56 if (ret) 54 if (ret)
57 return ret; 55 return ret;
58 56
59 ret = nvbios_init(&devinit->base, devinit->post); 57 ret = impl->post(&devinit->base, devinit->post);
60 if (ret) 58 if (ret)
61 return ret; 59 return ret;
62 60
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c
index c69bc7f54e37..4ba43d6a1ec8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/gm107.c
@@ -24,7 +24,7 @@
24 24
25#include "nv50.h" 25#include "nv50.h"
26 26
27static u64 27u64
28gm107_devinit_disable(struct nouveau_devinit *devinit) 28gm107_devinit_disable(struct nouveau_devinit *devinit)
29{ 29{
30 struct nv50_devinit_priv *priv = (void *)devinit; 30 struct nv50_devinit_priv *priv = (void *)devinit;
@@ -53,4 +53,5 @@ gm107_devinit_oclass = &(struct nouveau_devinit_impl) {
53 }, 53 },
54 .pll_set = nvc0_devinit_pll_set, 54 .pll_set = nvc0_devinit_pll_set,
55 .disable = gm107_devinit_disable, 55 .disable = gm107_devinit_disable,
56 .post = nvbios_init,
56}.base; 57}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c
new file mode 100644
index 000000000000..e44a86662a2a
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/gm204.c
@@ -0,0 +1,173 @@
1/*
2 * Copyright 2013 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include <subdev/bios.h>
26#include <subdev/bios/bit.h>
27#include <subdev/bios/pmu.h>
28
29#include "nv50.h"
30
31static void
32pmu_code(struct nv50_devinit_priv *priv, u32 pmu, u32 img, u32 len, bool sec)
33{
34 struct nouveau_bios *bios = nouveau_bios(priv);
35 int i;
36
37 nv_wr32(priv, 0x10a180, 0x01000000 | (sec ? 0x10000000 : 0) | pmu);
38 for (i = 0; i < len; i += 4) {
39 if ((i & 0xff) == 0)
40 nv_wr32(priv, 0x10a188, (pmu + i) >> 8);
41 nv_wr32(priv, 0x10a184, nv_ro32(bios, img + i));
42 }
43
44 while (i & 0xff) {
45 nv_wr32(priv, 0x10a184, 0x00000000);
46 i += 4;
47 }
48}
49
50static void
51pmu_data(struct nv50_devinit_priv *priv, u32 pmu, u32 img, u32 len)
52{
53 struct nouveau_bios *bios = nouveau_bios(priv);
54 int i;
55
56 nv_wr32(priv, 0x10a1c0, 0x01000000 | pmu);
57 for (i = 0; i < len; i += 4)
58 nv_wr32(priv, 0x10a1c4, nv_ro32(bios, img + i));
59}
60
61static u32
62pmu_args(struct nv50_devinit_priv *priv, u32 argp, u32 argi)
63{
64 nv_wr32(priv, 0x10a1c0, argp);
65 nv_wr32(priv, 0x10a1c0, nv_rd32(priv, 0x10a1c4) + argi);
66 return nv_rd32(priv, 0x10a1c4);
67}
68
69static void
70pmu_exec(struct nv50_devinit_priv *priv, u32 init_addr)
71{
72 nv_wr32(priv, 0x10a104, init_addr);
73 nv_wr32(priv, 0x10a10c, 0x00000000);
74 nv_wr32(priv, 0x10a100, 0x00000002);
75}
76
77static int
78pmu_load(struct nv50_devinit_priv *priv, u8 type, bool post,
79 u32 *init_addr_pmu, u32 *args_addr_pmu)
80{
81 struct nouveau_bios *bios = nouveau_bios(priv);
82 struct nvbios_pmuR pmu;
83
84 if (!nvbios_pmuRm(bios, type, &pmu)) {
85 nv_error(priv, "VBIOS PMU fuc %02x not found\n", type);
86 return -EINVAL;
87 }
88
89 if (!post)
90 return 0;
91
92 pmu_code(priv, pmu.boot_addr_pmu, pmu.boot_addr, pmu.boot_size, false);
93 pmu_code(priv, pmu.code_addr_pmu, pmu.code_addr, pmu.code_size, true);
94 pmu_data(priv, pmu.data_addr_pmu, pmu.data_addr, pmu.data_size);
95
96 if (init_addr_pmu) {
97 *init_addr_pmu = pmu.init_addr_pmu;
98 *args_addr_pmu = pmu.args_addr_pmu;
99 return 0;
100 }
101
102 return pmu_exec(priv, pmu.init_addr_pmu), 0;
103}
104
105static int
106gm204_devinit_post(struct nouveau_subdev *subdev, bool post)
107{
108 struct nv50_devinit_priv *priv = (void *)nouveau_devinit(subdev);
109 struct nouveau_bios *bios = nouveau_bios(priv);
110 struct bit_entry bit_I;
111 u32 init, args;
112 int ret;
113
114 if (bit_entry(bios, 'I', &bit_I) || bit_I.version != 1 ||
115 bit_I.length < 0x1c) {
116 nv_error(priv, "VBIOS PMU init data not found\n");
117 return -EINVAL;
118 }
119
120 /* reset PMU and load init table parser ucode */
121 if (post) {
122 nv_mask(priv, 0x000200, 0x00002000, 0x00000000);
123 nv_mask(priv, 0x000200, 0x00002000, 0x00002000);
124 nv_rd32(priv, 0x000200);
125 while (nv_rd32(priv, 0x10a10c) & 0x00000006) {
126 }
127 }
128
129 ret = pmu_load(priv, 0x04, post, &init, &args);
130 if (ret)
131 return ret;
132
133 /* upload first chunk of init data */
134 if (post) {
135 u32 pmu = pmu_args(priv, args + 0x08, 0x08);
136 u32 img = nv_ro16(bios, bit_I.offset + 0x14);
137 u32 len = nv_ro16(bios, bit_I.offset + 0x16);
138 pmu_data(priv, pmu, img, len);
139 }
140
141 /* upload second chunk of init data */
142 if (post) {
143 u32 pmu = pmu_args(priv, args + 0x08, 0x10);
144 u32 img = nv_ro16(bios, bit_I.offset + 0x18);
145 u32 len = nv_ro16(bios, bit_I.offset + 0x1a);
146 pmu_data(priv, pmu, img, len);
147 }
148
149 /* execute init tables */
150 if (post) {
151 nv_wr32(priv, 0x10a040, 0x00005000);
152 pmu_exec(priv, init);
153 while (!(nv_rd32(priv, 0x10a040) & 0x00002000)) {
154 }
155 }
156
157 /* load and execute some other ucode image (bios therm?) */
158 return pmu_load(priv, 0x01, post, NULL, NULL);
159}
160
161struct nouveau_oclass *
162gm204_devinit_oclass = &(struct nouveau_devinit_impl) {
163 .base.handle = NV_SUBDEV(DEVINIT, 0x07),
164 .base.ofuncs = &(struct nouveau_ofuncs) {
165 .ctor = nv50_devinit_ctor,
166 .dtor = _nouveau_devinit_dtor,
167 .init = nv50_devinit_init,
168 .fini = _nouveau_devinit_fini,
169 },
170 .pll_set = nvc0_devinit_pll_set,
171 .disable = gm107_devinit_disable,
172 .post = gm204_devinit_post,
173}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
index 052ad690b468..65651c50f6ea 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv04.c
@@ -464,4 +464,5 @@ nv04_devinit_oclass = &(struct nouveau_devinit_impl) {
464 }, 464 },
465 .meminit = nv04_devinit_meminit, 465 .meminit = nv04_devinit_meminit,
466 .pll_set = nv04_devinit_pll_set, 466 .pll_set = nv04_devinit_pll_set,
467 .post = nvbios_init,
467}.base; 468}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
index 4a19c10e5178..a2007a3efc4d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv05.c
@@ -136,4 +136,5 @@ nv05_devinit_oclass = &(struct nouveau_devinit_impl) {
136 }, 136 },
137 .meminit = nv05_devinit_meminit, 137 .meminit = nv05_devinit_meminit,
138 .pll_set = nv04_devinit_pll_set, 138 .pll_set = nv04_devinit_pll_set,
139 .post = nvbios_init,
139}.base; 140}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
index 3b8d657da279..178b46f79b50 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv10.c
@@ -107,4 +107,5 @@ nv10_devinit_oclass = &(struct nouveau_devinit_impl) {
107 }, 107 },
108 .meminit = nv10_devinit_meminit, 108 .meminit = nv10_devinit_meminit,
109 .pll_set = nv04_devinit_pll_set, 109 .pll_set = nv04_devinit_pll_set,
110 .post = nvbios_init,
110}.base; 111}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
index 526d0c6faacd..995dd97af3e9 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv1a.c
@@ -34,4 +34,5 @@ nv1a_devinit_oclass = &(struct nouveau_devinit_impl) {
34 .fini = nv04_devinit_fini, 34 .fini = nv04_devinit_fini,
35 }, 35 },
36 .pll_set = nv04_devinit_pll_set, 36 .pll_set = nv04_devinit_pll_set,
37 .post = nvbios_init,
37}.base; 38}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
index 04bc9732644c..915089fb46f7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv20.c
@@ -71,4 +71,5 @@ nv20_devinit_oclass = &(struct nouveau_devinit_impl) {
71 }, 71 },
72 .meminit = nv20_devinit_meminit, 72 .meminit = nv20_devinit_meminit,
73 .pll_set = nv04_devinit_pll_set, 73 .pll_set = nv04_devinit_pll_set,
74 .post = nvbios_init,
74}.base; 75}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
index b46c62a1d5d8..968334d1dca4 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.c
@@ -26,6 +26,7 @@
26#include <subdev/bios/dcb.h> 26#include <subdev/bios/dcb.h>
27#include <subdev/bios/disp.h> 27#include <subdev/bios/disp.h>
28#include <subdev/bios/init.h> 28#include <subdev/bios/init.h>
29#include <subdev/ibus.h>
29#include <subdev/vga.h> 30#include <subdev/vga.h>
30 31
31#include "nv50.h" 32#include "nv50.h"
@@ -91,6 +92,7 @@ int
91nv50_devinit_init(struct nouveau_object *object) 92nv50_devinit_init(struct nouveau_object *object)
92{ 93{
93 struct nouveau_bios *bios = nouveau_bios(object); 94 struct nouveau_bios *bios = nouveau_bios(object);
95 struct nouveau_ibus *ibus = nouveau_ibus(object);
94 struct nv50_devinit_priv *priv = (void *)object; 96 struct nv50_devinit_priv *priv = (void *)object;
95 struct nvbios_outp info; 97 struct nvbios_outp info;
96 struct dcb_output outp; 98 struct dcb_output outp;
@@ -105,6 +107,13 @@ nv50_devinit_init(struct nouveau_object *object)
105 } 107 }
106 } 108 }
107 109
110 /* some boards appear to require certain priv register timeouts
111 * to be bumped before runing devinit scripts. not a clue why
112 * the vbios engineers didn't make the scripts just work...
113 */
114 if (priv->base.post && ibus)
115 nv_ofuncs(ibus)->init(nv_object(ibus));
116
108 ret = nouveau_devinit_init(&priv->base); 117 ret = nouveau_devinit_init(&priv->base);
109 if (ret) 118 if (ret)
110 return ret; 119 return ret;
@@ -160,4 +169,5 @@ nv50_devinit_oclass = &(struct nouveau_devinit_impl) {
160 }, 169 },
161 .pll_set = nv50_devinit_pll_set, 170 .pll_set = nv50_devinit_pll_set,
162 .disable = nv50_devinit_disable, 171 .disable = nv50_devinit_disable,
172 .post = nvbios_init,
163}.base; 173}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
index 51d5076333ec..f412bb7f780e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv50.h
@@ -18,4 +18,6 @@ int nva3_devinit_pll_set(struct nouveau_devinit *, u32, u32);
18 18
19int nvc0_devinit_pll_set(struct nouveau_devinit *, u32, u32); 19int nvc0_devinit_pll_set(struct nouveau_devinit *, u32, u32);
20 20
21u64 gm107_devinit_disable(struct nouveau_devinit *);
22
21#endif 23#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c
index 787422505d87..a7c80ded77cd 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv84.c
@@ -60,4 +60,5 @@ nv84_devinit_oclass = &(struct nouveau_devinit_impl) {
60 }, 60 },
61 .pll_set = nv50_devinit_pll_set, 61 .pll_set = nv50_devinit_pll_set,
62 .disable = nv84_devinit_disable, 62 .disable = nv84_devinit_disable,
63 .post = nvbios_init,
63}.base; 64}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c
index 2b0e963fc6f0..a773253a17f6 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nv98.c
@@ -59,4 +59,5 @@ nv98_devinit_oclass = &(struct nouveau_devinit_impl) {
59 }, 59 },
60 .pll_set = nv50_devinit_pll_set, 60 .pll_set = nv50_devinit_pll_set,
61 .disable = nv98_devinit_disable, 61 .disable = nv98_devinit_disable,
62 .post = nvbios_init,
62}.base; 63}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
index 006cf348bda7..b9cd9e53f760 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nva3.c
@@ -142,4 +142,5 @@ nva3_devinit_oclass = &(struct nouveau_devinit_impl) {
142 .pll_set = nva3_devinit_pll_set, 142 .pll_set = nva3_devinit_pll_set,
143 .disable = nva3_devinit_disable, 143 .disable = nva3_devinit_disable,
144 .mmio = nva3_devinit_mmio, 144 .mmio = nva3_devinit_mmio,
145 .post = nvbios_init,
145}.base; 146}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c
index 4fc68d27eff3..3729846a8e5c 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvaf.c
@@ -60,4 +60,5 @@ nvaf_devinit_oclass = &(struct nouveau_devinit_impl) {
60 }, 60 },
61 .pll_set = nva3_devinit_pll_set, 61 .pll_set = nva3_devinit_pll_set,
62 .disable = nvaf_devinit_disable, 62 .disable = nvaf_devinit_disable,
63 .post = nvbios_init,
63}.base; 64}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c
index 30c765747eea..80bd7f5eda3d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/nvc0.c
@@ -115,4 +115,5 @@ nvc0_devinit_oclass = &(struct nouveau_devinit_impl) {
115 }, 115 },
116 .pll_set = nvc0_devinit_pll_set, 116 .pll_set = nvc0_devinit_pll_set,
117 .disable = nvc0_devinit_disable, 117 .disable = nvc0_devinit_disable,
118 .post = nvbios_init,
118}.base; 119}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
index f0e8683ad840..cbcd51852472 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/devinit/priv.h
@@ -3,6 +3,7 @@
3 3
4#include <subdev/bios.h> 4#include <subdev/bios.h>
5#include <subdev/bios/pll.h> 5#include <subdev/bios/pll.h>
6#include <subdev/bios/init.h>
6#include <subdev/clock/pll.h> 7#include <subdev/clock/pll.h>
7#include <subdev/devinit.h> 8#include <subdev/devinit.h>
8 9
@@ -12,6 +13,7 @@ struct nouveau_devinit_impl {
12 int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq); 13 int (*pll_set)(struct nouveau_devinit *, u32 type, u32 freq);
13 u64 (*disable)(struct nouveau_devinit *); 14 u64 (*disable)(struct nouveau_devinit *);
14 u32 (*mmio)(struct nouveau_devinit *, u32); 15 u32 (*mmio)(struct nouveau_devinit *, u32);
16 int (*post)(struct nouveau_subdev *, bool);
15}; 17};
16 18
17#define nouveau_devinit_create(p,e,o,d) \ 19#define nouveau_devinit_create(p,e,o,d) \
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
index f009d8a39d9d..c866148c440f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/base.c
@@ -23,37 +23,30 @@
23 */ 23 */
24 24
25#include <subdev/bios.h> 25#include <subdev/bios.h>
26#include <subdev/bios/bit.h> 26#include <subdev/bios/M0203.h>
27 27
28#include "priv.h" 28#include "priv.h"
29 29
30int 30int
31nouveau_fb_bios_memtype(struct nouveau_bios *bios) 31nouveau_fb_bios_memtype(struct nouveau_bios *bios)
32{ 32{
33 struct bit_entry M; 33 const u8 ramcfg = (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2;
34 u8 ramcfg; 34 struct nvbios_M0203E M0203E;
35 35 u8 ver, hdr;
36 ramcfg = (nv_rd32(bios, 0x101000) & 0x0000003c) >> 2; 36
37 if (!bit_entry(bios, 'M', &M) && M.version == 2 && M.length >= 5) { 37 if (nvbios_M0203Em(bios, ramcfg, &ver, &hdr, &M0203E)) {
38 u16 table = nv_ro16(bios, M.offset + 3); 38 switch (M0203E.type) {
39 u8 version = nv_ro08(bios, table + 0); 39 case M0203E_TYPE_DDR2 : return NV_MEM_TYPE_DDR2;
40 u8 header = nv_ro08(bios, table + 1); 40 case M0203E_TYPE_DDR3 : return NV_MEM_TYPE_DDR3;
41 u8 record = nv_ro08(bios, table + 2); 41 case M0203E_TYPE_GDDR3: return NV_MEM_TYPE_GDDR3;
42 u8 entries = nv_ro08(bios, table + 3); 42 case M0203E_TYPE_GDDR5: return NV_MEM_TYPE_GDDR5;
43 if (table && version == 0x10 && ramcfg < entries) { 43 default:
44 u16 entry = table + header + (ramcfg * record); 44 nv_warn(bios, "M0203E type %02x\n", M0203E.type);
45 switch (nv_ro08(bios, entry) & 0x0f) { 45 return NV_MEM_TYPE_UNKNOWN;
46 case 0: return NV_MEM_TYPE_DDR2;
47 case 1: return NV_MEM_TYPE_DDR3;
48 case 2: return NV_MEM_TYPE_GDDR3;
49 case 3: return NV_MEM_TYPE_GDDR5;
50 default:
51 break;
52 }
53
54 } 46 }
55 } 47 }
56 48
49 nv_warn(bios, "M0203E not matched!\n");
57 return NV_MEM_TYPE_UNKNOWN; 50 return NV_MEM_TYPE_UNKNOWN;
58} 51}
59 52
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c
new file mode 100644
index 000000000000..d85a25d027ee
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/gddr3.c
@@ -0,0 +1,117 @@
1/*
2 * Copyright 2013 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs <bskeggs@redhat.com>
23 * Roy Spliet <rspliet@eclipso.eu>
24 */
25
26#include <subdev/bios.h>
27#include "priv.h"
28
29struct ramxlat {
30 int id;
31 u8 enc;
32};
33
34static inline int
35ramxlat(const struct ramxlat *xlat, int id)
36{
37 while (xlat->id >= 0) {
38 if (xlat->id == id)
39 return xlat->enc;
40 xlat++;
41 }
42 return -EINVAL;
43}
44
45static const struct ramxlat
46ramgddr3_cl_lo[] = {
47 { 7, 7 }, { 8, 0 }, { 9, 1 }, { 10, 2 }, { 11, 3 },
48 /* the below are mentioned in some, but not all, gddr3 docs */
49 { 12, 4 }, { 13, 5 }, { 14, 6 },
50 /* XXX: Per Samsung docs, are these used? They overlap with Qimonda */
51 /* { 4, 4 }, { 5, 5 }, { 6, 6 }, { 12, 8 }, { 13, 9 }, { 14, 10 },
52 * { 15, 11 }, */
53 { -1 }
54};
55
56static const struct ramxlat
57ramgddr3_cl_hi[] = {
58 { 10, 2 }, { 11, 3 }, { 12, 4 }, { 13, 5 }, { 14, 6 }, { 15, 7 },
59 { 16, 0 }, { 17, 1 },
60 { -1 }
61};
62
63static const struct ramxlat
64ramgddr3_wr_lo[] = {
65 { 5, 2 }, { 7, 4 }, { 8, 5 }, { 9, 6 }, { 10, 7 },
66 { 11, 0 },
67 /* the below are mentioned in some, but not all, gddr3 docs */
68 { 4, 1 }, { 6, 3 }, { 12, 1 }, { 13 , 2 },
69 { -1 }
70};
71
72int
73nouveau_gddr3_calc(struct nouveau_ram *ram)
74{
75 int CL, WR, CWL, DLL = 0, ODT = 0, hi;
76
77 switch (ram->next->bios.timing_ver) {
78 case 0x10:
79 CWL = ram->next->bios.timing_10_CWL;
80 CL = ram->next->bios.timing_10_CL;
81 WR = ram->next->bios.timing_10_WR;
82 DLL = !ram->next->bios.ramcfg_10_DLLoff;
83 ODT = ram->next->bios.timing_10_ODT;
84 break;
85 case 0x20:
86 CWL = (ram->next->bios.timing[1] & 0x00000f80) >> 7;
87 CL = (ram->next->bios.timing[1] & 0x0000001f) >> 0;
88 WR = (ram->next->bios.timing[2] & 0x007f0000) >> 16;
89 /* XXX: Get these values from the VBIOS instead */
90 DLL = !(ram->mr[1] & 0x1);
91 ODT = (ram->mr[1] & 0x004) >> 2 |
92 (ram->mr[1] & 0x040) >> 5 |
93 (ram->mr[1] & 0x200) >> 7;
94 break;
95 default:
96 return -ENOSYS;
97 }
98
99 hi = ram->mr[2] & 0x1;
100 CL = ramxlat(hi ? ramgddr3_cl_hi : ramgddr3_cl_lo, CL);
101 WR = ramxlat(ramgddr3_wr_lo, WR);
102 if (CL < 0 || CWL < 1 || CWL > 7 || WR < 0)
103 return -EINVAL;
104
105 ram->mr[0] &= ~0xf74;
106 ram->mr[0] |= (CWL & 0x07) << 9;
107 ram->mr[0] |= (CL & 0x07) << 4;
108 ram->mr[0] |= (CL & 0x08) >> 1;
109
110 ram->mr[1] &= ~0x3fc;
111 ram->mr[1] |= (ODT & 0x03) << 2;
112 ram->mr[1] |= (ODT & 0x03) << 8;
113 ram->mr[1] |= (WR & 0x03) << 4;
114 ram->mr[1] |= (WR & 0x04) << 5;
115 ram->mr[1] |= !DLL << 6;
116 return 0;
117}
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
index 60322e906dd4..283863f7aa9b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/priv.h
@@ -37,6 +37,7 @@ extern struct nouveau_oclass gm107_ram_oclass;
37 37
38int nouveau_sddr2_calc(struct nouveau_ram *ram); 38int nouveau_sddr2_calc(struct nouveau_ram *ram);
39int nouveau_sddr3_calc(struct nouveau_ram *ram); 39int nouveau_sddr3_calc(struct nouveau_ram *ram);
40int nouveau_gddr3_calc(struct nouveau_ram *ram);
40int nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts); 41int nouveau_gddr5_calc(struct nouveau_ram *ram, bool nuts);
41 42
42#define nouveau_fb_create(p,e,c,d) \ 43#define nouveau_fb_create(p,e,c,d) \
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
index d1fbbe4b00a2..0ac7256443bb 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramfuc.h
@@ -141,6 +141,20 @@ ramfuc_wait_vblank(struct ramfuc *ram)
141} 141}
142 142
143static inline void 143static inline void
144ramfuc_train(struct ramfuc *ram)
145{
146 nouveau_memx_train(ram->memx);
147}
148
149static inline int
150ramfuc_train_result(struct nouveau_fb *pfb, u32 *result, u32 rsize)
151{
152 struct nouveau_pwr *ppwr = nouveau_pwr(pfb);
153
154 return nouveau_memx_train_result(ppwr, result, rsize);
155}
156
157static inline void
144ramfuc_block(struct ramfuc *ram) 158ramfuc_block(struct ramfuc *ram)
145{ 159{
146 nouveau_memx_block(ram->memx); 160 nouveau_memx_block(ram->memx);
@@ -162,6 +176,8 @@ ramfuc_unblock(struct ramfuc *ram)
162#define ram_wait(s,r,m,d,n) ramfuc_wait(&(s)->base, (r), (m), (d), (n)) 176#define ram_wait(s,r,m,d,n) ramfuc_wait(&(s)->base, (r), (m), (d), (n))
163#define ram_nsec(s,n) ramfuc_nsec(&(s)->base, (n)) 177#define ram_nsec(s,n) ramfuc_nsec(&(s)->base, (n))
164#define ram_wait_vblank(s) ramfuc_wait_vblank(&(s)->base) 178#define ram_wait_vblank(s) ramfuc_wait_vblank(&(s)->base)
179#define ram_train(s) ramfuc_train(&(s)->base)
180#define ram_train_result(s,r,l) ramfuc_train_result((s), (r), (l))
165#define ram_block(s) ramfuc_block(&(s)->base) 181#define ram_block(s) ramfuc_block(&(s)->base)
166#define ram_unblock(s) ramfuc_unblock(&(s)->base) 182#define ram_unblock(s) ramfuc_unblock(&(s)->base)
167 183
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
index 3601deca0bd5..3b38a538845d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/ramnva3.c
@@ -20,86 +20,512 @@
20 * OTHER DEALINGS IN THE SOFTWARE. 20 * OTHER DEALINGS IN THE SOFTWARE.
21 * 21 *
22 * Authors: Ben Skeggs 22 * Authors: Ben Skeggs
23 * Roy Spliet <rspliet@eclipso.eu>
23 */ 24 */
24 25
25#include <subdev/bios.h> 26#include <subdev/bios.h>
26#include <subdev/bios/bit.h> 27#include <subdev/bios/bit.h>
27#include <subdev/bios/pll.h> 28#include <subdev/bios/pll.h>
28#include <subdev/bios/rammap.h> 29#include <subdev/bios/rammap.h>
30#include <subdev/bios/M0205.h>
29#include <subdev/bios/timing.h> 31#include <subdev/bios/timing.h>
30 32
31#include <subdev/clock/nva3.h> 33#include <subdev/clock/nva3.h>
32#include <subdev/clock/pll.h> 34#include <subdev/clock/pll.h>
33 35
36#include <subdev/gpio.h>
37
38#include <subdev/timer.h>
39
40#include <engine/fifo.h>
41
34#include <core/option.h> 42#include <core/option.h>
35 43
36#include "ramfuc.h" 44#include "ramfuc.h"
37 45
38#include "nv50.h" 46#include "nv50.h"
39 47
48/* XXX: Remove when memx gains GPIO support */
49extern int nv50_gpio_location(int line, u32 *reg, u32 *shift);
50
40struct nva3_ramfuc { 51struct nva3_ramfuc {
41 struct ramfuc base; 52 struct ramfuc base;
53 struct ramfuc_reg r_0x001610;
54 struct ramfuc_reg r_0x001700;
55 struct ramfuc_reg r_0x002504;
42 struct ramfuc_reg r_0x004000; 56 struct ramfuc_reg r_0x004000;
43 struct ramfuc_reg r_0x004004; 57 struct ramfuc_reg r_0x004004;
44 struct ramfuc_reg r_0x004018; 58 struct ramfuc_reg r_0x004018;
45 struct ramfuc_reg r_0x004128; 59 struct ramfuc_reg r_0x004128;
46 struct ramfuc_reg r_0x004168; 60 struct ramfuc_reg r_0x004168;
61 struct ramfuc_reg r_0x100080;
47 struct ramfuc_reg r_0x100200; 62 struct ramfuc_reg r_0x100200;
48 struct ramfuc_reg r_0x100210; 63 struct ramfuc_reg r_0x100210;
49 struct ramfuc_reg r_0x100220[9]; 64 struct ramfuc_reg r_0x100220[9];
65 struct ramfuc_reg r_0x100264;
50 struct ramfuc_reg r_0x1002d0; 66 struct ramfuc_reg r_0x1002d0;
51 struct ramfuc_reg r_0x1002d4; 67 struct ramfuc_reg r_0x1002d4;
52 struct ramfuc_reg r_0x1002dc; 68 struct ramfuc_reg r_0x1002dc;
53 struct ramfuc_reg r_0x10053c; 69 struct ramfuc_reg r_0x10053c;
54 struct ramfuc_reg r_0x1005a0; 70 struct ramfuc_reg r_0x1005a0;
55 struct ramfuc_reg r_0x1005a4; 71 struct ramfuc_reg r_0x1005a4;
72 struct ramfuc_reg r_0x100700;
56 struct ramfuc_reg r_0x100714; 73 struct ramfuc_reg r_0x100714;
57 struct ramfuc_reg r_0x100718; 74 struct ramfuc_reg r_0x100718;
58 struct ramfuc_reg r_0x10071c; 75 struct ramfuc_reg r_0x10071c;
76 struct ramfuc_reg r_0x100720;
59 struct ramfuc_reg r_0x100760; 77 struct ramfuc_reg r_0x100760;
60 struct ramfuc_reg r_0x1007a0; 78 struct ramfuc_reg r_0x1007a0;
61 struct ramfuc_reg r_0x1007e0; 79 struct ramfuc_reg r_0x1007e0;
80 struct ramfuc_reg r_0x100da0;
62 struct ramfuc_reg r_0x10f804; 81 struct ramfuc_reg r_0x10f804;
63 struct ramfuc_reg r_0x1110e0; 82 struct ramfuc_reg r_0x1110e0;
64 struct ramfuc_reg r_0x111100; 83 struct ramfuc_reg r_0x111100;
65 struct ramfuc_reg r_0x111104; 84 struct ramfuc_reg r_0x111104;
85 struct ramfuc_reg r_0x1111e0;
86 struct ramfuc_reg r_0x111400;
66 struct ramfuc_reg r_0x611200; 87 struct ramfuc_reg r_0x611200;
67 struct ramfuc_reg r_mr[4]; 88 struct ramfuc_reg r_mr[4];
89 struct ramfuc_reg r_gpioFBVREF;
90};
91
92struct nva3_ltrain {
93 enum {
94 NVA3_TRAIN_UNKNOWN,
95 NVA3_TRAIN_UNSUPPORTED,
96 NVA3_TRAIN_ONCE,
97 NVA3_TRAIN_EXEC,
98 NVA3_TRAIN_DONE
99 } state;
100 u32 r_100720;
101 u32 r_1111e0;
102 u32 r_111400;
103 struct nouveau_mem *mem;
68}; 104};
69 105
70struct nva3_ram { 106struct nva3_ram {
71 struct nouveau_ram base; 107 struct nouveau_ram base;
72 struct nva3_ramfuc fuc; 108 struct nva3_ramfuc fuc;
109 struct nva3_ltrain ltrain;
73}; 110};
74 111
112void
113nva3_link_train_calc(u32 *vals, struct nva3_ltrain *train)
114{
115 int i, lo, hi;
116 u8 median[8], bins[4] = {0, 0, 0, 0}, bin = 0, qty = 0;
117
118 for (i = 0; i < 8; i++) {
119 for (lo = 0; lo < 0x40; lo++) {
120 if (!(vals[lo] & 0x80000000))
121 continue;
122 if (vals[lo] & (0x101 << i))
123 break;
124 }
125
126 if (lo == 0x40)
127 return;
128
129 for (hi = lo + 1; hi < 0x40; hi++) {
130 if (!(vals[lo] & 0x80000000))
131 continue;
132 if (!(vals[hi] & (0x101 << i))) {
133 hi--;
134 break;
135 }
136 }
137
138 median[i] = ((hi - lo) >> 1) + lo;
139 bins[(median[i] & 0xf0) >> 4]++;
140 median[i] += 0x30;
141 }
142
143 /* Find the best value for 0x1111e0 */
144 for (i = 0; i < 4; i++) {
145 if (bins[i] > qty) {
146 bin = i + 3;
147 qty = bins[i];
148 }
149 }
150
151 train->r_100720 = 0;
152 for (i = 0; i < 8; i++) {
153 median[i] = max(median[i], (u8) (bin << 4));
154 median[i] = min(median[i], (u8) ((bin << 4) | 0xf));
155
156 train->r_100720 |= ((median[i] & 0x0f) << (i << 2));
157 }
158
159 train->r_1111e0 = 0x02000000 | (bin * 0x101);
160 train->r_111400 = 0x0;
161}
162
163/*
164 * Link training for (at least) DDR3
165 */
166int
167nva3_link_train(struct nouveau_fb *pfb)
168{
169 struct nouveau_bios *bios = nouveau_bios(pfb);
170 struct nva3_ram *ram = (void *)pfb->ram;
171 struct nouveau_clock *clk = nouveau_clock(pfb);
172 struct nva3_ltrain *train = &ram->ltrain;
173 struct nouveau_device *device = nv_device(pfb);
174 struct nva3_ramfuc *fuc = &ram->fuc;
175 u32 *result, r1700;
176 int ret, i;
177 struct nvbios_M0205T M0205T = { 0 };
178 u8 ver, hdr, cnt, len, snr, ssz;
179 unsigned int clk_current;
180 unsigned long flags;
181 unsigned long *f = &flags;
182
183 if (nouveau_boolopt(device->cfgopt, "NvMemExec", true) != true)
184 return -ENOSYS;
185
186 /* XXX: Multiple partitions? */
187 result = kmalloc(64 * sizeof(u32), GFP_KERNEL);
188 if (!result)
189 return -ENOMEM;
190
191 train->state = NVA3_TRAIN_EXEC;
192
193 /* Clock speeds for training and back */
194 nvbios_M0205Tp(bios, &ver, &hdr, &cnt, &len, &snr, &ssz, &M0205T);
195 if (M0205T.freq == 0)
196 return -ENOENT;
197
198 clk_current = clk->read(clk, nv_clk_src_mem);
199
200 ret = nva3_clock_pre(clk, f);
201 if (ret)
202 goto out;
203
204 /* First: clock up/down */
205 ret = ram->base.calc(pfb, (u32) M0205T.freq * 1000);
206 if (ret)
207 goto out;
208
209 /* Do this *after* calc, eliminates write in script */
210 nv_wr32(pfb, 0x111400, 0x00000000);
211 /* XXX: Magic writes that improve train reliability? */
212 nv_mask(pfb, 0x100674, 0x0000ffff, 0x00000000);
213 nv_mask(pfb, 0x1005e4, 0x0000ffff, 0x00000000);
214 nv_mask(pfb, 0x100b0c, 0x000000ff, 0x00000000);
215 nv_wr32(pfb, 0x100c04, 0x00000400);
216
217 /* Now the training script */
218 r1700 = ram_rd32(fuc, 0x001700);
219
220 ram_mask(fuc, 0x100200, 0x00000800, 0x00000000);
221 ram_wr32(fuc, 0x611200, 0x3300);
222 ram_wait_vblank(fuc);
223 ram_wait(fuc, 0x611200, 0x00000003, 0x00000000, 500000);
224 ram_mask(fuc, 0x001610, 0x00000083, 0x00000003);
225 ram_mask(fuc, 0x100080, 0x00000020, 0x00000000);
226 ram_mask(fuc, 0x10f804, 0x80000000, 0x00000000);
227 ram_wr32(fuc, 0x001700, 0x00000000);
228
229 ram_train(fuc);
230
231 /* Reset */
232 ram_mask(fuc, 0x10f804, 0x80000000, 0x80000000);
233 ram_wr32(fuc, 0x10053c, 0x0);
234 ram_wr32(fuc, 0x100720, train->r_100720);
235 ram_wr32(fuc, 0x1111e0, train->r_1111e0);
236 ram_wr32(fuc, 0x111400, train->r_111400);
237 ram_nuke(fuc, 0x100080);
238 ram_mask(fuc, 0x100080, 0x00000020, 0x00000020);
239 ram_nsec(fuc, 1000);
240
241 ram_wr32(fuc, 0x001700, r1700);
242 ram_mask(fuc, 0x001610, 0x00000083, 0x00000080);
243 ram_wr32(fuc, 0x611200, 0x3330);
244 ram_mask(fuc, 0x100200, 0x00000800, 0x00000800);
245
246 ram_exec(fuc, true);
247
248 ram->base.calc(pfb, clk_current);
249 ram_exec(fuc, true);
250
251 /* Post-processing, avoids flicker */
252 nv_mask(pfb, 0x616308, 0x10, 0x10);
253 nv_mask(pfb, 0x616b08, 0x10, 0x10);
254
255 nva3_clock_post(clk, f);
256
257 ram_train_result(pfb, result, 64);
258 for (i = 0; i < 64; i++)
259 nv_debug(pfb, "Train: %08x", result[i]);
260 nva3_link_train_calc(result, train);
261
262 nv_debug(pfb, "Train: %08x %08x %08x", train->r_100720,
263 train->r_1111e0, train->r_111400);
264
265 kfree(result);
266
267 train->state = NVA3_TRAIN_DONE;
268
269 return ret;
270
271out:
272 if(ret == -EBUSY)
273 f = NULL;
274
275 train->state = NVA3_TRAIN_UNSUPPORTED;
276
277 nva3_clock_post(clk, f);
278 return ret;
279}
280
281int
282nva3_link_train_init(struct nouveau_fb *pfb)
283{
284 static const u32 pattern[16] = {
285 0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee,
286 0x00000000, 0x11111111, 0x44444444, 0xdddddddd,
287 0x33333333, 0x55555555, 0x77777777, 0x66666666,
288 0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb,
289 };
290 struct nouveau_bios *bios = nouveau_bios(pfb);
291 struct nva3_ram *ram = (void *)pfb->ram;
292 struct nva3_ltrain *train = &ram->ltrain;
293 struct nouveau_mem *mem;
294 struct nvbios_M0205E M0205E;
295 u8 ver, hdr, cnt, len;
296 u32 r001700;
297 int ret, i = 0;
298
299 train->state = NVA3_TRAIN_UNSUPPORTED;
300
301 /* We support type "5"
302 * XXX: training pattern table appears to be unused for this routine */
303 if (!nvbios_M0205Ep(bios, i, &ver, &hdr, &cnt, &len, &M0205E))
304 return -ENOENT;
305
306 if (M0205E.type != 5)
307 return 0;
308
309 train->state = NVA3_TRAIN_ONCE;
310
311 ret = pfb->ram->get(pfb, 0x8000, 0x10000, 0, 0x800, &ram->ltrain.mem);
312 if (ret)
313 return ret;
314
315 mem = ram->ltrain.mem;
316
317 nv_wr32(pfb, 0x100538, 0x10000000 | (mem->offset >> 16));
318 nv_wr32(pfb, 0x1005a8, 0x0000ffff);
319 nv_mask(pfb, 0x10f800, 0x00000001, 0x00000001);
320
321 for (i = 0; i < 0x30; i++) {
322 nv_wr32(pfb, 0x10f8c0, (i << 8) | i);
323 nv_wr32(pfb, 0x10f900, pattern[i % 16]);
324 }
325
326 for (i = 0; i < 0x30; i++) {
327 nv_wr32(pfb, 0x10f8e0, (i << 8) | i);
328 nv_wr32(pfb, 0x10f920, pattern[i % 16]);
329 }
330
331 /* And upload the pattern */
332 r001700 = nv_rd32(pfb, 0x1700);
333 nv_wr32(pfb, 0x1700, mem->offset >> 16);
334 for (i = 0; i < 16; i++)
335 nv_wr32(pfb, 0x700000 + (i << 2), pattern[i]);
336 for (i = 0; i < 16; i++)
337 nv_wr32(pfb, 0x700100 + (i << 2), pattern[i]);
338 nv_wr32(pfb, 0x1700, r001700);
339
340 train->r_100720 = nv_rd32(pfb, 0x100720);
341 train->r_1111e0 = nv_rd32(pfb, 0x1111e0);
342 train->r_111400 = nv_rd32(pfb, 0x111400);
343
344 return 0;
345}
346
347void
348nva3_link_train_fini(struct nouveau_fb *pfb)
349{
350 struct nva3_ram *ram = (void *)pfb->ram;
351
352 if (ram->ltrain.mem)
353 pfb->ram->put(pfb, &ram->ltrain.mem);
354}
355
356/*
357 * RAM reclocking
358 */
359#define T(t) cfg->timing_10_##t
360static int
361nva3_ram_timing_calc(struct nouveau_fb *pfb, u32 *timing)
362{
363 struct nva3_ram *ram = (void *)pfb->ram;
364 struct nvbios_ramcfg *cfg = &ram->base.target.bios;
365 int tUNK_base, tUNK_40_0, prevCL;
366 u32 cur2, cur3, cur7, cur8;
367
368 cur2 = nv_rd32(pfb, 0x100228);
369 cur3 = nv_rd32(pfb, 0x10022c);
370 cur7 = nv_rd32(pfb, 0x10023c);
371 cur8 = nv_rd32(pfb, 0x100240);
372
373
374 switch ((!T(CWL)) * ram->base.type) {
375 case NV_MEM_TYPE_DDR2:
376 T(CWL) = T(CL) - 1;
377 break;
378 case NV_MEM_TYPE_GDDR3:
379 T(CWL) = ((cur2 & 0xff000000) >> 24) + 1;
380 break;
381 }
382
383 prevCL = (cur3 & 0x000000ff) + 1;
384 tUNK_base = ((cur7 & 0x00ff0000) >> 16) - prevCL;
385
386 timing[0] = (T(RP) << 24 | T(RAS) << 16 | T(RFC) << 8 | T(RC));
387 timing[1] = (T(WR) + 1 + T(CWL)) << 24 |
388 max_t(u8,T(18), 1) << 16 |
389 (T(WTR) + 1 + T(CWL)) << 8 |
390 (5 + T(CL) - T(CWL));
391 timing[2] = (T(CWL) - 1) << 24 |
392 (T(RRD) << 16) |
393 (T(RCDWR) << 8) |
394 T(RCDRD);
395 timing[3] = (cur3 & 0x00ff0000) |
396 (0x30 + T(CL)) << 24 |
397 (0xb + T(CL)) << 8 |
398 (T(CL) - 1);
399 timing[4] = T(20) << 24 |
400 T(21) << 16 |
401 T(13) << 8 |
402 T(13);
403 timing[5] = T(RFC) << 24 |
404 max_t(u8,T(RCDRD), T(RCDWR)) << 16 |
405 max_t(u8, (T(CWL) + 6), (T(CL) + 2)) << 8 |
406 T(RP);
407 timing[6] = (0x5a + T(CL)) << 16 |
408 max_t(u8, 1, (6 - T(CL) + T(CWL))) << 8 |
409 (0x50 + T(CL) - T(CWL));
410 timing[7] = (cur7 & 0xff000000) |
411 ((tUNK_base + T(CL)) << 16) |
412 0x202;
413 timing[8] = cur8 & 0xffffff00;
414
415 switch (ram->base.type) {
416 case NV_MEM_TYPE_DDR2:
417 case NV_MEM_TYPE_GDDR3:
418 tUNK_40_0 = prevCL - (cur8 & 0xff);
419 if (tUNK_40_0 > 0)
420 timing[8] |= T(CL);
421 break;
422 default:
423 break;
424 }
425
426 nv_debug(pfb, "Entry: 220: %08x %08x %08x %08x\n",
427 timing[0], timing[1], timing[2], timing[3]);
428 nv_debug(pfb, " 230: %08x %08x %08x %08x\n",
429 timing[4], timing[5], timing[6], timing[7]);
430 nv_debug(pfb, " 240: %08x\n", timing[8]);
431 return 0;
432}
433#undef T
434
435static void
436nouveau_sddr2_dll_reset(struct nva3_ramfuc *fuc)
437{
438 ram_mask(fuc, mr[0], 0x100, 0x100);
439 ram_nsec(fuc, 1000);
440 ram_mask(fuc, mr[0], 0x100, 0x000);
441 ram_nsec(fuc, 1000);
442}
443
444static void
445nouveau_sddr3_dll_disable(struct nva3_ramfuc *fuc, u32 *mr)
446{
447 u32 mr1_old = ram_rd32(fuc, mr[1]);
448
449 if (!(mr1_old & 0x1)) {
450 ram_wr32(fuc, 0x1002d4, 0x00000001);
451 ram_wr32(fuc, mr[1], mr[1]);
452 ram_nsec(fuc, 1000);
453 }
454}
455
456static void
457nouveau_gddr3_dll_disable(struct nva3_ramfuc *fuc, u32 *mr)
458{
459 u32 mr1_old = ram_rd32(fuc, mr[1]);
460
461 if (!(mr1_old & 0x40)) {
462 ram_wr32(fuc, mr[1], mr[1]);
463 ram_nsec(fuc, 1000);
464 }
465}
466
467static void
468nva3_ram_lock_pll(struct nva3_ramfuc *fuc, struct nva3_clock_info *mclk)
469{
470 ram_wr32(fuc, 0x004004, mclk->pll);
471 ram_mask(fuc, 0x004000, 0x00000001, 0x00000001);
472 ram_mask(fuc, 0x004000, 0x00000010, 0x00000000);
473 ram_wait(fuc, 0x004000, 0x00020000, 0x00020000, 64000);
474 ram_mask(fuc, 0x004000, 0x00000010, 0x00000010);
475}
476
477static void
478nva3_ram_fbvref(struct nva3_ramfuc *fuc, u32 val)
479{
480 struct nouveau_gpio *gpio = nouveau_gpio(fuc->base.pfb);
481 struct dcb_gpio_func func;
482 u32 reg, sh, gpio_val;
483 int ret;
484
485 if (gpio->get(gpio, 0, 0x2e, DCB_GPIO_UNUSED) != val) {
486 ret = gpio->find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
487 if (ret)
488 return;
489
490 nv50_gpio_location(func.line, &reg, &sh);
491 gpio_val = ram_rd32(fuc, gpioFBVREF);
492 if (gpio_val & (8 << sh))
493 val = !val;
494
495 ram_mask(fuc, gpioFBVREF, (0x3 << sh), ((val | 0x2) << sh));
496 ram_nsec(fuc, 20000);
497 }
498}
499
75static int 500static int
76nva3_ram_calc(struct nouveau_fb *pfb, u32 freq) 501nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
77{ 502{
78 struct nouveau_bios *bios = nouveau_bios(pfb); 503 struct nouveau_bios *bios = nouveau_bios(pfb);
79 struct nva3_ram *ram = (void *)pfb->ram; 504 struct nva3_ram *ram = (void *)pfb->ram;
80 struct nva3_ramfuc *fuc = &ram->fuc; 505 struct nva3_ramfuc *fuc = &ram->fuc;
506 struct nva3_ltrain *train = &ram->ltrain;
81 struct nva3_clock_info mclk; 507 struct nva3_clock_info mclk;
82 struct nouveau_ram_data *next; 508 struct nouveau_ram_data *next;
83 u8 ver, hdr, cnt, len, strap; 509 u8 ver, hdr, cnt, len, strap;
84 u32 data; 510 u32 data;
85 u32 r004018, r100760, ctrl; 511 u32 r004018, r100760, r100da0, r111100, ctrl;
86 u32 unk714, unk718, unk71c; 512 u32 unk714, unk718, unk71c;
87 int ret, i; 513 int ret, i;
514 u32 timing[9];
515 bool pll2pll;
88 516
89 next = &ram->base.target; 517 next = &ram->base.target;
90 next->freq = freq; 518 next->freq = freq;
91 ram->base.next = next; 519 ram->base.next = next;
92 520
521 if (ram->ltrain.state == NVA3_TRAIN_ONCE)
522 nva3_link_train(pfb);
523
93 /* lookup memory config data relevant to the target frequency */ 524 /* lookup memory config data relevant to the target frequency */
94 i = 0; 525 i = 0;
95 while ((data = nvbios_rammapEp(bios, i++, &ver, &hdr, &cnt, &len, 526 data = nvbios_rammapEm(bios, freq / 1000, &ver, &hdr, &cnt, &len,
96 &next->bios))) { 527 &next->bios);
97 if (freq / 1000 >= next->bios.rammap_min && 528 if (!data || ver != 0x10 || hdr < 0x05) {
98 freq / 1000 <= next->bios.rammap_max)
99 break;
100 }
101
102 if (!data || ver != 0x10 || hdr < 0x0e) {
103 nv_error(pfb, "invalid/missing rammap entry\n"); 529 nv_error(pfb, "invalid/missing rammap entry\n");
104 return -EINVAL; 530 return -EINVAL;
105 } 531 }
@@ -113,7 +539,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
113 539
114 data = nvbios_rammapSp(bios, data, ver, hdr, cnt, len, strap, 540 data = nvbios_rammapSp(bios, data, ver, hdr, cnt, len, strap,
115 &ver, &hdr, &next->bios); 541 &ver, &hdr, &next->bios);
116 if (!data || ver != 0x10 || hdr < 0x0e) { 542 if (!data || ver != 0x10 || hdr < 0x09) {
117 nv_error(pfb, "invalid/missing ramcfg entry\n"); 543 nv_error(pfb, "invalid/missing ramcfg entry\n");
118 return -EINVAL; 544 return -EINVAL;
119 } 545 }
@@ -123,7 +549,7 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
123 data = nvbios_timingEp(bios, next->bios.ramcfg_timing, 549 data = nvbios_timingEp(bios, next->bios.ramcfg_timing,
124 &ver, &hdr, &cnt, &len, 550 &ver, &hdr, &cnt, &len,
125 &next->bios); 551 &next->bios);
126 if (!data || ver != 0x10 || hdr < 0x19) { 552 if (!data || ver != 0x10 || hdr < 0x17) {
127 nv_error(pfb, "invalid/missing timing entry\n"); 553 nv_error(pfb, "invalid/missing timing entry\n");
128 return -EINVAL; 554 return -EINVAL;
129 } 555 }
@@ -135,53 +561,99 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
135 return ret; 561 return ret;
136 } 562 }
137 563
564 nva3_ram_timing_calc(pfb, timing);
565
138 ret = ram_init(fuc, pfb); 566 ret = ram_init(fuc, pfb);
139 if (ret) 567 if (ret)
140 return ret; 568 return ret;
141 569
570 /* Determine ram-specific MR values */
571 ram->base.mr[0] = ram_rd32(fuc, mr[0]);
572 ram->base.mr[1] = ram_rd32(fuc, mr[1]);
573 ram->base.mr[2] = ram_rd32(fuc, mr[2]);
574
575 switch (ram->base.type) {
576 case NV_MEM_TYPE_DDR2:
577 ret = nouveau_sddr2_calc(&ram->base);
578 break;
579 case NV_MEM_TYPE_DDR3:
580 ret = nouveau_sddr3_calc(&ram->base);
581 break;
582 case NV_MEM_TYPE_GDDR3:
583 ret = nouveau_gddr3_calc(&ram->base);
584 break;
585 default:
586 ret = -ENOSYS;
587 break;
588 }
589
590 if (ret)
591 return ret;
592
142 /* XXX: where the fuck does 750MHz come from? */ 593 /* XXX: where the fuck does 750MHz come from? */
143 if (freq <= 750000) { 594 if (freq <= 750000) {
144 r004018 = 0x10000000; 595 r004018 = 0x10000000;
145 r100760 = 0x22222222; 596 r100760 = 0x22222222;
597 r100da0 = 0x00000010;
146 } else { 598 } else {
147 r004018 = 0x00000000; 599 r004018 = 0x00000000;
148 r100760 = 0x00000000; 600 r100760 = 0x00000000;
601 r100da0 = 0x00000000;
149 } 602 }
150 603
604 if (!next->bios.ramcfg_10_DLLoff)
605 r004018 |= 0x00004000;
606
607 /* pll2pll requires to switch to a safe clock first */
151 ctrl = ram_rd32(fuc, 0x004000); 608 ctrl = ram_rd32(fuc, 0x004000);
152 if (ctrl & 0x00000008) { 609 pll2pll = (!(ctrl & 0x00000008)) && mclk.pll;
153 if (mclk.pll) {
154 ram_mask(fuc, 0x004128, 0x00000101, 0x00000101);
155 ram_wr32(fuc, 0x004004, mclk.pll);
156 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001));
157 ram_wr32(fuc, 0x004000, (ctrl &= 0xffffffef));
158 ram_wait(fuc, 0x004000, 0x00020000, 0x00020000, 64000);
159 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000010));
160 ram_wr32(fuc, 0x004018, 0x00005000 | r004018);
161 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000004));
162 }
163 } else {
164 u32 ssel = 0x00000101;
165 if (mclk.clk)
166 ssel |= mclk.clk;
167 else
168 ssel |= 0x00080000; /* 324MHz, shouldn't matter... */
169 ram_mask(fuc, 0x004168, 0x003f3141, ctrl);
170 }
171 610
611 /* Pre, NVIDIA does this outside the script */
172 if (next->bios.ramcfg_10_02_10) { 612 if (next->bios.ramcfg_10_02_10) {
173 ram_mask(fuc, 0x111104, 0x00000600, 0x00000000); 613 ram_mask(fuc, 0x111104, 0x00000600, 0x00000000);
174 } else { 614 } else {
175 ram_mask(fuc, 0x111100, 0x40000000, 0x40000000); 615 ram_mask(fuc, 0x111100, 0x40000000, 0x40000000);
176 ram_mask(fuc, 0x111104, 0x00000180, 0x00000000); 616 ram_mask(fuc, 0x111104, 0x00000180, 0x00000000);
177 } 617 }
618 /* Always disable this bit during reclock */
619 ram_mask(fuc, 0x100200, 0x00000800, 0x00000000);
620
621 /* If switching from non-pll to pll, lock before disabling FB */
622 if (mclk.pll && !pll2pll) {
623 ram_mask(fuc, 0x004128, 0x003f3141, mclk.clk | 0x00000101);
624 nva3_ram_lock_pll(fuc, &mclk);
625 }
626
627 /* Start with disabling some CRTCs and PFIFO? */
628 ram_wait_vblank(fuc);
629 ram_wr32(fuc, 0x611200, 0x3300);
630 ram_mask(fuc, 0x002504, 0x1, 0x1);
631 ram_nsec(fuc, 10000);
632 ram_wait(fuc, 0x002504, 0x10, 0x10, 20000); /* XXX: or longer? */
633 ram_block(fuc);
634 ram_nsec(fuc, 2000);
635
636 if (!next->bios.ramcfg_10_02_10) {
637 if (ram->base.type == NV_MEM_TYPE_GDDR3)
638 ram_mask(fuc, 0x111100, 0x04020000, 0x00020000);
639 else
640 ram_mask(fuc, 0x111100, 0x04020000, 0x04020000);
641 }
642
643 /* If we're disabling the DLL, do it now */
644 switch (next->bios.ramcfg_10_DLLoff * ram->base.type) {
645 case NV_MEM_TYPE_DDR3:
646 nouveau_sddr3_dll_disable(fuc, ram->base.mr);
647 break;
648 case NV_MEM_TYPE_GDDR3:
649 nouveau_gddr3_dll_disable(fuc, ram->base.mr);
650 break;
651 }
178 652
179 if (!next->bios.rammap_10_04_02) 653 if (fuc->r_gpioFBVREF.addr && next->bios.timing_10_ODT)
180 ram_mask(fuc, 0x100200, 0x00000800, 0x00000000); 654 nva3_ram_fbvref(fuc, 0);
181 ram_wr32(fuc, 0x611200, 0x00003300);
182 if (!next->bios.ramcfg_10_02_10)
183 ram_wr32(fuc, 0x111100, 0x4c020000); /*XXX*/
184 655
656 /* Brace RAM for impact */
185 ram_wr32(fuc, 0x1002d4, 0x00000001); 657 ram_wr32(fuc, 0x1002d4, 0x00000001);
186 ram_wr32(fuc, 0x1002d0, 0x00000001); 658 ram_wr32(fuc, 0x1002d0, 0x00000001);
187 ram_wr32(fuc, 0x1002d0, 0x00000001); 659 ram_wr32(fuc, 0x1002d0, 0x00000001);
@@ -189,24 +661,38 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
189 ram_wr32(fuc, 0x1002dc, 0x00000001); 661 ram_wr32(fuc, 0x1002dc, 0x00000001);
190 ram_nsec(fuc, 2000); 662 ram_nsec(fuc, 2000);
191 663
192 ctrl = ram_rd32(fuc, 0x004000); 664 if (nv_device(pfb)->chipset == 0xa3 && freq <= 500000)
193 if (!(ctrl & 0x00000008) && mclk.pll) { 665 ram_mask(fuc, 0x100700, 0x00000006, 0x00000006);
194 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008)); 666
667 /* Fiddle with clocks */
668 /* There's 4 scenario's
669 * pll->pll: first switch to a 324MHz clock, set up new PLL, switch
670 * clk->pll: Set up new PLL, switch
671 * pll->clk: Set up clock, switch
672 * clk->clk: Overwrite ctrl and other bits, switch */
673
674 /* Switch to regular clock - 324MHz */
675 if (pll2pll) {
676 ram_mask(fuc, 0x004000, 0x00000004, 0x00000004);
677 ram_mask(fuc, 0x004168, 0x003f3141, 0x00083101);
678 ram_mask(fuc, 0x004000, 0x00000008, 0x00000008);
195 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000); 679 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000);
196 ram_wr32(fuc, 0x004018, 0x00001000); 680 ram_wr32(fuc, 0x004018, 0x00001000);
197 ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000001)); 681 nva3_ram_lock_pll(fuc, &mclk);
198 ram_wr32(fuc, 0x004004, mclk.pll); 682 }
199 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000001)); 683
200 udelay(64); 684 if (mclk.pll) {
201 ram_wr32(fuc, 0x004018, 0x00005000 | r004018); 685 ram_mask(fuc, 0x004000, 0x00000105, 0x00000105);
202 udelay(20); 686 ram_wr32(fuc, 0x004018, 0x00001000 | r004018);
203 } else 687 ram_wr32(fuc, 0x100da0, r100da0);
204 if (!mclk.pll) { 688 } else {
205 ram_mask(fuc, 0x004168, 0x003f3040, mclk.clk); 689 ram_mask(fuc, 0x004168, 0x003f3141, mclk.clk | 0x00000101);
206 ram_wr32(fuc, 0x004000, (ctrl |= 0x00000008)); 690 ram_mask(fuc, 0x004000, 0x00000108, 0x00000008);
207 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000); 691 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00088000);
208 ram_wr32(fuc, 0x004018, 0x0000d000 | r004018); 692 ram_wr32(fuc, 0x004018, 0x00009000 | r004018);
693 ram_wr32(fuc, 0x100da0, r100da0);
209 } 694 }
695 ram_nsec(fuc, 20000);
210 696
211 if (next->bios.rammap_10_04_08) { 697 if (next->bios.rammap_10_04_08) {
212 ram_wr32(fuc, 0x1005a0, next->bios.ramcfg_10_06 << 16 | 698 ram_wr32(fuc, 0x1005a0, next->bios.ramcfg_10_06 << 16 |
@@ -220,6 +706,12 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
220 0x80000000); 706 0x80000000);
221 ram_mask(fuc, 0x10053c, 0x00001000, 0x00000000); 707 ram_mask(fuc, 0x10053c, 0x00001000, 0x00000000);
222 } else { 708 } else {
709 if (train->state == NVA3_TRAIN_DONE) {
710 ram_wr32(fuc, 0x100080, 0x1020);
711 ram_mask(fuc, 0x111400, 0xffffffff, train->r_111400);
712 ram_mask(fuc, 0x1111e0, 0xffffffff, train->r_1111e0);
713 ram_mask(fuc, 0x100720, 0xffffffff, train->r_100720);
714 }
223 ram_mask(fuc, 0x10053c, 0x00001000, 0x00001000); 715 ram_mask(fuc, 0x10053c, 0x00001000, 0x00001000);
224 ram_mask(fuc, 0x10f804, 0x80000000, 0x00000000); 716 ram_mask(fuc, 0x10f804, 0x80000000, 0x00000000);
225 ram_mask(fuc, 0x100760, 0x22222222, r100760); 717 ram_mask(fuc, 0x100760, 0x22222222, r100760);
@@ -227,65 +719,131 @@ nva3_ram_calc(struct nouveau_fb *pfb, u32 freq)
227 ram_mask(fuc, 0x1007e0, 0x22222222, r100760); 719 ram_mask(fuc, 0x1007e0, 0x22222222, r100760);
228 } 720 }
229 721
722 if (nv_device(pfb)->chipset == 0xa3 && freq > 500000) {
723 ram_mask(fuc, 0x100700, 0x00000006, 0x00000000);
724 }
725
726 /* Final switch */
230 if (mclk.pll) { 727 if (mclk.pll) {
231 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00011000); 728 ram_mask(fuc, 0x1110e0, 0x00088000, 0x00011000);
232 ram_wr32(fuc, 0x004000, (ctrl &= ~0x00000008)); 729 ram_mask(fuc, 0x004000, 0x00000008, 0x00000000);
233 } 730 }
234 731
235 /*XXX: LEAVE */
236 ram_wr32(fuc, 0x1002dc, 0x00000000); 732 ram_wr32(fuc, 0x1002dc, 0x00000000);
237 ram_wr32(fuc, 0x1002d4, 0x00000001); 733 ram_wr32(fuc, 0x1002d4, 0x00000001);
238 ram_wr32(fuc, 0x100210, 0x80000000); 734 ram_wr32(fuc, 0x100210, 0x80000000);
239 ram_nsec(fuc, 1000); 735 ram_nsec(fuc, 2000);
240 ram_nsec(fuc, 1000);
241 736
242 ram_mask(fuc, mr[2], 0x00000000, 0x00000000); 737 /* Set RAM MR parameters and timings */
243 ram_nsec(fuc, 1000); 738 for (i = 2; i >= 0; i--) {
244 ram_nuke(fuc, mr[0]); 739 if (ram_rd32(fuc, mr[i]) != ram->base.mr[i]) {
245 ram_mask(fuc, mr[0], 0x00000000, 0x00000000); 740 ram_wr32(fuc, mr[i], ram->base.mr[i]);
246 ram_nsec(fuc, 1000); 741 ram_nsec(fuc, 1000);
742 }
743 }
247 744
248 ram_mask(fuc, 0x100220[3], 0x00000000, 0x00000000); 745 ram_wr32(fuc, 0x100220[3], timing[3]);
249 ram_mask(fuc, 0x100220[1], 0x00000000, 0x00000000); 746 ram_wr32(fuc, 0x100220[1], timing[1]);
250 ram_mask(fuc, 0x100220[6], 0x00000000, 0x00000000); 747 ram_wr32(fuc, 0x100220[6], timing[6]);
251 ram_mask(fuc, 0x100220[7], 0x00000000, 0x00000000); 748 ram_wr32(fuc, 0x100220[7], timing[7]);
252 ram_mask(fuc, 0x100220[2], 0x00000000, 0x00000000); 749 ram_wr32(fuc, 0x100220[2], timing[2]);
253 ram_mask(fuc, 0x100220[4], 0x00000000, 0x00000000); 750 ram_wr32(fuc, 0x100220[4], timing[4]);
254 ram_mask(fuc, 0x100220[5], 0x00000000, 0x00000000); 751 ram_wr32(fuc, 0x100220[5], timing[5]);
255 ram_mask(fuc, 0x100220[0], 0x00000000, 0x00000000); 752 ram_wr32(fuc, 0x100220[0], timing[0]);
256 ram_mask(fuc, 0x100220[8], 0x00000000, 0x00000000); 753 ram_wr32(fuc, 0x100220[8], timing[8]);
257 754
755 /* Misc */
258 ram_mask(fuc, 0x100200, 0x00001000, !next->bios.ramcfg_10_02_08 << 12); 756 ram_mask(fuc, 0x100200, 0x00001000, !next->bios.ramcfg_10_02_08 << 12);
259 757
260 unk714 = ram_rd32(fuc, 0x100714) & ~0xf0000010; 758 /* XXX: A lot of "chipset"/"ram type" specific stuff...? */
261 unk718 = ram_rd32(fuc, 0x100718) & ~0x00000100; 759 unk714 = ram_rd32(fuc, 0x100714) & ~0xf0000130;
262 unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100; 760 unk718 = ram_rd32(fuc, 0x100718) & ~0x00000100;
761 unk71c = ram_rd32(fuc, 0x10071c) & ~0x00000100;
762 r111100 = ram_rd32(fuc, 0x111100) & ~0x3a800000;
763
764 if (next->bios.ramcfg_10_02_04) {
765 switch (ram->base.type) {
766 case NV_MEM_TYPE_DDR3:
767 if (nv_device(pfb)->chipset != 0xa8)
768 r111100 |= 0x00000004;
769 /* no break */
770 case NV_MEM_TYPE_DDR2:
771 r111100 |= 0x08000000;
772 break;
773 default:
774 break;
775 }
776 } else {
777 switch (ram->base.type) {
778 case NV_MEM_TYPE_DDR2:
779 r111100 |= 0x1a800000;
780 unk714 |= 0x00000010;
781 break;
782 case NV_MEM_TYPE_DDR3:
783 if (nv_device(pfb)->chipset == 0xa8) {
784 r111100 |= 0x08000000;
785 } else {
786 r111100 &= ~0x00000004;
787 r111100 |= 0x12800000;
788 }
789 unk714 |= 0x00000010;
790 break;
791 case NV_MEM_TYPE_GDDR3:
792 r111100 |= 0x30000000;
793 unk714 |= 0x00000020;
794 break;
795 default:
796 break;
797 }
798 }
799
800 unk714 |= (next->bios.ramcfg_10_04_01) << 8;
801
263 if (next->bios.ramcfg_10_02_20) 802 if (next->bios.ramcfg_10_02_20)
264 unk714 |= 0xf0000000; 803 unk714 |= 0xf0000000;
265 if (!next->bios.ramcfg_10_02_04) 804 if (next->bios.ramcfg_10_02_02)
266 unk714 |= 0x00000010; 805 unk718 |= 0x00000100;
267 ram_wr32(fuc, 0x100714, unk714);
268
269 if (next->bios.ramcfg_10_02_01) 806 if (next->bios.ramcfg_10_02_01)
270 unk71c |= 0x00000100; 807 unk71c |= 0x00000100;
271 ram_wr32(fuc, 0x10071c, unk71c); 808 if (next->bios.timing_10_24 != 0xff) {
809 unk718 &= ~0xf0000000;
810 unk718 |= next->bios.timing_10_24 << 28;
811 }
812 if (next->bios.ramcfg_10_02_10)
813 r111100 &= ~0x04020000;
272 814
273 if (next->bios.ramcfg_10_02_02) 815 ram_mask(fuc, 0x100714, 0xffffffff, unk714);
274 unk718 |= 0x00000100; 816 ram_mask(fuc, 0x10071c, 0xffffffff, unk71c);
275 ram_wr32(fuc, 0x100718, unk718); 817 ram_mask(fuc, 0x100718, 0xffffffff, unk718);
818 ram_mask(fuc, 0x111100, 0xffffffff, r111100);
276 819
277 if (next->bios.ramcfg_10_02_10) 820 if (fuc->r_gpioFBVREF.addr && !next->bios.timing_10_ODT)
278 ram_wr32(fuc, 0x111100, 0x48000000); /*XXX*/ 821 nva3_ram_fbvref(fuc, 1);
279 822
280 ram_mask(fuc, mr[0], 0x100, 0x100); 823 /* Reset DLL */
281 ram_nsec(fuc, 1000); 824 if (!next->bios.ramcfg_10_DLLoff)
282 ram_mask(fuc, mr[0], 0x100, 0x000); 825 nouveau_sddr2_dll_reset(fuc);
283 ram_nsec(fuc, 1000);
284 826
285 ram_nsec(fuc, 2000); 827 if (ram->base.type == NV_MEM_TYPE_GDDR3) {
286 ram_nsec(fuc, 12000); 828 ram_nsec(fuc, 31000);
829 } else {
830 ram_nsec(fuc, 14000);
831 }
832
833 if (ram->base.type == NV_MEM_TYPE_DDR3) {
834 ram_wr32(fuc, 0x100264, 0x1);
835 ram_nsec(fuc, 2000);
836 }
287 837
288 ram_wr32(fuc, 0x611200, 0x00003330); 838 ram_nuke(fuc, 0x100700);
839 ram_mask(fuc, 0x100700, 0x01000000, 0x01000000);
840 ram_mask(fuc, 0x100700, 0x01000000, 0x00000000);
841
842 /* Re-enable FB */
843 ram_unblock(fuc);
844 ram_wr32(fuc, 0x611200, 0x3330);
845
846 /* Post fiddlings */
289 if (next->bios.rammap_10_04_02) 847 if (next->bios.rammap_10_04_02)
290 ram_mask(fuc, 0x100200, 0x00000800, 0x00000800); 848 ram_mask(fuc, 0x100200, 0x00000800, 0x00000800);
291 if (next->bios.ramcfg_10_02_10) { 849 if (next->bios.ramcfg_10_02_10) {
@@ -313,7 +871,22 @@ nva3_ram_prog(struct nouveau_fb *pfb)
313 struct nouveau_device *device = nv_device(pfb); 871 struct nouveau_device *device = nv_device(pfb);
314 struct nva3_ram *ram = (void *)pfb->ram; 872 struct nva3_ram *ram = (void *)pfb->ram;
315 struct nva3_ramfuc *fuc = &ram->fuc; 873 struct nva3_ramfuc *fuc = &ram->fuc;
316 ram_exec(fuc, nouveau_boolopt(device->cfgopt, "NvMemExec", true)); 874 bool exec = nouveau_boolopt(device->cfgopt, "NvMemExec", true);
875
876 if (exec) {
877 nv_mask(pfb, 0x001534, 0x2, 0x2);
878
879 ram_exec(fuc, true);
880
881 /* Post-processing, avoids flicker */
882 nv_mask(pfb, 0x002504, 0x1, 0x0);
883 nv_mask(pfb, 0x001534, 0x2, 0x0);
884
885 nv_mask(pfb, 0x616308, 0x10, 0x10);
886 nv_mask(pfb, 0x616b08, 0x10, 0x10);
887 } else {
888 ram_exec(fuc, false);
889 }
317 return 0; 890 return 0;
318} 891}
319 892
@@ -330,38 +903,24 @@ nva3_ram_init(struct nouveau_object *object)
330{ 903{
331 struct nouveau_fb *pfb = (void *)object->parent; 904 struct nouveau_fb *pfb = (void *)object->parent;
332 struct nva3_ram *ram = (void *)object; 905 struct nva3_ram *ram = (void *)object;
333 int ret, i; 906 int ret;
334 907
335 ret = nouveau_ram_init(&ram->base); 908 ret = nouveau_ram_init(&ram->base);
336 if (ret) 909 if (ret)
337 return ret; 910 return ret;
338 911
339 /* prepare for ddr link training, and load training patterns */ 912 nva3_link_train_init(pfb);
340 switch (ram->base.type) { 913
341 case NV_MEM_TYPE_DDR3: { 914 return 0;
342 if (nv_device(pfb)->chipset == 0xa8) { 915}
343 static const u32 pattern[16] = { 916
344 0xaaaaaaaa, 0xcccccccc, 0xdddddddd, 0xeeeeeeee, 917static int
345 0x00000000, 0x11111111, 0x44444444, 0xdddddddd, 918nva3_ram_fini(struct nouveau_object *object, bool suspend)
346 0x33333333, 0x55555555, 0x77777777, 0x66666666, 919{
347 0x99999999, 0x88888888, 0xeeeeeeee, 0xbbbbbbbb, 920 struct nouveau_fb *pfb = (void *)object->parent;
348 }; 921
349 922 if (!suspend)
350 nv_wr32(pfb, 0x100538, 0x10001ff6); /*XXX*/ 923 nva3_link_train_fini(pfb);
351 nv_wr32(pfb, 0x1005a8, 0x0000ffff);
352 nv_mask(pfb, 0x10f800, 0x00000001, 0x00000001);
353 for (i = 0; i < 0x30; i++) {
354 nv_wr32(pfb, 0x10f8c0, (i << 8) | i);
355 nv_wr32(pfb, 0x10f8e0, (i << 8) | i);
356 nv_wr32(pfb, 0x10f900, pattern[i % 16]);
357 nv_wr32(pfb, 0x10f920, pattern[i % 16]);
358 }
359 }
360 }
361 break;
362 default:
363 break;
364 }
365 924
366 return 0; 925 return 0;
367} 926}
@@ -371,8 +930,12 @@ nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
371 struct nouveau_oclass *oclass, void *data, u32 datasize, 930 struct nouveau_oclass *oclass, void *data, u32 datasize,
372 struct nouveau_object **pobject) 931 struct nouveau_object **pobject)
373{ 932{
933 struct nouveau_fb *pfb = nouveau_fb(parent);
934 struct nouveau_gpio *gpio = nouveau_gpio(pfb);
935 struct dcb_gpio_func func;
374 struct nva3_ram *ram; 936 struct nva3_ram *ram;
375 int ret, i; 937 int ret, i;
938 u32 reg, shift;
376 939
377 ret = nv50_ram_create(parent, engine, oclass, &ram); 940 ret = nv50_ram_create(parent, engine, oclass, &ram);
378 *pobject = nv_object(ram); 941 *pobject = nv_object(ram);
@@ -380,7 +943,9 @@ nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
380 return ret; 943 return ret;
381 944
382 switch (ram->base.type) { 945 switch (ram->base.type) {
946 case NV_MEM_TYPE_DDR2:
383 case NV_MEM_TYPE_DDR3: 947 case NV_MEM_TYPE_DDR3:
948 case NV_MEM_TYPE_GDDR3:
384 ram->base.calc = nva3_ram_calc; 949 ram->base.calc = nva3_ram_calc;
385 ram->base.prog = nva3_ram_prog; 950 ram->base.prog = nva3_ram_prog;
386 ram->base.tidy = nva3_ram_tidy; 951 ram->base.tidy = nva3_ram_tidy;
@@ -390,31 +955,41 @@ nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
390 return 0; 955 return 0;
391 } 956 }
392 957
958 ram->fuc.r_0x001610 = ramfuc_reg(0x001610);
959 ram->fuc.r_0x001700 = ramfuc_reg(0x001700);
960 ram->fuc.r_0x002504 = ramfuc_reg(0x002504);
393 ram->fuc.r_0x004000 = ramfuc_reg(0x004000); 961 ram->fuc.r_0x004000 = ramfuc_reg(0x004000);
394 ram->fuc.r_0x004004 = ramfuc_reg(0x004004); 962 ram->fuc.r_0x004004 = ramfuc_reg(0x004004);
395 ram->fuc.r_0x004018 = ramfuc_reg(0x004018); 963 ram->fuc.r_0x004018 = ramfuc_reg(0x004018);
396 ram->fuc.r_0x004128 = ramfuc_reg(0x004128); 964 ram->fuc.r_0x004128 = ramfuc_reg(0x004128);
397 ram->fuc.r_0x004168 = ramfuc_reg(0x004168); 965 ram->fuc.r_0x004168 = ramfuc_reg(0x004168);
966 ram->fuc.r_0x100080 = ramfuc_reg(0x100080);
398 ram->fuc.r_0x100200 = ramfuc_reg(0x100200); 967 ram->fuc.r_0x100200 = ramfuc_reg(0x100200);
399 ram->fuc.r_0x100210 = ramfuc_reg(0x100210); 968 ram->fuc.r_0x100210 = ramfuc_reg(0x100210);
400 for (i = 0; i < 9; i++) 969 for (i = 0; i < 9; i++)
401 ram->fuc.r_0x100220[i] = ramfuc_reg(0x100220 + (i * 4)); 970 ram->fuc.r_0x100220[i] = ramfuc_reg(0x100220 + (i * 4));
971 ram->fuc.r_0x100264 = ramfuc_reg(0x100264);
402 ram->fuc.r_0x1002d0 = ramfuc_reg(0x1002d0); 972 ram->fuc.r_0x1002d0 = ramfuc_reg(0x1002d0);
403 ram->fuc.r_0x1002d4 = ramfuc_reg(0x1002d4); 973 ram->fuc.r_0x1002d4 = ramfuc_reg(0x1002d4);
404 ram->fuc.r_0x1002dc = ramfuc_reg(0x1002dc); 974 ram->fuc.r_0x1002dc = ramfuc_reg(0x1002dc);
405 ram->fuc.r_0x10053c = ramfuc_reg(0x10053c); 975 ram->fuc.r_0x10053c = ramfuc_reg(0x10053c);
406 ram->fuc.r_0x1005a0 = ramfuc_reg(0x1005a0); 976 ram->fuc.r_0x1005a0 = ramfuc_reg(0x1005a0);
407 ram->fuc.r_0x1005a4 = ramfuc_reg(0x1005a4); 977 ram->fuc.r_0x1005a4 = ramfuc_reg(0x1005a4);
978 ram->fuc.r_0x100700 = ramfuc_reg(0x100700);
408 ram->fuc.r_0x100714 = ramfuc_reg(0x100714); 979 ram->fuc.r_0x100714 = ramfuc_reg(0x100714);
409 ram->fuc.r_0x100718 = ramfuc_reg(0x100718); 980 ram->fuc.r_0x100718 = ramfuc_reg(0x100718);
410 ram->fuc.r_0x10071c = ramfuc_reg(0x10071c); 981 ram->fuc.r_0x10071c = ramfuc_reg(0x10071c);
982 ram->fuc.r_0x100720 = ramfuc_reg(0x100720);
411 ram->fuc.r_0x100760 = ramfuc_stride(0x100760, 4, ram->base.part_mask); 983 ram->fuc.r_0x100760 = ramfuc_stride(0x100760, 4, ram->base.part_mask);
412 ram->fuc.r_0x1007a0 = ramfuc_stride(0x1007a0, 4, ram->base.part_mask); 984 ram->fuc.r_0x1007a0 = ramfuc_stride(0x1007a0, 4, ram->base.part_mask);
413 ram->fuc.r_0x1007e0 = ramfuc_stride(0x1007e0, 4, ram->base.part_mask); 985 ram->fuc.r_0x1007e0 = ramfuc_stride(0x1007e0, 4, ram->base.part_mask);
986 ram->fuc.r_0x100da0 = ramfuc_stride(0x100da0, 4, ram->base.part_mask);
414 ram->fuc.r_0x10f804 = ramfuc_reg(0x10f804); 987 ram->fuc.r_0x10f804 = ramfuc_reg(0x10f804);
415 ram->fuc.r_0x1110e0 = ramfuc_stride(0x1110e0, 4, ram->base.part_mask); 988 ram->fuc.r_0x1110e0 = ramfuc_stride(0x1110e0, 4, ram->base.part_mask);
416 ram->fuc.r_0x111100 = ramfuc_reg(0x111100); 989 ram->fuc.r_0x111100 = ramfuc_reg(0x111100);
417 ram->fuc.r_0x111104 = ramfuc_reg(0x111104); 990 ram->fuc.r_0x111104 = ramfuc_reg(0x111104);
991 ram->fuc.r_0x1111e0 = ramfuc_reg(0x1111e0);
992 ram->fuc.r_0x111400 = ramfuc_reg(0x111400);
418 ram->fuc.r_0x611200 = ramfuc_reg(0x611200); 993 ram->fuc.r_0x611200 = ramfuc_reg(0x611200);
419 994
420 if (ram->base.ranks > 1) { 995 if (ram->base.ranks > 1) {
@@ -429,6 +1004,12 @@ nva3_ram_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
429 ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4); 1004 ram->fuc.r_mr[3] = ramfuc_reg(0x1002e4);
430 } 1005 }
431 1006
1007 ret = gpio->find(gpio, 0, 0x2e, DCB_GPIO_UNUSED, &func);
1008 if (ret == 0) {
1009 nv50_gpio_location(func.line, &reg, &shift);
1010 ram->fuc.r_gpioFBVREF = ramfuc_reg(reg);
1011 }
1012
432 return 0; 1013 return 0;
433} 1014}
434 1015
@@ -438,6 +1019,6 @@ nva3_ram_oclass = {
438 .ctor = nva3_ram_ctor, 1019 .ctor = nva3_ram_ctor,
439 .dtor = _nouveau_ram_dtor, 1020 .dtor = _nouveau_ram_dtor,
440 .init = nva3_ram_init, 1021 .init = nva3_ram_init,
441 .fini = _nouveau_ram_fini, 1022 .fini = nva3_ram_fini,
442 }, 1023 },
443}; 1024};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c
index bb1eb8f3e639..252575f3aa29 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr2.c
@@ -66,7 +66,7 @@ nouveau_sddr2_calc(struct nouveau_ram *ram)
66 case 0x10: 66 case 0x10:
67 CL = ram->next->bios.timing_10_CL; 67 CL = ram->next->bios.timing_10_CL;
68 WR = ram->next->bios.timing_10_WR; 68 WR = ram->next->bios.timing_10_WR;
69 DLL = !ram->next->bios.ramcfg_10_02_40; 69 DLL = !ram->next->bios.ramcfg_10_DLLoff;
70 ODT = ram->next->bios.timing_10_ODT & 3; 70 ODT = ram->next->bios.timing_10_ODT & 3;
71 break; 71 break;
72 case 0x20: 72 case 0x20:
diff --git a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
index 83949b11833a..a2dca4869e52 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/fb/sddr3.c
@@ -80,7 +80,7 @@ nouveau_sddr3_calc(struct nouveau_ram *ram)
80 CWL = ram->next->bios.timing_10_CWL; 80 CWL = ram->next->bios.timing_10_CWL;
81 CL = ram->next->bios.timing_10_CL; 81 CL = ram->next->bios.timing_10_CL;
82 WR = ram->next->bios.timing_10_WR; 82 WR = ram->next->bios.timing_10_WR;
83 DLL = !ram->next->bios.ramcfg_10_02_40; 83 DLL = !ram->next->bios.ramcfg_10_DLLoff;
84 ODT = ram->next->bios.timing_10_ODT; 84 ODT = ram->next->bios.timing_10_ODT;
85 break; 85 break;
86 case 0x20: 86 case 0x20:
diff --git a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
index 1864fa98e6b1..2e30d5a62d6e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/gpio/nv50.c
@@ -54,7 +54,7 @@ nv50_gpio_reset(struct nouveau_gpio *gpio, u8 match)
54 } 54 }
55} 55}
56 56
57static int 57int
58nv50_gpio_location(int line, u32 *reg, u32 *shift) 58nv50_gpio_location(int line, u32 *reg, u32 *shift)
59{ 59{
60 const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 }; 60 const u32 nv50_gpio_reg[4] = { 0xe104, 0xe108, 0xe280, 0xe284 };
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
index 2b1bf545e488..0dc605db7ec8 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/base.c
@@ -473,18 +473,56 @@ nouveau_i2c_extdev_sclass[] = {
473 nouveau_anx9805_sclass, 473 nouveau_anx9805_sclass,
474}; 474};
475 475
476static void
477nouveau_i2c_create_port(struct nouveau_i2c *i2c, int index, u8 type,
478 struct dcb_i2c_entry *info)
479{
480 const struct nouveau_i2c_impl *impl = (void *)nv_oclass(i2c);
481 struct nouveau_oclass *oclass;
482 struct nouveau_object *parent;
483 struct nouveau_object *object;
484 int ret, pad;
485
486 if (info->share != DCB_I2C_UNUSED) {
487 pad = info->share;
488 oclass = impl->pad_s;
489 } else {
490 if (type != DCB_I2C_NVIO_AUX)
491 pad = 0x100 + info->drive;
492 else
493 pad = 0x100 + info->auxch;
494 oclass = impl->pad_x;
495 }
496
497 ret = nouveau_object_ctor(NULL, nv_object(i2c), oclass, NULL, pad,
498 &parent);
499 if (ret < 0)
500 return;
501
502 oclass = impl->sclass;
503 do {
504 ret = -EINVAL;
505 if (oclass->handle == type) {
506 ret = nouveau_object_ctor(parent, nv_object(i2c),
507 oclass, info, index,
508 &object);
509 }
510 } while (ret && (++oclass)->handle);
511
512 nouveau_object_ref(NULL, &parent);
513}
514
476int 515int
477nouveau_i2c_create_(struct nouveau_object *parent, 516nouveau_i2c_create_(struct nouveau_object *parent,
478 struct nouveau_object *engine, 517 struct nouveau_object *engine,
479 struct nouveau_oclass *oclass, 518 struct nouveau_oclass *oclass,
480 int length, void **pobject) 519 int length, void **pobject)
481{ 520{
482 const struct nouveau_i2c_impl *impl = (void *)oclass;
483 struct nouveau_bios *bios = nouveau_bios(parent); 521 struct nouveau_bios *bios = nouveau_bios(parent);
484 struct nouveau_i2c *i2c; 522 struct nouveau_i2c *i2c;
485 struct nouveau_object *object; 523 struct nouveau_object *object;
486 struct dcb_i2c_entry info; 524 struct dcb_i2c_entry info;
487 int ret, i, j, index = -1, pad; 525 int ret, i, j, index = -1;
488 struct dcb_output outp; 526 struct dcb_output outp;
489 u8 ver, hdr; 527 u8 ver, hdr;
490 u32 data; 528 u32 data;
@@ -507,43 +545,40 @@ nouveau_i2c_create_(struct nouveau_object *parent,
507 INIT_LIST_HEAD(&i2c->ports); 545 INIT_LIST_HEAD(&i2c->ports);
508 546
509 while (!dcb_i2c_parse(bios, ++index, &info)) { 547 while (!dcb_i2c_parse(bios, ++index, &info)) {
510 if (info.type == DCB_I2C_UNUSED) 548 switch (info.type) {
549 case DCB_I2C_NV04_BIT:
550 case DCB_I2C_NV4E_BIT:
551 case DCB_I2C_NVIO_BIT:
552 nouveau_i2c_create_port(i2c, NV_I2C_PORT(index),
553 info.type, &info);
554 break;
555 case DCB_I2C_NVIO_AUX:
556 nouveau_i2c_create_port(i2c, NV_I2C_AUX(index),
557 info.type, &info);
558 break;
559 case DCB_I2C_PMGR:
560 if (info.drive != DCB_I2C_UNUSED) {
561 nouveau_i2c_create_port(i2c, NV_I2C_PORT(index),
562 DCB_I2C_NVIO_BIT,
563 &info);
564 }
565 if (info.auxch != DCB_I2C_UNUSED) {
566 nouveau_i2c_create_port(i2c, NV_I2C_AUX(index),
567 DCB_I2C_NVIO_AUX,
568 &info);
569 }
570 break;
571 case DCB_I2C_UNUSED:
572 default:
511 continue; 573 continue;
512
513 if (info.share != DCB_I2C_UNUSED) {
514 if (info.type == DCB_I2C_NVIO_AUX)
515 pad = info.drive;
516 else
517 pad = info.share;
518 oclass = impl->pad_s;
519 } else {
520 pad = 0x100 + info.drive;
521 oclass = impl->pad_x;
522 } 574 }
523
524 ret = nouveau_object_ctor(NULL, *pobject, oclass,
525 NULL, pad, &parent);
526 if (ret < 0)
527 continue;
528
529 oclass = impl->sclass;
530 do {
531 ret = -EINVAL;
532 if (oclass->handle == info.type) {
533 ret = nouveau_object_ctor(parent, *pobject,
534 oclass, &info,
535 index, &object);
536 }
537 } while (ret && (++oclass)->handle);
538
539 nouveau_object_ref(NULL, &parent);
540 } 575 }
541 576
542 /* in addition to the busses specified in the i2c table, there 577 /* in addition to the busses specified in the i2c table, there
543 * may be ddc/aux channels hiding behind external tmds/dp/etc 578 * may be ddc/aux channels hiding behind external tmds/dp/etc
544 * transmitters. 579 * transmitters.
545 */ 580 */
546 index = ((index + 0x0f) / 0x10) * 0x10; 581 index = NV_I2C_EXT(0);
547 i = -1; 582 i = -1;
548 while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &outp))) { 583 while ((data = dcb_outp_parse(bios, ++i, &ver, &hdr, &outp))) {
549 if (!outp.location || !outp.extdev) 584 if (!outp.location || !outp.extdev)
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c
new file mode 100644
index 000000000000..06a2b87ccbf1
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/gm204.c
@@ -0,0 +1,221 @@
1/*
2 * Copyright 2012 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include "nv50.h"
26
27#define AUX_DBG(fmt, args...) nv_debug(aux, "AUXCH(%d): " fmt, ch, ##args)
28#define AUX_ERR(fmt, args...) nv_error(aux, "AUXCH(%d): " fmt, ch, ##args)
29
30static void
31auxch_fini(struct nouveau_i2c *aux, int ch)
32{
33 nv_mask(aux, 0x00d954 + (ch * 0x50), 0x00310000, 0x00000000);
34}
35
36static int
37auxch_init(struct nouveau_i2c *aux, int ch)
38{
39 const u32 unksel = 1; /* nfi which to use, or if it matters.. */
40 const u32 ureq = unksel ? 0x00100000 : 0x00200000;
41 const u32 urep = unksel ? 0x01000000 : 0x02000000;
42 u32 ctrl, timeout;
43
44 /* wait up to 1ms for any previous transaction to be done... */
45 timeout = 1000;
46 do {
47 ctrl = nv_rd32(aux, 0x00d954 + (ch * 0x50));
48 udelay(1);
49 if (!timeout--) {
50 AUX_ERR("begin idle timeout 0x%08x\n", ctrl);
51 return -EBUSY;
52 }
53 } while (ctrl & 0x03010000);
54
55 /* set some magic, and wait up to 1ms for it to appear */
56 nv_mask(aux, 0x00d954 + (ch * 0x50), 0x00300000, ureq);
57 timeout = 1000;
58 do {
59 ctrl = nv_rd32(aux, 0x00d954 + (ch * 0x50));
60 udelay(1);
61 if (!timeout--) {
62 AUX_ERR("magic wait 0x%08x\n", ctrl);
63 auxch_fini(aux, ch);
64 return -EBUSY;
65 }
66 } while ((ctrl & 0x03000000) != urep);
67
68 return 0;
69}
70
71int
72gm204_aux(struct nouveau_i2c_port *base, bool retry,
73 u8 type, u32 addr, u8 *data, u8 size)
74{
75 struct nouveau_i2c *aux = nouveau_i2c(base);
76 struct nv50_i2c_port *port = (void *)base;
77 u32 ctrl, stat, timeout, retries;
78 u32 xbuf[4] = {};
79 int ch = port->addr;
80 int ret, i;
81
82 AUX_DBG("%d: 0x%08x %d\n", type, addr, size);
83
84 ret = auxch_init(aux, ch);
85 if (ret)
86 goto out;
87
88 stat = nv_rd32(aux, 0x00d958 + (ch * 0x50));
89 if (!(stat & 0x10000000)) {
90 AUX_DBG("sink not detected\n");
91 ret = -ENXIO;
92 goto out;
93 }
94
95 if (!(type & 1)) {
96 memcpy(xbuf, data, size);
97 for (i = 0; i < 16; i += 4) {
98 AUX_DBG("wr 0x%08x\n", xbuf[i / 4]);
99 nv_wr32(aux, 0x00d930 + (ch * 0x50) + i, xbuf[i / 4]);
100 }
101 }
102
103 ctrl = nv_rd32(aux, 0x00d954 + (ch * 0x50));
104 ctrl &= ~0x0001f0ff;
105 ctrl |= type << 12;
106 ctrl |= size - 1;
107 nv_wr32(aux, 0x00d950 + (ch * 0x50), addr);
108
109 /* (maybe) retry transaction a number of times on failure... */
110 for (retries = 0; !ret && retries < 32; retries++) {
111 /* reset, and delay a while if this is a retry */
112 nv_wr32(aux, 0x00d954 + (ch * 0x50), 0x80000000 | ctrl);
113 nv_wr32(aux, 0x00d954 + (ch * 0x50), 0x00000000 | ctrl);
114 if (retries)
115 udelay(400);
116
117 /* transaction request, wait up to 1ms for it to complete */
118 nv_wr32(aux, 0x00d954 + (ch * 0x50), 0x00010000 | ctrl);
119
120 timeout = 1000;
121 do {
122 ctrl = nv_rd32(aux, 0x00d954 + (ch * 0x50));
123 udelay(1);
124 if (!timeout--) {
125 AUX_ERR("tx req timeout 0x%08x\n", ctrl);
126 ret = -EIO;
127 goto out;
128 }
129 } while (ctrl & 0x00010000);
130 ret = 1;
131
132 /* read status, and check if transaction completed ok */
133 stat = nv_mask(aux, 0x00d958 + (ch * 0x50), 0, 0);
134 if ((stat & 0x000f0000) == 0x00080000 ||
135 (stat & 0x000f0000) == 0x00020000)
136 ret = retry ? 0 : 1;
137 if ((stat & 0x00000100))
138 ret = -ETIMEDOUT;
139 if ((stat & 0x00000e00))
140 ret = -EIO;
141
142 AUX_DBG("%02d 0x%08x 0x%08x\n", retries, ctrl, stat);
143 }
144
145 if (type & 1) {
146 for (i = 0; i < 16; i += 4) {
147 xbuf[i / 4] = nv_rd32(aux, 0x00d940 + (ch * 0x50) + i);
148 AUX_DBG("rd 0x%08x\n", xbuf[i / 4]);
149 }
150 memcpy(data, xbuf, size);
151 }
152
153out:
154 auxch_fini(aux, ch);
155 return ret < 0 ? ret : (stat & 0x000f0000) >> 16;
156}
157
158static const struct nouveau_i2c_func
159gm204_aux_func = {
160 .aux = gm204_aux,
161};
162
163int
164gm204_aux_port_ctor(struct nouveau_object *parent,
165 struct nouveau_object *engine,
166 struct nouveau_oclass *oclass, void *data, u32 index,
167 struct nouveau_object **pobject)
168{
169 struct dcb_i2c_entry *info = data;
170 struct nv50_i2c_port *port;
171 int ret;
172
173 ret = nouveau_i2c_port_create(parent, engine, oclass, index,
174 &nouveau_i2c_aux_algo, &gm204_aux_func,
175 &port);
176 *pobject = nv_object(port);
177 if (ret)
178 return ret;
179
180 port->base.aux = info->auxch;
181 port->addr = info->auxch;
182 return 0;
183}
184
185struct nouveau_oclass
186gm204_i2c_sclass[] = {
187 { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT),
188 .ofuncs = &(struct nouveau_ofuncs) {
189 .ctor = nvd0_i2c_port_ctor,
190 .dtor = _nouveau_i2c_port_dtor,
191 .init = nv50_i2c_port_init,
192 .fini = _nouveau_i2c_port_fini,
193 },
194 },
195 { .handle = NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX),
196 .ofuncs = &(struct nouveau_ofuncs) {
197 .ctor = gm204_aux_port_ctor,
198 .dtor = _nouveau_i2c_port_dtor,
199 .init = _nouveau_i2c_port_init,
200 .fini = _nouveau_i2c_port_fini,
201 },
202 },
203 {}
204};
205
206struct nouveau_oclass *
207gm204_i2c_oclass = &(struct nouveau_i2c_impl) {
208 .base.handle = NV_SUBDEV(I2C, 0x24),
209 .base.ofuncs = &(struct nouveau_ofuncs) {
210 .ctor = _nouveau_i2c_ctor,
211 .dtor = _nouveau_i2c_dtor,
212 .init = _nouveau_i2c_init,
213 .fini = _nouveau_i2c_fini,
214 },
215 .sclass = gm204_i2c_sclass,
216 .pad_x = &nv04_i2c_pad_oclass,
217 .pad_s = &gm204_i2c_pad_oclass,
218 .aux = 8,
219 .aux_stat = nve0_aux_stat,
220 .aux_mask = nve0_aux_mask,
221}.base;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
index 5d2a77421c74..9ef965692fb1 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv50.h
@@ -10,8 +10,6 @@ struct nv50_i2c_priv {
10struct nv50_i2c_port { 10struct nv50_i2c_port {
11 struct nouveau_i2c_port base; 11 struct nouveau_i2c_port base;
12 u32 addr; 12 u32 addr;
13 u32 ctrl;
14 u32 data;
15 u32 state; 13 u32 state;
16}; 14};
17 15
@@ -29,4 +27,8 @@ int nv94_aux_port_ctor(struct nouveau_object *, struct nouveau_object *,
29void nv94_i2c_acquire(struct nouveau_i2c_port *); 27void nv94_i2c_acquire(struct nouveau_i2c_port *);
30void nv94_i2c_release(struct nouveau_i2c_port *); 28void nv94_i2c_release(struct nouveau_i2c_port *);
31 29
30int nvd0_i2c_port_ctor(struct nouveau_object *, struct nouveau_object *,
31 struct nouveau_oclass *, void *, u32,
32 struct nouveau_object **);
33
32#endif 34#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c
index f59c3a255462..e383ee81f4d2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nv94.c
@@ -214,10 +214,6 @@ nv94_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
214 214
215 port->state = 7; 215 port->state = 7;
216 port->addr = nv50_i2c_addr[info->drive]; 216 port->addr = nv50_i2c_addr[info->drive];
217 if (info->share != DCB_I2C_UNUSED) {
218 port->ctrl = 0x00e500 + (info->share * 0x50);
219 port->data = 0x0000e001;
220 }
221 return 0; 217 return 0;
222} 218}
223 219
@@ -242,13 +238,8 @@ nv94_aux_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
242 if (ret) 238 if (ret)
243 return ret; 239 return ret;
244 240
245 port->base.aux = info->drive; 241 port->base.aux = info->auxch;
246 port->addr = info->drive; 242 port->addr = info->auxch;
247 if (info->share != DCB_I2C_UNUSED) {
248 port->ctrl = 0x00e500 + (info->drive * 0x50);
249 port->data = 0x00002002;
250 }
251
252 return 0; 243 return 0;
253} 244}
254 245
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c
index 364ddb1c5f03..fd99380502ec 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nvd0.c
@@ -48,7 +48,7 @@ nvd0_i2c_func = {
48 .sense_sda = nvd0_i2c_sense_sda, 48 .sense_sda = nvd0_i2c_sense_sda,
49}; 49};
50 50
51static int 51int
52nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine, 52nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
53 struct nouveau_oclass *oclass, void *data, u32 index, 53 struct nouveau_oclass *oclass, void *data, u32 index,
54 struct nouveau_object **pobject) 54 struct nouveau_object **pobject)
@@ -66,10 +66,6 @@ nvd0_i2c_port_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
66 66
67 port->state = 0x00000007; 67 port->state = 0x00000007;
68 port->addr = 0x00d014 + (info->drive * 0x20); 68 port->addr = 0x00d014 + (info->drive * 0x20);
69 if (info->share != DCB_I2C_UNUSED) {
70 port->ctrl = 0x00e500 + (info->share * 0x50);
71 port->data = 0x0000e001;
72 }
73 return 0; 69 return 0;
74} 70}
75 71
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c
index cae77e1ad8dc..25fe5c2d110e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/nve0.c
@@ -24,7 +24,7 @@
24 24
25#include "nv50.h" 25#include "nv50.h"
26 26
27static void 27void
28nve0_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx) 28nve0_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
29{ 29{
30 u32 intr = nv_rd32(i2c, 0x00dc60); 30 u32 intr = nv_rd32(i2c, 0x00dc60);
@@ -38,7 +38,7 @@ nve0_aux_stat(struct nouveau_i2c *i2c, u32 *hi, u32 *lo, u32 *rq, u32 *tx)
38 nv_wr32(i2c, 0x00dc60, intr); 38 nv_wr32(i2c, 0x00dc60, intr);
39} 39}
40 40
41static void 41void
42nve0_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data) 42nve0_aux_mask(struct nouveau_i2c *i2c, u32 type, u32 mask, u32 data)
43{ 43{
44 u32 temp = nv_rd32(i2c, 0x00dc68), i; 44 u32 temp = nv_rd32(i2c, 0x00dc68), i;
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c b/drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c
new file mode 100644
index 000000000000..f0e6fbbaa8cd
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/padgm204.c
@@ -0,0 +1,86 @@
1/*
2 * Copyright 2014 Red Hat Inc.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
18 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20 * OTHER DEALINGS IN THE SOFTWARE.
21 *
22 * Authors: Ben Skeggs
23 */
24
25#include "pad.h"
26
27struct gm204_i2c_pad {
28 struct nvkm_i2c_pad base;
29 int addr;
30};
31
32static int
33gm204_i2c_pad_fini(struct nouveau_object *object, bool suspend)
34{
35 struct nouveau_i2c *i2c = (void *)object->engine;
36 struct gm204_i2c_pad *pad = (void *)object;
37 nv_mask(i2c, 0x00d97c + pad->addr, 0x00000001, 0x00000001);
38 return nvkm_i2c_pad_fini(&pad->base, suspend);
39}
40
41static int
42gm204_i2c_pad_init(struct nouveau_object *object)
43{
44 struct nouveau_i2c *i2c = (void *)object->engine;
45 struct gm204_i2c_pad *pad = (void *)object;
46
47 switch (nv_oclass(pad->base.next)->handle) {
48 case NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_AUX):
49 nv_mask(i2c, 0x00d970 + pad->addr, 0x0000c003, 0x00000002);
50 break;
51 case NV_I2C_TYPE_DCBI2C(DCB_I2C_NVIO_BIT):
52 default:
53 nv_mask(i2c, 0x00d970 + pad->addr, 0x0000c003, 0x0000c001);
54 break;
55 }
56
57 nv_mask(i2c, 0x00d97c + pad->addr, 0x00000001, 0x00000000);
58 return nvkm_i2c_pad_init(&pad->base);
59}
60
61static int
62gm204_i2c_pad_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
63 struct nouveau_oclass *oclass, void *data, u32 index,
64 struct nouveau_object **pobject)
65{
66 struct gm204_i2c_pad *pad;
67 int ret;
68
69 ret = nvkm_i2c_pad_create(parent, engine, oclass, index, &pad);
70 *pobject = nv_object(pad);
71 if (ret)
72 return ret;
73
74 pad->addr = index * 0x50;;
75 return 0;
76}
77
78struct nouveau_oclass
79gm204_i2c_pad_oclass = {
80 .ofuncs = &(struct nouveau_ofuncs) {
81 .ctor = gm204_i2c_pad_ctor,
82 .dtor = _nvkm_i2c_pad_dtor,
83 .init = gm204_i2c_pad_init,
84 .fini = gm204_i2c_pad_fini,
85 },
86};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h b/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
index 780090b6425a..4fe7ae3fde4e 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/i2c/priv.h
@@ -5,6 +5,7 @@
5 5
6extern struct nouveau_oclass nv04_i2c_pad_oclass; 6extern struct nouveau_oclass nv04_i2c_pad_oclass;
7extern struct nouveau_oclass nv94_i2c_pad_oclass; 7extern struct nouveau_oclass nv94_i2c_pad_oclass;
8extern struct nouveau_oclass gm204_i2c_pad_oclass;
8 9
9#define nouveau_i2c_port_create(p,e,o,i,a,f,d) \ 10#define nouveau_i2c_port_create(p,e,o,i,a,f,d) \
10 nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \ 11 nouveau_i2c_port_create_((p), (e), (o), (i), (a), (f), \
@@ -82,4 +83,7 @@ struct nouveau_i2c_impl {
82void nv94_aux_stat(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *); 83void nv94_aux_stat(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *);
83void nv94_aux_mask(struct nouveau_i2c *, u32, u32, u32); 84void nv94_aux_mask(struct nouveau_i2c *, u32, u32, u32);
84 85
86void nve0_aux_stat(struct nouveau_i2c *, u32 *, u32 *, u32 *, u32 *);
87void nve0_aux_mask(struct nouveau_i2c *, u32, u32, u32);
88
85#endif 89#endif
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
index e89789a53b80..ec03f9a4290b 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/memx.fuc
@@ -50,6 +50,7 @@ handler(WR32 , 0x0000, 0x0002, #memx_func_wr32)
50handler(WAIT , 0x0004, 0x0000, #memx_func_wait) 50handler(WAIT , 0x0004, 0x0000, #memx_func_wait)
51handler(DELAY , 0x0001, 0x0000, #memx_func_delay) 51handler(DELAY , 0x0001, 0x0000, #memx_func_delay)
52handler(VBLANK, 0x0001, 0x0000, #memx_func_wait_vblank) 52handler(VBLANK, 0x0001, 0x0000, #memx_func_wait_vblank)
53handler(TRAIN , 0x0000, 0x0000, #memx_func_train)
53memx_func_tail: 54memx_func_tail:
54 55
55.equ #memx_func_size #memx_func_next - #memx_func_head 56.equ #memx_func_size #memx_func_next - #memx_func_head
@@ -63,6 +64,10 @@ memx_ts_end:
63memx_data_head: 64memx_data_head:
64.skip 0x0800 65.skip 0x0800
65memx_data_tail: 66memx_data_tail:
67
68memx_train_head:
69.skip 0x0100
70memx_train_tail:
66#endif 71#endif
67 72
68/****************************************************************************** 73/******************************************************************************
@@ -260,6 +265,101 @@ memx_func_delay:
260// description 265// description
261// 266//
262// $r15 - current (memx) 267// $r15 - current (memx)
268// $r4 - packet length
269// $r3 - opcode desciption
270// $r0 - zero
271memx_func_train:
272#if NVKM_PPWR_CHIPSET == GT215
273// $r5 - outer loop counter
274// $r6 - inner loop counter
275// $r7 - entry counter (#memx_train_head + $r7)
276 movw $r5 0x3
277 movw $r7 0x0
278
279// Read random memory to wake up... things
280 imm32($r9, 0x700000)
281 nv_rd32($r8,$r9)
282 movw $r14 0x2710
283 call(nsec)
284
285 memx_func_train_loop_outer:
286 mulu $r8 $r5 0x101
287 sethi $r8 0x02000000
288 imm32($r9, 0x1111e0)
289 nv_wr32($r9, $r8)
290 push $r5
291
292 movw $r6 0x0
293 memx_func_train_loop_inner:
294 movw $r8 0x1111
295 mulu $r9 $r6 $r8
296 shl b32 $r8 $r9 0x10
297 or $r8 $r9
298 imm32($r9, 0x100720)
299 nv_wr32($r9, $r8)
300
301 imm32($r9, 0x100080)
302 nv_rd32($r8, $r9)
303 or $r8 $r8 0x20
304 nv_wr32($r9, $r8)
305
306 imm32($r9, 0x10053c)
307 imm32($r8, 0x80003002)
308 nv_wr32($r9, $r8)
309
310 imm32($r14, 0x100560)
311 imm32($r13, 0x80000000)
312 add b32 $r12 $r13 0
313 imm32($r11, 0x001e8480)
314 call(wait)
315
316 // $r5 - inner inner loop counter
317 // $r9 - result
318 movw $r5 0
319 imm32($r9, 0x8300ffff)
320 memx_func_train_loop_4x:
321 imm32($r10, 0x100080)
322 nv_rd32($r8, $r10)
323 imm32($r11, 0xffffffdf)
324 and $r8 $r11
325 nv_wr32($r10, $r8)
326
327 imm32($r10, 0x10053c)
328 imm32($r8, 0x80003002)
329 nv_wr32($r10, $r8)
330
331 imm32($r14, 0x100560)
332 imm32($r13, 0x80000000)
333 mov b32 $r12 $r13
334 imm32($r11, 0x00002710)
335 call(wait)
336
337 nv_rd32($r13, $r14)
338 and $r9 $r9 $r13
339
340 add b32 $r5 1
341 cmp b16 $r5 0x4
342 bra l #memx_func_train_loop_4x
343
344 add b32 $r10 $r7 #memx_train_head
345 st b32 D[$r10 + 0] $r9
346 add b32 $r6 1
347 add b32 $r7 4
348
349 cmp b16 $r6 0x10
350 bra l #memx_func_train_loop_inner
351
352 pop $r5
353 add b32 $r5 1
354 cmp b16 $r5 7
355 bra l #memx_func_train_loop_outer
356
357#endif
358 ret
359
360// description
361//
362// $r15 - current (memx)
263// $r14 - sender process name 363// $r14 - sender process name
264// $r13 - message (exec) 364// $r13 - message (exec)
265// $r12 - head of script 365// $r12 - head of script
@@ -307,8 +407,19 @@ memx_exec:
307// $r11 - data1 407// $r11 - data1
308// $r0 - zero 408// $r0 - zero
309memx_info: 409memx_info:
410 cmp b16 $r12 0x1
411 bra e #memx_info_train
412
413 memx_info_data:
310 mov $r12 #memx_data_head 414 mov $r12 #memx_data_head
311 mov $r11 #memx_data_tail - #memx_data_head 415 mov $r11 #memx_data_tail - #memx_data_head
416 bra #memx_info_send
417
418 memx_info_train:
419 mov $r12 #memx_train_head
420 mov $r11 #memx_train_tail - #memx_train_head
421
422 memx_info_send:
312 call(send) 423 call(send)
313 ret 424 ret
314 425
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
index 4d278a96b2bb..713e11e2953d 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nv108.fuc.h
@@ -46,8 +46,8 @@ uint32_t nv108_pwr_data[] = {
46 0x00000000, 46 0x00000000,
47 0x00000000, 47 0x00000000,
48 0x584d454d, 48 0x584d454d,
49 0x0000061c, 49 0x0000062d,
50 0x0000060e, 50 0x0000061f,
51 0x00000000, 51 0x00000000,
52 0x00000000, 52 0x00000000,
53 0x00000000, 53 0x00000000,
@@ -68,8 +68,8 @@ uint32_t nv108_pwr_data[] = {
68 0x00000000, 68 0x00000000,
69 0x00000000, 69 0x00000000,
70 0x46524550, 70 0x46524550,
71 0x00000620, 71 0x00000631,
72 0x0000061e, 72 0x0000062f,
73 0x00000000, 73 0x00000000,
74 0x00000000, 74 0x00000000,
75 0x00000000, 75 0x00000000,
@@ -90,8 +90,8 @@ uint32_t nv108_pwr_data[] = {
90 0x00000000, 90 0x00000000,
91 0x00000000, 91 0x00000000,
92 0x5f433249, 92 0x5f433249,
93 0x00000a24, 93 0x00000a35,
94 0x000008cb, 94 0x000008dc,
95 0x00000000, 95 0x00000000,
96 0x00000000, 96 0x00000000,
97 0x00000000, 97 0x00000000,
@@ -112,8 +112,8 @@ uint32_t nv108_pwr_data[] = {
112 0x00000000, 112 0x00000000,
113 0x00000000, 113 0x00000000,
114 0x54534554, 114 0x54534554,
115 0x00000a45, 115 0x00000a56,
116 0x00000a26, 116 0x00000a37,
117 0x00000000, 117 0x00000000,
118 0x00000000, 118 0x00000000,
119 0x00000000, 119 0x00000000,
@@ -134,8 +134,8 @@ uint32_t nv108_pwr_data[] = {
134 0x00000000, 134 0x00000000,
135 0x00000000, 135 0x00000000,
136 0x454c4449, 136 0x454c4449,
137 0x00000a50, 137 0x00000a61,
138 0x00000a4e, 138 0x00000a5f,
139 0x00000000, 139 0x00000000,
140 0x00000000, 140 0x00000000,
141 0x00000000, 141 0x00000000,
@@ -246,13 +246,15 @@ uint32_t nv108_pwr_data[] = {
246 0x00010006, 246 0x00010006,
247 0x00000000, 247 0x00000000,
248 0x0000057b, 248 0x0000057b,
249/* 0x03b8: memx_func_tail */ 249 0x00000007,
250/* 0x03b8: memx_ts_start */
251 0x00000000, 250 0x00000000,
252/* 0x03bc: memx_ts_end */ 251 0x000005c3,
252/* 0x03c4: memx_func_tail */
253/* 0x03c4: memx_ts_start */
253 0x00000000, 254 0x00000000,
254/* 0x03c0: memx_data_head */ 255/* 0x03c8: memx_ts_end */
255 0x00000000, 256 0x00000000,
257/* 0x03cc: memx_data_head */
256 0x00000000, 258 0x00000000,
257 0x00000000, 259 0x00000000,
258 0x00000000, 260 0x00000000,
@@ -764,8 +766,75 @@ uint32_t nv108_pwr_data[] = {
764 0x00000000, 766 0x00000000,
765 0x00000000, 767 0x00000000,
766 0x00000000, 768 0x00000000,
767/* 0x0bc0: memx_data_tail */ 769 0x00000000,
768/* 0x0bc0: i2c_scl_map */ 770/* 0x0bcc: memx_data_tail */
771/* 0x0bcc: memx_train_head */
772 0x00000000,
773 0x00000000,
774 0x00000000,
775 0x00000000,
776 0x00000000,
777 0x00000000,
778 0x00000000,
779 0x00000000,
780 0x00000000,
781 0x00000000,
782 0x00000000,
783 0x00000000,
784 0x00000000,
785 0x00000000,
786 0x00000000,
787 0x00000000,
788 0x00000000,
789 0x00000000,
790 0x00000000,
791 0x00000000,
792 0x00000000,
793 0x00000000,
794 0x00000000,
795 0x00000000,
796 0x00000000,
797 0x00000000,
798 0x00000000,
799 0x00000000,
800 0x00000000,
801 0x00000000,
802 0x00000000,
803 0x00000000,
804 0x00000000,
805 0x00000000,
806 0x00000000,
807 0x00000000,
808 0x00000000,
809 0x00000000,
810 0x00000000,
811 0x00000000,
812 0x00000000,
813 0x00000000,
814 0x00000000,
815 0x00000000,
816 0x00000000,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836/* 0x0ccc: memx_train_tail */
837/* 0x0ccc: i2c_scl_map */
769 0x00000400, 838 0x00000400,
770 0x00000800, 839 0x00000800,
771 0x00001000, 840 0x00001000,
@@ -776,7 +845,7 @@ uint32_t nv108_pwr_data[] = {
776 0x00020000, 845 0x00020000,
777 0x00040000, 846 0x00040000,
778 0x00080000, 847 0x00080000,
779/* 0x0be8: i2c_sda_map */ 848/* 0x0cf4: i2c_sda_map */
780 0x00100000, 849 0x00100000,
781 0x00200000, 850 0x00200000,
782 0x00400000, 851 0x00400000,
@@ -844,9 +913,6 @@ uint32_t nv108_pwr_data[] = {
844 0x00000000, 913 0x00000000,
845 0x00000000, 914 0x00000000,
846 0x00000000, 915 0x00000000,
847 0x00000000,
848 0x00000000,
849 0x00000000,
850}; 916};
851 917
852uint32_t nv108_pwr_code[] = { 918uint32_t nv108_pwr_code[] = {
@@ -1215,10 +1281,10 @@ uint32_t nv108_pwr_code[] = {
1215 0xf40464f0, 1281 0xf40464f0,
1216 0x2c06f70b, 1282 0x2c06f70b,
1217 0xb50066cf, 1283 0xb50066cf,
1218 0x00f8ee06, 1284 0x00f8f106,
1219/* 0x0500: memx_func_leave */ 1285/* 0x0500: memx_func_leave */
1220 0x66cf2c06, 1286 0x66cf2c06,
1221 0xef06b500, 1287 0xf206b500,
1222 0xe4400406, 1288 0xe4400406,
1223 0x0006f607, 1289 0x0006f607,
1224/* 0x0512: memx_func_leave_wait */ 1290/* 0x0512: memx_func_leave_wait */
@@ -1270,370 +1336,374 @@ uint32_t nv108_pwr_code[] = {
1270 0x9800f800, 1336 0x9800f800,
1271 0x10b6001e, 1337 0x10b6001e,
1272 0x005d7e04, 1338 0x005d7e04,
1273/* 0x05c3: memx_exec */ 1339/* 0x05c3: memx_func_train */
1274 0xf900f800, 1340 0xf800f800,
1275 0xb2d0f9e0, 1341/* 0x05c5: memx_exec */
1276/* 0x05cb: memx_exec_next */ 1342 0xf9e0f900,
1277 0x98b2b2c1, 1343 0xb2c1b2d0,
1278 0x10b60013, 1344/* 0x05cd: memx_exec_next */
1279 0xf034e704, 1345 0x001398b2,
1280 0xe033e701, 1346 0xe70410b6,
1281 0x0132b601, 1347 0xe701f034,
1282 0x980c30f0, 1348 0xb601e033,
1283 0x55f9de35, 1349 0x30f00132,
1284 0x1ef412a6, 1350 0xde35980c,
1285 0xee0b98e5, 1351 0x12a655f9,
1286 0xbbef0c98, 1352 0x98e51ef4,
1287 0xc44b02cb, 1353 0x0c98f10b,
1288 0x00bbcf07, 1354 0x02cbbbf2,
1289 0xe0fcd0fc, 1355 0xcf07c44b,
1290 0x0002c27e, 1356 0xd0fc00bb,
1291/* 0x0602: memx_info */ 1357 0xc27ee0fc,
1292 0xc04c00f8, 1358 0x00f80002,
1359/* 0x0604: memx_info */
1360 0xf401c670,
1361/* 0x060a: memx_info_data */
1362 0xcc4c0c0b,
1293 0x08004b03, 1363 0x08004b03,
1294 0x0002c27e, 1364/* 0x0613: memx_info_train */
1295/* 0x060e: memx_recv */ 1365 0x4c090ef4,
1296 0xd6b000f8, 1366 0x004b0bcc,
1297 0xb20bf401, 1367/* 0x0619: memx_info_send */
1298 0xf400d6b0, 1368 0x02c27e01,
1299 0x00f8eb0b, 1369/* 0x061f: memx_recv */
1300/* 0x061c: memx_init */ 1370 0xb000f800,
1301/* 0x061e: perf_recv */ 1371 0x0bf401d6,
1302 0x00f800f8, 1372 0x00d6b0a3,
1303/* 0x0620: perf_init */ 1373 0xf8dc0bf4,
1304/* 0x0622: i2c_drive_scl */ 1374/* 0x062d: memx_init */
1305 0x36b000f8, 1375/* 0x062f: perf_recv */
1306 0x0d0bf400, 1376 0xf800f800,
1307 0xf607e040, 1377/* 0x0631: perf_init */
1308 0x04bd0001, 1378/* 0x0633: i2c_drive_scl */
1309/* 0x0632: i2c_drive_scl_lo */ 1379 0xb000f800,
1310 0xe44000f8, 1380 0x0bf40036,
1311 0x0001f607, 1381 0x07e0400d,
1312 0x00f804bd, 1382 0xbd0001f6,
1313/* 0x063c: i2c_drive_sda */ 1383/* 0x0643: i2c_drive_scl_lo */
1314 0xf40036b0, 1384 0x4000f804,
1315 0xe0400d0b, 1385 0x01f607e4,
1316 0x0002f607, 1386 0xf804bd00,
1317 0x00f804bd, 1387/* 0x064d: i2c_drive_sda */
1318/* 0x064c: i2c_drive_sda_lo */ 1388 0x0036b000,
1319 0xf607e440, 1389 0x400d0bf4,
1320 0x04bd0002, 1390 0x02f607e0,
1321/* 0x0656: i2c_sense_scl */ 1391 0xf804bd00,
1322 0x32f400f8, 1392/* 0x065d: i2c_drive_sda_lo */
1323 0x07c44301, 1393 0x07e44000,
1324 0xfd0033cf, 1394 0xbd0002f6,
1325 0x0bf40431, 1395/* 0x0667: i2c_sense_scl */
1326 0x0131f406, 1396 0xf400f804,
1327/* 0x0668: i2c_sense_scl_done */ 1397 0xc4430132,
1328/* 0x066a: i2c_sense_sda */ 1398 0x0033cf07,
1329 0x32f400f8, 1399 0xf40431fd,
1330 0x07c44301, 1400 0x31f4060b,
1331 0xfd0033cf, 1401/* 0x0679: i2c_sense_scl_done */
1332 0x0bf40432, 1402/* 0x067b: i2c_sense_sda */
1333 0x0131f406, 1403 0xf400f801,
1334/* 0x067c: i2c_sense_sda_done */ 1404 0xc4430132,
1335/* 0x067e: i2c_raise_scl */ 1405 0x0033cf07,
1336 0x40f900f8, 1406 0xf40432fd,
1337 0x03089844, 1407 0x31f4060b,
1338 0x06227e01, 1408/* 0x068d: i2c_sense_sda_done */
1339/* 0x0689: i2c_raise_scl_wait */ 1409/* 0x068f: i2c_raise_scl */
1340 0x03e84e00, 1410 0xf900f801,
1341 0x00005d7e, 1411 0x08984440,
1342 0x0006567e, 1412 0x337e0103,
1343 0xb60901f4, 1413/* 0x069a: i2c_raise_scl_wait */
1344 0x1bf40142, 1414 0xe84e0006,
1345/* 0x069d: i2c_raise_scl_done */ 1415 0x005d7e03,
1346 0xf840fcef, 1416 0x06677e00,
1347/* 0x06a1: i2c_start */ 1417 0x0901f400,
1348 0x06567e00, 1418 0xf40142b6,
1349 0x0d11f400, 1419/* 0x06ae: i2c_raise_scl_done */
1350 0x00066a7e, 1420 0x40fcef1b,
1351 0xf40611f4, 1421/* 0x06b2: i2c_start */
1352/* 0x06b2: i2c_start_rep */ 1422 0x677e00f8,
1353 0x00032e0e, 1423 0x11f40006,
1354 0x0006227e, 1424 0x067b7e0d,
1355 0x3c7e0103, 1425 0x0611f400,
1356 0x76bb0006, 1426/* 0x06c3: i2c_start_rep */
1357 0x0465b600, 1427 0x032e0ef4,
1358 0x659450f9, 1428 0x06337e00,
1359 0x0256bb04,
1360 0x75fd50bd,
1361 0x7e50fc04,
1362 0xb600067e,
1363 0x11f40464,
1364/* 0x06dd: i2c_start_send */
1365 0x7e00031d,
1366 0x4e00063c,
1367 0x5d7e1388,
1368 0x00030000,
1369 0x0006227e,
1370 0x7e13884e,
1371/* 0x06f7: i2c_start_out */
1372 0xf800005d,
1373/* 0x06f9: i2c_stop */
1374 0x7e000300,
1375 0x03000622,
1376 0x063c7e00,
1377 0x03e84e00,
1378 0x00005d7e,
1379 0x227e0103,
1380 0x884e0006,
1381 0x005d7e13,
1382 0x7e010300, 1429 0x7e010300,
1383 0x4e00063c, 1430 0xbb00064d,
1384 0x5d7e1388,
1385 0x00f80000,
1386/* 0x0728: i2c_bitw */
1387 0x00063c7e,
1388 0x7e03e84e,
1389 0xbb00005d,
1390 0x65b60076, 1431 0x65b60076,
1391 0x9450f904, 1432 0x9450f904,
1392 0x56bb0465, 1433 0x56bb0465,
1393 0xfd50bd02, 1434 0xfd50bd02,
1394 0x50fc0475, 1435 0x50fc0475,
1395 0x00067e7e, 1436 0x00068f7e,
1396 0xf40464b6, 1437 0xf40464b6,
1397 0x884e1711, 1438/* 0x06ee: i2c_start_send */
1398 0x005d7e13, 1439 0x00031d11,
1399 0x7e000300, 1440 0x00064d7e,
1400 0x4e000622, 1441 0x7e13884e,
1401 0x5d7e1388, 1442 0x0300005d,
1402/* 0x0766: i2c_bitw_out */ 1443 0x06337e00,
1403 0x00f80000, 1444 0x13884e00,
1404/* 0x0768: i2c_bitr */ 1445 0x00005d7e,
1405 0x3c7e0103, 1446/* 0x0708: i2c_start_out */
1447/* 0x070a: i2c_stop */
1448 0x000300f8,
1449 0x0006337e,
1450 0x4d7e0003,
1406 0xe84e0006, 1451 0xe84e0006,
1407 0x005d7e03, 1452 0x005d7e03,
1408 0x0076bb00, 1453 0x7e010300,
1409 0xf90465b6, 1454 0x4e000633,
1410 0x04659450, 1455 0x5d7e1388,
1411 0xbd0256bb, 1456 0x01030000,
1412 0x0475fd50, 1457 0x00064d7e,
1413 0x7e7e50fc, 1458 0x7e13884e,
1414 0x64b60006, 1459 0xf800005d,
1415 0x1a11f404, 1460/* 0x0739: i2c_bitw */
1416 0x00066a7e, 1461 0x064d7e00,
1417 0x227e0003, 1462 0x03e84e00,
1418 0x884e0006, 1463 0x00005d7e,
1419 0x005d7e13,
1420 0x013cf000,
1421/* 0x07ab: i2c_bitr_done */
1422 0xf80131f4,
1423/* 0x07ad: i2c_get_byte */
1424 0x04000500,
1425/* 0x07b1: i2c_get_byte_next */
1426 0x0154b608,
1427 0xb60076bb, 1464 0xb60076bb,
1428 0x50f90465, 1465 0x50f90465,
1429 0xbb046594, 1466 0xbb046594,
1430 0x50bd0256, 1467 0x50bd0256,
1431 0xfc0475fd, 1468 0xfc0475fd,
1432 0x07687e50, 1469 0x068f7e50,
1433 0x0464b600, 1470 0x0464b600,
1434 0xfd2a11f4, 1471 0x4e1711f4,
1435 0x42b60553, 1472 0x5d7e1388,
1436 0xd81bf401, 1473 0x00030000,
1437 0x76bb0103, 1474 0x0006337e,
1475 0x7e13884e,
1476/* 0x0777: i2c_bitw_out */
1477 0xf800005d,
1478/* 0x0779: i2c_bitr */
1479 0x7e010300,
1480 0x4e00064d,
1481 0x5d7e03e8,
1482 0x76bb0000,
1438 0x0465b600, 1483 0x0465b600,
1439 0x659450f9, 1484 0x659450f9,
1440 0x0256bb04, 1485 0x0256bb04,
1441 0x75fd50bd, 1486 0x75fd50bd,
1442 0x7e50fc04, 1487 0x7e50fc04,
1443 0xb6000728, 1488 0xb600068f,
1444/* 0x07fa: i2c_get_byte_done */ 1489 0x11f40464,
1445 0x00f80464, 1490 0x067b7e1a,
1446/* 0x07fc: i2c_put_byte */ 1491 0x7e000300,
1447/* 0x07fe: i2c_put_byte_next */ 1492 0x4e000633,
1448 0x42b60804, 1493 0x5d7e1388,
1449 0x3854ff01, 1494 0x3cf00000,
1450 0xb60076bb, 1495 0x0131f401,
1451 0x50f90465, 1496/* 0x07bc: i2c_bitr_done */
1452 0xbb046594, 1497/* 0x07be: i2c_get_byte */
1453 0x50bd0256, 1498 0x000500f8,
1454 0xfc0475fd, 1499/* 0x07c2: i2c_get_byte_next */
1455 0x07287e50, 1500 0x54b60804,
1456 0x0464b600, 1501 0x0076bb01,
1457 0xb03411f4, 1502 0xf90465b6,
1458 0x1bf40046, 1503 0x04659450,
1459 0x0076bbd8, 1504 0xbd0256bb,
1505 0x0475fd50,
1506 0x797e50fc,
1507 0x64b60007,
1508 0x2a11f404,
1509 0xb60553fd,
1510 0x1bf40142,
1511 0xbb0103d8,
1512 0x65b60076,
1513 0x9450f904,
1514 0x56bb0465,
1515 0xfd50bd02,
1516 0x50fc0475,
1517 0x0007397e,
1518/* 0x080b: i2c_get_byte_done */
1519 0xf80464b6,
1520/* 0x080d: i2c_put_byte */
1521/* 0x080f: i2c_put_byte_next */
1522 0xb6080400,
1523 0x54ff0142,
1524 0x0076bb38,
1460 0xf90465b6, 1525 0xf90465b6,
1461 0x04659450, 1526 0x04659450,
1462 0xbd0256bb, 1527 0xbd0256bb,
1463 0x0475fd50, 1528 0x0475fd50,
1464 0x687e50fc, 1529 0x397e50fc,
1465 0x64b60007, 1530 0x64b60007,
1466 0x0f11f404, 1531 0x3411f404,
1467 0xb00076bb, 1532 0xf40046b0,
1468 0x1bf40136, 1533 0x76bbd81b,
1469 0x0132f406,
1470/* 0x0854: i2c_put_byte_done */
1471/* 0x0856: i2c_addr */
1472 0x76bb00f8,
1473 0x0465b600, 1534 0x0465b600,
1474 0x659450f9, 1535 0x659450f9,
1475 0x0256bb04, 1536 0x0256bb04,
1476 0x75fd50bd, 1537 0x75fd50bd,
1477 0x7e50fc04, 1538 0x7e50fc04,
1478 0xb60006a1, 1539 0xb6000779,
1479 0x11f40464, 1540 0x11f40464,
1480 0x2ec3e729, 1541 0x0076bb0f,
1481 0x0134b601, 1542 0xf40136b0,
1482 0xbb0553fd, 1543 0x32f4061b,
1544/* 0x0865: i2c_put_byte_done */
1545/* 0x0867: i2c_addr */
1546 0xbb00f801,
1483 0x65b60076, 1547 0x65b60076,
1484 0x9450f904, 1548 0x9450f904,
1485 0x56bb0465, 1549 0x56bb0465,
1486 0xfd50bd02, 1550 0xfd50bd02,
1487 0x50fc0475, 1551 0x50fc0475,
1488 0x0007fc7e, 1552 0x0006b27e,
1489/* 0x089b: i2c_addr_done */ 1553 0xf40464b6,
1490 0xf80464b6, 1554 0xc3e72911,
1491/* 0x089d: i2c_acquire_addr */ 1555 0x34b6012e,
1492 0xf8cec700, 1556 0x0553fd01,
1493 0xb705e4b6, 1557 0xb60076bb,
1494 0xf8d014e0, 1558 0x50f90465,
1495/* 0x08a9: i2c_acquire */ 1559 0xbb046594,
1496 0x089d7e00, 1560 0x50bd0256,
1497 0x00047e00, 1561 0xfc0475fd,
1498 0x03d9f000, 1562 0x080d7e50,
1499 0x00002e7e, 1563 0x0464b600,
1500/* 0x08ba: i2c_release */ 1564/* 0x08ac: i2c_addr_done */
1501 0x9d7e00f8, 1565/* 0x08ae: i2c_acquire_addr */
1566 0xcec700f8,
1567 0x05e4b6f8,
1568 0xd014e0b7,
1569/* 0x08ba: i2c_acquire */
1570 0xae7e00f8,
1502 0x047e0008, 1571 0x047e0008,
1503 0xdaf00000, 1572 0xd9f00000,
1504 0x002e7e03, 1573 0x002e7e03,
1505/* 0x08cb: i2c_recv */ 1574/* 0x08cb: i2c_release */
1506 0xf400f800, 1575 0x7e00f800,
1507 0xc1c70132, 1576 0x7e0008ae,
1508 0x0214b6f8, 1577 0xf0000004,
1509 0xf52816b0, 1578 0x2e7e03da,
1510 0xb801371f, 1579 0x00f80000,
1511 0x000be813, 1580/* 0x08dc: i2c_recv */
1512 0xb8003298, 1581 0xc70132f4,
1513 0x000bc013, 1582 0x14b6f8c1,
1514 0xf4003198, 1583 0x2816b002,
1515 0xd0f90231, 1584 0x01371ff5,
1516 0xd0f9e0f9, 1585 0x0cf413b8,
1517 0x000067f1, 1586 0x00329800,
1518 0x100063f1, 1587 0x0ccc13b8,
1519 0xbb016792, 1588 0x00319800,
1589 0xf90231f4,
1590 0xf9e0f9d0,
1591 0x0067f1d0,
1592 0x0063f100,
1593 0x01679210,
1594 0xb60076bb,
1595 0x50f90465,
1596 0xbb046594,
1597 0x50bd0256,
1598 0xfc0475fd,
1599 0x08ba7e50,
1600 0x0464b600,
1601 0xd6b0d0fc,
1602 0xb01bf500,
1603 0xbb000500,
1520 0x65b60076, 1604 0x65b60076,
1521 0x9450f904, 1605 0x9450f904,
1522 0x56bb0465, 1606 0x56bb0465,
1523 0xfd50bd02, 1607 0xfd50bd02,
1524 0x50fc0475, 1608 0x50fc0475,
1525 0x0008a97e, 1609 0x0008677e,
1526 0xfc0464b6, 1610 0xf50464b6,
1527 0x00d6b0d0, 1611 0xc700cc11,
1528 0x00b01bf5, 1612 0x76bbe0c5,
1529 0x76bb0005,
1530 0x0465b600, 1613 0x0465b600,
1531 0x659450f9, 1614 0x659450f9,
1532 0x0256bb04, 1615 0x0256bb04,
1533 0x75fd50bd, 1616 0x75fd50bd,
1534 0x7e50fc04, 1617 0x7e50fc04,
1535 0xb6000856, 1618 0xb600080d,
1536 0x11f50464, 1619 0x11f50464,
1537 0xc5c700cc, 1620 0x010500a9,
1538 0x0076bbe0, 1621 0xb60076bb,
1539 0xf90465b6, 1622 0x50f90465,
1540 0x04659450, 1623 0xbb046594,
1541 0xbd0256bb, 1624 0x50bd0256,
1542 0x0475fd50, 1625 0xfc0475fd,
1543 0xfc7e50fc, 1626 0x08677e50,
1544 0x64b60007, 1627 0x0464b600,
1545 0xa911f504, 1628 0x008711f5,
1546 0xbb010500, 1629 0xb60076bb,
1547 0x65b60076, 1630 0x50f90465,
1548 0x9450f904, 1631 0xbb046594,
1549 0x56bb0465, 1632 0x50bd0256,
1550 0xfd50bd02, 1633 0xfc0475fd,
1551 0x50fc0475, 1634 0x07be7e50,
1552 0x0008567e, 1635 0x0464b600,
1553 0xf50464b6, 1636 0xcb6711f4,
1554 0xbb008711, 1637 0x76bbe05b,
1555 0x65b60076, 1638 0x0465b600,
1556 0x9450f904, 1639 0x659450f9,
1557 0x56bb0465, 1640 0x0256bb04,
1558 0xfd50bd02, 1641 0x75fd50bd,
1559 0x50fc0475, 1642 0x7e50fc04,
1560 0x0007ad7e, 1643 0xb600070a,
1561 0xf40464b6, 1644 0x5bb20464,
1562 0x5bcb6711, 1645 0x0ef474bd,
1563 0x0076bbe0, 1646/* 0x09e1: i2c_recv_not_rd08 */
1564 0xf90465b6, 1647 0x01d6b041,
1565 0x04659450, 1648 0x053b1bf4,
1566 0xbd0256bb, 1649 0x08677e00,
1567 0x0475fd50, 1650 0x3211f400,
1568 0xf97e50fc, 1651 0x7ee0c5c7,
1569 0x64b60006, 1652 0xf400080d,
1570 0xbd5bb204, 1653 0x00052811,
1571 0x410ef474, 1654 0x0008677e,
1572/* 0x09d0: i2c_recv_not_rd08 */ 1655 0xc71f11f4,
1573 0xf401d6b0, 1656 0x0d7ee0b5,
1574 0x00053b1b, 1657 0x11f40008,
1575 0x0008567e, 1658 0x070a7e15,
1576 0xc73211f4, 1659 0xc774bd00,
1577 0xfc7ee0c5, 1660 0x1bf408c5,
1578 0x11f40007, 1661 0x0232f409,
1579 0x7e000528, 1662/* 0x0a1f: i2c_recv_not_wr08 */
1580 0xf4000856, 1663/* 0x0a1f: i2c_recv_done */
1581 0xb5c71f11, 1664 0xc7030ef4,
1582 0x07fc7ee0, 1665 0xcb7ef8ce,
1583 0x1511f400, 1666 0xe0fc0008,
1584 0x0006f97e, 1667 0x12f4d0fc,
1585 0xc5c774bd, 1668 0x7e7cb209,
1586 0x091bf408, 1669/* 0x0a33: i2c_recv_exit */
1587 0xf40232f4, 1670 0xf80002c2,
1588/* 0x0a0e: i2c_recv_not_wr08 */ 1671/* 0x0a35: i2c_init */
1589/* 0x0a0e: i2c_recv_done */ 1672/* 0x0a37: test_recv */
1590 0xcec7030e, 1673 0x4100f800,
1591 0x08ba7ef8, 1674 0x11cf0458,
1592 0xfce0fc00,
1593 0x0912f4d0,
1594 0xc27e7cb2,
1595/* 0x0a22: i2c_recv_exit */
1596 0x00f80002,
1597/* 0x0a24: i2c_init */
1598/* 0x0a26: test_recv */
1599 0x584100f8,
1600 0x0011cf04,
1601 0x400110b6,
1602 0x01f60458,
1603 0xf104bd00,
1604 0xf1d900e7,
1605 0x7e134fe3,
1606 0xf8000201,
1607/* 0x0a45: test_init */
1608 0x08004e00,
1609 0x0002017e,
1610/* 0x0a4e: idle_recv */
1611 0x00f800f8,
1612/* 0x0a50: idle */
1613 0x410031f4,
1614 0x11cf0454,
1615 0x0110b600, 1675 0x0110b600,
1616 0xf6045440, 1676 0xf6045840,
1617 0x04bd0001, 1677 0x04bd0001,
1618/* 0x0a64: idle_loop */ 1678 0xd900e7f1,
1619 0x32f45801, 1679 0x134fe3f1,
1620/* 0x0a69: idle_proc */ 1680 0x0002017e,
1621/* 0x0a69: idle_proc_exec */ 1681/* 0x0a56: test_init */
1622 0xb210f902, 1682 0x004e00f8,
1623 0x02cb7e1e, 1683 0x02017e08,
1624 0xf410fc00, 1684/* 0x0a5f: idle_recv */
1625 0x31f40911, 1685 0xf800f800,
1626 0xf00ef402, 1686/* 0x0a61: idle */
1627/* 0x0a7c: idle_proc_next */ 1687 0x0031f400,
1628 0xa65810b6, 1688 0xcf045441,
1629 0xe81bf41f, 1689 0x10b60011,
1630 0xf4e002f4, 1690 0x04544001,
1631 0x0ef40028, 1691 0xbd0001f6,
1632 0x000000c6, 1692/* 0x0a75: idle_loop */
1633 0x00000000, 1693 0xf4580104,
1634 0x00000000, 1694/* 0x0a7a: idle_proc */
1635 0x00000000, 1695/* 0x0a7a: idle_proc_exec */
1636 0x00000000, 1696 0x10f90232,
1697 0xcb7e1eb2,
1698 0x10fc0002,
1699 0xf40911f4,
1700 0x0ef40231,
1701/* 0x0a8d: idle_proc_next */
1702 0x5810b6f0,
1703 0x1bf41fa6,
1704 0xe002f4e8,
1705 0xf40028f4,
1706 0x0000c60e,
1637 0x00000000, 1707 0x00000000,
1638 0x00000000, 1708 0x00000000,
1639 0x00000000, 1709 0x00000000,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
index 64e97baabc3c..d1f9b6cb66d7 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nva3.fuc.h
@@ -46,8 +46,8 @@ uint32_t nva3_pwr_data[] = {
46 0x00000000, 46 0x00000000,
47 0x00000000, 47 0x00000000,
48 0x584d454d, 48 0x584d454d,
49 0x000006e0, 49 0x00000842,
50 0x000006d2, 50 0x00000834,
51 0x00000000, 51 0x00000000,
52 0x00000000, 52 0x00000000,
53 0x00000000, 53 0x00000000,
@@ -68,8 +68,8 @@ uint32_t nva3_pwr_data[] = {
68 0x00000000, 68 0x00000000,
69 0x00000000, 69 0x00000000,
70 0x46524550, 70 0x46524550,
71 0x000006e4, 71 0x00000846,
72 0x000006e2, 72 0x00000844,
73 0x00000000, 73 0x00000000,
74 0x00000000, 74 0x00000000,
75 0x00000000, 75 0x00000000,
@@ -90,8 +90,8 @@ uint32_t nva3_pwr_data[] = {
90 0x00000000, 90 0x00000000,
91 0x00000000, 91 0x00000000,
92 0x5f433249, 92 0x5f433249,
93 0x00000b14, 93 0x00000c76,
94 0x000009b7, 94 0x00000b19,
95 0x00000000, 95 0x00000000,
96 0x00000000, 96 0x00000000,
97 0x00000000, 97 0x00000000,
@@ -112,8 +112,8 @@ uint32_t nva3_pwr_data[] = {
112 0x00000000, 112 0x00000000,
113 0x00000000, 113 0x00000000,
114 0x54534554, 114 0x54534554,
115 0x00000b3d, 115 0x00000c9f,
116 0x00000b16, 116 0x00000c78,
117 0x00000000, 117 0x00000000,
118 0x00000000, 118 0x00000000,
119 0x00000000, 119 0x00000000,
@@ -134,8 +134,8 @@ uint32_t nva3_pwr_data[] = {
134 0x00000000, 134 0x00000000,
135 0x00000000, 135 0x00000000,
136 0x454c4449, 136 0x454c4449,
137 0x00000b49, 137 0x00000cab,
138 0x00000b47, 138 0x00000ca9,
139 0x00000000, 139 0x00000000,
140 0x00000000, 140 0x00000000,
141 0x00000000, 141 0x00000000,
@@ -246,13 +246,15 @@ uint32_t nva3_pwr_data[] = {
246 0x00010006, 246 0x00010006,
247 0x00000000, 247 0x00000000,
248 0x000005f8, 248 0x000005f8,
249/* 0x03b8: memx_func_tail */ 249 0x00000007,
250/* 0x03b8: memx_ts_start */
251 0x00000000, 250 0x00000000,
252/* 0x03bc: memx_ts_end */ 251 0x0000067e,
252/* 0x03c4: memx_func_tail */
253/* 0x03c4: memx_ts_start */
253 0x00000000, 254 0x00000000,
254/* 0x03c0: memx_data_head */ 255/* 0x03c8: memx_ts_end */
255 0x00000000, 256 0x00000000,
257/* 0x03cc: memx_data_head */
256 0x00000000, 258 0x00000000,
257 0x00000000, 259 0x00000000,
258 0x00000000, 260 0x00000000,
@@ -764,8 +766,75 @@ uint32_t nva3_pwr_data[] = {
764 0x00000000, 766 0x00000000,
765 0x00000000, 767 0x00000000,
766 0x00000000, 768 0x00000000,
767/* 0x0bc0: memx_data_tail */ 769 0x00000000,
768/* 0x0bc0: i2c_scl_map */ 770/* 0x0bcc: memx_data_tail */
771/* 0x0bcc: memx_train_head */
772 0x00000000,
773 0x00000000,
774 0x00000000,
775 0x00000000,
776 0x00000000,
777 0x00000000,
778 0x00000000,
779 0x00000000,
780 0x00000000,
781 0x00000000,
782 0x00000000,
783 0x00000000,
784 0x00000000,
785 0x00000000,
786 0x00000000,
787 0x00000000,
788 0x00000000,
789 0x00000000,
790 0x00000000,
791 0x00000000,
792 0x00000000,
793 0x00000000,
794 0x00000000,
795 0x00000000,
796 0x00000000,
797 0x00000000,
798 0x00000000,
799 0x00000000,
800 0x00000000,
801 0x00000000,
802 0x00000000,
803 0x00000000,
804 0x00000000,
805 0x00000000,
806 0x00000000,
807 0x00000000,
808 0x00000000,
809 0x00000000,
810 0x00000000,
811 0x00000000,
812 0x00000000,
813 0x00000000,
814 0x00000000,
815 0x00000000,
816 0x00000000,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836/* 0x0ccc: memx_train_tail */
837/* 0x0ccc: i2c_scl_map */
769 0x00001000, 838 0x00001000,
770 0x00004000, 839 0x00004000,
771 0x00010000, 840 0x00010000,
@@ -776,7 +845,7 @@ uint32_t nva3_pwr_data[] = {
776 0x01000000, 845 0x01000000,
777 0x04000000, 846 0x04000000,
778 0x10000000, 847 0x10000000,
779/* 0x0be8: i2c_sda_map */ 848/* 0x0cf4: i2c_sda_map */
780 0x00002000, 849 0x00002000,
781 0x00008000, 850 0x00008000,
782 0x00020000, 851 0x00020000,
@@ -787,7 +856,7 @@ uint32_t nva3_pwr_data[] = {
787 0x02000000, 856 0x02000000,
788 0x08000000, 857 0x08000000,
789 0x20000000, 858 0x20000000,
790/* 0x0c10: i2c_ctrl */ 859/* 0x0d1c: i2c_ctrl */
791 0x0000e138, 860 0x0000e138,
792 0x0000e150, 861 0x0000e150,
793 0x0000e168, 862 0x0000e168,
@@ -845,9 +914,6 @@ uint32_t nva3_pwr_data[] = {
845 0x00000000, 914 0x00000000,
846 0x00000000, 915 0x00000000,
847 0x00000000, 916 0x00000000,
848 0x00000000,
849 0x00000000,
850 0x00000000,
851}; 917};
852 918
853uint32_t nva3_pwr_code[] = { 919uint32_t nva3_pwr_code[] = {
@@ -1258,11 +1324,11 @@ uint32_t nva3_pwr_code[] = {
1258 0x67f0f30b, 1324 0x67f0f30b,
1259 0x0664b62c, 1325 0x0664b62c,
1260 0x800066cf, 1326 0x800066cf,
1261 0x00f8ee06, 1327 0x00f8f106,
1262/* 0x05a8: memx_func_leave */ 1328/* 0x05a8: memx_func_leave */
1263 0xb62c67f0, 1329 0xb62c67f0,
1264 0x66cf0664, 1330 0x66cf0664,
1265 0xef068000, 1331 0xf2068000,
1266 0xf10467f0, 1332 0xf10467f0,
1267 0xb607e407, 1333 0xb607e407,
1268 0x06d00604, 1334 0x06d00604,
@@ -1323,408 +1389,479 @@ uint32_t nva3_pwr_code[] = {
1323 0x9800f8a4, 1389 0x9800f8a4,
1324 0x10b6001e, 1390 0x10b6001e,
1325 0x7f21f404, 1391 0x7f21f404,
1326/* 0x067e: memx_exec */ 1392/* 0x067e: memx_func_train */
1327 0xe0f900f8, 1393 0x57f100f8,
1328 0xc1b9d0f9, 1394 0x77f10003,
1329 0x02b2b902, 1395 0x97f10000,
1330/* 0x0688: memx_exec_next */ 1396 0x93f00000,
1331 0xb6001398, 1397 0x029eb970,
1332 0x34e70410, 1398 0xb90421f4,
1333 0x33e701f0, 1399 0xe7f102d8,
1334 0x32b601e0, 1400 0x21f42710,
1335 0x0c30f001, 1401/* 0x069d: memx_func_train_loop_outer */
1336 0xf9de3598, 1402 0x0158e07f,
1337 0x0612b855, 1403 0x0083f101,
1338 0x98e41ef4, 1404 0xe097f102,
1339 0x0c98ee0b, 1405 0x1193f011,
1340 0x02cbbbef, 1406 0x80f990f9,
1341 0x07c4b7f1, 1407 0xe0fcd0fc,
1342 0xcf06b4b6, 1408 0xf93f21f4,
1343 0xd0fc00bb, 1409 0x0067f150,
1344 0x21f5e0fc, 1410/* 0x06bd: memx_func_train_loop_inner */
1411 0x1187f100,
1412 0x9068ff11,
1413 0xfd109894,
1414 0x97f10589,
1415 0x93f00720,
1416 0xf990f910,
1417 0xfcd0fc80,
1418 0x3f21f4e0,
1419 0x008097f1,
1420 0xb91093f0,
1421 0x21f4029e,
1422 0x02d8b904,
1423 0xf92088c5,
1424 0xfc80f990,
1425 0xf4e0fcd0,
1426 0x97f13f21,
1427 0x93f0053c,
1428 0x0287f110,
1429 0x0083f130,
1430 0xf990f980,
1431 0xfcd0fc80,
1432 0x3f21f4e0,
1433 0x0560e7f1,
1434 0xf110e3f0,
1435 0xf10000d7,
1436 0x908000d3,
1437 0xb7f100dc,
1438 0xb3f08480,
1439 0xa421f41e,
1440 0x000057f1,
1441 0xffff97f1,
1442 0x830093f1,
1443/* 0x073c: memx_func_train_loop_4x */
1444 0x0080a7f1,
1445 0xb910a3f0,
1446 0x21f402ae,
1447 0x02d8b904,
1448 0xffdfb7f1,
1449 0xffffb3f1,
1450 0xf9048bfd,
1451 0xfc80f9a0,
1452 0xf4e0fcd0,
1453 0xa7f13f21,
1454 0xa3f0053c,
1455 0x0287f110,
1456 0x0083f130,
1457 0xf9a0f980,
1458 0xfcd0fc80,
1459 0x3f21f4e0,
1460 0x0560e7f1,
1461 0xf110e3f0,
1462 0xf10000d7,
1463 0xb98000d3,
1464 0xb7f102dc,
1465 0xb3f02710,
1466 0xa421f400,
1467 0xf402eeb9,
1468 0xddb90421,
1469 0x949dff02,
1470 0x700150b6,
1471 0x1ef40456,
1472 0xcc7aa092,
1473 0x00a9800b,
1474 0xb60160b6,
1475 0x66700470,
1476 0x001ef510,
1477 0xb650fcff,
1478 0x56700150,
1479 0xd41ef507,
1480/* 0x07cf: memx_exec */
1481 0xf900f8fe,
1482 0xb9d0f9e0,
1483 0xb2b902c1,
1484/* 0x07d9: memx_exec_next */
1485 0x00139802,
1486 0xe70410b6,
1487 0xe701f034,
1488 0xb601e033,
1489 0x30f00132,
1490 0xde35980c,
1491 0x12b855f9,
1492 0xe41ef406,
1493 0x98f10b98,
1494 0xcbbbf20c,
1495 0xc4b7f102,
1496 0x06b4b607,
1497 0xfc00bbcf,
1498 0xf5e0fcd0,
1499 0xf8034221,
1500/* 0x0815: memx_info */
1501 0x01c67000,
1502/* 0x081b: memx_info_data */
1503 0xf10e0bf4,
1504 0xf103ccc7,
1505 0xf40800b7,
1506/* 0x0826: memx_info_train */
1507 0xc7f10b0e,
1508 0xb7f10bcc,
1509/* 0x082e: memx_info_send */
1510 0x21f50100,
1345 0x00f80342, 1511 0x00f80342,
1346/* 0x06c4: memx_info */ 1512/* 0x0834: memx_recv */
1347 0x03c0c7f1, 1513 0xf401d6b0,
1348 0x0800b7f1, 1514 0xd6b0980b,
1349 0x034221f5, 1515 0xd80bf400,
1350/* 0x06d2: memx_recv */ 1516/* 0x0842: memx_init */
1351 0xd6b000f8, 1517 0x00f800f8,
1352 0xa90bf401, 1518/* 0x0844: perf_recv */
1353 0xf400d6b0, 1519/* 0x0846: perf_init */
1354 0x00f8e90b,
1355/* 0x06e0: memx_init */
1356/* 0x06e2: perf_recv */
1357 0x00f800f8, 1520 0x00f800f8,
1358/* 0x06e4: perf_init */ 1521/* 0x0848: i2c_drive_scl */
1359/* 0x06e6: i2c_drive_scl */ 1522 0xf40036b0,
1523 0x07f1110b,
1524 0x04b607e0,
1525 0x0001d006,
1526 0x00f804bd,
1527/* 0x085c: i2c_drive_scl_lo */
1528 0x07e407f1,
1529 0xd00604b6,
1530 0x04bd0001,
1531/* 0x086a: i2c_drive_sda */
1360 0x36b000f8, 1532 0x36b000f8,
1361 0x110bf400, 1533 0x110bf400,
1362 0x07e007f1, 1534 0x07e007f1,
1363 0xd00604b6, 1535 0xd00604b6,
1364 0x04bd0001, 1536 0x04bd0002,
1365/* 0x06fa: i2c_drive_scl_lo */ 1537/* 0x087e: i2c_drive_sda_lo */
1366 0x07f100f8, 1538 0x07f100f8,
1367 0x04b607e4, 1539 0x04b607e4,
1368 0x0001d006,
1369 0x00f804bd,
1370/* 0x0708: i2c_drive_sda */
1371 0xf40036b0,
1372 0x07f1110b,
1373 0x04b607e0,
1374 0x0002d006, 1540 0x0002d006,
1375 0x00f804bd, 1541 0x00f804bd,
1376/* 0x071c: i2c_drive_sda_lo */ 1542/* 0x088c: i2c_sense_scl */
1377 0x07e407f1, 1543 0xf10132f4,
1378 0xd00604b6, 1544 0xb607c437,
1379 0x04bd0002, 1545 0x33cf0634,
1380/* 0x072a: i2c_sense_scl */ 1546 0x0431fd00,
1381 0x32f400f8, 1547 0xf4060bf4,
1382 0xc437f101, 1548/* 0x08a2: i2c_sense_scl_done */
1383 0x0634b607, 1549 0x00f80131,
1384 0xfd0033cf, 1550/* 0x08a4: i2c_sense_sda */
1385 0x0bf40431, 1551 0xf10132f4,
1386 0x0131f406, 1552 0xb607c437,
1387/* 0x0740: i2c_sense_scl_done */ 1553 0x33cf0634,
1388/* 0x0742: i2c_sense_sda */ 1554 0x0432fd00,
1389 0x32f400f8, 1555 0xf4060bf4,
1390 0xc437f101, 1556/* 0x08ba: i2c_sense_sda_done */
1391 0x0634b607, 1557 0x00f80131,
1392 0xfd0033cf, 1558/* 0x08bc: i2c_raise_scl */
1393 0x0bf40432, 1559 0x47f140f9,
1394 0x0131f406, 1560 0x37f00898,
1395/* 0x0758: i2c_sense_sda_done */ 1561 0x4821f501,
1396/* 0x075a: i2c_raise_scl */ 1562/* 0x08c9: i2c_raise_scl_wait */
1397 0x40f900f8, 1563 0xe8e7f108,
1398 0x089847f1,
1399 0xf50137f0,
1400/* 0x0767: i2c_raise_scl_wait */
1401 0xf106e621,
1402 0xf403e8e7,
1403 0x21f57f21,
1404 0x01f4072a,
1405 0x0142b609,
1406/* 0x077b: i2c_raise_scl_done */
1407 0xfcef1bf4,
1408/* 0x077f: i2c_start */
1409 0xf500f840,
1410 0xf4072a21,
1411 0x21f50d11,
1412 0x11f40742,
1413 0x300ef406,
1414/* 0x0790: i2c_start_rep */
1415 0xf50037f0,
1416 0xf006e621,
1417 0x21f50137,
1418 0x76bb0708,
1419 0x0465b600,
1420 0x659450f9,
1421 0x0256bb04,
1422 0x75fd50bd,
1423 0xf550fc04,
1424 0xb6075a21,
1425 0x11f40464,
1426/* 0x07bd: i2c_start_send */
1427 0x0037f01f,
1428 0x070821f5,
1429 0x1388e7f1,
1430 0xf07f21f4,
1431 0x21f50037,
1432 0xe7f106e6,
1433 0x21f41388,
1434/* 0x07d9: i2c_start_out */
1435/* 0x07db: i2c_stop */
1436 0xf000f87f,
1437 0x21f50037,
1438 0x37f006e6,
1439 0x0821f500,
1440 0xe8e7f107,
1441 0x7f21f403, 1564 0x7f21f403,
1442 0xf50137f0, 1565 0x088c21f5,
1443 0xf106e621, 1566 0xb60901f4,
1444 0xf41388e7, 1567 0x1bf40142,
1445 0x37f07f21, 1568/* 0x08dd: i2c_raise_scl_done */
1446 0x0821f501, 1569 0xf840fcef,
1447 0x88e7f107, 1570/* 0x08e1: i2c_start */
1448 0x7f21f413, 1571 0x8c21f500,
1449/* 0x080e: i2c_bitw */ 1572 0x0d11f408,
1450 0x21f500f8, 1573 0x08a421f5,
1451 0xe7f10708, 1574 0xf40611f4,
1452 0x21f403e8, 1575/* 0x08f2: i2c_start_rep */
1453 0x0076bb7f, 1576 0x37f0300e,
1454 0xf90465b6, 1577 0x4821f500,
1455 0x04659450, 1578 0x0137f008,
1456 0xbd0256bb, 1579 0x086a21f5,
1457 0x0475fd50, 1580 0xb60076bb,
1458 0x21f550fc, 1581 0x50f90465,
1459 0x64b6075a, 1582 0xbb046594,
1460 0x1811f404, 1583 0x50bd0256,
1461 0x1388e7f1, 1584 0xfc0475fd,
1462 0xf07f21f4, 1585 0xbc21f550,
1586 0x0464b608,
1587/* 0x091f: i2c_start_send */
1588 0xf01f11f4,
1463 0x21f50037, 1589 0x21f50037,
1464 0xe7f106e6, 1590 0xe7f1086a,
1465 0x21f41388, 1591 0x21f41388,
1466/* 0x084d: i2c_bitw_out */ 1592 0x0037f07f,
1467/* 0x084f: i2c_bitr */ 1593 0x084821f5,
1468 0xf000f87f, 1594 0x1388e7f1,
1469 0x21f50137, 1595/* 0x093b: i2c_start_out */
1470 0xe7f10708, 1596 0xf87f21f4,
1471 0x21f403e8, 1597/* 0x093d: i2c_stop */
1472 0x0076bb7f, 1598 0x0037f000,
1473 0xf90465b6, 1599 0x084821f5,
1474 0x04659450,
1475 0xbd0256bb,
1476 0x0475fd50,
1477 0x21f550fc,
1478 0x64b6075a,
1479 0x1b11f404,
1480 0x074221f5,
1481 0xf50037f0, 1600 0xf50037f0,
1482 0xf106e621, 1601 0xf1086a21,
1602 0xf403e8e7,
1603 0x37f07f21,
1604 0x4821f501,
1605 0x88e7f108,
1606 0x7f21f413,
1607 0xf50137f0,
1608 0xf1086a21,
1483 0xf41388e7, 1609 0xf41388e7,
1484 0x3cf07f21, 1610 0x00f87f21,
1485 0x0131f401, 1611/* 0x0970: i2c_bitw */
1486/* 0x0894: i2c_bitr_done */ 1612 0x086a21f5,
1487/* 0x0896: i2c_get_byte */ 1613 0x03e8e7f1,
1488 0x57f000f8, 1614 0xbb7f21f4,
1489 0x0847f000,
1490/* 0x089c: i2c_get_byte_next */
1491 0xbb0154b6,
1492 0x65b60076, 1615 0x65b60076,
1493 0x9450f904, 1616 0x9450f904,
1494 0x56bb0465, 1617 0x56bb0465,
1495 0xfd50bd02, 1618 0xfd50bd02,
1496 0x50fc0475, 1619 0x50fc0475,
1497 0x084f21f5, 1620 0x08bc21f5,
1498 0xf40464b6, 1621 0xf40464b6,
1499 0x53fd2b11, 1622 0xe7f11811,
1500 0x0142b605, 1623 0x21f41388,
1501 0xf0d81bf4, 1624 0x0037f07f,
1502 0x76bb0137, 1625 0x084821f5,
1503 0x0465b600, 1626 0x1388e7f1,
1504 0x659450f9, 1627/* 0x09af: i2c_bitw_out */
1505 0x0256bb04, 1628 0xf87f21f4,
1506 0x75fd50bd, 1629/* 0x09b1: i2c_bitr */
1507 0xf550fc04, 1630 0x0137f000,
1508 0xb6080e21, 1631 0x086a21f5,
1509/* 0x08e6: i2c_get_byte_done */ 1632 0x03e8e7f1,
1510 0x00f80464, 1633 0xbb7f21f4,
1511/* 0x08e8: i2c_put_byte */ 1634 0x65b60076,
1512/* 0x08eb: i2c_put_byte_next */ 1635 0x9450f904,
1513 0xb60847f0, 1636 0x56bb0465,
1514 0x54ff0142, 1637 0xfd50bd02,
1515 0x0076bb38, 1638 0x50fc0475,
1639 0x08bc21f5,
1640 0xf40464b6,
1641 0x21f51b11,
1642 0x37f008a4,
1643 0x4821f500,
1644 0x88e7f108,
1645 0x7f21f413,
1646 0xf4013cf0,
1647/* 0x09f6: i2c_bitr_done */
1648 0x00f80131,
1649/* 0x09f8: i2c_get_byte */
1650 0xf00057f0,
1651/* 0x09fe: i2c_get_byte_next */
1652 0x54b60847,
1653 0x0076bb01,
1516 0xf90465b6, 1654 0xf90465b6,
1517 0x04659450, 1655 0x04659450,
1518 0xbd0256bb, 1656 0xbd0256bb,
1519 0x0475fd50, 1657 0x0475fd50,
1520 0x21f550fc, 1658 0x21f550fc,
1521 0x64b6080e, 1659 0x64b609b1,
1522 0x3411f404, 1660 0x2b11f404,
1523 0xf40046b0, 1661 0xb60553fd,
1524 0x76bbd81b, 1662 0x1bf40142,
1525 0x0465b600, 1663 0x0137f0d8,
1526 0x659450f9, 1664 0xb60076bb,
1527 0x0256bb04, 1665 0x50f90465,
1528 0x75fd50bd, 1666 0xbb046594,
1529 0xf550fc04, 1667 0x50bd0256,
1530 0xb6084f21, 1668 0xfc0475fd,
1531 0x11f40464, 1669 0x7021f550,
1532 0x0076bb0f, 1670 0x0464b609,
1533 0xf40136b0, 1671/* 0x0a48: i2c_get_byte_done */
1534 0x32f4061b, 1672/* 0x0a4a: i2c_put_byte */
1535/* 0x0941: i2c_put_byte_done */ 1673 0x47f000f8,
1536/* 0x0943: i2c_addr */ 1674/* 0x0a4d: i2c_put_byte_next */
1537 0xbb00f801, 1675 0x0142b608,
1676 0xbb3854ff,
1538 0x65b60076, 1677 0x65b60076,
1539 0x9450f904, 1678 0x9450f904,
1540 0x56bb0465, 1679 0x56bb0465,
1541 0xfd50bd02, 1680 0xfd50bd02,
1542 0x50fc0475, 1681 0x50fc0475,
1543 0x077f21f5, 1682 0x097021f5,
1544 0xf40464b6, 1683 0xf40464b6,
1545 0xc3e72911, 1684 0x46b03411,
1546 0x34b6012e, 1685 0xd81bf400,
1547 0x0553fd01,
1548 0xb60076bb, 1686 0xb60076bb,
1549 0x50f90465, 1687 0x50f90465,
1550 0xbb046594, 1688 0xbb046594,
1551 0x50bd0256, 1689 0x50bd0256,
1552 0xfc0475fd, 1690 0xfc0475fd,
1553 0xe821f550, 1691 0xb121f550,
1554 0x0464b608, 1692 0x0464b609,
1555/* 0x0988: i2c_addr_done */ 1693 0xbb0f11f4,
1556/* 0x098a: i2c_acquire_addr */ 1694 0x36b00076,
1557 0xcec700f8, 1695 0x061bf401,
1558 0x02e4b6f8, 1696/* 0x0aa3: i2c_put_byte_done */
1559 0x0c10e0b7, 1697 0xf80132f4,
1560 0xf800ee98, 1698/* 0x0aa5: i2c_addr */
1561/* 0x0999: i2c_acquire */
1562 0x8a21f500,
1563 0x0421f409,
1564 0xf403d9f0,
1565 0x00f83f21,
1566/* 0x09a8: i2c_release */
1567 0x098a21f5,
1568 0xf00421f4,
1569 0x21f403da,
1570/* 0x09b7: i2c_recv */
1571 0xf400f83f,
1572 0xc1c70132,
1573 0x0214b6f8,
1574 0xf52816b0,
1575 0xa0013a1f,
1576 0x980be813,
1577 0x13a00032,
1578 0x31980bc0,
1579 0x0231f400,
1580 0xe0f9d0f9,
1581 0x67f1d0f9,
1582 0x63f10000,
1583 0x67921000,
1584 0x0076bb01,
1585 0xf90465b6,
1586 0x04659450,
1587 0xbd0256bb,
1588 0x0475fd50,
1589 0x21f550fc,
1590 0x64b60999,
1591 0xb0d0fc04,
1592 0x1bf500d6,
1593 0x57f000b3,
1594 0x0076bb00, 1699 0x0076bb00,
1595 0xf90465b6, 1700 0xf90465b6,
1596 0x04659450, 1701 0x04659450,
1597 0xbd0256bb, 1702 0xbd0256bb,
1598 0x0475fd50, 1703 0x0475fd50,
1599 0x21f550fc, 1704 0x21f550fc,
1600 0x64b60943, 1705 0x64b608e1,
1601 0xd011f504, 1706 0x2911f404,
1602 0xe0c5c700, 1707 0x012ec3e7,
1603 0xb60076bb, 1708 0xfd0134b6,
1604 0x50f90465, 1709 0x76bb0553,
1605 0xbb046594, 1710 0x0465b600,
1606 0x50bd0256, 1711 0x659450f9,
1607 0xfc0475fd, 1712 0x0256bb04,
1608 0xe821f550, 1713 0x75fd50bd,
1609 0x0464b608, 1714 0xf550fc04,
1610 0x00ad11f5, 1715 0xb60a4a21,
1611 0xbb0157f0, 1716/* 0x0aea: i2c_addr_done */
1717 0x00f80464,
1718/* 0x0aec: i2c_acquire_addr */
1719 0xb6f8cec7,
1720 0xe0b702e4,
1721 0xee980d1c,
1722/* 0x0afb: i2c_acquire */
1723 0xf500f800,
1724 0xf40aec21,
1725 0xd9f00421,
1726 0x3f21f403,
1727/* 0x0b0a: i2c_release */
1728 0x21f500f8,
1729 0x21f40aec,
1730 0x03daf004,
1731 0xf83f21f4,
1732/* 0x0b19: i2c_recv */
1733 0x0132f400,
1734 0xb6f8c1c7,
1735 0x16b00214,
1736 0x3a1ff528,
1737 0xf413a001,
1738 0x0032980c,
1739 0x0ccc13a0,
1740 0xf4003198,
1741 0xd0f90231,
1742 0xd0f9e0f9,
1743 0x000067f1,
1744 0x100063f1,
1745 0xbb016792,
1612 0x65b60076, 1746 0x65b60076,
1613 0x9450f904, 1747 0x9450f904,
1614 0x56bb0465, 1748 0x56bb0465,
1615 0xfd50bd02, 1749 0xfd50bd02,
1616 0x50fc0475, 1750 0x50fc0475,
1617 0x094321f5, 1751 0x0afb21f5,
1618 0xf50464b6, 1752 0xfc0464b6,
1619 0xbb008a11, 1753 0x00d6b0d0,
1754 0x00b31bf5,
1755 0xbb0057f0,
1620 0x65b60076, 1756 0x65b60076,
1621 0x9450f904, 1757 0x9450f904,
1622 0x56bb0465, 1758 0x56bb0465,
1623 0xfd50bd02, 1759 0xfd50bd02,
1624 0x50fc0475, 1760 0x50fc0475,
1625 0x089621f5, 1761 0x0aa521f5,
1626 0xf40464b6, 1762 0xf50464b6,
1627 0x5bcb6a11, 1763 0xc700d011,
1628 0x0076bbe0, 1764 0x76bbe0c5,
1765 0x0465b600,
1766 0x659450f9,
1767 0x0256bb04,
1768 0x75fd50bd,
1769 0xf550fc04,
1770 0xb60a4a21,
1771 0x11f50464,
1772 0x57f000ad,
1773 0x0076bb01,
1629 0xf90465b6, 1774 0xf90465b6,
1630 0x04659450, 1775 0x04659450,
1631 0xbd0256bb, 1776 0xbd0256bb,
1632 0x0475fd50, 1777 0x0475fd50,
1633 0x21f550fc, 1778 0x21f550fc,
1634 0x64b607db, 1779 0x64b60aa5,
1635 0x025bb904, 1780 0x8a11f504,
1636 0x0ef474bd, 1781 0x0076bb00,
1637/* 0x0abd: i2c_recv_not_rd08 */ 1782 0xf90465b6,
1638 0x01d6b043, 1783 0x04659450,
1639 0xf03d1bf4, 1784 0xbd0256bb,
1640 0x21f50057, 1785 0x0475fd50,
1641 0x11f40943, 1786 0x21f550fc,
1642 0xe0c5c733, 1787 0x64b609f8,
1643 0x08e821f5, 1788 0x6a11f404,
1644 0xf02911f4, 1789 0xbbe05bcb,
1645 0x21f50057, 1790 0x65b60076,
1646 0x11f40943, 1791 0x9450f904,
1647 0xe0b5c71f, 1792 0x56bb0465,
1648 0x08e821f5, 1793 0xfd50bd02,
1649 0xf51511f4, 1794 0x50fc0475,
1650 0xbd07db21, 1795 0x093d21f5,
1651 0x08c5c774, 1796 0xb90464b6,
1652 0xf4091bf4, 1797 0x74bd025b,
1653 0x0ef40232, 1798/* 0x0c1f: i2c_recv_not_rd08 */
1654/* 0x0afd: i2c_recv_not_wr08 */ 1799 0xb0430ef4,
1655/* 0x0afd: i2c_recv_done */ 1800 0x1bf401d6,
1656 0xf8cec703, 1801 0x0057f03d,
1657 0x09a821f5, 1802 0x0aa521f5,
1658 0xd0fce0fc, 1803 0xc73311f4,
1659 0xb90a12f4, 1804 0x21f5e0c5,
1660 0x21f5027c, 1805 0x11f40a4a,
1661/* 0x0b12: i2c_recv_exit */ 1806 0x0057f029,
1662 0x00f80342, 1807 0x0aa521f5,
1663/* 0x0b14: i2c_init */ 1808 0xc71f11f4,
1664/* 0x0b16: test_recv */ 1809 0x21f5e0b5,
1665 0x17f100f8, 1810 0x11f40a4a,
1666 0x14b605d8, 1811 0x3d21f515,
1667 0x0011cf06, 1812 0xc774bd09,
1668 0xf10110b6, 1813 0x1bf408c5,
1669 0xb605d807, 1814 0x0232f409,
1670 0x01d00604, 1815/* 0x0c5f: i2c_recv_not_wr08 */
1671 0xf104bd00, 1816/* 0x0c5f: i2c_recv_done */
1672 0xf1d900e7, 1817 0xc7030ef4,
1673 0xf5134fe3, 1818 0x21f5f8ce,
1674 0xf8026221, 1819 0xe0fc0b0a,
1675/* 0x0b3d: test_init */ 1820 0x12f4d0fc,
1676 0x00e7f100, 1821 0x027cb90a,
1677 0x6221f508, 1822 0x034221f5,
1678/* 0x0b47: idle_recv */ 1823/* 0x0c74: i2c_recv_exit */
1679 0xf800f802, 1824/* 0x0c76: i2c_init */
1680/* 0x0b49: idle */ 1825 0x00f800f8,
1681 0x0031f400, 1826/* 0x0c78: test_recv */
1682 0x05d417f1, 1827 0x05d817f1,
1683 0xcf0614b6, 1828 0xcf0614b6,
1684 0x10b60011, 1829 0x10b60011,
1685 0xd407f101, 1830 0xd807f101,
1686 0x0604b605, 1831 0x0604b605,
1687 0xbd0001d0, 1832 0xbd0001d0,
1688/* 0x0b65: idle_loop */ 1833 0x00e7f104,
1689 0x5817f004, 1834 0x4fe3f1d9,
1690/* 0x0b6b: idle_proc */ 1835 0x6221f513,
1691/* 0x0b6b: idle_proc_exec */ 1836/* 0x0c9f: test_init */
1692 0xf90232f4, 1837 0xf100f802,
1693 0x021eb910, 1838 0xf50800e7,
1694 0x034b21f5, 1839 0xf8026221,
1695 0x11f410fc, 1840/* 0x0ca9: idle_recv */
1696 0x0231f409, 1841/* 0x0cab: idle */
1697/* 0x0b7f: idle_proc_next */ 1842 0xf400f800,
1698 0xb6ef0ef4, 1843 0x17f10031,
1699 0x1fb85810, 1844 0x14b605d4,
1700 0xe61bf406, 1845 0x0011cf06,
1701 0xf4dd02f4, 1846 0xf10110b6,
1702 0x0ef40028, 1847 0xb605d407,
1703 0x000000bb, 1848 0x01d00604,
1704 0x00000000, 1849/* 0x0cc7: idle_loop */
1705 0x00000000, 1850 0xf004bd00,
1706 0x00000000, 1851 0x32f45817,
1707 0x00000000, 1852/* 0x0ccd: idle_proc */
1708 0x00000000, 1853/* 0x0ccd: idle_proc_exec */
1709 0x00000000, 1854 0xb910f902,
1710 0x00000000, 1855 0x21f5021e,
1711 0x00000000, 1856 0x10fc034b,
1712 0x00000000, 1857 0xf40911f4,
1713 0x00000000, 1858 0x0ef40231,
1714 0x00000000, 1859/* 0x0ce1: idle_proc_next */
1715 0x00000000, 1860 0x5810b6ef,
1716 0x00000000, 1861 0xf4061fb8,
1717 0x00000000, 1862 0x02f4e61b,
1718 0x00000000, 1863 0x0028f4dd,
1719 0x00000000, 1864 0x00bb0ef4,
1720 0x00000000,
1721 0x00000000,
1722 0x00000000,
1723 0x00000000,
1724 0x00000000,
1725 0x00000000,
1726 0x00000000,
1727 0x00000000,
1728 0x00000000, 1865 0x00000000,
1729 0x00000000, 1866 0x00000000,
1730 0x00000000, 1867 0x00000000,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
index ca30fa4011b5..90221d973f84 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvc0.fuc.h
@@ -46,8 +46,8 @@ uint32_t nvc0_pwr_data[] = {
46 0x00000000, 46 0x00000000,
47 0x00000000, 47 0x00000000,
48 0x584d454d, 48 0x584d454d,
49 0x0000074b, 49 0x0000075e,
50 0x0000073d, 50 0x00000750,
51 0x00000000, 51 0x00000000,
52 0x00000000, 52 0x00000000,
53 0x00000000, 53 0x00000000,
@@ -68,8 +68,8 @@ uint32_t nvc0_pwr_data[] = {
68 0x00000000, 68 0x00000000,
69 0x00000000, 69 0x00000000,
70 0x46524550, 70 0x46524550,
71 0x0000074f, 71 0x00000762,
72 0x0000074d, 72 0x00000760,
73 0x00000000, 73 0x00000000,
74 0x00000000, 74 0x00000000,
75 0x00000000, 75 0x00000000,
@@ -90,8 +90,8 @@ uint32_t nvc0_pwr_data[] = {
90 0x00000000, 90 0x00000000,
91 0x00000000, 91 0x00000000,
92 0x5f433249, 92 0x5f433249,
93 0x00000b7f, 93 0x00000b92,
94 0x00000a22, 94 0x00000a35,
95 0x00000000, 95 0x00000000,
96 0x00000000, 96 0x00000000,
97 0x00000000, 97 0x00000000,
@@ -112,8 +112,8 @@ uint32_t nvc0_pwr_data[] = {
112 0x00000000, 112 0x00000000,
113 0x00000000, 113 0x00000000,
114 0x54534554, 114 0x54534554,
115 0x00000ba8, 115 0x00000bbb,
116 0x00000b81, 116 0x00000b94,
117 0x00000000, 117 0x00000000,
118 0x00000000, 118 0x00000000,
119 0x00000000, 119 0x00000000,
@@ -134,8 +134,8 @@ uint32_t nvc0_pwr_data[] = {
134 0x00000000, 134 0x00000000,
135 0x00000000, 135 0x00000000,
136 0x454c4449, 136 0x454c4449,
137 0x00000bb4, 137 0x00000bc7,
138 0x00000bb2, 138 0x00000bc5,
139 0x00000000, 139 0x00000000,
140 0x00000000, 140 0x00000000,
141 0x00000000, 141 0x00000000,
@@ -246,13 +246,15 @@ uint32_t nvc0_pwr_data[] = {
246 0x00010006, 246 0x00010006,
247 0x00000000, 247 0x00000000,
248 0x00000663, 248 0x00000663,
249/* 0x03b8: memx_func_tail */ 249 0x00000007,
250/* 0x03b8: memx_ts_start */
251 0x00000000, 250 0x00000000,
252/* 0x03bc: memx_ts_end */ 251 0x000006e9,
252/* 0x03c4: memx_func_tail */
253/* 0x03c4: memx_ts_start */
253 0x00000000, 254 0x00000000,
254/* 0x03c0: memx_data_head */ 255/* 0x03c8: memx_ts_end */
255 0x00000000, 256 0x00000000,
257/* 0x03cc: memx_data_head */
256 0x00000000, 258 0x00000000,
257 0x00000000, 259 0x00000000,
258 0x00000000, 260 0x00000000,
@@ -764,8 +766,75 @@ uint32_t nvc0_pwr_data[] = {
764 0x00000000, 766 0x00000000,
765 0x00000000, 767 0x00000000,
766 0x00000000, 768 0x00000000,
767/* 0x0bc0: memx_data_tail */ 769 0x00000000,
768/* 0x0bc0: i2c_scl_map */ 770/* 0x0bcc: memx_data_tail */
771/* 0x0bcc: memx_train_head */
772 0x00000000,
773 0x00000000,
774 0x00000000,
775 0x00000000,
776 0x00000000,
777 0x00000000,
778 0x00000000,
779 0x00000000,
780 0x00000000,
781 0x00000000,
782 0x00000000,
783 0x00000000,
784 0x00000000,
785 0x00000000,
786 0x00000000,
787 0x00000000,
788 0x00000000,
789 0x00000000,
790 0x00000000,
791 0x00000000,
792 0x00000000,
793 0x00000000,
794 0x00000000,
795 0x00000000,
796 0x00000000,
797 0x00000000,
798 0x00000000,
799 0x00000000,
800 0x00000000,
801 0x00000000,
802 0x00000000,
803 0x00000000,
804 0x00000000,
805 0x00000000,
806 0x00000000,
807 0x00000000,
808 0x00000000,
809 0x00000000,
810 0x00000000,
811 0x00000000,
812 0x00000000,
813 0x00000000,
814 0x00000000,
815 0x00000000,
816 0x00000000,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836/* 0x0ccc: memx_train_tail */
837/* 0x0ccc: i2c_scl_map */
769 0x00001000, 838 0x00001000,
770 0x00004000, 839 0x00004000,
771 0x00010000, 840 0x00010000,
@@ -776,7 +845,7 @@ uint32_t nvc0_pwr_data[] = {
776 0x01000000, 845 0x01000000,
777 0x04000000, 846 0x04000000,
778 0x10000000, 847 0x10000000,
779/* 0x0be8: i2c_sda_map */ 848/* 0x0cf4: i2c_sda_map */
780 0x00002000, 849 0x00002000,
781 0x00008000, 850 0x00008000,
782 0x00020000, 851 0x00020000,
@@ -787,7 +856,7 @@ uint32_t nvc0_pwr_data[] = {
787 0x02000000, 856 0x02000000,
788 0x08000000, 857 0x08000000,
789 0x20000000, 858 0x20000000,
790/* 0x0c10: i2c_ctrl */ 859/* 0x0d1c: i2c_ctrl */
791 0x0000e138, 860 0x0000e138,
792 0x0000e150, 861 0x0000e150,
793 0x0000e168, 862 0x0000e168,
@@ -845,9 +914,6 @@ uint32_t nvc0_pwr_data[] = {
845 0x00000000, 914 0x00000000,
846 0x00000000, 915 0x00000000,
847 0x00000000, 916 0x00000000,
848 0x00000000,
849 0x00000000,
850 0x00000000,
851}; 917};
852 918
853uint32_t nvc0_pwr_code[] = { 919uint32_t nvc0_pwr_code[] = {
@@ -1272,10 +1338,10 @@ uint32_t nvc0_pwr_code[] = {
1272 0xcf0664b6, 1338 0xcf0664b6,
1273 0x06800066, 1339 0x06800066,
1274/* 0x05db: memx_func_leave */ 1340/* 0x05db: memx_func_leave */
1275 0xf000f8ee, 1341 0xf000f8f1,
1276 0x64b62c67, 1342 0x64b62c67,
1277 0x0066cf06, 1343 0x0066cf06,
1278 0xf0ef0680, 1344 0xf0f20680,
1279 0x07f10467, 1345 0x07f10467,
1280 0x04b607e4, 1346 0x04b607e4,
1281 0x0006d006, 1347 0x0006d006,
@@ -1350,382 +1416,450 @@ uint32_t nvc0_pwr_code[] = {
1350 0x1e9800f8, 1416 0x1e9800f8,
1351 0x0410b600, 1417 0x0410b600,
1352 0xf87f21f4, 1418 0xf87f21f4,
1353/* 0x06e9: memx_exec */ 1419/* 0x06e9: memx_func_train */
1354 0xf9e0f900, 1420/* 0x06eb: memx_exec */
1355 0x02c1b9d0, 1421 0xf900f800,
1356/* 0x06f3: memx_exec_next */ 1422 0xb9d0f9e0,
1357 0x9802b2b9, 1423 0xb2b902c1,
1358 0x10b60013, 1424/* 0x06f5: memx_exec_next */
1359 0xf034e704, 1425 0x00139802,
1360 0xe033e701, 1426 0xe70410b6,
1361 0x0132b601, 1427 0xe701f034,
1362 0x980c30f0, 1428 0xb601e033,
1363 0x55f9de35, 1429 0x30f00132,
1364 0xf40612b8, 1430 0xde35980c,
1365 0x0b98e41e, 1431 0x12b855f9,
1366 0xef0c98ee, 1432 0xe41ef406,
1367 0xf102cbbb, 1433 0x98f10b98,
1368 0xb607c4b7, 1434 0xcbbbf20c,
1369 0xbbcf06b4, 1435 0xc4b7f102,
1370 0xfcd0fc00, 1436 0x06b4b607,
1371 0x4221f5e0, 1437 0xfc00bbcf,
1372/* 0x072f: memx_info */ 1438 0xf5e0fcd0,
1373 0xf100f803,
1374 0xf103c0c7,
1375 0xf50800b7,
1376 0xf8034221, 1439 0xf8034221,
1377/* 0x073d: memx_recv */ 1440/* 0x0731: memx_info */
1378 0x01d6b000, 1441 0x01c67000,
1379 0xb0a90bf4, 1442/* 0x0737: memx_info_data */
1380 0x0bf400d6, 1443 0xf10e0bf4,
1381/* 0x074b: memx_init */ 1444 0xf103ccc7,
1382 0xf800f8e9, 1445 0xf40800b7,
1383/* 0x074d: perf_recv */ 1446/* 0x0742: memx_info_train */
1384/* 0x074f: perf_init */ 1447 0xc7f10b0e,
1385 0xf800f800, 1448 0xb7f10bcc,
1386/* 0x0751: i2c_drive_scl */ 1449/* 0x074a: memx_info_send */
1387 0x0036b000, 1450 0x21f50100,
1388 0xf1110bf4, 1451 0x00f80342,
1389 0xb607e007, 1452/* 0x0750: memx_recv */
1390 0x01d00604, 1453 0xf401d6b0,
1391 0xf804bd00, 1454 0xd6b0980b,
1392/* 0x0765: i2c_drive_scl_lo */ 1455 0xd80bf400,
1393 0xe407f100, 1456/* 0x075e: memx_init */
1394 0x0604b607, 1457 0x00f800f8,
1395 0xbd0001d0, 1458/* 0x0760: perf_recv */
1396/* 0x0773: i2c_drive_sda */ 1459/* 0x0762: perf_init */
1397 0xb000f804, 1460 0x00f800f8,
1398 0x0bf40036, 1461/* 0x0764: i2c_drive_scl */
1399 0xe007f111, 1462 0xf40036b0,
1400 0x0604b607, 1463 0x07f1110b,
1401 0xbd0002d0, 1464 0x04b607e0,
1402/* 0x0787: i2c_drive_sda_lo */ 1465 0x0001d006,
1403 0xf100f804, 1466 0x00f804bd,
1404 0xb607e407, 1467/* 0x0778: i2c_drive_scl_lo */
1405 0x02d00604, 1468 0x07e407f1,
1406 0xf804bd00, 1469 0xd00604b6,
1407/* 0x0795: i2c_sense_scl */ 1470 0x04bd0001,
1408 0x0132f400, 1471/* 0x0786: i2c_drive_sda */
1409 0x07c437f1, 1472 0x36b000f8,
1410 0xcf0634b6, 1473 0x110bf400,
1411 0x31fd0033, 1474 0x07e007f1,
1412 0x060bf404, 1475 0xd00604b6,
1413/* 0x07ab: i2c_sense_scl_done */ 1476 0x04bd0002,
1414 0xf80131f4, 1477/* 0x079a: i2c_drive_sda_lo */
1415/* 0x07ad: i2c_sense_sda */ 1478 0x07f100f8,
1416 0x0132f400, 1479 0x04b607e4,
1417 0x07c437f1, 1480 0x0002d006,
1418 0xcf0634b6, 1481 0x00f804bd,
1419 0x32fd0033, 1482/* 0x07a8: i2c_sense_scl */
1420 0x060bf404, 1483 0xf10132f4,
1421/* 0x07c3: i2c_sense_sda_done */ 1484 0xb607c437,
1422 0xf80131f4, 1485 0x33cf0634,
1423/* 0x07c5: i2c_raise_scl */ 1486 0x0431fd00,
1424 0xf140f900, 1487 0xf4060bf4,
1425 0xf0089847, 1488/* 0x07be: i2c_sense_scl_done */
1426 0x21f50137, 1489 0x00f80131,
1427/* 0x07d2: i2c_raise_scl_wait */ 1490/* 0x07c0: i2c_sense_sda */
1428 0xe7f10751, 1491 0xf10132f4,
1429 0x21f403e8, 1492 0xb607c437,
1430 0x9521f57f, 1493 0x33cf0634,
1431 0x0901f407, 1494 0x0432fd00,
1432 0xf40142b6, 1495 0xf4060bf4,
1433/* 0x07e6: i2c_raise_scl_done */ 1496/* 0x07d6: i2c_sense_sda_done */
1434 0x40fcef1b, 1497 0x00f80131,
1435/* 0x07ea: i2c_start */ 1498/* 0x07d8: i2c_raise_scl */
1436 0x21f500f8, 1499 0x47f140f9,
1437 0x11f40795, 1500 0x37f00898,
1438 0xad21f50d, 1501 0x6421f501,
1439 0x0611f407, 1502/* 0x07e5: i2c_raise_scl_wait */
1440/* 0x07fb: i2c_start_rep */
1441 0xf0300ef4,
1442 0x21f50037,
1443 0x37f00751,
1444 0x7321f501,
1445 0x0076bb07,
1446 0xf90465b6,
1447 0x04659450,
1448 0xbd0256bb,
1449 0x0475fd50,
1450 0x21f550fc,
1451 0x64b607c5,
1452 0x1f11f404,
1453/* 0x0828: i2c_start_send */
1454 0xf50037f0,
1455 0xf1077321,
1456 0xf41388e7,
1457 0x37f07f21,
1458 0x5121f500,
1459 0x88e7f107,
1460 0x7f21f413,
1461/* 0x0844: i2c_start_out */
1462/* 0x0846: i2c_stop */
1463 0x37f000f8,
1464 0x5121f500,
1465 0x0037f007,
1466 0x077321f5,
1467 0x03e8e7f1,
1468 0xf07f21f4,
1469 0x21f50137,
1470 0xe7f10751,
1471 0x21f41388,
1472 0x0137f07f,
1473 0x077321f5,
1474 0x1388e7f1,
1475 0xf87f21f4,
1476/* 0x0879: i2c_bitw */
1477 0x7321f500,
1478 0xe8e7f107, 1503 0xe8e7f107,
1479 0x7f21f403, 1504 0x7f21f403,
1505 0x07a821f5,
1506 0xb60901f4,
1507 0x1bf40142,
1508/* 0x07f9: i2c_raise_scl_done */
1509 0xf840fcef,
1510/* 0x07fd: i2c_start */
1511 0xa821f500,
1512 0x0d11f407,
1513 0x07c021f5,
1514 0xf40611f4,
1515/* 0x080e: i2c_start_rep */
1516 0x37f0300e,
1517 0x6421f500,
1518 0x0137f007,
1519 0x078621f5,
1480 0xb60076bb, 1520 0xb60076bb,
1481 0x50f90465, 1521 0x50f90465,
1482 0xbb046594, 1522 0xbb046594,
1483 0x50bd0256, 1523 0x50bd0256,
1484 0xfc0475fd, 1524 0xfc0475fd,
1485 0xc521f550, 1525 0xd821f550,
1486 0x0464b607, 1526 0x0464b607,
1487 0xf11811f4, 1527/* 0x083b: i2c_start_send */
1488 0xf41388e7, 1528 0xf01f11f4,
1529 0x21f50037,
1530 0xe7f10786,
1531 0x21f41388,
1532 0x0037f07f,
1533 0x076421f5,
1534 0x1388e7f1,
1535/* 0x0857: i2c_start_out */
1536 0xf87f21f4,
1537/* 0x0859: i2c_stop */
1538 0x0037f000,
1539 0x076421f5,
1540 0xf50037f0,
1541 0xf1078621,
1542 0xf403e8e7,
1489 0x37f07f21, 1543 0x37f07f21,
1490 0x5121f500, 1544 0x6421f501,
1491 0x88e7f107, 1545 0x88e7f107,
1492 0x7f21f413, 1546 0x7f21f413,
1493/* 0x08b8: i2c_bitw_out */ 1547 0xf50137f0,
1494/* 0x08ba: i2c_bitr */ 1548 0xf1078621,
1495 0x37f000f8, 1549 0xf41388e7,
1496 0x7321f501, 1550 0x00f87f21,
1497 0xe8e7f107, 1551/* 0x088c: i2c_bitw */
1498 0x7f21f403, 1552 0x078621f5,
1499 0xb60076bb, 1553 0x03e8e7f1,
1500 0x50f90465, 1554 0xbb7f21f4,
1501 0xbb046594, 1555 0x65b60076,
1502 0x50bd0256, 1556 0x9450f904,
1503 0xfc0475fd, 1557 0x56bb0465,
1504 0xc521f550, 1558 0xfd50bd02,
1505 0x0464b607, 1559 0x50fc0475,
1506 0xf51b11f4, 1560 0x07d821f5,
1507 0xf007ad21, 1561 0xf40464b6,
1508 0x21f50037, 1562 0xe7f11811,
1509 0xe7f10751,
1510 0x21f41388, 1563 0x21f41388,
1511 0x013cf07f, 1564 0x0037f07f,
1512/* 0x08ff: i2c_bitr_done */ 1565 0x076421f5,
1513 0xf80131f4, 1566 0x1388e7f1,
1514/* 0x0901: i2c_get_byte */ 1567/* 0x08cb: i2c_bitw_out */
1515 0x0057f000, 1568 0xf87f21f4,
1516/* 0x0907: i2c_get_byte_next */ 1569/* 0x08cd: i2c_bitr */
1517 0xb60847f0, 1570 0x0137f000,
1518 0x76bb0154, 1571 0x078621f5,
1519 0x0465b600, 1572 0x03e8e7f1,
1520 0x659450f9, 1573 0xbb7f21f4,
1521 0x0256bb04, 1574 0x65b60076,
1522 0x75fd50bd, 1575 0x9450f904,
1523 0xf550fc04, 1576 0x56bb0465,
1524 0xb608ba21, 1577 0xfd50bd02,
1525 0x11f40464, 1578 0x50fc0475,
1526 0x0553fd2b, 1579 0x07d821f5,
1527 0xf40142b6, 1580 0xf40464b6,
1528 0x37f0d81b, 1581 0x21f51b11,
1582 0x37f007c0,
1583 0x6421f500,
1584 0x88e7f107,
1585 0x7f21f413,
1586 0xf4013cf0,
1587/* 0x0912: i2c_bitr_done */
1588 0x00f80131,
1589/* 0x0914: i2c_get_byte */
1590 0xf00057f0,
1591/* 0x091a: i2c_get_byte_next */
1592 0x54b60847,
1529 0x0076bb01, 1593 0x0076bb01,
1530 0xf90465b6, 1594 0xf90465b6,
1531 0x04659450, 1595 0x04659450,
1532 0xbd0256bb, 1596 0xbd0256bb,
1533 0x0475fd50, 1597 0x0475fd50,
1534 0x21f550fc, 1598 0x21f550fc,
1535 0x64b60879, 1599 0x64b608cd,
1536/* 0x0951: i2c_get_byte_done */ 1600 0x2b11f404,
1537/* 0x0953: i2c_put_byte */ 1601 0xb60553fd,
1538 0xf000f804, 1602 0x1bf40142,
1539/* 0x0956: i2c_put_byte_next */ 1603 0x0137f0d8,
1540 0x42b60847,
1541 0x3854ff01,
1542 0xb60076bb, 1604 0xb60076bb,
1543 0x50f90465, 1605 0x50f90465,
1544 0xbb046594, 1606 0xbb046594,
1545 0x50bd0256, 1607 0x50bd0256,
1546 0xfc0475fd, 1608 0xfc0475fd,
1547 0x7921f550, 1609 0x8c21f550,
1548 0x0464b608, 1610 0x0464b608,
1549 0xb03411f4, 1611/* 0x0964: i2c_get_byte_done */
1550 0x1bf40046, 1612/* 0x0966: i2c_put_byte */
1551 0x0076bbd8, 1613 0x47f000f8,
1614/* 0x0969: i2c_put_byte_next */
1615 0x0142b608,
1616 0xbb3854ff,
1617 0x65b60076,
1618 0x9450f904,
1619 0x56bb0465,
1620 0xfd50bd02,
1621 0x50fc0475,
1622 0x088c21f5,
1623 0xf40464b6,
1624 0x46b03411,
1625 0xd81bf400,
1626 0xb60076bb,
1627 0x50f90465,
1628 0xbb046594,
1629 0x50bd0256,
1630 0xfc0475fd,
1631 0xcd21f550,
1632 0x0464b608,
1633 0xbb0f11f4,
1634 0x36b00076,
1635 0x061bf401,
1636/* 0x09bf: i2c_put_byte_done */
1637 0xf80132f4,
1638/* 0x09c1: i2c_addr */
1639 0x0076bb00,
1552 0xf90465b6, 1640 0xf90465b6,
1553 0x04659450, 1641 0x04659450,
1554 0xbd0256bb, 1642 0xbd0256bb,
1555 0x0475fd50, 1643 0x0475fd50,
1556 0x21f550fc, 1644 0x21f550fc,
1557 0x64b608ba, 1645 0x64b607fd,
1558 0x0f11f404, 1646 0x2911f404,
1559 0xb00076bb, 1647 0x012ec3e7,
1560 0x1bf40136, 1648 0xfd0134b6,
1561 0x0132f406, 1649 0x76bb0553,
1562/* 0x09ac: i2c_put_byte_done */
1563/* 0x09ae: i2c_addr */
1564 0x76bb00f8,
1565 0x0465b600, 1650 0x0465b600,
1566 0x659450f9, 1651 0x659450f9,
1567 0x0256bb04, 1652 0x0256bb04,
1568 0x75fd50bd, 1653 0x75fd50bd,
1569 0xf550fc04, 1654 0xf550fc04,
1570 0xb607ea21, 1655 0xb6096621,
1571 0x11f40464, 1656/* 0x0a06: i2c_addr_done */
1572 0x2ec3e729, 1657 0x00f80464,
1573 0x0134b601, 1658/* 0x0a08: i2c_acquire_addr */
1574 0xbb0553fd, 1659 0xb6f8cec7,
1660 0xe0b702e4,
1661 0xee980d1c,
1662/* 0x0a17: i2c_acquire */
1663 0xf500f800,
1664 0xf40a0821,
1665 0xd9f00421,
1666 0x3f21f403,
1667/* 0x0a26: i2c_release */
1668 0x21f500f8,
1669 0x21f40a08,
1670 0x03daf004,
1671 0xf83f21f4,
1672/* 0x0a35: i2c_recv */
1673 0x0132f400,
1674 0xb6f8c1c7,
1675 0x16b00214,
1676 0x3a1ff528,
1677 0xf413a001,
1678 0x0032980c,
1679 0x0ccc13a0,
1680 0xf4003198,
1681 0xd0f90231,
1682 0xd0f9e0f9,
1683 0x000067f1,
1684 0x100063f1,
1685 0xbb016792,
1575 0x65b60076, 1686 0x65b60076,
1576 0x9450f904, 1687 0x9450f904,
1577 0x56bb0465, 1688 0x56bb0465,
1578 0xfd50bd02, 1689 0xfd50bd02,
1579 0x50fc0475, 1690 0x50fc0475,
1580 0x095321f5, 1691 0x0a1721f5,
1581/* 0x09f3: i2c_addr_done */ 1692 0xfc0464b6,
1582 0xf80464b6, 1693 0x00d6b0d0,
1583/* 0x09f5: i2c_acquire_addr */ 1694 0x00b31bf5,
1584 0xf8cec700, 1695 0xbb0057f0,
1585 0xb702e4b6,
1586 0x980c10e0,
1587 0x00f800ee,
1588/* 0x0a04: i2c_acquire */
1589 0x09f521f5,
1590 0xf00421f4,
1591 0x21f403d9,
1592/* 0x0a13: i2c_release */
1593 0xf500f83f,
1594 0xf409f521,
1595 0xdaf00421,
1596 0x3f21f403,
1597/* 0x0a22: i2c_recv */
1598 0x32f400f8,
1599 0xf8c1c701,
1600 0xb00214b6,
1601 0x1ff52816,
1602 0x13a0013a,
1603 0x32980be8,
1604 0xc013a000,
1605 0x0031980b,
1606 0xf90231f4,
1607 0xf9e0f9d0,
1608 0x0067f1d0,
1609 0x0063f100,
1610 0x01679210,
1611 0xb60076bb,
1612 0x50f90465,
1613 0xbb046594,
1614 0x50bd0256,
1615 0xfc0475fd,
1616 0x0421f550,
1617 0x0464b60a,
1618 0xd6b0d0fc,
1619 0xb31bf500,
1620 0x0057f000,
1621 0xb60076bb,
1622 0x50f90465,
1623 0xbb046594,
1624 0x50bd0256,
1625 0xfc0475fd,
1626 0xae21f550,
1627 0x0464b609,
1628 0x00d011f5,
1629 0xbbe0c5c7,
1630 0x65b60076, 1696 0x65b60076,
1631 0x9450f904, 1697 0x9450f904,
1632 0x56bb0465, 1698 0x56bb0465,
1633 0xfd50bd02, 1699 0xfd50bd02,
1634 0x50fc0475, 1700 0x50fc0475,
1635 0x095321f5, 1701 0x09c121f5,
1636 0xf50464b6, 1702 0xf50464b6,
1637 0xf000ad11, 1703 0xc700d011,
1638 0x76bb0157, 1704 0x76bbe0c5,
1639 0x0465b600, 1705 0x0465b600,
1640 0x659450f9, 1706 0x659450f9,
1641 0x0256bb04, 1707 0x0256bb04,
1642 0x75fd50bd, 1708 0x75fd50bd,
1643 0xf550fc04, 1709 0xf550fc04,
1644 0xb609ae21, 1710 0xb6096621,
1645 0x11f50464, 1711 0x11f50464,
1646 0x76bb008a, 1712 0x57f000ad,
1647 0x0465b600, 1713 0x0076bb01,
1648 0x659450f9, 1714 0xf90465b6,
1649 0x0256bb04, 1715 0x04659450,
1650 0x75fd50bd, 1716 0xbd0256bb,
1651 0xf550fc04, 1717 0x0475fd50,
1652 0xb6090121, 1718 0x21f550fc,
1653 0x11f40464, 1719 0x64b609c1,
1654 0xe05bcb6a, 1720 0x8a11f504,
1655 0xb60076bb, 1721 0x0076bb00,
1656 0x50f90465, 1722 0xf90465b6,
1657 0xbb046594, 1723 0x04659450,
1658 0x50bd0256, 1724 0xbd0256bb,
1659 0xfc0475fd, 1725 0x0475fd50,
1660 0x4621f550, 1726 0x21f550fc,
1661 0x0464b608, 1727 0x64b60914,
1662 0xbd025bb9, 1728 0x6a11f404,
1663 0x430ef474, 1729 0xbbe05bcb,
1664/* 0x0b28: i2c_recv_not_rd08 */ 1730 0x65b60076,
1665 0xf401d6b0, 1731 0x9450f904,
1666 0x57f03d1b, 1732 0x56bb0465,
1667 0xae21f500, 1733 0xfd50bd02,
1668 0x3311f409, 1734 0x50fc0475,
1669 0xf5e0c5c7, 1735 0x085921f5,
1670 0xf4095321, 1736 0xb90464b6,
1671 0x57f02911, 1737 0x74bd025b,
1672 0xae21f500, 1738/* 0x0b3b: i2c_recv_not_rd08 */
1673 0x1f11f409, 1739 0xb0430ef4,
1674 0xf5e0b5c7, 1740 0x1bf401d6,
1675 0xf4095321, 1741 0x0057f03d,
1676 0x21f51511, 1742 0x09c121f5,
1677 0x74bd0846, 1743 0xc73311f4,
1678 0xf408c5c7, 1744 0x21f5e0c5,
1679 0x32f4091b, 1745 0x11f40966,
1680 0x030ef402, 1746 0x0057f029,
1681/* 0x0b68: i2c_recv_not_wr08 */ 1747 0x09c121f5,
1682/* 0x0b68: i2c_recv_done */ 1748 0xc71f11f4,
1683 0xf5f8cec7, 1749 0x21f5e0b5,
1684 0xfc0a1321, 1750 0x11f40966,
1685 0xf4d0fce0, 1751 0x5921f515,
1686 0x7cb90a12, 1752 0xc774bd08,
1687 0x4221f502, 1753 0x1bf408c5,
1688/* 0x0b7d: i2c_recv_exit */ 1754 0x0232f409,
1689/* 0x0b7f: i2c_init */ 1755/* 0x0b7b: i2c_recv_not_wr08 */
1690 0xf800f803, 1756/* 0x0b7b: i2c_recv_done */
1691/* 0x0b81: test_recv */ 1757 0xc7030ef4,
1692 0xd817f100, 1758 0x21f5f8ce,
1693 0x0614b605, 1759 0xe0fc0a26,
1694 0xb60011cf, 1760 0x12f4d0fc,
1695 0x07f10110, 1761 0x027cb90a,
1696 0x04b605d8, 1762 0x034221f5,
1697 0x0001d006, 1763/* 0x0b90: i2c_recv_exit */
1698 0xe7f104bd, 1764/* 0x0b92: i2c_init */
1699 0xe3f1d900,
1700 0x21f5134f,
1701 0x00f80262,
1702/* 0x0ba8: test_init */
1703 0x0800e7f1,
1704 0x026221f5,
1705/* 0x0bb2: idle_recv */
1706 0x00f800f8, 1765 0x00f800f8,
1707/* 0x0bb4: idle */ 1766/* 0x0b94: test_recv */
1708 0xf10031f4, 1767 0x05d817f1,
1709 0xb605d417, 1768 0xcf0614b6,
1710 0x11cf0614, 1769 0x10b60011,
1711 0x0110b600, 1770 0xd807f101,
1712 0x05d407f1, 1771 0x0604b605,
1713 0xd00604b6, 1772 0xbd0001d0,
1714 0x04bd0001, 1773 0x00e7f104,
1715/* 0x0bd0: idle_loop */ 1774 0x4fe3f1d9,
1716 0xf45817f0, 1775 0x6221f513,
1717/* 0x0bd6: idle_proc */ 1776/* 0x0bbb: test_init */
1718/* 0x0bd6: idle_proc_exec */ 1777 0xf100f802,
1719 0x10f90232, 1778 0xf50800e7,
1720 0xf5021eb9, 1779 0xf8026221,
1721 0xfc034b21, 1780/* 0x0bc5: idle_recv */
1722 0x0911f410, 1781/* 0x0bc7: idle */
1723 0xf40231f4, 1782 0xf400f800,
1724/* 0x0bea: idle_proc_next */ 1783 0x17f10031,
1725 0x10b6ef0e, 1784 0x14b605d4,
1726 0x061fb858, 1785 0x0011cf06,
1727 0xf4e61bf4, 1786 0xf10110b6,
1728 0x28f4dd02, 1787 0xb605d407,
1729 0xbb0ef400, 1788 0x01d00604,
1789/* 0x0be3: idle_loop */
1790 0xf004bd00,
1791 0x32f45817,
1792/* 0x0be9: idle_proc */
1793/* 0x0be9: idle_proc_exec */
1794 0xb910f902,
1795 0x21f5021e,
1796 0x10fc034b,
1797 0xf40911f4,
1798 0x0ef40231,
1799/* 0x0bfd: idle_proc_next */
1800 0x5810b6ef,
1801 0xf4061fb8,
1802 0x02f4e61b,
1803 0x0028f4dd,
1804 0x00bb0ef4,
1805 0x00000000,
1806 0x00000000,
1807 0x00000000,
1808 0x00000000,
1809 0x00000000,
1810 0x00000000,
1811 0x00000000,
1812 0x00000000,
1813 0x00000000,
1814 0x00000000,
1815 0x00000000,
1816 0x00000000,
1817 0x00000000,
1818 0x00000000,
1819 0x00000000,
1820 0x00000000,
1821 0x00000000,
1822 0x00000000,
1823 0x00000000,
1824 0x00000000,
1825 0x00000000,
1826 0x00000000,
1827 0x00000000,
1828 0x00000000,
1829 0x00000000,
1830 0x00000000,
1831 0x00000000,
1832 0x00000000,
1833 0x00000000,
1834 0x00000000,
1835 0x00000000,
1836 0x00000000,
1837 0x00000000,
1838 0x00000000,
1839 0x00000000,
1840 0x00000000,
1841 0x00000000,
1842 0x00000000,
1843 0x00000000,
1844 0x00000000,
1845 0x00000000,
1846 0x00000000,
1847 0x00000000,
1848 0x00000000,
1849 0x00000000,
1850 0x00000000,
1851 0x00000000,
1852 0x00000000,
1853 0x00000000,
1854 0x00000000,
1855 0x00000000,
1856 0x00000000,
1857 0x00000000,
1858 0x00000000,
1859 0x00000000,
1860 0x00000000,
1861 0x00000000,
1862 0x00000000,
1863 0x00000000,
1730 0x00000000, 1864 0x00000000,
1731}; 1865};
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
index 12d86f72ad10..7e16aab44d85 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/nvd0.fuc.h
@@ -46,8 +46,8 @@ uint32_t nvd0_pwr_data[] = {
46 0x00000000, 46 0x00000000,
47 0x00000000, 47 0x00000000,
48 0x584d454d, 48 0x584d454d,
49 0x00000678, 49 0x0000068b,
50 0x0000066a, 50 0x0000067d,
51 0x00000000, 51 0x00000000,
52 0x00000000, 52 0x00000000,
53 0x00000000, 53 0x00000000,
@@ -68,8 +68,8 @@ uint32_t nvd0_pwr_data[] = {
68 0x00000000, 68 0x00000000,
69 0x00000000, 69 0x00000000,
70 0x46524550, 70 0x46524550,
71 0x0000067c, 71 0x0000068f,
72 0x0000067a, 72 0x0000068d,
73 0x00000000, 73 0x00000000,
74 0x00000000, 74 0x00000000,
75 0x00000000, 75 0x00000000,
@@ -90,8 +90,8 @@ uint32_t nvd0_pwr_data[] = {
90 0x00000000, 90 0x00000000,
91 0x00000000, 91 0x00000000,
92 0x5f433249, 92 0x5f433249,
93 0x00000a97, 93 0x00000aaa,
94 0x0000093a, 94 0x0000094d,
95 0x00000000, 95 0x00000000,
96 0x00000000, 96 0x00000000,
97 0x00000000, 97 0x00000000,
@@ -112,8 +112,8 @@ uint32_t nvd0_pwr_data[] = {
112 0x00000000, 112 0x00000000,
113 0x00000000, 113 0x00000000,
114 0x54534554, 114 0x54534554,
115 0x00000aba, 115 0x00000acd,
116 0x00000a99, 116 0x00000aac,
117 0x00000000, 117 0x00000000,
118 0x00000000, 118 0x00000000,
119 0x00000000, 119 0x00000000,
@@ -134,8 +134,8 @@ uint32_t nvd0_pwr_data[] = {
134 0x00000000, 134 0x00000000,
135 0x00000000, 135 0x00000000,
136 0x454c4449, 136 0x454c4449,
137 0x00000ac6, 137 0x00000ad9,
138 0x00000ac4, 138 0x00000ad7,
139 0x00000000, 139 0x00000000,
140 0x00000000, 140 0x00000000,
141 0x00000000, 141 0x00000000,
@@ -246,13 +246,15 @@ uint32_t nvd0_pwr_data[] = {
246 0x00010006, 246 0x00010006,
247 0x00000000, 247 0x00000000,
248 0x000005d3, 248 0x000005d3,
249/* 0x03b8: memx_func_tail */ 249 0x00000007,
250/* 0x03b8: memx_ts_start */
251 0x00000000, 250 0x00000000,
252/* 0x03bc: memx_ts_end */ 251 0x00000619,
252/* 0x03c4: memx_func_tail */
253/* 0x03c4: memx_ts_start */
253 0x00000000, 254 0x00000000,
254/* 0x03c0: memx_data_head */ 255/* 0x03c8: memx_ts_end */
255 0x00000000, 256 0x00000000,
257/* 0x03cc: memx_data_head */
256 0x00000000, 258 0x00000000,
257 0x00000000, 259 0x00000000,
258 0x00000000, 260 0x00000000,
@@ -764,8 +766,75 @@ uint32_t nvd0_pwr_data[] = {
764 0x00000000, 766 0x00000000,
765 0x00000000, 767 0x00000000,
766 0x00000000, 768 0x00000000,
767/* 0x0bc0: memx_data_tail */ 769 0x00000000,
768/* 0x0bc0: i2c_scl_map */ 770/* 0x0bcc: memx_data_tail */
771/* 0x0bcc: memx_train_head */
772 0x00000000,
773 0x00000000,
774 0x00000000,
775 0x00000000,
776 0x00000000,
777 0x00000000,
778 0x00000000,
779 0x00000000,
780 0x00000000,
781 0x00000000,
782 0x00000000,
783 0x00000000,
784 0x00000000,
785 0x00000000,
786 0x00000000,
787 0x00000000,
788 0x00000000,
789 0x00000000,
790 0x00000000,
791 0x00000000,
792 0x00000000,
793 0x00000000,
794 0x00000000,
795 0x00000000,
796 0x00000000,
797 0x00000000,
798 0x00000000,
799 0x00000000,
800 0x00000000,
801 0x00000000,
802 0x00000000,
803 0x00000000,
804 0x00000000,
805 0x00000000,
806 0x00000000,
807 0x00000000,
808 0x00000000,
809 0x00000000,
810 0x00000000,
811 0x00000000,
812 0x00000000,
813 0x00000000,
814 0x00000000,
815 0x00000000,
816 0x00000000,
817 0x00000000,
818 0x00000000,
819 0x00000000,
820 0x00000000,
821 0x00000000,
822 0x00000000,
823 0x00000000,
824 0x00000000,
825 0x00000000,
826 0x00000000,
827 0x00000000,
828 0x00000000,
829 0x00000000,
830 0x00000000,
831 0x00000000,
832 0x00000000,
833 0x00000000,
834 0x00000000,
835 0x00000000,
836/* 0x0ccc: memx_train_tail */
837/* 0x0ccc: i2c_scl_map */
769 0x00000400, 838 0x00000400,
770 0x00000800, 839 0x00000800,
771 0x00001000, 840 0x00001000,
@@ -776,7 +845,7 @@ uint32_t nvd0_pwr_data[] = {
776 0x00020000, 845 0x00020000,
777 0x00040000, 846 0x00040000,
778 0x00080000, 847 0x00080000,
779/* 0x0be8: i2c_sda_map */ 848/* 0x0cf4: i2c_sda_map */
780 0x00100000, 849 0x00100000,
781 0x00200000, 850 0x00200000,
782 0x00400000, 851 0x00400000,
@@ -844,9 +913,6 @@ uint32_t nvd0_pwr_data[] = {
844 0x00000000, 913 0x00000000,
845 0x00000000, 914 0x00000000,
846 0x00000000, 915 0x00000000,
847 0x00000000,
848 0x00000000,
849 0x00000000,
850}; 916};
851 917
852uint32_t nvd0_pwr_code[] = { 918uint32_t nvd0_pwr_code[] = {
@@ -1236,11 +1302,11 @@ uint32_t nvd0_pwr_code[] = {
1236 0x0bf40464, 1302 0x0bf40464,
1237 0x2c67f0f6, 1303 0x2c67f0f6,
1238 0x800066cf, 1304 0x800066cf,
1239 0x00f8ee06, 1305 0x00f8f106,
1240/* 0x0554: memx_func_leave */ 1306/* 0x0554: memx_func_leave */
1241 0xcf2c67f0, 1307 0xcf2c67f0,
1242 0x06800066, 1308 0x06800066,
1243 0x0467f0ef, 1309 0x0467f0f2,
1244 0x07e407f1, 1310 0x07e407f1,
1245 0xbd0006d0, 1311 0xbd0006d0,
1246/* 0x0569: memx_func_leave_wait */ 1312/* 0x0569: memx_func_leave_wait */
@@ -1292,379 +1358,383 @@ uint32_t nvd0_pwr_code[] = {
1292 0x1e9800f8, 1358 0x1e9800f8,
1293 0x0410b600, 1359 0x0410b600,
1294 0xf86721f4, 1360 0xf86721f4,
1295/* 0x0619: memx_exec */ 1361/* 0x0619: memx_func_train */
1296 0xf9e0f900, 1362/* 0x061b: memx_exec */
1297 0x02c1b9d0, 1363 0xf900f800,
1298/* 0x0623: memx_exec_next */ 1364 0xb9d0f9e0,
1299 0x9802b2b9, 1365 0xb2b902c1,
1300 0x10b60013, 1366/* 0x0625: memx_exec_next */
1301 0xf034e704, 1367 0x00139802,
1302 0xe033e701, 1368 0xe70410b6,
1303 0x0132b601, 1369 0xe701f034,
1304 0x980c30f0, 1370 0xb601e033,
1305 0x55f9de35, 1371 0x30f00132,
1306 0xf40612b8, 1372 0xde35980c,
1307 0x0b98e41e, 1373 0x12b855f9,
1308 0xef0c98ee, 1374 0xe41ef406,
1309 0xf102cbbb, 1375 0x98f10b98,
1310 0xcf07c4b7, 1376 0xcbbbf20c,
1311 0xd0fc00bb, 1377 0xc4b7f102,
1312 0x21f5e0fc, 1378 0x00bbcf07,
1313 0x00f802f1, 1379 0xe0fcd0fc,
1314/* 0x065c: memx_info */
1315 0x03c0c7f1,
1316 0x0800b7f1,
1317 0x02f121f5, 1380 0x02f121f5,
1318/* 0x066a: memx_recv */ 1381/* 0x065e: memx_info */
1319 0xd6b000f8, 1382 0xc67000f8,
1320 0xac0bf401, 1383 0x0e0bf401,
1321 0xf400d6b0, 1384/* 0x0664: memx_info_data */
1322 0x00f8e90b, 1385 0x03ccc7f1,
1323/* 0x0678: memx_init */ 1386 0x0800b7f1,
1324/* 0x067a: perf_recv */ 1387/* 0x066f: memx_info_train */
1325 0x00f800f8, 1388 0xf10b0ef4,
1326/* 0x067c: perf_init */ 1389 0xf10bccc7,
1327/* 0x067e: i2c_drive_scl */ 1390/* 0x0677: memx_info_send */
1328 0x36b000f8, 1391 0xf50100b7,
1329 0x0e0bf400, 1392 0xf802f121,
1330 0x07e007f1, 1393/* 0x067d: memx_recv */
1331 0xbd0001d0, 1394 0x01d6b000,
1332/* 0x068f: i2c_drive_scl_lo */ 1395 0xb09b0bf4,
1333 0xf100f804, 1396 0x0bf400d6,
1334 0xd007e407, 1397/* 0x068b: memx_init */
1398 0xf800f8d8,
1399/* 0x068d: perf_recv */
1400/* 0x068f: perf_init */
1401 0xf800f800,
1402/* 0x0691: i2c_drive_scl */
1403 0x0036b000,
1404 0xf10e0bf4,
1405 0xd007e007,
1335 0x04bd0001, 1406 0x04bd0001,
1336/* 0x069a: i2c_drive_sda */ 1407/* 0x06a2: i2c_drive_scl_lo */
1337 0x36b000f8, 1408 0x07f100f8,
1338 0x0e0bf400, 1409 0x01d007e4,
1339 0x07e007f1, 1410 0xf804bd00,
1340 0xbd0002d0, 1411/* 0x06ad: i2c_drive_sda */
1341/* 0x06ab: i2c_drive_sda_lo */ 1412 0x0036b000,
1342 0xf100f804, 1413 0xf10e0bf4,
1343 0xd007e407, 1414 0xd007e007,
1344 0x04bd0002, 1415 0x04bd0002,
1345/* 0x06b6: i2c_sense_scl */ 1416/* 0x06be: i2c_drive_sda_lo */
1417 0x07f100f8,
1418 0x02d007e4,
1419 0xf804bd00,
1420/* 0x06c9: i2c_sense_scl */
1421 0x0132f400,
1422 0x07c437f1,
1423 0xfd0033cf,
1424 0x0bf40431,
1425 0x0131f406,
1426/* 0x06dc: i2c_sense_scl_done */
1427/* 0x06de: i2c_sense_sda */
1346 0x32f400f8, 1428 0x32f400f8,
1347 0xc437f101, 1429 0xc437f101,
1348 0x0033cf07, 1430 0x0033cf07,
1349 0xf40431fd, 1431 0xf40432fd,
1350 0x31f4060b, 1432 0x31f4060b,
1351/* 0x06c9: i2c_sense_scl_done */ 1433/* 0x06f1: i2c_sense_sda_done */
1352/* 0x06cb: i2c_sense_sda */ 1434/* 0x06f3: i2c_raise_scl */
1353 0xf400f801, 1435 0xf900f801,
1354 0x37f10132, 1436 0x9847f140,
1355 0x33cf07c4, 1437 0x0137f008,
1356 0x0432fd00, 1438 0x069121f5,
1357 0xf4060bf4, 1439/* 0x0700: i2c_raise_scl_wait */
1358/* 0x06de: i2c_sense_sda_done */
1359 0x00f80131,
1360/* 0x06e0: i2c_raise_scl */
1361 0x47f140f9,
1362 0x37f00898,
1363 0x7e21f501,
1364/* 0x06ed: i2c_raise_scl_wait */
1365 0xe8e7f106,
1366 0x6721f403,
1367 0x06b621f5,
1368 0xb60901f4,
1369 0x1bf40142,
1370/* 0x0701: i2c_raise_scl_done */
1371 0xf840fcef,
1372/* 0x0705: i2c_start */
1373 0xb621f500,
1374 0x0d11f406,
1375 0x06cb21f5,
1376 0xf40611f4,
1377/* 0x0716: i2c_start_rep */
1378 0x37f0300e,
1379 0x7e21f500,
1380 0x0137f006,
1381 0x069a21f5,
1382 0xb60076bb,
1383 0x50f90465,
1384 0xbb046594,
1385 0x50bd0256,
1386 0xfc0475fd,
1387 0xe021f550,
1388 0x0464b606,
1389/* 0x0743: i2c_start_send */
1390 0xf01f11f4,
1391 0x21f50037,
1392 0xe7f1069a,
1393 0x21f41388,
1394 0x0037f067,
1395 0x067e21f5,
1396 0x1388e7f1,
1397/* 0x075f: i2c_start_out */
1398 0xf86721f4,
1399/* 0x0761: i2c_stop */
1400 0x0037f000,
1401 0x067e21f5,
1402 0xf50037f0,
1403 0xf1069a21,
1404 0xf403e8e7,
1405 0x37f06721,
1406 0x7e21f501,
1407 0x88e7f106,
1408 0x6721f413,
1409 0xf50137f0,
1410 0xf1069a21,
1411 0xf41388e7,
1412 0x00f86721,
1413/* 0x0794: i2c_bitw */
1414 0x069a21f5,
1415 0x03e8e7f1, 1440 0x03e8e7f1,
1416 0xbb6721f4, 1441 0xf56721f4,
1417 0x65b60076, 1442 0xf406c921,
1418 0x9450f904, 1443 0x42b60901,
1419 0x56bb0465, 1444 0xef1bf401,
1420 0xfd50bd02, 1445/* 0x0714: i2c_raise_scl_done */
1421 0x50fc0475, 1446 0x00f840fc,
1422 0x06e021f5, 1447/* 0x0718: i2c_start */
1423 0xf40464b6, 1448 0x06c921f5,
1424 0xe7f11811, 1449 0xf50d11f4,
1425 0x21f41388, 1450 0xf406de21,
1426 0x0037f067, 1451 0x0ef40611,
1427 0x067e21f5, 1452/* 0x0729: i2c_start_rep */
1428 0x1388e7f1, 1453 0x0037f030,
1429/* 0x07d3: i2c_bitw_out */ 1454 0x069121f5,
1430 0xf86721f4, 1455 0xf50137f0,
1431/* 0x07d5: i2c_bitr */ 1456 0xbb06ad21,
1432 0x0137f000,
1433 0x069a21f5,
1434 0x03e8e7f1,
1435 0xbb6721f4,
1436 0x65b60076, 1457 0x65b60076,
1437 0x9450f904, 1458 0x9450f904,
1438 0x56bb0465, 1459 0x56bb0465,
1439 0xfd50bd02, 1460 0xfd50bd02,
1440 0x50fc0475, 1461 0x50fc0475,
1441 0x06e021f5, 1462 0x06f321f5,
1442 0xf40464b6, 1463 0xf40464b6,
1443 0x21f51b11, 1464/* 0x0756: i2c_start_send */
1444 0x37f006cb, 1465 0x37f01f11,
1445 0x7e21f500, 1466 0xad21f500,
1446 0x88e7f106, 1467 0x88e7f106,
1447 0x6721f413, 1468 0x6721f413,
1448 0xf4013cf0, 1469 0xf50037f0,
1449/* 0x081a: i2c_bitr_done */ 1470 0xf1069121,
1450 0x00f80131, 1471 0xf41388e7,
1451/* 0x081c: i2c_get_byte */ 1472/* 0x0772: i2c_start_out */
1452 0xf00057f0, 1473 0x00f86721,
1453/* 0x0822: i2c_get_byte_next */ 1474/* 0x0774: i2c_stop */
1454 0x54b60847, 1475 0xf50037f0,
1455 0x0076bb01, 1476 0xf0069121,
1456 0xf90465b6, 1477 0x21f50037,
1457 0x04659450, 1478 0xe7f106ad,
1458 0xbd0256bb, 1479 0x21f403e8,
1459 0x0475fd50, 1480 0x0137f067,
1460 0x21f550fc, 1481 0x069121f5,
1461 0x64b607d5, 1482 0x1388e7f1,
1462 0x2b11f404, 1483 0xf06721f4,
1463 0xb60553fd, 1484 0x21f50137,
1464 0x1bf40142, 1485 0xe7f106ad,
1465 0x0137f0d8, 1486 0x21f41388,
1487/* 0x07a7: i2c_bitw */
1488 0xf500f867,
1489 0xf106ad21,
1490 0xf403e8e7,
1491 0x76bb6721,
1492 0x0465b600,
1493 0x659450f9,
1494 0x0256bb04,
1495 0x75fd50bd,
1496 0xf550fc04,
1497 0xb606f321,
1498 0x11f40464,
1499 0x88e7f118,
1500 0x6721f413,
1501 0xf50037f0,
1502 0xf1069121,
1503 0xf41388e7,
1504/* 0x07e6: i2c_bitw_out */
1505 0x00f86721,
1506/* 0x07e8: i2c_bitr */
1507 0xf50137f0,
1508 0xf106ad21,
1509 0xf403e8e7,
1510 0x76bb6721,
1511 0x0465b600,
1512 0x659450f9,
1513 0x0256bb04,
1514 0x75fd50bd,
1515 0xf550fc04,
1516 0xb606f321,
1517 0x11f40464,
1518 0xde21f51b,
1519 0x0037f006,
1520 0x069121f5,
1521 0x1388e7f1,
1522 0xf06721f4,
1523 0x31f4013c,
1524/* 0x082d: i2c_bitr_done */
1525/* 0x082f: i2c_get_byte */
1526 0xf000f801,
1527 0x47f00057,
1528/* 0x0835: i2c_get_byte_next */
1529 0x0154b608,
1466 0xb60076bb, 1530 0xb60076bb,
1467 0x50f90465, 1531 0x50f90465,
1468 0xbb046594, 1532 0xbb046594,
1469 0x50bd0256, 1533 0x50bd0256,
1470 0xfc0475fd, 1534 0xfc0475fd,
1471 0x9421f550, 1535 0xe821f550,
1472 0x0464b607, 1536 0x0464b607,
1473/* 0x086c: i2c_get_byte_done */ 1537 0xfd2b11f4,
1474/* 0x086e: i2c_put_byte */ 1538 0x42b60553,
1475 0x47f000f8, 1539 0xd81bf401,
1476/* 0x0871: i2c_put_byte_next */ 1540 0xbb0137f0,
1477 0x0142b608, 1541 0x65b60076,
1478 0xbb3854ff, 1542 0x9450f904,
1543 0x56bb0465,
1544 0xfd50bd02,
1545 0x50fc0475,
1546 0x07a721f5,
1547/* 0x087f: i2c_get_byte_done */
1548 0xf80464b6,
1549/* 0x0881: i2c_put_byte */
1550 0x0847f000,
1551/* 0x0884: i2c_put_byte_next */
1552 0xff0142b6,
1553 0x76bb3854,
1554 0x0465b600,
1555 0x659450f9,
1556 0x0256bb04,
1557 0x75fd50bd,
1558 0xf550fc04,
1559 0xb607a721,
1560 0x11f40464,
1561 0x0046b034,
1562 0xbbd81bf4,
1479 0x65b60076, 1563 0x65b60076,
1480 0x9450f904, 1564 0x9450f904,
1481 0x56bb0465, 1565 0x56bb0465,
1482 0xfd50bd02, 1566 0xfd50bd02,
1483 0x50fc0475, 1567 0x50fc0475,
1484 0x079421f5, 1568 0x07e821f5,
1485 0xf40464b6, 1569 0xf40464b6,
1486 0x46b03411, 1570 0x76bb0f11,
1487 0xd81bf400, 1571 0x0136b000,
1572 0xf4061bf4,
1573/* 0x08da: i2c_put_byte_done */
1574 0x00f80132,
1575/* 0x08dc: i2c_addr */
1488 0xb60076bb, 1576 0xb60076bb,
1489 0x50f90465, 1577 0x50f90465,
1490 0xbb046594, 1578 0xbb046594,
1491 0x50bd0256, 1579 0x50bd0256,
1492 0xfc0475fd, 1580 0xfc0475fd,
1493 0xd521f550, 1581 0x1821f550,
1494 0x0464b607, 1582 0x0464b607,
1495 0xbb0f11f4, 1583 0xe72911f4,
1496 0x36b00076, 1584 0xb6012ec3,
1497 0x061bf401, 1585 0x53fd0134,
1498/* 0x08c7: i2c_put_byte_done */ 1586 0x0076bb05,
1499 0xf80132f4,
1500/* 0x08c9: i2c_addr */
1501 0x0076bb00,
1502 0xf90465b6, 1587 0xf90465b6,
1503 0x04659450, 1588 0x04659450,
1504 0xbd0256bb, 1589 0xbd0256bb,
1505 0x0475fd50, 1590 0x0475fd50,
1506 0x21f550fc, 1591 0x21f550fc,
1507 0x64b60705, 1592 0x64b60881,
1508 0x2911f404, 1593/* 0x0921: i2c_addr_done */
1509 0x012ec3e7, 1594/* 0x0923: i2c_acquire_addr */
1510 0xfd0134b6, 1595 0xc700f804,
1511 0x76bb0553, 1596 0xe4b6f8ce,
1512 0x0465b600, 1597 0x14e0b705,
1513 0x659450f9, 1598/* 0x092f: i2c_acquire */
1514 0x0256bb04, 1599 0xf500f8d0,
1515 0x75fd50bd, 1600 0xf4092321,
1516 0xf550fc04, 1601 0xd9f00421,
1517 0xb6086e21,
1518/* 0x090e: i2c_addr_done */
1519 0x00f80464,
1520/* 0x0910: i2c_acquire_addr */
1521 0xb6f8cec7,
1522 0xe0b705e4,
1523 0x00f8d014,
1524/* 0x091c: i2c_acquire */
1525 0x091021f5,
1526 0xf00421f4,
1527 0x21f403d9,
1528/* 0x092b: i2c_release */
1529 0xf500f833,
1530 0xf4091021,
1531 0xdaf00421,
1532 0x3321f403, 1602 0x3321f403,
1533/* 0x093a: i2c_recv */ 1603/* 0x093e: i2c_release */
1534 0x32f400f8, 1604 0x21f500f8,
1535 0xf8c1c701, 1605 0x21f40923,
1536 0xb00214b6, 1606 0x03daf004,
1537 0x1ff52816, 1607 0xf83321f4,
1538 0x13a0013a, 1608/* 0x094d: i2c_recv */
1539 0x32980be8, 1609 0x0132f400,
1540 0xc013a000, 1610 0xb6f8c1c7,
1541 0x0031980b, 1611 0x16b00214,
1542 0xf90231f4, 1612 0x3a1ff528,
1543 0xf9e0f9d0, 1613 0xf413a001,
1544 0x0067f1d0, 1614 0x0032980c,
1545 0x0063f100, 1615 0x0ccc13a0,
1546 0x01679210, 1616 0xf4003198,
1547 0xb60076bb, 1617 0xd0f90231,
1548 0x50f90465, 1618 0xd0f9e0f9,
1549 0xbb046594, 1619 0x000067f1,
1550 0x50bd0256, 1620 0x100063f1,
1551 0xfc0475fd, 1621 0xbb016792,
1552 0x1c21f550,
1553 0x0464b609,
1554 0xd6b0d0fc,
1555 0xb31bf500,
1556 0x0057f000,
1557 0xb60076bb,
1558 0x50f90465,
1559 0xbb046594,
1560 0x50bd0256,
1561 0xfc0475fd,
1562 0xc921f550,
1563 0x0464b608,
1564 0x00d011f5,
1565 0xbbe0c5c7,
1566 0x65b60076, 1622 0x65b60076,
1567 0x9450f904, 1623 0x9450f904,
1568 0x56bb0465, 1624 0x56bb0465,
1569 0xfd50bd02, 1625 0xfd50bd02,
1570 0x50fc0475, 1626 0x50fc0475,
1571 0x086e21f5, 1627 0x092f21f5,
1628 0xfc0464b6,
1629 0x00d6b0d0,
1630 0x00b31bf5,
1631 0xbb0057f0,
1632 0x65b60076,
1633 0x9450f904,
1634 0x56bb0465,
1635 0xfd50bd02,
1636 0x50fc0475,
1637 0x08dc21f5,
1572 0xf50464b6, 1638 0xf50464b6,
1573 0xf000ad11, 1639 0xc700d011,
1574 0x76bb0157, 1640 0x76bbe0c5,
1575 0x0465b600, 1641 0x0465b600,
1576 0x659450f9, 1642 0x659450f9,
1577 0x0256bb04, 1643 0x0256bb04,
1578 0x75fd50bd, 1644 0x75fd50bd,
1579 0xf550fc04, 1645 0xf550fc04,
1580 0xb608c921, 1646 0xb6088121,
1581 0x11f50464, 1647 0x11f50464,
1582 0x76bb008a, 1648 0x57f000ad,
1583 0x0465b600, 1649 0x0076bb01,
1584 0x659450f9, 1650 0xf90465b6,
1585 0x0256bb04, 1651 0x04659450,
1586 0x75fd50bd, 1652 0xbd0256bb,
1587 0xf550fc04, 1653 0x0475fd50,
1588 0xb6081c21, 1654 0x21f550fc,
1589 0x11f40464, 1655 0x64b608dc,
1590 0xe05bcb6a, 1656 0x8a11f504,
1591 0xb60076bb, 1657 0x0076bb00,
1592 0x50f90465, 1658 0xf90465b6,
1593 0xbb046594, 1659 0x04659450,
1594 0x50bd0256, 1660 0xbd0256bb,
1595 0xfc0475fd, 1661 0x0475fd50,
1596 0x6121f550, 1662 0x21f550fc,
1597 0x0464b607, 1663 0x64b6082f,
1598 0xbd025bb9, 1664 0x6a11f404,
1599 0x430ef474, 1665 0xbbe05bcb,
1600/* 0x0a40: i2c_recv_not_rd08 */ 1666 0x65b60076,
1601 0xf401d6b0, 1667 0x9450f904,
1602 0x57f03d1b, 1668 0x56bb0465,
1603 0xc921f500, 1669 0xfd50bd02,
1604 0x3311f408, 1670 0x50fc0475,
1605 0xf5e0c5c7, 1671 0x077421f5,
1606 0xf4086e21, 1672 0xb90464b6,
1607 0x57f02911, 1673 0x74bd025b,
1608 0xc921f500, 1674/* 0x0a53: i2c_recv_not_rd08 */
1609 0x1f11f408, 1675 0xb0430ef4,
1610 0xf5e0b5c7, 1676 0x1bf401d6,
1611 0xf4086e21, 1677 0x0057f03d,
1612 0x21f51511, 1678 0x08dc21f5,
1613 0x74bd0761, 1679 0xc73311f4,
1614 0xf408c5c7, 1680 0x21f5e0c5,
1615 0x32f4091b, 1681 0x11f40881,
1616 0x030ef402, 1682 0x0057f029,
1617/* 0x0a80: i2c_recv_not_wr08 */ 1683 0x08dc21f5,
1618/* 0x0a80: i2c_recv_done */ 1684 0xc71f11f4,
1619 0xf5f8cec7, 1685 0x21f5e0b5,
1620 0xfc092b21, 1686 0x11f40881,
1621 0xf4d0fce0, 1687 0x7421f515,
1622 0x7cb90a12, 1688 0xc774bd07,
1623 0xf121f502, 1689 0x1bf408c5,
1624/* 0x0a95: i2c_recv_exit */ 1690 0x0232f409,
1625/* 0x0a97: i2c_init */ 1691/* 0x0a93: i2c_recv_not_wr08 */
1692/* 0x0a93: i2c_recv_done */
1693 0xc7030ef4,
1694 0x21f5f8ce,
1695 0xe0fc093e,
1696 0x12f4d0fc,
1697 0x027cb90a,
1698 0x02f121f5,
1699/* 0x0aa8: i2c_recv_exit */
1700/* 0x0aaa: i2c_init */
1701 0x00f800f8,
1702/* 0x0aac: test_recv */
1703 0x05d817f1,
1704 0xb60011cf,
1705 0x07f10110,
1706 0x01d005d8,
1707 0xf104bd00,
1708 0xf1d900e7,
1709 0xf5134fe3,
1710 0xf8022321,
1711/* 0x0acd: test_init */
1712 0x00e7f100,
1713 0x2321f508,
1714/* 0x0ad7: idle_recv */
1626 0xf800f802, 1715 0xf800f802,
1627/* 0x0a99: test_recv */ 1716/* 0x0ad9: idle */
1628 0xd817f100, 1717 0x0031f400,
1629 0x0011cf05, 1718 0x05d417f1,
1630 0xf10110b6, 1719 0xb60011cf,
1631 0xd005d807, 1720 0x07f10110,
1632 0x04bd0001, 1721 0x01d005d4,
1633 0xd900e7f1, 1722/* 0x0aef: idle_loop */
1634 0x134fe3f1, 1723 0xf004bd00,
1635 0x022321f5, 1724 0x32f45817,
1636/* 0x0aba: test_init */ 1725/* 0x0af5: idle_proc */
1637 0xe7f100f8, 1726/* 0x0af5: idle_proc_exec */
1638 0x21f50800, 1727 0xb910f902,
1639 0x00f80223, 1728 0x21f5021e,
1640/* 0x0ac4: idle_recv */ 1729 0x10fc02fa,
1641/* 0x0ac6: idle */ 1730 0xf40911f4,
1642 0x31f400f8, 1731 0x0ef40231,
1643 0xd417f100, 1732/* 0x0b09: idle_proc_next */
1644 0x0011cf05, 1733 0x5810b6ef,
1645 0xf10110b6, 1734 0xf4061fb8,
1646 0xd005d407, 1735 0x02f4e61b,
1647 0x04bd0001, 1736 0x0028f4dd,
1648/* 0x0adc: idle_loop */ 1737 0x00c10ef4,
1649 0xf45817f0,
1650/* 0x0ae2: idle_proc */
1651/* 0x0ae2: idle_proc_exec */
1652 0x10f90232,
1653 0xf5021eb9,
1654 0xfc02fa21,
1655 0x0911f410,
1656 0xf40231f4,
1657/* 0x0af6: idle_proc_next */
1658 0x10b6ef0e,
1659 0x061fb858,
1660 0xf4e61bf4,
1661 0x28f4dd02,
1662 0xc10ef400,
1663 0x00000000,
1664 0x00000000,
1665 0x00000000,
1666 0x00000000,
1667 0x00000000,
1668 0x00000000, 1738 0x00000000,
1669 0x00000000, 1739 0x00000000,
1670 0x00000000, 1740 0x00000000,
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
index 522e3079f824..c8b06cb77e72 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/fuc/os.h
@@ -18,6 +18,10 @@
18#define MEMX_MSG_INFO 0 18#define MEMX_MSG_INFO 0
19#define MEMX_MSG_EXEC 1 19#define MEMX_MSG_EXEC 1
20 20
21/* MEMX: info types */
22#define MEMX_INFO_DATA 0
23#define MEMX_INFO_TRAIN 1
24
21/* MEMX: script opcode definitions */ 25/* MEMX: script opcode definitions */
22#define MEMX_ENTER 1 26#define MEMX_ENTER 1
23#define MEMX_LEAVE 2 27#define MEMX_LEAVE 2
@@ -25,6 +29,7 @@
25#define MEMX_WAIT 4 29#define MEMX_WAIT 4
26#define MEMX_DELAY 5 30#define MEMX_DELAY 5
27#define MEMX_VBLANK 6 31#define MEMX_VBLANK 6
32#define MEMX_TRAIN 7
28 33
29/* I2C_: message identifiers */ 34/* I2C_: message identifiers */
30#define I2C__MSG_RD08 0 35#define I2C__MSG_RD08 0
diff --git a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
index 65eaa2546cad..7a9299d7159f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/pwr/memx.c
@@ -47,7 +47,8 @@ nouveau_memx_init(struct nouveau_pwr *ppwr, struct nouveau_memx **pmemx)
47 u32 reply[2]; 47 u32 reply[2];
48 int ret; 48 int ret;
49 49
50 ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO, 0, 0); 50 ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO,
51 MEMX_INFO_DATA, 0);
51 if (ret) 52 if (ret)
52 return ret; 53 return ret;
53 54
@@ -106,7 +107,7 @@ nouveau_memx_wait(struct nouveau_memx *memx,
106{ 107{
107 nv_debug(memx->ppwr, "R[%06x] & 0x%08x == 0x%08x, %d us\n", 108 nv_debug(memx->ppwr, "R[%06x] & 0x%08x == 0x%08x, %d us\n",
108 addr, mask, data, nsec); 109 addr, mask, data, nsec);
109 memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, ~mask, data, nsec }); 110 memx_cmd(memx, MEMX_WAIT, 4, (u32[]){ addr, mask, data, nsec });
110 memx_out(memx); /* fuc can't handle multiple */ 111 memx_out(memx); /* fuc can't handle multiple */
111} 112}
112 113
@@ -152,6 +153,38 @@ nouveau_memx_wait_vblank(struct nouveau_memx *memx)
152} 153}
153 154
154void 155void
156nouveau_memx_train(struct nouveau_memx *memx)
157{
158 nv_debug(memx->ppwr, " MEM TRAIN\n");
159 memx_cmd(memx, MEMX_TRAIN, 0, NULL);
160}
161
162int
163nouveau_memx_train_result(struct nouveau_pwr *ppwr, u32 *res, int rsize)
164{
165 u32 reply[2], base, size, i;
166 int ret;
167
168 ret = ppwr->message(ppwr, reply, PROC_MEMX, MEMX_MSG_INFO,
169 MEMX_INFO_TRAIN, 0);
170 if (ret)
171 return ret;
172
173 base = reply[0];
174 size = reply[1] >> 2;
175 if (size > rsize)
176 return -ENOMEM;
177
178 /* read the packet */
179 nv_wr32(ppwr, 0x10a1c0, 0x02000000 | base);
180
181 for (i = 0; i < size; i++)
182 res[i] = nv_rd32(ppwr, 0x10a1c4);
183
184 return 0;
185}
186
187void
155nouveau_memx_block(struct nouveau_memx *memx) 188nouveau_memx_block(struct nouveau_memx *memx)
156{ 189{
157 nv_debug(memx->ppwr, " HOST BLOCKED\n"); 190 nv_debug(memx->ppwr, " HOST BLOCKED\n");
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c
index 32794a999106..26ccd8df193f 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/volt/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/volt/base.c
@@ -101,6 +101,41 @@ nouveau_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
101 return ret; 101 return ret;
102} 102}
103 103
104static void nouveau_volt_parse_bios(struct nouveau_bios *bios,
105 struct nouveau_volt *volt)
106{
107 struct nvbios_volt_entry ivid;
108 struct nvbios_volt info;
109 u8 ver, hdr, cnt, len;
110 u16 data;
111 int i;
112
113 data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info);
114 if (data && info.vidmask && info.base && info.step) {
115 for (i = 0; i < info.vidmask + 1; i++) {
116 if (info.base >= info.min &&
117 info.base <= info.max) {
118 volt->vid[volt->vid_nr].uv = info.base;
119 volt->vid[volt->vid_nr].vid = i;
120 volt->vid_nr++;
121 }
122 info.base += info.step;
123 }
124 volt->vid_mask = info.vidmask;
125 } else if (data && info.vidmask) {
126 for (i = 0; i < cnt; i++) {
127 data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
128 &ivid);
129 if (data) {
130 volt->vid[volt->vid_nr].uv = ivid.voltage;
131 volt->vid[volt->vid_nr].vid = ivid.vid;
132 volt->vid_nr++;
133 }
134 }
135 volt->vid_mask = info.vidmask;
136 }
137}
138
104int 139int
105_nouveau_volt_init(struct nouveau_object *object) 140_nouveau_volt_init(struct nouveau_object *object)
106{ 141{
@@ -136,10 +171,6 @@ nouveau_volt_create_(struct nouveau_object *parent,
136{ 171{
137 struct nouveau_bios *bios = nouveau_bios(parent); 172 struct nouveau_bios *bios = nouveau_bios(parent);
138 struct nouveau_volt *volt; 173 struct nouveau_volt *volt;
139 struct nvbios_volt_entry ivid;
140 struct nvbios_volt info;
141 u8 ver, hdr, cnt, len;
142 u16 data;
143 int ret, i; 174 int ret, i;
144 175
145 ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT", 176 ret = nouveau_subdev_create_(parent, engine, oclass, 0, "VOLT",
@@ -152,31 +183,9 @@ nouveau_volt_create_(struct nouveau_object *parent,
152 volt->set = nouveau_volt_set; 183 volt->set = nouveau_volt_set;
153 volt->set_id = nouveau_volt_set_id; 184 volt->set_id = nouveau_volt_set_id;
154 185
155 data = nvbios_volt_parse(bios, &ver, &hdr, &cnt, &len, &info); 186 /* Assuming the non-bios device should build the voltage table later */
156 if (data && info.vidmask && info.base && info.step) { 187 if (bios)
157 for (i = 0; i < info.vidmask + 1; i++) { 188 nouveau_volt_parse_bios(bios, volt);
158 if (info.base >= info.min &&
159 info.base <= info.max) {
160 volt->vid[volt->vid_nr].uv = info.base;
161 volt->vid[volt->vid_nr].vid = i;
162 volt->vid_nr++;
163 }
164 info.base += info.step;
165 }
166 volt->vid_mask = info.vidmask;
167 } else
168 if (data && info.vidmask) {
169 for (i = 0; i < cnt; i++) {
170 data = nvbios_volt_entry_parse(bios, i, &ver, &hdr,
171 &ivid);
172 if (data) {
173 volt->vid[volt->vid_nr].uv = ivid.voltage;
174 volt->vid[volt->vid_nr].vid = ivid.vid;
175 volt->vid_nr++;
176 }
177 }
178 volt->vid_mask = info.vidmask;
179 }
180 189
181 if (volt->vid_nr) { 190 if (volt->vid_nr) {
182 for (i = 0; i < volt->vid_nr; i++) { 191 for (i = 0; i < volt->vid_nr; i++) {
diff --git a/drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c b/drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c
new file mode 100644
index 000000000000..717368ef31ac
--- /dev/null
+++ b/drivers/gpu/drm/nouveau/core/subdev/volt/gk20a.c
@@ -0,0 +1,199 @@
1/*
2 * Copyright (c) 2014, NVIDIA CORPORATION. All rights reserved.
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
17 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 * DEALINGS IN THE SOFTWARE.
21 */
22
23#ifdef __KERNEL__
24#include <nouveau_platform.h>
25#endif
26#include <subdev/volt.h>
27
28struct cvb_coef {
29 int c0;
30 int c1;
31 int c2;
32 int c3;
33 int c4;
34 int c5;
35};
36
37struct gk20a_volt_priv {
38 struct nouveau_volt base;
39 struct regulator *vdd;
40};
41
42const struct cvb_coef gk20a_cvb_coef[] = {
43 /* MHz, c0, c1, c2, c3, c4, c5 */
44 /* 72 */ { 1209886, -36468, 515, 417, -13123, 203},
45 /* 108 */ { 1130804, -27659, 296, 298, -10834, 221},
46 /* 180 */ { 1162871, -27110, 247, 238, -10681, 268},
47 /* 252 */ { 1220458, -28654, 247, 179, -10376, 298},
48 /* 324 */ { 1280953, -30204, 247, 119, -9766, 304},
49 /* 396 */ { 1344547, -31777, 247, 119, -8545, 292},
50 /* 468 */ { 1420168, -34227, 269, 60, -7172, 256},
51 /* 540 */ { 1490757, -35955, 274, 60, -5188, 197},
52 /* 612 */ { 1599112, -42583, 398, 0, -1831, 119},
53 /* 648 */ { 1366986, -16459, -274, 0, -3204, 72},
54 /* 684 */ { 1391884, -17078, -274, -60, -1526, 30},
55 /* 708 */ { 1415522, -17497, -274, -60, -458, 0},
56 /* 756 */ { 1464061, -18331, -274, -119, 1831, -72},
57 /* 804 */ { 1524225, -20064, -254, -119, 4272, -155},
58 /* 852 */ { 1608418, -21643, -269, 0, 763, -48},
59};
60
61/**
62 * cvb_mv = ((c2 * speedo / s_scale + c1) * speedo / s_scale + c0)
63 */
64static inline int
65gk20a_volt_get_cvb_voltage(int speedo, int s_scale,
66 const struct cvb_coef *coef)
67{
68 int mv;
69
70 mv = DIV_ROUND_CLOSEST(coef->c2 * speedo, s_scale);
71 mv = DIV_ROUND_CLOSEST((mv + coef->c1) * speedo, s_scale) + coef->c0;
72 return mv;
73}
74
75/**
76 * cvb_t_mv =
77 * ((c2 * speedo / s_scale + c1) * speedo / s_scale + c0) +
78 * ((c3 * speedo / s_scale + c4 + c5 * T / t_scale) * T / t_scale)
79 */
80static inline int
81gk20a_volt_get_cvb_t_voltage(int speedo, int temp, int s_scale, int t_scale,
82 const struct cvb_coef *coef)
83{
84 int cvb_mv, mv;
85
86 cvb_mv = gk20a_volt_get_cvb_voltage(speedo, s_scale, coef);
87
88 mv = DIV_ROUND_CLOSEST(coef->c3 * speedo, s_scale) + coef->c4 +
89 DIV_ROUND_CLOSEST(coef->c5 * temp, t_scale);
90 mv = DIV_ROUND_CLOSEST(mv * temp, t_scale) + cvb_mv;
91 return mv;
92}
93
94static int
95gk20a_volt_calc_voltage(const struct cvb_coef *coef, int speedo)
96{
97 int mv;
98
99 mv = gk20a_volt_get_cvb_t_voltage(speedo, -10, 100, 10, coef);
100 mv = DIV_ROUND_UP(mv, 1000);
101
102 return mv * 1000;
103}
104
105static int
106gk20a_volt_vid_get(struct nouveau_volt *volt)
107{
108 struct gk20a_volt_priv *priv = (void *)volt;
109 int i, uv;
110
111 uv = regulator_get_voltage(priv->vdd);
112
113 for (i = 0; i < volt->vid_nr; i++)
114 if (volt->vid[i].uv >= uv)
115 return i;
116
117 return -EINVAL;
118}
119
120static int
121gk20a_volt_vid_set(struct nouveau_volt *volt, u8 vid)
122{
123 struct gk20a_volt_priv *priv = (void *)volt;
124
125 nv_debug(volt, "set voltage as %duv\n", volt->vid[vid].uv);
126 return regulator_set_voltage(priv->vdd, volt->vid[vid].uv, 1200000);
127}
128
129static int
130gk20a_volt_set_id(struct nouveau_volt *volt, u8 id, int condition)
131{
132 struct gk20a_volt_priv *priv = (void *)volt;
133 int prev_uv = regulator_get_voltage(priv->vdd);
134 int target_uv = volt->vid[id].uv;
135 int ret;
136
137 nv_debug(volt, "prev=%d, target=%d, condition=%d\n",
138 prev_uv, target_uv, condition);
139 if (!condition ||
140 (condition < 0 && target_uv < prev_uv) ||
141 (condition > 0 && target_uv > prev_uv)) {
142 ret = gk20a_volt_vid_set(volt, volt->vid[id].vid);
143 } else {
144 ret = 0;
145 }
146
147 return ret;
148}
149
150static int
151gk20a_volt_ctor(struct nouveau_object *parent, struct nouveau_object *engine,
152 struct nouveau_oclass *oclass, void *data, u32 size,
153 struct nouveau_object **pobject)
154{
155 struct gk20a_volt_priv *priv;
156 struct nouveau_volt *volt;
157 struct nouveau_platform_device *plat;
158 int i, ret, uv;
159
160 ret = nouveau_volt_create(parent, engine, oclass, &priv);
161 *pobject = nv_object(priv);
162 if (ret)
163 return ret;
164
165 volt = &priv->base;
166
167 plat = nv_device_to_platform(nv_device(parent));
168
169 uv = regulator_get_voltage(plat->gpu->vdd);
170 nv_info(priv, "The default voltage is %duV\n", uv);
171
172 priv->vdd = plat->gpu->vdd;
173 priv->base.vid_get = gk20a_volt_vid_get;
174 priv->base.vid_set = gk20a_volt_vid_set;
175 priv->base.set_id = gk20a_volt_set_id;
176
177 volt->vid_nr = ARRAY_SIZE(gk20a_cvb_coef);
178 nv_debug(priv, "%s - vid_nr = %d\n", __func__, volt->vid_nr);
179 for (i = 0; i < volt->vid_nr; i++) {
180 volt->vid[i].vid = i;
181 volt->vid[i].uv = gk20a_volt_calc_voltage(&gk20a_cvb_coef[i],
182 plat->gpu_speedo);
183 nv_debug(priv, "%2d: vid=%d, uv=%d\n", i, volt->vid[i].vid,
184 volt->vid[i].uv);
185 }
186
187 return 0;
188}
189
190struct nouveau_oclass
191gk20a_volt_oclass = {
192 .handle = NV_SUBDEV(VOLT, 0xea),
193 .ofuncs = &(struct nouveau_ofuncs) {
194 .ctor = gk20a_volt_ctor,
195 .dtor = _nouveau_volt_dtor,
196 .init = _nouveau_volt_init,
197 .fini = _nouveau_volt_fini,
198 },
199};