These changes are the raw update to linux-4.4.6-rt14. Kernel sources
[kvmfornfv.git] / kernel / drivers / gpu / drm / nouveau / nvkm / subdev / fb / ramnv40.c
index 3d31fa4..56f8cff 100644 (file)
@@ -21,9 +21,8 @@
  *
  * Authors: Ben Skeggs
  */
-#include "nv40.h"
+#include "ramnv40.h"
 
-#include <core/device.h>
 #include <subdev/bios.h>
 #include <subdev/bios/bit.h>
 #include <subdev/bios/init.h>
 #include <subdev/clk/pll.h>
 #include <subdev/timer.h>
 
-int
-nv40_ram_calc(struct nvkm_fb *pfb, u32 freq)
+static int
+nv40_ram_calc(struct nvkm_ram *base, u32 freq)
 {
-       struct nvkm_bios *bios = nvkm_bios(pfb);
-       struct nv40_ram *ram = (void *)pfb->ram;
+       struct nv40_ram *ram = nv40_ram(base);
+       struct nvkm_subdev *subdev = &ram->base.fb->subdev;
+       struct nvkm_bios *bios = subdev->device->bios;
        struct nvbios_pll pll;
        int N1, M1, N2, M2;
        int log2P, ret;
 
        ret = nvbios_pll_parse(bios, 0x04, &pll);
        if (ret) {
-               nv_error(pfb, "mclk pll data not found\n");
+               nvkm_error(subdev, "mclk pll data not found\n");
                return ret;
        }
 
-       ret = nv04_pll_calc(nv_subdev(pfb), &pll, freq,
-                           &N1, &M1, &N2, &M2, &log2P);
+       ret = nv04_pll_calc(subdev, &pll, freq, &N1, &M1, &N2, &M2, &log2P);
        if (ret < 0)
                return ret;
 
@@ -64,11 +63,13 @@ nv40_ram_calc(struct nvkm_fb *pfb, u32 freq)
        return 0;
 }
 
-int
-nv40_ram_prog(struct nvkm_fb *pfb)
+static int
+nv40_ram_prog(struct nvkm_ram *base)
 {
-       struct nvkm_bios *bios = nvkm_bios(pfb);
-       struct nv40_ram *ram = (void *)pfb->ram;
+       struct nv40_ram *ram = nv40_ram(base);
+       struct nvkm_subdev *subdev = &ram->base.fb->subdev;
+       struct nvkm_device *device = subdev->device;
+       struct nvkm_bios *bios = device->bios;
        struct bit_entry M;
        u32 crtc_mask = 0;
        u8  sr1[2];
@@ -76,12 +77,12 @@ nv40_ram_prog(struct nvkm_fb *pfb)
 
        /* determine which CRTCs are active, fetch VGA_SR1 for each */
        for (i = 0; i < 2; i++) {
-               u32 vbl = nv_rd32(pfb, 0x600808 + (i * 0x2000));
+               u32 vbl = nvkm_rd32(device, 0x600808 + (i * 0x2000));
                u32 cnt = 0;
                do {
-                       if (vbl != nv_rd32(pfb, 0x600808 + (i * 0x2000))) {
-                               nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
-                               sr1[i] = nv_rd08(pfb, 0x0c03c5 + (i * 0x2000));
+                       if (vbl != nvkm_rd32(device, 0x600808 + (i * 0x2000))) {
+                               nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+                               sr1[i] = nvkm_rd08(device, 0x0c03c5 + (i * 0x2000));
                                if (!(sr1[i] & 0x20))
                                        crtc_mask |= (1 << i);
                                break;
@@ -94,55 +95,66 @@ nv40_ram_prog(struct nvkm_fb *pfb)
        for (i = 0; i < 2; i++) {
                if (!(crtc_mask & (1 << i)))
                        continue;
-               nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00000000);
-               nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
-               nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
-               nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
+
+               nvkm_msec(device, 2000,
+                       u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
+                       if (!(tmp & 0x00010000))
+                               break;
+               );
+
+               nvkm_msec(device, 2000,
+                       u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
+                       if ( (tmp & 0x00010000))
+                               break;
+               );
+
+               nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+               nvkm_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
        }
 
        /* prepare ram for reclocking */
-       nv_wr32(pfb, 0x1002d4, 0x00000001); /* precharge */
-       nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */
-       nv_wr32(pfb, 0x1002d0, 0x00000001); /* refresh */
-       nv_mask(pfb, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
-       nv_wr32(pfb, 0x1002dc, 0x00000001); /* enable self-refresh */
+       nvkm_wr32(device, 0x1002d4, 0x00000001); /* precharge */
+       nvkm_wr32(device, 0x1002d0, 0x00000001); /* refresh */
+       nvkm_wr32(device, 0x1002d0, 0x00000001); /* refresh */
+       nvkm_mask(device, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
+       nvkm_wr32(device, 0x1002dc, 0x00000001); /* enable self-refresh */
 
        /* change the PLL of each memory partition */
-       nv_mask(pfb, 0x00c040, 0x0000c000, 0x00000000);
-       switch (nv_device(pfb)->chipset) {
+       nvkm_mask(device, 0x00c040, 0x0000c000, 0x00000000);
+       switch (device->chipset) {
        case 0x40:
        case 0x45:
        case 0x41:
        case 0x42:
        case 0x47:
-               nv_mask(pfb, 0x004044, 0xc0771100, ram->ctrl);
-               nv_mask(pfb, 0x00402c, 0xc0771100, ram->ctrl);
-               nv_wr32(pfb, 0x004048, ram->coef);
-               nv_wr32(pfb, 0x004030, ram->coef);
+               nvkm_mask(device, 0x004044, 0xc0771100, ram->ctrl);
+               nvkm_mask(device, 0x00402c, 0xc0771100, ram->ctrl);
+               nvkm_wr32(device, 0x004048, ram->coef);
+               nvkm_wr32(device, 0x004030, ram->coef);
        case 0x43:
        case 0x49:
        case 0x4b:
-               nv_mask(pfb, 0x004038, 0xc0771100, ram->ctrl);
-               nv_wr32(pfb, 0x00403c, ram->coef);
+               nvkm_mask(device, 0x004038, 0xc0771100, ram->ctrl);
+               nvkm_wr32(device, 0x00403c, ram->coef);
        default:
-               nv_mask(pfb, 0x004020, 0xc0771100, ram->ctrl);
-               nv_wr32(pfb, 0x004024, ram->coef);
+               nvkm_mask(device, 0x004020, 0xc0771100, ram->ctrl);
+               nvkm_wr32(device, 0x004024, ram->coef);
                break;
        }
        udelay(100);
-       nv_mask(pfb, 0x00c040, 0x0000c000, 0x0000c000);
+       nvkm_mask(device, 0x00c040, 0x0000c000, 0x0000c000);
 
        /* re-enable normal operation of memory controller */
-       nv_wr32(pfb, 0x1002dc, 0x00000000);
-       nv_mask(pfb, 0x100210, 0x80000000, 0x80000000);
+       nvkm_wr32(device, 0x1002dc, 0x00000000);
+       nvkm_mask(device, 0x100210, 0x80000000, 0x80000000);
        udelay(100);
 
        /* execute memory reset script from vbios */
        if (!bit_entry(bios, 'M', &M)) {
                struct nvbios_init init = {
-                       .subdev = nv_subdev(pfb),
+                       .subdev = subdev,
                        .bios = bios,
-                       .offset = nv_ro16(bios, M.offset + 0x00),
+                       .offset = nvbios_rd16(bios, M.offset + 0x00),
                        .execute = 1,
                };
 
@@ -155,58 +167,64 @@ nv40_ram_prog(struct nvkm_fb *pfb)
        for (i = 0; i < 2; i++) {
                if (!(crtc_mask & (1 << i)))
                        continue;
-               nv_wait(pfb, 0x600808 + (i * 0x2000), 0x00010000, 0x00010000);
-               nv_wr08(pfb, 0x0c03c4 + (i * 0x2000), 0x01);
-               nv_wr08(pfb, 0x0c03c5 + (i * 0x2000), sr1[i]);
+
+               nvkm_msec(device, 2000,
+                       u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
+                       if ( (tmp & 0x00010000))
+                               break;
+               );
+
+               nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
+               nvkm_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i]);
        }
 
        return 0;
 }
 
-void
-nv40_ram_tidy(struct nvkm_fb *pfb)
+static void
+nv40_ram_tidy(struct nvkm_ram *base)
 {
 }
 
-static int
-nv40_ram_create(struct nvkm_object *parent, struct nvkm_object *engine,
-               struct nvkm_oclass *oclass, void *data, u32 size,
-               struct nvkm_object **pobject)
+static const struct nvkm_ram_func
+nv40_ram_func = {
+       .calc = nv40_ram_calc,
+       .prog = nv40_ram_prog,
+       .tidy = nv40_ram_tidy,
+};
+
+int
+nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type type, u64 size,
+             u32 tags, struct nvkm_ram **pram)
 {
-       struct nvkm_fb *pfb = nvkm_fb(parent);
        struct nv40_ram *ram;
-       u32 pbus1218 = nv_rd32(pfb, 0x001218);
-       int ret;
+       if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
+               return -ENOMEM;
+       *pram = &ram->base;
+       return nvkm_ram_ctor(&nv40_ram_func, fb, type, size, tags, &ram->base);
+}
 
-       ret = nvkm_ram_create(parent, engine, oclass, &ram);
-       *pobject = nv_object(ram);
-       if (ret)
-               return ret;
+int
+nv40_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
+{
+       struct nvkm_device *device = fb->subdev.device;
+       u32 pbus1218 = nvkm_rd32(device, 0x001218);
+       u32     size = nvkm_rd32(device, 0x10020c) & 0xff000000;
+       u32     tags = nvkm_rd32(device, 0x100320);
+       enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN;
+       int ret;
 
        switch (pbus1218 & 0x00000300) {
-       case 0x00000000: ram->base.type = NV_MEM_TYPE_SDRAM; break;
-       case 0x00000100: ram->base.type = NV_MEM_TYPE_DDR1; break;
-       case 0x00000200: ram->base.type = NV_MEM_TYPE_GDDR3; break;
-       case 0x00000300: ram->base.type = NV_MEM_TYPE_DDR2; break;
+       case 0x00000000: type = NVKM_RAM_TYPE_SDRAM; break;
+       case 0x00000100: type = NVKM_RAM_TYPE_DDR1 ; break;
+       case 0x00000200: type = NVKM_RAM_TYPE_GDDR3; break;
+       case 0x00000300: type = NVKM_RAM_TYPE_DDR2 ; break;
        }
 
-       ram->base.size  =  nv_rd32(pfb, 0x10020c) & 0xff000000;
-       ram->base.parts = (nv_rd32(pfb, 0x100200) & 0x00000003) + 1;
-       ram->base.tags  =  nv_rd32(pfb, 0x100320);
-       ram->base.calc = nv40_ram_calc;
-       ram->base.prog = nv40_ram_prog;
-       ram->base.tidy = nv40_ram_tidy;
+       ret = nv40_ram_new_(fb, type, size, tags, pram);
+       if (ret)
+               return ret;
+
+       (*pram)->parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
        return 0;
 }
-
-
-struct nvkm_oclass
-nv40_ram_oclass = {
-       .handle = 0,
-       .ofuncs = &(struct nvkm_ofuncs) {
-               .ctor = nv40_ram_create,
-               .dtor = _nvkm_ram_dtor,
-               .init = _nvkm_ram_init,
-               .fini = _nvkm_ram_fini,
-       }
-};