/*
 * Copyright 2012 Red Hat Inc.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR
 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
 * OTHER DEALINGS IN THE SOFTWARE.
 *
 * Authors: Ben Skeggs
 *          Roy Spliet
 */
#define gt215_clk(p) container_of((p), struct gt215_clk, base)
#include "gt215.h"
#include "pll.h"

#include <engine/fifo.h>
#include <subdev/bios.h>
#include <subdev/bios/pll.h>
#include <subdev/timer.h>

struct gt215_clk {
	struct nvkm_clk base;
	struct gt215_clk_info eng[nv_clk_src_max];
};

static u32 read_clk(struct gt215_clk *, int, bool);
static u32 read_pll(struct gt215_clk *, int, u32);

static u32
read_vco(struct gt215_clk *clk, int idx)
{
	struct nvkm_device *device = clk->base.subdev.device;
	u32 sctl = nvkm_rd32(device, 0x4120 + (idx * 4));

	switch (sctl & 0x00000030) {
	case 0x00000000:
		return device->crystal;
	case 0x00000020:
		return read_pll(clk, 0x41, 0x00e820);
	case 0x00000030:
		return read_pll(clk, 0x42, 0x00e8a0);
	default:
		return 0;
	}
}

static u32
read_clk(struct gt215_clk *clk, int idx, bool ignore_en)
{
	struct nvkm_device *device = clk->base.subdev.device;
	u32 sctl, sdiv, sclk;

	/* refclk for the 0xe8xx plls is a fixed frequency */
	if (idx >= 0x40) {
		if (device->chipset == 0xaf) {
			/* no joke.. seriously.. sigh.. */
			return nvkm_rd32(device, 0x00471c) * 1000;
		}

		return device->crystal;
	}

	sctl = nvkm_rd32(device, 0x4120 + (idx * 4));
	if (!ignore_en && !(sctl & 0x00000100))
		return 0;

	/* out_alt */
	if (sctl & 0x00000400)
		return 108000;

	/* vco_out */
	switch (sctl & 0x00003000) {
	case 0x00000000:
		if (!(sctl & 0x00000200))
			return device->crystal;
		return 0;
	case 0x00002000:
		if (sctl & 0x00000040)
			return 108000;
		return 100000;
	case 0x00003000:
		/* vco_enable */
		if (!(sctl & 0x00000001))
			return 0;

		sclk = read_vco(clk, idx);
		sdiv = ((sctl & 0x003f0000) >> 16) + 2;
		return (sclk * 2) / sdiv;
	default:
		return 0;
	}
}

static u32
read_pll(struct gt215_clk *clk, int idx, u32 pll)
{
	struct nvkm_device *device = clk->base.subdev.device;
	u32 ctrl = nvkm_rd32(device, pll + 0);
	u32 sclk = 0, P = 1, N = 1, M = 1;

	if (!(ctrl & 0x00000008)) {
		if (ctrl & 0x00000001) {
			u32 coef = nvkm_rd32(device, pll + 4);
			M = (coef & 0x000000ff) >> 0;
			N = (coef & 0x0000ff00) >> 8;
			P = (coef & 0x003f0000) >> 16;

			/* no post-divider on these..
			 * XXX: it looks more like two post-"dividers" that
			 * cross each other out in the default RPLL config */
			if ((pll & 0x00ff00) == 0x00e800)
				P = 1;

			sclk = read_clk(clk, 0x00 + idx, false);
		}
	} else {
		sclk = read_clk(clk, 0x10 + idx, false);
	}

	if (M * P)
		return sclk * N / (M * P);

	return 0;
}

static int
gt215_clk_read(struct nvkm_clk *base, enum nv_clk_src src)
{
	struct gt215_clk *clk = gt215_clk(base);
	struct nvkm_subdev *subdev = &clk->base.subdev;
	struct nvkm_device *device = subdev->device;
	u32 hsrc;

	switch (src) {
	case nv_clk_src_crystal:
		return device->crystal;
	case nv_clk_src_core:
	case nv_clk_src_core_intm:
		return read_pll(clk, 0x00, 0x4200);
	case nv_clk_src_shader:
		return read_pll(clk, 0x01, 0x4220);
	case nv_clk_src_mem:
		return read_pll(clk, 0x02, 0x4000);
	case nv_clk_src_disp:
		return read_clk(clk, 0x20, false);
	case nv_clk_src_vdec:
		return read_clk(clk, 0x21, false);
	case nv_clk_src_pmu:
		return read_clk(clk, 0x25, false);
	case nv_clk_src_host:
		hsrc = (nvkm_rd32(device, 0xc040) & 0x30000000) >> 28;
		switch (hsrc) {
		case 0:
			return read_clk(clk, 0x1d, false);
		case 2:
		case 3:
			return 277000;
		default:
			nvkm_error(subdev, "unknown HOST clock source %d\n", hsrc);
			return -EINVAL;
		}
	default:
		nvkm_error(subdev, "invalid clock source %d\n", src);
		return -EINVAL;
	}

	return 0;
}

static int
gt215_clk_info(struct nvkm_clk *base, int idx, u32 khz,
	       struct gt215_clk_info *info)
{
	struct gt215_clk *clk = gt215_clk(base);
	u32 oclk, sclk, sdiv;
	s32 diff;

	info->clk = 0;

	switch (khz) {
	case 27000:
		info->clk = 0x00000100;
		return khz;
	case 100000:
		info->clk = 0x00002100;
		return khz;
	case 108000:
		info->clk = 0x00002140;
		return khz;
	default:
		sclk = read_vco(clk, idx);
		sdiv = min((sclk * 2) / khz, (u32)65);
		oclk = (sclk * 2) / sdiv;
		diff = ((khz + 3000) - oclk);

		/* When imprecise, play it safe and aim for a clock lower than
		 * desired rather than higher */
		if (diff < 0) {
			sdiv++;
			oclk = (sclk * 2) / sdiv;
		}

		/* divider can go as low as 2, limited here because NVIDIA
		 * and the VBIOS on my NVA8 seem to prefer using the PLL
		 * for 810MHz - is there a good reason?
		 * XXX: PLLs with refclk 810MHz?  */
		if (sdiv > 4) {
			info->clk = (((sdiv - 2) << 16) | 0x00003100);
			return oclk;
		}

		break;
	}

	return -ERANGE;
}

int
gt215_pll_info(struct nvkm_clk *base, int idx, u32 pll, u32 khz,
	       struct gt215_clk_info *info)
{
	struct gt215_clk *clk = gt215_clk(base);
	struct nvkm_subdev *subdev = &clk->base.subdev;
	struct nvbios_pll limits;
	int P, N, M, diff;
	int ret;

	info->pll = 0;

	/* If we can get a within [-2, 3) MHz of a divider, we'll disable the
	 * PLL and use the divider instead. */
	ret = gt215_clk_info(&clk->base, idx, khz, info);
	diff = khz - ret;
	if (!pll || (diff >= -2000 && diff < 3000)) {
		goto out;
	}

	/* Try with PLL */
	ret = nvbios_pll_parse(subdev->device->bios, pll, &limits);
	if (ret)
		return ret;

	ret = gt215_clk_info(&clk->base, idx - 0x10, limits.refclk, info);
	if (ret != limits.refclk)
		return -EINVAL;

	ret = gt215_pll_calc(subdev, &limits, khz, &N, NULL, &M, &P);
	if (ret >= 0) {
		info->pll = (P << 16) | (N << 8) | M;
	}

out:
	info->fb_delay = max(((khz + 7566) / 15133), (u32) 18);
	return ret ? ret : -ERANGE;
}

static int
calc_clk(struct gt215_clk *clk, struct nvkm_cstate *cstate,
	 int idx, u32 pll, int dom)
{
	int ret = gt215_pll_info(&clk->base, idx, pll, cstate->domain[dom],
				 &clk->eng[dom]);
	if (ret >= 0)
		return 0;
	return ret;
}

static int
calc_host(struct gt215_clk *clk, struct nvkm_cstate *cstate)
{
	int ret = 0;
	u32 kHz = cstate->domain[nv_clk_src_host];
	struct gt215_clk_info *info = &clk->eng[nv_clk_src_host];

	if (kHz == 277000) {
		info->clk = 0;
		info->host_out = NVA3_HOST_277;
		return 0;
	}

	info->host_out = NVA3_HOST_CLK;

	ret = gt215_clk_info(&clk->base, 0x1d, kHz, info);
	if (ret >= 0)
		return 0;

	return ret;
}

int
gt215_clk_pre(struct nvkm_clk *clk, unsigned long *flags)
{
	struct nvkm_device *device = clk->subdev.device;
	struct nvkm_fifo *fifo = device->fifo;

	/* halt and idle execution engines */
	nvkm_mask(device, 0x020060, 0x00070000, 0x00000000);
	nvkm_mask(device, 0x002504, 0x00000001, 0x00000001);
	/* Wait until the interrupt handler is finished */
	if (nvkm_msec(device, 2000,
		if (!nvkm_rd32(device, 0x000100))
			break;
	) < 0)
		return -EBUSY;

	if (fifo)
		nvkm_fifo_pause(fifo, flags);

	if (nvkm_msec(device, 2000,
		if (nvkm_rd32(device, 0x002504) & 0x00000010)
			break;
	) < 0)
		return -EIO;

	if (nvkm_msec(device, 2000,
		u32 tmp = nvkm_rd32(device, 0x00251c) & 0x0000003f;
		if (tmp == 0x0000003f)
			break;
	) < 0)
		return -EIO;

	return 0;
}

void
gt215_clk_post(struct nvkm_clk *clk, unsigned long *flags)
{
	struct nvkm_device *device = clk->subdev.device;
	struct nvkm_fifo *fifo = device->fifo;

	if (fifo && flags)
		nvkm_fifo_start(fifo, flags);

	nvkm_mask(device, 0x002504, 0x00000001, 0x00000000);
	nvkm_mask(device, 0x020060, 0x00070000, 0x00040000);
}

static void
disable_clk_src(struct gt215_clk *clk, u32 src)
{
	struct nvkm_device *device = clk->base.subdev.device;
	nvkm_mask(device, src, 0x00000100, 0x00000000);
	nvkm_mask(device, src, 0x00000001, 0x00000000);
}

static void
prog_pll(struct gt215_clk *clk, int idx, u32 pll, int dom)
{
	struct gt215_clk_info *info = &clk->eng[dom];
	struct nvkm_device *device = clk->base.subdev.device;
	const u32 src0 = 0x004120 + (idx * 4);
	const u32 src1 = 0x004160 + (idx * 4);
	const u32 ctrl = pll + 0;
	const u32 coef = pll + 4;
	u32 bypass;

	if (info->pll) {
		/* Always start from a non-PLL clock */
		bypass = nvkm_rd32(device, ctrl)  & 0x00000008;
		if (!bypass) {
			nvkm_mask(device, src1, 0x00000101, 0x00000101);
			nvkm_mask(device, ctrl, 0x00000008, 0x00000008);
			udelay(20);
		}

		nvkm_mask(device, src0, 0x003f3141, 0x00000101 | info->clk);
		nvkm_wr32(device, coef, info->pll);
		nvkm_mask(device, ctrl, 0x00000015, 0x00000015);
		nvkm_mask(device, ctrl, 0x00000010, 0x00000000);
		if (nvkm_msec(device, 2000,
			if (nvkm_rd32(device, ctrl) & 0x00020000)
				break;
		) < 0) {
			nvkm_mask(device, ctrl, 0x00000010, 0x00000010);
			nvkm_mask(device, src0, 0x00000101, 0x00000000);
			return;
		}
		nvkm_mask(device, ctrl, 0x00000010, 0x00000010);
		nvkm_mask(device, ctrl, 0x00000008, 0x00000000);
		disable_clk_src(clk, src1);
	} else {
		nvkm_mask(device, src1, 0x003f3141, 0x00000101 | info->clk);
		nvkm_mask(device, ctrl, 0x00000018, 0x00000018);
		udelay(20);
		nvkm_mask(device, ctrl, 0x00000001, 0x00000000);
		disable_clk_src(clk, src0);
	}
}

static void
prog_clk(struct gt215_clk *clk, int idx, int dom)
{
	struct gt215_clk_info *info = &clk->eng[dom];
	struct nvkm_device *device = clk->base.subdev.device;
	nvkm_mask(device, 0x004120 + (idx * 4), 0x003f3141, 0x00000101 | info->clk);
}

static void
prog_host(struct gt215_clk *clk)
{
	struct gt215_clk_info *info = &clk->eng[nv_clk_src_host];
	struct nvkm_device *device = clk->base.subdev.device;
	u32 hsrc = (nvkm_rd32(device, 0xc040));

	switch (info->host_out) {
	case NVA3_HOST_277:
		if ((hsrc & 0x30000000) == 0) {
			nvkm_wr32(device, 0xc040, hsrc | 0x20000000);
			disable_clk_src(clk, 0x4194);
		}
		break;
	case NVA3_HOST_CLK:
		prog_clk(clk, 0x1d, nv_clk_src_host);
		if ((hsrc & 0x30000000) >= 0x20000000) {
			nvkm_wr32(device, 0xc040, hsrc & ~0x30000000);
		}
		break;
	default:
		break;
	}

	/* This seems to be a clock gating factor on idle, always set to 64 */
	nvkm_wr32(device, 0xc044, 0x3e);
}

static void
prog_core(struct gt215_clk *clk, int dom)
{
	struct gt215_clk_info *info = &clk->eng[dom];
	struct nvkm_device *device = clk->base.subdev.device;
	u32 fb_delay = nvkm_rd32(device, 0x10002c);

	if (fb_delay < info->fb_delay)
		nvkm_wr32(device, 0x10002c, info->fb_delay);

	prog_pll(clk, 0x00, 0x004200, dom);

	if (fb_delay > info->fb_delay)
		nvkm_wr32(device, 0x10002c, info->fb_delay);
}

static int
gt215_clk_calc(struct nvkm_clk *base, struct nvkm_cstate *cstate)
{
	struct gt215_clk *clk = gt215_clk(base);
	struct gt215_clk_info *core = &clk->eng[nv_clk_src_core];
	int ret;

	if ((ret = calc_clk(clk, cstate, 0x10, 0x4200, nv_clk_src_core)) ||
	    (ret = calc_clk(clk, cstate, 0x11, 0x4220, nv_clk_src_shader)) ||
	    (ret = calc_clk(clk, cstate, 0x20, 0x0000, nv_clk_src_disp)) ||
	    (ret = calc_clk(clk, cstate, 0x21, 0x0000, nv_clk_src_vdec)) ||
	    (ret = calc_host(clk, cstate)))
		return ret;

	/* XXX: Should be reading the highest bit in the VBIOS clock to decide
	 * whether to use a PLL or not... but using a PLL defeats the purpose */
	if (core->pll) {
		ret = gt215_clk_info(&clk->base, 0x10,
				     cstate->domain[nv_clk_src_core_intm],
				     &clk->eng[nv_clk_src_core_intm]);
		if (ret < 0)
			return ret;
	}

	return 0;
}

static int
gt215_clk_prog(struct nvkm_clk *base)
{
	struct gt215_clk *clk = gt215_clk(base);
	struct gt215_clk_info *core = &clk->eng[nv_clk_src_core];
	int ret = 0;
	unsigned long flags;
	unsigned long *f = &flags;

	ret = gt215_clk_pre(&clk->base, f);
	if (ret)
		goto out;

	if (core->pll)
		prog_core(clk, nv_clk_src_core_intm);

	prog_core(clk,  nv_clk_src_core);
	prog_pll(clk, 0x01, 0x004220, nv_clk_src_shader);
	prog_clk(clk, 0x20, nv_clk_src_disp);
	prog_clk(clk, 0x21, nv_clk_src_vdec);
	prog_host(clk);

out:
	if (ret == -EBUSY)
		f = NULL;

	gt215_clk_post(&clk->base, f);
	return ret;
}

static void
gt215_clk_tidy(struct nvkm_clk *base)
{
}

static const struct nvkm_clk_func
gt215_clk = {
	.read = gt215_clk_read,
	.calc = gt215_clk_calc,
	.prog = gt215_clk_prog,
	.tidy = gt215_clk_tidy,
	.domains = {
		{ nv_clk_src_crystal  , 0xff },
		{ nv_clk_src_core     , 0x00, 0, "core", 1000 },
		{ nv_clk_src_shader   , 0x01, 0, "shader", 1000 },
		{ nv_clk_src_mem      , 0x02, 0, "memory", 1000 },
		{ nv_clk_src_vdec     , 0x03 },
		{ nv_clk_src_disp     , 0x04 },
		{ nv_clk_src_host     , 0x05 },
		{ nv_clk_src_core_intm, 0x06 },
		{ nv_clk_src_max }
	}
};

int
gt215_clk_new(struct nvkm_device *device, int index, struct nvkm_clk **pclk)
{
	struct gt215_clk *clk;

	if (!(clk = kzalloc(sizeof(*clk), GFP_KERNEL)))
		return -ENOMEM;
	*pclk = &clk->base;

	return nvkm_clk_ctor(&gt215_clk, device, index, true, &clk->base);
}
