/*
 * Copyright 2010 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
 */

#include <drm/drmP.h>
#include "nouveau_drm.h"
#include "nouveau_bios.h"
#include "dispnv04/hw.h"
#include "nouveau_pm.h"
#include "nouveau_hwsq.h"

#include "nv50_display.h"

#include <subdev/bios/pll.h>
#include <subdev/clock.h>
#include <subdev/timer.h>
#include <subdev/fb.h>

enum clk_src {
	clk_src_crystal,
	clk_src_href,
	clk_src_hclk,
	clk_src_hclkm3,
	clk_src_hclkm3d2,
	clk_src_host,
	clk_src_nvclk,
	clk_src_sclk,
	clk_src_mclk,
	clk_src_vdec,
	clk_src_dom6
};

static u32 read_clk(struct drm_device *, enum clk_src);

static u32
read_div(struct drm_device *dev)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);

	switch (nv_device(drm->device)->chipset) {
	case 0x50: /* it exists, but only has bit 31, not the dividers.. */
	case 0x84:
	case 0x86:
	case 0x98:
	case 0xa0:
		return nv_rd32(device, 0x004700);
	case 0x92:
	case 0x94:
	case 0x96:
		return nv_rd32(device, 0x004800);
	default:
		return 0x00000000;
	}
}

static u32
read_pll_src(struct drm_device *dev, u32 base)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	u32 coef, ref = read_clk(dev, clk_src_crystal);
	u32 rsel = nv_rd32(device, 0x00e18c);
	int P, N, M, id;

	switch (nv_device(drm->device)->chipset) {
	case 0x50:
	case 0xa0:
		switch (base) {
		case 0x4020:
		case 0x4028: id = !!(rsel & 0x00000004); break;
		case 0x4008: id = !!(rsel & 0x00000008); break;
		case 0x4030: id = 0; break;
		default:
			NV_ERROR(drm, "ref: bad pll 0x%06x\n", base);
			return 0;
		}

		coef = nv_rd32(device, 0x00e81c + (id * 0x0c));
		ref *=  (coef & 0x01000000) ? 2 : 4;
		P    =  (coef & 0x00070000) >> 16;
		N    = ((coef & 0x0000ff00) >> 8) + 1;
		M    = ((coef & 0x000000ff) >> 0) + 1;
		break;
	case 0x84:
	case 0x86:
	case 0x92:
		coef = nv_rd32(device, 0x00e81c);
		P    = (coef & 0x00070000) >> 16;
		N    = (coef & 0x0000ff00) >> 8;
		M    = (coef & 0x000000ff) >> 0;
		break;
	case 0x94:
	case 0x96:
	case 0x98:
		rsel = nv_rd32(device, 0x00c050);
		switch (base) {
		case 0x4020: rsel = (rsel & 0x00000003) >> 0; break;
		case 0x4008: rsel = (rsel & 0x0000000c) >> 2; break;
		case 0x4028: rsel = (rsel & 0x00001800) >> 11; break;
		case 0x4030: rsel = 3; break;
		default:
			NV_ERROR(drm, "ref: bad pll 0x%06x\n", base);
			return 0;
		}

		switch (rsel) {
		case 0: id = 1; break;
		case 1: return read_clk(dev, clk_src_crystal);
		case 2: return read_clk(dev, clk_src_href);
		case 3: id = 0; break;
		}

		coef =  nv_rd32(device, 0x00e81c + (id * 0x28));
		P    = (nv_rd32(device, 0x00e824 + (id * 0x28)) >> 16) & 7;
		P   += (coef & 0x00070000) >> 16;
		N    = (coef & 0x0000ff00) >> 8;
		M    = (coef & 0x000000ff) >> 0;
		break;
	default:
		BUG_ON(1);
	}

	if (M)
		return (ref * N / M) >> P;
	return 0;
}

static u32
read_pll_ref(struct drm_device *dev, u32 base)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	u32 src, mast = nv_rd32(device, 0x00c040);

	switch (base) {
	case 0x004028:
		src = !!(mast & 0x00200000);
		break;
	case 0x004020:
		src = !!(mast & 0x00400000);
		break;
	case 0x004008:
		src = !!(mast & 0x00010000);
		break;
	case 0x004030:
		src = !!(mast & 0x02000000);
		break;
	case 0x00e810:
		return read_clk(dev, clk_src_crystal);
	default:
		NV_ERROR(drm, "bad pll 0x%06x\n", base);
		return 0;
	}

	if (src)
		return read_clk(dev, clk_src_href);
	return read_pll_src(dev, base);
}

static u32
read_pll(struct drm_device *dev, u32 base)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	u32 mast = nv_rd32(device, 0x00c040);
	u32 ctrl = nv_rd32(device, base + 0);
	u32 coef = nv_rd32(device, base + 4);
	u32 ref = read_pll_ref(dev, base);
	u32 clk = 0;
	int N1, N2, M1, M2;

	if (base == 0x004028 && (mast & 0x00100000)) {
		/* wtf, appears to only disable post-divider on nva0 */
		if (nv_device(drm->device)->chipset != 0xa0)
			return read_clk(dev, clk_src_dom6);
	}

	N2 = (coef & 0xff000000) >> 24;
	M2 = (coef & 0x00ff0000) >> 16;
	N1 = (coef & 0x0000ff00) >> 8;
	M1 = (coef & 0x000000ff);
	if ((ctrl & 0x80000000) && M1) {
		clk = ref * N1 / M1;
		if ((ctrl & 0x40000100) == 0x40000000) {
			if (M2)
				clk = clk * N2 / M2;
			else
				clk = 0;
		}
	}

	return clk;
}

static u32
read_clk(struct drm_device *dev, enum clk_src src)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	u32 mast = nv_rd32(device, 0x00c040);
	u32 P = 0;

	switch (src) {
	case clk_src_crystal:
		return device->crystal;
	case clk_src_href:
		return 100000; /* PCIE reference clock */
	case clk_src_hclk:
		return read_clk(dev, clk_src_href) * 27778 / 10000;
	case clk_src_hclkm3:
		return read_clk(dev, clk_src_hclk) * 3;
	case clk_src_hclkm3d2:
		return read_clk(dev, clk_src_hclk) * 3 / 2;
	case clk_src_host:
		switch (mast & 0x30000000) {
		case 0x00000000: return read_clk(dev, clk_src_href);
		case 0x10000000: break;
		case 0x20000000: /* !0x50 */
		case 0x30000000: return read_clk(dev, clk_src_hclk);
		}
		break;
	case clk_src_nvclk:
		if (!(mast & 0x00100000))
			P = (nv_rd32(device, 0x004028) & 0x00070000) >> 16;
		switch (mast & 0x00000003) {
		case 0x00000000: return read_clk(dev, clk_src_crystal) >> P;
		case 0x00000001: return read_clk(dev, clk_src_dom6);
		case 0x00000002: return read_pll(dev, 0x004020) >> P;
		case 0x00000003: return read_pll(dev, 0x004028) >> P;
		}
		break;
	case clk_src_sclk:
		P = (nv_rd32(device, 0x004020) & 0x00070000) >> 16;
		switch (mast & 0x00000030) {
		case 0x00000000:
			if (mast & 0x00000080)
				return read_clk(dev, clk_src_host) >> P;
			return read_clk(dev, clk_src_crystal) >> P;
		case 0x00000010: break;
		case 0x00000020: return read_pll(dev, 0x004028) >> P;
		case 0x00000030: return read_pll(dev, 0x004020) >> P;
		}
		break;
	case clk_src_mclk:
		P = (nv_rd32(device, 0x004008) & 0x00070000) >> 16;
		if (nv_rd32(device, 0x004008) & 0x00000200) {
			switch (mast & 0x0000c000) {
			case 0x00000000:
				return read_clk(dev, clk_src_crystal) >> P;
			case 0x00008000:
			case 0x0000c000:
				return read_clk(dev, clk_src_href) >> P;
			}
		} else {
			return read_pll(dev, 0x004008) >> P;
		}
		break;
	case clk_src_vdec:
		P = (read_div(dev) & 0x00000700) >> 8;
		switch (nv_device(drm->device)->chipset) {
		case 0x84:
		case 0x86:
		case 0x92:
		case 0x94:
		case 0x96:
		case 0xa0:
			switch (mast & 0x00000c00) {
			case 0x00000000:
				if (nv_device(drm->device)->chipset == 0xa0) /* wtf?? */
					return read_clk(dev, clk_src_nvclk) >> P;
				return read_clk(dev, clk_src_crystal) >> P;
			case 0x00000400:
				return 0;
			case 0x00000800:
				if (mast & 0x01000000)
					return read_pll(dev, 0x004028) >> P;
				return read_pll(dev, 0x004030) >> P;
			case 0x00000c00:
				return read_clk(dev, clk_src_nvclk) >> P;
			}
			break;
		case 0x98:
			switch (mast & 0x00000c00) {
			case 0x00000000:
				return read_clk(dev, clk_src_nvclk) >> P;
			case 0x00000400:
				return 0;
			case 0x00000800:
				return read_clk(dev, clk_src_hclkm3d2) >> P;
			case 0x00000c00:
				return read_clk(dev, clk_src_mclk) >> P;
			}
			break;
		}
		break;
	case clk_src_dom6:
		switch (nv_device(drm->device)->chipset) {
		case 0x50:
		case 0xa0:
			return read_pll(dev, 0x00e810) >> 2;
		case 0x84:
		case 0x86:
		case 0x92:
		case 0x94:
		case 0x96:
		case 0x98:
			P = (read_div(dev) & 0x00000007) >> 0;
			switch (mast & 0x0c000000) {
			case 0x00000000: return read_clk(dev, clk_src_href);
			case 0x04000000: break;
			case 0x08000000: return read_clk(dev, clk_src_hclk);
			case 0x0c000000:
				return read_clk(dev, clk_src_hclkm3) >> P;
			}
			break;
		default:
			break;
		}
	default:
		break;
	}

	NV_DEBUG(drm, "unknown clock source %d 0x%08x\n", src, mast);
	return 0;
}

int
nv50_pm_clocks_get(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	if (nv_device(drm->device)->chipset == 0xaa ||
	    nv_device(drm->device)->chipset == 0xac)
		return 0;

	perflvl->core   = read_clk(dev, clk_src_nvclk);
	perflvl->shader = read_clk(dev, clk_src_sclk);
	perflvl->memory = read_clk(dev, clk_src_mclk);
	if (nv_device(drm->device)->chipset != 0x50) {
		perflvl->vdec = read_clk(dev, clk_src_vdec);
		perflvl->dom6 = read_clk(dev, clk_src_dom6);
	}

	return 0;
}

struct nv50_pm_state {
	struct nouveau_pm_level *perflvl;
	struct hwsq_ucode eclk_hwsq;
	struct hwsq_ucode mclk_hwsq;
	u32 mscript;
	u32 mmast;
	u32 mctrl;
	u32 mcoef;
};

static u32
calc_pll(struct drm_device *dev, u32 reg, struct nvbios_pll *pll,
	 u32 clk, int *N1, int *M1, int *log2P)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_bios *bios = nouveau_bios(device);
	struct nouveau_clock *pclk = nouveau_clock(device);
	struct nouveau_pll_vals coef;
	int ret;

	ret = nvbios_pll_parse(bios, reg, pll);
	if (ret)
		return 0;

	pll->vco2.max_freq = 0;
	pll->refclk = read_pll_ref(dev, reg);
	if (!pll->refclk)
		return 0;

	ret = pclk->pll_calc(pclk, pll, clk, &coef);
	if (ret == 0)
		return 0;

	*N1 = coef.N1;
	*M1 = coef.M1;
	*log2P = coef.log2P;
	return ret;
}

static inline u32
calc_div(u32 src, u32 target, int *div)
{
	u32 clk0 = src, clk1 = src;
	for (*div = 0; *div <= 7; (*div)++) {
		if (clk0 <= target) {
			clk1 = clk0 << (*div ? 1 : 0);
			break;
		}
		clk0 >>= 1;
	}

	if (target - clk0 <= clk1 - target)
		return clk0;
	(*div)--;
	return clk1;
}

static inline u32
clk_same(u32 a, u32 b)
{
	return ((a / 1000) == (b / 1000));
}

static void
mclk_precharge(struct nouveau_mem_exec_func *exec)
{
	struct nv50_pm_state *info = exec->priv;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;

	hwsq_wr32(hwsq, 0x1002d4, 0x00000001);
}

static void
mclk_refresh(struct nouveau_mem_exec_func *exec)
{
	struct nv50_pm_state *info = exec->priv;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;

	hwsq_wr32(hwsq, 0x1002d0, 0x00000001);
}

static void
mclk_refresh_auto(struct nouveau_mem_exec_func *exec, bool enable)
{
	struct nv50_pm_state *info = exec->priv;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;

	hwsq_wr32(hwsq, 0x100210, enable ? 0x80000000 : 0x00000000);
}

static void
mclk_refresh_self(struct nouveau_mem_exec_func *exec, bool enable)
{
	struct nv50_pm_state *info = exec->priv;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;

	hwsq_wr32(hwsq, 0x1002dc, enable ? 0x00000001 : 0x00000000);
}

static void
mclk_wait(struct nouveau_mem_exec_func *exec, u32 nsec)
{
	struct nv50_pm_state *info = exec->priv;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;

	if (nsec > 1000)
		hwsq_usec(hwsq, (nsec + 500) / 1000);
}

static u32
mclk_mrg(struct nouveau_mem_exec_func *exec, int mr)
{
	struct nouveau_device *device = nouveau_dev(exec->dev);
	if (mr <= 1)
		return nv_rd32(device, 0x1002c0 + ((mr - 0) * 4));
	if (mr <= 3)
		return nv_rd32(device, 0x1002e0 + ((mr - 2) * 4));
	return 0;
}

static void
mclk_mrs(struct nouveau_mem_exec_func *exec, int mr, u32 data)
{
	struct nouveau_device *device = nouveau_dev(exec->dev);
	struct nouveau_fb *pfb = nouveau_fb(device);
	struct nv50_pm_state *info = exec->priv;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;

	if (mr <= 1) {
		if (pfb->ram->ranks > 1)
			hwsq_wr32(hwsq, 0x1002c8 + ((mr - 0) * 4), data);
		hwsq_wr32(hwsq, 0x1002c0 + ((mr - 0) * 4), data);
	} else
	if (mr <= 3) {
		if (pfb->ram->ranks > 1)
			hwsq_wr32(hwsq, 0x1002e8 + ((mr - 2) * 4), data);
		hwsq_wr32(hwsq, 0x1002e0 + ((mr - 2) * 4), data);
	}
}

static void
mclk_clock_set(struct nouveau_mem_exec_func *exec)
{
	struct nouveau_device *device = nouveau_dev(exec->dev);
	struct nv50_pm_state *info = exec->priv;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;
	u32 ctrl = nv_rd32(device, 0x004008);

	info->mmast = nv_rd32(device, 0x00c040);
	info->mmast &= ~0xc0000000; /* get MCLK_2 from HREF */
	info->mmast |=  0x0000c000; /* use MCLK_2 as MPLL_BYPASS clock */

	hwsq_wr32(hwsq, 0xc040, info->mmast);
	hwsq_wr32(hwsq, 0x4008, ctrl | 0x00000200); /* bypass MPLL */
	if (info->mctrl & 0x80000000)
		hwsq_wr32(hwsq, 0x400c, info->mcoef);
	hwsq_wr32(hwsq, 0x4008, info->mctrl);
}

static void
mclk_timing_set(struct nouveau_mem_exec_func *exec)
{
	struct nouveau_device *device = nouveau_dev(exec->dev);
	struct nv50_pm_state *info = exec->priv;
	struct nouveau_pm_level *perflvl = info->perflvl;
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;
	int i;

	for (i = 0; i < 9; i++) {
		u32 reg = 0x100220 + (i * 4);
		u32 val = nv_rd32(device, reg);
		if (val != perflvl->timing.reg[i])
			hwsq_wr32(hwsq, reg, perflvl->timing.reg[i]);
	}
}

static int
calc_mclk(struct drm_device *dev, struct nouveau_pm_level *perflvl,
	  struct nv50_pm_state *info)
{
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nouveau_device *device = nouveau_dev(dev);
	u32 crtc_mask = 0; /*XXX: nv50_display_active_crtcs(dev); */
	struct nouveau_mem_exec_func exec = {
		.dev = dev,
		.precharge = mclk_precharge,
		.refresh = mclk_refresh,
		.refresh_auto = mclk_refresh_auto,
		.refresh_self = mclk_refresh_self,
		.wait = mclk_wait,
		.mrg = mclk_mrg,
		.mrs = mclk_mrs,
		.clock_set = mclk_clock_set,
		.timing_set = mclk_timing_set,
		.priv = info
	};
	struct hwsq_ucode *hwsq = &info->mclk_hwsq;
	struct nvbios_pll pll;
	int N, M, P;
	int ret;

	/* use pcie refclock if possible, otherwise use mpll */
	info->mctrl  = nv_rd32(device, 0x004008);
	info->mctrl &= ~0x81ff0200;
	if (clk_same(perflvl->memory, read_clk(dev, clk_src_href))) {
		info->mctrl |= 0x00000200 | (pll.bias_p << 19);
	} else {
		ret = calc_pll(dev, 0x4008, &pll, perflvl->memory, &N, &M, &P);
		if (ret == 0)
			return -EINVAL;

		info->mctrl |= 0x80000000 | (P << 22) | (P << 16);
		info->mctrl |= pll.bias_p << 19;
		info->mcoef  = (N << 8) | M;
	}

	/* build the ucode which will reclock the memory for us */
	hwsq_init(hwsq);
	if (crtc_mask) {
		hwsq_op5f(hwsq, crtc_mask, 0x00); /* wait for scanout */
		hwsq_op5f(hwsq, crtc_mask, 0x01); /* wait for vblank */
	}
	if (nv_device(drm->device)->chipset >= 0x92)
		hwsq_wr32(hwsq, 0x611200, 0x00003300); /* disable scanout */
	hwsq_setf(hwsq, 0x10, 0); /* disable bus access */
	hwsq_op5f(hwsq, 0x00, 0x01); /* no idea :s */

	ret = nouveau_mem_exec(&exec, perflvl);
	if (ret)
		return ret;

	hwsq_setf(hwsq, 0x10, 1); /* enable bus access */
	hwsq_op5f(hwsq, 0x00, 0x00); /* no idea, reverse of 0x00, 0x01? */
	if (nv_device(drm->device)->chipset >= 0x92)
		hwsq_wr32(hwsq, 0x611200, 0x00003330); /* enable scanout */
	hwsq_fini(hwsq);
	return 0;
}

void *
nv50_pm_clocks_pre(struct drm_device *dev, struct nouveau_pm_level *perflvl)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	struct nv50_pm_state *info;
	struct hwsq_ucode *hwsq;
	struct nvbios_pll pll;
	u32 out, mast, divs, ctrl;
	int clk, ret = -EINVAL;
	int N, M, P1, P2;

	if (nv_device(drm->device)->chipset == 0xaa ||
	    nv_device(drm->device)->chipset == 0xac)
		return ERR_PTR(-ENODEV);

	info = kmalloc(sizeof(*info), GFP_KERNEL);
	if (!info)
		return ERR_PTR(-ENOMEM);
	info->perflvl = perflvl;

	/* memory: build hwsq ucode which we'll use to reclock memory.
	 *         use pcie refclock if possible, otherwise use mpll */
	info->mclk_hwsq.len = 0;
	if (perflvl->memory) {
		ret = calc_mclk(dev, perflvl, info);
		if (ret)
			goto error;
		info->mscript = perflvl->memscript;
	}

	divs = read_div(dev);
	mast = info->mmast;

	/* start building HWSQ script for engine reclocking */
	hwsq = &info->eclk_hwsq;
	hwsq_init(hwsq);
	hwsq_setf(hwsq, 0x10, 0); /* disable bus access */
	hwsq_op5f(hwsq, 0x00, 0x01); /* wait for access disabled? */

	/* vdec/dom6: switch to "safe" clocks temporarily */
	if (perflvl->vdec) {
		mast &= ~0x00000c00;
		divs &= ~0x00000700;
	}

	if (perflvl->dom6) {
		mast &= ~0x0c000000;
		divs &= ~0x00000007;
	}

	hwsq_wr32(hwsq, 0x00c040, mast);

	/* vdec: avoid modifying xpll until we know exactly how the other
	 * clock domains work, i suspect at least some of them can also be
	 * tied to xpll...
	 */
	if (perflvl->vdec) {
		/* see how close we can get using nvclk as a source */
		clk = calc_div(perflvl->core, perflvl->vdec, &P1);

		/* see how close we can get using xpll/hclk as a source */
		if (nv_device(drm->device)->chipset != 0x98)
			out = read_pll(dev, 0x004030);
		else
			out = read_clk(dev, clk_src_hclkm3d2);
		out = calc_div(out, perflvl->vdec, &P2);

		/* select whichever gets us closest */
		if (abs((int)perflvl->vdec - clk) <=
		    abs((int)perflvl->vdec - out)) {
			if (nv_device(drm->device)->chipset != 0x98)
				mast |= 0x00000c00;
			divs |= P1 << 8;
		} else {
			mast |= 0x00000800;
			divs |= P2 << 8;
		}
	}

	/* dom6: nfi what this is, but we're limited to various combinations
	 * of the host clock frequency
	 */
	if (perflvl->dom6) {
		if (clk_same(perflvl->dom6, read_clk(dev, clk_src_href))) {
			mast |= 0x00000000;
		} else
		if (clk_same(perflvl->dom6, read_clk(dev, clk_src_hclk))) {
			mast |= 0x08000000;
		} else {
			clk = read_clk(dev, clk_src_hclk) * 3;
			clk = calc_div(clk, perflvl->dom6, &P1);

			mast |= 0x0c000000;
			divs |= P1;
		}
	}

	/* vdec/dom6: complete switch to new clocks */
	switch (nv_device(drm->device)->chipset) {
	case 0x92:
	case 0x94:
	case 0x96:
		hwsq_wr32(hwsq, 0x004800, divs);
		break;
	default:
		hwsq_wr32(hwsq, 0x004700, divs);
		break;
	}

	hwsq_wr32(hwsq, 0x00c040, mast);

	/* core/shader: make sure sclk/nvclk are disconnected from their
	 * PLLs (nvclk to dom6, sclk to hclk)
	 */
	if (nv_device(drm->device)->chipset < 0x92)
		mast = (mast & ~0x001000b0) | 0x00100080;
	else
		mast = (mast & ~0x000000b3) | 0x00000081;

	hwsq_wr32(hwsq, 0x00c040, mast);

	/* core: for the moment at least, always use nvpll */
	clk = calc_pll(dev, 0x4028, &pll, perflvl->core, &N, &M, &P1);
	if (clk == 0)
		goto error;

	ctrl  = nv_rd32(device, 0x004028) & ~0xc03f0100;
	mast &= ~0x00100000;
	mast |= 3;

	hwsq_wr32(hwsq, 0x004028, 0x80000000 | (P1 << 19) | (P1 << 16) | ctrl);
	hwsq_wr32(hwsq, 0x00402c, (N << 8) | M);

	/* shader: tie to nvclk if possible, otherwise use spll.  have to be
	 * very careful that the shader clock is at least twice the core, or
	 * some chipsets will be very unhappy.  i expect most or all of these
	 * cases will be handled by tying to nvclk, but it's possible there's
	 * corners
	 */
	ctrl = nv_rd32(device, 0x004020) & ~0xc03f0100;

	if (P1-- && perflvl->shader == (perflvl->core << 1)) {
		hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl);
		hwsq_wr32(hwsq, 0x00c040, 0x00000020 | mast);
	} else {
		clk = calc_pll(dev, 0x4020, &pll, perflvl->shader, &N, &M, &P1);
		if (clk == 0)
			goto error;
		ctrl |= 0x80000000;

		hwsq_wr32(hwsq, 0x004020, (P1 << 19) | (P1 << 16) | ctrl);
		hwsq_wr32(hwsq, 0x004024, (N << 8) | M);
		hwsq_wr32(hwsq, 0x00c040, 0x00000030 | mast);
	}

	hwsq_setf(hwsq, 0x10, 1); /* enable bus access */
	hwsq_op5f(hwsq, 0x00, 0x00); /* wait for access enabled? */
	hwsq_fini(hwsq);

	return info;
error:
	kfree(info);
	return ERR_PTR(ret);
}

static int
prog_hwsq(struct drm_device *dev, struct hwsq_ucode *hwsq)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nouveau_drm *drm = nouveau_drm(dev);
	u32 hwsq_data, hwsq_kick;
	int i;

	if (nv_device(drm->device)->chipset < 0x94) {
		hwsq_data = 0x001400;
		hwsq_kick = 0x00000003;
	} else {
		hwsq_data = 0x080000;
		hwsq_kick = 0x00000001;
	}
	/* upload hwsq ucode */
	nv_mask(device, 0x001098, 0x00000008, 0x00000000);
	nv_wr32(device, 0x001304, 0x00000000);
	if (nv_device(drm->device)->chipset >= 0x92)
		nv_wr32(device, 0x001318, 0x00000000);
	for (i = 0; i < hwsq->len / 4; i++)
		nv_wr32(device, hwsq_data + (i * 4), hwsq->ptr.u32[i]);
	nv_mask(device, 0x001098, 0x00000018, 0x00000018);

	/* launch, and wait for completion */
	nv_wr32(device, 0x00130c, hwsq_kick);
	if (!nv_wait(device, 0x001308, 0x00000100, 0x00000000)) {
		NV_ERROR(drm, "hwsq ucode exec timed out\n");
		NV_ERROR(drm, "0x001308: 0x%08x\n", nv_rd32(device, 0x001308));
		for (i = 0; i < hwsq->len / 4; i++) {
			NV_ERROR(drm, "0x%06x: 0x%08x\n", 0x1400 + (i * 4),
				 nv_rd32(device, 0x001400 + (i * 4)));
		}

		return -EIO;
	}

	return 0;
}

int
nv50_pm_clocks_set(struct drm_device *dev, void *data)
{
	struct nouveau_device *device = nouveau_dev(dev);
	struct nv50_pm_state *info = data;
	struct bit_entry M;
	int ret = -EBUSY;

	/* halt and idle execution engines */
	nv_mask(device, 0x002504, 0x00000001, 0x00000001);
	if (!nv_wait(device, 0x002504, 0x00000010, 0x00000010))
		goto resume;
	if (!nv_wait(device, 0x00251c, 0x0000003f, 0x0000003f))
		goto resume;

	/* program memory clock, if necessary - must come before engine clock
	 * reprogramming due to how we construct the hwsq scripts in pre()
	 */
#define nouveau_bios_init_exec(a,b) nouveau_bios_run_init_table((a), (b), NULL, 0)
	if (info->mclk_hwsq.len) {
		/* execute some scripts that do ??? from the vbios.. */
		if (!bit_table(dev, 'M', &M) && M.version == 1) {
			if (M.length >= 6)
				nouveau_bios_init_exec(dev, ROM16(M.data[5]));
			if (M.length >= 8)
				nouveau_bios_init_exec(dev, ROM16(M.data[7]));
			if (M.length >= 10)
				nouveau_bios_init_exec(dev, ROM16(M.data[9]));
			nouveau_bios_init_exec(dev, info->mscript);
		}

		ret = prog_hwsq(dev, &info->mclk_hwsq);
		if (ret)
			goto resume;
	}

	/* program engine clocks */
	ret = prog_hwsq(dev, &info->eclk_hwsq);

resume:
	nv_mask(device, 0x002504, 0x00000001, 0x00000000);
	kfree(info);
	return ret;
}
