0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024 #include "nv50.h"
0025
0026 #include <subdev/bios.h>
0027 #include <subdev/bios/init.h>
0028 #include <subdev/bios/pll.h>
0029 #include <subdev/clk/pll.h>
0030
0031 int
0032 gt215_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
0033 {
0034 struct nvkm_subdev *subdev = &init->subdev;
0035 struct nvkm_device *device = subdev->device;
0036 struct nvbios_pll info;
0037 int N, fN, M, P;
0038 int ret;
0039
0040 ret = nvbios_pll_parse(device->bios, type, &info);
0041 if (ret)
0042 return ret;
0043
0044 ret = gt215_pll_calc(subdev, &info, freq, &N, &fN, &M, &P);
0045 if (ret < 0)
0046 return ret;
0047
0048 switch (info.type) {
0049 case PLL_VPLL0:
0050 case PLL_VPLL1:
0051 nvkm_wr32(device, info.reg + 0, 0x50000610);
0052 nvkm_mask(device, info.reg + 4, 0x003fffff,
0053 (P << 16) | (M << 8) | N);
0054 nvkm_wr32(device, info.reg + 8, fN);
0055 break;
0056 default:
0057 nvkm_warn(subdev, "%08x/%dKhz unimplemented\n", type, freq);
0058 ret = -EINVAL;
0059 break;
0060 }
0061
0062 return ret;
0063 }
0064
0065 static u64
0066 gt215_devinit_disable(struct nvkm_devinit *init)
0067 {
0068 struct nvkm_device *device = init->subdev.device;
0069 u32 r001540 = nvkm_rd32(device, 0x001540);
0070 u32 r00154c = nvkm_rd32(device, 0x00154c);
0071
0072 if (!(r001540 & 0x40000000)) {
0073 nvkm_subdev_disable(device, NVKM_ENGINE_MSPDEC, 0);
0074 nvkm_subdev_disable(device, NVKM_ENGINE_MSPPP, 0);
0075 }
0076
0077 if (!(r00154c & 0x00000004))
0078 nvkm_subdev_disable(device, NVKM_ENGINE_DISP, 0);
0079 if (!(r00154c & 0x00000020))
0080 nvkm_subdev_disable(device, NVKM_ENGINE_MSVLD, 0);
0081 if (!(r00154c & 0x00000200))
0082 nvkm_subdev_disable(device, NVKM_ENGINE_CE, 0);
0083
0084 return 0ULL;
0085 }
0086
0087 static u32
0088 gt215_devinit_mmio_part[] = {
0089 0x100720, 0x1008bc, 4,
0090 0x100a20, 0x100adc, 4,
0091 0x100d80, 0x100ddc, 4,
0092 0x110000, 0x110f9c, 4,
0093 0x111000, 0x11103c, 8,
0094 0x111080, 0x1110fc, 4,
0095 0x111120, 0x1111fc, 4,
0096 0x111300, 0x1114bc, 4,
0097 0,
0098 };
0099
0100 static u32
0101 gt215_devinit_mmio(struct nvkm_devinit *base, u32 addr)
0102 {
0103 struct nv50_devinit *init = nv50_devinit(base);
0104 struct nvkm_device *device = init->base.subdev.device;
0105 u32 *mmio = gt215_devinit_mmio_part;
0106
0107
0108
0109
0110
0111
0112
0113
0114
0115
0116
0117
0118
0119
0120
0121
0122 while (mmio[0]) {
0123 if (addr >= mmio[0] && addr <= mmio[1]) {
0124 u32 part = (addr / mmio[2]) & 7;
0125 if (!init->r001540)
0126 init->r001540 = nvkm_rd32(device, 0x001540);
0127 if (part >= hweight8((init->r001540 >> 16) & 0xff))
0128 return ~0;
0129 return addr;
0130 }
0131 mmio += 3;
0132 }
0133
0134 return addr;
0135 }
0136
0137 static const struct nvkm_devinit_func
0138 gt215_devinit = {
0139 .preinit = nv50_devinit_preinit,
0140 .init = nv50_devinit_init,
0141 .post = nv04_devinit_post,
0142 .mmio = gt215_devinit_mmio,
0143 .pll_set = gt215_devinit_pll_set,
0144 .disable = gt215_devinit_disable,
0145 };
0146
0147 int
0148 gt215_devinit_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
0149 struct nvkm_devinit **pinit)
0150 {
0151 return nv50_devinit_new_(>215_devinit, device, type, inst, pinit);
0152 }