linux/drivers/gpu/drm/nouveau/nvkm/subdev/fb/ramnv40.c
<<
>>
Prefs
   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#include "ramnv40.h"
  25
  26#include <subdev/bios.h>
  27#include <subdev/bios/bit.h>
  28#include <subdev/bios/init.h>
  29#include <subdev/bios/pll.h>
  30#include <subdev/clk/pll.h>
  31#include <subdev/timer.h>
  32
  33static int
  34nv40_ram_calc(struct nvkm_ram *base, u32 freq)
  35{
  36        struct nv40_ram *ram = nv40_ram(base);
  37        struct nvkm_subdev *subdev = &ram->base.fb->subdev;
  38        struct nvkm_bios *bios = subdev->device->bios;
  39        struct nvbios_pll pll;
  40        int N1, M1, N2, M2;
  41        int log2P, ret;
  42
  43        ret = nvbios_pll_parse(bios, 0x04, &pll);
  44        if (ret) {
  45                nvkm_error(subdev, "mclk pll data not found\n");
  46                return ret;
  47        }
  48
  49        ret = nv04_pll_calc(subdev, &pll, freq, &N1, &M1, &N2, &M2, &log2P);
  50        if (ret < 0)
  51                return ret;
  52
  53        ram->ctrl  = 0x80000000 | (log2P << 16);
  54        ram->ctrl |= min(pll.bias_p + log2P, (int)pll.max_p) << 20;
  55        if (N2 == M2) {
  56                ram->ctrl |= 0x00000100;
  57                ram->coef  = (N1 << 8) | M1;
  58        } else {
  59                ram->ctrl |= 0x40000000;
  60                ram->coef  = (N2 << 24) | (M2 << 16) | (N1 << 8) | M1;
  61        }
  62
  63        return 0;
  64}
  65
  66static int
  67nv40_ram_prog(struct nvkm_ram *base)
  68{
  69        struct nv40_ram *ram = nv40_ram(base);
  70        struct nvkm_subdev *subdev = &ram->base.fb->subdev;
  71        struct nvkm_device *device = subdev->device;
  72        struct nvkm_bios *bios = device->bios;
  73        struct bit_entry M;
  74        u32 crtc_mask = 0;
  75        u8  sr1[2];
  76        int i;
  77
  78        /* determine which CRTCs are active, fetch VGA_SR1 for each */
  79        for (i = 0; i < 2; i++) {
  80                u32 vbl = nvkm_rd32(device, 0x600808 + (i * 0x2000));
  81                u32 cnt = 0;
  82                do {
  83                        if (vbl != nvkm_rd32(device, 0x600808 + (i * 0x2000))) {
  84                                nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
  85                                sr1[i] = nvkm_rd08(device, 0x0c03c5 + (i * 0x2000));
  86                                if (!(sr1[i] & 0x20))
  87                                        crtc_mask |= (1 << i);
  88                                break;
  89                        }
  90                        udelay(1);
  91                } while (cnt++ < 32);
  92        }
  93
  94        /* wait for vblank start on active crtcs, disable memory access */
  95        for (i = 0; i < 2; i++) {
  96                if (!(crtc_mask & (1 << i)))
  97                        continue;
  98
  99                nvkm_msec(device, 2000,
 100                        u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
 101                        if (!(tmp & 0x00010000))
 102                                break;
 103                );
 104
 105                nvkm_msec(device, 2000,
 106                        u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
 107                        if ( (tmp & 0x00010000))
 108                                break;
 109                );
 110
 111                nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
 112                nvkm_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i] | 0x20);
 113        }
 114
 115        /* prepare ram for reclocking */
 116        nvkm_wr32(device, 0x1002d4, 0x00000001); /* precharge */
 117        nvkm_wr32(device, 0x1002d0, 0x00000001); /* refresh */
 118        nvkm_wr32(device, 0x1002d0, 0x00000001); /* refresh */
 119        nvkm_mask(device, 0x100210, 0x80000000, 0x00000000); /* no auto refresh */
 120        nvkm_wr32(device, 0x1002dc, 0x00000001); /* enable self-refresh */
 121
 122        /* change the PLL of each memory partition */
 123        nvkm_mask(device, 0x00c040, 0x0000c000, 0x00000000);
 124        switch (device->chipset) {
 125        case 0x40:
 126        case 0x45:
 127        case 0x41:
 128        case 0x42:
 129        case 0x47:
 130                nvkm_mask(device, 0x004044, 0xc0771100, ram->ctrl);
 131                nvkm_mask(device, 0x00402c, 0xc0771100, ram->ctrl);
 132                nvkm_wr32(device, 0x004048, ram->coef);
 133                nvkm_wr32(device, 0x004030, ram->coef);
 134                fallthrough;
 135        case 0x43:
 136        case 0x49:
 137        case 0x4b:
 138                nvkm_mask(device, 0x004038, 0xc0771100, ram->ctrl);
 139                nvkm_wr32(device, 0x00403c, ram->coef);
 140                fallthrough;
 141        default:
 142                nvkm_mask(device, 0x004020, 0xc0771100, ram->ctrl);
 143                nvkm_wr32(device, 0x004024, ram->coef);
 144                break;
 145        }
 146        udelay(100);
 147        nvkm_mask(device, 0x00c040, 0x0000c000, 0x0000c000);
 148
 149        /* re-enable normal operation of memory controller */
 150        nvkm_wr32(device, 0x1002dc, 0x00000000);
 151        nvkm_mask(device, 0x100210, 0x80000000, 0x80000000);
 152        udelay(100);
 153
 154        /* execute memory reset script from vbios */
 155        if (!bit_entry(bios, 'M', &M))
 156                nvbios_init(subdev, nvbios_rd16(bios, M.offset + 0x00));
 157
 158        /* make sure we're in vblank (hopefully the same one as before), and
 159         * then re-enable crtc memory access
 160         */
 161        for (i = 0; i < 2; i++) {
 162                if (!(crtc_mask & (1 << i)))
 163                        continue;
 164
 165                nvkm_msec(device, 2000,
 166                        u32 tmp = nvkm_rd32(device, 0x600808 + (i * 0x2000));
 167                        if ( (tmp & 0x00010000))
 168                                break;
 169                );
 170
 171                nvkm_wr08(device, 0x0c03c4 + (i * 0x2000), 0x01);
 172                nvkm_wr08(device, 0x0c03c5 + (i * 0x2000), sr1[i]);
 173        }
 174
 175        return 0;
 176}
 177
 178static void
 179nv40_ram_tidy(struct nvkm_ram *base)
 180{
 181}
 182
 183static const struct nvkm_ram_func
 184nv40_ram_func = {
 185        .calc = nv40_ram_calc,
 186        .prog = nv40_ram_prog,
 187        .tidy = nv40_ram_tidy,
 188};
 189
 190int
 191nv40_ram_new_(struct nvkm_fb *fb, enum nvkm_ram_type type, u64 size,
 192              struct nvkm_ram **pram)
 193{
 194        struct nv40_ram *ram;
 195        if (!(ram = kzalloc(sizeof(*ram), GFP_KERNEL)))
 196                return -ENOMEM;
 197        *pram = &ram->base;
 198        return nvkm_ram_ctor(&nv40_ram_func, fb, type, size, &ram->base);
 199}
 200
 201int
 202nv40_ram_new(struct nvkm_fb *fb, struct nvkm_ram **pram)
 203{
 204        struct nvkm_device *device = fb->subdev.device;
 205        u32 pbus1218 = nvkm_rd32(device, 0x001218);
 206        u32     size = nvkm_rd32(device, 0x10020c) & 0xff000000;
 207        enum nvkm_ram_type type = NVKM_RAM_TYPE_UNKNOWN;
 208        int ret;
 209
 210        switch (pbus1218 & 0x00000300) {
 211        case 0x00000000: type = NVKM_RAM_TYPE_SDRAM; break;
 212        case 0x00000100: type = NVKM_RAM_TYPE_DDR1 ; break;
 213        case 0x00000200: type = NVKM_RAM_TYPE_GDDR3; break;
 214        case 0x00000300: type = NVKM_RAM_TYPE_DDR2 ; break;
 215        }
 216
 217        ret = nv40_ram_new_(fb, type, size, pram);
 218        if (ret)
 219                return ret;
 220
 221        (*pram)->parts = (nvkm_rd32(device, 0x100200) & 0x00000003) + 1;
 222        return 0;
 223}
 224