// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2019 Samsung Electronics Co., Ltd.
 * Author: Lukasz Luba <l.luba@partner.samsung.com>
 */

#include <linux/clk.h>
#include <linux/devfreq.h>
#include <linux/devfreq-event.h>
#include <linux/device.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/mfd/syscon.h>
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/of_device.h>
#include <linux/pm_opp.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
#include "../jedec_ddr.h"
#include "../of_memory.h"

static int irqmode;
module_param(irqmode, int, 0644);
MODULE_PARM_DESC(irqmode, "Enable IRQ mode (0=off [default], 1=on)");

#define EXYNOS5_DREXI_TIMINGAREF		(0x0030)
#define EXYNOS5_DREXI_TIMINGROW0		(0x0034)
#define EXYNOS5_DREXI_TIMINGDATA0		(0x0038)
#define EXYNOS5_DREXI_TIMINGPOWER0		(0x003C)
#define EXYNOS5_DREXI_TIMINGROW1		(0x00E4)
#define EXYNOS5_DREXI_TIMINGDATA1		(0x00E8)
#define EXYNOS5_DREXI_TIMINGPOWER1		(0x00EC)
#define CDREX_PAUSE				(0x2091c)
#define CDREX_LPDDR3PHY_CON3			(0x20a20)
#define CDREX_LPDDR3PHY_CLKM_SRC		(0x20700)
#define EXYNOS5_TIMING_SET_SWI			BIT(28)
#define USE_MX_MSPLL_TIMINGS			(1)
#define USE_BPLL_TIMINGS			(0)
#define EXYNOS5_AREF_NORMAL			(0x2e)

#define DREX_PPCCLKCON		(0x0130)
#define DREX_PEREV2CONFIG	(0x013c)
#define DREX_PMNC_PPC		(0xE000)
#define DREX_CNTENS_PPC		(0xE010)
#define DREX_CNTENC_PPC		(0xE020)
#define DREX_INTENS_PPC		(0xE030)
#define DREX_INTENC_PPC		(0xE040)
#define DREX_FLAG_PPC		(0xE050)
#define DREX_PMCNT2_PPC		(0xE130)

/*
 * A value for register DREX_PMNC_PPC which should be written to reset
 * the cycle counter CCNT (a reference wall clock). It sets zero to the
 * CCNT counter.
 */
#define CC_RESET		BIT(2)

/*
 * A value for register DREX_PMNC_PPC which does the reset of all performance
 * counters to zero.
 */
#define PPC_COUNTER_RESET	BIT(1)

/*
 * Enables all configured counters (including cycle counter). The value should
 * be written to the register DREX_PMNC_PPC.
 */
#define PPC_ENABLE		BIT(0)

/* A value for register DREX_PPCCLKCON which enables performance events clock.
 * Must be written before first access to the performance counters register
 * set, otherwise it could crash.
 */
#define PEREV_CLK_EN		BIT(0)

/*
 * Values which are used to enable counters, interrupts or configure flags of
 * the performance counters. They configure counter 2 and cycle counter.
 */
#define PERF_CNT2		BIT(2)
#define PERF_CCNT		BIT(31)

/*
 * Performance event types which are used for setting the preferred event
 * to track in the counters.
 * There is a set of different types, the values are from range 0 to 0x6f.
 * These settings should be written to the configuration register which manages
 * the type of the event (register DREX_PEREV2CONFIG).
 */
#define READ_TRANSFER_CH0	(0x6d)
#define READ_TRANSFER_CH1	(0x6f)

#define PERF_COUNTER_START_VALUE 0xff000000
#define PERF_EVENT_UP_DOWN_THRESHOLD 900000000ULL

/**
 * struct dmc_opp_table - Operating level desciption
 *
 * Covers frequency and voltage settings of the DMC operating mode.
 */
struct dmc_opp_table {
	u32 freq_hz;
	u32 volt_uv;
};

/**
 * struct exynos5_dmc - main structure describing DMC device
 *
 * The main structure for the Dynamic Memory Controller which covers clocks,
 * memory regions, HW information, parameters and current operating mode.
 */
struct exynos5_dmc {
	struct device *dev;
	struct devfreq *df;
	struct devfreq_simple_ondemand_data gov_data;
	void __iomem *base_drexi0;
	void __iomem *base_drexi1;
	struct regmap *clk_regmap;
	struct mutex lock;
	unsigned long curr_rate;
	unsigned long curr_volt;
	unsigned long bypass_rate;
	struct dmc_opp_table *opp;
	struct dmc_opp_table opp_bypass;
	int opp_count;
	u32 timings_arr_size;
	u32 *timing_row;
	u32 *timing_data;
	u32 *timing_power;
	const struct lpddr3_timings *timings;
	const struct lpddr3_min_tck *min_tck;
	u32 bypass_timing_row;
	u32 bypass_timing_data;
	u32 bypass_timing_power;
	struct regulator *vdd_mif;
	struct clk *fout_spll;
	struct clk *fout_bpll;
	struct clk *mout_spll;
	struct clk *mout_bpll;
	struct clk *mout_mclk_cdrex;
	struct clk *mout_mx_mspll_ccore;
	struct clk *mx_mspll_ccore_phy;
	struct clk *mout_mx_mspll_ccore_phy;
	struct devfreq_event_dev **counter;
	int num_counters;
	u64 last_overflow_ts[2];
	unsigned long load;
	unsigned long total;
	bool in_irq_mode;
};

#define TIMING_FIELD(t_name, t_bit_beg, t_bit_end) \
	{ .name = t_name, .bit_beg = t_bit_beg, .bit_end = t_bit_end }

#define TIMING_VAL2REG(timing, t_val)			\
({							\
		u32 __val;				\
		__val = (t_val) << (timing)->bit_beg;	\
		__val;					\
})

struct timing_reg {
	char *name;
	int bit_beg;
	int bit_end;
	unsigned int val;
};

static const struct timing_reg timing_row[] = {
	TIMING_FIELD("tRFC", 24, 31),
	TIMING_FIELD("tRRD", 20, 23),
	TIMING_FIELD("tRP", 16, 19),
	TIMING_FIELD("tRCD", 12, 15),
	TIMING_FIELD("tRC", 6, 11),
	TIMING_FIELD("tRAS", 0, 5),
};

static const struct timing_reg timing_data[] = {
	TIMING_FIELD("tWTR", 28, 31),
	TIMING_FIELD("tWR", 24, 27),
	TIMING_FIELD("tRTP", 20, 23),
	TIMING_FIELD("tW2W-C2C", 14, 14),
	TIMING_FIELD("tR2R-C2C", 12, 12),
	TIMING_FIELD("WL", 8, 11),
	TIMING_FIELD("tDQSCK", 4, 7),
	TIMING_FIELD("RL", 0, 3),
};

static const struct timing_reg timing_power[] = {
	TIMING_FIELD("tFAW", 26, 31),
	TIMING_FIELD("tXSR", 16, 25),
	TIMING_FIELD("tXP", 8, 15),
	TIMING_FIELD("tCKE", 4, 7),
	TIMING_FIELD("tMRD", 0, 3),
};

#define TIMING_COUNT (ARRAY_SIZE(timing_row) + ARRAY_SIZE(timing_data) + \
		      ARRAY_SIZE(timing_power))

static int exynos5_counters_set_event(struct exynos5_dmc *dmc)
{
	int i, ret;

	for (i = 0; i < dmc->num_counters; i++) {
		if (!dmc->counter[i])
			continue;
		ret = devfreq_event_set_event(dmc->counter[i]);
		if (ret < 0)
			return ret;
	}
	return 0;
}

static int exynos5_counters_enable_edev(struct exynos5_dmc *dmc)
{
	int i, ret;

	for (i = 0; i < dmc->num_counters; i++) {
		if (!dmc->counter[i])
			continue;
		ret = devfreq_event_enable_edev(dmc->counter[i]);
		if (ret < 0)
			return ret;
	}
	return 0;
}

static int exynos5_counters_disable_edev(struct exynos5_dmc *dmc)
{
	int i, ret;

	for (i = 0; i < dmc->num_counters; i++) {
		if (!dmc->counter[i])
			continue;
		ret = devfreq_event_disable_edev(dmc->counter[i]);
		if (ret < 0)
			return ret;
	}
	return 0;
}

/**
 * find_target_freq_id() - Finds requested frequency in local DMC configuration
 * @dmc:	device for which the information is checked
 * @target_rate:	requested frequency in KHz
 *
 * Seeks in the local DMC driver structure for the requested frequency value
 * and returns index or error value.
 */
static int find_target_freq_idx(struct exynos5_dmc *dmc,
				unsigned long target_rate)
{
	int i;

	for (i = dmc->opp_count - 1; i >= 0; i--)
		if (dmc->opp[i].freq_hz <= target_rate)
			return i;

	return -EINVAL;
}

/**
 * exynos5_switch_timing_regs() - Changes bank register set for DRAM timings
 * @dmc:	device for which the new settings is going to be applied
 * @set:	boolean variable passing set value
 *
 * Changes the register set, which holds timing parameters.
 * There is two register sets: 0 and 1. The register set 0
 * is used in normal operation when the clock is provided from main PLL.
 * The bank register set 1 is used when the main PLL frequency is going to be
 * changed and the clock is taken from alternative, stable source.
 * This function switches between these banks according to the
 * currently used clock source.
 */
static int exynos5_switch_timing_regs(struct exynos5_dmc *dmc, bool set)
{
	unsigned int reg;
	int ret;

	ret = regmap_read(dmc->clk_regmap, CDREX_LPDDR3PHY_CON3, &reg);
	if (ret)
		return ret;

	if (set)
		reg |= EXYNOS5_TIMING_SET_SWI;
	else
		reg &= ~EXYNOS5_TIMING_SET_SWI;

	regmap_write(dmc->clk_regmap, CDREX_LPDDR3PHY_CON3, reg);

	return 0;
}

/**
 * exynos5_init_freq_table() - Initialized PM OPP framework
 * @dmc:	DMC device for which the frequencies are used for OPP init
 * @profile:	devfreq device's profile
 *
 * Populate the devfreq device's OPP table based on current frequency, voltage.
 */
static int exynos5_init_freq_table(struct exynos5_dmc *dmc,
				   struct devfreq_dev_profile *profile)
{
	int i, ret;
	int idx;
	unsigned long freq;

	ret = dev_pm_opp_of_add_table(dmc->dev);
	if (ret < 0) {
		dev_err(dmc->dev, "Failed to get OPP table\n");
		return ret;
	}

	dmc->opp_count = dev_pm_opp_get_opp_count(dmc->dev);

	dmc->opp = devm_kmalloc_array(dmc->dev, dmc->opp_count,
				      sizeof(struct dmc_opp_table), GFP_KERNEL);
	if (!dmc->opp)
		goto err_opp;

	idx = dmc->opp_count - 1;
	for (i = 0, freq = ULONG_MAX; i < dmc->opp_count; i++, freq--) {
		struct dev_pm_opp *opp;

		opp = dev_pm_opp_find_freq_floor(dmc->dev, &freq);
		if (IS_ERR(opp))
			goto err_opp;

		dmc->opp[idx - i].freq_hz = freq;
		dmc->opp[idx - i].volt_uv = dev_pm_opp_get_voltage(opp);

		dev_pm_opp_put(opp);
	}

	return 0;

err_opp:
	dev_pm_opp_of_remove_table(dmc->dev);

	return -EINVAL;
}

/**
 * exynos5_set_bypass_dram_timings() - Low-level changes of the DRAM timings
 * @dmc:	device for which the new settings is going to be applied
 * @param:	DRAM parameters which passes timing data
 *
 * Low-level function for changing timings for DRAM memory clocking from
 * 'bypass' clock source (fixed frequency @400MHz).
 * It uses timing bank registers set 1.
 */
static void exynos5_set_bypass_dram_timings(struct exynos5_dmc *dmc)
{
	writel(EXYNOS5_AREF_NORMAL,
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGAREF);

	writel(dmc->bypass_timing_row,
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGROW1);
	writel(dmc->bypass_timing_row,
	       dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGROW1);
	writel(dmc->bypass_timing_data,
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGDATA1);
	writel(dmc->bypass_timing_data,
	       dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGDATA1);
	writel(dmc->bypass_timing_power,
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGPOWER1);
	writel(dmc->bypass_timing_power,
	       dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGPOWER1);
}

/**
 * exynos5_dram_change_timings() - Low-level changes of the DRAM final timings
 * @dmc:	device for which the new settings is going to be applied
 * @target_rate:	target frequency of the DMC
 *
 * Low-level function for changing timings for DRAM memory operating from main
 * clock source (BPLL), which can have different frequencies. Thus, each
 * frequency must have corresponding timings register values in order to keep
 * the needed delays.
 * It uses timing bank registers set 0.
 */
static int exynos5_dram_change_timings(struct exynos5_dmc *dmc,
				       unsigned long target_rate)
{
	int idx;

	for (idx = dmc->opp_count - 1; idx >= 0; idx--)
		if (dmc->opp[idx].freq_hz <= target_rate)
			break;

	if (idx < 0)
		return -EINVAL;

	writel(EXYNOS5_AREF_NORMAL,
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGAREF);

	writel(dmc->timing_row[idx],
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGROW0);
	writel(dmc->timing_row[idx],
	       dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGROW0);
	writel(dmc->timing_data[idx],
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGDATA0);
	writel(dmc->timing_data[idx],
	       dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGDATA0);
	writel(dmc->timing_power[idx],
	       dmc->base_drexi0 + EXYNOS5_DREXI_TIMINGPOWER0);
	writel(dmc->timing_power[idx],
	       dmc->base_drexi1 + EXYNOS5_DREXI_TIMINGPOWER0);

	return 0;
}

/**
 * exynos5_dmc_align_target_voltage() - Sets the final voltage for the DMC
 * @dmc:	device for which it is going to be set
 * @target_volt:	new voltage which is chosen to be final
 *
 * Function tries to align voltage to the safe level for 'normal' mode.
 * It checks the need of higher voltage and changes the value. The target
 * voltage might be lower that currently set and still the system will be
 * stable.
 */
static int exynos5_dmc_align_target_voltage(struct exynos5_dmc *dmc,
					    unsigned long target_volt)
{
	int ret = 0;

	if (dmc->curr_volt <= target_volt)
		return 0;

	ret = regulator_set_voltage(dmc->vdd_mif, target_volt,
				    target_volt);
	if (!ret)
		dmc->curr_volt = target_volt;

	return ret;
}

/**
 * exynos5_dmc_align_bypass_voltage() - Sets the voltage for the DMC
 * @dmc:	device for which it is going to be set
 * @target_volt:	new voltage which is chosen to be final
 *
 * Function tries to align voltage to the safe level for the 'bypass' mode.
 * It checks the need of higher voltage and changes the value.
 * The target voltage must not be less than currently needed, because
 * for current frequency the device might become unstable.
 */
static int exynos5_dmc_align_bypass_voltage(struct exynos5_dmc *dmc,
					    unsigned long target_volt)
{
	int ret = 0;
	unsigned long bypass_volt = dmc->opp_bypass.volt_uv;

	target_volt = max(bypass_volt, target_volt);

	if (dmc->curr_volt >= target_volt)
		return 0;

	ret = regulator_set_voltage(dmc->vdd_mif, target_volt,
				    target_volt);
	if (!ret)
		dmc->curr_volt = target_volt;

	return ret;
}

/**
 * exynos5_dmc_align_bypass_dram_timings() - Chooses and sets DRAM timings
 * @dmc:	device for which it is going to be set
 * @target_rate:	new frequency which is chosen to be final
 *
 * Function changes the DRAM timings for the temporary 'bypass' mode.
 */
static int exynos5_dmc_align_bypass_dram_timings(struct exynos5_dmc *dmc,
						 unsigned long target_rate)
{
	int idx = find_target_freq_idx(dmc, target_rate);

	if (idx < 0)
		return -EINVAL;

	exynos5_set_bypass_dram_timings(dmc);

	return 0;
}

/**
 * exynos5_dmc_switch_to_bypass_configuration() - Switching to temporary clock
 * @dmc:	DMC device for which the switching is going to happen
 * @target_rate:	new frequency which is going to be set as a final
 * @target_volt:	new voltage which is going to be set as a final
 *
 * Function configures DMC and clocks for operating in temporary 'bypass' mode.
 * This mode is used only temporary but if required, changes voltage and timings
 * for DRAM chips. It switches the main clock to stable clock source for the
 * period of the main PLL reconfiguration.
 */
static int
exynos5_dmc_switch_to_bypass_configuration(struct exynos5_dmc *dmc,
					   unsigned long target_rate,
					   unsigned long target_volt)
{
	int ret;

	/*
	 * Having higher voltage for a particular frequency does not harm
	 * the chip. Use it for the temporary frequency change when one
	 * voltage manipulation might be avoided.
	 */
	ret = exynos5_dmc_align_bypass_voltage(dmc, target_volt);
	if (ret)
		return ret;

	/*
	 * Longer delays for DRAM does not cause crash, the opposite does.
	 */
	ret = exynos5_dmc_align_bypass_dram_timings(dmc, target_rate);
	if (ret)
		return ret;

	/*
	 * Delays are long enough, so use them for the new coming clock.
	 */
	ret = exynos5_switch_timing_regs(dmc, USE_MX_MSPLL_TIMINGS);

	return ret;
}

/**
 * exynos5_dmc_change_freq_and_volt() - Changes voltage and frequency of the DMC
 * using safe procedure
 * @dmc:	device for which the frequency is going to be changed
 * @target_rate:	requested new frequency
 * @target_volt:	requested voltage which corresponds to the new frequency
 *
 * The DMC frequency change procedure requires a few steps.
 * The main requirement is to change the clock source in the clk mux
 * for the time of main clock PLL locking. The assumption is that the
 * alternative clock source set as parent is stable.
 * The second parent's clock frequency is fixed to 400MHz, it is named 'bypass'
 * clock. This requires alignment in DRAM timing parameters for the new
 * T-period. There is two bank sets for keeping DRAM
 * timings: set 0 and set 1. The set 0 is used when main clock source is
 * chosen. The 2nd set of regs is used for 'bypass' clock. Switching between
 * the two bank sets is part of the process.
 * The voltage must also be aligned to the minimum required level. There is
 * this intermediate step with switching to 'bypass' parent clock source.
 * if the old voltage is lower, it requires an increase of the voltage level.
 * The complexity of the voltage manipulation is hidden in low level function.
 * In this function there is last alignment of the voltage level at the end.
 */
static int
exynos5_dmc_change_freq_and_volt(struct exynos5_dmc *dmc,
				 unsigned long target_rate,
				 unsigned long target_volt)
{
	int ret;

	ret = exynos5_dmc_switch_to_bypass_configuration(dmc, target_rate,
							 target_volt);
	if (ret)
		return ret;

	/*
	 * Voltage is set at least to a level needed for this frequency,
	 * so switching clock source is safe now.
	 */
	clk_prepare_enable(dmc->fout_spll);
	clk_prepare_enable(dmc->mout_spll);
	clk_prepare_enable(dmc->mout_mx_mspll_ccore);

	ret = clk_set_parent(dmc->mout_mclk_cdrex, dmc->mout_mx_mspll_ccore);
	if (ret)
		goto disable_clocks;

	/*
	 * We are safe to increase the timings for current bypass frequency.
	 * Thanks to this the settings will be ready for the upcoming clock
	 * source change.
	 */
	exynos5_dram_change_timings(dmc, target_rate);

	clk_set_rate(dmc->fout_bpll, target_rate);

	ret = exynos5_switch_timing_regs(dmc, USE_BPLL_TIMINGS);
	if (ret)
		goto disable_clocks;

	ret = clk_set_parent(dmc->mout_mclk_cdrex, dmc->mout_bpll);
	if (ret)
		goto disable_clocks;

	/*
	 * Make sure if the voltage is not from 'bypass' settings and align to
	 * the right level for power efficiency.
	 */
	ret = exynos5_dmc_align_target_voltage(dmc, target_volt);

disable_clocks:
	clk_disable_unprepare(dmc->mout_mx_mspll_ccore);
	clk_disable_unprepare(dmc->mout_spll);
	clk_disable_unprepare(dmc->fout_spll);

	return ret;
}

/**
 * exynos5_dmc_get_volt_freq() - Gets the frequency and voltage from the OPP
 * table.
 * @dmc:	device for which the frequency is going to be changed
 * @freq:       requested frequency in KHz
 * @target_rate:	returned frequency which is the same or lower than
 *			requested
 * @target_volt:	returned voltage which corresponds to the returned
 *			frequency
 *
 * Function gets requested frequency and checks OPP framework for needed
 * frequency and voltage. It populates the values 'target_rate' and
 * 'target_volt' or returns error value when OPP framework fails.
 */
static int exynos5_dmc_get_volt_freq(struct exynos5_dmc *dmc,
				     unsigned long *freq,
				     unsigned long *target_rate,
				     unsigned long *target_volt, u32 flags)
{
	struct dev_pm_opp *opp;

	opp = devfreq_recommended_opp(dmc->dev, freq, flags);
	if (IS_ERR(opp))
		return PTR_ERR(opp);

	*target_rate = dev_pm_opp_get_freq(opp);
	*target_volt = dev_pm_opp_get_voltage(opp);
	dev_pm_opp_put(opp);

	return 0;
}

/**
 * exynos5_dmc_target() - Function responsible for changing frequency of DMC
 * @dev:	device for which the frequency is going to be changed
 * @freq:	requested frequency in KHz
 * @flags:	flags provided for this frequency change request
 *
 * An entry function provided to the devfreq framework which provides frequency
 * change of the DMC. The function gets the possible rate from OPP table based
 * on requested frequency. It calls the next function responsible for the
 * frequency and voltage change. In case of failure, does not set 'curr_rate'
 * and returns error value to the framework.
 */
static int exynos5_dmc_target(struct device *dev, unsigned long *freq,
			      u32 flags)
{
	struct exynos5_dmc *dmc = dev_get_drvdata(dev);
	unsigned long target_rate = 0;
	unsigned long target_volt = 0;
	int ret;

	ret = exynos5_dmc_get_volt_freq(dmc, freq, &target_rate, &target_volt,
					flags);

	if (ret)
		return ret;

	if (target_rate == dmc->curr_rate)
		return 0;

	mutex_lock(&dmc->lock);

	ret = exynos5_dmc_change_freq_and_volt(dmc, target_rate, target_volt);

	if (ret) {
		mutex_unlock(&dmc->lock);
		return ret;
	}

	dmc->curr_rate = target_rate;

	mutex_unlock(&dmc->lock);
	return 0;
}

/**
 * exynos5_counters_get() - Gets the performance counters values.
 * @dmc:	device for which the counters are going to be checked
 * @load_count:	variable which is populated with counter value
 * @total_count:	variable which is used as 'wall clock' reference
 *
 * Function which provides performance counters values. It sums up counters for
 * two DMC channels. The 'total_count' is used as a reference and max value.
 * The ratio 'load_count/total_count' shows the busy percentage [0%, 100%].
 */
static int exynos5_counters_get(struct exynos5_dmc *dmc,
				unsigned long *load_count,
				unsigned long *total_count)
{
	unsigned long total = 0;
	struct devfreq_event_data event;
	int ret, i;

	*load_count = 0;

	/* Take into account only read+write counters, but stop all */
	for (i = 0; i < dmc->num_counters; i++) {
		if (!dmc->counter[i])
			continue;

		ret = devfreq_event_get_event(dmc->counter[i], &event);
		if (ret < 0)
			return ret;

		*load_count += event.load_count;

		if (total < event.total_count)
			total = event.total_count;
	}

	*total_count = total;

	return 0;
}

/**
 * exynos5_dmc_start_perf_events() - Setup and start performance event counters
 * @dmc:	device for which the counters are going to be checked
 * @beg_value:	initial value for the counter
 *
 * Function which enables needed counters, interrupts and sets initial values
 * then starts the counters.
 */
static void exynos5_dmc_start_perf_events(struct exynos5_dmc *dmc,
					  u32 beg_value)
{
	/* Enable interrupts for counter 2 */
	writel(PERF_CNT2, dmc->base_drexi0 + DREX_INTENS_PPC);
	writel(PERF_CNT2, dmc->base_drexi1 + DREX_INTENS_PPC);

	/* Enable counter 2 and CCNT  */
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_CNTENS_PPC);
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_CNTENS_PPC);

	/* Clear overflow flag for all counters */
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_FLAG_PPC);
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_FLAG_PPC);

	/* Reset all counters */
	writel(CC_RESET | PPC_COUNTER_RESET, dmc->base_drexi0 + DREX_PMNC_PPC);
	writel(CC_RESET | PPC_COUNTER_RESET, dmc->base_drexi1 + DREX_PMNC_PPC);

	/*
	 * Set start value for the counters, the number of samples that
	 * will be gathered is calculated as: 0xffffffff - beg_value
	 */
	writel(beg_value, dmc->base_drexi0 + DREX_PMCNT2_PPC);
	writel(beg_value, dmc->base_drexi1 + DREX_PMCNT2_PPC);

	/* Start all counters */
	writel(PPC_ENABLE, dmc->base_drexi0 + DREX_PMNC_PPC);
	writel(PPC_ENABLE, dmc->base_drexi1 + DREX_PMNC_PPC);
}

/**
 * exynos5_dmc_perf_events_calc() - Calculate utilization
 * @dmc:	device for which the counters are going to be checked
 * @diff_ts:	time between last interrupt and current one
 *
 * Function which calculates needed utilization for the devfreq governor.
 * It prepares values for 'busy_time' and 'total_time' based on elapsed time
 * between interrupts, which approximates utilization.
 */
static void exynos5_dmc_perf_events_calc(struct exynos5_dmc *dmc, u64 diff_ts)
{
	/*
	 * This is a simple algorithm for managing traffic on DMC.
	 * When there is almost no load the counters overflow every 4s,
	 * no mater the DMC frequency.
	 * The high load might be approximated using linear function.
	 * Knowing that, simple calculation can provide 'busy_time' and
	 * 'total_time' to the devfreq governor which picks up target
	 * frequency.
	 * We want a fast ramp up and slow decay in frequency change function.
	 */
	if (diff_ts < PERF_EVENT_UP_DOWN_THRESHOLD) {
		/*
		 * Set higher utilization for the simple_ondemand governor.
		 * The governor should increase the frequency of the DMC.
		 */
		dmc->load = 70;
		dmc->total = 100;
	} else {
		/*
		 * Set low utilization for the simple_ondemand governor.
		 * The governor should decrease the frequency of the DMC.
		 */
		dmc->load = 35;
		dmc->total = 100;
	}

	dev_dbg(dmc->dev, "diff_ts=%llu\n", diff_ts);
}

/**
 * exynos5_dmc_perf_events_check() - Checks the status of the counters
 * @dmc:	device for which the counters are going to be checked
 *
 * Function which is called from threaded IRQ to check the counters state
 * and to call approximation for the needed utilization.
 */
static void exynos5_dmc_perf_events_check(struct exynos5_dmc *dmc)
{
	u32 val;
	u64 diff_ts, ts;

	ts = ktime_get_ns();

	/* Stop all counters */
	writel(0, dmc->base_drexi0 + DREX_PMNC_PPC);
	writel(0, dmc->base_drexi1 + DREX_PMNC_PPC);

	/* Check the source in interrupt flag registers (which channel) */
	val = readl(dmc->base_drexi0 + DREX_FLAG_PPC);
	if (val) {
		diff_ts = ts - dmc->last_overflow_ts[0];
		dmc->last_overflow_ts[0] = ts;
		dev_dbg(dmc->dev, "drex0 0xE050 val= 0x%08x\n",  val);
	} else {
		val = readl(dmc->base_drexi1 + DREX_FLAG_PPC);
		diff_ts = ts - dmc->last_overflow_ts[1];
		dmc->last_overflow_ts[1] = ts;
		dev_dbg(dmc->dev, "drex1 0xE050 val= 0x%08x\n",  val);
	}

	exynos5_dmc_perf_events_calc(dmc, diff_ts);

	exynos5_dmc_start_perf_events(dmc, PERF_COUNTER_START_VALUE);
}

/**
 * exynos5_dmc_enable_perf_events() - Enable performance events
 * @dmc:	device for which the counters are going to be checked
 *
 * Function which is setup needed environment and enables counters.
 */
static void exynos5_dmc_enable_perf_events(struct exynos5_dmc *dmc)
{
	u64 ts;

	/* Enable Performance Event Clock */
	writel(PEREV_CLK_EN, dmc->base_drexi0 + DREX_PPCCLKCON);
	writel(PEREV_CLK_EN, dmc->base_drexi1 + DREX_PPCCLKCON);

	/* Select read transfers as performance event2 */
	writel(READ_TRANSFER_CH0, dmc->base_drexi0 + DREX_PEREV2CONFIG);
	writel(READ_TRANSFER_CH1, dmc->base_drexi1 + DREX_PEREV2CONFIG);

	ts = ktime_get_ns();
	dmc->last_overflow_ts[0] = ts;
	dmc->last_overflow_ts[1] = ts;

	/* Devfreq shouldn't be faster than initialization, play safe though. */
	dmc->load = 99;
	dmc->total = 100;
}

/**
 * exynos5_dmc_disable_perf_events() - Disable performance events
 * @dmc:	device for which the counters are going to be checked
 *
 * Function which stops, disables performance event counters and interrupts.
 */
static void exynos5_dmc_disable_perf_events(struct exynos5_dmc *dmc)
{
	/* Stop all counters */
	writel(0, dmc->base_drexi0 + DREX_PMNC_PPC);
	writel(0, dmc->base_drexi1 + DREX_PMNC_PPC);

	/* Disable interrupts for counter 2 */
	writel(PERF_CNT2, dmc->base_drexi0 + DREX_INTENC_PPC);
	writel(PERF_CNT2, dmc->base_drexi1 + DREX_INTENC_PPC);

	/* Disable counter 2 and CCNT  */
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_CNTENC_PPC);
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_CNTENC_PPC);

	/* Clear overflow flag for all counters */
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi0 + DREX_FLAG_PPC);
	writel(PERF_CNT2 | PERF_CCNT, dmc->base_drexi1 + DREX_FLAG_PPC);
}

/**
 * exynos5_dmc_get_status() - Read current DMC performance statistics.
 * @dev:	device for which the statistics are requested
 * @stat:	structure which has statistic fields
 *
 * Function reads the DMC performance counters and calculates 'busy_time'
 * and 'total_time'. To protect from overflow, the values are shifted right
 * by 10. After read out the counters are setup to count again.
 */
static int exynos5_dmc_get_status(struct device *dev,
				  struct devfreq_dev_status *stat)
{
	struct exynos5_dmc *dmc = dev_get_drvdata(dev);
	unsigned long load, total;
	int ret;

	if (dmc->in_irq_mode) {
		stat->current_frequency = dmc->curr_rate;
		stat->busy_time = dmc->load;
		stat->total_time = dmc->total;
	} else {
		ret = exynos5_counters_get(dmc, &load, &total);
		if (ret < 0)
			return -EINVAL;

		/* To protect from overflow, divide by 1024 */
		stat->busy_time = load >> 10;
		stat->total_time = total >> 10;

		ret = exynos5_counters_set_event(dmc);
		if (ret < 0) {
			dev_err(dev, "could not set event counter\n");
			return ret;
		}
	}

	return 0;
}

/**
 * exynos5_dmc_get_cur_freq() - Function returns current DMC frequency
 * @dev:	device for which the framework checks operating frequency
 * @freq:	returned frequency value
 *
 * It returns the currently used frequency of the DMC. The real operating
 * frequency might be lower when the clock source value could not be divided
 * to the requested value.
 */
static int exynos5_dmc_get_cur_freq(struct device *dev, unsigned long *freq)
{
	struct exynos5_dmc *dmc = dev_get_drvdata(dev);

	mutex_lock(&dmc->lock);
	*freq = dmc->curr_rate;
	mutex_unlock(&dmc->lock);

	return 0;
}

/**
 * exynos5_dmc_df_profile - Devfreq governor's profile structure
 *
 * It provides to the devfreq framework needed functions and polling period.
 */
static struct devfreq_dev_profile exynos5_dmc_df_profile = {
	.timer = DEVFREQ_TIMER_DELAYED,
	.target = exynos5_dmc_target,
	.get_dev_status = exynos5_dmc_get_status,
	.get_cur_freq = exynos5_dmc_get_cur_freq,
};

/**
 * exynos5_dmc_align_initial_frequency() - Align initial frequency value
 * @dmc:	device for which the frequency is going to be set
 * @bootloader_init_freq:	initial frequency set by the bootloader in KHz
 *
 * The initial bootloader frequency, which is present during boot, might be
 * different that supported frequency values in the driver. It is possible
 * due to different PLL settings or used PLL as a source.
 * This function provides the 'initial_freq' for the devfreq framework
 * statistics engine which supports only registered values. Thus, some alignment
 * must be made.
 */
static unsigned long
exynos5_dmc_align_init_freq(struct exynos5_dmc *dmc,
			    unsigned long bootloader_init_freq)
{
	unsigned long aligned_freq;
	int idx;

	idx = find_target_freq_idx(dmc, bootloader_init_freq);
	if (idx >= 0)
		aligned_freq = dmc->opp[idx].freq_hz;
	else
		aligned_freq = dmc->opp[dmc->opp_count - 1].freq_hz;

	return aligned_freq;
}

/**
 * create_timings_aligned() - Create register values and align with standard
 * @dmc:	device for which the frequency is going to be set
 * @idx:	speed bin in the OPP table
 * @clk_period_ps:	the period of the clock, known as tCK
 *
 * The function calculates timings and creates a register value ready for
 * a frequency transition. The register contains a few timings. They are
 * shifted by a known offset. The timing value is calculated based on memory
 * specyfication: minimal time required and minimal cycles required.
 */
static int create_timings_aligned(struct exynos5_dmc *dmc, u32 *reg_timing_row,
				  u32 *reg_timing_data, u32 *reg_timing_power,
				  u32 clk_period_ps)
{
	u32 val;
	const struct timing_reg *reg;

	if (clk_period_ps == 0)
		return -EINVAL;

	*reg_timing_row = 0;
	*reg_timing_data = 0;
	*reg_timing_power = 0;

	val = dmc->timings->tRFC / clk_period_ps;
	val += dmc->timings->tRFC % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRFC);
	reg = &timing_row[0];
	*reg_timing_row |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tRRD / clk_period_ps;
	val += dmc->timings->tRRD % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRRD);
	reg = &timing_row[1];
	*reg_timing_row |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tRPab / clk_period_ps;
	val += dmc->timings->tRPab % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRPab);
	reg = &timing_row[2];
	*reg_timing_row |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tRCD / clk_period_ps;
	val += dmc->timings->tRCD % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRCD);
	reg = &timing_row[3];
	*reg_timing_row |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tRC / clk_period_ps;
	val += dmc->timings->tRC % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRC);
	reg = &timing_row[4];
	*reg_timing_row |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tRAS / clk_period_ps;
	val += dmc->timings->tRAS % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRAS);
	reg = &timing_row[5];
	*reg_timing_row |= TIMING_VAL2REG(reg, val);

	/* data related timings */
	val = dmc->timings->tWTR / clk_period_ps;
	val += dmc->timings->tWTR % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tWTR);
	reg = &timing_data[0];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tWR / clk_period_ps;
	val += dmc->timings->tWR % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tWR);
	reg = &timing_data[1];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tRTP / clk_period_ps;
	val += dmc->timings->tRTP % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRTP);
	reg = &timing_data[2];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tW2W_C2C / clk_period_ps;
	val += dmc->timings->tW2W_C2C % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tW2W_C2C);
	reg = &timing_data[3];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tR2R_C2C / clk_period_ps;
	val += dmc->timings->tR2R_C2C % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tR2R_C2C);
	reg = &timing_data[4];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tWL / clk_period_ps;
	val += dmc->timings->tWL % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tWL);
	reg = &timing_data[5];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tDQSCK / clk_period_ps;
	val += dmc->timings->tDQSCK % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tDQSCK);
	reg = &timing_data[6];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tRL / clk_period_ps;
	val += dmc->timings->tRL % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tRL);
	reg = &timing_data[7];
	*reg_timing_data |= TIMING_VAL2REG(reg, val);

	/* power related timings */
	val = dmc->timings->tFAW / clk_period_ps;
	val += dmc->timings->tFAW % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tFAW);
	reg = &timing_power[0];
	*reg_timing_power |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tXSR / clk_period_ps;
	val += dmc->timings->tXSR % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tXSR);
	reg = &timing_power[1];
	*reg_timing_power |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tXP / clk_period_ps;
	val += dmc->timings->tXP % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tXP);
	reg = &timing_power[2];
	*reg_timing_power |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tCKE / clk_period_ps;
	val += dmc->timings->tCKE % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tCKE);
	reg = &timing_power[3];
	*reg_timing_power |= TIMING_VAL2REG(reg, val);

	val = dmc->timings->tMRD / clk_period_ps;
	val += dmc->timings->tMRD % clk_period_ps ? 1 : 0;
	val = max(val, dmc->min_tck->tMRD);
	reg = &timing_power[4];
	*reg_timing_power |= TIMING_VAL2REG(reg, val);

	return 0;
}

/**
 * of_get_dram_timings() - helper function for parsing DT settings for DRAM
 * @dmc:        device for which the frequency is going to be set
 *
 * The function parses DT entries with DRAM information.
 */
static int of_get_dram_timings(struct exynos5_dmc *dmc)
{
	int ret = 0;
	int idx;
	struct device_node *np_ddr;
	u32 freq_mhz, clk_period_ps;

	np_ddr = of_parse_phandle(dmc->dev->of_node, "device-handle", 0);
	if (!np_ddr) {
		dev_warn(dmc->dev, "could not find 'device-handle' in DT\n");
		return -EINVAL;
	}

	dmc->timing_row = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
					     sizeof(u32), GFP_KERNEL);
	if (!dmc->timing_row)
		return -ENOMEM;

	dmc->timing_data = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
					      sizeof(u32), GFP_KERNEL);
	if (!dmc->timing_data)
		return -ENOMEM;

	dmc->timing_power = devm_kmalloc_array(dmc->dev, TIMING_COUNT,
					       sizeof(u32), GFP_KERNEL);
	if (!dmc->timing_power)
		return -ENOMEM;

	dmc->timings = of_lpddr3_get_ddr_timings(np_ddr, dmc->dev,
						 DDR_TYPE_LPDDR3,
						 &dmc->timings_arr_size);
	if (!dmc->timings) {
		of_node_put(np_ddr);
		dev_warn(dmc->dev, "could not get timings from DT\n");
		return -EINVAL;
	}

	dmc->min_tck = of_lpddr3_get_min_tck(np_ddr, dmc->dev);
	if (!dmc->min_tck) {
		of_node_put(np_ddr);
		dev_warn(dmc->dev, "could not get tck from DT\n");
		return -EINVAL;
	}

	/* Sorted array of OPPs with frequency ascending */
	for (idx = 0; idx < dmc->opp_count; idx++) {
		freq_mhz = dmc->opp[idx].freq_hz / 1000000;
		clk_period_ps = 1000000 / freq_mhz;

		ret = create_timings_aligned(dmc, &dmc->timing_row[idx],
					     &dmc->timing_data[idx],
					     &dmc->timing_power[idx],
					     clk_period_ps);
	}

	of_node_put(np_ddr);

	/* Take the highest frequency's timings as 'bypass' */
	dmc->bypass_timing_row = dmc->timing_row[idx - 1];
	dmc->bypass_timing_data = dmc->timing_data[idx - 1];
	dmc->bypass_timing_power = dmc->timing_power[idx - 1];

	return ret;
}

/**
 * exynos5_dmc_init_clks() - Initialize clocks needed for DMC operation.
 * @dmc:	DMC structure containing needed fields
 *
 * Get the needed clocks defined in DT device, enable and set the right parents.
 * Read current frequency and initialize the initial rate for governor.
 */
static int exynos5_dmc_init_clks(struct exynos5_dmc *dmc)
{
	int ret;
	unsigned long target_volt = 0;
	unsigned long target_rate = 0;
	unsigned int tmp;

	dmc->fout_spll = devm_clk_get(dmc->dev, "fout_spll");
	if (IS_ERR(dmc->fout_spll))
		return PTR_ERR(dmc->fout_spll);

	dmc->fout_bpll = devm_clk_get(dmc->dev, "fout_bpll");
	if (IS_ERR(dmc->fout_bpll))
		return PTR_ERR(dmc->fout_bpll);

	dmc->mout_mclk_cdrex = devm_clk_get(dmc->dev, "mout_mclk_cdrex");
	if (IS_ERR(dmc->mout_mclk_cdrex))
		return PTR_ERR(dmc->mout_mclk_cdrex);

	dmc->mout_bpll = devm_clk_get(dmc->dev, "mout_bpll");
	if (IS_ERR(dmc->mout_bpll))
		return PTR_ERR(dmc->mout_bpll);

	dmc->mout_mx_mspll_ccore = devm_clk_get(dmc->dev,
						"mout_mx_mspll_ccore");
	if (IS_ERR(dmc->mout_mx_mspll_ccore))
		return PTR_ERR(dmc->mout_mx_mspll_ccore);

	dmc->mout_spll = devm_clk_get(dmc->dev, "ff_dout_spll2");
	if (IS_ERR(dmc->mout_spll)) {
		dmc->mout_spll = devm_clk_get(dmc->dev, "mout_sclk_spll");
		if (IS_ERR(dmc->mout_spll))
			return PTR_ERR(dmc->mout_spll);
	}

	/*
	 * Convert frequency to KHz values and set it for the governor.
	 */
	dmc->curr_rate = clk_get_rate(dmc->mout_mclk_cdrex);
	dmc->curr_rate = exynos5_dmc_align_init_freq(dmc, dmc->curr_rate);
	exynos5_dmc_df_profile.initial_freq = dmc->curr_rate;

	ret = exynos5_dmc_get_volt_freq(dmc, &dmc->curr_rate, &target_rate,
					&target_volt, 0);
	if (ret)
		return ret;

	dmc->curr_volt = target_volt;

	clk_set_parent(dmc->mout_mx_mspll_ccore, dmc->mout_spll);

	dmc->bypass_rate = clk_get_rate(dmc->mout_mx_mspll_ccore);

	clk_prepare_enable(dmc->fout_bpll);
	clk_prepare_enable(dmc->mout_bpll);

	/*
	 * Some bootloaders do not set clock routes correctly.
	 * Stop one path in clocks to PHY.
	 */
	regmap_read(dmc->clk_regmap, CDREX_LPDDR3PHY_CLKM_SRC, &tmp);
	tmp &= ~(BIT(1) | BIT(0));
	regmap_write(dmc->clk_regmap, CDREX_LPDDR3PHY_CLKM_SRC, tmp);

	return 0;
}

/**
 * exynos5_performance_counters_init() - Initializes performance DMC's counters
 * @dmc:	DMC for which it does the setup
 *
 * Initialization of performance counters in DMC for estimating usage.
 * The counter's values are used for calculation of a memory bandwidth and based
 * on that the governor changes the frequency.
 * The counters are not used when the governor is GOVERNOR_USERSPACE.
 */
static int exynos5_performance_counters_init(struct exynos5_dmc *dmc)
{
	int counters_size;
	int ret, i;

	dmc->num_counters = devfreq_event_get_edev_count(dmc->dev);
	if (dmc->num_counters < 0) {
		dev_err(dmc->dev, "could not get devfreq-event counters\n");
		return dmc->num_counters;
	}

	counters_size = sizeof(struct devfreq_event_dev) * dmc->num_counters;
	dmc->counter = devm_kzalloc(dmc->dev, counters_size, GFP_KERNEL);
	if (!dmc->counter)
		return -ENOMEM;

	for (i = 0; i < dmc->num_counters; i++) {
		dmc->counter[i] =
			devfreq_event_get_edev_by_phandle(dmc->dev, i);
		if (IS_ERR_OR_NULL(dmc->counter[i]))
			return -EPROBE_DEFER;
	}

	ret = exynos5_counters_enable_edev(dmc);
	if (ret < 0) {
		dev_err(dmc->dev, "could not enable event counter\n");
		return ret;
	}

	ret = exynos5_counters_set_event(dmc);
	if (ret < 0) {
		exynos5_counters_disable_edev(dmc);
		dev_err(dmc->dev, "could not set event counter\n");
		return ret;
	}

	return 0;
}

/**
 * exynos5_dmc_set_pause_on_switching() - Controls a pause feature in DMC
 * @dmc:	device which is used for changing this feature
 * @set:	a boolean state passing enable/disable request
 *
 * There is a need of pausing DREX DMC when divider or MUX in clock tree
 * changes its configuration. In such situation access to the memory is blocked
 * in DMC automatically. This feature is used when clock frequency change
 * request appears and touches clock tree.
 */
static inline int exynos5_dmc_set_pause_on_switching(struct exynos5_dmc *dmc)
{
	unsigned int val;
	int ret;

	ret = regmap_read(dmc->clk_regmap, CDREX_PAUSE, &val);
	if (ret)
		return ret;

	val |= 1UL;
	regmap_write(dmc->clk_regmap, CDREX_PAUSE, val);

	return 0;
}

static irqreturn_t dmc_irq_thread(int irq, void *priv)
{
	int res;
	struct exynos5_dmc *dmc = priv;

	mutex_lock(&dmc->df->lock);
	exynos5_dmc_perf_events_check(dmc);
	res = update_devfreq(dmc->df);
	mutex_unlock(&dmc->df->lock);

	if (res)
		dev_warn(dmc->dev, "devfreq failed with %d\n", res);

	return IRQ_HANDLED;
}

/**
 * exynos5_dmc_probe() - Probe function for the DMC driver
 * @pdev:	platform device for which the driver is going to be initialized
 *
 * Initialize basic components: clocks, regulators, performance counters, etc.
 * Read out product version and based on the information setup
 * internal structures for the controller (frequency and voltage) and for DRAM
 * memory parameters: timings for each operating frequency.
 * Register new devfreq device for controlling DVFS of the DMC.
 */
static int exynos5_dmc_probe(struct platform_device *pdev)
{
	int ret = 0;
	struct device *dev = &pdev->dev;
	struct device_node *np = dev->of_node;
	struct exynos5_dmc *dmc;
	int irq[2];

	dmc = devm_kzalloc(dev, sizeof(*dmc), GFP_KERNEL);
	if (!dmc)
		return -ENOMEM;

	mutex_init(&dmc->lock);

	dmc->dev = dev;
	platform_set_drvdata(pdev, dmc);

	dmc->base_drexi0 = devm_platform_ioremap_resource(pdev, 0);
	if (IS_ERR(dmc->base_drexi0))
		return PTR_ERR(dmc->base_drexi0);

	dmc->base_drexi1 = devm_platform_ioremap_resource(pdev, 1);
	if (IS_ERR(dmc->base_drexi1))
		return PTR_ERR(dmc->base_drexi1);

	dmc->clk_regmap = syscon_regmap_lookup_by_phandle(np,
							  "samsung,syscon-clk");
	if (IS_ERR(dmc->clk_regmap))
		return PTR_ERR(dmc->clk_regmap);

	ret = exynos5_init_freq_table(dmc, &exynos5_dmc_df_profile);
	if (ret) {
		dev_warn(dev, "couldn't initialize frequency settings\n");
		return ret;
	}

	dmc->vdd_mif = devm_regulator_get(dev, "vdd");
	if (IS_ERR(dmc->vdd_mif)) {
		ret = PTR_ERR(dmc->vdd_mif);
		return ret;
	}

	ret = exynos5_dmc_init_clks(dmc);
	if (ret)
		return ret;

	ret = of_get_dram_timings(dmc);
	if (ret) {
		dev_warn(dev, "couldn't initialize timings settings\n");
		goto remove_clocks;
	}

	ret = exynos5_dmc_set_pause_on_switching(dmc);
	if (ret) {
		dev_warn(dev, "couldn't get access to PAUSE register\n");
		goto remove_clocks;
	}

	/* There is two modes in which the driver works: polling or IRQ */
	irq[0] = platform_get_irq_byname(pdev, "drex_0");
	irq[1] = platform_get_irq_byname(pdev, "drex_1");
	if (irq[0] > 0 && irq[1] > 0 && irqmode) {
		ret = devm_request_threaded_irq(dev, irq[0], NULL,
						dmc_irq_thread, IRQF_ONESHOT,
						dev_name(dev), dmc);
		if (ret) {
			dev_err(dev, "couldn't grab IRQ\n");
			goto remove_clocks;
		}

		ret = devm_request_threaded_irq(dev, irq[1], NULL,
						dmc_irq_thread, IRQF_ONESHOT,
						dev_name(dev), dmc);
		if (ret) {
			dev_err(dev, "couldn't grab IRQ\n");
			goto remove_clocks;
		}

		/*
		 * Setup default thresholds for the devfreq governor.
		 * The values are chosen based on experiments.
		 */
		dmc->gov_data.upthreshold = 55;
		dmc->gov_data.downdifferential = 5;

		exynos5_dmc_enable_perf_events(dmc);

		dmc->in_irq_mode = 1;
	} else {
		ret = exynos5_performance_counters_init(dmc);
		if (ret) {
			dev_warn(dev, "couldn't probe performance counters\n");
			goto remove_clocks;
		}

		/*
		 * Setup default thresholds for the devfreq governor.
		 * The values are chosen based on experiments.
		 */
		dmc->gov_data.upthreshold = 10;
		dmc->gov_data.downdifferential = 5;

		exynos5_dmc_df_profile.polling_ms = 100;
	}

	dmc->df = devm_devfreq_add_device(dev, &exynos5_dmc_df_profile,
					  DEVFREQ_GOV_SIMPLE_ONDEMAND,
					  &dmc->gov_data);

	if (IS_ERR(dmc->df)) {
		ret = PTR_ERR(dmc->df);
		goto err_devfreq_add;
	}

	if (dmc->in_irq_mode)
		exynos5_dmc_start_perf_events(dmc, PERF_COUNTER_START_VALUE);

	dev_info(dev, "DMC initialized, in irq mode: %d\n", dmc->in_irq_mode);

	return 0;

err_devfreq_add:
	if (dmc->in_irq_mode)
		exynos5_dmc_disable_perf_events(dmc);
	else
		exynos5_counters_disable_edev(dmc);
remove_clocks:
	clk_disable_unprepare(dmc->mout_bpll);
	clk_disable_unprepare(dmc->fout_bpll);

	return ret;
}

/**
 * exynos5_dmc_remove() - Remove function for the platform device
 * @pdev:	platform device which is going to be removed
 *
 * The function relies on 'devm' framework function which automatically
 * clean the device's resources. It just calls explicitly disable function for
 * the performance counters.
 */
static int exynos5_dmc_remove(struct platform_device *pdev)
{
	struct exynos5_dmc *dmc = dev_get_drvdata(&pdev->dev);

	if (dmc->in_irq_mode)
		exynos5_dmc_disable_perf_events(dmc);
	else
		exynos5_counters_disable_edev(dmc);

	clk_disable_unprepare(dmc->mout_bpll);
	clk_disable_unprepare(dmc->fout_bpll);

	dev_pm_opp_remove_table(dmc->dev);

	return 0;
}

static const struct of_device_id exynos5_dmc_of_match[] = {
	{ .compatible = "samsung,exynos5422-dmc", },
	{ },
};
MODULE_DEVICE_TABLE(of, exynos5_dmc_of_match);

static struct platform_driver exynos5_dmc_platdrv = {
	.probe	= exynos5_dmc_probe,
	.remove = exynos5_dmc_remove,
	.driver = {
		.name	= "exynos5-dmc",
		.of_match_table = exynos5_dmc_of_match,
	},
};
module_platform_driver(exynos5_dmc_platdrv);
MODULE_DESCRIPTION("Driver for Exynos5422 Dynamic Memory Controller dynamic frequency and voltage change");
MODULE_LICENSE("GPL v2");
MODULE_AUTHOR("Lukasz Luba");
