0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022 #include "nv50.h"
0023
0024 #include <subdev/bios.h>
0025 #include <subdev/bios/pll.h>
0026 #include <subdev/clk/pll.h>
0027
0028 static int
0029 tu102_devinit_pll_set(struct nvkm_devinit *init, u32 type, u32 freq)
0030 {
0031 struct nvkm_subdev *subdev = &init->subdev;
0032 struct nvkm_device *device = subdev->device;
0033 struct nvbios_pll info;
0034 int head = type - PLL_VPLL0;
0035 int N, fN, M, P;
0036 int ret;
0037
0038 ret = nvbios_pll_parse(device->bios, type, &info);
0039 if (ret)
0040 return ret;
0041
0042 ret = gt215_pll_calc(subdev, &info, freq, &N, &fN, &M, &P);
0043 if (ret < 0)
0044 return ret;
0045
0046 switch (info.type) {
0047 case PLL_VPLL0:
0048 case PLL_VPLL1:
0049 case PLL_VPLL2:
0050 case PLL_VPLL3:
0051 nvkm_wr32(device, 0x00ef10 + (head * 0x40), fN << 16);
0052 nvkm_wr32(device, 0x00ef04 + (head * 0x40), (P << 16) |
0053 (N << 8) |
0054 (M << 0));
0055
0056 nvkm_wr32(device, 0x00ef0c + (head * 0x40), 0x00000900);
0057 nvkm_wr32(device, 0x00ef00 + (head * 0x40), 0x02000014);
0058 break;
0059 default:
0060 nvkm_warn(subdev, "%08x/%dKhz unimplemented\n", type, freq);
0061 ret = -EINVAL;
0062 break;
0063 }
0064
0065 return ret;
0066 }
0067
0068 int
0069 tu102_devinit_post(struct nvkm_devinit *base, bool post)
0070 {
0071 struct nv50_devinit *init = nv50_devinit(base);
0072 gm200_devinit_preos(init, post);
0073 return 0;
0074 }
0075
0076 static const struct nvkm_devinit_func
0077 tu102_devinit = {
0078 .init = nv50_devinit_init,
0079 .post = tu102_devinit_post,
0080 .pll_set = tu102_devinit_pll_set,
0081 .disable = gm107_devinit_disable,
0082 };
0083
0084 int
0085 tu102_devinit_new(struct nvkm_device *device, enum nvkm_subdev_type type, int inst,
0086 struct nvkm_devinit **pinit)
0087 {
0088 return nv50_devinit_new_(&tu102_devinit, device, type, inst, pinit);
0089 }