/*
 *
 * MNH Clock Driver
 * Copyright (c) 2016-2018, Intel Corporation.
 *
 * This program is free software; you can redistribute it and/or modify it
 * under the terms and conditions of the GNU General Public License,
 * version 2, as published by the Free Software Foundation.
 *
 * This program is distributed in the hope it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 */

#include <linux/delay.h>
#include <linux/err.h>
#include <linux/io.h>
#include <linux/module.h>
#include <linux/sysfs.h>
#include <linux/device.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/interrupt.h>
#include <linux/gpio.h>
#include <linux/intel-hwio.h>
#include <linux/spinlock.h>
#include <soc/mnh/mnh-hwio-scu.h>
#include <soc/mnh/mnh-hwio-cpu.h>
#include <soc/mnh/mnh-hwio-ddr-ctl.h>
#include <linux/arm-smccc.h>
#include "mnh-clk.h"

#define PLL_UNLOCK 0x4CD9
#define REF_FREQ_SEL 0x8
#define MAX_STR_COPY 9
#define LP4_LPC_FREQ_SWITCH 0x8A
#define SYS200_CLK_KHZ 200000

#define DEVICE_NAME "mnh_freq_cooling"

#define LP_CMD_EXIT_LP 0x81

#define MR_READ_SBIT 23
#define LP_CMD_SBIT 5

#define INIT_REFRESH_RATE 0x06
#define MNH_PM_FSP_SET_AARCH64	0xC300FF05
#define MNH_PM_FSP_GET_AARCH64	0xC300FF06

static unsigned long invoke_mnh_fn_smc(unsigned long function_id,
			unsigned long arg0, unsigned long arg1,
			unsigned long arg2)
{
	struct arm_smccc_res res;

	arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
	return res.a0;
}


/* consider moving to struct */
u8 previous_refresh_rate;
u32 mnh_ddr_refresh_msec = 50;
struct delayed_work mnh_ddr_adjust_refresh_work;

#define MNH_CPU_IN(reg) \
HW_IN(mnh_dev->cpuaddr, CPU, reg)
#define MNH_DDR_CTL_IN(reg) \
HW_IN(mnh_dev->ddraddr, DDR_CTL, reg)
#define MNH_DDR_CTL_INf(reg, fld) \
HW_INf(mnh_dev->ddraddr, DDR_CTL, reg, fld)
#define MNH_DDR_CTL_OUTf(reg, fld, val) \
HW_OUTf(mnh_dev->ddraddr, DDR_CTL, reg, fld, val)
#define MNH_DDR_CTL_OUT(reg, val) \
HW_OUT(mnh_dev->ddraddr, DDR_CTL, reg, val)

/* If IPU clock is driven by CPU_IPU PLL
 * calculate IPU divider based on CPU clk and divider
 * CPU CLK < 850: IPU_CLK_DIV = ((CPU_CLK_DIV+1)*2-1)
 * CPU CLK > 850: IPU_CLK_DIV = ((CPU_CLK_DIV+1)*2)
 */
#define IPU_DIV_BY_CPU(freq, div) \
	((freq < 850) ? ((div+1)*2-1):((div+1)*2))

int mnh_ddr_clr_int_status(void);
static void mnh_ddr_adjust_refresh_worker(struct work_struct *work);
static void mnh_ddr_disable_lp(void);
static u8 lp_counters[4];

enum mnh_refclk_type {
	REFCLK_KHZ_19200 = 0,
	REFCLK_KHZ_24000,
	REFCLK_KHZ_MAX
};

enum mnh_pll_type {
	CPU_CLK = 0,
	IPU_CLK
};

enum mnh_lpddr_lpc_rsp_type {
	LPC_CMD_NOERR = 0,
	LPC_CMD_ERR = 1
};

enum mnh_ipu_clk_src {
	CPU_IPU_PLL = 0,/*Both CPU and IPU Clock is derived from same PLL */
	IPU_PLL	/* IPU Clock is derived from IPU PLL */
};

struct freq_reg_table {
	char *freq_str;
	int fbdiv;
	int postdiv1;
	int postdiv2;
	int clk_div;
};

/* PLL reference clk table */
static uint32_t refclk_khz_tables[] = {
	19200,	/* 19.2 MHz */
	24000	/* 24.0 MHz */
};

/* SYS200 frequency calculation tables
 * SYS200  FBDIV FBDIV	POSTDIV1 POSTDIV2 FOUTPOSTDIV CLKDIV CLKFreq
 * CPU	 200	 104	 2	  1	   200.000	0	 200.000
 * IPU	 200	 104	 2	  1	   200.000	1	 100.000
 */
static const struct freq_reg_table sys200_reg_tables[] = {
	{"200", 104, 2, 1, 0},	/* CPU, 200 MHz */
	{"100", 104, 2, 1, 1}	/* IPU, 100 MHz */
};

/* CPU clock frequency calculation table */
static const struct freq_reg_table cpu_reg_tables[][CPU_FREQ_MAX+1] = {
	/* refclk = 19.2 MHz */
	{
		{"200", 125, 6, 2, 0},	/* 200 MHz */
		{"400", 125, 6, 1, 0},	/* 400 MHz */
		{"600", 125, 4, 1, 0},	/* 600 MHz */
		{"800", 125, 3, 1, 0},	/* 800 MHz */
		{"950", 99, 2, 1, 0}	/* 950 MHz */
	},
	/* refclk = 24.0 MHz */
	{
		{"200", 100, 6, 2, 0},	/* 200 MHz */
		{"400", 100, 6, 1, 0},	/* 400 MHz */
		{"600", 100, 4, 1, 0},	/* 600 MHz */
		{"800", 100, 3, 1, 0},	/* 800 MHz */
		{"950", 79, 2, 1, 0}	/* 948 MHz */
	}
};

/* IPU clock frequency calculation table */
static const struct freq_reg_table ipu_reg_tables[][IPU_FREQ_MAX+1] = {
	/* refclk = 19.2 MHz */
	{
		{"100", 125, 6, 2, 1},	/* 100 MHz */
		{"200", 125, 6, 1, 1},	/* 200 MHz */
		{"300", 125, 4, 1, 1},	/* 300 MHz */
		{"400", 125, 6, 1, 0},	/* 400 MHz */
		{"425", 133, 6, 1, 0}	/* 425 MHz */
	},
	/* refclk = 24.0 MHz */
	{
		{"100", 100, 6, 2, 1},	/* 100 MHz */
		{"200", 100, 6, 1, 1},	/* 200 MHz */
		{"300", 100, 4, 1, 1},	/* 300 MHz */
		{"400", 100, 6, 1, 0},	/* 400 MHz */
		{"425", 106, 6, 1, 0}	/* 424 MHz */
	}
};

struct mnh_freq_cooling_device {
	struct device *dev;
	void __iomem *regs;
	void __iomem *ddraddr;
	void __iomem *cpuaddr;
	int ddr_irq;
	struct completion ddr_mrr;
	u32 ddr_mrr4;
	struct completion ddr_lp_cmd;
	struct completion ddr_switch;
	enum mnh_cpu_freq_type cpu_freq;
	enum mnh_lpddr_freq_type ddr_freq;
	enum mnh_refclk_type refclk;
	const struct freq_reg_table *cpu_pllcfg;
	const struct freq_reg_table *ipu_pllcfg;
	spinlock_t reset_lock;
	uint32_t fsp_cycle;
};

static struct mnh_freq_cooling_device *mnh_dev;

/* Frequency calculation by PLL configuration
 * @cfg: struct freq_reg_table with pll config information.
 * Return: freq MHz.
 *
 * This returns current frequency in MHz unit
 * freq = (refclk*fbdiv)/((postdiv1*postdiv2)*(clk_div+1))
 */
static int mnh_freq_get_by_pll(struct freq_reg_table cfg, int sys200)
{
	uint32_t freq_khz;

	if (sys200)
		freq_khz = (SYS200_CLK_KHZ)/(cfg.clk_div+1);
	else
		freq_khz = (refclk_khz_tables[mnh_dev->refclk]*cfg.fbdiv)/
			((cfg.postdiv1*cfg.postdiv2)*(cfg.clk_div+1));

	return (freq_khz/1000);
}

static int mnh_get_cpu_pllcfg(struct freq_reg_table *pllcfg)
{
	int sys200;

	/* Check CPU is in SYS200 mode */
	sys200 = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE);

	/* Calculate frequency by PLL configuration */
	pllcfg->fbdiv = HW_INf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV,
			       FBDIV);
	pllcfg->postdiv1 = HW_INf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV,
				  POSTDIV1);
	pllcfg->postdiv2 = HW_INf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV,
				  POSTDIV2);
	pllcfg->clk_div = HW_INf(mnh_dev->regs, SCU, CCU_CLK_DIV, CPU_CLK_DIV);

	return mnh_freq_get_by_pll(*pllcfg, sys200);
}

static int mnh_get_ipu_pllcfg(struct freq_reg_table *pllcfg)
{
	int sys200, clk_src;

	/* Check IPU is in SYS200 mode */
	clk_src = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC);
	sys200 = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE);
	if (sys200 && (clk_src == IPU_PLL))
		sys200 = 0;

	/* Calculate frequency by PLL configuration */
	if (clk_src == CPU_IPU_PLL) {
		pllcfg->fbdiv = HW_INf(mnh_dev->regs, SCU,
				       CPU_IPU_PLL_INTGR_DIV, FBDIV);
		pllcfg->postdiv1 = HW_INf(mnh_dev->regs, SCU,
					  CPU_IPU_PLL_INTGR_DIV, POSTDIV1);
		pllcfg->postdiv2 = HW_INf(mnh_dev->regs, SCU,
					  CPU_IPU_PLL_INTGR_DIV, POSTDIV2);
	} else {
		pllcfg->fbdiv = HW_INf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV,
				       FBDIV);
		pllcfg->postdiv1 = HW_INf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV,
					  POSTDIV1);
		pllcfg->postdiv2 = HW_INf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV,
					  POSTDIV2);
	}
	pllcfg->clk_div = HW_INf(mnh_dev->regs, SCU, CCU_CLK_DIV, IPU_CLK_DIV);

	return mnh_freq_get_by_pll(*pllcfg, sys200);
}

static int mnh_get_cpu_freq(void)
{
	struct freq_reg_table pllcfg;

	return mnh_get_cpu_pllcfg(&pllcfg);
}

static int mnh_get_ipu_freq(void)
{
	struct freq_reg_table pllcfg;

	return mnh_get_ipu_pllcfg(&pllcfg);
}

int mnh_cpu_freq_to_index(void)
{
	int fbdiv, postdiv1, postdiv2, clk_div;
	int sys200, i;
	const struct freq_reg_table *table = cpu_reg_tables[mnh_dev->refclk];

	sys200 = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE);
	if (sys200)
		return 0;

	fbdiv = HW_INf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV, FBDIV);
	postdiv1 = HW_INf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV, POSTDIV1);
	postdiv2 = HW_INf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV, POSTDIV2);
	clk_div = HW_INf(mnh_dev->regs, SCU, CCU_CLK_DIV, CPU_CLK_DIV);

	for (i = 0; i < ARRAY_SIZE(cpu_reg_tables[0]); i++) {
		if ((fbdiv == table[i].fbdiv) &&
		    (postdiv1 == table[i].postdiv1) &&
		    (postdiv2 == table[i].postdiv2) &&
		    (clk_div == table[i].clk_div))
			return i;
	}

	return -EINVAL;
}

int mnh_ipu_freq_to_index(void)
{
	int fbdiv, postdiv1, postdiv2, clk_div;
	int sys200, ipu_clk_src;
	int i;
	const struct freq_reg_table *table = ipu_reg_tables[mnh_dev->refclk];

	sys200 = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE);
	if (sys200)
		return 0;

	ipu_clk_src = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC);
	if (ipu_clk_src == CPU_IPU_PLL)
		return mnh_cpu_freq_to_index();

	fbdiv = HW_INf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV, FBDIV);
	postdiv1 = HW_INf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV, POSTDIV1);
	postdiv2 = HW_INf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV, POSTDIV2);
	clk_div = HW_INf(mnh_dev->regs, SCU, CCU_CLK_DIV, IPU_CLK_DIV);

	for (i = 0; i < ARRAY_SIZE(ipu_reg_tables[0]); i++) {
		if ((fbdiv == table[i].fbdiv) &&
		    (postdiv1 == table[i].postdiv1) &&
		    (postdiv2 == table[i].postdiv2) &&
		    (clk_div == table[i].clk_div))
			return i;
	}

	return -EINVAL;
}

/**
 * CPU clock controller
 * @index: int with frquency table index info.
 * Return: 0 on success, an error code otherwise.
 *
 * 1PLL(CPU_IPU PLL) for CPU/IPU clocks. Since CPU and IPU clocks are derived
 * from same PLL in this mode, there would be restriction on achedivable clock
 * frequencies for CPU and IPU clocks. IPU clock would be half of CPU clock. Any
 * frequency changes is achieved by changing FBDIV(integer feedback division) of
 * the PLL(PLL output = FBDIV * REFCLK frequency).
 * Default CPU_CLK_DIV : 1, IPU_CLK_DIV: 2
 * CLK = (REFCLK FREQ * FBDIV) / ((POSTDIV1 * POSTDIV2) * (CLK_DIV + 1))
 */
int mnh_cpu_freq_change(int index)
{
	int lock = 0;
	int sys200, ipu_div = 0;
	const struct freq_reg_table *pllcfg;
	bool use_sys200;
	int ipu_clk_src;
	int cpu_freq, old_cpu_freq;
	int clk_div;

	if (!mnh_dev)
		return -ENODEV;

	if (index < CPU_FREQ_MIN || index > CPU_FREQ_MAX)
		return -EINVAL;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, index);

	/* Get PLL config from reg table */
	pllcfg = &mnh_dev->cpu_pllcfg[index];

	/* Get current SYS200 mode */
	sys200 = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE);

	/* Calculate frequency from PLL config */
	old_cpu_freq = mnh_get_cpu_freq();
	cpu_freq = mnh_freq_get_by_pll(*pllcfg, 0);

	/* Check to see if we need to change the frequency */
	if (old_cpu_freq == cpu_freq) {
		dev_dbg(mnh_dev->dev, "%s: already at desired frequency\n",
			__func__);
		return 0;
	}

	/* Check to see if we should use SYS200 mode */
	if (cpu_freq == 200) {
		use_sys200 = true;
		clk_div = 0;
	} else {
		use_sys200 = false;
		clk_div = pllcfg->clk_div;
	}

	/* Unlock PLL access */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, PLL_UNLOCK);

	/* Switch to SYS200 mode */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE, 0x1);

	/* Read current IPU clock source */
	ipu_clk_src = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC);

	/* Latch current settings going to PLL */
	HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FRZ_PLL_IN, 1);

	/* Configure CPU PLL */
	if (use_sys200) {
		/* Power down PLL and PLL output */
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, PD, 1);
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FOUTPOSTDIVPD, 1);
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FRZ_PLL_IN, 0);
	} else {
		/* Configure FBDIV first and set POSTDIV1, POSTDIV2
		* Compute dividers based on REF_FREQ_SEL hardware strap
		* Check FBDIV * REFCLK is witin VCO range (950-3800MHz)
		*/
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV, FBDIV,
			pllcfg->fbdiv);
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV, POSTDIV1,
			pllcfg->postdiv1);
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_INTGR_DIV, POSTDIV2,
			pllcfg->postdiv2);

		/* Set FOUTPOSTDIVPD = 1 to avoid glitches to output */
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FOUTPOSTDIVPD, 1);

		/* Apply the updated PLL configurations  */
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FRZ_PLL_IN, 0);

		/* Power up PLL */
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, PD, 0);

		/* Wait for minimum 128REFCLK, 6.7usec for 19.2MHz refclk
		* before checking PLL lock
		*/
		udelay(7);

		/* Check PLL is locked */
		do {
			lock = HW_INf(mnh_dev->regs,
				SCU, CPU_IPU_PLL_STS, LOCK);
		} while (lock != 1);

		/* Set FOUTPOSTDIVPD = 0 to ensure clk output is un-gated */
		HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FOUTPOSTDIVPD, 0);
	}

	/* Configure CPU_CLK_DIV */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_DIV, CPU_CLK_DIV, clk_div);

	/* If IPU clock is driven by CPU_IPU PLL,
	*  configure IPU divider based on CPU divider value
	*  to make sure IPU clock does not go over its limit
	*/
	if (ipu_clk_src == CPU_IPU_PLL) {
		ipu_div = IPU_DIV_BY_CPU(cpu_freq, clk_div);
		HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_DIV, IPU_CLK_DIV, ipu_div);
	}

	/* Set final CPU clock source */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE,
		use_sys200);

	mnh_dev->cpu_freq = index;

	/* Lock PLL access */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, 0);

	return 0;
}
EXPORT_SYMBOL(mnh_cpu_freq_change);

/**
 * IPU clock controller
 * @index: int with frquency table index info.
 * Return: 0 on success, an error code otherwise.
 *
 * Until IPU clock is configured, IPU clock is driven from PCIe or CPU_IPU PLL,
 * and once it is configured by driver, IPU PLL is used to control IPU clock.
 * To turn off IPU PLL, CPU frequency needs to be set to 200MHz to put
 * both CPU and IPU into SYS200 mode.
 */
int mnh_ipu_freq_change(int index)
{
	int lock = 0;
	const struct freq_reg_table *pllcfg;
	bool use_cpu_clk_src;
	int ipu_freq, old_ipu_freq, cpu_freq;
	int clk_div;
	int ipu_clken;

	if (!mnh_dev)
		return -ENODEV;

	if (index < IPU_FREQ_MIN || index > IPU_FREQ_MAX)
		return -EINVAL;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, index);

	/* Get PLL config from reg table */
	pllcfg = &mnh_dev->ipu_pllcfg[index];

	/* Calculate frequency from PLL config */
	old_ipu_freq = mnh_get_ipu_freq();
	cpu_freq = mnh_get_cpu_freq();
	ipu_freq = mnh_freq_get_by_pll(*pllcfg, 0);

	/* Check to see if we need to change the frequency */
	if (old_ipu_freq == ipu_freq) {
		dev_dbg(mnh_dev->dev, "%s: already at desired frequency\n",
			__func__);
		return 0;
	}

	/* TODO: determine if we can get to IPU frequency from CPU frequency */
	if ((cpu_freq == 200) && (ipu_freq == 100)) {
		use_cpu_clk_src = true;
		clk_div = 1;
	} else if ((cpu_freq == 200) && (ipu_freq == 200)) {
		use_cpu_clk_src = true;
		clk_div = 0;
	} else {
		use_cpu_clk_src = false;
		clk_div = pllcfg->clk_div;
	}

	/* Disable IPU_PLL clock output */
	ipu_clken = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLKEN);
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLKEN, 0x0);

	/* Unlock PLL access */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, PLL_UNLOCK);

	/* Switch to stable clock before freq switch to avoid glitches */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC, CPU_IPU_PLL);

	/* Set FRZ_PLL_IN=1 to latch the current settings going to PLL */
	HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FRZ_PLL_IN, 1);

	/* Configure IPU PLL */
	if (use_cpu_clk_src) {
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, PD, 1);
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FOUTPOSTDIVPD, 1);
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FRZ_PLL_IN, 0);
	} else {
		/* Configure FBDIV first and set POSTDIV1, POSTDIV2 */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV, FBDIV, pllcfg->fbdiv);
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV, POSTDIV1,
			pllcfg->postdiv1);
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_INTGR_DIV, POSTDIV2,
			pllcfg->postdiv2);

		/* Set FOUTPOSTDIVPD = 1 to avoid glitches to output */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FOUTPOSTDIVPD, 1);

		/* Apply the updated PLL configurations  */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FRZ_PLL_IN, 0);

		/* Power up PLL */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, PD, 0);

		/* Wait for minimum 128REFCLK, 6.7usec for 19.2MHz refclk
		* before checking PLL lock
		*/
		udelay(7);

		/* Check PLL is locked */
		do {
			lock = HW_INf(mnh_dev->regs, SCU, IPU_PLL_STS, LOCK);
		} while (lock != 1);

		/* Set FOUTPOSTDIVPD = 0 to ensure clk output is un-gated */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FOUTPOSTDIVPD, 0);
	}

	/* Configure IPU_CLK_DIV */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_DIV, IPU_CLK_DIV, clk_div);

	/* Go back to IPU PLL output */
	if (!use_cpu_clk_src)
		HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC, IPU_PLL);

	/* Lock PLL access */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, 0);

	/* Enable IPU_PLL clock output */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLKEN, ipu_clken);

	return 0;
}
EXPORT_SYMBOL(mnh_ipu_freq_change);

/**
 * LPDDR clock control driver
 * @index: int with frquency table index info.
 * Return: 0 on success, an error code otherwise.
 *
 * LPDDR clock is controlled by LPC instead of using direct PLL configuration.
 * Precondition:
 * LPDDR refclk pll should be enabled at cold boot and resume
 * LPDDR FSPx registers should be configured at cold boot and resume
 */
int mnh_lpddr_hw_freq_change(int index)
{
	int status = 0;

	if (!mnh_dev)
		return -ENODEV;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, index);

	if (index < LPDDR_FREQ_MIN || index > LPDDR_FREQ_MAX)
		return -EINVAL;

	/* Check the requested FSP is already in use */
	mnh_dev->ddr_freq = HW_INf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_STS,
		LPDDR4_CUR_FSP);
	if (mnh_dev->ddr_freq == index) {
		dev_dbg(mnh_dev->dev, "requested fsp%d is in use\n", index);
		return 0;
	}

	if (!HW_INxf(mnh_dev->regs, SCU,
		LPDDR4_FSP_SETTING, index, FSP_SYS200_MODE))
		mnh_lpddr_sys200_mode(false);

	/* Must resume below */
	cancel_delayed_work_sync(&mnh_ddr_adjust_refresh_work);

	/* Disable LPC SW override */
	HW_OUTf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_CFG,
		LP4_FSP_SW_OVERRIDE, 0);

	/* Configure FSP index */
	HW_OUTf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_CFG,
		LPC_FREQ_CHG_COPY_NUM, index);

	/* Configure LPC cmd for frequency switch */
	HW_OUTf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_CFG,
		LPC_EXT_CMD, LP4_LPC_FREQ_SWITCH);

	/* Initiate LPC cmd to LPDDR controller */
	dev_info(mnh_dev->dev, "lpddr freq switching from fsp%d to fsp%d\n",
		mnh_dev->ddr_freq, index);
	HW_OUTf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_CFG, LPC_EXT_CMD_REQ, 1);

	/* Wait until LPC cmd process is done */
	do {
		status = HW_INf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_STS,
			LPC_CMD_DONE);
	} while (status != 1);

	/* Clear LPC cmd status */
	HW_OUTf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_STS, LPC_CMD_DONE, 1);

	/* Check LPC error status */
	if (HW_INf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_STS, LPC_CMD_RSP)
		== LPC_CMD_ERR) {
		/* Clear error status */
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_STS,
			LPC_CMD_RSP, 1);
		dev_err(mnh_dev->dev, "Failed to process lpc cmd:0x%x\n",
			LP4_LPC_FREQ_SWITCH);
		return -1;
	}

	/* Check FSPx switch status */
	if (HW_INf(mnh_dev->regs, SCU, LPDDR4_LOW_POWER_STS, LPDDR4_CUR_FSP)
		!= index) {
		dev_err(mnh_dev->dev, "Failed to switch to fsp%d\n", index);
		return -1;
	}

	mnh_dev->ddr_freq = index;

	if (HW_INxf(mnh_dev->regs, SCU,
		LPDDR4_FSP_SETTING, index, FSP_SYS200_MODE))
		mnh_lpddr_sys200_mode(true);

	mnh_ddr_clr_int_status();

	/* reschedule refresh worker after cancel_delayed_work_sync */
	mnh_ddr_adjust_refresh_resume();

	return 0;
}
EXPORT_SYMBOL(mnh_lpddr_hw_freq_change);


int mnh_lpddr_sw_freq_change(int index)
{
	int ret = 0;
	static int iteration;
	if (!mnh_dev)
		return -ENODEV;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, index);

	if (index < LPDDR_FREQ_MIN || index > LPDDR_FREQ_MAX)
		return -EINVAL;

	/* Check the requested FSP is already in use */
	mnh_dev->ddr_freq = MNH_DDR_CTL_INf(133, CURRENT_REG_COPY);
	if (mnh_dev->ddr_freq == index) {
		dev_dbg(mnh_dev->dev, "requested fsp%d is in use\n", index);
		return 0;
	}

	if (!HW_INxf(mnh_dev->regs, SCU,
		LPDDR4_FSP_SETTING, index, FSP_SYS200_MODE))
		mnh_lpddr_sys200_mode(false);

	/* Must resume below */
	cancel_delayed_work_sync(&mnh_ddr_adjust_refresh_work);
	/* disable before entering SBL, as SBL won't do it */
	mnh_ddr_disable_lp();
	/* SBL will clear bits it pends on */
	mnh_ddr_clr_int_status();

	/* debug register */
	HW_OUTx(mnh_dev->regs, SCU, GPS, 3, 0);
	ret = invoke_mnh_fn_smc(MNH_PM_FSP_SET_AARCH64,
		index,
		virt_to_phys(&mnh_dev->fsp_cycle),
		0);
	if (ret) {
		dev_err(mnh_dev->dev, "Switch routine returned an error: %d %d\n",
			ret, HW_INx(mnh_dev->regs, SCU, GPS, 3));
		return -1;
	}
	/* Check FSPx switch status */
	if (MNH_DDR_CTL_INf(133, CURRENT_REG_COPY)
		!= index) {
		dev_err(mnh_dev->dev, "Failed to switch to fsp%d\n", index);
		return -1;
	} else {
		dev_dbg(mnh_dev->dev, "%s #%d.\n",
			__func__, iteration++);
	}

	mnh_dev->ddr_freq = index;

	if (HW_INxf(mnh_dev->regs, SCU,
		LPDDR4_FSP_SETTING, index, FSP_SYS200_MODE))
		mnh_lpddr_sys200_mode(true);

	mnh_ddr_clr_int_status();

	/* reschedule refresh worker after cancel_delayed_work_sync */
	mnh_ddr_adjust_refresh_resume();

	return 0;
}
EXPORT_SYMBOL(mnh_lpddr_sw_freq_change);

/**
 * LPDDR clock control driver
 * Return: 0 on success, an error code otherwise.
 *
 * LPDDR clock is derived from sys200 clk instead of separate lpddr clk
 */
int mnh_lpddr_sys200_mode(bool enable)
{
	int lock;

	if (!mnh_dev)
		return -ENODEV;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, enable);
	/* Unlock PLL access */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, PLL_UNLOCK);

	if (enable) {
		/* Power down LPDDR PLL */
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, PD, 1);
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, FOUTPOSTDIVPD, 1);
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, BYPASS, 1);

	} else {
		/* Power up LPDDR PLL */
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, FRZ_PLL_IN, 1);
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, PD, 0);
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, FOUTPOSTDIVPD, 0);
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, BYPASS, 0);
		HW_OUTf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_CTRL, FRZ_PLL_IN, 0);
		/* Check PLL is locked */
		do {
			lock = HW_INf(mnh_dev->regs, SCU, LPDDR4_REFCLK_PLL_STS, LOCK);
		} while (lock != 1);
	}

	/* Lock PLL */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, 0);

	return 0;
}
EXPORT_SYMBOL(mnh_lpddr_sys200_mode);

/**
 * CPU and IPU SYS200 clock control driver
 * Return: 0 on success, an error code otherwise.
 *
 * CPU and IPU clock is derived from sys200 clk instead of separate plls
 */
int mnh_cpu_ipu_sys200_mode(void)
{
	int ipu_clk_src;

	if (!mnh_dev)
		return -ENODEV;

	dev_dbg(mnh_dev->dev, "%s\n", __func__);

	/* Unlock PLL access */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, PLL_UNLOCK);

	/* Switch to SYS200 mode */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE, 0x1);

	/* Read current IPU clock source */
	ipu_clk_src = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC);

	if (ipu_clk_src == IPU_PLL) {
		/* Change clk source to CPU_IPU_PLL */
		HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL,
			IPU_CLK_SRC, CPU_IPU_PLL);

		/* IPU: Latch current settings to go into PLL */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FRZ_PLL_IN, 1);

		/* IPU: Power down PLL */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, PD, 1);
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL,
			FOUTPOSTDIVPD, 1);

		/* IPU: Apply PLL configurations */
		HW_OUTf(mnh_dev->regs, SCU, IPU_PLL_CTRL, FRZ_PLL_IN, 0);
	}

	/* Configure IPU_CLK_DIV */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_DIV, IPU_CLK_DIV,
	sys200_reg_tables[IPU_CLK].clk_div);

	/* Configure CPU_CLK_DIV */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_DIV, CPU_CLK_DIV,
		sys200_reg_tables[CPU_CLK].clk_div);

	/* CPU_IPU: Latch current settings to go into PLL */
	HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FRZ_PLL_IN, 1);

	/* CPU_IPU: Power down PLL */
	HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, PD, 1);
	HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FOUTPOSTDIVPD, 1);

	/* CPU_IPU: Apply PLL configurations */
	HW_OUTf(mnh_dev->regs, SCU, CPU_IPU_PLL_CTRL, FRZ_PLL_IN, 0);

	mnh_dev->cpu_freq = 0;

	/* Lock PLL access */
	HW_OUTf(mnh_dev->regs, SCU, PLL_PASSCODE, PASSCODE, 0);

	return 0;
}
EXPORT_SYMBOL(mnh_cpu_ipu_sys200_mode);

/* read entire int_status */
u64 mnh_ddr_int_status(void)
{
	u64 int_stat;

	if (!mnh_dev)
		return -ENODEV;

	int_stat = ((u64)MNH_DDR_CTL_IN(228) << 32) | MNH_DDR_CTL_IN(227);
	return int_stat;
}
EXPORT_SYMBOL(mnh_ddr_int_status);

/* clear entire int_status */
int mnh_ddr_clr_int_status(void)
{
	u64 stat = 0;

	if (!mnh_dev)
		return -ENODEV;

	MNH_DDR_CTL_OUT(230, 0x0F);
	MNH_DDR_CTL_OUT(229, 0xFFFFFFFF);

	stat = mnh_ddr_int_status();
	if (stat) {
		pr_err("%s: int stat not all clear: %llx\n",
			__func__, stat);
		return -1;
	}
	return 0;
}
EXPORT_SYMBOL(mnh_ddr_clr_int_status);

/* read single bit in int_status */
static u32 mnh_ddr_int_status_bit(u8 sbit)
{
	u64 status = 0;
	const u32 max_int_status_bit = 35;
	if (sbit > max_int_status_bit)
		return -EINVAL;

	status = mnh_ddr_int_status();
	status &= (1 << sbit);
	return status;
}

/* clear single bit in int_status */
static int mnh_ddr_clr_int_status_bit(u8 sbit)
{
	const u32 max_int_status_bit = 35;
	const u32 first_upper_bit = 32;
	if (sbit > max_int_status_bit)
		return -EINVAL;

	if (sbit >= first_upper_bit)
		MNH_DDR_CTL_OUT(230, 1 << (sbit - first_upper_bit));
	else
		MNH_DDR_CTL_OUT(229, 1 << sbit);

	if (mnh_ddr_int_status_bit(sbit)) {
		pr_info("%s: bit %d is still set.\n",
			__func__, sbit);
		return -1;
	}
	return 0;
}

static int mnh_ddr_send_lp_cmd(u8 cmd)
{
	unsigned long timeout = msecs_to_jiffies(100);

	dev_dbg(mnh_dev->dev,
		"%s sending cmd: 0x%x\n",
		__func__, cmd);

	reinit_completion(&mnh_dev->ddr_lp_cmd);
	MNH_DDR_CTL_OUTf(112, LP_CMD, cmd);

	if (!wait_for_completion_timeout(&mnh_dev->ddr_lp_cmd,
		timeout)) {
		dev_err(mnh_dev->dev,
		"%s ERROR timeout sending cmd: 0x%02x\n",
		__func__, cmd);
		return -ETIMEDOUT;
	}
	return 0;
}

static void mnh_ddr_enable_lp(void)
{
	u32 fsp = 0;

	/*
	These are roughly scaled to the frequency of the fsp
	*/
	const u32 sleep_val[LPDDR_FREQ_NUM_FSPS] = {
		0x04, 0x10, 0x40, 0x60 };

	fsp = MNH_DDR_CTL_INf(133, CURRENT_REG_COPY);

	if (fsp >= LPDDR_FREQ_NUM_FSPS)
		fsp = LPDDR_FREQ_MAX;

	dev_dbg(mnh_dev->dev, "%s\n", __func__);

	MNH_DDR_CTL_OUTf(124, LP_AUTO_SR_MC_GATE_IDLE,
		sleep_val[fsp]);

	MNH_DDR_CTL_OUTf(123, LP_AUTO_PD_IDLE, lp_counters[0]);
	MNH_DDR_CTL_OUTf(123, LP_AUTO_SRPD_LITE_IDLE, lp_counters[1]);
	MNH_DDR_CTL_OUTf(124, LP_AUTO_SR_IDLE, lp_counters[2]);
	MNH_DDR_CTL_OUTf(124, LP_AUTO_SR_MC_GATE_IDLE, lp_counters[3]);

	if (MNH_DDR_CTL_INf(122, LP_AUTO_EXIT_EN) == 0)
		MNH_DDR_CTL_OUTf(122, LP_AUTO_EXIT_EN, 0xF);

	if (MNH_DDR_CTL_INf(122, LP_AUTO_MEM_GATE_EN) == 0)
		MNH_DDR_CTL_OUTf(122, LP_AUTO_MEM_GATE_EN, 0x4);

	if (MNH_DDR_CTL_INf(122, LP_AUTO_ENTRY_EN) == 0)
		MNH_DDR_CTL_OUTf(122, LP_AUTO_ENTRY_EN, 0x4);
}

static void mnh_ddr_disable_lp(void)
{
	dev_dbg(mnh_dev->dev, "%s\n", __func__);
	lp_counters[0] = MNH_DDR_CTL_INf(123, LP_AUTO_PD_IDLE);
	lp_counters[1] = MNH_DDR_CTL_INf(123, LP_AUTO_SRPD_LITE_IDLE);
	lp_counters[2] = MNH_DDR_CTL_INf(124, LP_AUTO_SR_IDLE);
	lp_counters[3] = MNH_DDR_CTL_INf(124, LP_AUTO_SR_MC_GATE_IDLE);

	MNH_DDR_CTL_OUTf(123, LP_AUTO_PD_IDLE, 0x0);
	MNH_DDR_CTL_OUTf(123, LP_AUTO_SRPD_LITE_IDLE, 0x0);
	MNH_DDR_CTL_OUTf(124, LP_AUTO_SR_IDLE, 0x0);
	MNH_DDR_CTL_OUTf(124, LP_AUTO_SR_MC_GATE_IDLE, 0x0);
	MNH_DDR_CTL_OUTf(122, LP_AUTO_ENTRY_EN, 0x0);
	mnh_ddr_send_lp_cmd(LP_CMD_EXIT_LP);
}

/*
val0 and val1 are the values for modereg, read from
chip 0 and chip 1 respectively.
*/
int mnh_ddr_read_mode_reg(u8 modereg, u8 *val0, u8 *val1)
{
	int ret = 0;
	const u64 readable = 0x00000000030C51f1;
	u32 val = 0;
	unsigned long timeout = 0;
	u32 peripheral_mrr_data = 0;

	if ((modereg >= 64) ||
		((readable & ((u64)1 << modereg)) == 0)) {
		pr_err("%s %d is not readable.\n",
			__func__, modereg);
		*val0 = 0;
		*val1 = 0;
		return -1;
	}

	val = 0xFF & modereg;
	val |= 1 << 16;

	mnh_ddr_disable_lp();

	timeout = msecs_to_jiffies(50);
	reinit_completion(&mnh_dev->ddr_mrr);
	MNH_DDR_CTL_OUTf(141, READ_MODEREG, val);

	if (!wait_for_completion_timeout(&mnh_dev->ddr_mrr,
			timeout)) {
		pr_err("%s timeout on mrr\n", __func__);
		mnh_ddr_enable_lp();
		return -ETIMEDOUT;
	}

	mnh_ddr_enable_lp();

	peripheral_mrr_data =
		MNH_DDR_CTL_INf(142, PERIPHERAL_MRR_DATA);

	*val0 = 0xFF & peripheral_mrr_data;
	*val1 = 0xFF & (peripheral_mrr_data >> 16);
	dev_dbg(mnh_dev->dev,
		"%s values: 0x%02x 0x%02x\n",
		__func__, *val0, *val1);
	return ret;
}

int mnh_ddr_adjust_refresh_suspend(void)
{
	cancel_delayed_work_sync(&mnh_ddr_adjust_refresh_work);
	/*
	 * AP will re-init (resume) ddr with hottest settings
	 * and we will adjust appropriately on resume,
	 * just like cold-boot case.
	 */
	previous_refresh_rate = INIT_REFRESH_RATE;
	return 1;
}

int mnh_ddr_adjust_refresh_resume(void)
{
	/* force the refresh worker execution, the worker
	 * schedules itself for subsequent execution
	 */
	mnh_ddr_adjust_refresh_worker(NULL);
	return 1;
}

static u16 mnh_ddr_update_refresh(u8 old_rate, u16 old_interval,
	u8 new_rate)
{
	u16 new_interval;

	/* mask out everything but refresh rate */
	old_rate &= 0x07;
	new_rate &= 0x07;

	if ((new_rate == 0) ||
		(new_rate == 0x7)) {
		panic("ddr temp exceeds parameters: 0x%02x "
			" and preventing undeterministic side effects now",
			new_rate);
	}

	if (/* no changes */
		(old_rate == new_rate) ||
		/* same range */
		((old_rate == 0x5) && (new_rate == 0x6)) ||
		((old_rate == 0x6) && (new_rate == 0x5)))
		return old_interval;

	if (new_rate > old_rate) {
		/* getting hotter */
		new_interval = old_interval >> (new_rate - old_rate);
	} else {
		/* getting cooler */
		if (old_rate > 0x5)
			old_rate = 0x5;
		new_interval = old_interval << (old_rate - new_rate);
	}

	pr_info("%s changed 0x%04x to 0x%04x\n",
		__func__, old_interval, new_interval);

	return new_interval;
}

static void mnh_ddr_adjust_refresh(u8 refresh_rate)
{
	u16 tref[LPDDR_FREQ_NUM_FSPS];
	int fsp;

	/* sanitize refresh rate */
	refresh_rate &= 0x07;

	if (refresh_rate != previous_refresh_rate) {
		pr_info("%s 0x%02x -> 0x%02x\n",
			__func__, previous_refresh_rate,
			refresh_rate);
		tref[0]		= MNH_DDR_CTL_INf(56,  TREF_F0);
		tref[1]		= MNH_DDR_CTL_INf(57,  TREF_F1);
		tref[2]		= MNH_DDR_CTL_INf(58,  TREF_F2);
		tref[3]		= MNH_DDR_CTL_INf(59,  TREF_F3);

		for (fsp = 0; fsp < LPDDR_FREQ_NUM_FSPS; fsp++) {
			tref[fsp] =
				mnh_ddr_update_refresh(previous_refresh_rate,
					tref[fsp],
					refresh_rate);
		}

		MNH_DDR_CTL_OUTf(56,  TREF_F0,     tref[0]);
		MNH_DDR_CTL_OUTf(57,  TREF_F1,     tref[1]);
		MNH_DDR_CTL_OUTf(58,  TREF_F2,     tref[2]);
		MNH_DDR_CTL_OUTf(59,  TREF_F3,     tref[3]);
		previous_refresh_rate = refresh_rate;
	}
}

static void mnh_ddr_adjust_refresh_worker(struct work_struct *work)
{
	u8 val0 = 0, val1 = 0;
	u32 combined_val = 0;
	const u8 rr_fld = 0x07;
	u8 refresh_rate;
	const u8 tuf_fld = 0x80;
	int ret = 0;
	int got_tuf = 0;

	/* skip the refresh rate update if the DRAM is in low power state */
	if ((MNH_DDR_CTL_INf(121, LP_STATE) & 0xF) > 0x7)
		goto refresh_again;

	ret = mnh_ddr_read_mode_reg(4, &val0, &val1);
	mnh_dev->ddr_mrr4 = (u32)val1 << 16 | (u32)val0;

	if (ret) {
		dev_err(mnh_dev->dev,
			"%s ERROR refresh rate read failed. %d\n",
			__func__, ret);
		goto refresh_again;
	}

	refresh_rate = rr_fld & val0;
	if (refresh_rate < (rr_fld & val1)) {
		dev_dbg(mnh_dev->dev,
			"%s rrs don't match: 0x%02x != 0x%02x"
			"deferring to higher temp die rate",
			__func__, val0, val1);
		refresh_rate = rr_fld & val1;
	}

	if ((tuf_fld & val0) ||
		(tuf_fld & val1)) {
		pr_debug("%s TUF 0x%02x 0x%02x\n",
			 __func__, val0, val1);
		got_tuf = 1;
	}

	mnh_ddr_adjust_refresh(refresh_rate);

refresh_again:
	schedule_delayed_work(&mnh_ddr_adjust_refresh_work,
		msecs_to_jiffies(mnh_ddr_refresh_msec));
}

/**
 * Set the SCU clock gating at init
 * Return: 0 on success, an error code otherwise.
 *
 * enable == 1 sets the SCU to enable clock gating in general when CPU enters
 * L2 WFI state.
 */
int mnh_clock_init_gating(int enabled)
{
	unsigned long irq_flags;

	if (!mnh_dev)
		return -ENODEV;

	dev_dbg(mnh_dev->dev, "%s:%d\n", __func__, __LINE__);

	if (enabled != 1 && enabled != 0)
		return -EINVAL;

	spin_lock_irqsave(&mnh_dev->reset_lock, irq_flags);

	/* Add periph clk gates */
	HW_OUTf(mnh_dev->regs, SCU, RSTC, PERI_DMA_RST, enabled);

	spin_unlock_irqrestore(&mnh_dev->reset_lock, irq_flags);

	HW_OUTf(mnh_dev->regs, SCU, PERIPH_CLK_CTRL, PERI_DMA_CLKEN_SW,
		!enabled);
	HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, HALT_BTROM_PD_EN, enabled);
	HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, HALT_BTSRAM_PD_EN, enabled);
	HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, BTROM_SLP, enabled);
	HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, BTSRAM_DS, enabled);
	/* HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_AHBCG_EN, enabled); */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_BTSRAMCG_EN, enabled);
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_BTROMCG_EN, enabled);

	/* HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_LP4CG_EN, enabled); */
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_LP4_PLL_BYPCLK_CG_EN,
		enabled);
	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, LP4PHY_PLL_BYPASS_CLKEN,
		enabled);

	return 0;
}
EXPORT_SYMBOL(mnh_clock_init_gating);

int mnh_bypass_clock_gating(int enabled)
{
	unsigned long irq_flags;

	if (!mnh_dev)
		return -ENODEV;

	dev_dbg(mnh_dev->dev, "%s:%d\n", __func__, __LINE__);

	if (enabled != 1 && enabled != 0)
		return -EINVAL;

	if (enabled) {
		HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_CPUCG_EN,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, HALT_CPUMEM_PD_EN,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, CPU_L2MEM_DS,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, CPU_L1MEM_DS,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, HALT_LP4CMEM_PD_EN,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, LP4C_MEM_DS,
			enabled);
	} else {
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, CPU_L2MEM_DS,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, CPU_L1MEM_DS,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, HALT_CPUMEM_PD_EN,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, LP4C_MEM_DS,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, HALT_LP4CMEM_PD_EN,
			enabled);
		HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_CPUCG_EN,
			enabled);
	}


	spin_lock_irqsave(&mnh_dev->reset_lock, irq_flags);

	HW_OUTf(mnh_dev->regs, SCU, RSTC, WDT_RST, enabled);

	spin_unlock_irqrestore(&mnh_dev->reset_lock, irq_flags);

	HW_OUTf(mnh_dev->regs, SCU, PERIPH_CLK_CTRL, PVT_CLKEN, !enabled);
	HW_OUTf(mnh_dev->regs, SCU, PERIPH_CLK_CTRL, WDT_CLKEN_SW, !enabled);

	return 0;
}
EXPORT_SYMBOL(mnh_bypass_clock_gating);

int mnh_pcie_axi_clock_enable(int enabled)
{
	if (!mnh_dev)
		return -ENODEV;

	if (enabled != 1 && enabled != 0)
		return -EINVAL;

	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, PCIE_AXI_CLKEN, enabled);

	return 0;
}
EXPORT_SYMBOL(mnh_pcie_axi_clock_enable);

int mnh_axi_clock_gating(int enabled)
{
	if (!mnh_dev)
		return -ENODEV;

	if (enabled != 1 && enabled != 0)
		return -EINVAL;

	HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_AXICG_EN, enabled);

	return 0;
}
EXPORT_SYMBOL(mnh_axi_clock_gating);

/**
 * Set the SCU clock gating for bypass mode
 * Return: 0 on success, an error code otherwise.
 *
 * enable == 1 sets the SCU to enable clock gating in general when CPU enters
 * L2 WFI state.
 */
int mnh_ipu_clock_gating(int enabled)
{
	if (!mnh_dev)
		return -ENOENT;

	dev_dbg(mnh_dev->dev, "%s\n", __func__);

	if (enabled != 1 && enabled != 0)
		return -EINVAL;

	if (enabled) {
		HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLKEN, !enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, IPU_MEM_DS, enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, IPU_MEM_SD, enabled);
	} else {
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, IPU_MEM_SD, enabled);
		HW_OUTf(mnh_dev->regs, SCU, MEM_PWR_MGMNT, IPU_MEM_DS, enabled);
		HW_OUTf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLKEN, !enabled);
	}

	return 0;
}
EXPORT_SYMBOL(mnh_ipu_clock_gating);

int mnh_ipu_reset(void)
{
	unsigned long irq_flags;

	dev_dbg(mnh_dev->dev, "%s\n", __func__);
	if (!mnh_dev)
		return -ENOENT;

	spin_lock_irqsave(&mnh_dev->reset_lock, irq_flags);

	HW_OUTf(mnh_dev->regs, SCU, RSTC, IPU_RST, 1);
	HW_OUTf(mnh_dev->regs, SCU, RSTC, IPU_RST, 0);

	spin_unlock_irqrestore(&mnh_dev->reset_lock, irq_flags);

	return 0;
}
EXPORT_SYMBOL(mnh_ipu_reset);

/* Current reference clock rate
 * Return: refclk index of mnh_refclk_type
 *
 * This returns current reference clk rate by index of mnh_refclk_type
 */
static int mnh_freq_check_refclk(uint32_t refclk_gpio)
{
	int ret, refclk = 0;

	if (gpio_is_valid(refclk_gpio)) {
		ret = gpio_request(refclk_gpio, "REFCLK");
		if (ret)
			goto end_gpio;
		ret = gpio_direction_input(refclk_gpio);
		if (ret)
			goto err_gpio;
		if (gpio_get_value(refclk_gpio))
			refclk = refclk | 0x1;

		pr_debug("%s gpio:%d refclk:%d\n", __func__,
			refclk_gpio, refclk);
	}
err_gpio:
	if (gpio_is_valid(refclk_gpio))
		gpio_free(refclk_gpio);
end_gpio:
	return refclk;
}

static ssize_t cpu_freq_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return sprintf(buf, "%dMHz\n", mnh_get_cpu_freq());
}

static ssize_t cpu_freq_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int i, err;

	dev_dbg(mnh_dev->dev, "%s: %s\n", __func__, buf);
	for (i = 0; i < ARRAY_SIZE(cpu_reg_tables[0]); i++) {
		if (!strncmp(buf, mnh_dev->cpu_pllcfg[i].freq_str,
			strlen(mnh_dev->cpu_pllcfg[i].freq_str))) {
			err = mnh_cpu_freq_change(i);
			if (!err)
				return count;
			else
				return -EIO;
		}
	}

	dev_err(mnh_dev->dev, "invalid freq: %s\n", buf);
	return -EINVAL;

}

static const char * const ipu_freq_str[] = {"100", "200", "300", "400", "425"};
static ssize_t ipu_freq_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return sprintf(buf, "%dMHz\n", mnh_get_ipu_freq());
}

static ssize_t ipu_freq_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int i, err;

	dev_dbg(mnh_dev->dev, "%s: %s\n", __func__, buf);
	for (i = 0; i < ARRAY_SIZE(ipu_reg_tables[0]); i++) {
		if (!strncmp(buf, mnh_dev->ipu_pllcfg[i].freq_str,
			strlen(mnh_dev->ipu_pllcfg[i].freq_str))) {
			err = mnh_ipu_freq_change(i);
			if (!err)
				return count;
			else
				return -EIO;
		}
	}

	dev_err(mnh_dev->dev, "invalid freq: %s\n", buf);
	return -EINVAL;
}

static ssize_t lpddr_hw_freq_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	uint32_t var = MNH_DDR_CTL_INf(133, CURRENT_REG_COPY);

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, var);
	return sprintf(buf, "FSP%d\n", var);
}

static ssize_t lpddr_hw_freq_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int var = 0;
	int ret;

	ret = kstrtoint(buf, 10, &var);
	if (ret < 0)
		return ret;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, var);
	if (!mnh_lpddr_hw_freq_change(var))
		return count;
	else
		return -EIO;
}

static ssize_t ipu_clk_src_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	int ipu_clk_src = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC);

	return scnprintf(buf, MAX_STR_COPY, "%s\n",
		(ipu_clk_src == CPU_IPU_PLL) ? "CPU_IPU":"IPU");
}

static ssize_t sys200_freq_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	int sys200, clk_src;

	clk_src = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLK_SRC);
	sys200 = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, CPU_IPU_SYS200_MODE);
	if (sys200 && (clk_src == IPU_PLL))
		sys200 = 0;

	return sprintf(buf, "%d\n", sys200);
}

static ssize_t sys200_freq_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int var = 0;
	int ret;

	ret = kstrtoint(buf, 10, &var);
	if (ret < 0)
		return ret;

	if (var == 1) {
		dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, var);
		if (!mnh_cpu_ipu_sys200_mode())
			return count;
	}
	return -EIO;
}

static ssize_t ipu_clock_gating_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	int clk_gated;

	clk_gated = !HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, IPU_CLKEN);

	return sprintf(buf, "%d\n", clk_gated);
}

static ssize_t ipu_clock_gating_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int var = 0;
	int ret;

	ret = kstrtoint(buf, 10, &var);
	if (ret < 0)
		return ret;

	if (var == 1 || var == 0) {
		dev_info(mnh_dev->dev, "%s: %d\n", __func__, var);
		if (!mnh_ipu_clock_gating(var))
			return count;
	}
	return -EIO;
}

static ssize_t bypass_clock_gating_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	int clk_gated;

	clk_gated = HW_INf(mnh_dev->regs, SCU, CCU_CLK_CTL, HALT_CPUCG_EN);

	return sprintf(buf, "%d\n", clk_gated);
}

static ssize_t bypass_clock_gating_set(struct device *dev,
				      struct device_attribute *attr,
				      const char *buf,
				      size_t count)
{
	int var = 0;
	int ret;

	ret = kstrtoint(buf, 10, &var);
	if (ret < 0)
		return ret;

	if (var == 1 || var == 0) {
		dev_info(mnh_dev->dev, "%s: %d\n", __func__, var);
		if (!mnh_bypass_clock_gating(var))
			return count;
	}
	return -EIO;
}

static ssize_t lpddr_lp_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return sprintf(buf, "%d\n",
		MNH_DDR_CTL_INf(122, LP_AUTO_ENTRY_EN));
}

static ssize_t lpddr_lp_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int var = 0;
	int ret;

	ret = kstrtoint(buf, 10, &var);
	if (ret < 0)
		return ret;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, var);
	if (var == 1)
		mnh_ddr_enable_lp();
	else if (var == 0)
		mnh_ddr_disable_lp();
	else
		return -EIO;

	return count;
}

static ssize_t lpddr_sys200_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	int sys200_mode = 0, fsp = 0;
	if (HW_INf(mnh_dev->regs, SCU,
			LPDDR4_LOW_POWER_CFG,
			LP4_FSP_SW_OVERRIDE)) {
		sys200_mode = HW_INf(mnh_dev->regs, SCU,
			CCU_CLK_CTL, LP4_AXI_SYS200_MODE);
	} else {
		fsp = MNH_DDR_CTL_INf(133, CURRENT_REG_COPY);
		sys200_mode = HW_INxf(mnh_dev->regs, SCU,
			LPDDR4_FSP_SETTING, fsp, FSP_SYS200_MODE);
	}
	return sprintf(buf, "%d\n", sys200_mode);
}

static ssize_t lpddr_sys200_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int var = 0;
	int ret;

	ret = kstrtoint(buf, 10, &var);
	if (ret < 0)
		return ret;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, var);
	if ((var == 0) || (var == 1)) {
		mnh_lpddr_sys200_mode(var);
	} else {
		dev_err(mnh_dev->dev, "%s: Invalid argument", __func__);
		return -EINVAL;
	}

	return count;
}

static ssize_t lpddr_mrr4_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	return sprintf(buf, "0x%08x\n", mnh_dev->ddr_mrr4);
}

static ssize_t dump_powerregs_get(struct device *dev,
				struct device_attribute *attr,	
				char *buf)
{
	int val = 0;
       	const char* origbuf = buf;
	val = HW_IN(mnh_dev->regs, SCU, GLOBAL_IRQ_STATUS_SET0);
	buf += sprintf(buf, "GLOBAL_IRQ_STATUS_SET0\t\t0x%x\n", val);
	val = HW_IN(mnh_dev->regs, SCU, GLOBAL_IRQ_STATUS_SET1);
	buf += sprintf(buf, "GBOBAL_IRQ_STATUS_SET1\t\t0x%x\n", val);

	val = HW_IN(mnh_dev->regs, SCU, GLOBAL_IRQ_HLT_RST_EN_SET0);
	buf += sprintf(buf, "GLOBAL_IRQ_HLT_RST_EN_SET0\t0x%x\n", val);
	val = HW_IN(mnh_dev->regs, SCU, GLOBAL_IRQ_HLT_RST_EN_SET1);
	buf += sprintf(buf, "GLOBAL_IRQ_HLT_RST_EN_SET1\t0x%x\n", val);

	val = HW_IN(mnh_dev->regs, SCU, GLOBAL_WAKE_EN_SET0);
	buf += sprintf(buf, "GLOBAL_WAKE_EN_SET0\t\t0x%x\n", val);
	val = HW_IN(mnh_dev->regs, SCU, GLOBAL_WAKE_EN_SET1);
	buf += sprintf(buf, "GLOBAL_WAKE_EN_SET1\t\t0x%x\n", val);

	val = HW_IN(mnh_dev->regs, SCU, SCU_IRQ_STATUS);
	buf += sprintf(buf, "SCU_IRQ_STATUS\t\t\t0x%x\n", val);
	val = HW_IN(mnh_dev->regs, SCU, SCU_IRQ_ENABLE);
	buf += sprintf(buf, "SCU_IRQ_ENABLE\t\t\t0x%x\n", val);

	val = HW_IN(mnh_dev->regs, SCU, CCU_CLK_CTL);
	buf += sprintf(buf, "CCU_CLK_CTL\t\t\t0x%x\n", val);

	val = HW_IN(mnh_dev->regs, SCU, PERIPH_CLK_CTRL);
	buf += sprintf(buf, "PERIPH_CLK_CTRL\t\t\t0x%x\n", val);

	val = HW_IN(mnh_dev->regs, SCU, RSTC);
	buf += sprintf(buf, "RSTC\t\t\t\t0x%x\n", val);

	val = HW_IN(mnh_dev->regs, SCU, MEM_PWR_MGMNT);
	buf += sprintf(buf, "MEM_PWR_MGMNT\t\t\t0x%x\n", val);

	/* cpu for now */	
	val = MNH_CPU_IN(STS);
	buf += sprintf(buf, "CPU STS\t\t\t\t0x%x\n", val);

	val = MNH_CPU_IN(PWR_MGMT_STS);
	buf += sprintf(buf, "CPU PWR_MGMT_STS\t\t0x%x\n", val);

	val = MNH_DDR_CTL_IN(227);
	buf += sprintf(buf, "DDR_CTL 227\t\t\t0x%x\n", val);

	val = MNH_DDR_CTL_IN(228);
	buf += sprintf(buf, "DDR_CTL 228\t\t\t0x%x\n", val);


	return (ssize_t) (buf - origbuf);
}

static ssize_t lpddr_sw_freq_get(struct device *dev,
				struct device_attribute *attr,
				char *buf)
{
	unsigned long fsp = 0;
	int ret = invoke_mnh_fn_smc(MNH_PM_FSP_GET_AARCH64, 0, 0, 0);

	return sprintf(buf, "%d\n", ret);
}

static ssize_t lpddr_sw_freq_set(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	unsigned long fsp = 0;
	int ret;

	ret = kstrtoint(buf, 10, &fsp);
	if (ret < 0)
		return ret;
	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, fsp);

	ret = mnh_lpddr_sw_freq_change(fsp);

	return count;
}

static DEVICE_ATTR(cpu_freq, S_IWUSR | S_IRUGO,
		cpu_freq_get, cpu_freq_set);
static DEVICE_ATTR(ipu_freq, S_IWUSR | S_IRUGO,
		ipu_freq_get, ipu_freq_set);
static DEVICE_ATTR(lpddr_freq_hw, S_IWUSR | S_IRUGO,
		lpddr_hw_freq_get, lpddr_hw_freq_set);
static DEVICE_ATTR(ipu_clk_src, S_IRUGO,
		ipu_clk_src_get, NULL);
static DEVICE_ATTR(sys200, S_IWUSR | S_IRUGO,
		sys200_freq_get, sys200_freq_set);
static DEVICE_ATTR(ipu_clock_gating, S_IWUSR | S_IRUGO,
		ipu_clock_gating_get, ipu_clock_gating_set);
static DEVICE_ATTR(bypass_clock_gating, S_IWUSR | S_IRUGO,
		bypass_clock_gating_get, bypass_clock_gating_set);
static DEVICE_ATTR(lpddr_lp, S_IWUSR | S_IRUGO,
		lpddr_lp_get, lpddr_lp_set);
static DEVICE_ATTR(lpddr_sys200, S_IWUSR | S_IRUGO,
		lpddr_sys200_get, lpddr_sys200_set);
static DEVICE_ATTR(lpddr_mrr4, S_IRUGO,
		lpddr_mrr4_get, NULL);
static DEVICE_ATTR(dump_powerregs, S_IRUGO,
		dump_powerregs_get, NULL);
static DEVICE_ATTR(lpddr_freq, S_IWUSR | S_IRUGO,
		lpddr_sw_freq_get, lpddr_sw_freq_set);

static int ddr_ctl_read_reg;
#define MAX_DDR_CTL_REG 558

static ssize_t ddr_ctl_read_show(struct device *dev,
				 struct device_attribute *attr,
				 char *buf)
{
	int val;

	val = readl(mnh_dev->ddraddr + (4 * ddr_ctl_read_reg));

	return sprintf(buf, "0x%08x", val);
}

static ssize_t ddr_ctl_read_store(struct device *dev,
				  struct device_attribute *attr,
				  const char *buf,
				  size_t count)
{
	int val = 0;
	int ret;

	ret = kstrtoint(buf, 10, &val);
	if (ret < 0)
		return ret;

	dev_dbg(mnh_dev->dev, "%s: %d\n", __func__, val);

	if ((val < 0) || (val > MAX_DDR_CTL_REG))
		return -EINVAL;

	ddr_ctl_read_reg = val;

	return count;
}
DEVICE_ATTR_RW(ddr_ctl_read);

static ssize_t ddr_ctl_write_store(struct device *dev,
				   struct device_attribute *attr,
				   const char *buf,
				   size_t count)
{
	int val1 = 0, val2 = 0;
	int ret;
	char *str;

	str = strsep((char **)&buf, ";");
	if (!str)
		return -EINVAL;

	ret = kstrtoint(str, 10, &val1);
	if (ret < 0)
		return ret;

	if ((val1 < 0) || (val1 > MAX_DDR_CTL_REG))
		return -EINVAL;

	ret = kstrtoint(buf, 0, &val2);
	if (ret < 0)
		return ret;

	dev_dbg(mnh_dev->dev, "%s: reg %d, data 0x%08x\n", __func__,
		val1, val2);

	writel(val2, mnh_dev->ddraddr + (4 * val1));

	return count;
}
DEVICE_ATTR_WO(ddr_ctl_write);

static struct attribute *freq_dev_attributes[] = {
	&dev_attr_cpu_freq.attr,
	&dev_attr_ipu_freq.attr,
	&dev_attr_lpddr_freq.attr,
	&dev_attr_ipu_clk_src.attr,
	&dev_attr_sys200.attr,
	&dev_attr_ipu_clock_gating.attr,
	&dev_attr_bypass_clock_gating.attr,
	&dev_attr_lpddr_lp.attr,
	&dev_attr_lpddr_sys200.attr,
	&dev_attr_lpddr_mrr4.attr,
	&dev_attr_dump_powerregs.attr,
	&dev_attr_ddr_ctl_read.attr,
	&dev_attr_ddr_ctl_write.attr,
	&dev_attr_lpddr_freq_hw.attr,
	NULL
};

static struct attribute_group mnh_freq_cooling_group = {
	.name = "mnh_freq_cool",
	.attrs = freq_dev_attributes
};


static int init_sysfs(struct device *dev, struct kobject *sysfs_kobj)
{
	int ret;

	ret = sysfs_create_group(sysfs_kobj, &mnh_freq_cooling_group);
	if (ret) {
		dev_err(dev, "Failed to create sysfs\n");
		return -EINVAL;
	}

	return 0;
}

static void clean_sysfs(void)
{
	sysfs_remove_group(kernel_kobj, &mnh_freq_cooling_group);
}

/**
 * Initial handler for ddr interrupts
 */
static irqreturn_t mnh_pm_handle_ddr_irq(int irq, void *dev_id)
{
	u64 status = mnh_ddr_int_status();

	dev_dbg(mnh_dev->dev,
		"%s status=0x%llx\n", __func__, status);

	if (status & (1 << MR_READ_SBIT)) {
		mnh_ddr_clr_int_status_bit(MR_READ_SBIT);
		complete(&mnh_dev->ddr_mrr);
	}

	if (status & (1 << LP_CMD_SBIT)) {
		mnh_ddr_clr_int_status_bit(LP_CMD_SBIT);
		complete(&mnh_dev->ddr_lp_cmd);
	}

	status = mnh_ddr_int_status();

	if (status) {
		mnh_ddr_clr_int_status();
		dev_dbg(mnh_dev->dev,
			"%s unhandled status=0x%llx, but cleared.\n", __func__, status);
	}

	/* return interrupt handled */
	return IRQ_HANDLED;
}
int mnh_clk_init(struct platform_device *pdev, void __iomem *baseadress)
{
	int ret = 0, err = 0;
	struct resource *res;
	struct mnh_freq_cooling_device *tmp_mnh_dev;
	uint32_t refclk_gpio;

	dev_info(&pdev->dev, "mnh_freq_cooling_init\n");

	tmp_mnh_dev = devm_kzalloc(&pdev->dev, sizeof(*tmp_mnh_dev),
			GFP_KERNEL);
	if (!tmp_mnh_dev)
		return -ENOMEM;

	/* Set baseadress for SCU */
	tmp_mnh_dev->regs = baseadress;
	tmp_mnh_dev->dev = &pdev->dev;
	init_completion(&tmp_mnh_dev->ddr_mrr);
	tmp_mnh_dev->ddr_mrr4 = 0xDEADDEAD;
	init_completion(&tmp_mnh_dev->ddr_lp_cmd);
	init_completion(&tmp_mnh_dev->ddr_switch);
	// spin_lock_init(&tmp_mnh_dev->irqlock);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res) {
		dev_err(tmp_mnh_dev->dev, "cannot get platform resources\n");
		ret = -ENOENT;
		goto mnh_probe_err;
	}
	tmp_mnh_dev->ddraddr = ioremap_nocache(res->start, resource_size(res));
	if (!tmp_mnh_dev->ddraddr) {
		dev_err(tmp_mnh_dev->dev, "unable to remap resources\n");
		ret = -ENOMEM;
		goto mnh_probe_err;
	}

	res = platform_get_resource(pdev, IORESOURCE_MEM, 2);
	if (!res) {
		dev_err(tmp_mnh_dev->dev, "cannot get platform resources\n");
		ret = -ENOENT;
		goto mnh_probe_err;
	}
	tmp_mnh_dev->cpuaddr = ioremap_nocache(res->start, resource_size(res));
	if (!tmp_mnh_dev->cpuaddr) {
		dev_err(tmp_mnh_dev->dev, "unable to remap resources\n");
		ret = -ENOMEM;
		goto mnh_probe_err;
	}

	/* Check refclk rate */
	err = device_property_read_u32(tmp_mnh_dev->dev, "refclk-gpio",
		&refclk_gpio);
	if (!err) {
		tmp_mnh_dev->refclk = mnh_freq_check_refclk(refclk_gpio);
	} else {
		pr_err("unable to read refclk-gpio\n");
		ret = -ENOMEM;
		goto mnh_probe_err;
	}
	tmp_mnh_dev->cpu_pllcfg = (const struct freq_reg_table*)&cpu_reg_tables[tmp_mnh_dev->refclk];
	tmp_mnh_dev->ipu_pllcfg = (const struct freq_reg_table*)&ipu_reg_tables[tmp_mnh_dev->refclk];

	mnh_dev = tmp_mnh_dev;
	mnh_dev->cpu_freq = mnh_cpu_freq_to_index();

	mnh_dev->ddr_irq = platform_get_irq(pdev, 0);
	dev_dbg(mnh_dev->dev, "Allocate ddr irq %d\n", mnh_dev->ddr_irq);
	err = request_irq(mnh_dev->ddr_irq, mnh_pm_handle_ddr_irq,
			  IRQF_SHARED, DEVICE_NAME, mnh_dev->dev);
	if (err) {
		dev_err(mnh_dev->dev, "Could not allocated ddr irq\n");
		ret = -EINVAL;
		goto mnh_probe_err;
	}

	spin_lock_init(&mnh_dev->reset_lock);

	init_sysfs(mnh_dev->dev, kernel_kobj);
	previous_refresh_rate = INIT_REFRESH_RATE;
	INIT_DELAYED_WORK(&mnh_ddr_adjust_refresh_work,
		mnh_ddr_adjust_refresh_worker);
	schedule_delayed_work(&mnh_ddr_adjust_refresh_work,
		msecs_to_jiffies(mnh_ddr_refresh_msec));
	mnh_clock_init_gating(1);

	return 0;

mnh_probe_err:
	if (tmp_mnh_dev->ddraddr)
		iounmap(&tmp_mnh_dev->ddraddr);
	return ret;
}

void mnh_clk_clean(struct device *dev)
{
	clean_sysfs();
}
