From a613b739b8c08eab811e677810045cc0522fc3e6 Mon Sep 17 00:00:00 2001 From: Tony Lindgren Date: Thu, 10 Apr 2014 16:47:18 -0700 Subject: mfd: twl-core: Fix idle mode signaling for omaps when booted with device tree I noticed a regression where the omap sys_clkreq signal will never trigger for omap3 when booted with device tree while it triggers when booted in legacy mode. This means voltage scaling does not do anything when booted with device tree. Turns out the reason is we fail to initialize the SmartReflex enable bit in twl4030 with the following error: twl: not initialized And that happens because we are wrongly tinkering with the twl4030 registers in arch/arm/mach-omap2/omap_twl.c before the driver is initialized. Looking at the the SmartReflex bit enable code in omap_twl.c, we need to always set it. So let's fix the issue by always enabling the twl4030 SmartReflex bit in the drivers/mfd/twl-core.c probe, and drop the related code in omap_twl.c. Note that we still have some twl4030 tinkering left in omap_twl.c for the twl6030 case, but that's a different patch. Signed-off-by: Tony Lindgren Signed-off-by: Lee Jones --- drivers/mfd/twl-core.c | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'drivers') diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c index ed718328eff1..ad7d04f95dd1 100644 --- a/drivers/mfd/twl-core.c +++ b/drivers/mfd/twl-core.c @@ -98,7 +98,11 @@ #define TWL4030_BASEADD_BACKUP 0x0014 #define TWL4030_BASEADD_INT 0x002E #define TWL4030_BASEADD_PM_MASTER 0x0036 + #define TWL4030_BASEADD_PM_RECEIVER 0x005B +#define TWL4030_DCDC_GLOBAL_CFG 0x06 +#define SMARTREFLEX_ENABLE BIT(3) + #define TWL4030_BASEADD_RTC 0x001C #define TWL4030_BASEADD_SECURED_REG 0x0000 @@ -1204,6 +1208,11 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) * Disable TWL4030/TWL5030 I2C Pull-up on I2C1 and I2C4(SR) interface. * Program I2C_SCL_CTRL_PU(bit 0)=0, I2C_SDA_CTRL_PU (bit 2)=0, * SR_I2C_SCL_CTRL_PU(bit 4)=0 and SR_I2C_SDA_CTRL_PU(bit 6)=0. + * + * Also, always enable SmartReflex bit as that's needed for omaps to + * to do anything over I2C4 for voltage scaling even if SmartReflex + * is disabled. Without the SmartReflex bit omap sys_clkreq idle + * signal will never trigger for retention idle. */ if (twl_class_is_4030()) { u8 temp; @@ -1212,6 +1221,12 @@ twl_probe(struct i2c_client *client, const struct i2c_device_id *id) temp &= ~(SR_I2C_SDA_CTRL_PU | SR_I2C_SCL_CTRL_PU | \ I2C_SDA_CTRL_PU | I2C_SCL_CTRL_PU); twl_i2c_write_u8(TWL4030_MODULE_INTBR, temp, REG_GPPUPDCTR1); + + twl_i2c_read_u8(TWL_MODULE_PM_RECEIVER, &temp, + TWL4030_DCDC_GLOBAL_CFG); + temp |= SMARTREFLEX_ENABLE; + twl_i2c_write_u8(TWL_MODULE_PM_RECEIVER, temp, + TWL4030_DCDC_GLOBAL_CFG); } if (node) { -- cgit v1.2.2 From 5686a1e5aa436c49187a60052d5885fb1f541ce6 Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 14 Apr 2014 15:47:01 +0200 Subject: bus: mvebu: pass the coherency availability information at init time Until now, the mvebu-mbus was guessing by itself whether hardware I/O coherency was available or not by poking into the Device Tree to see if the coherency fabric Device Tree node was present or not. However, on some upcoming SoCs, the presence or absence of the coherency fabric DT node isn't sufficient: in CONFIG_SMP, the coherency can be enabled, but not in !CONFIG_SMP. In order to clean this up, the mvebu_mbus_dt_init() function is extended to get a boolean argument telling whether coherency is enabled or not. Therefore, the logic to decide whether coherency is available or not now belongs to the core SoC code instead of the mvebu-mbus driver itself, which is much better. Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397483228-25625-4-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/bus/mvebu-mbus.c | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'drivers') diff --git a/drivers/bus/mvebu-mbus.c b/drivers/bus/mvebu-mbus.c index 293e2e0a0a87..ff02fc90fc21 100644 --- a/drivers/bus/mvebu-mbus.c +++ b/drivers/bus/mvebu-mbus.c @@ -694,7 +694,6 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, phys_addr_t sdramwins_phys_base, size_t sdramwins_size) { - struct device_node *np; int win; mbus->mbuswins_base = ioremap(mbuswins_phys_base, mbuswins_size); @@ -707,12 +706,6 @@ static int __init mvebu_mbus_common_init(struct mvebu_mbus_state *mbus, return -ENOMEM; } - np = of_find_compatible_node(NULL, NULL, "marvell,coherency-fabric"); - if (np) { - mbus->hw_io_coherency = 1; - of_node_put(np); - } - for (win = 0; win < mbus->soc->num_wins; win++) mvebu_mbus_disable_window(mbus, win); @@ -882,7 +875,7 @@ static void __init mvebu_mbus_get_pcie_resources(struct device_node *np, } } -int __init mvebu_mbus_dt_init(void) +int __init mvebu_mbus_dt_init(bool is_coherent) { struct resource mbuswins_res, sdramwins_res; struct device_node *np, *controller; @@ -920,6 +913,8 @@ int __init mvebu_mbus_dt_init(void) return -EINVAL; } + mbus_state.hw_io_coherency = is_coherent; + /* Get optional pcie-{mem,io}-aperture properties */ mvebu_mbus_get_pcie_resources(np, &mbus_state.pcie_mem_aperture, &mbus_state.pcie_io_aperture); -- cgit v1.2.2 From 27cb1c2083373a44130d50d4d2fb64cf7eff2d90 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 7 May 2014 18:00:08 +0200 Subject: clk: at91: rework main clk implementation AT91 main clk is a clk multiplexer and not a simple fixed rate clk as currently implemented. In some SoCs (sam9x5, sama5, sam9g45 families) this multiplexer can choose among 2 sources: an internal RC oscillator circuit and an oscillator using an external crystal. In other Socs (sam9260, rm9200 families) the multiplexer source is hardcoded to the external crystal oscillator. Signed-off-by: Boris BREZILLON Acked-by: Mike Turquette Signed-off-by: Nicolas Ferre --- drivers/clk/at91/clk-main.c | 577 +++++++++++++++++++++++++++++++++++++++----- drivers/clk/at91/pmc.c | 12 + drivers/clk/at91/pmc.h | 6 + 3 files changed, 532 insertions(+), 63 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/at91/clk-main.c b/drivers/clk/at91/clk-main.c index 8e9e8cc0412d..733306131b99 100644 --- a/drivers/clk/at91/clk-main.c +++ b/drivers/clk/at91/clk-main.c @@ -30,99 +30,546 @@ #define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ) #define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT -struct clk_main { +#define MOR_KEY_MASK (0xff << 16) + +struct clk_main_osc { struct clk_hw hw; struct at91_pmc *pmc; - unsigned long rate; unsigned int irq; wait_queue_head_t wait; }; -#define to_clk_main(hw) container_of(hw, struct clk_main, hw) +#define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw) + +struct clk_main_rc_osc { + struct clk_hw hw; + struct at91_pmc *pmc; + unsigned int irq; + wait_queue_head_t wait; + unsigned long frequency; + unsigned long accuracy; +}; + +#define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw) + +struct clk_rm9200_main { + struct clk_hw hw; + struct at91_pmc *pmc; +}; + +#define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw) -static irqreturn_t clk_main_irq_handler(int irq, void *dev_id) +struct clk_sam9x5_main { + struct clk_hw hw; + struct at91_pmc *pmc; + unsigned int irq; + wait_queue_head_t wait; + u8 parent; +}; + +#define to_clk_sam9x5_main(hw) container_of(hw, struct clk_sam9x5_main, hw) + +static irqreturn_t clk_main_osc_irq_handler(int irq, void *dev_id) { - struct clk_main *clkmain = (struct clk_main *)dev_id; + struct clk_main_osc *osc = dev_id; - wake_up(&clkmain->wait); - disable_irq_nosync(clkmain->irq); + wake_up(&osc->wait); + disable_irq_nosync(osc->irq); return IRQ_HANDLED; } -static int clk_main_prepare(struct clk_hw *hw) +static int clk_main_osc_prepare(struct clk_hw *hw) { - struct clk_main *clkmain = to_clk_main(hw); - struct at91_pmc *pmc = clkmain->pmc; - unsigned long halt_time, timeout; + struct clk_main_osc *osc = to_clk_main_osc(hw); + struct at91_pmc *pmc = osc->pmc; u32 tmp; + tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; + if (tmp & AT91_PMC_OSCBYPASS) + return 0; + + if (!(tmp & AT91_PMC_MOSCEN)) { + tmp |= AT91_PMC_MOSCEN | AT91_PMC_KEY; + pmc_write(pmc, AT91_CKGR_MOR, tmp); + } + while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS)) { - enable_irq(clkmain->irq); - wait_event(clkmain->wait, + enable_irq(osc->irq); + wait_event(osc->wait, pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS); } - if (clkmain->rate) - return 0; + return 0; +} + +static void clk_main_osc_unprepare(struct clk_hw *hw) +{ + struct clk_main_osc *osc = to_clk_main_osc(hw); + struct at91_pmc *pmc = osc->pmc; + u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); + + if (tmp & AT91_PMC_OSCBYPASS) + return; + + if (!(tmp & AT91_PMC_MOSCEN)) + return; + + tmp &= ~(AT91_PMC_KEY | AT91_PMC_MOSCEN); + pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); +} + +static int clk_main_osc_is_prepared(struct clk_hw *hw) +{ + struct clk_main_osc *osc = to_clk_main_osc(hw); + struct at91_pmc *pmc = osc->pmc; + u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); + + if (tmp & AT91_PMC_OSCBYPASS) + return 1; + + return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCS) && + (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN)); +} + +static const struct clk_ops main_osc_ops = { + .prepare = clk_main_osc_prepare, + .unprepare = clk_main_osc_unprepare, + .is_prepared = clk_main_osc_is_prepared, +}; + +static struct clk * __init +at91_clk_register_main_osc(struct at91_pmc *pmc, + unsigned int irq, + const char *name, + const char *parent_name, + bool bypass) +{ + int ret; + struct clk_main_osc *osc; + struct clk *clk = NULL; + struct clk_init_data init; + + if (!pmc || !irq || !name || !parent_name) + return ERR_PTR(-EINVAL); + + osc = kzalloc(sizeof(*osc), GFP_KERNEL); + if (!osc) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &main_osc_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + init.flags = CLK_IGNORE_UNUSED; + + osc->hw.init = &init; + osc->pmc = pmc; + osc->irq = irq; + + init_waitqueue_head(&osc->wait); + irq_set_status_flags(osc->irq, IRQ_NOAUTOEN); + ret = request_irq(osc->irq, clk_main_osc_irq_handler, + IRQF_TRIGGER_HIGH, name, osc); + if (ret) + return ERR_PTR(ret); + + if (bypass) + pmc_write(pmc, AT91_CKGR_MOR, + (pmc_read(pmc, AT91_CKGR_MOR) & + ~(MOR_KEY_MASK | AT91_PMC_MOSCEN)) | + AT91_PMC_OSCBYPASS | AT91_PMC_KEY); + + clk = clk_register(NULL, &osc->hw); + if (IS_ERR(clk)) { + free_irq(irq, osc); + kfree(osc); + } + + return clk; +} + +void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np, + struct at91_pmc *pmc) +{ + struct clk *clk; + unsigned int irq; + const char *name = np->name; + const char *parent_name; + bool bypass; + + of_property_read_string(np, "clock-output-names", &name); + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + parent_name = of_clk_get_parent_name(np, 0); + + irq = irq_of_parse_and_map(np, 0); + if (!irq) + return; + + clk = at91_clk_register_main_osc(pmc, irq, name, parent_name, bypass); + if (IS_ERR(clk)) + return; + + of_clk_add_provider(np, of_clk_src_simple_get, clk); +} + +static irqreturn_t clk_main_rc_osc_irq_handler(int irq, void *dev_id) +{ + struct clk_main_rc_osc *osc = dev_id; + + wake_up(&osc->wait); + disable_irq_nosync(osc->irq); + + return IRQ_HANDLED; +} + +static int clk_main_rc_osc_prepare(struct clk_hw *hw) +{ + struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); + struct at91_pmc *pmc = osc->pmc; + u32 tmp; + + tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; + + if (!(tmp & AT91_PMC_MOSCRCEN)) { + tmp |= AT91_PMC_MOSCRCEN | AT91_PMC_KEY; + pmc_write(pmc, AT91_CKGR_MOR, tmp); + } + + while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS)) { + enable_irq(osc->irq); + wait_event(osc->wait, + pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS); + } + + return 0; +} + +static void clk_main_rc_osc_unprepare(struct clk_hw *hw) +{ + struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); + struct at91_pmc *pmc = osc->pmc; + u32 tmp = pmc_read(pmc, AT91_CKGR_MOR); + + if (!(tmp & AT91_PMC_MOSCRCEN)) + return; + + tmp &= ~(MOR_KEY_MASK | AT91_PMC_MOSCRCEN); + pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_KEY); +} + +static int clk_main_rc_osc_is_prepared(struct clk_hw *hw) +{ + struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); + struct at91_pmc *pmc = osc->pmc; + + return !!((pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCRCS) && + (pmc_read(pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCRCEN)); +} + +static unsigned long clk_main_rc_osc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); + + return osc->frequency; +} + +static unsigned long clk_main_rc_osc_recalc_accuracy(struct clk_hw *hw, + unsigned long parent_acc) +{ + struct clk_main_rc_osc *osc = to_clk_main_rc_osc(hw); + + return osc->accuracy; +} + +static const struct clk_ops main_rc_osc_ops = { + .prepare = clk_main_rc_osc_prepare, + .unprepare = clk_main_rc_osc_unprepare, + .is_prepared = clk_main_rc_osc_is_prepared, + .recalc_rate = clk_main_rc_osc_recalc_rate, + .recalc_accuracy = clk_main_rc_osc_recalc_accuracy, +}; + +static struct clk * __init +at91_clk_register_main_rc_osc(struct at91_pmc *pmc, + unsigned int irq, + const char *name, + u32 frequency, u32 accuracy) +{ + int ret; + struct clk_main_rc_osc *osc; + struct clk *clk = NULL; + struct clk_init_data init; + + if (!pmc || !irq || !name || !frequency) + return ERR_PTR(-EINVAL); + + osc = kzalloc(sizeof(*osc), GFP_KERNEL); + if (!osc) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &main_rc_osc_ops; + init.parent_names = NULL; + init.num_parents = 0; + init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; + + osc->hw.init = &init; + osc->pmc = pmc; + osc->irq = irq; + osc->frequency = frequency; + osc->accuracy = accuracy; + + init_waitqueue_head(&osc->wait); + irq_set_status_flags(osc->irq, IRQ_NOAUTOEN); + ret = request_irq(osc->irq, clk_main_rc_osc_irq_handler, + IRQF_TRIGGER_HIGH, name, osc); + if (ret) + return ERR_PTR(ret); + + clk = clk_register(NULL, &osc->hw); + if (IS_ERR(clk)) { + free_irq(irq, osc); + kfree(osc); + } + + return clk; +} + +void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np, + struct at91_pmc *pmc) +{ + struct clk *clk; + unsigned int irq; + u32 frequency = 0; + u32 accuracy = 0; + const char *name = np->name; + + of_property_read_string(np, "clock-output-names", &name); + of_property_read_u32(np, "clock-frequency", &frequency); + of_property_read_u32(np, "clock-accuracy", &accuracy); + + irq = irq_of_parse_and_map(np, 0); + if (!irq) + return; + + clk = at91_clk_register_main_rc_osc(pmc, irq, name, frequency, + accuracy); + if (IS_ERR(clk)) + return; + + of_clk_add_provider(np, of_clk_src_simple_get, clk); +} + + +static int clk_main_probe_frequency(struct at91_pmc *pmc) +{ + unsigned long prep_time, timeout; + u32 tmp; timeout = jiffies + usecs_to_jiffies(MAINFRDY_TIMEOUT); do { - halt_time = jiffies; + prep_time = jiffies; tmp = pmc_read(pmc, AT91_CKGR_MCFR); if (tmp & AT91_PMC_MAINRDY) return 0; usleep_range(MAINF_LOOP_MIN_WAIT, MAINF_LOOP_MAX_WAIT); - } while (time_before(halt_time, timeout)); + } while (time_before(prep_time, timeout)); - return 0; + return -ETIMEDOUT; } -static int clk_main_is_prepared(struct clk_hw *hw) +static unsigned long clk_main_recalc_rate(struct at91_pmc *pmc, + unsigned long parent_rate) { - struct clk_main *clkmain = to_clk_main(hw); + u32 tmp; + + if (parent_rate) + return parent_rate; + + tmp = pmc_read(pmc, AT91_CKGR_MCFR); + if (!(tmp & AT91_PMC_MAINRDY)) + return 0; - return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCS); + return ((tmp & AT91_PMC_MAINF) * SLOW_CLOCK_FREQ) / MAINF_DIV; } -static unsigned long clk_main_recalc_rate(struct clk_hw *hw, - unsigned long parent_rate) +static int clk_rm9200_main_prepare(struct clk_hw *hw) { - u32 tmp; - struct clk_main *clkmain = to_clk_main(hw); + struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); + + return clk_main_probe_frequency(clkmain->pmc); +} + +static int clk_rm9200_main_is_prepared(struct clk_hw *hw) +{ + struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); + + return !!(pmc_read(clkmain->pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINRDY); +} + +static unsigned long clk_rm9200_main_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_rm9200_main *clkmain = to_clk_rm9200_main(hw); + + return clk_main_recalc_rate(clkmain->pmc, parent_rate); +} + +static const struct clk_ops rm9200_main_ops = { + .prepare = clk_rm9200_main_prepare, + .is_prepared = clk_rm9200_main_is_prepared, + .recalc_rate = clk_rm9200_main_recalc_rate, +}; + +static struct clk * __init +at91_clk_register_rm9200_main(struct at91_pmc *pmc, + const char *name, + const char *parent_name) +{ + struct clk_rm9200_main *clkmain; + struct clk *clk = NULL; + struct clk_init_data init; + + if (!pmc || !name) + return ERR_PTR(-EINVAL); + + if (!parent_name) + return ERR_PTR(-EINVAL); + + clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL); + if (!clkmain) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &rm9200_main_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + init.flags = 0; + + clkmain->hw.init = &init; + clkmain->pmc = pmc; + + clk = clk_register(NULL, &clkmain->hw); + if (IS_ERR(clk)) + kfree(clkmain); + + return clk; +} + +void __init of_at91rm9200_clk_main_setup(struct device_node *np, + struct at91_pmc *pmc) +{ + struct clk *clk; + const char *parent_name; + const char *name = np->name; + + parent_name = of_clk_get_parent_name(np, 0); + of_property_read_string(np, "clock-output-names", &name); + + clk = at91_clk_register_rm9200_main(pmc, name, parent_name); + if (IS_ERR(clk)) + return; + + of_clk_add_provider(np, of_clk_src_simple_get, clk); +} + +static irqreturn_t clk_sam9x5_main_irq_handler(int irq, void *dev_id) +{ + struct clk_sam9x5_main *clkmain = dev_id; + + wake_up(&clkmain->wait); + disable_irq_nosync(clkmain->irq); + + return IRQ_HANDLED; +} + +static int clk_sam9x5_main_prepare(struct clk_hw *hw) +{ + struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); struct at91_pmc *pmc = clkmain->pmc; - if (clkmain->rate) - return clkmain->rate; + while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) { + enable_irq(clkmain->irq); + wait_event(clkmain->wait, + pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); + } + + return clk_main_probe_frequency(pmc); +} - tmp = pmc_read(pmc, AT91_CKGR_MCFR) & AT91_PMC_MAINF; - clkmain->rate = (tmp * parent_rate) / MAINF_DIV; +static int clk_sam9x5_main_is_prepared(struct clk_hw *hw) +{ + struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); - return clkmain->rate; + return !!(pmc_read(clkmain->pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); } -static const struct clk_ops main_ops = { - .prepare = clk_main_prepare, - .is_prepared = clk_main_is_prepared, - .recalc_rate = clk_main_recalc_rate, +static unsigned long clk_sam9x5_main_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); + + return clk_main_recalc_rate(clkmain->pmc, parent_rate); +} + +static int clk_sam9x5_main_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); + struct at91_pmc *pmc = clkmain->pmc; + u32 tmp; + + if (index > 1) + return -EINVAL; + + tmp = pmc_read(pmc, AT91_CKGR_MOR) & ~MOR_KEY_MASK; + + if (index && !(tmp & AT91_PMC_MOSCSEL)) + pmc_write(pmc, AT91_CKGR_MOR, tmp | AT91_PMC_MOSCSEL); + else if (!index && (tmp & AT91_PMC_MOSCSEL)) + pmc_write(pmc, AT91_CKGR_MOR, tmp & ~AT91_PMC_MOSCSEL); + + while (!(pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS)) { + enable_irq(clkmain->irq); + wait_event(clkmain->wait, + pmc_read(pmc, AT91_PMC_SR) & AT91_PMC_MOSCSELS); + } + + return 0; +} + +static u8 clk_sam9x5_main_get_parent(struct clk_hw *hw) +{ + struct clk_sam9x5_main *clkmain = to_clk_sam9x5_main(hw); + + return !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & AT91_PMC_MOSCEN); +} + +static const struct clk_ops sam9x5_main_ops = { + .prepare = clk_sam9x5_main_prepare, + .is_prepared = clk_sam9x5_main_is_prepared, + .recalc_rate = clk_sam9x5_main_recalc_rate, + .set_parent = clk_sam9x5_main_set_parent, + .get_parent = clk_sam9x5_main_get_parent, }; static struct clk * __init -at91_clk_register_main(struct at91_pmc *pmc, - unsigned int irq, - const char *name, - const char *parent_name, - unsigned long rate) +at91_clk_register_sam9x5_main(struct at91_pmc *pmc, + unsigned int irq, + const char *name, + const char **parent_names, + int num_parents) { int ret; - struct clk_main *clkmain; + struct clk_sam9x5_main *clkmain; struct clk *clk = NULL; struct clk_init_data init; if (!pmc || !irq || !name) return ERR_PTR(-EINVAL); - if (!rate && !parent_name) + if (!parent_names || !num_parents) return ERR_PTR(-EINVAL); clkmain = kzalloc(sizeof(*clkmain), GFP_KERNEL); @@ -130,19 +577,20 @@ at91_clk_register_main(struct at91_pmc *pmc, return ERR_PTR(-ENOMEM); init.name = name; - init.ops = &main_ops; - init.parent_names = parent_name ? &parent_name : NULL; - init.num_parents = parent_name ? 1 : 0; - init.flags = parent_name ? 0 : CLK_IS_ROOT; + init.ops = &sam9x5_main_ops; + init.parent_names = parent_names; + init.num_parents = num_parents; + init.flags = CLK_SET_PARENT_GATE; clkmain->hw.init = &init; - clkmain->rate = rate; clkmain->pmc = pmc; clkmain->irq = irq; + clkmain->parent = !!(pmc_read(clkmain->pmc, AT91_CKGR_MOR) & + AT91_PMC_MOSCEN); init_waitqueue_head(&clkmain->wait); irq_set_status_flags(clkmain->irq, IRQ_NOAUTOEN); - ret = request_irq(clkmain->irq, clk_main_irq_handler, - IRQF_TRIGGER_HIGH, "clk-main", clkmain); + ret = request_irq(clkmain->irq, clk_sam9x5_main_irq_handler, + IRQF_TRIGGER_HIGH, name, clkmain); if (ret) return ERR_PTR(ret); @@ -155,33 +603,36 @@ at91_clk_register_main(struct at91_pmc *pmc, return clk; } - - -static void __init -of_at91_clk_main_setup(struct device_node *np, struct at91_pmc *pmc) +void __init of_at91sam9x5_clk_main_setup(struct device_node *np, + struct at91_pmc *pmc) { struct clk *clk; + const char *parent_names[2]; + int num_parents; unsigned int irq; - const char *parent_name; const char *name = np->name; - u32 rate = 0; + int i; + + num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + if (num_parents <= 0 || num_parents > 2) + return; + + for (i = 0; i < num_parents; ++i) { + parent_names[i] = of_clk_get_parent_name(np, i); + if (!parent_names[i]) + return; + } - parent_name = of_clk_get_parent_name(np, 0); of_property_read_string(np, "clock-output-names", &name); - of_property_read_u32(np, "clock-frequency", &rate); + irq = irq_of_parse_and_map(np, 0); if (!irq) return; - clk = at91_clk_register_main(pmc, irq, name, parent_name, rate); + clk = at91_clk_register_sam9x5_main(pmc, irq, name, parent_names, + num_parents); if (IS_ERR(clk)) return; of_clk_add_provider(np, of_clk_src_simple_get, clk); } - -void __init of_at91rm9200_clk_main_setup(struct device_node *np, - struct at91_pmc *pmc) -{ - of_at91_clk_main_setup(np, pmc); -} diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index 6a61477a57e0..dc5fdde98e1a 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -230,10 +230,22 @@ out_free_pmc: static const struct of_device_id pmc_clk_ids[] __initconst = { /* Main clock */ + { + .compatible = "atmel,at91rm9200-clk-main-osc", + .data = of_at91rm9200_clk_main_osc_setup, + }, + { + .compatible = "atmel,at91sam9x5-clk-main-rc-osc", + .data = of_at91sam9x5_clk_main_rc_osc_setup, + }, { .compatible = "atmel,at91rm9200-clk-main", .data = of_at91rm9200_clk_main_setup, }, + { + .compatible = "atmel,at91sam9x5-clk-main", + .data = of_at91sam9x5_clk_main_setup, + }, /* PLL clocks */ { .compatible = "atmel,at91rm9200-clk-pll", diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 441350983ccb..42cc7cc5e1d3 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -58,8 +58,14 @@ static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value) int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range); +extern void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np, + struct at91_pmc *pmc); +extern void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np, + struct at91_pmc *pmc); extern void __init of_at91rm9200_clk_main_setup(struct device_node *np, struct at91_pmc *pmc); +extern void __init of_at91sam9x5_clk_main_setup(struct device_node *np, + struct at91_pmc *pmc); extern void __init of_at91rm9200_clk_pll_setup(struct device_node *np, struct at91_pmc *pmc); -- cgit v1.2.2 From 80eded6ce8bb8bade60955660c6957d6166c44c1 Mon Sep 17 00:00:00 2001 From: Boris BREZILLON Date: Wed, 7 May 2014 18:02:15 +0200 Subject: clk: at91: add slow clks driver AT91 slow clk is a clk multiplexer. In some SoCs (sam9x5, sama5, sam9g45 families) this multiplexer can choose among 2 sources: an internal RC oscillator circuit and an oscillator using an external crystal. In other Socs (sam9260 family) the multiplexer source is hardcoded with the OSCSEL signal. Signed-off-by: Boris BREZILLON Acked-by: Mike Turquette Signed-off-by: Nicolas Ferre --- drivers/clk/at91/Makefile | 4 +- drivers/clk/at91/clk-slow.c | 467 ++++++++++++++++++++++++++++++++++++++++++++ drivers/clk/at91/pmc.c | 5 + drivers/clk/at91/pmc.h | 3 + drivers/clk/at91/sckc.c | 57 ++++++ drivers/clk/at91/sckc.h | 22 +++ 6 files changed, 556 insertions(+), 2 deletions(-) create mode 100644 drivers/clk/at91/clk-slow.c create mode 100644 drivers/clk/at91/sckc.c create mode 100644 drivers/clk/at91/sckc.h (limited to 'drivers') diff --git a/drivers/clk/at91/Makefile b/drivers/clk/at91/Makefile index 46c1d3d0d66b..4998aee59267 100644 --- a/drivers/clk/at91/Makefile +++ b/drivers/clk/at91/Makefile @@ -2,8 +2,8 @@ # Makefile for at91 specific clk # -obj-y += pmc.o -obj-y += clk-main.o clk-pll.o clk-plldiv.o clk-master.o +obj-y += pmc.o sckc.o +obj-y += clk-slow.o clk-main.o clk-pll.o clk-plldiv.o clk-master.o obj-y += clk-system.o clk-peripheral.o clk-programmable.o obj-$(CONFIG_HAVE_AT91_UTMI) += clk-utmi.o diff --git a/drivers/clk/at91/clk-slow.c b/drivers/clk/at91/clk-slow.c new file mode 100644 index 000000000000..0300c46ee247 --- /dev/null +++ b/drivers/clk/at91/clk-slow.c @@ -0,0 +1,467 @@ +/* + * drivers/clk/at91/clk-slow.c + * + * Copyright (C) 2013 Boris BREZILLON + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "pmc.h" +#include "sckc.h" + +#define SLOW_CLOCK_FREQ 32768 +#define SLOWCK_SW_CYCLES 5 +#define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \ + SLOW_CLOCK_FREQ) + +#define AT91_SCKC_CR 0x00 +#define AT91_SCKC_RCEN (1 << 0) +#define AT91_SCKC_OSC32EN (1 << 1) +#define AT91_SCKC_OSC32BYP (1 << 2) +#define AT91_SCKC_OSCSEL (1 << 3) + +struct clk_slow_osc { + struct clk_hw hw; + void __iomem *sckcr; + unsigned long startup_usec; +}; + +#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw) + +struct clk_slow_rc_osc { + struct clk_hw hw; + void __iomem *sckcr; + unsigned long frequency; + unsigned long accuracy; + unsigned long startup_usec; +}; + +#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw) + +struct clk_sam9260_slow { + struct clk_hw hw; + struct at91_pmc *pmc; +}; + +#define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw) + +struct clk_sam9x5_slow { + struct clk_hw hw; + void __iomem *sckcr; + u8 parent; +}; + +#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw) + + +static int clk_slow_osc_prepare(struct clk_hw *hw) +{ + struct clk_slow_osc *osc = to_clk_slow_osc(hw); + void __iomem *sckcr = osc->sckcr; + u32 tmp = readl(sckcr); + + if (tmp & AT91_SCKC_OSC32BYP) + return 0; + + writel(tmp | AT91_SCKC_OSC32EN, sckcr); + + usleep_range(osc->startup_usec, osc->startup_usec + 1); + + return 0; +} + +static void clk_slow_osc_unprepare(struct clk_hw *hw) +{ + struct clk_slow_osc *osc = to_clk_slow_osc(hw); + void __iomem *sckcr = osc->sckcr; + u32 tmp = readl(sckcr); + + if (tmp & AT91_SCKC_OSC32BYP) + return; + + writel(tmp & ~AT91_SCKC_OSC32EN, sckcr); +} + +static int clk_slow_osc_is_prepared(struct clk_hw *hw) +{ + struct clk_slow_osc *osc = to_clk_slow_osc(hw); + void __iomem *sckcr = osc->sckcr; + u32 tmp = readl(sckcr); + + if (tmp & AT91_SCKC_OSC32BYP) + return 1; + + return !!(tmp & AT91_SCKC_OSC32EN); +} + +static const struct clk_ops slow_osc_ops = { + .prepare = clk_slow_osc_prepare, + .unprepare = clk_slow_osc_unprepare, + .is_prepared = clk_slow_osc_is_prepared, +}; + +static struct clk * __init +at91_clk_register_slow_osc(void __iomem *sckcr, + const char *name, + const char *parent_name, + unsigned long startup, + bool bypass) +{ + struct clk_slow_osc *osc; + struct clk *clk = NULL; + struct clk_init_data init; + + if (!sckcr || !name || !parent_name) + return ERR_PTR(-EINVAL); + + osc = kzalloc(sizeof(*osc), GFP_KERNEL); + if (!osc) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &slow_osc_ops; + init.parent_names = &parent_name; + init.num_parents = 1; + init.flags = CLK_IGNORE_UNUSED; + + osc->hw.init = &init; + osc->sckcr = sckcr; + osc->startup_usec = startup; + + if (bypass) + writel((readl(sckcr) & ~AT91_SCKC_OSC32EN) | AT91_SCKC_OSC32BYP, + sckcr); + + clk = clk_register(NULL, &osc->hw); + if (IS_ERR(clk)) + kfree(osc); + + return clk; +} + +void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, + void __iomem *sckcr) +{ + struct clk *clk; + const char *parent_name; + const char *name = np->name; + u32 startup; + bool bypass; + + parent_name = of_clk_get_parent_name(np, 0); + of_property_read_string(np, "clock-output-names", &name); + of_property_read_u32(np, "atmel,startup-time-usec", &startup); + bypass = of_property_read_bool(np, "atmel,osc-bypass"); + + clk = at91_clk_register_slow_osc(sckcr, name, parent_name, startup, + bypass); + if (IS_ERR(clk)) + return; + + of_clk_add_provider(np, of_clk_src_simple_get, clk); +} + +static unsigned long clk_slow_rc_osc_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); + + return osc->frequency; +} + +static unsigned long clk_slow_rc_osc_recalc_accuracy(struct clk_hw *hw, + unsigned long parent_acc) +{ + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); + + return osc->accuracy; +} + +static int clk_slow_rc_osc_prepare(struct clk_hw *hw) +{ + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); + void __iomem *sckcr = osc->sckcr; + + writel(readl(sckcr) | AT91_SCKC_RCEN, sckcr); + + usleep_range(osc->startup_usec, osc->startup_usec + 1); + + return 0; +} + +static void clk_slow_rc_osc_unprepare(struct clk_hw *hw) +{ + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); + void __iomem *sckcr = osc->sckcr; + + writel(readl(sckcr) & ~AT91_SCKC_RCEN, sckcr); +} + +static int clk_slow_rc_osc_is_prepared(struct clk_hw *hw) +{ + struct clk_slow_rc_osc *osc = to_clk_slow_rc_osc(hw); + + return !!(readl(osc->sckcr) & AT91_SCKC_RCEN); +} + +static const struct clk_ops slow_rc_osc_ops = { + .prepare = clk_slow_rc_osc_prepare, + .unprepare = clk_slow_rc_osc_unprepare, + .is_prepared = clk_slow_rc_osc_is_prepared, + .recalc_rate = clk_slow_rc_osc_recalc_rate, + .recalc_accuracy = clk_slow_rc_osc_recalc_accuracy, +}; + +static struct clk * __init +at91_clk_register_slow_rc_osc(void __iomem *sckcr, + const char *name, + unsigned long frequency, + unsigned long accuracy, + unsigned long startup) +{ + struct clk_slow_rc_osc *osc; + struct clk *clk = NULL; + struct clk_init_data init; + + if (!sckcr || !name) + return ERR_PTR(-EINVAL); + + osc = kzalloc(sizeof(*osc), GFP_KERNEL); + if (!osc) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &slow_rc_osc_ops; + init.parent_names = NULL; + init.num_parents = 0; + init.flags = CLK_IS_ROOT | CLK_IGNORE_UNUSED; + + osc->hw.init = &init; + osc->sckcr = sckcr; + osc->frequency = frequency; + osc->accuracy = accuracy; + osc->startup_usec = startup; + + clk = clk_register(NULL, &osc->hw); + if (IS_ERR(clk)) + kfree(osc); + + return clk; +} + +void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, + void __iomem *sckcr) +{ + struct clk *clk; + u32 frequency = 0; + u32 accuracy = 0; + u32 startup = 0; + const char *name = np->name; + + of_property_read_string(np, "clock-output-names", &name); + of_property_read_u32(np, "clock-frequency", &frequency); + of_property_read_u32(np, "clock-accuracy", &accuracy); + of_property_read_u32(np, "atmel,startup-time-usec", &startup); + + clk = at91_clk_register_slow_rc_osc(sckcr, name, frequency, accuracy, + startup); + if (IS_ERR(clk)) + return; + + of_clk_add_provider(np, of_clk_src_simple_get, clk); +} + +static int clk_sam9x5_slow_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); + void __iomem *sckcr = slowck->sckcr; + u32 tmp; + + if (index > 1) + return -EINVAL; + + tmp = readl(sckcr); + + if ((!index && !(tmp & AT91_SCKC_OSCSEL)) || + (index && (tmp & AT91_SCKC_OSCSEL))) + return 0; + + if (index) + tmp |= AT91_SCKC_OSCSEL; + else + tmp &= ~AT91_SCKC_OSCSEL; + + writel(tmp, sckcr); + + usleep_range(SLOWCK_SW_TIME_USEC, SLOWCK_SW_TIME_USEC + 1); + + return 0; +} + +static u8 clk_sam9x5_slow_get_parent(struct clk_hw *hw) +{ + struct clk_sam9x5_slow *slowck = to_clk_sam9x5_slow(hw); + + return !!(readl(slowck->sckcr) & AT91_SCKC_OSCSEL); +} + +static const struct clk_ops sam9x5_slow_ops = { + .set_parent = clk_sam9x5_slow_set_parent, + .get_parent = clk_sam9x5_slow_get_parent, +}; + +static struct clk * __init +at91_clk_register_sam9x5_slow(void __iomem *sckcr, + const char *name, + const char **parent_names, + int num_parents) +{ + struct clk_sam9x5_slow *slowck; + struct clk *clk = NULL; + struct clk_init_data init; + + if (!sckcr || !name || !parent_names || !num_parents) + return ERR_PTR(-EINVAL); + + slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); + if (!slowck) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &sam9x5_slow_ops; + init.parent_names = parent_names; + init.num_parents = num_parents; + init.flags = 0; + + slowck->hw.init = &init; + slowck->sckcr = sckcr; + slowck->parent = !!(readl(sckcr) & AT91_SCKC_OSCSEL); + + clk = clk_register(NULL, &slowck->hw); + if (IS_ERR(clk)) + kfree(slowck); + + return clk; +} + +void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, + void __iomem *sckcr) +{ + struct clk *clk; + const char *parent_names[2]; + int num_parents; + const char *name = np->name; + int i; + + num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + if (num_parents <= 0 || num_parents > 2) + return; + + for (i = 0; i < num_parents; ++i) { + parent_names[i] = of_clk_get_parent_name(np, i); + if (!parent_names[i]) + return; + } + + of_property_read_string(np, "clock-output-names", &name); + + clk = at91_clk_register_sam9x5_slow(sckcr, name, parent_names, + num_parents); + if (IS_ERR(clk)) + return; + + of_clk_add_provider(np, of_clk_src_simple_get, clk); +} + +static u8 clk_sam9260_slow_get_parent(struct clk_hw *hw) +{ + struct clk_sam9260_slow *slowck = to_clk_sam9260_slow(hw); + + return !!(pmc_read(slowck->pmc, AT91_PMC_SR) & AT91_PMC_OSCSEL); +} + +static const struct clk_ops sam9260_slow_ops = { + .get_parent = clk_sam9260_slow_get_parent, +}; + +static struct clk * __init +at91_clk_register_sam9260_slow(struct at91_pmc *pmc, + const char *name, + const char **parent_names, + int num_parents) +{ + struct clk_sam9260_slow *slowck; + struct clk *clk = NULL; + struct clk_init_data init; + + if (!pmc || !name) + return ERR_PTR(-EINVAL); + + if (!parent_names || !num_parents) + return ERR_PTR(-EINVAL); + + slowck = kzalloc(sizeof(*slowck), GFP_KERNEL); + if (!slowck) + return ERR_PTR(-ENOMEM); + + init.name = name; + init.ops = &sam9260_slow_ops; + init.parent_names = parent_names; + init.num_parents = num_parents; + init.flags = 0; + + slowck->hw.init = &init; + slowck->pmc = pmc; + + clk = clk_register(NULL, &slowck->hw); + if (IS_ERR(clk)) + kfree(slowck); + + return clk; +} + +void __init of_at91sam9260_clk_slow_setup(struct device_node *np, + struct at91_pmc *pmc) +{ + struct clk *clk; + const char *parent_names[2]; + int num_parents; + const char *name = np->name; + int i; + + num_parents = of_count_phandle_with_args(np, "clocks", "#clock-cells"); + if (num_parents <= 0 || num_parents > 1) + return; + + for (i = 0; i < num_parents; ++i) { + parent_names[i] = of_clk_get_parent_name(np, i); + if (!parent_names[i]) + return; + } + + of_property_read_string(np, "clock-output-names", &name); + + clk = at91_clk_register_sam9260_slow(pmc, name, parent_names, + num_parents); + if (IS_ERR(clk)) + return; + + of_clk_add_provider(np, of_clk_src_simple_get, clk); +} diff --git a/drivers/clk/at91/pmc.c b/drivers/clk/at91/pmc.c index dc5fdde98e1a..524196bb35a5 100644 --- a/drivers/clk/at91/pmc.c +++ b/drivers/clk/at91/pmc.c @@ -229,6 +229,11 @@ out_free_pmc: } static const struct of_device_id pmc_clk_ids[] __initconst = { + /* Slow oscillator */ + { + .compatible = "atmel,at91sam9260-clk-slow", + .data = of_at91sam9260_clk_slow_setup, + }, /* Main clock */ { .compatible = "atmel,at91rm9200-clk-main-osc", diff --git a/drivers/clk/at91/pmc.h b/drivers/clk/at91/pmc.h index 42cc7cc5e1d3..6c7625976113 100644 --- a/drivers/clk/at91/pmc.h +++ b/drivers/clk/at91/pmc.h @@ -58,6 +58,9 @@ static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value) int of_at91_get_clk_range(struct device_node *np, const char *propname, struct clk_range *range); +extern void __init of_at91sam9260_clk_slow_setup(struct device_node *np, + struct at91_pmc *pmc); + extern void __init of_at91rm9200_clk_main_osc_setup(struct device_node *np, struct at91_pmc *pmc); extern void __init of_at91sam9x5_clk_main_rc_osc_setup(struct device_node *np, diff --git a/drivers/clk/at91/sckc.c b/drivers/clk/at91/sckc.c new file mode 100644 index 000000000000..1184d76a7ab7 --- /dev/null +++ b/drivers/clk/at91/sckc.c @@ -0,0 +1,57 @@ +/* + * drivers/clk/at91/sckc.c + * + * Copyright (C) 2013 Boris BREZILLON + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + */ + +#include +#include +#include +#include +#include + +#include "sckc.h" + +static const struct of_device_id sckc_clk_ids[] __initconst = { + /* Slow clock */ + { + .compatible = "atmel,at91sam9x5-clk-slow-osc", + .data = of_at91sam9x5_clk_slow_osc_setup, + }, + { + .compatible = "atmel,at91sam9x5-clk-slow-rc-osc", + .data = of_at91sam9x5_clk_slow_rc_osc_setup, + }, + { + .compatible = "atmel,at91sam9x5-clk-slow", + .data = of_at91sam9x5_clk_slow_setup, + }, + { /*sentinel*/ } +}; + +static void __init of_at91sam9x5_sckc_setup(struct device_node *np) +{ + struct device_node *childnp; + void (*clk_setup)(struct device_node *, void __iomem *); + const struct of_device_id *clk_id; + void __iomem *regbase = of_iomap(np, 0); + + if (!regbase) + return; + + for_each_child_of_node(np, childnp) { + clk_id = of_match_node(sckc_clk_ids, childnp); + if (!clk_id) + continue; + clk_setup = clk_id->data; + clk_setup(childnp, regbase); + } +} +CLK_OF_DECLARE(at91sam9x5_clk_sckc, "atmel,at91sam9x5-sckc", + of_at91sam9x5_sckc_setup); diff --git a/drivers/clk/at91/sckc.h b/drivers/clk/at91/sckc.h new file mode 100644 index 000000000000..836fcf59820f --- /dev/null +++ b/drivers/clk/at91/sckc.h @@ -0,0 +1,22 @@ +/* + * drivers/clk/at91/sckc.h + * + * Copyright (C) 2013 Boris BREZILLON + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + */ + +#ifndef __AT91_SCKC_H_ +#define __AT91_SCKC_H_ + +extern void __init of_at91sam9x5_clk_slow_osc_setup(struct device_node *np, + void __iomem *sckcr); +extern void __init of_at91sam9x5_clk_slow_rc_osc_setup(struct device_node *np, + void __iomem *sckcr); +extern void __init of_at91sam9x5_clk_slow_setup(struct device_node *np, + void __iomem *sckcr); + +#endif /* __AT91_SCKC_H_ */ -- cgit v1.2.2 From 2de0c019f34ffbe49744c453628afb270aa9adb6 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 15 Apr 2014 12:27:58 +0200 Subject: iio: adc: at91: cleanup platform_data num_channels and registers are not used anymore since they are defined inside the driver and assigned by matching the id_table. Also, struct at91_adc_reg_desc is now only used inside the driver. Signed-off-by: Alexandre Belloni Acked-by: Jonathan Cameron Signed-off-by: Nicolas Ferre --- drivers/iio/adc/at91_adc.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 89777ed9abd8..1beae65aef2c 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -46,6 +46,25 @@ #define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */ #define TOUCH_PEN_DETECT_DEBOUNCE_US 200 +/** + * struct at91_adc_reg_desc - Various informations relative to registers + * @channel_base: Base offset for the channel data registers + * @drdy_mask: Mask of the DRDY field in the relevant registers + (Interruptions registers mostly) + * @status_register: Offset of the Interrupt Status Register + * @trigger_register: Offset of the Trigger setup register + * @mr_prescal_mask: Mask of the PRESCAL field in the adc MR register + * @mr_startup_mask: Mask of the STARTUP field in the adc MR register + */ +struct at91_adc_reg_desc { + u8 channel_base; + u32 drdy_mask; + u8 status_register; + u8 trigger_register; + u32 mr_prescal_mask; + u32 mr_startup_mask; +}; + struct at91_adc_caps { bool has_ts; /* Support touch screen */ bool has_tsmr; /* only at91sam9x5, sama5d3 have TSMR reg */ -- cgit v1.2.2 From 84882b060301c35ab7e2c1ef355b0bd06b764195 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 15 Apr 2014 12:27:59 +0200 Subject: iio: adc: at91_adc: Add support for touchscreens without TSMR Old ADCs, as present on the sam9rl and the sam9g45 don't have a TSMR register and the touchscreen support should be handled differently. Signed-off-by: Alexandre Belloni Acked-by: Jonathan Cameron Signed-off-by: Nicolas Ferre --- drivers/iio/adc/at91_adc.c | 200 ++++++++++++++++++++++++++++++++++----------- 1 file changed, 153 insertions(+), 47 deletions(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index 1beae65aef2c..c0e4206e34e5 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -46,6 +46,10 @@ #define TOUCH_SAMPLE_PERIOD_US 2000 /* 2ms */ #define TOUCH_PEN_DETECT_DEBOUNCE_US 200 +#define MAX_RLPOS_BITS 10 +#define TOUCH_SAMPLE_PERIOD_US_RL 10000 /* 10ms, the SoC can't keep up with 2ms */ +#define TOUCH_SHTIM 0xa + /** * struct at91_adc_reg_desc - Various informations relative to registers * @channel_base: Base offset for the channel data registers @@ -83,12 +87,6 @@ struct at91_adc_caps { struct at91_adc_reg_desc registers; }; -enum atmel_adc_ts_type { - ATMEL_ADC_TOUCHSCREEN_NONE = 0, - ATMEL_ADC_TOUCHSCREEN_4WIRE = 4, - ATMEL_ADC_TOUCHSCREEN_5WIRE = 5, -}; - struct at91_adc_state { struct clk *adc_clk; u16 *buffer; @@ -133,6 +131,11 @@ struct at91_adc_state { u16 ts_sample_period_val; u32 ts_pressure_threshold; + u16 ts_pendbc; + + bool ts_bufferedmeasure; + u32 ts_prev_absx; + u32 ts_prev_absy; }; static irqreturn_t at91_adc_trigger_handler(int irq, void *p) @@ -239,7 +242,72 @@ static int at91_ts_sample(struct at91_adc_state *st) return 0; } -static irqreturn_t at91_adc_interrupt(int irq, void *private) +static irqreturn_t at91_adc_rl_interrupt(int irq, void *private) +{ + struct iio_dev *idev = private; + struct at91_adc_state *st = iio_priv(idev); + u32 status = at91_adc_readl(st, st->registers->status_register); + unsigned int reg; + + status &= at91_adc_readl(st, AT91_ADC_IMR); + if (status & st->registers->drdy_mask) + handle_adc_eoc_trigger(irq, idev); + + if (status & AT91RL_ADC_IER_PEN) { + /* Disabling pen debounce is required to get a NOPEN irq */ + reg = at91_adc_readl(st, AT91_ADC_MR); + reg &= ~AT91_ADC_PENDBC; + at91_adc_writel(st, AT91_ADC_MR, reg); + + at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); + at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_NOPEN + | AT91_ADC_EOC(3)); + /* Set up period trigger for sampling */ + at91_adc_writel(st, st->registers->trigger_register, + AT91_ADC_TRGR_MOD_PERIOD_TRIG | + AT91_ADC_TRGR_TRGPER_(st->ts_sample_period_val)); + } else if (status & AT91RL_ADC_IER_NOPEN) { + reg = at91_adc_readl(st, AT91_ADC_MR); + reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; + at91_adc_writel(st, AT91_ADC_MR, reg); + at91_adc_writel(st, st->registers->trigger_register, + AT91_ADC_TRGR_NONE); + + at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_NOPEN + | AT91_ADC_EOC(3)); + at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); + st->ts_bufferedmeasure = false; + input_report_key(st->ts_input, BTN_TOUCH, 0); + input_sync(st->ts_input); + } else if (status & AT91_ADC_EOC(3)) { + /* Conversion finished */ + if (st->ts_bufferedmeasure) { + /* + * Last measurement is always discarded, since it can + * be erroneous. + * Always report previous measurement + */ + input_report_abs(st->ts_input, ABS_X, st->ts_prev_absx); + input_report_abs(st->ts_input, ABS_Y, st->ts_prev_absy); + input_report_key(st->ts_input, BTN_TOUCH, 1); + input_sync(st->ts_input); + } else + st->ts_bufferedmeasure = true; + + /* Now make new measurement */ + st->ts_prev_absx = at91_adc_readl(st, AT91_ADC_CHAN(st, 3)) + << MAX_RLPOS_BITS; + st->ts_prev_absx /= at91_adc_readl(st, AT91_ADC_CHAN(st, 2)); + + st->ts_prev_absy = at91_adc_readl(st, AT91_ADC_CHAN(st, 1)) + << MAX_RLPOS_BITS; + st->ts_prev_absy /= at91_adc_readl(st, AT91_ADC_CHAN(st, 0)); + } + + return IRQ_HANDLED; +} + +static irqreturn_t at91_adc_9x5_interrupt(int irq, void *private) { struct iio_dev *idev = private; struct at91_adc_state *st = iio_priv(idev); @@ -672,6 +740,8 @@ static int at91_adc_probe_dt_ts(struct device_node *node, return -EINVAL; } + if (!st->caps->has_tsmr) + return 0; prop = 0; of_property_read_u32(node, "atmel,adc-ts-pressure-threshold", &prop); st->ts_pressure_threshold = prop; @@ -795,6 +865,7 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st, st->trigger_number = pdata->trigger_number; st->trigger_list = pdata->trigger_list; st->registers = &st->caps->registers; + st->touchscreen_type = pdata->touchscreen_type; return 0; } @@ -809,7 +880,10 @@ static int atmel_ts_open(struct input_dev *dev) { struct at91_adc_state *st = input_get_drvdata(dev); - at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); + if (st->caps->has_tsmr) + at91_adc_writel(st, AT91_ADC_IER, AT91_ADC_IER_PEN); + else + at91_adc_writel(st, AT91_ADC_IER, AT91RL_ADC_IER_PEN); return 0; } @@ -817,45 +891,61 @@ static void atmel_ts_close(struct input_dev *dev) { struct at91_adc_state *st = input_get_drvdata(dev); - at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); + if (st->caps->has_tsmr) + at91_adc_writel(st, AT91_ADC_IDR, AT91_ADC_IER_PEN); + else + at91_adc_writel(st, AT91_ADC_IDR, AT91RL_ADC_IER_PEN); } static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz) { - u32 reg = 0, pendbc; + u32 reg = 0; int i = 0; - if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) - reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS; - else - reg = AT91_ADC_TSMR_TSMODE_5WIRE; - /* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid * pen detect noise. * The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock */ - pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / 1000, 1); + st->ts_pendbc = round_up(TOUCH_PEN_DETECT_DEBOUNCE_US * adc_clk_khz / + 1000, 1); - while (pendbc >> ++i) + while (st->ts_pendbc >> ++i) ; /* Empty! Find the shift offset */ - if (abs(pendbc - (1 << i)) < abs(pendbc - (1 << (i - 1)))) - pendbc = i; + if (abs(st->ts_pendbc - (1 << i)) < abs(st->ts_pendbc - (1 << (i - 1)))) + st->ts_pendbc = i; else - pendbc = i - 1; + st->ts_pendbc = i - 1; - if (st->caps->has_tsmr) { - reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average) - & AT91_ADC_TSMR_TSAV; - reg |= AT91_ADC_TSMR_PENDBC_(pendbc) & AT91_ADC_TSMR_PENDBC; - reg |= AT91_ADC_TSMR_NOTSDMA; - reg |= AT91_ADC_TSMR_PENDET_ENA; - reg |= 0x03 << 8; /* TSFREQ, need bigger than TSAV */ - - at91_adc_writel(st, AT91_ADC_TSMR, reg); - } else { - /* TODO: for 9g45 which has no TSMR */ + if (!st->caps->has_tsmr) { + reg = at91_adc_readl(st, AT91_ADC_MR); + reg |= AT91_ADC_TSAMOD_TS_ONLY_MODE | AT91_ADC_PENDET; + + reg |= AT91_ADC_PENDBC_(st->ts_pendbc) & AT91_ADC_PENDBC; + at91_adc_writel(st, AT91_ADC_MR, reg); + + reg = AT91_ADC_TSR_SHTIM_(TOUCH_SHTIM) & AT91_ADC_TSR_SHTIM; + at91_adc_writel(st, AT91_ADC_TSR, reg); + + st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US_RL * + adc_clk_khz / 1000) - 1, 1); + + return 0; } + if (st->touchscreen_type == ATMEL_ADC_TOUCHSCREEN_4WIRE) + reg = AT91_ADC_TSMR_TSMODE_4WIRE_PRESS; + else + reg = AT91_ADC_TSMR_TSMODE_5WIRE; + + reg |= AT91_ADC_TSMR_TSAV_(st->caps->ts_filter_average) + & AT91_ADC_TSMR_TSAV; + reg |= AT91_ADC_TSMR_PENDBC_(st->ts_pendbc) & AT91_ADC_TSMR_PENDBC; + reg |= AT91_ADC_TSMR_NOTSDMA; + reg |= AT91_ADC_TSMR_PENDET_ENA; + reg |= 0x03 << 8; /* TSFREQ, needs to be bigger than TSAV */ + + at91_adc_writel(st, AT91_ADC_TSMR, reg); + /* Change adc internal resistor value for better pen detection, * default value is 100 kOhm. * 0 = 200 kOhm, 1 = 150 kOhm, 2 = 100 kOhm, 3 = 50 kOhm @@ -864,7 +954,7 @@ static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz) at91_adc_writel(st, AT91_ADC_ACR, st->caps->ts_pen_detect_sensitivity & AT91_ADC_ACR_PENDETSENS); - /* Sample Peroid Time = (TRGPER + 1) / ADCClock */ + /* Sample Period Time = (TRGPER + 1) / ADCClock */ st->ts_sample_period_val = round_up((TOUCH_SAMPLE_PERIOD_US * adc_clk_khz / 1000) - 1, 1); @@ -893,17 +983,37 @@ static int at91_ts_register(struct at91_adc_state *st, __set_bit(EV_ABS, input->evbit); __set_bit(EV_KEY, input->evbit); __set_bit(BTN_TOUCH, input->keybit); - input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, 0, 0); - input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, 0, 0); - input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0); + if (st->caps->has_tsmr) { + input_set_abs_params(input, ABS_X, 0, (1 << MAX_POS_BITS) - 1, + 0, 0); + input_set_abs_params(input, ABS_Y, 0, (1 << MAX_POS_BITS) - 1, + 0, 0); + input_set_abs_params(input, ABS_PRESSURE, 0, 0xffffff, 0, 0); + } else { + if (st->touchscreen_type != ATMEL_ADC_TOUCHSCREEN_4WIRE) { + dev_err(&pdev->dev, + "This touchscreen controller only support 4 wires\n"); + ret = -EINVAL; + goto err; + } + + input_set_abs_params(input, ABS_X, 0, (1 << MAX_RLPOS_BITS) - 1, + 0, 0); + input_set_abs_params(input, ABS_Y, 0, (1 << MAX_RLPOS_BITS) - 1, + 0, 0); + } st->ts_input = input; input_set_drvdata(input, st); ret = input_register_device(input); if (ret) - input_free_device(st->ts_input); + goto err; + + return ret; +err: + input_free_device(st->ts_input); return ret; } @@ -962,11 +1072,13 @@ static int at91_adc_probe(struct platform_device *pdev) */ at91_adc_writel(st, AT91_ADC_CR, AT91_ADC_SWRST); at91_adc_writel(st, AT91_ADC_IDR, 0xFFFFFFFF); - ret = request_irq(st->irq, - at91_adc_interrupt, - 0, - pdev->dev.driver->name, - idev); + + if (st->caps->has_tsmr) + ret = request_irq(st->irq, at91_adc_9x5_interrupt, 0, + pdev->dev.driver->name, idev); + else + ret = request_irq(st->irq, at91_adc_rl_interrupt, 0, + pdev->dev.driver->name, idev); if (ret) { dev_err(&pdev->dev, "Failed to allocate IRQ.\n"); return ret; @@ -1070,12 +1182,6 @@ static int at91_adc_probe(struct platform_device *pdev) goto error_disable_adc_clk; } } else { - if (!st->caps->has_tsmr) { - dev_err(&pdev->dev, "We don't support non-TSMR adc\n"); - ret = -ENODEV; - goto error_disable_adc_clk; - } - ret = at91_ts_register(st, pdev); if (ret) goto error_disable_adc_clk; -- cgit v1.2.2 From bee20c4be1e2c32172f41c24ebaa7762aa9e4825 Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 15 Apr 2014 12:28:01 +0200 Subject: iio: adc: at91: remove unused include from include/mach That include file is now only used by the at91_adc driver, remove it from include/mach for better driver separation. Signed-off-by: Alexandre Belloni Acked-by: Jonathan Cameron Signed-off-by: Nicolas Ferre --- drivers/iio/adc/at91_adc.c | 103 ++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 102 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index c0e4206e34e5..a51b8badbf8e 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -31,7 +31,108 @@ #include #include -#include +/* Registers */ +#define AT91_ADC_CR 0x00 /* Control Register */ +#define AT91_ADC_SWRST (1 << 0) /* Software Reset */ +#define AT91_ADC_START (1 << 1) /* Start Conversion */ + +#define AT91_ADC_MR 0x04 /* Mode Register */ +#define AT91_ADC_TSAMOD (3 << 0) /* ADC mode */ +#define AT91_ADC_TSAMOD_ADC_ONLY_MODE (0 << 0) /* ADC Mode */ +#define AT91_ADC_TSAMOD_TS_ONLY_MODE (1 << 0) /* Touch Screen Only Mode */ +#define AT91_ADC_TRGEN (1 << 0) /* Trigger Enable */ +#define AT91_ADC_TRGSEL (7 << 1) /* Trigger Selection */ +#define AT91_ADC_TRGSEL_TC0 (0 << 1) +#define AT91_ADC_TRGSEL_TC1 (1 << 1) +#define AT91_ADC_TRGSEL_TC2 (2 << 1) +#define AT91_ADC_TRGSEL_EXTERNAL (6 << 1) +#define AT91_ADC_LOWRES (1 << 4) /* Low Resolution */ +#define AT91_ADC_SLEEP (1 << 5) /* Sleep Mode */ +#define AT91_ADC_PENDET (1 << 6) /* Pen contact detection enable */ +#define AT91_ADC_PRESCAL_9260 (0x3f << 8) /* Prescalar Rate Selection */ +#define AT91_ADC_PRESCAL_9G45 (0xff << 8) +#define AT91_ADC_PRESCAL_(x) ((x) << 8) +#define AT91_ADC_STARTUP_9260 (0x1f << 16) /* Startup Up Time */ +#define AT91_ADC_STARTUP_9G45 (0x7f << 16) +#define AT91_ADC_STARTUP_9X5 (0xf << 16) +#define AT91_ADC_STARTUP_(x) ((x) << 16) +#define AT91_ADC_SHTIM (0xf << 24) /* Sample & Hold Time */ +#define AT91_ADC_SHTIM_(x) ((x) << 24) +#define AT91_ADC_PENDBC (0x0f << 28) /* Pen Debounce time */ +#define AT91_ADC_PENDBC_(x) ((x) << 28) + +#define AT91_ADC_TSR 0x0C +#define AT91_ADC_TSR_SHTIM (0xf << 24) /* Sample & Hold Time */ +#define AT91_ADC_TSR_SHTIM_(x) ((x) << 24) + +#define AT91_ADC_CHER 0x10 /* Channel Enable Register */ +#define AT91_ADC_CHDR 0x14 /* Channel Disable Register */ +#define AT91_ADC_CHSR 0x18 /* Channel Status Register */ +#define AT91_ADC_CH(n) (1 << (n)) /* Channel Number */ + +#define AT91_ADC_SR 0x1C /* Status Register */ +#define AT91_ADC_EOC(n) (1 << (n)) /* End of Conversion on Channel N */ +#define AT91_ADC_OVRE(n) (1 << ((n) + 8))/* Overrun Error on Channel N */ +#define AT91_ADC_DRDY (1 << 16) /* Data Ready */ +#define AT91_ADC_GOVRE (1 << 17) /* General Overrun Error */ +#define AT91_ADC_ENDRX (1 << 18) /* End of RX Buffer */ +#define AT91_ADC_RXFUFF (1 << 19) /* RX Buffer Full */ + +#define AT91_ADC_SR_9X5 0x30 /* Status Register for 9x5 */ +#define AT91_ADC_SR_DRDY_9X5 (1 << 24) /* Data Ready */ + +#define AT91_ADC_LCDR 0x20 /* Last Converted Data Register */ +#define AT91_ADC_LDATA (0x3ff) + +#define AT91_ADC_IER 0x24 /* Interrupt Enable Register */ +#define AT91_ADC_IDR 0x28 /* Interrupt Disable Register */ +#define AT91_ADC_IMR 0x2C /* Interrupt Mask Register */ +#define AT91RL_ADC_IER_PEN (1 << 20) +#define AT91RL_ADC_IER_NOPEN (1 << 21) +#define AT91_ADC_IER_PEN (1 << 29) +#define AT91_ADC_IER_NOPEN (1 << 30) +#define AT91_ADC_IER_XRDY (1 << 20) +#define AT91_ADC_IER_YRDY (1 << 21) +#define AT91_ADC_IER_PRDY (1 << 22) +#define AT91_ADC_ISR_PENS (1 << 31) + +#define AT91_ADC_CHR(n) (0x30 + ((n) * 4)) /* Channel Data Register N */ +#define AT91_ADC_DATA (0x3ff) + +#define AT91_ADC_CDR0_9X5 (0x50) /* Channel Data Register 0 for 9X5 */ + +#define AT91_ADC_ACR 0x94 /* Analog Control Register */ +#define AT91_ADC_ACR_PENDETSENS (0x3 << 0) /* pull-up resistor */ + +#define AT91_ADC_TSMR 0xB0 +#define AT91_ADC_TSMR_TSMODE (3 << 0) /* Touch Screen Mode */ +#define AT91_ADC_TSMR_TSMODE_NONE (0 << 0) +#define AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS (1 << 0) +#define AT91_ADC_TSMR_TSMODE_4WIRE_PRESS (2 << 0) +#define AT91_ADC_TSMR_TSMODE_5WIRE (3 << 0) +#define AT91_ADC_TSMR_TSAV (3 << 4) /* Averages samples */ +#define AT91_ADC_TSMR_TSAV_(x) ((x) << 4) +#define AT91_ADC_TSMR_SCTIM (0x0f << 16) /* Switch closure time */ +#define AT91_ADC_TSMR_PENDBC (0x0f << 28) /* Pen Debounce time */ +#define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28) +#define AT91_ADC_TSMR_NOTSDMA (1 << 22) /* No Touchscreen DMA */ +#define AT91_ADC_TSMR_PENDET_DIS (0 << 24) /* Pen contact detection disable */ +#define AT91_ADC_TSMR_PENDET_ENA (1 << 24) /* Pen contact detection enable */ + +#define AT91_ADC_TSXPOSR 0xB4 +#define AT91_ADC_TSYPOSR 0xB8 +#define AT91_ADC_TSPRESSR 0xBC + +#define AT91_ADC_TRGR_9260 AT91_ADC_MR +#define AT91_ADC_TRGR_9G45 0x08 +#define AT91_ADC_TRGR_9X5 0xC0 + +/* Trigger Register bit field */ +#define AT91_ADC_TRGR_TRGPER (0xffff << 16) +#define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16) +#define AT91_ADC_TRGR_TRGMOD (0x7 << 0) +#define AT91_ADC_TRGR_NONE (0 << 0) +#define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0) #define AT91_ADC_CHAN(st, ch) \ (st->registers->channel_base + (ch * 4)) -- cgit v1.2.2 From 65b1fdbac9e39d98a1416633106e89c1be1bef1b Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 15 Apr 2014 12:28:02 +0200 Subject: iio: adc: at91: add sam9rl support Signed-off-by: Alexandre Belloni Acked-by: Jonathan Cameron Signed-off-by: Nicolas Ferre --- drivers/iio/adc/at91_adc.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) (limited to 'drivers') diff --git a/drivers/iio/adc/at91_adc.c b/drivers/iio/adc/at91_adc.c index a51b8badbf8e..3b5bacd4d8da 100644 --- a/drivers/iio/adc/at91_adc.c +++ b/drivers/iio/adc/at91_adc.c @@ -1346,6 +1346,20 @@ static struct at91_adc_caps at91sam9260_caps = { }, }; +static struct at91_adc_caps at91sam9rl_caps = { + .has_ts = true, + .calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */ + .num_channels = 6, + .registers = { + .channel_base = AT91_ADC_CHR(0), + .drdy_mask = AT91_ADC_DRDY, + .status_register = AT91_ADC_SR, + .trigger_register = AT91_ADC_TRGR_9G45, + .mr_prescal_mask = AT91_ADC_PRESCAL_9260, + .mr_startup_mask = AT91_ADC_STARTUP_9G45, + }, +}; + static struct at91_adc_caps at91sam9g45_caps = { .has_ts = true, .calc_startup_ticks = calc_startup_ticks_9260, /* same as 9260 */ @@ -1380,6 +1394,7 @@ static struct at91_adc_caps at91sam9x5_caps = { static const struct of_device_id at91_adc_dt_ids[] = { { .compatible = "atmel,at91sam9260-adc", .data = &at91sam9260_caps }, + { .compatible = "atmel,at91sam9rl-adc", .data = &at91sam9rl_caps }, { .compatible = "atmel,at91sam9g45-adc", .data = &at91sam9g45_caps }, { .compatible = "atmel,at91sam9x5-adc", .data = &at91sam9x5_caps }, {}, @@ -1390,6 +1405,9 @@ static const struct platform_device_id at91_adc_ids[] = { { .name = "at91sam9260-adc", .driver_data = (unsigned long)&at91sam9260_caps, + }, { + .name = "at91sam9rl-adc", + .driver_data = (unsigned long)&at91sam9rl_caps, }, { .name = "at91sam9g45-adc", .driver_data = (unsigned long)&at91sam9g45_caps, -- cgit v1.2.2 From e4719d8ddb60a907d8fe8afa08f5719b31bf709d Mon Sep 17 00:00:00 2001 From: Alexandre Belloni Date: Tue, 15 Apr 2014 12:28:08 +0200 Subject: Input: atmel_tsadcc: remove driver The atmel_tsadcc driver is not used anymore, it has been replaced by at91_adc so remove it. Signed-off-by: Alexandre Belloni Acked-by: Dmitry Torokhov Signed-off-by: Nicolas Ferre --- drivers/input/touchscreen/Kconfig | 12 -- drivers/input/touchscreen/Makefile | 1 - drivers/input/touchscreen/atmel_tsadcc.c | 358 ------------------------------- 3 files changed, 371 deletions(-) delete mode 100644 drivers/input/touchscreen/atmel_tsadcc.c (limited to 'drivers') diff --git a/drivers/input/touchscreen/Kconfig b/drivers/input/touchscreen/Kconfig index 68edc9db2c64..0b5965ba51bc 100644 --- a/drivers/input/touchscreen/Kconfig +++ b/drivers/input/touchscreen/Kconfig @@ -550,18 +550,6 @@ config TOUCHSCREEN_TI_AM335X_TSC To compile this driver as a module, choose M here: the module will be called ti_am335x_tsc. -config TOUCHSCREEN_ATMEL_TSADCC - tristate "Atmel Touchscreen Interface" - depends on ARCH_AT91 - help - Say Y here if you have a 4-wire touchscreen connected to the - ADC Controller on your Atmel SoC. - - If unsure, say N. - - To compile this driver as a module, choose M here: the - module will be called atmel_tsadcc. - config TOUCHSCREEN_UCB1400 tristate "Philips UCB1400 touchscreen" depends on AC97_BUS diff --git a/drivers/input/touchscreen/Makefile b/drivers/input/touchscreen/Makefile index 4bc954b7c7c3..03f12a1f2218 100644 --- a/drivers/input/touchscreen/Makefile +++ b/drivers/input/touchscreen/Makefile @@ -13,7 +13,6 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI) += ad7879-spi.o obj-$(CONFIG_TOUCHSCREEN_ADS7846) += ads7846.o obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT) += atmel_mxt_ts.o -obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) += atmel_tsadcc.o obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR) += auo-pixcir-ts.o obj-$(CONFIG_TOUCHSCREEN_BU21013) += bu21013_ts.o obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110) += cy8ctmg110_ts.o diff --git a/drivers/input/touchscreen/atmel_tsadcc.c b/drivers/input/touchscreen/atmel_tsadcc.c deleted file mode 100644 index a7c9d6967d1e..000000000000 --- a/drivers/input/touchscreen/atmel_tsadcc.c +++ /dev/null @@ -1,358 +0,0 @@ -/* - * Atmel Touch Screen Driver - * - * Copyright (c) 2008 ATMEL - * Copyright (c) 2008 Dan Liang - * Copyright (c) 2008 TimeSys Corporation - * Copyright (c) 2008 Justin Waters - * - * Based on touchscreen code from Atmel Corporation. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License version 2 as - * published by the Free Software Foundation. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */ - -#define ATMEL_TSADCC_CR 0x00 /* Control register */ -#define ATMEL_TSADCC_SWRST (1 << 0) /* Software Reset*/ -#define ATMEL_TSADCC_START (1 << 1) /* Start conversion */ - -#define ATMEL_TSADCC_MR 0x04 /* Mode register */ -#define ATMEL_TSADCC_TSAMOD (3 << 0) /* ADC mode */ -#define ATMEL_TSADCC_TSAMOD_ADC_ONLY_MODE (0x0) /* ADC Mode */ -#define ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE (0x1) /* Touch Screen Only Mode */ -#define ATMEL_TSADCC_LOWRES (1 << 4) /* Resolution selection */ -#define ATMEL_TSADCC_SLEEP (1 << 5) /* Sleep mode */ -#define ATMEL_TSADCC_PENDET (1 << 6) /* Pen Detect selection */ -#define ATMEL_TSADCC_PRES (1 << 7) /* Pressure Measurement Selection */ -#define ATMEL_TSADCC_PRESCAL (0x3f << 8) /* Prescalar Rate Selection */ -#define ATMEL_TSADCC_EPRESCAL (0xff << 8) /* Prescalar Rate Selection (Extended) */ -#define ATMEL_TSADCC_STARTUP (0x7f << 16) /* Start Up time */ -#define ATMEL_TSADCC_SHTIM (0xf << 24) /* Sample & Hold time */ -#define ATMEL_TSADCC_PENDBC (0xf << 28) /* Pen Detect debouncing time */ - -#define ATMEL_TSADCC_TRGR 0x08 /* Trigger register */ -#define ATMEL_TSADCC_TRGMOD (7 << 0) /* Trigger mode */ -#define ATMEL_TSADCC_TRGMOD_NONE (0 << 0) -#define ATMEL_TSADCC_TRGMOD_EXT_RISING (1 << 0) -#define ATMEL_TSADCC_TRGMOD_EXT_FALLING (2 << 0) -#define ATMEL_TSADCC_TRGMOD_EXT_ANY (3 << 0) -#define ATMEL_TSADCC_TRGMOD_PENDET (4 << 0) -#define ATMEL_TSADCC_TRGMOD_PERIOD (5 << 0) -#define ATMEL_TSADCC_TRGMOD_CONTINUOUS (6 << 0) -#define ATMEL_TSADCC_TRGPER (0xffff << 16) /* Trigger period */ - -#define ATMEL_TSADCC_TSR 0x0C /* Touch Screen register */ -#define ATMEL_TSADCC_TSFREQ (0xf << 0) /* TS Frequency in Interleaved mode */ -#define ATMEL_TSADCC_TSSHTIM (0xf << 24) /* Sample & Hold time */ - -#define ATMEL_TSADCC_CHER 0x10 /* Channel Enable register */ -#define ATMEL_TSADCC_CHDR 0x14 /* Channel Disable register */ -#define ATMEL_TSADCC_CHSR 0x18 /* Channel Status register */ -#define ATMEL_TSADCC_CH(n) (1 << (n)) /* Channel number */ - -#define ATMEL_TSADCC_SR 0x1C /* Status register */ -#define ATMEL_TSADCC_EOC(n) (1 << ((n)+0)) /* End of conversion for channel N */ -#define ATMEL_TSADCC_OVRE(n) (1 << ((n)+8)) /* Overrun error for channel N */ -#define ATMEL_TSADCC_DRDY (1 << 16) /* Data Ready */ -#define ATMEL_TSADCC_GOVRE (1 << 17) /* General Overrun Error */ -#define ATMEL_TSADCC_ENDRX (1 << 18) /* End of RX Buffer */ -#define ATMEL_TSADCC_RXBUFF (1 << 19) /* TX Buffer full */ -#define ATMEL_TSADCC_PENCNT (1 << 20) /* Pen contact */ -#define ATMEL_TSADCC_NOCNT (1 << 21) /* No contact */ - -#define ATMEL_TSADCC_LCDR 0x20 /* Last Converted Data register */ -#define ATMEL_TSADCC_DATA (0x3ff << 0) /* Channel data */ - -#define ATMEL_TSADCC_IER 0x24 /* Interrupt Enable register */ -#define ATMEL_TSADCC_IDR 0x28 /* Interrupt Disable register */ -#define ATMEL_TSADCC_IMR 0x2C /* Interrupt Mask register */ -#define ATMEL_TSADCC_CDR0 0x30 /* Channel Data 0 */ -#define ATMEL_TSADCC_CDR1 0x34 /* Channel Data 1 */ -#define ATMEL_TSADCC_CDR2 0x38 /* Channel Data 2 */ -#define ATMEL_TSADCC_CDR3 0x3C /* Channel Data 3 */ -#define ATMEL_TSADCC_CDR4 0x40 /* Channel Data 4 */ -#define ATMEL_TSADCC_CDR5 0x44 /* Channel Data 5 */ - -#define ATMEL_TSADCC_XPOS 0x50 -#define ATMEL_TSADCC_Z1DAT 0x54 -#define ATMEL_TSADCC_Z2DAT 0x58 - -#define PRESCALER_VAL(x) ((x) >> 8) - -#define ADC_DEFAULT_CLOCK 100000 - -struct atmel_tsadcc { - struct input_dev *input; - char phys[32]; - struct clk *clk; - int irq; - unsigned int prev_absx; - unsigned int prev_absy; - unsigned char bufferedmeasure; -}; - -static void __iomem *tsc_base; - -#define atmel_tsadcc_read(reg) __raw_readl(tsc_base + (reg)) -#define atmel_tsadcc_write(reg, val) __raw_writel((val), tsc_base + (reg)) - -static irqreturn_t atmel_tsadcc_interrupt(int irq, void *dev) -{ - struct atmel_tsadcc *ts_dev = (struct atmel_tsadcc *)dev; - struct input_dev *input_dev = ts_dev->input; - - unsigned int status; - unsigned int reg; - - status = atmel_tsadcc_read(ATMEL_TSADCC_SR); - status &= atmel_tsadcc_read(ATMEL_TSADCC_IMR); - - if (status & ATMEL_TSADCC_NOCNT) { - /* Contact lost */ - reg = atmel_tsadcc_read(ATMEL_TSADCC_MR) | ATMEL_TSADCC_PENDBC; - - atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); - atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); - atmel_tsadcc_write(ATMEL_TSADCC_IDR, - ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT); - atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); - - input_report_key(input_dev, BTN_TOUCH, 0); - ts_dev->bufferedmeasure = 0; - input_sync(input_dev); - - } else if (status & ATMEL_TSADCC_PENCNT) { - /* Pen detected */ - reg = atmel_tsadcc_read(ATMEL_TSADCC_MR); - reg &= ~ATMEL_TSADCC_PENDBC; - - atmel_tsadcc_write(ATMEL_TSADCC_IDR, ATMEL_TSADCC_PENCNT); - atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); - atmel_tsadcc_write(ATMEL_TSADCC_IER, - ATMEL_TSADCC_EOC(3) | ATMEL_TSADCC_NOCNT); - atmel_tsadcc_write(ATMEL_TSADCC_TRGR, - ATMEL_TSADCC_TRGMOD_PERIOD | (0x0FFF << 16)); - - } else if (status & ATMEL_TSADCC_EOC(3)) { - /* Conversion finished */ - - if (ts_dev->bufferedmeasure) { - /* Last measurement is always discarded, since it can - * be erroneous. - * Always report previous measurement */ - input_report_abs(input_dev, ABS_X, ts_dev->prev_absx); - input_report_abs(input_dev, ABS_Y, ts_dev->prev_absy); - input_report_key(input_dev, BTN_TOUCH, 1); - input_sync(input_dev); - } else - ts_dev->bufferedmeasure = 1; - - /* Now make new measurement */ - ts_dev->prev_absx = atmel_tsadcc_read(ATMEL_TSADCC_CDR3) << 10; - ts_dev->prev_absx /= atmel_tsadcc_read(ATMEL_TSADCC_CDR2); - - ts_dev->prev_absy = atmel_tsadcc_read(ATMEL_TSADCC_CDR1) << 10; - ts_dev->prev_absy /= atmel_tsadcc_read(ATMEL_TSADCC_CDR0); - } - - return IRQ_HANDLED; -} - -/* - * The functions for inserting/removing us as a module. - */ - -static int atmel_tsadcc_probe(struct platform_device *pdev) -{ - struct atmel_tsadcc *ts_dev; - struct input_dev *input_dev; - struct resource *res; - struct at91_tsadcc_data *pdata = dev_get_platdata(&pdev->dev); - int err; - unsigned int prsc; - unsigned int reg; - - if (!pdata) - return -EINVAL; - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - if (!res) { - dev_err(&pdev->dev, "no mmio resource defined.\n"); - return -ENXIO; - } - - /* Allocate memory for device */ - ts_dev = kzalloc(sizeof(struct atmel_tsadcc), GFP_KERNEL); - if (!ts_dev) { - dev_err(&pdev->dev, "failed to allocate memory.\n"); - return -ENOMEM; - } - platform_set_drvdata(pdev, ts_dev); - - input_dev = input_allocate_device(); - if (!input_dev) { - dev_err(&pdev->dev, "failed to allocate input device.\n"); - err = -EBUSY; - goto err_free_mem; - } - - ts_dev->irq = platform_get_irq(pdev, 0); - if (ts_dev->irq < 0) { - dev_err(&pdev->dev, "no irq ID is designated.\n"); - err = -ENODEV; - goto err_free_dev; - } - - if (!request_mem_region(res->start, resource_size(res), - "atmel tsadcc regs")) { - dev_err(&pdev->dev, "resources is unavailable.\n"); - err = -EBUSY; - goto err_free_dev; - } - - tsc_base = ioremap(res->start, resource_size(res)); - if (!tsc_base) { - dev_err(&pdev->dev, "failed to map registers.\n"); - err = -ENOMEM; - goto err_release_mem; - } - - err = request_irq(ts_dev->irq, atmel_tsadcc_interrupt, 0, - pdev->dev.driver->name, ts_dev); - if (err) { - dev_err(&pdev->dev, "failed to allocate irq.\n"); - goto err_unmap_regs; - } - - ts_dev->clk = clk_get(&pdev->dev, "tsc_clk"); - if (IS_ERR(ts_dev->clk)) { - dev_err(&pdev->dev, "failed to get ts_clk\n"); - err = PTR_ERR(ts_dev->clk); - goto err_free_irq; - } - - ts_dev->input = input_dev; - ts_dev->bufferedmeasure = 0; - - snprintf(ts_dev->phys, sizeof(ts_dev->phys), - "%s/input0", dev_name(&pdev->dev)); - - input_dev->name = "atmel touch screen controller"; - input_dev->phys = ts_dev->phys; - input_dev->dev.parent = &pdev->dev; - - __set_bit(EV_ABS, input_dev->evbit); - input_set_abs_params(input_dev, ABS_X, 0, 0x3FF, 0, 0); - input_set_abs_params(input_dev, ABS_Y, 0, 0x3FF, 0, 0); - - input_set_capability(input_dev, EV_KEY, BTN_TOUCH); - - /* clk_enable() always returns 0, no need to check it */ - clk_enable(ts_dev->clk); - - prsc = clk_get_rate(ts_dev->clk); - dev_info(&pdev->dev, "Master clock is set at: %d Hz\n", prsc); - - if (!pdata->adc_clock) - pdata->adc_clock = ADC_DEFAULT_CLOCK; - - prsc = (prsc / (2 * pdata->adc_clock)) - 1; - - /* saturate if this value is too high */ - if (cpu_is_at91sam9rl()) { - if (prsc > PRESCALER_VAL(ATMEL_TSADCC_PRESCAL)) - prsc = PRESCALER_VAL(ATMEL_TSADCC_PRESCAL); - } else { - if (prsc > PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL)) - prsc = PRESCALER_VAL(ATMEL_TSADCC_EPRESCAL); - } - - dev_info(&pdev->dev, "Prescaler is set at: %d\n", prsc); - - reg = ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE | - ((0x00 << 5) & ATMEL_TSADCC_SLEEP) | /* Normal Mode */ - ((0x01 << 6) & ATMEL_TSADCC_PENDET) | /* Enable Pen Detect */ - (prsc << 8) | - ((0x26 << 16) & ATMEL_TSADCC_STARTUP) | - ((pdata->pendet_debounce << 28) & ATMEL_TSADCC_PENDBC); - - atmel_tsadcc_write(ATMEL_TSADCC_CR, ATMEL_TSADCC_SWRST); - atmel_tsadcc_write(ATMEL_TSADCC_MR, reg); - atmel_tsadcc_write(ATMEL_TSADCC_TRGR, ATMEL_TSADCC_TRGMOD_NONE); - atmel_tsadcc_write(ATMEL_TSADCC_TSR, - (pdata->ts_sample_hold_time << 24) & ATMEL_TSADCC_TSSHTIM); - - atmel_tsadcc_read(ATMEL_TSADCC_SR); - atmel_tsadcc_write(ATMEL_TSADCC_IER, ATMEL_TSADCC_PENCNT); - - /* All went ok, so register to the input system */ - err = input_register_device(input_dev); - if (err) - goto err_fail; - - return 0; - -err_fail: - clk_disable(ts_dev->clk); - clk_put(ts_dev->clk); -err_free_irq: - free_irq(ts_dev->irq, ts_dev); -err_unmap_regs: - iounmap(tsc_base); -err_release_mem: - release_mem_region(res->start, resource_size(res)); -err_free_dev: - input_free_device(input_dev); -err_free_mem: - kfree(ts_dev); - return err; -} - -static int atmel_tsadcc_remove(struct platform_device *pdev) -{ - struct atmel_tsadcc *ts_dev = platform_get_drvdata(pdev); - struct resource *res; - - free_irq(ts_dev->irq, ts_dev); - - input_unregister_device(ts_dev->input); - - res = platform_get_resource(pdev, IORESOURCE_MEM, 0); - iounmap(tsc_base); - release_mem_region(res->start, resource_size(res)); - - clk_disable(ts_dev->clk); - clk_put(ts_dev->clk); - - kfree(ts_dev); - - return 0; -} - -static struct platform_driver atmel_tsadcc_driver = { - .probe = atmel_tsadcc_probe, - .remove = atmel_tsadcc_remove, - .driver = { - .name = "atmel_tsadcc", - }, -}; -module_platform_driver(atmel_tsadcc_driver); - -MODULE_LICENSE("GPL"); -MODULE_DESCRIPTION("Atmel TouchScreen Driver"); -MODULE_AUTHOR("Dan Liang "); - -- cgit v1.2.2 From ef37d337e1d37bd84ccaa5811a8d1f00f8b3677c Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 14 Apr 2014 15:54:01 +0200 Subject: irqchip: irq-armada-370-xp: Do the set_smp_cross_call() in the driver Instead of having the SoC code in arch/arm/mach-mvebu/platsmp.c do the set_smp_cross_call() to register the IPI-triggering function, it makes more sense to do exactly what the GIC driver is doing: let the irqchip driver do it. This way, it avoids having to expose the armada_mpic_send_doorbell() function between the irqchip driver and the SoC code. Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397483648-26611-5-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 41be897df8d5..727566216e24 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -315,7 +315,8 @@ static int armada_370_xp_mpic_irq_map(struct irq_domain *h, } #ifdef CONFIG_SMP -void armada_mpic_send_doorbell(const struct cpumask *mask, unsigned int irq) +static void armada_mpic_send_doorbell(const struct cpumask *mask, + unsigned int irq) { int cpu; unsigned long map = 0; @@ -511,6 +512,9 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, if (parent_irq <= 0) { irq_set_default_host(armada_370_xp_mpic_domain); set_handle_irq(armada_370_xp_handle_irq); +#ifdef CONFIG_SMP + set_smp_cross_call(armada_mpic_send_doorbell); +#endif } else { irq_set_chained_handler(parent_irq, armada_370_xp_mpic_handle_cascade_irq); -- cgit v1.2.2 From d7df84b3cecad4c768e4065d1d61b2f8fd02b7fa Mon Sep 17 00:00:00 2001 From: Thomas Petazzoni Date: Mon, 14 Apr 2014 15:54:02 +0200 Subject: irqchip: irq-armada-370-xp: Use cpu notifier to initialize secondary CPUs Some irqchip initialization must be done on secondary CPUs. On mvebu platforms, this is currently achieved by having the arch/arm/mach-mvebu/platsmp.c code directly call into a function exported by the irqchip driver, which isn't really nice. This commit changes this by using the same solution as the one used in the GIC driver: the irqchip driver registers a CPU notifier, which is used to do the secondary CPU IRQ initialization. This way, the irqchip driver is completely autonomous, and the function no longer needs to be exposed from the irqchip driver to the SoC code. Signed-off-by: Thomas Petazzoni Link: https://lkml.kernel.org/r/1397483648-26611-6-git-send-email-thomas.petazzoni@free-electrons.com Signed-off-by: Jason Cooper --- drivers/irqchip/irq-armada-370-xp.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c index 727566216e24..71f77848bc23 100644 --- a/drivers/irqchip/irq-armada-370-xp.c +++ b/drivers/irqchip/irq-armada-370-xp.c @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -336,7 +337,7 @@ static void armada_mpic_send_doorbell(const struct cpumask *mask, ARMADA_370_XP_SW_TRIG_INT_OFFS); } -void armada_xp_mpic_smp_cpu_init(void) +static void armada_xp_mpic_smp_cpu_init(void) { /* Clear pending IPIs */ writel(0, per_cpu_int_base + ARMADA_370_XP_IN_DRBEL_CAUSE_OFFS); @@ -348,6 +349,20 @@ void armada_xp_mpic_smp_cpu_init(void) /* Unmask IPI interrupt */ writel(0, per_cpu_int_base + ARMADA_370_XP_INT_CLEAR_MASK_OFFS); } + +static int armada_xp_mpic_secondary_init(struct notifier_block *nfb, + unsigned long action, void *hcpu) +{ + if (action == CPU_STARTING || action == CPU_STARTING_FROZEN) + armada_xp_mpic_smp_cpu_init(); + return NOTIFY_OK; +} + +static struct notifier_block armada_370_xp_mpic_cpu_notifier = { + .notifier_call = armada_xp_mpic_secondary_init, + .priority = 100, +}; + #endif /* CONFIG_SMP */ static struct irq_domain_ops armada_370_xp_mpic_irq_ops = { @@ -514,6 +529,7 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, set_handle_irq(armada_370_xp_handle_irq); #ifdef CONFIG_SMP set_smp_cross_call(armada_mpic_send_doorbell); + register_cpu_notifier(&armada_370_xp_mpic_cpu_notifier); #endif } else { irq_set_chained_handler(parent_irq, -- cgit v1.2.2 From bffbc6eabd0e48bba5415c4aec34cb75d459c73a Mon Sep 17 00:00:00 2001 From: Sebastian Hesselbarth Date: Mon, 28 Apr 2014 23:12:08 +0200 Subject: irqchip: orion: Reverse irq handling priority Non-DT irq handlers were working through irq causes from most-significant to least-significant bit, while DT irqchip driver does it the other way round. This revealed some more HW issues on Kirkwood peripheral IP, where spurious sdio irqs can happen although irqs are masked. Also, the generated binaries show that original non-DT order compared to DT order save two instructions for each bit count check: irqchip DT order with ffs(): 60: e3a06001 mov r6, #1 64: e2643000 rsb r3, r4, #0 68: e0033004 and r3, r3, r4 6c: e16f3f13 clz r3, r3 70: e263301f rsb r3, r3, #31 74: e1c44316 bic r4, r4, r6, lsl r3 78: e5971004 ldr r1, [r7, #4] Original non-DT order with fls(): 60: e3a07001 mov r7, #1 64: e16f3f14 clz r3, r4 68: e263301f rsb r3, r3, #31 6c: e1c44317 bic r4, r4, r7, lsl r3 70: e5951004 ldr r1, [r5, #4] Therefore, reverse irq bit handling back to original order by replacing ffs() with fls(). Signed-off-by: Sebastian Hesselbarth Link: https://lkml.kernel.org/r/1398719528-23607-1-git-send-email-sebastian.hesselbarth@gmail.com Acked-by: Jason Cooper Signed-off-by: Jason Cooper --- drivers/irqchip/irq-orion.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/irqchip/irq-orion.c b/drivers/irqchip/irq-orion.c index e25f246cd2fb..34d18b48bb78 100644 --- a/drivers/irqchip/irq-orion.c +++ b/drivers/irqchip/irq-orion.c @@ -42,7 +42,7 @@ __exception_irq_entry orion_handle_irq(struct pt_regs *regs) u32 stat = readl_relaxed(gc->reg_base + ORION_IRQ_CAUSE) & gc->mask_cache; while (stat) { - u32 hwirq = ffs(stat) - 1; + u32 hwirq = __fls(stat); u32 irq = irq_find_mapping(orion_irq_domain, gc->irq_base + hwirq); handle_IRQ(irq, regs); @@ -117,7 +117,7 @@ static void orion_bridge_irq_handler(unsigned int irq, struct irq_desc *desc) gc->mask_cache; while (stat) { - u32 hwirq = ffs(stat) - 1; + u32 hwirq = __fls(stat); generic_handle_irq(irq_find_mapping(d, gc->irq_base + hwirq)); stat &= ~(1 << hwirq); -- cgit v1.2.2 From b858fbc1919720f7f54360098ece03b383e961fa Mon Sep 17 00:00:00 2001 From: Gregory CLEMENT Date: Mon, 14 Apr 2014 17:10:13 +0200 Subject: cpuidle: mvebu: Add initial CPU idle support for Armada 370/XP SoC Add the wfi, cpu idle and cpu deep idle power states support for the Armada XP SoCs. All the latencies and the power consumption values used at the "armada_370_xp_idle_driver" structure are preliminary and will be modified in the future after running some measurements and analysis. Based on the work of Nadav Haklai. Signed-off-by: Nadav Haklai Link: https://lkml.kernel.org/r/1397488214-20685-11-git-send-email-gregory.clement@free-electrons.com Signed-off-by: Gregory CLEMENT Link: https://lkml.kernel.org/r/1397488214-20685-11-git-send-email-gregory.clement@free-electrons.com Acked-by: Daniel Lezcano Signed-off-by: Jason Cooper --- drivers/cpuidle/Kconfig.arm | 5 ++ drivers/cpuidle/Makefile | 1 + drivers/cpuidle/cpuidle-armada-370-xp.c | 93 +++++++++++++++++++++++++++++++++ 3 files changed, 99 insertions(+) create mode 100644 drivers/cpuidle/cpuidle-armada-370-xp.c (limited to 'drivers') diff --git a/drivers/cpuidle/Kconfig.arm b/drivers/cpuidle/Kconfig.arm index 97ccc31dbdd8..5bb94780d377 100644 --- a/drivers/cpuidle/Kconfig.arm +++ b/drivers/cpuidle/Kconfig.arm @@ -1,6 +1,11 @@ # # ARM CPU Idle drivers # +config ARM_ARMADA_370_XP_CPUIDLE + bool "CPU Idle Driver for Armada 370/XP family processors" + depends on ARCH_MVEBU + help + Select this to enable cpuidle on Armada 370/XP processors. config ARM_BIG_LITTLE_CPUIDLE bool "Support for ARM big.LITTLE processors" diff --git a/drivers/cpuidle/Makefile b/drivers/cpuidle/Makefile index f71ae1b373c5..9902d052bd87 100644 --- a/drivers/cpuidle/Makefile +++ b/drivers/cpuidle/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_ARCH_NEEDS_CPU_IDLE_COUPLED) += coupled.o ################################################################################## # ARM SoC drivers +obj-$(CONFIG_ARM_ARMADA_370_XP_CPUIDLE) += cpuidle-armada-370-xp.o obj-$(CONFIG_ARM_BIG_LITTLE_CPUIDLE) += cpuidle-big_little.o obj-$(CONFIG_ARM_HIGHBANK_CPUIDLE) += cpuidle-calxeda.o obj-$(CONFIG_ARM_KIRKWOOD_CPUIDLE) += cpuidle-kirkwood.o diff --git a/drivers/cpuidle/cpuidle-armada-370-xp.c b/drivers/cpuidle/cpuidle-armada-370-xp.c new file mode 100644 index 000000000000..28587d0f3947 --- /dev/null +++ b/drivers/cpuidle/cpuidle-armada-370-xp.c @@ -0,0 +1,93 @@ +/* + * Marvell Armada 370 and Armada XP SoC cpuidle driver + * + * Copyright (C) 2014 Marvell + * + * Nadav Haklai + * Gregory CLEMENT + * + * This file is licensed under the terms of the GNU General Public + * License version 2. This program is licensed "as is" without any + * warranty of any kind, whether express or implied. + * + * Maintainer: Gregory CLEMENT + */ + +#include +#include +#include +#include +#include +#include +#include + +#define ARMADA_370_XP_MAX_STATES 3 +#define ARMADA_370_XP_FLAG_DEEP_IDLE 0x10000 + +static int (*armada_370_xp_cpu_suspend)(int); + +static int armada_370_xp_enter_idle(struct cpuidle_device *dev, + struct cpuidle_driver *drv, + int index) +{ + int ret; + bool deepidle = false; + cpu_pm_enter(); + + if (drv->states[index].flags & ARMADA_370_XP_FLAG_DEEP_IDLE) + deepidle = true; + + ret = armada_370_xp_cpu_suspend(deepidle); + if (ret) + return ret; + + cpu_pm_exit(); + + return index; +} + +static struct cpuidle_driver armada_370_xp_idle_driver = { + .name = "armada_370_xp_idle", + .states[0] = ARM_CPUIDLE_WFI_STATE, + .states[1] = { + .enter = armada_370_xp_enter_idle, + .exit_latency = 10, + .power_usage = 50, + .target_residency = 100, + .flags = CPUIDLE_FLAG_TIME_VALID, + .name = "MV CPU IDLE", + .desc = "CPU power down", + }, + .states[2] = { + .enter = armada_370_xp_enter_idle, + .exit_latency = 100, + .power_usage = 5, + .target_residency = 1000, + .flags = CPUIDLE_FLAG_TIME_VALID | + ARMADA_370_XP_FLAG_DEEP_IDLE, + .name = "MV CPU DEEP IDLE", + .desc = "CPU and L2 Fabric power down", + }, + .state_count = ARMADA_370_XP_MAX_STATES, +}; + +static int armada_370_xp_cpuidle_probe(struct platform_device *pdev) +{ + + armada_370_xp_cpu_suspend = (void *)(pdev->dev.platform_data); + return cpuidle_register(&armada_370_xp_idle_driver, NULL); +} + +static struct platform_driver armada_370_xp_cpuidle_plat_driver = { + .driver = { + .name = "cpuidle-armada-370-xp", + .owner = THIS_MODULE, + }, + .probe = armada_370_xp_cpuidle_probe, +}; + +module_platform_driver(armada_370_xp_cpuidle_plat_driver); + +MODULE_AUTHOR("Gregory CLEMENT "); +MODULE_DESCRIPTION("Armada 370/XP cpu idle driver"); +MODULE_LICENSE("GPL"); -- cgit v1.2.2 From 976face4b46ab36b04312b4e404d160296716d46 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Wed, 12 Mar 2014 20:26:44 +0530 Subject: clk/samsung: add support for multiple clock providers Samsung CCF helper functions do not provide support to register multiple Clock Providers for a given SoC. Due to this limitation, SoC platforms are not able to use these helpers for registering multiple clock providers and are forced to bypass this layer. This layer is modified accordingly to enable the support for multiple clock providers. Clock file for exynos4, exynos5250, exynos5420, exynos5440, S3c64xx, S3c24xx are also modified as per changed helper functions. Signed-off-by: Rahul Sharma [t.figa: Modified s3c2410 clock driver as well] Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos4.c | 47 ++++++++------- drivers/clk/samsung/clk-exynos5250.c | 25 +++++--- drivers/clk/samsung/clk-exynos5420.c | 24 +++++--- drivers/clk/samsung/clk-exynos5440.c | 18 +++--- drivers/clk/samsung/clk-pll.c | 14 +++-- drivers/clk/samsung/clk-s3c2410.c | 51 +++++++++------- drivers/clk/samsung/clk-s3c2412.c | 29 +++++---- drivers/clk/samsung/clk-s3c2443.c | 46 +++++++------- drivers/clk/samsung/clk-s3c64xx.c | 44 ++++++++------ drivers/clk/samsung/clk.c | 114 +++++++++++++++++++---------------- drivers/clk/samsung/clk.h | 72 ++++++++++++++-------- 11 files changed, 279 insertions(+), 205 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index b4f967210175..57ed5a8fb052 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -1043,7 +1043,7 @@ static unsigned long exynos4_get_xom(void) return xom; } -static void __init exynos4_clk_register_finpll(void) +static void __init exynos4_clk_register_finpll(struct samsung_clk_provider *ctx) { struct samsung_fixed_rate_clock fclk; struct clk *clk; @@ -1066,7 +1066,7 @@ static void __init exynos4_clk_register_finpll(void) fclk.parent_name = NULL; fclk.flags = CLK_IS_ROOT; fclk.fixed_rate = finpll_f; - samsung_clk_register_fixed_rate(&fclk, 1); + samsung_clk_register_fixed_rate(ctx, &fclk, 1); } @@ -1176,22 +1176,25 @@ static struct samsung_pll_clock exynos4x12_plls[nr_plls] __initdata = { static void __init exynos4_clk_init(struct device_node *np, enum exynos4_soc soc) { + struct samsung_clk_provider *ctx; exynos4_soc = soc; reg_base = of_iomap(np, 0); if (!reg_base) panic("%s: failed to map registers\n", __func__); - samsung_clk_init(np, reg_base, CLK_NR_CLKS); + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); - samsung_clk_of_register_fixed_ext(exynos4_fixed_rate_ext_clks, + samsung_clk_of_register_fixed_ext(ctx, exynos4_fixed_rate_ext_clks, ARRAY_SIZE(exynos4_fixed_rate_ext_clks), ext_clk_match); - exynos4_clk_register_finpll(); + exynos4_clk_register_finpll(ctx); if (exynos4_soc == EXYNOS4210) { - samsung_clk_register_mux(exynos4210_mux_early, + samsung_clk_register_mux(ctx, exynos4210_mux_early, ARRAY_SIZE(exynos4210_mux_early)); if (_get_rate("fin_pll") == 24000000) { @@ -1205,7 +1208,7 @@ static void __init exynos4_clk_init(struct device_node *np, exynos4210_plls[vpll].rate_table = exynos4210_vpll_rates; - samsung_clk_register_pll(exynos4210_plls, + samsung_clk_register_pll(ctx, exynos4210_plls, ARRAY_SIZE(exynos4210_plls), reg_base); } else { if (_get_rate("fin_pll") == 24000000) { @@ -1217,42 +1220,42 @@ static void __init exynos4_clk_init(struct device_node *np, exynos4x12_vpll_rates; } - samsung_clk_register_pll(exynos4x12_plls, + samsung_clk_register_pll(ctx, exynos4x12_plls, ARRAY_SIZE(exynos4x12_plls), reg_base); } - samsung_clk_register_fixed_rate(exynos4_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, exynos4_fixed_rate_clks, ARRAY_SIZE(exynos4_fixed_rate_clks)); - samsung_clk_register_mux(exynos4_mux_clks, + samsung_clk_register_mux(ctx, exynos4_mux_clks, ARRAY_SIZE(exynos4_mux_clks)); - samsung_clk_register_div(exynos4_div_clks, + samsung_clk_register_div(ctx, exynos4_div_clks, ARRAY_SIZE(exynos4_div_clks)); - samsung_clk_register_gate(exynos4_gate_clks, + samsung_clk_register_gate(ctx, exynos4_gate_clks, ARRAY_SIZE(exynos4_gate_clks)); if (exynos4_soc == EXYNOS4210) { - samsung_clk_register_fixed_rate(exynos4210_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, exynos4210_fixed_rate_clks, ARRAY_SIZE(exynos4210_fixed_rate_clks)); - samsung_clk_register_mux(exynos4210_mux_clks, + samsung_clk_register_mux(ctx, exynos4210_mux_clks, ARRAY_SIZE(exynos4210_mux_clks)); - samsung_clk_register_div(exynos4210_div_clks, + samsung_clk_register_div(ctx, exynos4210_div_clks, ARRAY_SIZE(exynos4210_div_clks)); - samsung_clk_register_gate(exynos4210_gate_clks, + samsung_clk_register_gate(ctx, exynos4210_gate_clks, ARRAY_SIZE(exynos4210_gate_clks)); - samsung_clk_register_alias(exynos4210_aliases, + samsung_clk_register_alias(ctx, exynos4210_aliases, ARRAY_SIZE(exynos4210_aliases)); } else { - samsung_clk_register_mux(exynos4x12_mux_clks, + samsung_clk_register_mux(ctx, exynos4x12_mux_clks, ARRAY_SIZE(exynos4x12_mux_clks)); - samsung_clk_register_div(exynos4x12_div_clks, + samsung_clk_register_div(ctx, exynos4x12_div_clks, ARRAY_SIZE(exynos4x12_div_clks)); - samsung_clk_register_gate(exynos4x12_gate_clks, + samsung_clk_register_gate(ctx, exynos4x12_gate_clks, ARRAY_SIZE(exynos4x12_gate_clks)); - samsung_clk_register_alias(exynos4x12_aliases, + samsung_clk_register_alias(ctx, exynos4x12_aliases, ARRAY_SIZE(exynos4x12_aliases)); } - samsung_clk_register_alias(exynos4_aliases, + samsung_clk_register_alias(ctx, exynos4_aliases, ARRAY_SIZE(exynos4_aliases)); exynos4_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index e7ee4420da81..e549e862524a 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -686,6 +686,8 @@ static struct of_device_id ext_clk_match[] __initdata = { /* register exynox5250 clocks */ static void __init exynos5250_clk_init(struct device_node *np) { + struct samsung_clk_provider *ctx; + if (np) { reg_base = of_iomap(np, 0); if (!reg_base) @@ -694,11 +696,13 @@ static void __init exynos5250_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, CLK_NR_CLKS); - samsung_clk_of_register_fixed_ext(exynos5250_fixed_rate_ext_clks, + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + samsung_clk_of_register_fixed_ext(ctx, exynos5250_fixed_rate_ext_clks, ARRAY_SIZE(exynos5250_fixed_rate_ext_clks), ext_clk_match); - samsung_clk_register_mux(exynos5250_pll_pmux_clks, + samsung_clk_register_mux(ctx, exynos5250_pll_pmux_clks, ARRAY_SIZE(exynos5250_pll_pmux_clks)); if (_get_rate("fin_pll") == 24 * MHZ) { @@ -709,17 +713,18 @@ static void __init exynos5250_clk_init(struct device_node *np) if (_get_rate("mout_vpllsrc") == 24 * MHZ) exynos5250_plls[vpll].rate_table = vpll_24mhz_tbl; - samsung_clk_register_pll(exynos5250_plls, ARRAY_SIZE(exynos5250_plls), - reg_base); - samsung_clk_register_fixed_rate(exynos5250_fixed_rate_clks, + samsung_clk_register_pll(ctx, exynos5250_plls, + ARRAY_SIZE(exynos5250_plls), + reg_base); + samsung_clk_register_fixed_rate(ctx, exynos5250_fixed_rate_clks, ARRAY_SIZE(exynos5250_fixed_rate_clks)); - samsung_clk_register_fixed_factor(exynos5250_fixed_factor_clks, + samsung_clk_register_fixed_factor(ctx, exynos5250_fixed_factor_clks, ARRAY_SIZE(exynos5250_fixed_factor_clks)); - samsung_clk_register_mux(exynos5250_mux_clks, + samsung_clk_register_mux(ctx, exynos5250_mux_clks, ARRAY_SIZE(exynos5250_mux_clks)); - samsung_clk_register_div(exynos5250_div_clks, + samsung_clk_register_div(ctx, exynos5250_div_clks, ARRAY_SIZE(exynos5250_div_clks)); - samsung_clk_register_gate(exynos5250_gate_clks, + samsung_clk_register_gate(ctx, exynos5250_gate_clks, ARRAY_SIZE(exynos5250_gate_clks)); exynos5250_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 60b26819bed5..c3e0894d0279 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -778,6 +778,8 @@ static struct of_device_id ext_clk_match[] __initdata = { /* register exynos5420 clocks */ static void __init exynos5420_clk_init(struct device_node *np) { + struct samsung_clk_provider *ctx; + if (np) { reg_base = of_iomap(np, 0); if (!reg_base) @@ -786,21 +788,25 @@ static void __init exynos5420_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } - samsung_clk_init(np, reg_base, CLK_NR_CLKS); - samsung_clk_of_register_fixed_ext(exynos5420_fixed_rate_ext_clks, + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + + samsung_clk_of_register_fixed_ext(ctx, exynos5420_fixed_rate_ext_clks, ARRAY_SIZE(exynos5420_fixed_rate_ext_clks), ext_clk_match); - samsung_clk_register_pll(exynos5420_plls, ARRAY_SIZE(exynos5420_plls), - reg_base); - samsung_clk_register_fixed_rate(exynos5420_fixed_rate_clks, + samsung_clk_register_pll(ctx, exynos5420_plls, + ARRAY_SIZE(exynos5420_plls), + reg_base); + samsung_clk_register_fixed_rate(ctx, exynos5420_fixed_rate_clks, ARRAY_SIZE(exynos5420_fixed_rate_clks)); - samsung_clk_register_fixed_factor(exynos5420_fixed_factor_clks, + samsung_clk_register_fixed_factor(ctx, exynos5420_fixed_factor_clks, ARRAY_SIZE(exynos5420_fixed_factor_clks)); - samsung_clk_register_mux(exynos5420_mux_clks, + samsung_clk_register_mux(ctx, exynos5420_mux_clks, ARRAY_SIZE(exynos5420_mux_clks)); - samsung_clk_register_div(exynos5420_div_clks, + samsung_clk_register_div(ctx, exynos5420_div_clks, ARRAY_SIZE(exynos5420_div_clks)); - samsung_clk_register_gate(exynos5420_gate_clks, + samsung_clk_register_gate(ctx, exynos5420_gate_clks, ARRAY_SIZE(exynos5420_gate_clks)); exynos5420_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-exynos5440.c b/drivers/clk/samsung/clk-exynos5440.c index 2bfad5a993d0..647f1440aa6a 100644 --- a/drivers/clk/samsung/clk-exynos5440.c +++ b/drivers/clk/samsung/clk-exynos5440.c @@ -93,6 +93,7 @@ static struct of_device_id ext_clk_match[] __initdata = { static void __init exynos5440_clk_init(struct device_node *np) { void __iomem *reg_base; + struct samsung_clk_provider *ctx; reg_base = of_iomap(np, 0); if (!reg_base) { @@ -101,22 +102,25 @@ static void __init exynos5440_clk_init(struct device_node *np) return; } - samsung_clk_init(np, reg_base, CLK_NR_CLKS); - samsung_clk_of_register_fixed_ext(exynos5440_fixed_rate_ext_clks, + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + + samsung_clk_of_register_fixed_ext(ctx, exynos5440_fixed_rate_ext_clks, ARRAY_SIZE(exynos5440_fixed_rate_ext_clks), ext_clk_match); samsung_clk_register_pll2550x("cplla", "xtal", reg_base + 0x1c, 0x10); samsung_clk_register_pll2550x("cpllb", "xtal", reg_base + 0x20, 0x10); - samsung_clk_register_fixed_rate(exynos5440_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, exynos5440_fixed_rate_clks, ARRAY_SIZE(exynos5440_fixed_rate_clks)); - samsung_clk_register_fixed_factor(exynos5440_fixed_factor_clks, + samsung_clk_register_fixed_factor(ctx, exynos5440_fixed_factor_clks, ARRAY_SIZE(exynos5440_fixed_factor_clks)); - samsung_clk_register_mux(exynos5440_mux_clks, + samsung_clk_register_mux(ctx, exynos5440_mux_clks, ARRAY_SIZE(exynos5440_mux_clks)); - samsung_clk_register_div(exynos5440_div_clks, + samsung_clk_register_div(ctx, exynos5440_div_clks, ARRAY_SIZE(exynos5440_div_clks)); - samsung_clk_register_gate(exynos5440_gate_clks, + samsung_clk_register_gate(ctx, exynos5440_gate_clks, ARRAY_SIZE(exynos5440_gate_clks)); pr_info("Exynos5440: arm_clk = %ldHz\n", _get_rate("arm_clk")); diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 7fb0a28e65d5..1f310be17742 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -947,8 +947,9 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name, return clk; } -static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, - void __iomem *base) +static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, + struct samsung_pll_clock *pll_clk, + void __iomem *base) { struct samsung_clk_pll *pll; struct clk *clk; @@ -1066,7 +1067,7 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, return; } - samsung_clk_add_lookup(clk, pll_clk->id); + samsung_clk_add_lookup(ctx, clk, pll_clk->id); if (!pll_clk->alias) return; @@ -1077,11 +1078,12 @@ static void __init _samsung_clk_register_pll(struct samsung_pll_clock *pll_clk, __func__, pll_clk->name, ret); } -void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, - unsigned int nr_pll, void __iomem *base) +void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, + struct samsung_pll_clock *pll_list, + unsigned int nr_pll, void __iomem *base) { int cnt; for (cnt = 0; cnt < nr_pll; cnt++) - _samsung_clk_register_pll(&pll_list[cnt], base); + _samsung_clk_register_pll(ctx, &pll_list[cnt], base); } diff --git a/drivers/clk/samsung/clk-s3c2410.c b/drivers/clk/samsung/clk-s3c2410.c index 7b4182186a30..ba0716801db2 100644 --- a/drivers/clk/samsung/clk-s3c2410.c +++ b/drivers/clk/samsung/clk-s3c2410.c @@ -344,21 +344,24 @@ struct samsung_fixed_rate_clock s3c2410_common_frate_clks[] __initdata = { FRATE(XTI, "xti", NULL, CLK_IS_ROOT, 0), }; -static void __init s3c2410_common_clk_register_fixed_ext(unsigned long xti_f) +static void __init s3c2410_common_clk_register_fixed_ext( + struct samsung_clk_provider *ctx, + unsigned long xti_f) { struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal"); s3c2410_common_frate_clks[0].fixed_rate = xti_f; - samsung_clk_register_fixed_rate(s3c2410_common_frate_clks, + samsung_clk_register_fixed_rate(ctx, s3c2410_common_frate_clks, ARRAY_SIZE(s3c2410_common_frate_clks)); - samsung_clk_register_alias(&xti_alias, 1); + samsung_clk_register_alias(ctx, &xti_alias, 1); } void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, int current_soc, void __iomem *base) { + struct samsung_clk_provider *ctx; reg_base = base; if (np) { @@ -367,11 +370,13 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, panic("%s: failed to map registers\n", __func__); } - samsung_clk_init(np, reg_base, NR_CLKS); + ctx = samsung_clk_init(np, reg_base, NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); /* Register external clocks only in non-dt cases */ if (!np) - s3c2410_common_clk_register_fixed_ext(xti_f); + s3c2410_common_clk_register_fixed_ext(ctx, xti_f); if (current_soc == 2410) { if (_get_rate("xti") == 12 * MHZ) { @@ -380,7 +385,7 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, } /* Register PLLs. */ - samsung_clk_register_pll(s3c2410_plls, + samsung_clk_register_pll(ctx, s3c2410_plls, ARRAY_SIZE(s3c2410_plls), reg_base); } else { /* S3C2440, S3C2442 */ @@ -396,49 +401,49 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, } /* Register PLLs. */ - samsung_clk_register_pll(s3c244x_common_plls, + samsung_clk_register_pll(ctx, s3c244x_common_plls, ARRAY_SIZE(s3c244x_common_plls), reg_base); } /* Register common internal clocks. */ - samsung_clk_register_mux(s3c2410_common_muxes, + samsung_clk_register_mux(ctx, s3c2410_common_muxes, ARRAY_SIZE(s3c2410_common_muxes)); - samsung_clk_register_div(s3c2410_common_dividers, + samsung_clk_register_div(ctx, s3c2410_common_dividers, ARRAY_SIZE(s3c2410_common_dividers)); - samsung_clk_register_gate(s3c2410_common_gates, + samsung_clk_register_gate(ctx, s3c2410_common_gates, ARRAY_SIZE(s3c2410_common_gates)); if (current_soc == S3C2440 || current_soc == S3C2442) { - samsung_clk_register_div(s3c244x_common_dividers, + samsung_clk_register_div(ctx, s3c244x_common_dividers, ARRAY_SIZE(s3c244x_common_dividers)); - samsung_clk_register_gate(s3c244x_common_gates, + samsung_clk_register_gate(ctx, s3c244x_common_gates, ARRAY_SIZE(s3c244x_common_gates)); - samsung_clk_register_mux(s3c244x_common_muxes, + samsung_clk_register_mux(ctx, s3c244x_common_muxes, ARRAY_SIZE(s3c244x_common_muxes)); - samsung_clk_register_fixed_factor(s3c244x_common_ffactor, + samsung_clk_register_fixed_factor(ctx, s3c244x_common_ffactor, ARRAY_SIZE(s3c244x_common_ffactor)); } /* Register SoC-specific clocks. */ switch (current_soc) { case S3C2410: - samsung_clk_register_div(s3c2410_dividers, + samsung_clk_register_div(ctx, s3c2410_dividers, ARRAY_SIZE(s3c2410_dividers)); - samsung_clk_register_fixed_factor(s3c2410_ffactor, + samsung_clk_register_fixed_factor(ctx, s3c2410_ffactor, ARRAY_SIZE(s3c2410_ffactor)); - samsung_clk_register_alias(s3c2410_aliases, + samsung_clk_register_alias(ctx, s3c2410_aliases, ARRAY_SIZE(s3c2410_common_aliases)); break; case S3C2440: - samsung_clk_register_mux(s3c2440_muxes, + samsung_clk_register_mux(ctx, s3c2440_muxes, ARRAY_SIZE(s3c2440_muxes)); - samsung_clk_register_gate(s3c2440_gates, + samsung_clk_register_gate(ctx, s3c2440_gates, ARRAY_SIZE(s3c2440_gates)); break; case S3C2442: - samsung_clk_register_mux(s3c2442_muxes, + samsung_clk_register_mux(ctx, s3c2442_muxes, ARRAY_SIZE(s3c2442_muxes)); - samsung_clk_register_fixed_factor(s3c2442_ffactor, + samsung_clk_register_fixed_factor(ctx, s3c2442_ffactor, ARRAY_SIZE(s3c2442_ffactor)); break; } @@ -447,11 +452,11 @@ void __init s3c2410_common_clk_init(struct device_node *np, unsigned long xti_f, * Register common aliases at the end, as some of the aliased clocks * are SoC specific. */ - samsung_clk_register_alias(s3c2410_common_aliases, + samsung_clk_register_alias(ctx, s3c2410_common_aliases, ARRAY_SIZE(s3c2410_common_aliases)); if (current_soc == S3C2440 || current_soc == S3C2442) { - samsung_clk_register_alias(s3c244x_common_aliases, + samsung_clk_register_alias(ctx, s3c244x_common_aliases, ARRAY_SIZE(s3c244x_common_aliases)); } diff --git a/drivers/clk/samsung/clk-s3c2412.c b/drivers/clk/samsung/clk-s3c2412.c index 0f11a07d5c01..23e4313f625e 100644 --- a/drivers/clk/samsung/clk-s3c2412.c +++ b/drivers/clk/samsung/clk-s3c2412.c @@ -214,23 +214,25 @@ struct samsung_fixed_rate_clock s3c2412_common_frate_clks[] __initdata = { FRATE(0, "ext", NULL, CLK_IS_ROOT, 0), }; -static void __init s3c2412_common_clk_register_fixed_ext(unsigned long xti_f, - unsigned long ext_f) +static void __init s3c2412_common_clk_register_fixed_ext( + struct samsung_clk_provider *ctx, + unsigned long xti_f, unsigned long ext_f) { /* xtal alias is necessary for the current cpufreq driver */ struct samsung_clock_alias xti_alias = ALIAS(XTI, NULL, "xtal"); s3c2412_common_frate_clks[0].fixed_rate = xti_f; s3c2412_common_frate_clks[1].fixed_rate = ext_f; - samsung_clk_register_fixed_rate(s3c2412_common_frate_clks, + samsung_clk_register_fixed_rate(ctx, s3c2412_common_frate_clks, ARRAY_SIZE(s3c2412_common_frate_clks)); - samsung_clk_register_alias(&xti_alias, 1); + samsung_clk_register_alias(ctx, &xti_alias, 1); } void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f, unsigned long ext_f, void __iomem *base) { + struct samsung_clk_provider *ctx; reg_base = base; if (np) { @@ -239,24 +241,27 @@ void __init s3c2412_common_clk_init(struct device_node *np, unsigned long xti_f, panic("%s: failed to map registers\n", __func__); } - samsung_clk_init(np, reg_base, NR_CLKS); + ctx = samsung_clk_init(np, reg_base, NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); /* Register external clocks only in non-dt cases */ if (!np) - s3c2412_common_clk_register_fixed_ext(xti_f, ext_f); + s3c2412_common_clk_register_fixed_ext(ctx, xti_f, ext_f); /* Register PLLs. */ - samsung_clk_register_pll(s3c2412_plls, ARRAY_SIZE(s3c2412_plls), + samsung_clk_register_pll(ctx, s3c2412_plls, ARRAY_SIZE(s3c2412_plls), reg_base); /* Register common internal clocks. */ - samsung_clk_register_mux(s3c2412_muxes, ARRAY_SIZE(s3c2412_muxes)); - samsung_clk_register_div(s3c2412_dividers, + samsung_clk_register_mux(ctx, s3c2412_muxes, ARRAY_SIZE(s3c2412_muxes)); + samsung_clk_register_div(ctx, s3c2412_dividers, ARRAY_SIZE(s3c2412_dividers)); - samsung_clk_register_gate(s3c2412_gates, ARRAY_SIZE(s3c2412_gates)); - samsung_clk_register_fixed_factor(s3c2412_ffactor, + samsung_clk_register_gate(ctx, s3c2412_gates, + ARRAY_SIZE(s3c2412_gates)); + samsung_clk_register_fixed_factor(ctx, s3c2412_ffactor, ARRAY_SIZE(s3c2412_ffactor)); - samsung_clk_register_alias(s3c2412_aliases, + samsung_clk_register_alias(ctx, s3c2412_aliases, ARRAY_SIZE(s3c2412_aliases)); s3c2412_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk-s3c2443.c b/drivers/clk/samsung/clk-s3c2443.c index 8e4f4517e95c..c4bbdabebaa4 100644 --- a/drivers/clk/samsung/clk-s3c2443.c +++ b/drivers/clk/samsung/clk-s3c2443.c @@ -365,10 +365,11 @@ struct samsung_fixed_rate_clock s3c2443_common_frate_clks[] __initdata = { FRATE(0, "ext_uart", NULL, CLK_IS_ROOT, 0), }; -static void __init s3c2443_common_clk_register_fixed_ext(unsigned long xti_f) +static void __init s3c2443_common_clk_register_fixed_ext( + struct samsung_clk_provider *ctx, unsigned long xti_f) { s3c2443_common_frate_clks[0].fixed_rate = xti_f; - samsung_clk_register_fixed_rate(s3c2443_common_frate_clks, + samsung_clk_register_fixed_rate(ctx, s3c2443_common_frate_clks, ARRAY_SIZE(s3c2443_common_frate_clks)); } @@ -376,6 +377,7 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, int current_soc, void __iomem *base) { + struct samsung_clk_provider *ctx; reg_base = base; if (np) { @@ -384,58 +386,60 @@ void __init s3c2443_common_clk_init(struct device_node *np, unsigned long xti_f, panic("%s: failed to map registers\n", __func__); } - samsung_clk_init(np, reg_base, NR_CLKS); + ctx = samsung_clk_init(np, reg_base, NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); /* Register external clocks only in non-dt cases */ if (!np) - s3c2443_common_clk_register_fixed_ext(xti_f); + s3c2443_common_clk_register_fixed_ext(ctx, xti_f); /* Register PLLs. */ if (current_soc == S3C2416 || current_soc == S3C2450) - samsung_clk_register_pll(s3c2416_pll_clks, + samsung_clk_register_pll(ctx, s3c2416_pll_clks, ARRAY_SIZE(s3c2416_pll_clks), reg_base); else - samsung_clk_register_pll(s3c2443_pll_clks, + samsung_clk_register_pll(ctx, s3c2443_pll_clks, ARRAY_SIZE(s3c2443_pll_clks), reg_base); /* Register common internal clocks. */ - samsung_clk_register_mux(s3c2443_common_muxes, + samsung_clk_register_mux(ctx, s3c2443_common_muxes, ARRAY_SIZE(s3c2443_common_muxes)); - samsung_clk_register_div(s3c2443_common_dividers, + samsung_clk_register_div(ctx, s3c2443_common_dividers, ARRAY_SIZE(s3c2443_common_dividers)); - samsung_clk_register_gate(s3c2443_common_gates, + samsung_clk_register_gate(ctx, s3c2443_common_gates, ARRAY_SIZE(s3c2443_common_gates)); - samsung_clk_register_alias(s3c2443_common_aliases, + samsung_clk_register_alias(ctx, s3c2443_common_aliases, ARRAY_SIZE(s3c2443_common_aliases)); /* Register SoC-specific clocks. */ switch (current_soc) { case S3C2450: - samsung_clk_register_div(s3c2450_dividers, + samsung_clk_register_div(ctx, s3c2450_dividers, ARRAY_SIZE(s3c2450_dividers)); - samsung_clk_register_mux(s3c2450_muxes, + samsung_clk_register_mux(ctx, s3c2450_muxes, ARRAY_SIZE(s3c2450_muxes)); - samsung_clk_register_gate(s3c2450_gates, + samsung_clk_register_gate(ctx, s3c2450_gates, ARRAY_SIZE(s3c2450_gates)); - samsung_clk_register_alias(s3c2450_aliases, + samsung_clk_register_alias(ctx, s3c2450_aliases, ARRAY_SIZE(s3c2450_aliases)); /* fall through, as s3c2450 extends the s3c2416 clocks */ case S3C2416: - samsung_clk_register_div(s3c2416_dividers, + samsung_clk_register_div(ctx, s3c2416_dividers, ARRAY_SIZE(s3c2416_dividers)); - samsung_clk_register_mux(s3c2416_muxes, + samsung_clk_register_mux(ctx, s3c2416_muxes, ARRAY_SIZE(s3c2416_muxes)); - samsung_clk_register_gate(s3c2416_gates, + samsung_clk_register_gate(ctx, s3c2416_gates, ARRAY_SIZE(s3c2416_gates)); - samsung_clk_register_alias(s3c2416_aliases, + samsung_clk_register_alias(ctx, s3c2416_aliases, ARRAY_SIZE(s3c2416_aliases)); break; case S3C2443: - samsung_clk_register_div(s3c2443_dividers, + samsung_clk_register_div(ctx, s3c2443_dividers, ARRAY_SIZE(s3c2443_dividers)); - samsung_clk_register_gate(s3c2443_gates, + samsung_clk_register_gate(ctx, s3c2443_gates, ARRAY_SIZE(s3c2443_gates)); - samsung_clk_register_alias(s3c2443_aliases, + samsung_clk_register_alias(ctx, s3c2443_aliases, ARRAY_SIZE(s3c2443_aliases)); break; } diff --git a/drivers/clk/samsung/clk-s3c64xx.c b/drivers/clk/samsung/clk-s3c64xx.c index 8bda658137a8..efa16ee592c8 100644 --- a/drivers/clk/samsung/clk-s3c64xx.c +++ b/drivers/clk/samsung/clk-s3c64xx.c @@ -442,12 +442,14 @@ static struct samsung_clock_alias s3c6410_clock_aliases[] = { ALIAS(MEM0_SROM, NULL, "srom"), }; -static void __init s3c64xx_clk_register_fixed_ext(unsigned long fin_pll_f, - unsigned long xusbxti_f) +static void __init s3c64xx_clk_register_fixed_ext( + struct samsung_clk_provider *ctx, + unsigned long fin_pll_f, + unsigned long xusbxti_f) { s3c64xx_fixed_rate_ext_clks[0].fixed_rate = fin_pll_f; s3c64xx_fixed_rate_ext_clks[1].fixed_rate = xusbxti_f; - samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_ext_clks, + samsung_clk_register_fixed_rate(ctx, s3c64xx_fixed_rate_ext_clks, ARRAY_SIZE(s3c64xx_fixed_rate_ext_clks)); } @@ -456,6 +458,8 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, unsigned long xusbxti_f, bool s3c6400, void __iomem *base) { + struct samsung_clk_provider *ctx; + reg_base = base; is_s3c6400 = s3c6400; @@ -465,48 +469,50 @@ void __init s3c64xx_clk_init(struct device_node *np, unsigned long xtal_f, panic("%s: failed to map registers\n", __func__); } - samsung_clk_init(np, reg_base, NR_CLKS); + ctx = samsung_clk_init(np, reg_base, NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); /* Register external clocks. */ if (!np) - s3c64xx_clk_register_fixed_ext(xtal_f, xusbxti_f); + s3c64xx_clk_register_fixed_ext(ctx, xtal_f, xusbxti_f); /* Register PLLs. */ - samsung_clk_register_pll(s3c64xx_pll_clks, + samsung_clk_register_pll(ctx, s3c64xx_pll_clks, ARRAY_SIZE(s3c64xx_pll_clks), reg_base); /* Register common internal clocks. */ - samsung_clk_register_fixed_rate(s3c64xx_fixed_rate_clks, + samsung_clk_register_fixed_rate(ctx, s3c64xx_fixed_rate_clks, ARRAY_SIZE(s3c64xx_fixed_rate_clks)); - samsung_clk_register_mux(s3c64xx_mux_clks, + samsung_clk_register_mux(ctx, s3c64xx_mux_clks, ARRAY_SIZE(s3c64xx_mux_clks)); - samsung_clk_register_div(s3c64xx_div_clks, + samsung_clk_register_div(ctx, s3c64xx_div_clks, ARRAY_SIZE(s3c64xx_div_clks)); - samsung_clk_register_gate(s3c64xx_gate_clks, + samsung_clk_register_gate(ctx, s3c64xx_gate_clks, ARRAY_SIZE(s3c64xx_gate_clks)); /* Register SoC-specific clocks. */ if (is_s3c6400) { - samsung_clk_register_mux(s3c6400_mux_clks, + samsung_clk_register_mux(ctx, s3c6400_mux_clks, ARRAY_SIZE(s3c6400_mux_clks)); - samsung_clk_register_div(s3c6400_div_clks, + samsung_clk_register_div(ctx, s3c6400_div_clks, ARRAY_SIZE(s3c6400_div_clks)); - samsung_clk_register_gate(s3c6400_gate_clks, + samsung_clk_register_gate(ctx, s3c6400_gate_clks, ARRAY_SIZE(s3c6400_gate_clks)); - samsung_clk_register_alias(s3c6400_clock_aliases, + samsung_clk_register_alias(ctx, s3c6400_clock_aliases, ARRAY_SIZE(s3c6400_clock_aliases)); } else { - samsung_clk_register_mux(s3c6410_mux_clks, + samsung_clk_register_mux(ctx, s3c6410_mux_clks, ARRAY_SIZE(s3c6410_mux_clks)); - samsung_clk_register_div(s3c6410_div_clks, + samsung_clk_register_div(ctx, s3c6410_div_clks, ARRAY_SIZE(s3c6410_div_clks)); - samsung_clk_register_gate(s3c6410_gate_clks, + samsung_clk_register_gate(ctx, s3c6410_gate_clks, ARRAY_SIZE(s3c6410_gate_clks)); - samsung_clk_register_alias(s3c6410_clock_aliases, + samsung_clk_register_alias(ctx, s3c6410_clock_aliases, ARRAY_SIZE(s3c6410_clock_aliases)); } - samsung_clk_register_alias(s3c64xx_clock_aliases, + samsung_clk_register_alias(ctx, s3c64xx_clock_aliases, ARRAY_SIZE(s3c64xx_clock_aliases)); s3c64xx_clk_sleep_init(); diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 91bec3ebdc8f..41c1461d2f58 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -14,13 +14,6 @@ #include #include "clk.h" -static DEFINE_SPINLOCK(lock); -static struct clk **clk_table; -static void __iomem *reg_base; -#ifdef CONFIG_OF -static struct clk_onecell_data clk_data; -#endif - void samsung_clk_save(void __iomem *base, struct samsung_clk_reg_dump *rd, unsigned int num_regs) @@ -55,40 +48,53 @@ struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( } /* setup the essentials required to support clock lookup using ccf */ -void __init samsung_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks) +struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np, + void __iomem *base, unsigned long nr_clks) { - reg_base = base; + struct samsung_clk_provider *ctx; + struct clk **clk_table; + int ret; + ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL); + if (!ctx) + panic("could not allocate clock provider context.\n"); clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); if (!clk_table) panic("could not allocate clock lookup table\n"); + ctx->reg_base = base; + ctx->clk_data.clks = clk_table; + ctx->clk_data.clk_num = nr_clks; + spin_lock_init(&ctx->lock); + if (!np) - return; + return ctx; -#ifdef CONFIG_OF - clk_data.clks = clk_table; - clk_data.clk_num = nr_clks; - of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data); -#endif + ret = of_clk_add_provider(np, of_clk_src_onecell_get, + &ctx->clk_data); + if (ret) + panic("could not register clock provide\n"); + + return ctx; } /* add a clock instance to the clock lookup table used for dt based lookup */ -void samsung_clk_add_lookup(struct clk *clk, unsigned int id) +void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, struct clk *clk, + unsigned int id) { - if (clk_table && id) - clk_table[id] = clk; + if (ctx->clk_data.clks && id) + ctx->clk_data.clks[id] = clk; } /* register a list of aliases */ -void __init samsung_clk_register_alias(struct samsung_clock_alias *list, - unsigned int nr_clk) +void __init samsung_clk_register_alias(struct samsung_clk_provider *ctx, + struct samsung_clock_alias *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; - if (!clk_table) { + if (!ctx->clk_data.clks) { pr_err("%s: clock table missing\n", __func__); return; } @@ -100,7 +106,7 @@ void __init samsung_clk_register_alias(struct samsung_clock_alias *list, continue; } - clk = clk_table[list->id]; + clk = ctx->clk_data.clks[list->id]; if (!clk) { pr_err("%s: failed to find clock %d\n", __func__, list->id); @@ -115,7 +121,7 @@ void __init samsung_clk_register_alias(struct samsung_clock_alias *list, } /* register a list of fixed clocks */ -void __init samsung_clk_register_fixed_rate( +void __init samsung_clk_register_fixed_rate(struct samsung_clk_provider *ctx, struct samsung_fixed_rate_clock *list, unsigned int nr_clk) { struct clk *clk; @@ -130,7 +136,7 @@ void __init samsung_clk_register_fixed_rate( continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); /* * Unconditionally add a clock lookup for the fixed rate clocks. @@ -144,7 +150,7 @@ void __init samsung_clk_register_fixed_rate( } /* register a list of fixed factor clocks */ -void __init samsung_clk_register_fixed_factor( +void __init samsung_clk_register_fixed_factor(struct samsung_clk_provider *ctx, struct samsung_fixed_factor_clock *list, unsigned int nr_clk) { struct clk *clk; @@ -159,28 +165,30 @@ void __init samsung_clk_register_fixed_factor( continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); } } /* register a list of mux clocks */ -void __init samsung_clk_register_mux(struct samsung_mux_clock *list, - unsigned int nr_clk) +void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, + struct samsung_mux_clock *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { clk = clk_register_mux(NULL, list->name, list->parent_names, - list->num_parents, list->flags, reg_base + list->offset, - list->shift, list->width, list->mux_flags, &lock); + list->num_parents, list->flags, + ctx->reg_base + list->offset, + list->shift, list->width, list->mux_flags, &ctx->lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); /* register a clock lookup only if a clock alias is specified */ if (list->alias) { @@ -194,8 +202,9 @@ void __init samsung_clk_register_mux(struct samsung_mux_clock *list, } /* register a list of div clocks */ -void __init samsung_clk_register_div(struct samsung_div_clock *list, - unsigned int nr_clk) +void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, + struct samsung_div_clock *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; @@ -203,22 +212,22 @@ void __init samsung_clk_register_div(struct samsung_div_clock *list, for (idx = 0; idx < nr_clk; idx++, list++) { if (list->table) clk = clk_register_divider_table(NULL, list->name, - list->parent_name, list->flags, - reg_base + list->offset, list->shift, - list->width, list->div_flags, - list->table, &lock); + list->parent_name, list->flags, + ctx->reg_base + list->offset, + list->shift, list->width, list->div_flags, + list->table, &ctx->lock); else clk = clk_register_divider(NULL, list->name, - list->parent_name, list->flags, - reg_base + list->offset, list->shift, - list->width, list->div_flags, &lock); + list->parent_name, list->flags, + ctx->reg_base + list->offset, list->shift, + list->width, list->div_flags, &ctx->lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); continue; } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); /* register a clock lookup only if a clock alias is specified */ if (list->alias) { @@ -232,16 +241,17 @@ void __init samsung_clk_register_div(struct samsung_div_clock *list, } /* register a list of gate clocks */ -void __init samsung_clk_register_gate(struct samsung_gate_clock *list, - unsigned int nr_clk) +void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, + struct samsung_gate_clock *list, + unsigned int nr_clk) { struct clk *clk; unsigned int idx, ret; for (idx = 0; idx < nr_clk; idx++, list++) { clk = clk_register_gate(NULL, list->name, list->parent_name, - list->flags, reg_base + list->offset, - list->bit_idx, list->gate_flags, &lock); + list->flags, ctx->reg_base + list->offset, + list->bit_idx, list->gate_flags, &ctx->lock); if (IS_ERR(clk)) { pr_err("%s: failed to register clock %s\n", __func__, list->name); @@ -257,7 +267,7 @@ void __init samsung_clk_register_gate(struct samsung_gate_clock *list, __func__, list->alias); } - samsung_clk_add_lookup(clk, list->id); + samsung_clk_add_lookup(ctx, clk, list->id); } } @@ -266,21 +276,21 @@ void __init samsung_clk_register_gate(struct samsung_gate_clock *list, * tree and register it */ #ifdef CONFIG_OF -void __init samsung_clk_of_register_fixed_ext( +void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, struct samsung_fixed_rate_clock *fixed_rate_clk, unsigned int nr_fixed_rate_clk, struct of_device_id *clk_matches) { const struct of_device_id *match; - struct device_node *np; + struct device_node *clk_np; u32 freq; - for_each_matching_node_and_match(np, clk_matches, &match) { - if (of_property_read_u32(np, "clock-frequency", &freq)) + for_each_matching_node_and_match(clk_np, clk_matches, &match) { + if (of_property_read_u32(clk_np, "clock-frequency", &freq)) continue; fixed_rate_clk[(u32)match->data].fixed_rate = freq; } - samsung_clk_register_fixed_rate(fixed_rate_clk, nr_fixed_rate_clk); + samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk); } #endif diff --git a/drivers/clk/samsung/clk.h b/drivers/clk/samsung/clk.h index c7141ba826e0..9693b80d924f 100644 --- a/drivers/clk/samsung/clk.h +++ b/drivers/clk/samsung/clk.h @@ -21,6 +21,18 @@ #include #include "clk-pll.h" +/** + * struct samsung_clk_provider: information about clock provider + * @reg_base: virtual address for the register base. + * @clk_data: holds clock related data like clk* and number of clocks. + * @lock: maintains exclusion bwtween callbacks for a given clock-provider. + */ +struct samsung_clk_provider { + void __iomem *reg_base; + struct clk_onecell_data clk_data; + spinlock_t lock; +}; + /** * struct samsung_clock_alias: information about mux clock * @id: platform specific id of the clock. @@ -312,40 +324,52 @@ struct samsung_pll_clock { __PLL(_typ, _id, NULL, _name, _pname, CLK_GET_RATE_NOCACHE, \ _lock, _con, _rtable, _alias) -extern void __init samsung_clk_init(struct device_node *np, void __iomem *base, - unsigned long nr_clks); +extern struct samsung_clk_provider *__init samsung_clk_init( + struct device_node *np, void __iomem *base, + unsigned long nr_clks); extern void __init samsung_clk_of_register_fixed_ext( - struct samsung_fixed_rate_clock *fixed_rate_clk, - unsigned int nr_fixed_rate_clk, - struct of_device_id *clk_matches); + struct samsung_clk_provider *ctx, + struct samsung_fixed_rate_clock *fixed_rate_clk, + unsigned int nr_fixed_rate_clk, + struct of_device_id *clk_matches); -extern void samsung_clk_add_lookup(struct clk *clk, unsigned int id); +extern void samsung_clk_add_lookup(struct samsung_clk_provider *ctx, + struct clk *clk, unsigned int id); -extern void samsung_clk_register_alias(struct samsung_clock_alias *list, - unsigned int nr_clk); +extern void samsung_clk_register_alias(struct samsung_clk_provider *ctx, + struct samsung_clock_alias *list, + unsigned int nr_clk); extern void __init samsung_clk_register_fixed_rate( - struct samsung_fixed_rate_clock *clk_list, unsigned int nr_clk); + struct samsung_clk_provider *ctx, + struct samsung_fixed_rate_clock *clk_list, + unsigned int nr_clk); extern void __init samsung_clk_register_fixed_factor( - struct samsung_fixed_factor_clock *list, unsigned int nr_clk); -extern void __init samsung_clk_register_mux(struct samsung_mux_clock *clk_list, - unsigned int nr_clk); -extern void __init samsung_clk_register_div(struct samsung_div_clock *clk_list, - unsigned int nr_clk); -extern void __init samsung_clk_register_gate( - struct samsung_gate_clock *clk_list, unsigned int nr_clk); -extern void __init samsung_clk_register_pll(struct samsung_pll_clock *pll_list, - unsigned int nr_clk, void __iomem *base); + struct samsung_clk_provider *ctx, + struct samsung_fixed_factor_clock *list, + unsigned int nr_clk); +extern void __init samsung_clk_register_mux(struct samsung_clk_provider *ctx, + struct samsung_mux_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_div(struct samsung_clk_provider *ctx, + struct samsung_div_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_gate(struct samsung_clk_provider *ctx, + struct samsung_gate_clock *clk_list, + unsigned int nr_clk); +extern void __init samsung_clk_register_pll(struct samsung_clk_provider *ctx, + struct samsung_pll_clock *pll_list, + unsigned int nr_clk, void __iomem *base); extern unsigned long _get_rate(const char *clk_name); extern void samsung_clk_save(void __iomem *base, - struct samsung_clk_reg_dump *rd, - unsigned int num_regs); + struct samsung_clk_reg_dump *rd, + unsigned int num_regs); extern void samsung_clk_restore(void __iomem *base, - const struct samsung_clk_reg_dump *rd, - unsigned int num_regs); + const struct samsung_clk_reg_dump *rd, + unsigned int num_regs); extern struct samsung_clk_reg_dump *samsung_clk_alloc_reg_dump( - const unsigned long *rdump, - unsigned long nr_rdump); + const unsigned long *rdump, + unsigned long nr_rdump); #endif /* __SAMSUNG_CLK_H */ -- cgit v1.2.2 From 8432984732b59b333706fceb4cfb5123140be827 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Wed, 12 Mar 2014 20:26:45 +0530 Subject: clk/samsung: add support for pll2550xx exynos5260 use pll2550xx and it has different bit fields for P,M,S values as compared to pll2550. Support for pll2550xx is added here. Signed-off-by: Pankaj Dubey Signed-off-by: Rahul Sharma Signed-off-by: Arun Kumar K Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-pll.c | 108 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h | 1 + 2 files changed, 109 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 1f310be17742..18e42ef56ea6 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -947,6 +947,108 @@ struct clk * __init samsung_clk_register_pll2550x(const char *name, return clk; } +/* + * PLL2550xx Clock Type + */ + +/* Maximum lock time can be 270 * PDIV cycles */ +#define PLL2550XX_LOCK_FACTOR 270 + +#define PLL2550XX_M_MASK 0x3FF +#define PLL2550XX_P_MASK 0x3F +#define PLL2550XX_S_MASK 0x7 +#define PLL2550XX_LOCK_STAT_MASK 0x1 +#define PLL2550XX_M_SHIFT 9 +#define PLL2550XX_P_SHIFT 3 +#define PLL2550XX_S_SHIFT 0 +#define PLL2550XX_LOCK_STAT_SHIFT 21 + +static unsigned long samsung_pll2550xx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 mdiv, pdiv, sdiv, pll_con; + u64 fvco = parent_rate; + + pll_con = __raw_readl(pll->con_reg); + mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK; + pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK; + sdiv = (pll_con >> PLL2550XX_S_SHIFT) & PLL2550XX_S_MASK; + + fvco *= mdiv; + do_div(fvco, (pdiv << sdiv)); + + return (unsigned long)fvco; +} + +static inline bool samsung_pll2550xx_mp_change(u32 mdiv, u32 pdiv, u32 pll_con) +{ + u32 old_mdiv, old_pdiv; + + old_mdiv = (pll_con >> PLL2550XX_M_SHIFT) & PLL2550XX_M_MASK; + old_pdiv = (pll_con >> PLL2550XX_P_SHIFT) & PLL2550XX_P_MASK; + + return mdiv != old_mdiv || pdiv != old_pdiv; +} + +static int samsung_pll2550xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long prate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + const struct samsung_pll_rate_table *rate; + u32 tmp; + + /* Get required rate settings from table */ + rate = samsung_get_pll_settings(pll, drate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, + drate, __clk_get_name(hw->clk)); + return -EINVAL; + } + + tmp = __raw_readl(pll->con_reg); + + if (!(samsung_pll2550xx_mp_change(rate->mdiv, rate->pdiv, tmp))) { + /* If only s change, change just s value only*/ + tmp &= ~(PLL2550XX_S_MASK << PLL2550XX_S_SHIFT); + tmp |= rate->sdiv << PLL2550XX_S_SHIFT; + __raw_writel(tmp, pll->con_reg); + + return 0; + } + + /* Set PLL lock time. */ + __raw_writel(rate->pdiv * PLL2550XX_LOCK_FACTOR, pll->lock_reg); + + /* Change PLL PMS values */ + tmp &= ~((PLL2550XX_M_MASK << PLL2550XX_M_SHIFT) | + (PLL2550XX_P_MASK << PLL2550XX_P_SHIFT) | + (PLL2550XX_S_MASK << PLL2550XX_S_SHIFT)); + tmp |= (rate->mdiv << PLL2550XX_M_SHIFT) | + (rate->pdiv << PLL2550XX_P_SHIFT) | + (rate->sdiv << PLL2550XX_S_SHIFT); + __raw_writel(tmp, pll->con_reg); + + /* wait_lock_time */ + do { + cpu_relax(); + tmp = __raw_readl(pll->con_reg); + } while (!(tmp & (PLL2550XX_LOCK_STAT_MASK + << PLL2550XX_LOCK_STAT_SHIFT))); + + return 0; +} + +static const struct clk_ops samsung_pll2550xx_clk_ops = { + .recalc_rate = samsung_pll2550xx_recalc_rate, + .round_rate = samsung_pll_round_rate, + .set_rate = samsung_pll2550xx_set_rate, +}; + +static const struct clk_ops samsung_pll2550xx_clk_min_ops = { + .recalc_rate = samsung_pll2550xx_recalc_rate, +}; + static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, struct samsung_pll_clock *pll_clk, void __iomem *base) @@ -1049,6 +1151,12 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = &samsung_s3c2440_mpll_clk_ops; break; + case pll_2550xx: + if (!pll->rate_table) + init.ops = &samsung_pll2550xx_clk_min_ops; + else + init.ops = &samsung_pll2550xx_clk_ops; + break; default: pr_warn("%s: Unknown pll type for pll clk %s\n", __func__, pll_clk->name); diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index 6428bcc6df6f..ec4bc1d45e31 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -31,6 +31,7 @@ enum samsung_pll_type { pll_s3c2410_mpll, pll_s3c2410_upll, pll_s3c2440_mpll, + pll_2550xx, }; #define PLL_35XX_RATE(_rate, _m, _p, _s) \ -- cgit v1.2.2 From eefe119b81eb1afb6e815818ad119cdd2d442fd3 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Wed, 12 Mar 2014 20:26:46 +0530 Subject: clk/samsung: add support for pll2650xx Add support for pll2650xx in samsung pll file. This PLL variant is close to pll36xx but uses CON2 registers instead of CON1. Aud_pll in Exynos5260 is pll2650xx and uses this code. Signed-off-by: Rahul Sharma Reviewed-by: Pankaj Dubey Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-pll.c | 101 ++++++++++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-pll.h | 1 + 2 files changed, 102 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-pll.c b/drivers/clk/samsung/clk-pll.c index 18e42ef56ea6..b07fad2a9167 100644 --- a/drivers/clk/samsung/clk-pll.c +++ b/drivers/clk/samsung/clk-pll.c @@ -1049,6 +1049,101 @@ static const struct clk_ops samsung_pll2550xx_clk_min_ops = { .recalc_rate = samsung_pll2550xx_recalc_rate, }; +/* + * PLL2650XX Clock Type + */ + +/* Maximum lock time can be 3000 * PDIV cycles */ +#define PLL2650XX_LOCK_FACTOR 3000 + +#define PLL2650XX_MDIV_SHIFT 9 +#define PLL2650XX_PDIV_SHIFT 3 +#define PLL2650XX_SDIV_SHIFT 0 +#define PLL2650XX_KDIV_SHIFT 0 +#define PLL2650XX_MDIV_MASK 0x1ff +#define PLL2650XX_PDIV_MASK 0x3f +#define PLL2650XX_SDIV_MASK 0x7 +#define PLL2650XX_KDIV_MASK 0xffff +#define PLL2650XX_PLL_ENABLE_SHIFT 23 +#define PLL2650XX_PLL_LOCKTIME_SHIFT 21 +#define PLL2650XX_PLL_FOUTMASK_SHIFT 31 + +static unsigned long samsung_pll2650xx_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 mdiv, pdiv, sdiv, pll_con0, pll_con2; + s16 kdiv; + u64 fvco = parent_rate; + + pll_con0 = __raw_readl(pll->con_reg); + pll_con2 = __raw_readl(pll->con_reg + 8); + mdiv = (pll_con0 >> PLL2650XX_MDIV_SHIFT) & PLL2650XX_MDIV_MASK; + pdiv = (pll_con0 >> PLL2650XX_PDIV_SHIFT) & PLL2650XX_PDIV_MASK; + sdiv = (pll_con0 >> PLL2650XX_SDIV_SHIFT) & PLL2650XX_SDIV_MASK; + kdiv = (s16)(pll_con2 & PLL2650XX_KDIV_MASK); + + fvco *= (mdiv << 16) + kdiv; + do_div(fvco, (pdiv << sdiv)); + fvco >>= 16; + + return (unsigned long)fvco; +} + +static int samsung_pll2650xx_set_rate(struct clk_hw *hw, unsigned long drate, + unsigned long parent_rate) +{ + struct samsung_clk_pll *pll = to_clk_pll(hw); + u32 tmp, pll_con0, pll_con2; + const struct samsung_pll_rate_table *rate; + + rate = samsung_get_pll_settings(pll, drate); + if (!rate) { + pr_err("%s: Invalid rate : %lu for pll clk %s\n", __func__, + drate, __clk_get_name(hw->clk)); + return -EINVAL; + } + + pll_con0 = __raw_readl(pll->con_reg); + pll_con2 = __raw_readl(pll->con_reg + 8); + + /* Change PLL PMS values */ + pll_con0 &= ~(PLL2650XX_MDIV_MASK << PLL2650XX_MDIV_SHIFT | + PLL2650XX_PDIV_MASK << PLL2650XX_PDIV_SHIFT | + PLL2650XX_SDIV_MASK << PLL2650XX_SDIV_SHIFT); + pll_con0 |= rate->mdiv << PLL2650XX_MDIV_SHIFT; + pll_con0 |= rate->pdiv << PLL2650XX_PDIV_SHIFT; + pll_con0 |= rate->sdiv << PLL2650XX_SDIV_SHIFT; + pll_con0 |= 1 << PLL2650XX_PLL_ENABLE_SHIFT; + pll_con0 |= 1 << PLL2650XX_PLL_FOUTMASK_SHIFT; + + pll_con2 &= ~(PLL2650XX_KDIV_MASK << PLL2650XX_KDIV_SHIFT); + pll_con2 |= ((~(rate->kdiv) + 1) & PLL2650XX_KDIV_MASK) + << PLL2650XX_KDIV_SHIFT; + + /* Set PLL lock time. */ + __raw_writel(PLL2650XX_LOCK_FACTOR * rate->pdiv, pll->lock_reg); + + __raw_writel(pll_con0, pll->con_reg); + __raw_writel(pll_con2, pll->con_reg + 8); + + do { + tmp = __raw_readl(pll->con_reg); + } while (!(tmp & (0x1 << PLL2650XX_PLL_LOCKTIME_SHIFT))); + + return 0; +} + +static const struct clk_ops samsung_pll2650xx_clk_ops = { + .recalc_rate = samsung_pll2650xx_recalc_rate, + .set_rate = samsung_pll2650xx_set_rate, + .round_rate = samsung_pll_round_rate, +}; + +static const struct clk_ops samsung_pll2650xx_clk_min_ops = { + .recalc_rate = samsung_pll2650xx_recalc_rate, +}; + static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, struct samsung_pll_clock *pll_clk, void __iomem *base) @@ -1157,6 +1252,12 @@ static void __init _samsung_clk_register_pll(struct samsung_clk_provider *ctx, else init.ops = &samsung_pll2550xx_clk_ops; break; + case pll_2650xx: + if (!pll->rate_table) + init.ops = &samsung_pll2650xx_clk_min_ops; + else + init.ops = &samsung_pll2650xx_clk_ops; + break; default: pr_warn("%s: Unknown pll type for pll clk %s\n", __func__, pll_clk->name); diff --git a/drivers/clk/samsung/clk-pll.h b/drivers/clk/samsung/clk-pll.h index ec4bc1d45e31..c0ed4d41fd90 100644 --- a/drivers/clk/samsung/clk-pll.h +++ b/drivers/clk/samsung/clk-pll.h @@ -32,6 +32,7 @@ enum samsung_pll_type { pll_s3c2410_upll, pll_s3c2440_mpll, pll_2550xx, + pll_2650xx, }; #define PLL_35XX_RATE(_rate, _m, _p, _s) \ -- cgit v1.2.2 From d39e55e06371c1ba9d11f4a17a56a0f925d12415 Mon Sep 17 00:00:00 2001 From: Rahul Sharma Date: Mon, 24 Mar 2014 02:15:54 +0530 Subject: clk/exynos5260: add clock file for exynos5260 Add support for exynos5260 clocks in clock driver. Signed-off-by: Rahul Sharma Signed-off-by: Pankaj Dubey Signed-off-by: Tomasz Figa --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos5260.c | 1980 ++++++++++++++++++++++++++++++++++ drivers/clk/samsung/clk-exynos5260.h | 459 ++++++++ 3 files changed, 2440 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5260.c create mode 100644 drivers/clk/samsung/clk-exynos5260.h (limited to 'drivers') diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 2cb62f87e068..916049472ba3 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -5,6 +5,7 @@ obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o +obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o diff --git a/drivers/clk/samsung/clk-exynos5260.c b/drivers/clk/samsung/clk-exynos5260.c new file mode 100644 index 000000000000..64596ba58df1 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5260.c @@ -0,0 +1,1980 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Rahul Sharma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Common Clock Framework support for Exynos5260 SoC. + */ + +#include +#include +#include +#include +#include +#include + +#include "clk-exynos5260.h" +#include "clk.h" +#include "clk-pll.h" + +#include + +static LIST_HEAD(clock_reg_cache_list); + +struct exynos5260_clock_reg_cache { + struct list_head node; + void __iomem *reg_base; + struct samsung_clk_reg_dump *rdump; + unsigned int rd_num; +}; + +struct exynos5260_cmu_info { + /* list of pll clocks and respective count */ + struct samsung_pll_clock *pll_clks; + unsigned int nr_pll_clks; + /* list of mux clocks and respective count */ + struct samsung_mux_clock *mux_clks; + unsigned int nr_mux_clks; + /* list of div clocks and respective count */ + struct samsung_div_clock *div_clks; + unsigned int nr_div_clks; + /* list of gate clocks and respective count */ + struct samsung_gate_clock *gate_clks; + unsigned int nr_gate_clks; + /* list of fixed clocks and respective count */ + struct samsung_fixed_rate_clock *fixed_clks; + unsigned int nr_fixed_clks; + /* total number of clocks with IDs assigned*/ + unsigned int nr_clk_ids; + + /* list and number of clocks registers */ + unsigned long *clk_regs; + unsigned int nr_clk_regs; +}; + +/* + * Applicable for all 2550 Type PLLS for Exynos5260, listed below + * DISP_PLL, EGL_PLL, KFC_PLL, MEM_PLL, BUS_PLL, MEDIA_PLL, G3D_PLL. + */ +static struct samsung_pll_rate_table pll2550_24mhz_tbl[] __initdata = { + PLL_35XX_RATE(1700000000, 425, 6, 0), + PLL_35XX_RATE(1600000000, 200, 3, 0), + PLL_35XX_RATE(1500000000, 250, 4, 0), + PLL_35XX_RATE(1400000000, 175, 3, 0), + PLL_35XX_RATE(1300000000, 325, 6, 0), + PLL_35XX_RATE(1200000000, 400, 4, 1), + PLL_35XX_RATE(1100000000, 275, 3, 1), + PLL_35XX_RATE(1000000000, 250, 3, 1), + PLL_35XX_RATE(933000000, 311, 4, 1), + PLL_35XX_RATE(900000000, 300, 4, 1), + PLL_35XX_RATE(800000000, 200, 3, 1), + PLL_35XX_RATE(733000000, 733, 12, 1), + PLL_35XX_RATE(700000000, 175, 3, 1), + PLL_35XX_RATE(667000000, 667, 12, 1), + PLL_35XX_RATE(633000000, 211, 4, 1), + PLL_35XX_RATE(620000000, 310, 3, 2), + PLL_35XX_RATE(600000000, 400, 4, 2), + PLL_35XX_RATE(543000000, 362, 4, 2), + PLL_35XX_RATE(533000000, 533, 6, 2), + PLL_35XX_RATE(500000000, 250, 3, 2), + PLL_35XX_RATE(450000000, 300, 4, 2), + PLL_35XX_RATE(400000000, 200, 3, 2), + PLL_35XX_RATE(350000000, 175, 3, 2), + PLL_35XX_RATE(300000000, 400, 4, 3), + PLL_35XX_RATE(266000000, 266, 3, 3), + PLL_35XX_RATE(200000000, 200, 3, 3), + PLL_35XX_RATE(160000000, 160, 3, 3), +}; + +/* + * Applicable for 2650 Type PLL for AUD_PLL. + */ +static struct samsung_pll_rate_table pll2650_24mhz_tbl[] __initdata = { + PLL_36XX_RATE(1600000000, 200, 3, 0, 0), + PLL_36XX_RATE(1200000000, 100, 2, 0, 0), + PLL_36XX_RATE(1000000000, 250, 3, 1, 0), + PLL_36XX_RATE(800000000, 200, 3, 1, 0), + PLL_36XX_RATE(600000000, 100, 2, 1, 0), + PLL_36XX_RATE(532000000, 266, 3, 2, 0), + PLL_36XX_RATE(480000000, 160, 2, 2, 0), + PLL_36XX_RATE(432000000, 144, 2, 2, 0), + PLL_36XX_RATE(400000000, 200, 3, 2, 0), + PLL_36XX_RATE(394073130, 459, 7, 2, 49282), + PLL_36XX_RATE(333000000, 111, 2, 2, 0), + PLL_36XX_RATE(300000000, 100, 2, 2, 0), + PLL_36XX_RATE(266000000, 266, 3, 3, 0), + PLL_36XX_RATE(200000000, 200, 3, 3, 0), + PLL_36XX_RATE(166000000, 166, 3, 3, 0), + PLL_36XX_RATE(133000000, 266, 3, 4, 0), + PLL_36XX_RATE(100000000, 200, 3, 4, 0), + PLL_36XX_RATE(66000000, 176, 2, 5, 0), +}; + +#ifdef CONFIG_PM_SLEEP + +static int exynos5260_clk_suspend(void) +{ + struct exynos5260_clock_reg_cache *cache; + + list_for_each_entry(cache, &clock_reg_cache_list, node) + samsung_clk_save(cache->reg_base, cache->rdump, + cache->rd_num); + + return 0; +} + +static void exynos5260_clk_resume(void) +{ + struct exynos5260_clock_reg_cache *cache; + + list_for_each_entry(cache, &clock_reg_cache_list, node) + samsung_clk_restore(cache->reg_base, cache->rdump, + cache->rd_num); +} + +static struct syscore_ops exynos5260_clk_syscore_ops = { + .suspend = exynos5260_clk_suspend, + .resume = exynos5260_clk_resume, +}; + +static void exynos5260_clk_sleep_init(void __iomem *reg_base, + unsigned long *rdump, + unsigned long nr_rdump) +{ + struct exynos5260_clock_reg_cache *reg_cache; + + reg_cache = kzalloc(sizeof(struct exynos5260_clock_reg_cache), + GFP_KERNEL); + if (!reg_cache) + panic("could not allocate register cache.\n"); + + reg_cache->rdump = samsung_clk_alloc_reg_dump(rdump, nr_rdump); + + if (!reg_cache->rdump) + panic("could not allocate register dump storage.\n"); + + if (list_empty(&clock_reg_cache_list)) + register_syscore_ops(&exynos5260_clk_syscore_ops); + + reg_cache->rd_num = nr_rdump; + reg_cache->reg_base = reg_base; + list_add_tail(®_cache->node, &clock_reg_cache_list); +} + +#else +static void exynos5260_clk_sleep_init(void __iomem *reg_base, + unsigned long *rdump, + unsigned long nr_rdump){} +#endif + +/* + * Common function which registers plls, muxes, dividers and gates + * for each CMU. It also add CMU register list to register cache. + */ + +void __init exynos5260_cmu_register_one(struct device_node *np, + struct exynos5260_cmu_info *cmu) +{ + void __iomem *reg_base; + struct samsung_clk_provider *ctx; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + ctx = samsung_clk_init(np, reg_base, cmu->nr_clk_ids); + if (!ctx) + panic("%s: unable to alllocate ctx\n", __func__); + + if (cmu->pll_clks) + samsung_clk_register_pll(ctx, cmu->pll_clks, cmu->nr_pll_clks, + reg_base); + if (cmu->mux_clks) + samsung_clk_register_mux(ctx, cmu->mux_clks, + cmu->nr_mux_clks); + if (cmu->div_clks) + samsung_clk_register_div(ctx, cmu->div_clks, cmu->nr_div_clks); + if (cmu->gate_clks) + samsung_clk_register_gate(ctx, cmu->gate_clks, + cmu->nr_gate_clks); + if (cmu->fixed_clks) + samsung_clk_register_fixed_rate(ctx, cmu->fixed_clks, + cmu->nr_fixed_clks); + if (cmu->clk_regs) + exynos5260_clk_sleep_init(reg_base, cmu->clk_regs, + cmu->nr_clk_regs); +} + + +/* CMU_AUD */ + +static unsigned long aud_clk_regs[] __initdata = { + MUX_SEL_AUD, + DIV_AUD0, + DIV_AUD1, + EN_ACLK_AUD, + EN_PCLK_AUD, + EN_SCLK_AUD, + EN_IP_AUD, +}; + +PNAME(mout_aud_pll_user_p) = {"fin_pll", "fout_aud_pll"}; +PNAME(mout_sclk_aud_i2s_p) = {"mout_aud_pll_user", "ioclk_i2s_cdclk"}; +PNAME(mout_sclk_aud_pcm_p) = {"mout_aud_pll_user", "ioclk_pcm_extclk"}; + +struct samsung_mux_clock aud_mux_clks[] __initdata = { + MUX(AUD_MOUT_AUD_PLL_USER, "mout_aud_pll_user", mout_aud_pll_user_p, + MUX_SEL_AUD, 0, 1), + MUX(AUD_MOUT_SCLK_AUD_I2S, "mout_sclk_aud_i2s", mout_sclk_aud_i2s_p, + MUX_SEL_AUD, 4, 1), + MUX(AUD_MOUT_SCLK_AUD_PCM, "mout_sclk_aud_pcm", mout_sclk_aud_pcm_p, + MUX_SEL_AUD, 8, 1), +}; + +struct samsung_div_clock aud_div_clks[] __initdata = { + DIV(AUD_DOUT_ACLK_AUD_131, "dout_aclk_aud_131", "mout_aud_pll_user", + DIV_AUD0, 0, 4), + + DIV(AUD_DOUT_SCLK_AUD_I2S, "dout_sclk_aud_i2s", "mout_sclk_aud_i2s", + DIV_AUD1, 0, 4), + DIV(AUD_DOUT_SCLK_AUD_PCM, "dout_sclk_aud_pcm", "mout_sclk_aud_pcm", + DIV_AUD1, 4, 8), + DIV(AUD_DOUT_SCLK_AUD_UART, "dout_sclk_aud_uart", "mout_aud_pll_user", + DIV_AUD1, 12, 4), +}; + +struct samsung_gate_clock aud_gate_clks[] __initdata = { + GATE(AUD_SCLK_I2S, "sclk_aud_i2s", "dout_sclk_aud_i2s", + EN_SCLK_AUD, 0, CLK_SET_RATE_PARENT, 0), + GATE(AUD_SCLK_PCM, "sclk_aud_pcm", "dout_sclk_aud_pcm", + EN_SCLK_AUD, 1, CLK_SET_RATE_PARENT, 0), + GATE(AUD_SCLK_AUD_UART, "sclk_aud_uart", "dout_sclk_aud_uart", + EN_SCLK_AUD, 2, CLK_SET_RATE_PARENT, 0), + + GATE(AUD_CLK_SRAMC, "clk_sramc", "dout_aclk_aud_131", EN_IP_AUD, + 0, 0, 0), + GATE(AUD_CLK_DMAC, "clk_dmac", "dout_aclk_aud_131", + EN_IP_AUD, 1, 0, 0), + GATE(AUD_CLK_I2S, "clk_i2s", "dout_aclk_aud_131", EN_IP_AUD, 2, 0, 0), + GATE(AUD_CLK_PCM, "clk_pcm", "dout_aclk_aud_131", EN_IP_AUD, 3, 0, 0), + GATE(AUD_CLK_AUD_UART, "clk_aud_uart", "dout_aclk_aud_131", + EN_IP_AUD, 4, 0, 0), +}; + +static void __init exynos5260_clk_aud_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = aud_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(aud_mux_clks); + cmu.div_clks = aud_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(aud_div_clks); + cmu.gate_clks = aud_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(aud_gate_clks); + cmu.nr_clk_ids = AUD_NR_CLK; + cmu.clk_regs = aud_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(aud_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_aud, "samsung,exynos5260-clock-aud", + exynos5260_clk_aud_init); + + +/* CMU_DISP */ + +static unsigned long disp_clk_regs[] __initdata = { + MUX_SEL_DISP0, + MUX_SEL_DISP1, + MUX_SEL_DISP2, + MUX_SEL_DISP3, + MUX_SEL_DISP4, + DIV_DISP, + EN_ACLK_DISP, + EN_PCLK_DISP, + EN_SCLK_DISP0, + EN_SCLK_DISP1, + EN_IP_DISP, + EN_IP_DISP_BUS, +}; + +PNAME(mout_phyclk_dptx_phy_ch3_txd_clk_user_p) = {"fin_pll", + "phyclk_dptx_phy_ch3_txd_clk"}; +PNAME(mout_phyclk_dptx_phy_ch2_txd_clk_user_p) = {"fin_pll", + "phyclk_dptx_phy_ch2_txd_clk"}; +PNAME(mout_phyclk_dptx_phy_ch1_txd_clk_user_p) = {"fin_pll", + "phyclk_dptx_phy_ch1_txd_clk"}; +PNAME(mout_phyclk_dptx_phy_ch0_txd_clk_user_p) = {"fin_pll", + "phyclk_dptx_phy_ch0_txd_clk"}; +PNAME(mout_aclk_disp_222_user_p) = {"fin_pll", "dout_aclk_disp_222"}; +PNAME(mout_sclk_disp_pixel_user_p) = {"fin_pll", "dout_sclk_disp_pixel"}; +PNAME(mout_aclk_disp_333_user_p) = {"fin_pll", "dout_aclk_disp_333"}; +PNAME(mout_phyclk_hdmi_phy_tmds_clko_user_p) = {"fin_pll", + "phyclk_hdmi_phy_tmds_clko"}; +PNAME(mout_phyclk_hdmi_phy_ref_clko_user_p) = {"fin_pll", + "phyclk_hdmi_phy_ref_clko"}; +PNAME(mout_phyclk_hdmi_phy_pixel_clko_user_p) = {"fin_pll", + "phyclk_hdmi_phy_pixel_clko"}; +PNAME(mout_phyclk_hdmi_link_o_tmds_clkhi_user_p) = {"fin_pll", + "phyclk_hdmi_link_o_tmds_clkhi"}; +PNAME(mout_phyclk_mipi_dphy_4l_m_txbyte_clkhs_p) = {"fin_pll", + "phyclk_mipi_dphy_4l_m_txbyte_clkhs"}; +PNAME(mout_phyclk_dptx_phy_o_ref_clk_24m_user_p) = {"fin_pll", + "phyclk_dptx_phy_o_ref_clk_24m"}; +PNAME(mout_phyclk_dptx_phy_clk_div2_user_p) = {"fin_pll", + "phyclk_dptx_phy_clk_div2"}; +PNAME(mout_sclk_hdmi_pixel_p) = {"mout_sclk_disp_pixel_user", + "mout_aclk_disp_222_user"}; +PNAME(mout_phyclk_mipi_dphy_4lmrxclk_esc0_user_p) = {"fin_pll", + "phyclk_mipi_dphy_4l_m_rxclkesc0"}; +PNAME(mout_sclk_hdmi_spdif_p) = {"fin_pll", "ioclk_spdif_extclk", + "dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"}; + +struct samsung_mux_clock disp_mux_clks[] __initdata = { + MUX(DISP_MOUT_ACLK_DISP_333_USER, "mout_aclk_disp_333_user", + mout_aclk_disp_333_user_p, + MUX_SEL_DISP0, 0, 1), + MUX(DISP_MOUT_SCLK_DISP_PIXEL_USER, "mout_sclk_disp_pixel_user", + mout_sclk_disp_pixel_user_p, + MUX_SEL_DISP0, 4, 1), + MUX(DISP_MOUT_ACLK_DISP_222_USER, "mout_aclk_disp_222_user", + mout_aclk_disp_222_user_p, + MUX_SEL_DISP0, 8, 1), + MUX(DISP_MOUT_PHYCLK_DPTX_PHY_CH0_TXD_CLK_USER, + "mout_phyclk_dptx_phy_ch0_txd_clk_user", + mout_phyclk_dptx_phy_ch0_txd_clk_user_p, + MUX_SEL_DISP0, 16, 1), + MUX(DISP_MOUT_PHYCLK_DPTX_PHY_CH1_TXD_CLK_USER, + "mout_phyclk_dptx_phy_ch1_txd_clk_user", + mout_phyclk_dptx_phy_ch1_txd_clk_user_p, + MUX_SEL_DISP0, 20, 1), + MUX(DISP_MOUT_PHYCLK_DPTX_PHY_CH2_TXD_CLK_USER, + "mout_phyclk_dptx_phy_ch2_txd_clk_user", + mout_phyclk_dptx_phy_ch2_txd_clk_user_p, + MUX_SEL_DISP0, 24, 1), + MUX(DISP_MOUT_PHYCLK_DPTX_PHY_CH3_TXD_CLK_USER, + "mout_phyclk_dptx_phy_ch3_txd_clk_user", + mout_phyclk_dptx_phy_ch3_txd_clk_user_p, + MUX_SEL_DISP0, 28, 1), + + MUX(DISP_MOUT_PHYCLK_DPTX_PHY_CLK_DIV2_USER, + "mout_phyclk_dptx_phy_clk_div2_user", + mout_phyclk_dptx_phy_clk_div2_user_p, + MUX_SEL_DISP1, 0, 1), + MUX(DISP_MOUT_PHYCLK_DPTX_PHY_O_REF_CLK_24M_USER, + "mout_phyclk_dptx_phy_o_ref_clk_24m_user", + mout_phyclk_dptx_phy_o_ref_clk_24m_user_p, + MUX_SEL_DISP1, 4, 1), + MUX(DISP_MOUT_PHYCLK_MIPI_DPHY_4L_M_TXBYTE_CLKHS, + "mout_phyclk_mipi_dphy_4l_m_txbyte_clkhs", + mout_phyclk_mipi_dphy_4l_m_txbyte_clkhs_p, + MUX_SEL_DISP1, 8, 1), + MUX(DISP_MOUT_PHYCLK_HDMI_LINK_O_TMDS_CLKHI_USER, + "mout_phyclk_hdmi_link_o_tmds_clkhi_user", + mout_phyclk_hdmi_link_o_tmds_clkhi_user_p, + MUX_SEL_DISP1, 16, 1), + MUX(DISP_MOUT_HDMI_PHY_PIXEL, + "mout_phyclk_hdmi_phy_pixel_clko_user", + mout_phyclk_hdmi_phy_pixel_clko_user_p, + MUX_SEL_DISP1, 20, 1), + MUX(DISP_MOUT_PHYCLK_HDMI_PHY_REF_CLKO_USER, + "mout_phyclk_hdmi_phy_ref_clko_user", + mout_phyclk_hdmi_phy_ref_clko_user_p, + MUX_SEL_DISP1, 24, 1), + MUX(DISP_MOUT_PHYCLK_HDMI_PHY_TMDS_CLKO_USER, + "mout_phyclk_hdmi_phy_tmds_clko_user", + mout_phyclk_hdmi_phy_tmds_clko_user_p, + MUX_SEL_DISP1, 28, 1), + + MUX(DISP_MOUT_PHYCLK_MIPI_DPHY_4LMRXCLK_ESC0_USER, + "mout_phyclk_mipi_dphy_4lmrxclk_esc0_user", + mout_phyclk_mipi_dphy_4lmrxclk_esc0_user_p, + MUX_SEL_DISP2, 0, 1), + MUX(DISP_MOUT_SCLK_HDMI_PIXEL, "mout_sclk_hdmi_pixel", + mout_sclk_hdmi_pixel_p, + MUX_SEL_DISP2, 4, 1), + + MUX(DISP_MOUT_SCLK_HDMI_SPDIF, "mout_sclk_hdmi_spdif", + mout_sclk_hdmi_spdif_p, + MUX_SEL_DISP4, 4, 2), +}; + +struct samsung_div_clock disp_div_clks[] __initdata = { + DIV(DISP_DOUT_PCLK_DISP_111, "dout_pclk_disp_111", + "mout_aclk_disp_222_user", + DIV_DISP, 8, 4), + DIV(DISP_DOUT_SCLK_FIMD1_EXTCLKPLL, "dout_sclk_fimd1_extclkpll", + "mout_sclk_disp_pixel_user", + DIV_DISP, 12, 4), + DIV(DISP_DOUT_SCLK_HDMI_PHY_PIXEL_CLKI, + "dout_sclk_hdmi_phy_pixel_clki", + "mout_sclk_hdmi_pixel", + DIV_DISP, 16, 4), +}; + +struct samsung_gate_clock disp_gate_clks[] __initdata = { + GATE(DISP_MOUT_HDMI_PHY_PIXEL_USER, "sclk_hdmi_link_i_pixel", + "mout_phyclk_hdmi_phy_pixel_clko_user", + EN_SCLK_DISP0, 26, CLK_SET_RATE_PARENT, 0), + GATE(DISP_SCLK_PIXEL, "sclk_hdmi_phy_pixel_clki", + "dout_sclk_hdmi_phy_pixel_clki", + EN_SCLK_DISP0, 29, CLK_SET_RATE_PARENT, 0), + + GATE(DISP_CLK_DP, "clk_dptx_link", "mout_aclk_disp_222_user", + EN_IP_DISP, 4, 0, 0), + GATE(DISP_CLK_DPPHY, "clk_dptx_phy", "mout_aclk_disp_222_user", + EN_IP_DISP, 5, 0, 0), + GATE(DISP_CLK_DSIM1, "clk_dsim1", "mout_aclk_disp_222_user", + EN_IP_DISP, 6, 0, 0), + GATE(DISP_CLK_FIMD1, "clk_fimd1", "mout_aclk_disp_222_user", + EN_IP_DISP, 7, 0, 0), + GATE(DISP_CLK_HDMI, "clk_hdmi", "mout_aclk_disp_222_user", + EN_IP_DISP, 8, 0, 0), + GATE(DISP_CLK_HDMIPHY, "clk_hdmiphy", "mout_aclk_disp_222_user", + EN_IP_DISP, 9, 0, 0), + GATE(DISP_CLK_MIPIPHY, "clk_mipi_dphy", "mout_aclk_disp_222_user", + EN_IP_DISP, 10, 0, 0), + GATE(DISP_CLK_MIXER, "clk_mixer", "mout_aclk_disp_222_user", + EN_IP_DISP, 11, 0, 0), + GATE(DISP_CLK_PIXEL_DISP, "clk_pixel_disp", "mout_aclk_disp_222_user", + EN_IP_DISP, 12, CLK_IGNORE_UNUSED, 0), + GATE(DISP_CLK_PIXEL_MIXER, "clk_pixel_mixer", "mout_aclk_disp_222_user", + EN_IP_DISP, 13, CLK_IGNORE_UNUSED, 0), + GATE(DISP_CLK_SMMU_FIMD1M0, "clk_smmu3_fimd1m0", + "mout_aclk_disp_222_user", + EN_IP_DISP, 22, 0, 0), + GATE(DISP_CLK_SMMU_FIMD1M1, "clk_smmu3_fimd1m1", + "mout_aclk_disp_222_user", + EN_IP_DISP, 23, 0, 0), + GATE(DISP_CLK_SMMU_TV, "clk_smmu3_tv", "mout_aclk_disp_222_user", + EN_IP_DISP, 25, 0, 0), +}; + +static void __init exynos5260_clk_disp_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = disp_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(disp_mux_clks); + cmu.div_clks = disp_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(disp_div_clks); + cmu.gate_clks = disp_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(disp_gate_clks); + cmu.nr_clk_ids = DISP_NR_CLK; + cmu.clk_regs = disp_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(disp_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_disp, "samsung,exynos5260-clock-disp", + exynos5260_clk_disp_init); + + +/* CMU_EGL */ + +static unsigned long egl_clk_regs[] __initdata = { + EGL_PLL_LOCK, + EGL_PLL_CON0, + EGL_PLL_CON1, + EGL_PLL_FREQ_DET, + MUX_SEL_EGL, + MUX_ENABLE_EGL, + DIV_EGL, + DIV_EGL_PLL_FDET, + EN_ACLK_EGL, + EN_PCLK_EGL, + EN_SCLK_EGL, +}; + +PNAME(mout_egl_b_p) = {"mout_egl_pll", "dout_bus_pll"}; +PNAME(mout_egl_pll_p) = {"fin_pll", "fout_egl_pll"}; + +struct samsung_mux_clock egl_mux_clks[] __initdata = { + MUX(EGL_MOUT_EGL_PLL, "mout_egl_pll", mout_egl_pll_p, + MUX_SEL_EGL, 4, 1), + MUX(EGL_MOUT_EGL_B, "mout_egl_b", mout_egl_b_p, MUX_SEL_EGL, 16, 1), +}; + +struct samsung_div_clock egl_div_clks[] __initdata = { + DIV(EGL_DOUT_EGL1, "dout_egl1", "mout_egl_b", DIV_EGL, 0, 3), + DIV(EGL_DOUT_EGL2, "dout_egl2", "dout_egl1", DIV_EGL, 4, 3), + DIV(EGL_DOUT_ACLK_EGL, "dout_aclk_egl", "dout_egl2", DIV_EGL, 8, 3), + DIV(EGL_DOUT_PCLK_EGL, "dout_pclk_egl", "dout_egl_atclk", + DIV_EGL, 12, 3), + DIV(EGL_DOUT_EGL_ATCLK, "dout_egl_atclk", "dout_egl2", DIV_EGL, 16, 3), + DIV(EGL_DOUT_EGL_PCLK_DBG, "dout_egl_pclk_dbg", "dout_egl_atclk", + DIV_EGL, 20, 3), + DIV(EGL_DOUT_EGL_PLL, "dout_egl_pll", "mout_egl_b", DIV_EGL, 24, 3), +}; + +static struct samsung_pll_clock egl_pll_clks[] __initdata = { + PLL(pll_2550xx, EGL_FOUT_EGL_PLL, "fout_egl_pll", "fin_pll", + EGL_PLL_LOCK, EGL_PLL_CON0, + pll2550_24mhz_tbl), +}; + +static void __init exynos5260_clk_egl_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.pll_clks = egl_pll_clks; + cmu.nr_pll_clks = ARRAY_SIZE(egl_pll_clks); + cmu.mux_clks = egl_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(egl_mux_clks); + cmu.div_clks = egl_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(egl_div_clks); + cmu.nr_clk_ids = EGL_NR_CLK; + cmu.clk_regs = egl_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(egl_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_egl, "samsung,exynos5260-clock-egl", + exynos5260_clk_egl_init); + + +/* CMU_FSYS */ + +static unsigned long fsys_clk_regs[] __initdata = { + MUX_SEL_FSYS0, + MUX_SEL_FSYS1, + EN_ACLK_FSYS, + EN_ACLK_FSYS_SECURE_RTIC, + EN_ACLK_FSYS_SECURE_SMMU_RTIC, + EN_SCLK_FSYS, + EN_IP_FSYS, + EN_IP_FSYS_SECURE_RTIC, + EN_IP_FSYS_SECURE_SMMU_RTIC, +}; + +PNAME(mout_phyclk_usbhost20_phyclk_user_p) = {"fin_pll", + "phyclk_usbhost20_phy_phyclock"}; +PNAME(mout_phyclk_usbhost20_freeclk_user_p) = {"fin_pll", + "phyclk_usbhost20_phy_freeclk"}; +PNAME(mout_phyclk_usbhost20_clk48mohci_user_p) = {"fin_pll", + "phyclk_usbhost20_phy_clk48mohci"}; +PNAME(mout_phyclk_usbdrd30_pipe_pclk_user_p) = {"fin_pll", + "phyclk_usbdrd30_udrd30_pipe_pclk"}; +PNAME(mout_phyclk_usbdrd30_phyclock_user_p) = {"fin_pll", + "phyclk_usbdrd30_udrd30_phyclock"}; + +struct samsung_mux_clock fsys_mux_clks[] __initdata = { + MUX(FSYS_MOUT_PHYCLK_USBDRD30_PHYCLOCK_USER, + "mout_phyclk_usbdrd30_phyclock_user", + mout_phyclk_usbdrd30_phyclock_user_p, + MUX_SEL_FSYS1, 0, 1), + MUX(FSYS_MOUT_PHYCLK_USBDRD30_PIPE_PCLK_USER, + "mout_phyclk_usbdrd30_pipe_pclk_user", + mout_phyclk_usbdrd30_pipe_pclk_user_p, + MUX_SEL_FSYS1, 4, 1), + MUX(FSYS_MOUT_PHYCLK_USBHOST20_CLK48MOHCI_USER, + "mout_phyclk_usbhost20_clk48mohci_user", + mout_phyclk_usbhost20_clk48mohci_user_p, + MUX_SEL_FSYS1, 8, 1), + MUX(FSYS_MOUT_PHYCLK_USBHOST20_FREECLK_USER, + "mout_phyclk_usbhost20_freeclk_user", + mout_phyclk_usbhost20_freeclk_user_p, + MUX_SEL_FSYS1, 12, 1), + MUX(FSYS_MOUT_PHYCLK_USBHOST20_PHYCLK_USER, + "mout_phyclk_usbhost20_phyclk_user", + mout_phyclk_usbhost20_phyclk_user_p, + MUX_SEL_FSYS1, 16, 1), +}; + +struct samsung_gate_clock fsys_gate_clks[] __initdata = { + GATE(FSYS_PHYCLK_USBHOST20, "phyclk_usbhost20_phyclock", + "mout_phyclk_usbdrd30_phyclock_user", + EN_SCLK_FSYS, 1, 0, 0), + GATE(FSYS_PHYCLK_USBDRD30, "phyclk_usbdrd30_udrd30_phyclock_g", + "mout_phyclk_usbdrd30_phyclock_user", + EN_SCLK_FSYS, 7, 0, 0), + + GATE(FSYS_CLK_MMC0, "clk_mmc0", "dout_aclk_fsys_200", + EN_IP_FSYS, 6, 0, 0), + GATE(FSYS_CLK_MMC1, "clk_mmc1", "dout_aclk_fsys_200", + EN_IP_FSYS, 7, 0, 0), + GATE(FSYS_CLK_MMC2, "clk_mmc2", "dout_aclk_fsys_200", + EN_IP_FSYS, 8, 0, 0), + GATE(FSYS_CLK_PDMA, "clk_pdma", "dout_aclk_fsys_200", + EN_IP_FSYS, 9, 0, 0), + GATE(FSYS_CLK_SROMC, "clk_sromc", "dout_aclk_fsys_200", + EN_IP_FSYS, 13, 0, 0), + GATE(FSYS_CLK_USBDRD30, "clk_usbdrd30", "dout_aclk_fsys_200", + EN_IP_FSYS, 14, 0, 0), + GATE(FSYS_CLK_USBHOST20, "clk_usbhost20", "dout_aclk_fsys_200", + EN_IP_FSYS, 15, 0, 0), + GATE(FSYS_CLK_USBLINK, "clk_usblink", "dout_aclk_fsys_200", + EN_IP_FSYS, 18, 0, 0), + GATE(FSYS_CLK_TSI, "clk_tsi", "dout_aclk_fsys_200", + EN_IP_FSYS, 20, 0, 0), + + GATE(FSYS_CLK_RTIC, "clk_rtic", "dout_aclk_fsys_200", + EN_IP_FSYS_SECURE_RTIC, 11, 0, 0), + GATE(FSYS_CLK_SMMU_RTIC, "clk_smmu_rtic", "dout_aclk_fsys_200", + EN_IP_FSYS_SECURE_SMMU_RTIC, 12, 0, 0), +}; + +static void __init exynos5260_clk_fsys_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = fsys_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(fsys_mux_clks); + cmu.gate_clks = fsys_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(fsys_gate_clks); + cmu.nr_clk_ids = FSYS_NR_CLK; + cmu.clk_regs = fsys_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(fsys_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_fsys, "samsung,exynos5260-clock-fsys", + exynos5260_clk_fsys_init); + + +/* CMU_G2D */ + +static unsigned long g2d_clk_regs[] __initdata = { + MUX_SEL_G2D, + MUX_STAT_G2D, + DIV_G2D, + EN_ACLK_G2D, + EN_ACLK_G2D_SECURE_SSS, + EN_ACLK_G2D_SECURE_SLIM_SSS, + EN_ACLK_G2D_SECURE_SMMU_SLIM_SSS, + EN_ACLK_G2D_SECURE_SMMU_SSS, + EN_ACLK_G2D_SECURE_SMMU_MDMA, + EN_ACLK_G2D_SECURE_SMMU_G2D, + EN_PCLK_G2D, + EN_PCLK_G2D_SECURE_SMMU_SLIM_SSS, + EN_PCLK_G2D_SECURE_SMMU_SSS, + EN_PCLK_G2D_SECURE_SMMU_MDMA, + EN_PCLK_G2D_SECURE_SMMU_G2D, + EN_IP_G2D, + EN_IP_G2D_SECURE_SSS, + EN_IP_G2D_SECURE_SLIM_SSS, + EN_IP_G2D_SECURE_SMMU_SLIM_SSS, + EN_IP_G2D_SECURE_SMMU_SSS, + EN_IP_G2D_SECURE_SMMU_MDMA, + EN_IP_G2D_SECURE_SMMU_G2D, +}; + +PNAME(mout_aclk_g2d_333_user_p) = {"fin_pll", "dout_aclk_g2d_333"}; + +struct samsung_mux_clock g2d_mux_clks[] __initdata = { + MUX(G2D_MOUT_ACLK_G2D_333_USER, "mout_aclk_g2d_333_user", + mout_aclk_g2d_333_user_p, + MUX_SEL_G2D, 0, 1), +}; + +struct samsung_div_clock g2d_div_clks[] __initdata = { + DIV(G2D_DOUT_PCLK_G2D_83, "dout_pclk_g2d_83", "mout_aclk_g2d_333_user", + DIV_G2D, 0, 3), +}; + +struct samsung_gate_clock g2d_gate_clks[] __initdata = { + GATE(G2D_CLK_G2D, "clk_g2d", "mout_aclk_g2d_333_user", + EN_IP_G2D, 4, 0, 0), + GATE(G2D_CLK_JPEG, "clk_jpeg", "mout_aclk_g2d_333_user", + EN_IP_G2D, 5, 0, 0), + GATE(G2D_CLK_MDMA, "clk_mdma", "mout_aclk_g2d_333_user", + EN_IP_G2D, 6, 0, 0), + GATE(G2D_CLK_SMMU3_JPEG, "clk_smmu3_jpeg", "mout_aclk_g2d_333_user", + EN_IP_G2D, 16, 0, 0), + + GATE(G2D_CLK_SSS, "clk_sss", "mout_aclk_g2d_333_user", + EN_IP_G2D_SECURE_SSS, 17, 0, 0), + + GATE(G2D_CLK_SLIM_SSS, "clk_slim_sss", "mout_aclk_g2d_333_user", + EN_IP_G2D_SECURE_SLIM_SSS, 11, 0, 0), + + GATE(G2D_CLK_SMMU_SLIM_SSS, "clk_smmu_slim_sss", + "mout_aclk_g2d_333_user", + EN_IP_G2D_SECURE_SMMU_SLIM_SSS, 13, 0, 0), + + GATE(G2D_CLK_SMMU_SSS, "clk_smmu_sss", "mout_aclk_g2d_333_user", + EN_IP_G2D_SECURE_SMMU_SSS, 14, 0, 0), + + GATE(G2D_CLK_SMMU_MDMA, "clk_smmu_mdma", "mout_aclk_g2d_333_user", + EN_IP_G2D_SECURE_SMMU_MDMA, 12, 0, 0), + + GATE(G2D_CLK_SMMU3_G2D, "clk_smmu3_g2d", "mout_aclk_g2d_333_user", + EN_IP_G2D_SECURE_SMMU_G2D, 15, 0, 0), +}; + +static void __init exynos5260_clk_g2d_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = g2d_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(g2d_mux_clks); + cmu.div_clks = g2d_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(g2d_div_clks); + cmu.gate_clks = g2d_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(g2d_gate_clks); + cmu.nr_clk_ids = G2D_NR_CLK; + cmu.clk_regs = g2d_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(g2d_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_g2d, "samsung,exynos5260-clock-g2d", + exynos5260_clk_g2d_init); + + +/* CMU_G3D */ + +static unsigned long g3d_clk_regs[] __initdata = { + G3D_PLL_LOCK, + G3D_PLL_CON0, + G3D_PLL_CON1, + G3D_PLL_FDET, + MUX_SEL_G3D, + DIV_G3D, + DIV_G3D_PLL_FDET, + EN_ACLK_G3D, + EN_PCLK_G3D, + EN_SCLK_G3D, + EN_IP_G3D, +}; + +PNAME(mout_g3d_pll_p) = {"fin_pll", "fout_g3d_pll"}; + +struct samsung_mux_clock g3d_mux_clks[] __initdata = { + MUX(G3D_MOUT_G3D_PLL, "mout_g3d_pll", mout_g3d_pll_p, + MUX_SEL_G3D, 0, 1), +}; + +struct samsung_div_clock g3d_div_clks[] __initdata = { + DIV(G3D_DOUT_PCLK_G3D, "dout_pclk_g3d", "dout_aclk_g3d", DIV_G3D, 0, 3), + DIV(G3D_DOUT_ACLK_G3D, "dout_aclk_g3d", "mout_g3d_pll", DIV_G3D, 4, 3), +}; + +struct samsung_gate_clock g3d_gate_clks[] __initdata = { + GATE(G3D_CLK_G3D, "clk_g3d", "dout_aclk_g3d", EN_IP_G3D, 2, 0, 0), + GATE(G3D_CLK_G3D_HPM, "clk_g3d_hpm", "dout_aclk_g3d", + EN_IP_G3D, 3, 0, 0), +}; + +static struct samsung_pll_clock g3d_pll_clks[] __initdata = { + PLL(pll_2550, G3D_FOUT_G3D_PLL, "fout_g3d_pll", "fin_pll", + G3D_PLL_LOCK, G3D_PLL_CON0, + pll2550_24mhz_tbl), +}; + +static void __init exynos5260_clk_g3d_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.pll_clks = g3d_pll_clks; + cmu.nr_pll_clks = ARRAY_SIZE(g3d_pll_clks); + cmu.mux_clks = g3d_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(g3d_mux_clks); + cmu.div_clks = g3d_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(g3d_div_clks); + cmu.gate_clks = g3d_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(g3d_gate_clks); + cmu.nr_clk_ids = G3D_NR_CLK; + cmu.clk_regs = g3d_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(g3d_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_g3d, "samsung,exynos5260-clock-g3d", + exynos5260_clk_g3d_init); + + +/* CMU_GSCL */ + +static unsigned long gscl_clk_regs[] __initdata = { + MUX_SEL_GSCL, + DIV_GSCL, + EN_ACLK_GSCL, + EN_ACLK_GSCL_FIMC, + EN_ACLK_GSCL_SECURE_SMMU_GSCL0, + EN_ACLK_GSCL_SECURE_SMMU_GSCL1, + EN_ACLK_GSCL_SECURE_SMMU_MSCL0, + EN_ACLK_GSCL_SECURE_SMMU_MSCL1, + EN_PCLK_GSCL, + EN_PCLK_GSCL_FIMC, + EN_PCLK_GSCL_SECURE_SMMU_GSCL0, + EN_PCLK_GSCL_SECURE_SMMU_GSCL1, + EN_PCLK_GSCL_SECURE_SMMU_MSCL0, + EN_PCLK_GSCL_SECURE_SMMU_MSCL1, + EN_SCLK_GSCL, + EN_SCLK_GSCL_FIMC, + EN_IP_GSCL, + EN_IP_GSCL_FIMC, + EN_IP_GSCL_SECURE_SMMU_GSCL0, + EN_IP_GSCL_SECURE_SMMU_GSCL1, + EN_IP_GSCL_SECURE_SMMU_MSCL0, + EN_IP_GSCL_SECURE_SMMU_MSCL1, +}; + +PNAME(mout_aclk_gscl_333_user_p) = {"fin_pll", "dout_aclk_gscl_333"}; +PNAME(mout_aclk_m2m_400_user_p) = {"fin_pll", "dout_aclk_gscl_400"}; +PNAME(mout_aclk_gscl_fimc_user_p) = {"fin_pll", "dout_aclk_gscl_400"}; +PNAME(mout_aclk_csis_p) = {"dout_aclk_csis_200", "mout_aclk_gscl_fimc_user"}; + +struct samsung_mux_clock gscl_mux_clks[] __initdata = { + MUX(GSCL_MOUT_ACLK_GSCL_333_USER, "mout_aclk_gscl_333_user", + mout_aclk_gscl_333_user_p, + MUX_SEL_GSCL, 0, 1), + MUX(GSCL_MOUT_ACLK_M2M_400_USER, "mout_aclk_m2m_400_user", + mout_aclk_m2m_400_user_p, + MUX_SEL_GSCL, 4, 1), + MUX(GSCL_MOUT_ACLK_GSCL_FIMC_USER, "mout_aclk_gscl_fimc_user", + mout_aclk_gscl_fimc_user_p, + MUX_SEL_GSCL, 8, 1), + MUX(GSCL_MOUT_ACLK_CSIS, "mout_aclk_csis", mout_aclk_csis_p, + MUX_SEL_GSCL, 24, 1), +}; + +struct samsung_div_clock gscl_div_clks[] __initdata = { + DIV(GSCL_DOUT_PCLK_M2M_100, "dout_pclk_m2m_100", + "mout_aclk_m2m_400_user", + DIV_GSCL, 0, 3), + DIV(GSCL_DOUT_ACLK_CSIS_200, "dout_aclk_csis_200", + "mout_aclk_m2m_400_user", + DIV_GSCL, 4, 3), +}; + +struct samsung_gate_clock gscl_gate_clks[] __initdata = { + GATE(GSCL_SCLK_CSIS0_WRAP, "sclk_csis0_wrap", "dout_aclk_csis_200", + EN_SCLK_GSCL_FIMC, 0, CLK_SET_RATE_PARENT, 0), + GATE(GSCL_SCLK_CSIS1_WRAP, "sclk_csis1_wrap", "dout_aclk_csis_200", + EN_SCLK_GSCL_FIMC, 1, CLK_SET_RATE_PARENT, 0), + + GATE(GSCL_CLK_GSCL0, "clk_gscl0", "mout_aclk_gscl_333_user", + EN_IP_GSCL, 2, 0, 0), + GATE(GSCL_CLK_GSCL1, "clk_gscl1", "mout_aclk_gscl_333_user", + EN_IP_GSCL, 3, 0, 0), + GATE(GSCL_CLK_MSCL0, "clk_mscl0", "mout_aclk_gscl_333_user", + EN_IP_GSCL, 4, 0, 0), + GATE(GSCL_CLK_MSCL1, "clk_mscl1", "mout_aclk_gscl_333_user", + EN_IP_GSCL, 5, 0, 0), + GATE(GSCL_CLK_PIXEL_GSCL0, "clk_pixel_gscl0", + "mout_aclk_gscl_333_user", + EN_IP_GSCL, 8, 0, 0), + GATE(GSCL_CLK_PIXEL_GSCL1, "clk_pixel_gscl1", + "mout_aclk_gscl_333_user", + EN_IP_GSCL, 9, 0, 0), + + GATE(GSCL_CLK_SMMU3_LITE_A, "clk_smmu3_lite_a", + "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 5, 0, 0), + GATE(GSCL_CLK_SMMU3_LITE_B, "clk_smmu3_lite_b", + "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 6, 0, 0), + GATE(GSCL_CLK_SMMU3_LITE_D, "clk_smmu3_lite_d", + "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 7, 0, 0), + GATE(GSCL_CLK_CSIS0, "clk_csis0", "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 8, 0, 0), + GATE(GSCL_CLK_CSIS1, "clk_csis1", "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 9, 0, 0), + GATE(GSCL_CLK_FIMC_LITE_A, "clk_fimc_lite_a", + "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 10, 0, 0), + GATE(GSCL_CLK_FIMC_LITE_B, "clk_fimc_lite_b", + "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 11, 0, 0), + GATE(GSCL_CLK_FIMC_LITE_D, "clk_fimc_lite_d", + "mout_aclk_gscl_fimc_user", + EN_IP_GSCL_FIMC, 12, 0, 0), + + GATE(GSCL_CLK_SMMU3_GSCL0, "clk_smmu3_gscl0", + "mout_aclk_gscl_333_user", + EN_IP_GSCL_SECURE_SMMU_GSCL0, 17, 0, 0), + GATE(GSCL_CLK_SMMU3_GSCL1, "clk_smmu3_gscl1", "mout_aclk_gscl_333_user", + EN_IP_GSCL_SECURE_SMMU_GSCL1, 18, 0, 0), + GATE(GSCL_CLK_SMMU3_MSCL0, "clk_smmu3_mscl0", + "mout_aclk_m2m_400_user", + EN_IP_GSCL_SECURE_SMMU_MSCL0, 19, 0, 0), + GATE(GSCL_CLK_SMMU3_MSCL1, "clk_smmu3_mscl1", + "mout_aclk_m2m_400_user", + EN_IP_GSCL_SECURE_SMMU_MSCL1, 20, 0, 0), +}; + +static void __init exynos5260_clk_gscl_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = gscl_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(gscl_mux_clks); + cmu.div_clks = gscl_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(gscl_div_clks); + cmu.gate_clks = gscl_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(gscl_gate_clks); + cmu.nr_clk_ids = GSCL_NR_CLK; + cmu.clk_regs = gscl_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(gscl_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_gscl, "samsung,exynos5260-clock-gscl", + exynos5260_clk_gscl_init); + + +/* CMU_ISP */ + +static unsigned long isp_clk_regs[] __initdata = { + MUX_SEL_ISP0, + MUX_SEL_ISP1, + DIV_ISP, + EN_ACLK_ISP0, + EN_ACLK_ISP1, + EN_PCLK_ISP0, + EN_PCLK_ISP1, + EN_SCLK_ISP, + EN_IP_ISP0, + EN_IP_ISP1, +}; + +PNAME(mout_isp_400_user_p) = {"fin_pll", "dout_aclk_isp1_400"}; +PNAME(mout_isp_266_user_p) = {"fin_pll", "dout_aclk_isp1_266"}; + +struct samsung_mux_clock isp_mux_clks[] __initdata = { + MUX(ISP_MOUT_ISP_266_USER, "mout_isp_266_user", mout_isp_266_user_p, + MUX_SEL_ISP0, 0, 1), + MUX(ISP_MOUT_ISP_400_USER, "mout_isp_400_user", mout_isp_400_user_p, + MUX_SEL_ISP0, 4, 1), +}; + +struct samsung_div_clock isp_div_clks[] __initdata = { + DIV(ISP_DOUT_PCLK_ISP_66, "dout_pclk_isp_66", "mout_kfc", + DIV_ISP, 0, 3), + DIV(ISP_DOUT_PCLK_ISP_133, "dout_pclk_isp_133", "mout_kfc", + DIV_ISP, 4, 4), + DIV(ISP_DOUT_CA5_ATCLKIN, "dout_ca5_atclkin", "mout_kfc", + DIV_ISP, 12, 3), + DIV(ISP_DOUT_CA5_PCLKDBG, "dout_ca5_pclkdbg", "mout_kfc", + DIV_ISP, 16, 4), + DIV(ISP_DOUT_SCLK_MPWM, "dout_sclk_mpwm", "mout_kfc", DIV_ISP, 20, 2), +}; + +struct samsung_gate_clock isp_gate_clks[] __initdata = { + GATE(ISP_CLK_GIC, "clk_isp_gic", "mout_aclk_isp1_266", + EN_IP_ISP0, 15, 0, 0), + + GATE(ISP_CLK_CA5, "clk_isp_ca5", "mout_aclk_isp1_266", + EN_IP_ISP1, 1, 0, 0), + GATE(ISP_CLK_FIMC_DRC, "clk_isp_fimc_drc", "mout_aclk_isp1_266", + EN_IP_ISP1, 2, 0, 0), + GATE(ISP_CLK_FIMC_FD, "clk_isp_fimc_fd", "mout_aclk_isp1_266", + EN_IP_ISP1, 3, 0, 0), + GATE(ISP_CLK_FIMC, "clk_isp_fimc", "mout_aclk_isp1_266", + EN_IP_ISP1, 4, 0, 0), + GATE(ISP_CLK_FIMC_SCALERC, "clk_isp_fimc_scalerc", + "mout_aclk_isp1_266", + EN_IP_ISP1, 5, 0, 0), + GATE(ISP_CLK_FIMC_SCALERP, "clk_isp_fimc_scalerp", + "mout_aclk_isp1_266", + EN_IP_ISP1, 6, 0, 0), + GATE(ISP_CLK_I2C0, "clk_isp_i2c0", "mout_aclk_isp1_266", + EN_IP_ISP1, 7, 0, 0), + GATE(ISP_CLK_I2C1, "clk_isp_i2c1", "mout_aclk_isp1_266", + EN_IP_ISP1, 8, 0, 0), + GATE(ISP_CLK_MCUCTL, "clk_isp_mcuctl", "mout_aclk_isp1_266", + EN_IP_ISP1, 9, 0, 0), + GATE(ISP_CLK_MPWM, "clk_isp_mpwm", "mout_aclk_isp1_266", + EN_IP_ISP1, 10, 0, 0), + GATE(ISP_CLK_MTCADC, "clk_isp_mtcadc", "mout_aclk_isp1_266", + EN_IP_ISP1, 11, 0, 0), + GATE(ISP_CLK_PWM, "clk_isp_pwm", "mout_aclk_isp1_266", + EN_IP_ISP1, 14, 0, 0), + GATE(ISP_CLK_SMMU_DRC, "clk_smmu_drc", "mout_aclk_isp1_266", + EN_IP_ISP1, 21, 0, 0), + GATE(ISP_CLK_SMMU_FD, "clk_smmu_fd", "mout_aclk_isp1_266", + EN_IP_ISP1, 22, 0, 0), + GATE(ISP_CLK_SMMU_ISP, "clk_smmu_isp", "mout_aclk_isp1_266", + EN_IP_ISP1, 23, 0, 0), + GATE(ISP_CLK_SMMU_ISPCX, "clk_smmu_ispcx", "mout_aclk_isp1_266", + EN_IP_ISP1, 24, 0, 0), + GATE(ISP_CLK_SMMU_SCALERC, "clk_isp_smmu_scalerc", + "mout_aclk_isp1_266", + EN_IP_ISP1, 25, 0, 0), + GATE(ISP_CLK_SMMU_SCALERP, "clk_isp_smmu_scalerp", + "mout_aclk_isp1_266", + EN_IP_ISP1, 26, 0, 0), + GATE(ISP_CLK_SPI0, "clk_isp_spi0", "mout_aclk_isp1_266", + EN_IP_ISP1, 27, 0, 0), + GATE(ISP_CLK_SPI1, "clk_isp_spi1", "mout_aclk_isp1_266", + EN_IP_ISP1, 28, 0, 0), + GATE(ISP_CLK_WDT, "clk_isp_wdt", "mout_aclk_isp1_266", + EN_IP_ISP1, 31, 0, 0), + GATE(ISP_CLK_UART, "clk_isp_uart", "mout_aclk_isp1_266", + EN_IP_ISP1, 30, 0, 0), + + GATE(ISP_SCLK_UART_EXT, "sclk_isp_uart_ext", "fin_pll", + EN_SCLK_ISP, 7, CLK_SET_RATE_PARENT, 0), + GATE(ISP_SCLK_SPI1_EXT, "sclk_isp_spi1_ext", "fin_pll", + EN_SCLK_ISP, 8, CLK_SET_RATE_PARENT, 0), + GATE(ISP_SCLK_SPI0_EXT, "sclk_isp_spi0_ext", "fin_pll", + EN_SCLK_ISP, 9, CLK_SET_RATE_PARENT, 0), +}; + +static void __init exynos5260_clk_isp_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = isp_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(isp_mux_clks); + cmu.div_clks = isp_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(isp_div_clks); + cmu.gate_clks = isp_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(isp_gate_clks); + cmu.nr_clk_ids = ISP_NR_CLK; + cmu.clk_regs = isp_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(isp_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_isp, "samsung,exynos5260-clock-isp", + exynos5260_clk_isp_init); + + +/* CMU_KFC */ + +static unsigned long kfc_clk_regs[] __initdata = { + KFC_PLL_LOCK, + KFC_PLL_CON0, + KFC_PLL_CON1, + KFC_PLL_FDET, + MUX_SEL_KFC0, + MUX_SEL_KFC2, + DIV_KFC, + DIV_KFC_PLL_FDET, + EN_ACLK_KFC, + EN_PCLK_KFC, + EN_SCLK_KFC, + EN_IP_KFC, +}; + +PNAME(mout_kfc_pll_p) = {"fin_pll", "fout_kfc_pll"}; +PNAME(mout_kfc_p) = {"mout_kfc_pll", "dout_media_pll"}; + +struct samsung_mux_clock kfc_mux_clks[] __initdata = { + MUX(KFC_MOUT_KFC_PLL, "mout_kfc_pll", mout_kfc_pll_p, + MUX_SEL_KFC0, 0, 1), + MUX(KFC_MOUT_KFC, "mout_kfc", mout_kfc_p, MUX_SEL_KFC2, 0, 1), +}; + +struct samsung_div_clock kfc_div_clks[] __initdata = { + DIV(KFC_DOUT_KFC1, "dout_kfc1", "mout_kfc", DIV_KFC, 0, 3), + DIV(KFC_DOUT_KFC2, "dout_kfc2", "dout_kfc1", DIV_KFC, 4, 3), + DIV(KFC_DOUT_KFC_ATCLK, "dout_kfc_atclk", "dout_kfc2", DIV_KFC, 8, 3), + DIV(KFC_DOUT_KFC_PCLK_DBG, "dout_kfc_pclk_dbg", "dout_kfc2", + DIV_KFC, 12, 3), + DIV(KFC_DOUT_ACLK_KFC, "dout_aclk_kfc", "dout_kfc2", DIV_KFC, 16, 3), + DIV(KFC_DOUT_PCLK_KFC, "dout_pclk_kfc", "dout_kfc2", DIV_KFC, 20, 3), + DIV(KFC_DOUT_KFC_PLL, "dout_kfc_pll", "mout_kfc", DIV_KFC, 24, 3), +}; + +static struct samsung_pll_clock kfc_pll_clks[] __initdata = { + PLL(pll_2550xx, KFC_FOUT_KFC_PLL, "fout_kfc_pll", "fin_pll", + KFC_PLL_LOCK, KFC_PLL_CON0, + pll2550_24mhz_tbl), +}; + +static void __init exynos5260_clk_kfc_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.pll_clks = kfc_pll_clks; + cmu.nr_pll_clks = ARRAY_SIZE(kfc_pll_clks); + cmu.mux_clks = kfc_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(kfc_mux_clks); + cmu.div_clks = kfc_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(kfc_div_clks); + cmu.nr_clk_ids = KFC_NR_CLK; + cmu.clk_regs = kfc_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(kfc_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_kfc, "samsung,exynos5260-clock-kfc", + exynos5260_clk_kfc_init); + + +/* CMU_MFC */ + +static unsigned long mfc_clk_regs[] __initdata = { + MUX_SEL_MFC, + DIV_MFC, + EN_ACLK_MFC, + EN_ACLK_SECURE_SMMU2_MFC, + EN_PCLK_MFC, + EN_PCLK_SECURE_SMMU2_MFC, + EN_IP_MFC, + EN_IP_MFC_SECURE_SMMU2_MFC, +}; + +PNAME(mout_aclk_mfc_333_user_p) = {"fin_pll", "dout_aclk_mfc_333"}; + +struct samsung_mux_clock mfc_mux_clks[] __initdata = { + MUX(MFC_MOUT_ACLK_MFC_333_USER, "mout_aclk_mfc_333_user", + mout_aclk_mfc_333_user_p, + MUX_SEL_MFC, 0, 1), +}; + +struct samsung_div_clock mfc_div_clks[] __initdata = { + DIV(MFC_DOUT_PCLK_MFC_83, "dout_pclk_mfc_83", "mout_aclk_mfc_333_user", + DIV_MFC, 0, 3), +}; + +struct samsung_gate_clock mfc_gate_clks[] __initdata = { + GATE(MFC_CLK_MFC, "clk_mfc", "mout_aclk_mfc_333_user", + EN_IP_MFC, 1, 0, 0), + GATE(MFC_CLK_SMMU2_MFCM0, "clk_smmu2_mfcm0", "mout_aclk_mfc_333_user", + EN_IP_MFC_SECURE_SMMU2_MFC, 6, 0, 0), + GATE(MFC_CLK_SMMU2_MFCM1, "clk_smmu2_mfcm1", "mout_aclk_mfc_333_user", + EN_IP_MFC_SECURE_SMMU2_MFC, 7, 0, 0), +}; + +static void __init exynos5260_clk_mfc_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = mfc_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(mfc_mux_clks); + cmu.div_clks = mfc_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(mfc_div_clks); + cmu.gate_clks = mfc_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(mfc_gate_clks); + cmu.nr_clk_ids = MFC_NR_CLK; + cmu.clk_regs = mfc_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(mfc_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_mfc, "samsung,exynos5260-clock-mfc", + exynos5260_clk_mfc_init); + + +/* CMU_MIF */ + +static unsigned long mif_clk_regs[] __initdata = { + MEM_PLL_LOCK, + BUS_PLL_LOCK, + MEDIA_PLL_LOCK, + MEM_PLL_CON0, + MEM_PLL_CON1, + MEM_PLL_FDET, + BUS_PLL_CON0, + BUS_PLL_CON1, + BUS_PLL_FDET, + MEDIA_PLL_CON0, + MEDIA_PLL_CON1, + MEDIA_PLL_FDET, + MUX_SEL_MIF, + DIV_MIF, + DIV_MIF_PLL_FDET, + EN_ACLK_MIF, + EN_ACLK_MIF_SECURE_DREX1_TZ, + EN_ACLK_MIF_SECURE_DREX0_TZ, + EN_ACLK_MIF_SECURE_INTMEM, + EN_PCLK_MIF, + EN_PCLK_MIF_SECURE_MONOCNT, + EN_PCLK_MIF_SECURE_RTC_APBIF, + EN_PCLK_MIF_SECURE_DREX1_TZ, + EN_PCLK_MIF_SECURE_DREX0_TZ, + EN_SCLK_MIF, + EN_IP_MIF, + EN_IP_MIF_SECURE_MONOCNT, + EN_IP_MIF_SECURE_RTC_APBIF, + EN_IP_MIF_SECURE_DREX1_TZ, + EN_IP_MIF_SECURE_DREX0_TZ, + EN_IP_MIF_SECURE_INTEMEM, +}; + +PNAME(mout_mem_pll_p) = {"fin_pll", "fout_mem_pll"}; +PNAME(mout_bus_pll_p) = {"fin_pll", "fout_bus_pll"}; +PNAME(mout_media_pll_p) = {"fin_pll", "fout_media_pll"}; +PNAME(mout_mif_drex_p) = {"dout_mem_pll", "dout_bus_pll"}; +PNAME(mout_mif_drex2x_p) = {"dout_mem_pll", "dout_bus_pll"}; +PNAME(mout_clkm_phy_p) = {"mout_mif_drex", "dout_media_pll"}; +PNAME(mout_clk2x_phy_p) = {"mout_mif_drex2x", "dout_media_pll"}; + +struct samsung_mux_clock mif_mux_clks[] __initdata = { + MUX(MIF_MOUT_MEM_PLL, "mout_mem_pll", mout_mem_pll_p, + MUX_SEL_MIF, 0, 1), + MUX(MIF_MOUT_BUS_PLL, "mout_bus_pll", mout_bus_pll_p, + MUX_SEL_MIF, 4, 1), + MUX(MIF_MOUT_MEDIA_PLL, "mout_media_pll", mout_media_pll_p, + MUX_SEL_MIF, 8, 1), + MUX(MIF_MOUT_MIF_DREX, "mout_mif_drex", mout_mif_drex_p, + MUX_SEL_MIF, 12, 1), + MUX(MIF_MOUT_CLKM_PHY, "mout_clkm_phy", mout_clkm_phy_p, + MUX_SEL_MIF, 16, 1), + MUX(MIF_MOUT_MIF_DREX2X, "mout_mif_drex2x", mout_mif_drex2x_p, + MUX_SEL_MIF, 20, 1), + MUX(MIF_MOUT_CLK2X_PHY, "mout_clk2x_phy", mout_clk2x_phy_p, + MUX_SEL_MIF, 24, 1), +}; + +struct samsung_div_clock mif_div_clks[] __initdata = { + DIV(MIF_DOUT_MEDIA_PLL, "dout_media_pll", "mout_media_pll", + DIV_MIF, 0, 3), + DIV(MIF_DOUT_MEM_PLL, "dout_mem_pll", "mout_mem_pll", + DIV_MIF, 4, 3), + DIV(MIF_DOUT_BUS_PLL, "dout_bus_pll", "mout_bus_pll", + DIV_MIF, 8, 3), + DIV(MIF_DOUT_CLKM_PHY, "dout_clkm_phy", "mout_clkm_phy", + DIV_MIF, 12, 3), + DIV(MIF_DOUT_CLK2X_PHY, "dout_clk2x_phy", "mout_clk2x_phy", + DIV_MIF, 16, 4), + DIV(MIF_DOUT_ACLK_MIF_466, "dout_aclk_mif_466", "dout_clk2x_phy", + DIV_MIF, 20, 3), + DIV(MIF_DOUT_ACLK_BUS_200, "dout_aclk_bus_200", "dout_bus_pll", + DIV_MIF, 24, 3), + DIV(MIF_DOUT_ACLK_BUS_100, "dout_aclk_bus_100", "dout_bus_pll", + DIV_MIF, 28, 4), +}; + +struct samsung_gate_clock mif_gate_clks[] __initdata = { + GATE(MIF_CLK_LPDDR3PHY_WRAP0, "clk_lpddr3phy_wrap0", "dout_clk2x_phy", + EN_IP_MIF, 12, CLK_IGNORE_UNUSED, 0), + GATE(MIF_CLK_LPDDR3PHY_WRAP1, "clk_lpddr3phy_wrap1", "dout_clk2x_phy", + EN_IP_MIF, 13, CLK_IGNORE_UNUSED, 0), + + GATE(MIF_CLK_MONOCNT, "clk_monocnt", "dout_aclk_bus_100", + EN_IP_MIF_SECURE_MONOCNT, 22, + CLK_IGNORE_UNUSED, 0), + + GATE(MIF_CLK_MIF_RTC, "clk_mif_rtc", "dout_aclk_bus_100", + EN_IP_MIF_SECURE_RTC_APBIF, 23, + CLK_IGNORE_UNUSED, 0), + + GATE(MIF_CLK_DREX1, "clk_drex1", "dout_aclk_mif_466", + EN_IP_MIF_SECURE_DREX1_TZ, 9, + CLK_IGNORE_UNUSED, 0), + + GATE(MIF_CLK_DREX0, "clk_drex0", "dout_aclk_mif_466", + EN_IP_MIF_SECURE_DREX0_TZ, 9, + CLK_IGNORE_UNUSED, 0), + + GATE(MIF_CLK_INTMEM, "clk_intmem", "dout_aclk_bus_200", + EN_IP_MIF_SECURE_INTEMEM, 11, + CLK_IGNORE_UNUSED, 0), + + GATE(MIF_SCLK_LPDDR3PHY_WRAP_U0, "sclk_lpddr3phy_wrap_u0", + "dout_clkm_phy", EN_SCLK_MIF, 0, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), + GATE(MIF_SCLK_LPDDR3PHY_WRAP_U1, "sclk_lpddr3phy_wrap_u1", + "dout_clkm_phy", EN_SCLK_MIF, 1, + CLK_IGNORE_UNUSED | CLK_SET_RATE_PARENT, 0), +}; + +static struct samsung_pll_clock mif_pll_clks[] __initdata = { + PLL(pll_2550xx, MIF_FOUT_MEM_PLL, "fout_mem_pll", "fin_pll", + MEM_PLL_LOCK, MEM_PLL_CON0, + pll2550_24mhz_tbl), + PLL(pll_2550xx, MIF_FOUT_BUS_PLL, "fout_bus_pll", "fin_pll", + BUS_PLL_LOCK, BUS_PLL_CON0, + pll2550_24mhz_tbl), + PLL(pll_2550xx, MIF_FOUT_MEDIA_PLL, "fout_media_pll", "fin_pll", + MEDIA_PLL_LOCK, MEDIA_PLL_CON0, + pll2550_24mhz_tbl), +}; + +static void __init exynos5260_clk_mif_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.pll_clks = mif_pll_clks; + cmu.nr_pll_clks = ARRAY_SIZE(mif_pll_clks); + cmu.mux_clks = mif_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(mif_mux_clks); + cmu.div_clks = mif_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(mif_div_clks); + cmu.gate_clks = mif_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(mif_gate_clks); + cmu.nr_clk_ids = MIF_NR_CLK; + cmu.clk_regs = mif_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(mif_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_mif, "samsung,exynos5260-clock-mif", + exynos5260_clk_mif_init); + + +/* CMU_PERI */ + +static unsigned long peri_clk_regs[] __initdata = { + MUX_SEL_PERI, + MUX_SEL_PERI1, + DIV_PERI, + EN_PCLK_PERI0, + EN_PCLK_PERI1, + EN_PCLK_PERI2, + EN_PCLK_PERI3, + EN_PCLK_PERI_SECURE_CHIPID, + EN_PCLK_PERI_SECURE_PROVKEY0, + EN_PCLK_PERI_SECURE_PROVKEY1, + EN_PCLK_PERI_SECURE_SECKEY, + EN_PCLK_PERI_SECURE_ANTIRBKCNT, + EN_PCLK_PERI_SECURE_TOP_RTC, + EN_PCLK_PERI_SECURE_TZPC, + EN_SCLK_PERI, + EN_SCLK_PERI_SECURE_TOP_RTC, + EN_IP_PERI0, + EN_IP_PERI1, + EN_IP_PERI2, + EN_IP_PERI_SECURE_CHIPID, + EN_IP_PERI_SECURE_PROVKEY0, + EN_IP_PERI_SECURE_PROVKEY1, + EN_IP_PERI_SECURE_SECKEY, + EN_IP_PERI_SECURE_ANTIRBKCNT, + EN_IP_PERI_SECURE_TOP_RTC, + EN_IP_PERI_SECURE_TZPC, +}; + +PNAME(mout_sclk_pcm_p) = {"ioclk_pcm_extclk", "fin_pll", "dout_aclk_peri_aud", + "phyclk_hdmi_phy_ref_cko"}; +PNAME(mout_sclk_i2scod_p) = {"ioclk_i2s_cdclk", "fin_pll", "dout_aclk_peri_aud", + "phyclk_hdmi_phy_ref_cko"}; +PNAME(mout_sclk_spdif_p) = {"ioclk_spdif_extclk", "fin_pll", + "dout_aclk_peri_aud", "phyclk_hdmi_phy_ref_cko"}; + +struct samsung_mux_clock peri_mux_clks[] __initdata = { + MUX(PERI_MOUT_SCLK_PCM, "mout_sclk_pcm", mout_sclk_pcm_p, + MUX_SEL_PERI1, 4, 2), + MUX(PERI_MOUT_SCLK_I2SCOD, "mout_sclk_i2scod", mout_sclk_i2scod_p, + MUX_SEL_PERI1, 12, 2), + MUX(PERI_MOUT_SCLK_SPDIF, "mout_sclk_spdif", mout_sclk_spdif_p, + MUX_SEL_PERI1, 20, 2), +}; + +struct samsung_div_clock peri_div_clks[] __initdata = { + DIV(PERI_DOUT_PCM, "dout_pcm", "mout_sclk_pcm", DIV_PERI, 0, 8), + DIV(PERI_DOUT_I2S, "dout_i2s", "mout_sclk_i2scod", DIV_PERI, 8, 6), +}; + +struct samsung_gate_clock peri_gate_clks[] __initdata = { + GATE(PERI_SCLK_PCM1, "sclk_pcm1", "dout_pcm", EN_SCLK_PERI, 0, + CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_I2S, "sclk_i2s", "dout_i2s", EN_SCLK_PERI, 1, + CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_SPDIF, "sclk_spdif", "dout_sclk_peri_spi0_b", + EN_SCLK_PERI, 2, CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_SPI0, "sclk_spi0", "dout_sclk_peri_spi0_b", + EN_SCLK_PERI, 7, CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_SPI1, "sclk_spi1", "dout_sclk_peri_spi1_b", + EN_SCLK_PERI, 8, CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_SPI2, "sclk_spi2", "dout_sclk_peri_spi2_b", + EN_SCLK_PERI, 9, CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_UART0, "sclk_uart0", "dout_sclk_peri_uart0", + EN_SCLK_PERI, 10, CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_UART1, "sclk_uart1", "dout_sclk_peri_uart1", + EN_SCLK_PERI, 11, CLK_SET_RATE_PARENT, 0), + GATE(PERI_SCLK_UART2, "sclk_uart2", "dout_sclk_peri_uart2", + EN_SCLK_PERI, 12, CLK_SET_RATE_PARENT, 0), + + GATE(PERI_CLK_ABB, "clk_abb", "dout_aclk_peri_66", + EN_IP_PERI0, 1, 0, 0), + GATE(PERI_CLK_EFUSE_WRITER, "clk_efuse_writer", "dout_aclk_peri_66", + EN_IP_PERI0, 5, 0, 0), + GATE(PERI_CLK_HDMICEC, "clk_hdmicec", "dout_aclk_peri_66", + EN_IP_PERI0, 6, 0, 0), + GATE(PERI_CLK_I2C10, "clk_i2c10", "dout_aclk_peri_66", + EN_IP_PERI0, 7, 0, 0), + GATE(PERI_CLK_I2C11, "clk_i2c11", "dout_aclk_peri_66", + EN_IP_PERI0, 8, 0, 0), + GATE(PERI_CLK_I2C8, "clk_i2c8", "dout_aclk_peri_66", + EN_IP_PERI0, 9, 0, 0), + GATE(PERI_CLK_I2C9, "clk_i2c9", "dout_aclk_peri_66", + EN_IP_PERI0, 10, 0, 0), + GATE(PERI_CLK_I2C4, "clk_i2c4", "dout_aclk_peri_66", + EN_IP_PERI0, 11, 0, 0), + GATE(PERI_CLK_I2C5, "clk_i2c5", "dout_aclk_peri_66", + EN_IP_PERI0, 12, 0, 0), + GATE(PERI_CLK_I2C6, "clk_i2c6", "dout_aclk_peri_66", + EN_IP_PERI0, 13, 0, 0), + GATE(PERI_CLK_I2C7, "clk_i2c7", "dout_aclk_peri_66", + EN_IP_PERI0, 14, 0, 0), + GATE(PERI_CLK_I2CHDMI, "clk_i2chdmi", "dout_aclk_peri_66", + EN_IP_PERI0, 15, 0, 0), + GATE(PERI_CLK_I2S, "clk_peri_i2s", "dout_aclk_peri_66", + EN_IP_PERI0, 16, 0, 0), + GATE(PERI_CLK_MCT, "clk_mct", "dout_aclk_peri_66", + EN_IP_PERI0, 17, 0, 0), + GATE(PERI_CLK_PCM, "clk_peri_pcm", "dout_aclk_peri_66", + EN_IP_PERI0, 18, 0, 0), + GATE(PERI_CLK_HSIC0, "clk_hsic0", "dout_aclk_peri_66", + EN_IP_PERI0, 20, 0, 0), + GATE(PERI_CLK_HSIC1, "clk_hsic1", "dout_aclk_peri_66", + EN_IP_PERI0, 21, 0, 0), + GATE(PERI_CLK_HSIC2, "clk_hsic2", "dout_aclk_peri_66", + EN_IP_PERI0, 22, 0, 0), + GATE(PERI_CLK_HSIC3, "clk_hsic3", "dout_aclk_peri_66", + EN_IP_PERI0, 23, 0, 0), + GATE(PERI_CLK_WDT_EGL, "clk_wdt_egl", "dout_aclk_peri_66", + EN_IP_PERI0, 24, 0, 0), + GATE(PERI_CLK_WDT_KFC, "clk_wdt_kfc", "dout_aclk_peri_66", + EN_IP_PERI0, 25, 0, 0), + + GATE(PERI_CLK_UART4, "clk_uart4", "dout_aclk_peri_66", + EN_IP_PERI2, 0, 0, 0), + GATE(PERI_CLK_PWM, "clk_pwm", "dout_aclk_peri_66", + EN_IP_PERI2, 3, 0, 0), + GATE(PERI_CLK_SPDIF, "clk_spdif", "dout_aclk_peri_66", + EN_IP_PERI2, 6, 0, 0), + GATE(PERI_CLK_SPI0, "clk_spi0", "dout_aclk_peri_66", + EN_IP_PERI2, 7, 0, 0), + GATE(PERI_CLK_SPI1, "clk_spi1", "dout_aclk_peri_66", + EN_IP_PERI2, 8, 0, 0), + GATE(PERI_CLK_SPI2, "clk_spi2", "dout_aclk_peri_66", + EN_IP_PERI2, 9, 0, 0), + GATE(PERI_CLK_TMU0, "clk_tmu0", "dout_aclk_peri_66", + EN_IP_PERI2, 10, 0, 0), + GATE(PERI_CLK_TMU1, "clk_tmu1", "dout_aclk_peri_66", + EN_IP_PERI2, 11, 0, 0), + GATE(PERI_CLK_TMU2, "clk_tmu2", "dout_aclk_peri_66", + EN_IP_PERI2, 12, 0, 0), + GATE(PERI_CLK_TMU3, "clk_tmu3", "dout_aclk_peri_66", + EN_IP_PERI2, 13, 0, 0), + GATE(PERI_CLK_TMU4, "clk_tmu4", "dout_aclk_peri_66", + EN_IP_PERI2, 14, 0, 0), + GATE(PERI_CLK_ADC, "clk_adc", "dout_aclk_peri_66", + EN_IP_PERI2, 18, 0, 0), + GATE(PERI_CLK_UART0, "clk_uart0", "dout_aclk_peri_66", + EN_IP_PERI2, 19, 0, 0), + GATE(PERI_CLK_UART1, "clk_uart1", "dout_aclk_peri_66", + EN_IP_PERI2, 20, 0, 0), + GATE(PERI_CLK_UART2, "clk_uart2", "dout_aclk_peri_66", + EN_IP_PERI2, 21, 0, 0), + + GATE(PERI_CLK_CHIPID, "clk_chipid", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_CHIPID, 2, 0, 0), + + GATE(PERI_CLK_PROVKEY0, "clk_provkey0", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_PROVKEY0, 1, 0, 0), + + GATE(PERI_CLK_PROVKEY1, "clk_provkey1", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_PROVKEY1, 2, 0, 0), + + GATE(PERI_CLK_SECKEY, "clk_seckey", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_SECKEY, 5, 0, 0), + + GATE(PERI_CLK_TOP_RTC, "clk_top_rtc", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TOP_RTC, 5, 0, 0), + + GATE(PERI_CLK_TZPC0, "clk_tzpc0", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 10, 0, 0), + GATE(PERI_CLK_TZPC1, "clk_tzpc1", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 11, 0, 0), + GATE(PERI_CLK_TZPC2, "clk_tzpc2", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 12, 0, 0), + GATE(PERI_CLK_TZPC3, "clk_tzpc3", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 13, 0, 0), + GATE(PERI_CLK_TZPC4, "clk_tzpc4", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 14, 0, 0), + GATE(PERI_CLK_TZPC5, "clk_tzpc5", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 15, 0, 0), + GATE(PERI_CLK_TZPC6, "clk_tzpc6", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 16, 0, 0), + GATE(PERI_CLK_TZPC7, "clk_tzpc7", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 17, 0, 0), + GATE(PERI_CLK_TZPC8, "clk_tzpc8", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 18, 0, 0), + GATE(PERI_CLK_TZPC9, "clk_tzpc9", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 19, 0, 0), + GATE(PERI_CLK_TZPC10, "clk_tzpc10", "dout_aclk_peri_66", + EN_IP_PERI_SECURE_TZPC, 20, 0, 0), +}; + +static void __init exynos5260_clk_peri_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.mux_clks = peri_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(peri_mux_clks); + cmu.div_clks = peri_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(peri_div_clks); + cmu.gate_clks = peri_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(peri_gate_clks); + cmu.nr_clk_ids = PERI_NR_CLK; + cmu.clk_regs = peri_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(peri_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_peri, "samsung,exynos5260-clock-peri", + exynos5260_clk_peri_init); + + +/* CMU_TOP */ + +static unsigned long top_clk_regs[] __initdata = { + DISP_PLL_LOCK, + AUD_PLL_LOCK, + DISP_PLL_CON0, + DISP_PLL_CON1, + DISP_PLL_FDET, + AUD_PLL_CON0, + AUD_PLL_CON1, + AUD_PLL_CON2, + AUD_PLL_FDET, + MUX_SEL_TOP_PLL0, + MUX_SEL_TOP_MFC, + MUX_SEL_TOP_G2D, + MUX_SEL_TOP_GSCL, + MUX_SEL_TOP_ISP10, + MUX_SEL_TOP_ISP11, + MUX_SEL_TOP_DISP0, + MUX_SEL_TOP_DISP1, + MUX_SEL_TOP_BUS, + MUX_SEL_TOP_PERI0, + MUX_SEL_TOP_PERI1, + MUX_SEL_TOP_FSYS, + DIV_TOP_G2D_MFC, + DIV_TOP_GSCL_ISP0, + DIV_TOP_ISP10, + DIV_TOP_ISP11, + DIV_TOP_DISP, + DIV_TOP_BUS, + DIV_TOP_PERI0, + DIV_TOP_PERI1, + DIV_TOP_PERI2, + DIV_TOP_FSYS0, + DIV_TOP_FSYS1, + DIV_TOP_HPM, + DIV_TOP_PLL_FDET, + EN_ACLK_TOP, + EN_SCLK_TOP, + EN_IP_TOP, +}; + +/* fixed rate clocks generated inside the soc */ +struct samsung_fixed_rate_clock fixed_rate_clks[] __initdata = { + FRATE(PHYCLK_DPTX_PHY_CH3_TXD_CLK, "phyclk_dptx_phy_ch3_txd_clk", NULL, + CLK_IS_ROOT, 270000000), + FRATE(PHYCLK_DPTX_PHY_CH2_TXD_CLK, "phyclk_dptx_phy_ch2_txd_clk", NULL, + CLK_IS_ROOT, 270000000), + FRATE(PHYCLK_DPTX_PHY_CH1_TXD_CLK, "phyclk_dptx_phy_ch1_txd_clk", NULL, + CLK_IS_ROOT, 270000000), + FRATE(PHYCLK_DPTX_PHY_CH0_TXD_CLK, "phyclk_dptx_phy_ch0_txd_clk", NULL, + CLK_IS_ROOT, 270000000), + FRATE(phyclk_hdmi_phy_tmds_clko, "phyclk_hdmi_phy_tmds_clko", NULL, + CLK_IS_ROOT, 250000000), + FRATE(PHYCLK_HDMI_PHY_PIXEL_CLKO, "phyclk_hdmi_phy_pixel_clko", NULL, + CLK_IS_ROOT, 1660000000), + FRATE(PHYCLK_HDMI_LINK_O_TMDS_CLKHI, "phyclk_hdmi_link_o_tmds_clkhi", + NULL, CLK_IS_ROOT, 125000000), + FRATE(PHYCLK_MIPI_DPHY_4L_M_TXBYTECLKHS, + "phyclk_mipi_dphy_4l_m_txbyteclkhs" , NULL, + CLK_IS_ROOT, 187500000), + FRATE(PHYCLK_DPTX_PHY_O_REF_CLK_24M, "phyclk_dptx_phy_o_ref_clk_24m", + NULL, CLK_IS_ROOT, 24000000), + FRATE(PHYCLK_DPTX_PHY_CLK_DIV2, "phyclk_dptx_phy_clk_div2", NULL, + CLK_IS_ROOT, 135000000), + FRATE(PHYCLK_MIPI_DPHY_4L_M_RXCLKESC0, + "phyclk_mipi_dphy_4l_m_rxclkesc0", NULL, + CLK_IS_ROOT, 20000000), + FRATE(PHYCLK_USBHOST20_PHY_PHYCLOCK, "phyclk_usbhost20_phy_phyclock", + NULL, CLK_IS_ROOT, 60000000), + FRATE(PHYCLK_USBHOST20_PHY_FREECLK, "phyclk_usbhost20_phy_freeclk", + NULL, CLK_IS_ROOT, 60000000), + FRATE(PHYCLK_USBHOST20_PHY_CLK48MOHCI, + "phyclk_usbhost20_phy_clk48mohci", + NULL, CLK_IS_ROOT, 48000000), + FRATE(PHYCLK_USBDRD30_UDRD30_PIPE_PCLK, + "phyclk_usbdrd30_udrd30_pipe_pclk", NULL, + CLK_IS_ROOT, 125000000), + FRATE(PHYCLK_USBDRD30_UDRD30_PHYCLOCK, + "phyclk_usbdrd30_udrd30_phyclock", NULL, + CLK_IS_ROOT, 60000000), +}; + +PNAME(mout_memtop_pll_user_p) = {"fin_pll", "dout_mem_pll"}; +PNAME(mout_bustop_pll_user_p) = {"fin_pll", "dout_bus_pll"}; +PNAME(mout_mediatop_pll_user_p) = {"fin_pll", "dout_media_pll"}; +PNAME(mout_audtop_pll_user_p) = {"fin_pll", "mout_aud_pll"}; +PNAME(mout_aud_pll_p) = {"fin_pll", "fout_aud_pll"}; +PNAME(mout_disp_pll_p) = {"fin_pll", "fout_disp_pll"}; +PNAME(mout_mfc_bustop_333_p) = {"mout_bustop_pll_user", "mout_disp_pll"}; +PNAME(mout_aclk_mfc_333_p) = {"mout_mediatop_pll_user", "mout_mfc_bustop_333"}; +PNAME(mout_g2d_bustop_333_p) = {"mout_bustop_pll_user", "mout_disp_pll"}; +PNAME(mout_aclk_g2d_333_p) = {"mout_mediatop_pll_user", "mout_g2d_bustop_333"}; +PNAME(mout_gscl_bustop_333_p) = {"mout_bustop_pll_user", "mout_disp_pll"}; +PNAME(mout_aclk_gscl_333_p) = {"mout_mediatop_pll_user", + "mout_gscl_bustop_333"}; +PNAME(mout_m2m_mediatop_400_p) = {"mout_mediatop_pll_user", "mout_disp_pll"}; +PNAME(mout_aclk_gscl_400_p) = {"mout_bustop_pll_user", + "mout_m2m_mediatop_400"}; +PNAME(mout_gscl_bustop_fimc_p) = {"mout_bustop_pll_user", "mout_disp_pll"}; +PNAME(mout_aclk_gscl_fimc_p) = {"mout_mediatop_pll_user", + "mout_gscl_bustop_fimc"}; +PNAME(mout_isp1_media_266_p) = {"mout_mediatop_pll_user", + "mout_memtop_pll_user"}; +PNAME(mout_aclk_isp1_266_p) = {"mout_bustop_pll_user", "mout_isp1_media_266"}; +PNAME(mout_isp1_media_400_p) = {"mout_mediatop_pll_user", "mout_disp_pll"}; +PNAME(mout_aclk_isp1_400_p) = {"mout_bustop_pll_user", "mout_isp1_media_400"}; +PNAME(mout_sclk_isp_spi_p) = {"fin_pll", "mout_bustop_pll_user"}; +PNAME(mout_sclk_isp_uart_p) = {"fin_pll", "mout_bustop_pll_user"}; +PNAME(mout_sclk_isp_sensor_p) = {"fin_pll", "mout_bustop_pll_user"}; +PNAME(mout_disp_disp_333_p) = {"mout_disp_pll", "mout_bustop_pll_user"}; +PNAME(mout_aclk_disp_333_p) = {"mout_mediatop_pll_user", "mout_disp_disp_333"}; +PNAME(mout_disp_disp_222_p) = {"mout_disp_pll", "mout_bustop_pll_user"}; +PNAME(mout_aclk_disp_222_p) = {"mout_mediatop_pll_user", "mout_disp_disp_222"}; +PNAME(mout_disp_media_pixel_p) = {"mout_mediatop_pll_user", + "mout_bustop_pll_user"}; +PNAME(mout_sclk_disp_pixel_p) = {"mout_disp_pll", "mout_disp_media_pixel"}; +PNAME(mout_bus_bustop_400_p) = {"mout_bustop_pll_user", "mout_memtop_pll_user"}; +PNAME(mout_bus_bustop_100_p) = {"mout_bustop_pll_user", "mout_memtop_pll_user"}; +PNAME(mout_sclk_peri_spi_clk_p) = {"fin_pll", "mout_bustop_pll_user"}; +PNAME(mout_sclk_peri_uart_uclk_p) = {"fin_pll", "mout_bustop_pll_user"}; +PNAME(mout_sclk_fsys_usb_p) = {"fin_pll", "mout_bustop_pll_user"}; +PNAME(mout_sclk_fsys_mmc_sdclkin_a_p) = {"fin_pll", "mout_bustop_pll_user"}; +PNAME(mout_sclk_fsys_mmc0_sdclkin_b_p) = {"mout_sclk_fsys_mmc0_sdclkin_a", + "mout_mediatop_pll_user"}; +PNAME(mout_sclk_fsys_mmc1_sdclkin_b_p) = {"mout_sclk_fsys_mmc1_sdclkin_a", + "mout_mediatop_pll_user"}; +PNAME(mout_sclk_fsys_mmc2_sdclkin_b_p) = {"mout_sclk_fsys_mmc2_sdclkin_a", + "mout_mediatop_pll_user"}; + +struct samsung_mux_clock top_mux_clks[] __initdata = { + MUX(TOP_MOUT_MEDIATOP_PLL_USER, "mout_mediatop_pll_user", + mout_mediatop_pll_user_p, + MUX_SEL_TOP_PLL0, 0, 1), + MUX(TOP_MOUT_MEMTOP_PLL_USER, "mout_memtop_pll_user", + mout_memtop_pll_user_p, + MUX_SEL_TOP_PLL0, 4, 1), + MUX(TOP_MOUT_BUSTOP_PLL_USER, "mout_bustop_pll_user", + mout_bustop_pll_user_p, + MUX_SEL_TOP_PLL0, 8, 1), + MUX(TOP_MOUT_DISP_PLL, "mout_disp_pll", mout_disp_pll_p, + MUX_SEL_TOP_PLL0, 12, 1), + MUX(TOP_MOUT_AUD_PLL, "mout_aud_pll", mout_aud_pll_p, + MUX_SEL_TOP_PLL0, 16, 1), + MUX(TOP_MOUT_AUDTOP_PLL_USER, "mout_audtop_pll_user", + mout_audtop_pll_user_p, + MUX_SEL_TOP_PLL0, 24, 1), + + MUX(TOP_MOUT_DISP_DISP_333, "mout_disp_disp_333", mout_disp_disp_333_p, + MUX_SEL_TOP_DISP0, 0, 1), + MUX(TOP_MOUT_ACLK_DISP_333, "mout_aclk_disp_333", mout_aclk_disp_333_p, + MUX_SEL_TOP_DISP0, 8, 1), + MUX(TOP_MOUT_DISP_DISP_222, "mout_disp_disp_222", mout_disp_disp_222_p, + MUX_SEL_TOP_DISP0, 12, 1), + MUX(TOP_MOUT_ACLK_DISP_222, "mout_aclk_disp_222", mout_aclk_disp_222_p, + MUX_SEL_TOP_DISP0, 20, 1), + + MUX(TOP_MOUT_FIMD1, "mout_sclk_disp_pixel", mout_sclk_disp_pixel_p, + MUX_SEL_TOP_DISP1, 0, 1), + MUX(TOP_MOUT_DISP_MEDIA_PIXEL, "mout_disp_media_pixel", + mout_disp_media_pixel_p, + MUX_SEL_TOP_DISP1, 8, 1), + + MUX(TOP_MOUT_SCLK_PERI_SPI2_CLK, "mout_sclk_peri_spi2_clk", + mout_sclk_peri_spi_clk_p, + MUX_SEL_TOP_PERI1, 0, 1), + MUX(TOP_MOUT_SCLK_PERI_SPI1_CLK, "mout_sclk_peri_spi1_clk", + mout_sclk_peri_spi_clk_p, + MUX_SEL_TOP_PERI1, 4, 1), + MUX(TOP_MOUT_SCLK_PERI_SPI0_CLK, "mout_sclk_peri_spi0_clk", + mout_sclk_peri_spi_clk_p, + MUX_SEL_TOP_PERI1, 8, 1), + MUX(TOP_MOUT_SCLK_PERI_UART1_UCLK, "mout_sclk_peri_uart1_uclk", + mout_sclk_peri_uart_uclk_p, + MUX_SEL_TOP_PERI1, 12, 1), + MUX(TOP_MOUT_SCLK_PERI_UART2_UCLK, "mout_sclk_peri_uart2_uclk", + mout_sclk_peri_uart_uclk_p, + MUX_SEL_TOP_PERI1, 16, 1), + MUX(TOP_MOUT_SCLK_PERI_UART0_UCLK, "mout_sclk_peri_uart0_uclk", + mout_sclk_peri_uart_uclk_p, + MUX_SEL_TOP_PERI1, 20, 1), + + + MUX(TOP_MOUT_BUS1_BUSTOP_400, "mout_bus1_bustop_400", + mout_bus_bustop_400_p, + MUX_SEL_TOP_BUS, 0, 1), + MUX(TOP_MOUT_BUS1_BUSTOP_100, "mout_bus1_bustop_100", + mout_bus_bustop_100_p, + MUX_SEL_TOP_BUS, 4, 1), + MUX(TOP_MOUT_BUS2_BUSTOP_100, "mout_bus2_bustop_100", + mout_bus_bustop_100_p, + MUX_SEL_TOP_BUS, 8, 1), + MUX(TOP_MOUT_BUS2_BUSTOP_400, "mout_bus2_bustop_400", + mout_bus_bustop_400_p, + MUX_SEL_TOP_BUS, 12, 1), + MUX(TOP_MOUT_BUS3_BUSTOP_400, "mout_bus3_bustop_400", + mout_bus_bustop_400_p, + MUX_SEL_TOP_BUS, 16, 1), + MUX(TOP_MOUT_BUS3_BUSTOP_100, "mout_bus3_bustop_100", + mout_bus_bustop_100_p, + MUX_SEL_TOP_BUS, 20, 1), + MUX(TOP_MOUT_BUS4_BUSTOP_400, "mout_bus4_bustop_400", + mout_bus_bustop_400_p, + MUX_SEL_TOP_BUS, 24, 1), + MUX(TOP_MOUT_BUS4_BUSTOP_100, "mout_bus4_bustop_100", + mout_bus_bustop_100_p, + MUX_SEL_TOP_BUS, 28, 1), + + MUX(TOP_MOUT_SCLK_FSYS_USB, "mout_sclk_fsys_usb", + mout_sclk_fsys_usb_p, + MUX_SEL_TOP_FSYS, 0, 1), + MUX(TOP_MOUT_SCLK_FSYS_MMC2_SDCLKIN_A, "mout_sclk_fsys_mmc2_sdclkin_a", + mout_sclk_fsys_mmc_sdclkin_a_p, + MUX_SEL_TOP_FSYS, 4, 1), + MUX(TOP_MOUT_SCLK_FSYS_MMC2_SDCLKIN_B, "mout_sclk_fsys_mmc2_sdclkin_b", + mout_sclk_fsys_mmc2_sdclkin_b_p, + MUX_SEL_TOP_FSYS, 8, 1), + MUX(TOP_MOUT_SCLK_FSYS_MMC1_SDCLKIN_A, "mout_sclk_fsys_mmc1_sdclkin_a", + mout_sclk_fsys_mmc_sdclkin_a_p, + MUX_SEL_TOP_FSYS, 12, 1), + MUX(TOP_MOUT_SCLK_FSYS_MMC1_SDCLKIN_B, "mout_sclk_fsys_mmc1_sdclkin_b", + mout_sclk_fsys_mmc1_sdclkin_b_p, + MUX_SEL_TOP_FSYS, 16, 1), + MUX(TOP_MOUT_SCLK_FSYS_MMC0_SDCLKIN_A, "mout_sclk_fsys_mmc0_sdclkin_a", + mout_sclk_fsys_mmc_sdclkin_a_p, + MUX_SEL_TOP_FSYS, 20, 1), + MUX(TOP_MOUT_SCLK_FSYS_MMC0_SDCLKIN_B, "mout_sclk_fsys_mmc0_sdclkin_b", + mout_sclk_fsys_mmc0_sdclkin_b_p, + MUX_SEL_TOP_FSYS, 24, 1), + + MUX(TOP_MOUT_ISP1_MEDIA_400, "mout_isp1_media_400", + mout_isp1_media_400_p, + MUX_SEL_TOP_ISP10, 4, 1), + MUX(TOP_MOUT_ACLK_ISP1_400, "mout_aclk_isp1_400", mout_aclk_isp1_400_p, + MUX_SEL_TOP_ISP10, 8 , 1), + MUX(TOP_MOUT_ISP1_MEDIA_266, "mout_isp1_media_266", + mout_isp1_media_266_p, + MUX_SEL_TOP_ISP10, 16, 1), + MUX(TOP_MOUT_ACLK_ISP1_266, "mout_aclk_isp1_266", mout_aclk_isp1_266_p, + MUX_SEL_TOP_ISP10, 20, 1), + + MUX(TOP_MOUT_SCLK_ISP1_SPI0, "mout_sclk_isp1_spi0", mout_sclk_isp_spi_p, + MUX_SEL_TOP_ISP11, 4, 1), + MUX(TOP_MOUT_SCLK_ISP1_SPI1, "mout_sclk_isp1_spi1", mout_sclk_isp_spi_p, + MUX_SEL_TOP_ISP11, 8, 1), + MUX(TOP_MOUT_SCLK_ISP1_UART, "mout_sclk_isp1_uart", + mout_sclk_isp_uart_p, + MUX_SEL_TOP_ISP11, 12, 1), + MUX(TOP_MOUT_SCLK_ISP1_SENSOR0, "mout_sclk_isp1_sensor0", + mout_sclk_isp_sensor_p, + MUX_SEL_TOP_ISP11, 16, 1), + MUX(TOP_MOUT_SCLK_ISP1_SENSOR1, "mout_sclk_isp1_sensor1", + mout_sclk_isp_sensor_p, + MUX_SEL_TOP_ISP11, 20, 1), + MUX(TOP_MOUT_SCLK_ISP1_SENSOR2, "mout_sclk_isp1_sensor2", + mout_sclk_isp_sensor_p, + MUX_SEL_TOP_ISP11, 24, 1), + + MUX(TOP_MOUT_MFC_BUSTOP_333, "mout_mfc_bustop_333", + mout_mfc_bustop_333_p, + MUX_SEL_TOP_MFC, 4, 1), + MUX(TOP_MOUT_ACLK_MFC_333, "mout_aclk_mfc_333", mout_aclk_mfc_333_p, + MUX_SEL_TOP_MFC, 8, 1), + + MUX(TOP_MOUT_G2D_BUSTOP_333, "mout_g2d_bustop_333", + mout_g2d_bustop_333_p, + MUX_SEL_TOP_G2D, 4, 1), + MUX(TOP_MOUT_ACLK_G2D_333, "mout_aclk_g2d_333", mout_aclk_g2d_333_p, + MUX_SEL_TOP_G2D, 8, 1), + + MUX(TOP_MOUT_M2M_MEDIATOP_400, "mout_m2m_mediatop_400", + mout_m2m_mediatop_400_p, + MUX_SEL_TOP_GSCL, 0, 1), + MUX(TOP_MOUT_ACLK_GSCL_400, "mout_aclk_gscl_400", + mout_aclk_gscl_400_p, + MUX_SEL_TOP_GSCL, 4, 1), + MUX(TOP_MOUT_GSCL_BUSTOP_333, "mout_gscl_bustop_333", + mout_gscl_bustop_333_p, + MUX_SEL_TOP_GSCL, 8, 1), + MUX(TOP_MOUT_ACLK_GSCL_333, "mout_aclk_gscl_333", + mout_aclk_gscl_333_p, + MUX_SEL_TOP_GSCL, 12, 1), + MUX(TOP_MOUT_GSCL_BUSTOP_FIMC, "mout_gscl_bustop_fimc", + mout_gscl_bustop_fimc_p, + MUX_SEL_TOP_GSCL, 16, 1), + MUX(TOP_MOUT_ACLK_GSCL_FIMC, "mout_aclk_gscl_fimc", + mout_aclk_gscl_fimc_p, + MUX_SEL_TOP_GSCL, 20, 1), +}; + +struct samsung_div_clock top_div_clks[] __initdata = { + DIV(TOP_DOUT_ACLK_G2D_333, "dout_aclk_g2d_333", "mout_aclk_g2d_333", + DIV_TOP_G2D_MFC, 0, 3), + DIV(TOP_DOUT_ACLK_MFC_333, "dout_aclk_mfc_333", "mout_aclk_mfc_333", + DIV_TOP_G2D_MFC, 4, 3), + + DIV(TOP_DOUT_ACLK_GSCL_333, "dout_aclk_gscl_333", "mout_aclk_gscl_333", + DIV_TOP_GSCL_ISP0, 0, 3), + DIV(TOP_DOUT_ACLK_GSCL_400, "dout_aclk_gscl_400", "mout_aclk_gscl_400", + DIV_TOP_GSCL_ISP0, 4, 3), + DIV(TOP_DOUT_ACLK_GSCL_FIMC, "dout_aclk_gscl_fimc", + "mout_aclk_gscl_fimc", DIV_TOP_GSCL_ISP0, 8, 3), + DIV(TOP_DOUT_SCLK_ISP1_SENSOR0_A, "dout_sclk_isp1_sensor0_a", + "mout_aclk_gscl_fimc", DIV_TOP_GSCL_ISP0, 16, 4), + DIV(TOP_DOUT_SCLK_ISP1_SENSOR1_A, "dout_sclk_isp1_sensor1_a", + "mout_aclk_gscl_400", DIV_TOP_GSCL_ISP0, 20, 4), + DIV(TOP_DOUT_SCLK_ISP1_SENSOR2_A, "dout_sclk_isp1_sensor2_a", + "mout_aclk_gscl_fimc", DIV_TOP_GSCL_ISP0, 24, 4), + + DIV(TOP_DOUT_ACLK_ISP1_266, "dout_aclk_isp1_266", "mout_aclk_isp1_266", + DIV_TOP_ISP10, 0, 3), + DIV(TOP_DOUT_ACLK_ISP1_400, "dout_aclk_isp1_400", "mout_aclk_isp1_400", + DIV_TOP_ISP10, 4, 3), + DIV(TOP_DOUT_SCLK_ISP1_SPI0_A, "dout_sclk_isp1_spi0_a", + "mout_sclk_isp1_spi0", DIV_TOP_ISP10, 12, 4), + DIV(TOP_DOUT_SCLK_ISP1_SPI0_B, "dout_sclk_isp1_spi0_b", + "dout_sclk_isp1_spi0_a", DIV_TOP_ISP10, 16, 8), + + DIV(TOP_DOUT_SCLK_ISP1_SPI1_A, "dout_sclk_isp1_spi1_a", + "mout_sclk_isp1_spi1", DIV_TOP_ISP11, 0, 4), + DIV(TOP_DOUT_SCLK_ISP1_SPI1_B, "dout_sclk_isp1_spi1_b", + "dout_sclk_isp1_spi1_a", DIV_TOP_ISP11, 4, 8), + DIV(TOP_DOUT_SCLK_ISP1_UART, "dout_sclk_isp1_uart", + "mout_sclk_isp1_uart", DIV_TOP_ISP11, 12, 4), + DIV(TOP_DOUT_SCLK_ISP1_SENSOR0_B, "dout_sclk_isp1_sensor0_b", + "dout_sclk_isp1_sensor0_a", DIV_TOP_ISP11, 16, 4), + DIV(TOP_DOUT_SCLK_ISP1_SENSOR1_B, "dout_sclk_isp1_sensor1_b", + "dout_sclk_isp1_sensor1_a", DIV_TOP_ISP11, 20, 4), + DIV(TOP_DOUT_SCLK_ISP1_SENSOR2_B, "dout_sclk_isp1_sensor2_b", + "dout_sclk_isp1_sensor2_a", DIV_TOP_ISP11, 24, 4), + + DIV(TOP_DOUTTOP__SCLK_HPM_TARGETCLK, "dout_sclk_hpm_targetclk", + "mout_bustop_pll_user", DIV_TOP_HPM, 0, 3), + + DIV(TOP_DOUT_ACLK_DISP_333, "dout_aclk_disp_333", "mout_aclk_disp_333", + DIV_TOP_DISP, 0, 3), + DIV(TOP_DOUT_ACLK_DISP_222, "dout_aclk_disp_222", "mout_aclk_disp_222", + DIV_TOP_DISP, 4, 3), + DIV(TOP_DOUT_SCLK_DISP_PIXEL, "dout_sclk_disp_pixel", + "mout_sclk_disp_pixel", DIV_TOP_DISP, 8, 3), + + DIV(TOP_DOUT_ACLK_BUS1_400, "dout_aclk_bus1_400", + "mout_bus1_bustop_400", DIV_TOP_BUS, 0, 3), + DIV(TOP_DOUT_ACLK_BUS1_100, "dout_aclk_bus1_100", + "mout_bus1_bustop_100", DIV_TOP_BUS, 4, 4), + DIV(TOP_DOUT_ACLK_BUS2_400, "dout_aclk_bus2_400", + "mout_bus2_bustop_400", DIV_TOP_BUS, 8, 3), + DIV(TOP_DOUT_ACLK_BUS2_100, "dout_aclk_bus2_100", + "mout_bus2_bustop_100", DIV_TOP_BUS, 12, 4), + DIV(TOP_DOUT_ACLK_BUS3_400, "dout_aclk_bus3_400", + "mout_bus3_bustop_400", DIV_TOP_BUS, 16, 3), + DIV(TOP_DOUT_ACLK_BUS3_100, "dout_aclk_bus3_100", + "mout_bus3_bustop_100", DIV_TOP_BUS, 20, 4), + DIV(TOP_DOUT_ACLK_BUS4_400, "dout_aclk_bus4_400", + "mout_bus4_bustop_400", DIV_TOP_BUS, 24, 3), + DIV(TOP_DOUT_ACLK_BUS4_100, "dout_aclk_bus4_100", + "mout_bus4_bustop_100", DIV_TOP_BUS, 28, 4), + + DIV(TOP_DOUT_SCLK_PERI_SPI0_A, "dout_sclk_peri_spi0_a", + "mout_sclk_peri_spi0_clk", DIV_TOP_PERI0, 4, 4), + DIV(TOP_DOUT_SCLK_PERI_SPI0_B, "dout_sclk_peri_spi0_b", + "dout_sclk_peri_spi0_a", DIV_TOP_PERI0, 8, 8), + DIV(TOP_DOUT_SCLK_PERI_SPI1_A, "dout_sclk_peri_spi1_a", + "mout_sclk_peri_spi1_clk", DIV_TOP_PERI0, 16, 4), + DIV(TOP_DOUT_SCLK_PERI_SPI1_B, "dout_sclk_peri_spi1_b", + "dout_sclk_peri_spi1_a", DIV_TOP_PERI0, 20, 8), + + DIV(TOP_DOUT_SCLK_PERI_SPI2_A, "dout_sclk_peri_spi2_a", + "mout_sclk_peri_spi2_clk", DIV_TOP_PERI1, 0, 4), + DIV(TOP_DOUT_SCLK_PERI_SPI2_B, "dout_sclk_peri_spi2_b", + "dout_sclk_peri_spi2_a", DIV_TOP_PERI1, 4, 8), + DIV(TOP_DOUT_SCLK_PERI_UART1, "dout_sclk_peri_uart1", + "mout_sclk_peri_uart1_uclk", DIV_TOP_PERI1, 16, 4), + DIV(TOP_DOUT_SCLK_PERI_UART2, "dout_sclk_peri_uart2", + "mout_sclk_peri_uart2_uclk", DIV_TOP_PERI1, 20, 4), + DIV(TOP_DOUT_SCLK_PERI_UART0, "dout_sclk_peri_uart0", + "mout_sclk_peri_uart0_uclk", DIV_TOP_PERI1, 24, 4), + + DIV(TOP_DOUT_ACLK_PERI_66, "dout_aclk_peri_66", "mout_bustop_pll_user", + DIV_TOP_PERI2, 20, 4), + DIV(TOP_DOUT_ACLK_PERI_AUD, "dout_aclk_peri_aud", + "mout_audtop_pll_user", DIV_TOP_PERI2, 24, 3), + + DIV(TOP_DOUT_ACLK_FSYS_200, "dout_aclk_fsys_200", + "mout_bustop_pll_user", DIV_TOP_FSYS0, 0, 3), + DIV(TOP_DOUT_SCLK_FSYS_USBDRD30_SUSPEND_CLK, + "dout_sclk_fsys_usbdrd30_suspend_clk", + "mout_sclk_fsys_usb", DIV_TOP_FSYS0, 4, 4), + DIV(TOP_DOUT_SCLK_FSYS_MMC0_SDCLKIN_A, "dout_sclk_fsys_mmc0_sdclkin_a", + "mout_sclk_fsys_mmc0_sdclkin_b", + DIV_TOP_FSYS0, 12, 4), + DIV(TOP_DOUT_SCLK_FSYS_MMC0_SDCLKIN_B, "dout_sclk_fsys_mmc0_sdclkin_b", + "dout_sclk_fsys_mmc0_sdclkin_a", + DIV_TOP_FSYS0, 16, 8), + + + DIV(TOP_DOUT_SCLK_FSYS_MMC1_SDCLKIN_A, "dout_sclk_fsys_mmc1_sdclkin_a", + "mout_sclk_fsys_mmc1_sdclkin_b", + DIV_TOP_FSYS1, 0, 4), + DIV(TOP_DOUT_SCLK_FSYS_MMC1_SDCLKIN_B, "dout_sclk_fsys_mmc1_sdclkin_b", + "dout_sclk_fsys_mmc1_sdclkin_a", + DIV_TOP_FSYS1, 4, 8), + DIV(TOP_DOUT_SCLK_FSYS_MMC2_SDCLKIN_A, "dout_sclk_fsys_mmc2_sdclkin_a", + "mout_sclk_fsys_mmc2_sdclkin_b", + DIV_TOP_FSYS1, 12, 4), + DIV(TOP_DOUT_SCLK_FSYS_MMC2_SDCLKIN_B, "dout_sclk_fsys_mmc2_sdclkin_b", + "dout_sclk_fsys_mmc2_sdclkin_a", + DIV_TOP_FSYS1, 16, 8), + +}; + +struct samsung_gate_clock top_gate_clks[] __initdata = { + GATE(TOP_SCLK_MMC0, "sclk_fsys_mmc0_sdclkin", + "dout_sclk_fsys_mmc0_sdclkin_b", + EN_SCLK_TOP, 7, CLK_SET_RATE_PARENT, 0), + GATE(TOP_SCLK_MMC1, "sclk_fsys_mmc1_sdclkin", + "dout_sclk_fsys_mmc1_sdclkin_b", + EN_SCLK_TOP, 8, CLK_SET_RATE_PARENT, 0), + GATE(TOP_SCLK_MMC2, "sclk_fsys_mmc2_sdclkin", + "dout_sclk_fsys_mmc2_sdclkin_b", + EN_SCLK_TOP, 9, CLK_SET_RATE_PARENT, 0), + GATE(TOP_SCLK_FIMD1, "sclk_disp_pixel", "dout_sclk_disp_pixel", + EN_ACLK_TOP, 10, CLK_IGNORE_UNUSED | + CLK_SET_RATE_PARENT, 0), +}; + +static struct samsung_pll_clock top_pll_clks[] __initdata = { + PLL(pll_2550xx, TOP_FOUT_DISP_PLL, "fout_disp_pll", "fin_pll", + DISP_PLL_LOCK, DISP_PLL_CON0, + pll2550_24mhz_tbl), + PLL(pll_2650xx, TOP_FOUT_AUD_PLL, "fout_aud_pll", "fin_pll", + AUD_PLL_LOCK, AUD_PLL_CON0, + pll2650_24mhz_tbl), +}; + +static void __init exynos5260_clk_top_init(struct device_node *np) +{ + struct exynos5260_cmu_info cmu = {0}; + + cmu.pll_clks = top_pll_clks; + cmu.nr_pll_clks = ARRAY_SIZE(top_pll_clks); + cmu.mux_clks = top_mux_clks; + cmu.nr_mux_clks = ARRAY_SIZE(top_mux_clks); + cmu.div_clks = top_div_clks; + cmu.nr_div_clks = ARRAY_SIZE(top_div_clks); + cmu.gate_clks = top_gate_clks; + cmu.nr_gate_clks = ARRAY_SIZE(top_gate_clks); + cmu.fixed_clks = fixed_rate_clks; + cmu.nr_fixed_clks = ARRAY_SIZE(fixed_rate_clks); + cmu.nr_clk_ids = TOP_NR_CLK; + cmu.clk_regs = top_clk_regs; + cmu.nr_clk_regs = ARRAY_SIZE(top_clk_regs); + + exynos5260_cmu_register_one(np, &cmu); +} + +CLK_OF_DECLARE(exynos5260_clk_top, "samsung,exynos5260-clock-top", + exynos5260_clk_top_init); diff --git a/drivers/clk/samsung/clk-exynos5260.h b/drivers/clk/samsung/clk-exynos5260.h new file mode 100644 index 000000000000..d739716d6ea1 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5260.h @@ -0,0 +1,459 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * Author: Rahul Sharma + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Common Clock Framework support for Exynos5260 SoC. + */ + +#ifndef __CLK_EXYNOS5260_H +#define __CLK_EXYNOS5260_H + +/* +*Registers for CMU_AUD +*/ +#define MUX_SEL_AUD 0x0200 +#define MUX_ENABLE_AUD 0x0300 +#define MUX_STAT_AUD 0x0400 +#define MUX_IGNORE_AUD 0x0500 +#define DIV_AUD0 0x0600 +#define DIV_AUD1 0x0604 +#define DIV_STAT_AUD0 0x0700 +#define DIV_STAT_AUD1 0x0704 +#define EN_ACLK_AUD 0x0800 +#define EN_PCLK_AUD 0x0900 +#define EN_SCLK_AUD 0x0a00 +#define EN_IP_AUD 0x0b00 + +/* +*Registers for CMU_DISP +*/ +#define MUX_SEL_DISP0 0x0200 +#define MUX_SEL_DISP1 0x0204 +#define MUX_SEL_DISP2 0x0208 +#define MUX_SEL_DISP3 0x020C +#define MUX_SEL_DISP4 0x0210 +#define MUX_ENABLE_DISP0 0x0300 +#define MUX_ENABLE_DISP1 0x0304 +#define MUX_ENABLE_DISP2 0x0308 +#define MUX_ENABLE_DISP3 0x030c +#define MUX_ENABLE_DISP4 0x0310 +#define MUX_STAT_DISP0 0x0400 +#define MUX_STAT_DISP1 0x0404 +#define MUX_STAT_DISP2 0x0408 +#define MUX_STAT_DISP3 0x040c +#define MUX_STAT_DISP4 0x0410 +#define MUX_IGNORE_DISP0 0x0500 +#define MUX_IGNORE_DISP1 0x0504 +#define MUX_IGNORE_DISP2 0x0508 +#define MUX_IGNORE_DISP3 0x050c +#define MUX_IGNORE_DISP4 0x0510 +#define DIV_DISP 0x0600 +#define DIV_STAT_DISP 0x0700 +#define EN_ACLK_DISP 0x0800 +#define EN_PCLK_DISP 0x0900 +#define EN_SCLK_DISP0 0x0a00 +#define EN_SCLK_DISP1 0x0a04 +#define EN_IP_DISP 0x0b00 +#define EN_IP_DISP_BUS 0x0b04 + + +/* +*Registers for CMU_EGL +*/ +#define EGL_PLL_LOCK 0x0000 +#define EGL_DPLL_LOCK 0x0004 +#define EGL_PLL_CON0 0x0100 +#define EGL_PLL_CON1 0x0104 +#define EGL_PLL_FREQ_DET 0x010c +#define EGL_DPLL_CON0 0x0110 +#define EGL_DPLL_CON1 0x0114 +#define EGL_DPLL_FREQ_DET 0x011c +#define MUX_SEL_EGL 0x0200 +#define MUX_ENABLE_EGL 0x0300 +#define MUX_STAT_EGL 0x0400 +#define DIV_EGL 0x0600 +#define DIV_EGL_PLL_FDET 0x0604 +#define DIV_STAT_EGL 0x0700 +#define DIV_STAT_EGL_PLL_FDET 0x0704 +#define EN_ACLK_EGL 0x0800 +#define EN_PCLK_EGL 0x0900 +#define EN_SCLK_EGL 0x0a00 +#define EN_IP_EGL 0x0b00 +#define CLKOUT_CMU_EGL 0x0c00 +#define CLKOUT_CMU_EGL_DIV_STAT 0x0c04 +#define ARMCLK_STOPCTRL 0x1000 +#define EAGLE_EMA_CTRL 0x1008 +#define EAGLE_EMA_STATUS 0x100c +#define PWR_CTRL 0x1020 +#define PWR_CTRL2 0x1024 +#define CLKSTOP_CTRL 0x1028 +#define INTR_SPREAD_EN 0x1080 +#define INTR_SPREAD_USE_STANDBYWFI 0x1084 +#define INTR_SPREAD_BLOCKING_DURATION 0x1088 +#define CMU_EGL_SPARE0 0x2000 +#define CMU_EGL_SPARE1 0x2004 +#define CMU_EGL_SPARE2 0x2008 +#define CMU_EGL_SPARE3 0x200c +#define CMU_EGL_SPARE4 0x2010 + +/* +*Registers for CMU_FSYS +*/ + +#define MUX_SEL_FSYS0 0x0200 +#define MUX_SEL_FSYS1 0x0204 +#define MUX_ENABLE_FSYS0 0x0300 +#define MUX_ENABLE_FSYS1 0x0304 +#define MUX_STAT_FSYS0 0x0400 +#define MUX_STAT_FSYS1 0x0404 +#define MUX_IGNORE_FSYS0 0x0500 +#define MUX_IGNORE_FSYS1 0x0504 +#define EN_ACLK_FSYS 0x0800 +#define EN_ACLK_FSYS_SECURE_RTIC 0x0804 +#define EN_ACLK_FSYS_SECURE_SMMU_RTIC 0x0808 +#define EN_PCLK_FSYS 0x0900 +#define EN_SCLK_FSYS 0x0a00 +#define EN_IP_FSYS 0x0b00 +#define EN_IP_FSYS_SECURE_RTIC 0x0b04 +#define EN_IP_FSYS_SECURE_SMMU_RTIC 0x0b08 + +/* +*Registers for CMU_G2D +*/ + +#define MUX_SEL_G2D 0x0200 +#define MUX_ENABLE_G2D 0x0300 +#define MUX_STAT_G2D 0x0400 +#define DIV_G2D 0x0600 +#define DIV_STAT_G2D 0x0700 +#define EN_ACLK_G2D 0x0800 +#define EN_ACLK_G2D_SECURE_SSS 0x0804 +#define EN_ACLK_G2D_SECURE_SLIM_SSS 0x0808 +#define EN_ACLK_G2D_SECURE_SMMU_SLIM_SSS 0x080c +#define EN_ACLK_G2D_SECURE_SMMU_SSS 0x0810 +#define EN_ACLK_G2D_SECURE_SMMU_MDMA 0x0814 +#define EN_ACLK_G2D_SECURE_SMMU_G2D 0x0818 +#define EN_PCLK_G2D 0x0900 +#define EN_PCLK_G2D_SECURE_SMMU_SLIM_SSS 0x0904 +#define EN_PCLK_G2D_SECURE_SMMU_SSS 0x0908 +#define EN_PCLK_G2D_SECURE_SMMU_MDMA 0x090c +#define EN_PCLK_G2D_SECURE_SMMU_G2D 0x0910 +#define EN_IP_G2D 0x0b00 +#define EN_IP_G2D_SECURE_SSS 0x0b04 +#define EN_IP_G2D_SECURE_SLIM_SSS 0x0b08 +#define EN_IP_G2D_SECURE_SMMU_SLIM_SSS 0x0b0c +#define EN_IP_G2D_SECURE_SMMU_SSS 0x0b10 +#define EN_IP_G2D_SECURE_SMMU_MDMA 0x0b14 +#define EN_IP_G2D_SECURE_SMMU_G2D 0x0b18 + +/* +*Registers for CMU_G3D +*/ + +#define G3D_PLL_LOCK 0x0000 +#define G3D_PLL_CON0 0x0100 +#define G3D_PLL_CON1 0x0104 +#define G3D_PLL_FDET 0x010c +#define MUX_SEL_G3D 0x0200 +#define MUX_EN_G3D 0x0300 +#define MUX_STAT_G3D 0x0400 +#define MUX_IGNORE_G3D 0x0500 +#define DIV_G3D 0x0600 +#define DIV_G3D_PLL_FDET 0x0604 +#define DIV_STAT_G3D 0x0700 +#define DIV_STAT_G3D_PLL_FDET 0x0704 +#define EN_ACLK_G3D 0x0800 +#define EN_PCLK_G3D 0x0900 +#define EN_SCLK_G3D 0x0a00 +#define EN_IP_G3D 0x0b00 +#define CLKOUT_CMU_G3D 0x0c00 +#define CLKOUT_CMU_G3D_DIV_STAT 0x0c04 +#define G3DCLK_STOPCTRL 0x1000 +#define G3D_EMA_CTRL 0x1008 +#define G3D_EMA_STATUS 0x100c + +/* +*Registers for CMU_GSCL +*/ + +#define MUX_SEL_GSCL 0x0200 +#define MUX_EN_GSCL 0x0300 +#define MUX_STAT_GSCL 0x0400 +#define MUX_IGNORE_GSCL 0x0500 +#define DIV_GSCL 0x0600 +#define DIV_STAT_GSCL 0x0700 +#define EN_ACLK_GSCL 0x0800 +#define EN_ACLK_GSCL_FIMC 0x0804 +#define EN_ACLK_GSCL_SECURE_SMMU_GSCL0 0x0808 +#define EN_ACLK_GSCL_SECURE_SMMU_GSCL1 0x080c +#define EN_ACLK_GSCL_SECURE_SMMU_MSCL0 0x0810 +#define EN_ACLK_GSCL_SECURE_SMMU_MSCL1 0x0814 +#define EN_PCLK_GSCL 0x0900 +#define EN_PCLK_GSCL_FIMC 0x0904 +#define EN_PCLK_GSCL_SECURE_SMMU_GSCL0 0x0908 +#define EN_PCLK_GSCL_SECURE_SMMU_GSCL1 0x090c +#define EN_PCLK_GSCL_SECURE_SMMU_MSCL0 0x0910 +#define EN_PCLK_GSCL_SECURE_SMMU_MSCL1 0x0914 +#define EN_SCLK_GSCL 0x0a00 +#define EN_SCLK_GSCL_FIMC 0x0a04 +#define EN_IP_GSCL 0x0b00 +#define EN_IP_GSCL_FIMC 0x0b04 +#define EN_IP_GSCL_SECURE_SMMU_GSCL0 0x0b08 +#define EN_IP_GSCL_SECURE_SMMU_GSCL1 0x0b0c +#define EN_IP_GSCL_SECURE_SMMU_MSCL0 0x0b10 +#define EN_IP_GSCL_SECURE_SMMU_MSCL1 0x0b14 + +/* +*Registers for CMU_ISP +*/ +#define MUX_SEL_ISP0 0x0200 +#define MUX_SEL_ISP1 0x0204 +#define MUX_ENABLE_ISP0 0x0300 +#define MUX_ENABLE_ISP1 0x0304 +#define MUX_STAT_ISP0 0x0400 +#define MUX_STAT_ISP1 0x0404 +#define MUX_IGNORE_ISP0 0x0500 +#define MUX_IGNORE_ISP1 0x0504 +#define DIV_ISP 0x0600 +#define DIV_STAT_ISP 0x0700 +#define EN_ACLK_ISP0 0x0800 +#define EN_ACLK_ISP1 0x0804 +#define EN_PCLK_ISP0 0x0900 +#define EN_PCLK_ISP1 0x0904 +#define EN_SCLK_ISP 0x0a00 +#define EN_IP_ISP0 0x0b00 +#define EN_IP_ISP1 0x0b04 + +/* +*Registers for CMU_KFC +*/ +#define KFC_PLL_LOCK 0x0000 +#define KFC_PLL_CON0 0x0100 +#define KFC_PLL_CON1 0x0104 +#define KFC_PLL_FDET 0x010c +#define MUX_SEL_KFC0 0x0200 +#define MUX_SEL_KFC2 0x0208 +#define MUX_ENABLE_KFC0 0x0300 +#define MUX_ENABLE_KFC2 0x0308 +#define MUX_STAT_KFC0 0x0400 +#define MUX_STAT_KFC2 0x0408 +#define DIV_KFC 0x0600 +#define DIV_KFC_PLL_FDET 0x0604 +#define DIV_STAT_KFC 0x0700 +#define DIV_STAT_KFC_PLL_FDET 0x0704 +#define EN_ACLK_KFC 0x0800 +#define EN_PCLK_KFC 0x0900 +#define EN_SCLK_KFC 0x0a00 +#define EN_IP_KFC 0x0b00 +#define CLKOUT_CMU_KFC 0x0c00 +#define CLKOUT_CMU_KFC_DIV_STAT 0x0c04 +#define ARMCLK_STOPCTRL_KFC 0x1000 +#define ARM_EMA_CTRL 0x1008 +#define ARM_EMA_STATUS 0x100c +#define PWR_CTRL_KFC 0x1020 +#define PWR_CTRL2_KFC 0x1024 +#define CLKSTOP_CTRL_KFC 0x1028 +#define INTR_SPREAD_ENABLE_KFC 0x1080 +#define INTR_SPREAD_USE_STANDBYWFI_KFC 0x1084 +#define INTR_SPREAD_BLOCKING_DURATION_KFC 0x1088 +#define CMU_KFC_SPARE0 0x2000 +#define CMU_KFC_SPARE1 0x2004 +#define CMU_KFC_SPARE2 0x2008 +#define CMU_KFC_SPARE3 0x200c +#define CMU_KFC_SPARE4 0x2010 + +/* +*Registers for CMU_MFC +*/ +#define MUX_SEL_MFC 0x0200 +#define MUX_ENABLE_MFC 0x0300 +#define MUX_STAT_MFC 0x0400 +#define DIV_MFC 0x0600 +#define DIV_STAT_MFC 0x0700 +#define EN_ACLK_MFC 0x0800 +#define EN_ACLK_SECURE_SMMU2_MFC 0x0804 +#define EN_PCLK_MFC 0x0900 +#define EN_PCLK_SECURE_SMMU2_MFC 0x0904 +#define EN_IP_MFC 0x0b00 +#define EN_IP_MFC_SECURE_SMMU2_MFC 0x0b04 + +/* +*Registers for CMU_MIF +*/ +#define MEM_PLL_LOCK 0x0000 +#define BUS_PLL_LOCK 0x0004 +#define MEDIA_PLL_LOCK 0x0008 +#define MEM_PLL_CON0 0x0100 +#define MEM_PLL_CON1 0x0104 +#define MEM_PLL_FDET 0x010c +#define BUS_PLL_CON0 0x0110 +#define BUS_PLL_CON1 0x0114 +#define BUS_PLL_FDET 0x011c +#define MEDIA_PLL_CON0 0x0120 +#define MEDIA_PLL_CON1 0x0124 +#define MEDIA_PLL_FDET 0x012c +#define MUX_SEL_MIF 0x0200 +#define MUX_ENABLE_MIF 0x0300 +#define MUX_STAT_MIF 0x0400 +#define MUX_IGNORE_MIF 0x0500 +#define DIV_MIF 0x0600 +#define DIV_MIF_PLL_FDET 0x0604 +#define DIV_STAT_MIF 0x0700 +#define DIV_STAT_MIF_PLL_FDET 0x0704 +#define EN_ACLK_MIF 0x0800 +#define EN_ACLK_MIF_SECURE_DREX1_TZ 0x0804 +#define EN_ACLK_MIF_SECURE_DREX0_TZ 0x0808 +#define EN_ACLK_MIF_SECURE_INTMEM 0x080c +#define EN_PCLK_MIF 0x0900 +#define EN_PCLK_MIF_SECURE_MONOCNT 0x0904 +#define EN_PCLK_MIF_SECURE_RTC_APBIF 0x0908 +#define EN_PCLK_MIF_SECURE_DREX1_TZ 0x090c +#define EN_PCLK_MIF_SECURE_DREX0_TZ 0x0910 +#define EN_SCLK_MIF 0x0a00 +#define EN_IP_MIF 0x0b00 +#define EN_IP_MIF_SECURE_MONOCNT 0x0b04 +#define EN_IP_MIF_SECURE_RTC_APBIF 0x0b08 +#define EN_IP_MIF_SECURE_DREX1_TZ 0x0b0c +#define EN_IP_MIF_SECURE_DREX0_TZ 0x0b10 +#define EN_IP_MIF_SECURE_INTEMEM 0x0b14 +#define CLKOUT_CMU_MIF_DIV_STAT 0x0c04 +#define DREX_FREQ_CTRL 0x1000 +#define PAUSE 0x1004 +#define DDRPHY_LOCK_CTRL 0x1008 +#define CLKOUT_CMU_MIF 0xcb00 + +/* +*Registers for CMU_PERI +*/ +#define MUX_SEL_PERI 0x0200 +#define MUX_SEL_PERI1 0x0204 +#define MUX_ENABLE_PERI 0x0300 +#define MUX_ENABLE_PERI1 0x0304 +#define MUX_STAT_PERI 0x0400 +#define MUX_STAT_PERI1 0x0404 +#define MUX_IGNORE_PERI 0x0500 +#define MUX_IGNORE_PERI1 0x0504 +#define DIV_PERI 0x0600 +#define DIV_STAT_PERI 0x0700 +#define EN_PCLK_PERI0 0x0800 +#define EN_PCLK_PERI1 0x0804 +#define EN_PCLK_PERI2 0x0808 +#define EN_PCLK_PERI3 0x080c +#define EN_PCLK_PERI_SECURE_CHIPID 0x0810 +#define EN_PCLK_PERI_SECURE_PROVKEY0 0x0814 +#define EN_PCLK_PERI_SECURE_PROVKEY1 0x0818 +#define EN_PCLK_PERI_SECURE_SECKEY 0x081c +#define EN_PCLK_PERI_SECURE_ANTIRBKCNT 0x0820 +#define EN_PCLK_PERI_SECURE_TOP_RTC 0x0824 +#define EN_PCLK_PERI_SECURE_TZPC 0x0828 +#define EN_SCLK_PERI 0x0a00 +#define EN_SCLK_PERI_SECURE_TOP_RTC 0x0a04 +#define EN_IP_PERI0 0x0b00 +#define EN_IP_PERI1 0x0b04 +#define EN_IP_PERI2 0x0b08 +#define EN_IP_PERI_SECURE_CHIPID 0x0b0c +#define EN_IP_PERI_SECURE_PROVKEY0 0x0b10 +#define EN_IP_PERI_SECURE_PROVKEY1 0x0b14 +#define EN_IP_PERI_SECURE_SECKEY 0x0b18 +#define EN_IP_PERI_SECURE_ANTIRBKCNT 0x0b1c +#define EN_IP_PERI_SECURE_TOP_RTC 0x0b20 +#define EN_IP_PERI_SECURE_TZPC 0x0b24 + +/* +*Registers for CMU_TOP +*/ +#define DISP_PLL_LOCK 0x0000 +#define AUD_PLL_LOCK 0x0004 +#define DISP_PLL_CON0 0x0100 +#define DISP_PLL_CON1 0x0104 +#define DISP_PLL_FDET 0x0108 +#define AUD_PLL_CON0 0x0110 +#define AUD_PLL_CON1 0x0114 +#define AUD_PLL_CON2 0x0118 +#define AUD_PLL_FDET 0x011c +#define MUX_SEL_TOP_PLL0 0x0200 +#define MUX_SEL_TOP_MFC 0x0204 +#define MUX_SEL_TOP_G2D 0x0208 +#define MUX_SEL_TOP_GSCL 0x020c +#define MUX_SEL_TOP_ISP10 0x0214 +#define MUX_SEL_TOP_ISP11 0x0218 +#define MUX_SEL_TOP_DISP0 0x021c +#define MUX_SEL_TOP_DISP1 0x0220 +#define MUX_SEL_TOP_BUS 0x0224 +#define MUX_SEL_TOP_PERI0 0x0228 +#define MUX_SEL_TOP_PERI1 0x022c +#define MUX_SEL_TOP_FSYS 0x0230 +#define MUX_ENABLE_TOP_PLL0 0x0300 +#define MUX_ENABLE_TOP_MFC 0x0304 +#define MUX_ENABLE_TOP_G2D 0x0308 +#define MUX_ENABLE_TOP_GSCL 0x030c +#define MUX_ENABLE_TOP_ISP10 0x0314 +#define MUX_ENABLE_TOP_ISP11 0x0318 +#define MUX_ENABLE_TOP_DISP0 0x031c +#define MUX_ENABLE_TOP_DISP1 0x0320 +#define MUX_ENABLE_TOP_BUS 0x0324 +#define MUX_ENABLE_TOP_PERI0 0x0328 +#define MUX_ENABLE_TOP_PERI1 0x032c +#define MUX_ENABLE_TOP_FSYS 0x0330 +#define MUX_STAT_TOP_PLL0 0x0400 +#define MUX_STAT_TOP_MFC 0x0404 +#define MUX_STAT_TOP_G2D 0x0408 +#define MUX_STAT_TOP_GSCL 0x040c +#define MUX_STAT_TOP_ISP10 0x0414 +#define MUX_STAT_TOP_ISP11 0x0418 +#define MUX_STAT_TOP_DISP0 0x041c +#define MUX_STAT_TOP_DISP1 0x0420 +#define MUX_STAT_TOP_BUS 0x0424 +#define MUX_STAT_TOP_PERI0 0x0428 +#define MUX_STAT_TOP_PERI1 0x042c +#define MUX_STAT_TOP_FSYS 0x0430 +#define MUX_IGNORE_TOP_PLL0 0x0500 +#define MUX_IGNORE_TOP_MFC 0x0504 +#define MUX_IGNORE_TOP_G2D 0x0508 +#define MUX_IGNORE_TOP_GSCL 0x050c +#define MUX_IGNORE_TOP_ISP10 0x0514 +#define MUX_IGNORE_TOP_ISP11 0x0518 +#define MUX_IGNORE_TOP_DISP0 0x051c +#define MUX_IGNORE_TOP_DISP1 0x0520 +#define MUX_IGNORE_TOP_BUS 0x0524 +#define MUX_IGNORE_TOP_PERI0 0x0528 +#define MUX_IGNORE_TOP_PERI1 0x052c +#define MUX_IGNORE_TOP_FSYS 0x0530 +#define DIV_TOP_G2D_MFC 0x0600 +#define DIV_TOP_GSCL_ISP0 0x0604 +#define DIV_TOP_ISP10 0x0608 +#define DIV_TOP_ISP11 0x060c +#define DIV_TOP_DISP 0x0610 +#define DIV_TOP_BUS 0x0614 +#define DIV_TOP_PERI0 0x0618 +#define DIV_TOP_PERI1 0x061c +#define DIV_TOP_PERI2 0x0620 +#define DIV_TOP_FSYS0 0x0624 +#define DIV_TOP_FSYS1 0x0628 +#define DIV_TOP_HPM 0x062c +#define DIV_TOP_PLL_FDET 0x0630 +#define DIV_STAT_TOP_G2D_MFC 0x0700 +#define DIV_STAT_TOP_GSCL_ISP0 0x0704 +#define DIV_STAT_TOP_ISP10 0x0708 +#define DIV_STAT_TOP_ISP11 0x070c +#define DIV_STAT_TOP_DISP 0x0710 +#define DIV_STAT_TOP_BUS 0x0714 +#define DIV_STAT_TOP_PERI0 0x0718 +#define DIV_STAT_TOP_PERI1 0x071c +#define DIV_STAT_TOP_PERI2 0x0720 +#define DIV_STAT_TOP_FSYS0 0x0724 +#define DIV_STAT_TOP_FSYS1 0x0728 +#define DIV_STAT_TOP_HPM 0x072c +#define DIV_STAT_TOP_PLL_FDET 0x0730 +#define EN_ACLK_TOP 0x0800 +#define EN_SCLK_TOP 0x0a00 +#define EN_IP_TOP 0x0b00 +#define CLKOUT_CMU_TOP 0x0c00 +#define CLKOUT_CMU_TOP_DIV_STAT 0x0c04 + +#endif /*__CLK_EXYNOS5260_H */ + -- cgit v1.2.2 From 91a1263fd2bab8704fa0a940c1ab6b813143ecc4 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Thu, 6 Feb 2014 19:33:11 +0100 Subject: clk: samsung: Initialize clock table with error pointers Before this patch, the driver was simply zeroing the clock table, which is incorrect, because invalid clock numbers returned NULL instead of error pointers. This patch fixes this by changing the driver to initialize the array with PTR_ERR(-ENOENT). Signed-off-by: Tomasz Figa Acked-by: Kyungmin Park --- drivers/clk/samsung/clk.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index 41c1461d2f58..ce4d8a25dd61 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -54,14 +54,19 @@ struct samsung_clk_provider *__init samsung_clk_init(struct device_node *np, struct samsung_clk_provider *ctx; struct clk **clk_table; int ret; + int i; + ctx = kzalloc(sizeof(struct samsung_clk_provider), GFP_KERNEL); if (!ctx) panic("could not allocate clock provider context.\n"); - clk_table = kzalloc(sizeof(struct clk *) * nr_clks, GFP_KERNEL); + clk_table = kcalloc(nr_clks, sizeof(struct clk *), GFP_KERNEL); if (!clk_table) panic("could not allocate clock lookup table\n"); + for (i = 0; i < nr_clks; ++i) + clk_table[i] = ERR_PTR(-ENOENT); + ctx->reg_base = base; ctx->clk_data.clks = clk_table; ctx->clk_data.clk_num = nr_clks; -- cgit v1.2.2 From 5b73721b60360163169a8eccd3c4285f4a605d07 Mon Sep 17 00:00:00 2001 From: Naveen Krishna Chatradhi Date: Mon, 17 Feb 2014 15:14:31 +0530 Subject: clk: samsung: exynos5250/5420: Add gate clock for SSS module This patch adds gating clock for SSS(Security SubSystem) module on Exynos5250/5420. Signed-off-by: Naveen Krishna Chatradhi [t.figa: Fixed sort order and group name.] Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5250.c | 1 + drivers/clk/samsung/clk-exynos5420.c | 4 ++++ 2 files changed, 5 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index e549e862524a..d1d53ca45e20 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -428,6 +428,7 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { * CMU_ACP */ GATE(CLK_MDMA0, "mdma0", "div_aclk266", GATE_IP_ACP, 1, 0, 0), + GATE(CLK_SSS, "sss", "div_aclk266", GATE_IP_ACP, 2, 0, 0), GATE(CLK_G2D, "g2d", "div_aclk200", GATE_IP_ACP, 3, 0, 0), GATE(CLK_SMMU_MDMA0, "smmu_mdma0", "div_aclk266", GATE_IP_ACP, 5, 0, 0), diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index c3e0894d0279..a8704540a214 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -27,6 +27,7 @@ #define DIV_CPU1 0x504 #define GATE_BUS_CPU 0x700 #define GATE_SCLK_CPU 0x800 +#define GATE_IP_G2D 0x8800 #define CPLL_LOCK 0x10020 #define DPLL_LOCK 0x10030 #define EPLL_LOCK 0x10040 @@ -515,6 +516,9 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { }; static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { + /* G2D */ + GATE(CLK_SSS, "sss", "aclk266_g2d", GATE_IP_G2D, 2, 0, 0), + /* TODO: Re-verify the CG bits for all the gate clocks */ GATE_A(CLK_MCT, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, "mct"), -- cgit v1.2.2 From 53cb6342dee87c99c61bc4d9f3dd4471936f71e7 Mon Sep 17 00:00:00 2001 From: Sachin Kamat Date: Thu, 13 Mar 2014 08:57:02 +0530 Subject: clk: samsung: exynos5420: Fix VPLL lock offset Set it as per the user manual. Signed-off-by: Sachin Kamat Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index a8704540a214..676a0bdabba0 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -34,7 +34,7 @@ #define RPLL_LOCK 0x10050 #define IPLL_LOCK 0x10060 #define SPLL_LOCK 0x10070 -#define VPLL_LOCK 0x10070 +#define VPLL_LOCK 0x10080 #define MPLL_LOCK 0x10090 #define CPLL_CON0 0x10120 #define DPLL_CON0 0x10128 -- cgit v1.2.2 From 42fb57c008406ab667bcc6e3164cee092c6f35e7 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Wed, 26 Feb 2014 11:42:41 +0900 Subject: clk: samsung: fixed compiler warning [-Wpointer-to-int-cast] When compiled using ARM64 cross compiler, gcc complains as drivers/clk/samsung/clk.c:293:18: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast] Signed-off-by: Pankaj Dubey Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk.c b/drivers/clk/samsung/clk.c index ce4d8a25dd61..49629c71c9e7 100644 --- a/drivers/clk/samsung/clk.c +++ b/drivers/clk/samsung/clk.c @@ -293,7 +293,7 @@ void __init samsung_clk_of_register_fixed_ext(struct samsung_clk_provider *ctx, for_each_matching_node_and_match(clk_np, clk_matches, &match) { if (of_property_read_u32(clk_np, "clock-frequency", &freq)) continue; - fixed_rate_clk[(u32)match->data].fixed_rate = freq; + fixed_rate_clk[(unsigned long)match->data].fixed_rate = freq; } samsung_clk_register_fixed_rate(ctx, fixed_rate_clk, nr_fixed_rate_clk); } -- cgit v1.2.2 From 04bc7d96fbbbd7c379a8351db9f2466b47c74ec2 Mon Sep 17 00:00:00 2001 From: Sylwester Nawrocki Date: Tue, 15 Apr 2014 18:30:20 +0200 Subject: clk: samsung: exynos4: Use single clock ID for CLK_MDMA gate clocks Exynos4210 and Exynos4x12 SoCs have the PL330 MDMA IP block clock defined exactly in same way in documentation. Using different names for these clocks is a bit misleading. Since there is no users of CLK_MDMA2 in existing dts files this patch drops CLK_MDMA2 and replaces it with CLK_MDMA in the driver. This ensures PL330 MDMA has correct clock assigned on Exynos4x12 SoCs. Suggested-by: Tomasz Figa Signed-off-by: Sylwester Nawrocki Acked-by: Kyungmin Park Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 57ed5a8fb052..7e2adcbee4cd 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -903,7 +903,7 @@ static struct samsung_gate_clock exynos4x12_gate_clks[] __initdata = { GATE(CLK_AUDSS, "audss", "sclk_epll", E4X12_GATE_IP_MAUDIO, 0, 0, 0), GATE(CLK_MDNIE0, "mdnie0", "aclk160", GATE_IP_LCD0, 2, 0, 0), GATE(CLK_ROTATOR, "rotator", "aclk200", E4X12_GATE_IP_IMAGE, 1, 0, 0), - GATE(CLK_MDMA2, "mdma2", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0), + GATE(CLK_MDMA, "mdma", "aclk200", E4X12_GATE_IP_IMAGE, 2, 0, 0), GATE(CLK_SMMU_MDMA, "smmu_mdma", "aclk200", E4X12_GATE_IP_IMAGE, 5, 0, 0), GATE(CLK_MIPI_HSI, "mipi_hsi", "aclk133", GATE_IP_FSYS, 10, 0, 0), -- cgit v1.2.2 From 20b82ae27e89739ed8740323913d58efe593ef91 Mon Sep 17 00:00:00 2001 From: Arun Kumar K Date: Mon, 28 Apr 2014 15:07:01 +0530 Subject: clk: samsung: exynos5250: Add clocks for G3D This patch adds the required clocks for ARM Mali IP in Exynos5250. Signed-off-by: Arun Kumar K [t.figa: Changed clock ID to avoid conflict with CLK_SSS] Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5250.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index d1d53ca45e20..88488596c00b 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -37,6 +37,7 @@ #define VPLL_CON0 0x10140 #define GPLL_CON0 0x10150 #define SRC_TOP0 0x10210 +#define SRC_TOP1 0x10214 #define SRC_TOP2 0x10218 #define SRC_TOP3 0x1021c #define SRC_GSCL 0x10220 @@ -71,6 +72,7 @@ #define GATE_IP_GSCL 0x10920 #define GATE_IP_DISP1 0x10928 #define GATE_IP_MFC 0x1092c +#define GATE_IP_G3D 0x10930 #define GATE_IP_GEN 0x10934 #define GATE_IP_FSYS 0x10944 #define GATE_IP_PERIC 0x10950 @@ -100,6 +102,7 @@ static unsigned long exynos5250_clk_regs[] __initdata = { DIV_CPU0, SRC_CORE1, SRC_TOP0, + SRC_TOP1, SRC_TOP2, SRC_TOP3, SRC_GSCL, @@ -133,6 +136,7 @@ static unsigned long exynos5250_clk_regs[] __initdata = { DIV_PERIC5, GATE_IP_GSCL, GATE_IP_MFC, + GATE_IP_G3D, GATE_IP_GEN, GATE_IP_FSYS, GATE_IP_PERIC, @@ -189,10 +193,12 @@ PNAME(mout_vpllsrc_p) = { "fin_pll", "sclk_hdmi27m" }; PNAME(mout_vpll_p) = { "mout_vpllsrc", "fout_vpll" }; PNAME(mout_cpll_p) = { "fin_pll", "fout_cpll" }; PNAME(mout_epll_p) = { "fin_pll", "fout_epll" }; +PNAME(mout_gpll_p) = { "fin_pll", "fout_gpll" }; PNAME(mout_mpll_user_p) = { "fin_pll", "mout_mpll" }; PNAME(mout_bpll_user_p) = { "fin_pll", "mout_bpll" }; PNAME(mout_aclk166_p) = { "mout_cpll", "mout_mpll_user" }; PNAME(mout_aclk200_p) = { "mout_mpll_user", "mout_bpll_user" }; +PNAME(mout_aclk400_p) = { "mout_aclk400_g3d_mid", "mout_gpll" }; PNAME(mout_aclk200_sub_p) = { "fin_pll", "div_aclk200" }; PNAME(mout_aclk266_sub_p) = { "fin_pll", "div_aclk266" }; PNAME(mout_aclk333_sub_p) = { "fin_pll", "div_aclk333" }; @@ -273,12 +279,16 @@ static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { MUX(0, "mout_aclk166", mout_aclk166_p, SRC_TOP0, 8, 1), MUX(0, "mout_aclk200", mout_aclk200_p, SRC_TOP0, 12, 1), MUX(0, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1), + MUX(0, "mout_aclk400_g3d_mid", mout_aclk200_p, SRC_TOP0, 20, 1), + + MUX(0, "mout_aclk400_g3d", mout_aclk400_p, SRC_TOP1, 28, 1), MUX(0, "mout_cpll", mout_cpll_p, SRC_TOP2, 8, 1), MUX(0, "mout_epll", mout_epll_p, SRC_TOP2, 12, 1), MUX(0, "mout_vpll", mout_vpll_p, SRC_TOP2, 16, 1), MUX(0, "mout_mpll_user", mout_mpll_user_p, SRC_TOP2, 20, 1), MUX(0, "mout_bpll_user", mout_bpll_user_p, SRC_TOP2, 24, 1), + MUX(CLK_MOUT_GPLL, "mout_gpll", mout_gpll_p, SRC_TOP2, 28, 1), MUX(0, "mout_aclk200_disp1_sub", mout_aclk200_sub_p, SRC_TOP3, 4, 1), MUX(0, "mout_aclk266_gscl_sub", mout_aclk266_sub_p, SRC_TOP3, 8, 1), @@ -351,6 +361,8 @@ static struct samsung_div_clock exynos5250_div_clks[] __initdata = { DIV(0, "div_aclk200", "mout_aclk200", DIV_TOP0, 12, 3), DIV(0, "div_aclk266", "mout_mpll_user", DIV_TOP0, 16, 3), DIV(0, "div_aclk333", "mout_aclk333", DIV_TOP0, 20, 3), + DIV(0, "div_aclk400_g3d", "mout_aclk400_g3d", DIV_TOP0, + 24, 3), DIV(0, "div_aclk66_pre", "mout_mpll_user", DIV_TOP1, 24, 3), @@ -534,7 +546,8 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { 0), GATE(CLK_SMMU_MFCL, "smmu_mfcl", "mout_aclk333_sub", GATE_IP_MFC, 2, 0, 0), - + GATE(CLK_G3D, "g3d", "div_aclk400_g3d", GATE_IP_G3D, 0, + CLK_SET_RATE_PARENT, 0), GATE(CLK_ROTATOR, "rotator", "div_aclk266", GATE_IP_GEN, 1, 0, 0), GATE(CLK_JPEG, "jpeg", "div_aclk166", GATE_IP_GEN, 2, 0, 0), GATE(CLK_MDMA1, "mdma1", "div_aclk266", GATE_IP_GEN, 4, 0, 0), -- cgit v1.2.2 From a5b219b40c463ff162368c7a1dc93387054c79f5 Mon Sep 17 00:00:00 2001 From: Tomasz Stanislawski Date: Fri, 4 Apr 2014 16:53:19 +0200 Subject: clk: samsung: exynos4: export sclk_hdmiphy clock Export sclk_hdmiphy clock to be usable from DT. Signed-off-by: Tomasz Stanislawski Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos4.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos4.c b/drivers/clk/samsung/clk-exynos4.c index 7e2adcbee4cd..c4df294bb7fb 100644 --- a/drivers/clk/samsung/clk-exynos4.c +++ b/drivers/clk/samsung/clk-exynos4.c @@ -428,7 +428,7 @@ static struct samsung_fixed_rate_clock exynos4_fixed_rate_ext_clks[] __initdata /* fixed rate clocks generated inside the soc */ static struct samsung_fixed_rate_clock exynos4_fixed_rate_clks[] __initdata = { FRATE(0, "sclk_hdmi24m", NULL, CLK_IS_ROOT, 24000000), - FRATE(0, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), + FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 27000000), FRATE(0, "sclk_usbphy0", NULL, CLK_IS_ROOT, 48000000), }; -- cgit v1.2.2 From 2ce262f456550f046da1175b968d754b0862b309 Mon Sep 17 00:00:00 2001 From: Arun Kumar K Date: Mon, 28 Apr 2014 15:50:44 +0530 Subject: clk: samsung: exynos5420: Add clock IDs needed by GPU Adds IDs for the clocks needed by the ARM Mali GPU in exynos5420. Signed-off-by: Arun Kumar K Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 676a0bdabba0..15c884d0628f 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -363,7 +363,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1), MUX(0, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1), MUX(0, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1), - MUX_A(0, "mout_user_aclk_g3d", user_aclk_g3d_p, + MUX_A(CLK_MOUT_G3D, "mout_user_aclk_g3d", user_aclk_g3d_p, SRC_TOP5, 16, 1, "aclkg3d"), MUX(0, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p, SRC_TOP5, 20, 1), @@ -373,7 +373,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP5, 28, 1), MUX(0, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1), - MUX(0, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1), + MUX(CLK_MOUT_VPLL, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1), MUX(0, "sclk_spll", spll_p, SRC_TOP6, 8, 1), MUX(0, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1), MUX(0, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1), -- cgit v1.2.2 From dbd713bb907e83453b4811d585b96a4bc86df619 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:50 +0530 Subject: clk: samsung: exynos5420: Rename mux parent arrays This patch renames the mux parent arrays as per the naming convension followed by the other exynos specific clock drivers. And it also renames "mout_cpu_kfc" clock to "mout_kfc". Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 359 ++++++++++++++++++----------------- 1 file changed, 186 insertions(+), 173 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 15c884d0628f..2ee7ef21909d 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -217,85 +217,92 @@ static void exynos5420_clk_sleep_init(void) {} #endif /* list of all parent clocks */ -PNAME(mspll_cpu_p) = { "sclk_cpll", "sclk_dpll", - "sclk_mpll", "sclk_spll" }; -PNAME(cpu_p) = { "mout_apll" , "mout_mspll_cpu" }; -PNAME(kfc_p) = { "mout_kpll" , "mout_mspll_kfc" }; -PNAME(apll_p) = { "fin_pll", "fout_apll", }; -PNAME(bpll_p) = { "fin_pll", "fout_bpll", }; -PNAME(cpll_p) = { "fin_pll", "fout_cpll", }; -PNAME(dpll_p) = { "fin_pll", "fout_dpll", }; -PNAME(epll_p) = { "fin_pll", "fout_epll", }; -PNAME(ipll_p) = { "fin_pll", "fout_ipll", }; -PNAME(kpll_p) = { "fin_pll", "fout_kpll", }; -PNAME(mpll_p) = { "fin_pll", "fout_mpll", }; -PNAME(rpll_p) = { "fin_pll", "fout_rpll", }; -PNAME(spll_p) = { "fin_pll", "fout_spll", }; -PNAME(vpll_p) = { "fin_pll", "fout_vpll", }; - -PNAME(group1_p) = { "sclk_cpll", "sclk_dpll", "sclk_mpll" }; -PNAME(group2_p) = { "fin_pll", "sclk_cpll", "sclk_dpll", "sclk_mpll", - "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; -PNAME(group3_p) = { "sclk_rpll", "sclk_spll" }; -PNAME(group4_p) = { "sclk_ipll", "sclk_dpll", "sclk_mpll" }; -PNAME(group5_p) = { "sclk_vpll", "sclk_dpll" }; - -PNAME(sw_aclk66_p) = { "dout_aclk66", "sclk_spll" }; -PNAME(aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66" }; - -PNAME(sw_aclk200_fsys_p) = { "dout_aclk200_fsys", "sclk_spll"}; -PNAME(user_aclk200_fsys_p) = { "fin_pll", "mout_sw_aclk200_fsys" }; - -PNAME(sw_aclk200_fsys2_p) = { "dout_aclk200_fsys2", "sclk_spll"}; -PNAME(user_aclk200_fsys2_p) = { "fin_pll", "mout_sw_aclk200_fsys2" }; - -PNAME(sw_aclk200_p) = { "dout_aclk200", "sclk_spll"}; -PNAME(aclk200_disp1_p) = { "fin_pll", "mout_sw_aclk200" }; - -PNAME(sw_aclk400_mscl_p) = { "dout_aclk400_mscl", "sclk_spll"}; -PNAME(user_aclk400_mscl_p) = { "fin_pll", "mout_sw_aclk400_mscl" }; - -PNAME(sw_aclk333_p) = { "dout_aclk333", "sclk_spll"}; -PNAME(user_aclk333_p) = { "fin_pll", "mout_sw_aclk333" }; - -PNAME(sw_aclk166_p) = { "dout_aclk166", "sclk_spll"}; -PNAME(user_aclk166_p) = { "fin_pll", "mout_sw_aclk166" }; - -PNAME(sw_aclk266_p) = { "dout_aclk266", "sclk_spll"}; -PNAME(user_aclk266_p) = { "fin_pll", "mout_sw_aclk266" }; - -PNAME(sw_aclk333_432_gscl_p) = { "dout_aclk333_432_gscl", "sclk_spll"}; -PNAME(user_aclk333_432_gscl_p) = { "fin_pll", "mout_sw_aclk333_432_gscl" }; - -PNAME(sw_aclk300_gscl_p) = { "dout_aclk300_gscl", "sclk_spll"}; -PNAME(user_aclk300_gscl_p) = { "fin_pll", "mout_sw_aclk300_gscl" }; - -PNAME(sw_aclk300_disp1_p) = { "dout_aclk300_disp1", "sclk_spll"}; -PNAME(user_aclk300_disp1_p) = { "fin_pll", "mout_sw_aclk300_disp1" }; - -PNAME(sw_aclk300_jpeg_p) = { "dout_aclk300_jpeg", "sclk_spll"}; -PNAME(user_aclk300_jpeg_p) = { "fin_pll", "mout_sw_aclk300_jpeg" }; - -PNAME(sw_aclk_g3d_p) = { "dout_aclk_g3d", "sclk_spll"}; -PNAME(user_aclk_g3d_p) = { "fin_pll", "mout_sw_aclk_g3d" }; - -PNAME(sw_aclk266_g2d_p) = { "dout_aclk266_g2d", "sclk_spll"}; -PNAME(user_aclk266_g2d_p) = { "fin_pll", "mout_sw_aclk266_g2d" }; - -PNAME(sw_aclk333_g2d_p) = { "dout_aclk333_g2d", "sclk_spll"}; -PNAME(user_aclk333_g2d_p) = { "fin_pll", "mout_sw_aclk333_g2d" }; - -PNAME(audio0_p) = { "fin_pll", "cdclk0", "sclk_dpll", "sclk_mpll", - "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; -PNAME(audio1_p) = { "fin_pll", "cdclk1", "sclk_dpll", "sclk_mpll", - "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; -PNAME(audio2_p) = { "fin_pll", "cdclk2", "sclk_dpll", "sclk_mpll", - "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; -PNAME(spdif_p) = { "fin_pll", "dout_audio0", "dout_audio1", "dout_audio2", - "spdif_extclk", "sclk_ipll", "sclk_epll", "sclk_rpll" }; -PNAME(hdmi_p) = { "dout_hdmi_pixel", "sclk_hdmiphy" }; -PNAME(maudio0_p) = { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll", - "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; +PNAME(mout_mspll_cpu_p) = {"mout_sclk_cpll", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll"}; +PNAME(mout_cpu_p) = {"mout_apll" , "mout_mspll_cpu"}; +PNAME(mout_kfc_p) = {"mout_kpll" , "mout_mspll_kfc"}; +PNAME(mout_apll_p) = {"fin_pll", "fout_apll"}; +PNAME(mout_bpll_p) = {"fin_pll", "fout_bpll"}; +PNAME(mout_cpll_p) = {"fin_pll", "fout_cpll"}; +PNAME(mout_dpll_p) = {"fin_pll", "fout_dpll"}; +PNAME(mout_epll_p) = {"fin_pll", "fout_epll"}; +PNAME(mout_ipll_p) = {"fin_pll", "fout_ipll"}; +PNAME(mout_kpll_p) = {"fin_pll", "fout_kpll"}; +PNAME(mout_mpll_p) = {"fin_pll", "fout_mpll"}; +PNAME(mout_rpll_p) = {"fin_pll", "fout_rpll"}; +PNAME(mout_spll_p) = {"fin_pll", "fout_spll"}; +PNAME(mout_vpll_p) = {"fin_pll", "fout_vpll"}; + +PNAME(mout_group1_p) = {"mout_sclk_cpll", "mout_sclk_dpll", + "mout_sclk_mpll"}; +PNAME(mout_group2_p) = {"fin_pll", "mout_sclk_cpll", + "mout_sclk_dpll", "mout_sclk_mpll", "mout_sclk_spll", + "mout_sclk_ipll", "mout_sclk_epll", "mout_sclk_rpll"}; +PNAME(mout_group3_p) = {"mout_sclk_rpll", "mout_sclk_spll"}; +PNAME(mout_group4_p) = {"mout_sclk_ipll", "mout_sclk_dpll", "mout_sclk_mpll"}; +PNAME(mout_group5_p) = {"mout_sclk_vpll", "mout_sclk_dpll"}; + +PNAME(mout_sw_aclk66_p) = {"dout_aclk66", "mout_sclk_spll"}; +PNAME(mout_aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66" }; + +PNAME(mout_sw_aclk200_fsys_p) = {"dout_aclk200_fsys", "mout_sclk_spll"}; +PNAME(mout_user_aclk200_fsys_p) = {"fin_pll", "mout_sw_aclk200_fsys"}; + +PNAME(mout_sw_aclk200_fsys2_p) = {"dout_aclk200_fsys2", "mout_sclk_spll"}; +PNAME(mout_user_aclk200_fsys2_p) = {"fin_pll", "mout_sw_aclk200_fsys2"}; + +PNAME(mout_sw_aclk200_p) = {"dout_aclk200", "mout_sclk_spll"}; +PNAME(mout_aclk200_disp1_p) = {"fin_pll", "mout_sw_aclk200"}; + +PNAME(mout_sw_aclk400_mscl_p) = {"dout_aclk400_mscl", "mout_sclk_spll"}; +PNAME(mout_user_aclk400_mscl_p) = {"fin_pll", "mout_sw_aclk400_mscl"}; + +PNAME(mout_sw_aclk333_p) = {"dout_aclk333", "mout_sclk_spll"}; +PNAME(mout_user_aclk333_p) = {"fin_pll", "mout_sw_aclk333"}; + +PNAME(mout_sw_aclk166_p) = {"dout_aclk166", "mout_sclk_spll"}; +PNAME(mout_user_aclk166_p) = {"fin_pll", "mout_sw_aclk166"}; + +PNAME(mout_sw_aclk266_p) = {"dout_aclk266", "mout_sclk_spll"}; +PNAME(mout_user_aclk266_p) = {"fin_pll", "mout_sw_aclk266"}; + +PNAME(mout_sw_aclk333_432_gscl_p) = {"dout_aclk333_432_gscl", "mout_sclk_spll"}; +PNAME(mout_user_aclk333_432_gscl_p) = {"fin_pll", "mout_sw_aclk333_432_gscl"}; + +PNAME(mout_sw_aclk300_gscl_p) = {"dout_aclk300_gscl", "mout_sclk_spll"}; +PNAME(mout_user_aclk300_gscl_p) = {"fin_pll", "mout_sw_aclk300_gscl"}; + +PNAME(mout_sw_aclk300_disp1_p) = {"dout_aclk300_disp1", "mout_sclk_spll"}; +PNAME(mout_user_aclk300_disp1_p) = {"fin_pll", "mout_sw_aclk300_disp1"}; + +PNAME(mout_sw_aclk300_jpeg_p) = {"dout_aclk300_jpeg", "mout_sclk_spll"}; +PNAME(mout_user_aclk300_jpeg_p) = {"fin_pll", "mout_sw_aclk300_jpeg"}; + +PNAME(mout_sw_aclk_g3d_p) = {"dout_aclk_g3d", "mout_sclk_spll"}; +PNAME(mout_user_aclk_g3d_p) = {"fin_pll", "mout_sw_aclk_g3d"}; + +PNAME(mout_sw_aclk266_g2d_p) = {"dout_aclk266_g2d", "mout_sclk_spll"}; +PNAME(mout_user_aclk266_g2d_p) = {"fin_pll", "mout_sw_aclk266_g2d"}; + +PNAME(mout_sw_aclk333_g2d_p) = {"dout_aclk333_g2d", "mout_sclk_spll"}; +PNAME(mout_user_aclk333_g2d_p) = {"fin_pll", "mout_sw_aclk333_g2d"}; + +PNAME(mout_audio0_p) = {"fin_pll", "cdclk0", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll", "mout_sclk_ipll", + "mout_sclk_epll", "mout_sclk_rpll"}; +PNAME(mout_audio1_p) = {"fin_pll", "cdclk1", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll", "mout_sclk_ipll", + "mout_sclk_epll", "mout_sclk_rpll"}; +PNAME(mout_audio2_p) = {"fin_pll", "cdclk2", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll", "mout_sclk_ipll", + "mout_sclk_epll", "mout_sclk_rpll"}; +PNAME(mout_spdif_p) = {"fin_pll", "dout_audio0", "dout_audio1", + "dout_audio2", "spdif_extclk", "mout_sclk_ipll", + "mout_sclk_epll", "mout_sclk_rpll"}; +PNAME(mout_hdmi_p) = {"dout_hdmi_pixel", "sclk_hdmiphy"}; +PNAME(mout_maudio0_p) = {"fin_pll", "maudio_clk", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll", "mout_sclk_ipll", + "mout_sclk_epll", "mout_sclk_rpll"}; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = { @@ -316,130 +323,136 @@ static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initda }; static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { - MUX(0, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2), - MUX(0, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2), - MUX(0, "mout_apll", apll_p, SRC_CPU, 0, 1), - MUX(0, "mout_cpu", cpu_p, SRC_CPU, 16, 1), - MUX(0, "mout_kpll", kpll_p, SRC_KFC, 0, 1), - MUX(0, "mout_cpu_kfc", kfc_p, SRC_KFC, 16, 1), + MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2), + MUX(0, "mout_mspll_cpu", mout_mspll_cpu_p, SRC_TOP7, 12, 2), + MUX(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), + MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), + MUX(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1), + MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1), - MUX(0, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1), + MUX(0, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), - MUX_A(0, "mout_aclk400_mscl", group1_p, + MUX_A(0, "mout_aclk400_mscl", mout_group1_p, SRC_TOP0, 4, 2, "aclk400_mscl"), - MUX(0, "mout_aclk200", group1_p, SRC_TOP0, 8, 2), - MUX(0, "mout_aclk200_fsys2", group1_p, SRC_TOP0, 12, 2), - MUX(0, "mout_aclk200_fsys", group1_p, SRC_TOP0, 28, 2), - - MUX(0, "mout_aclk333_432_gscl", group4_p, SRC_TOP1, 0, 2), - MUX(0, "mout_aclk66", group1_p, SRC_TOP1, 8, 2), - MUX(0, "mout_aclk266", group1_p, SRC_TOP1, 20, 2), - MUX(0, "mout_aclk166", group1_p, SRC_TOP1, 24, 2), - MUX(0, "mout_aclk333", group1_p, SRC_TOP1, 28, 2), - - MUX(0, "mout_aclk333_g2d", group1_p, SRC_TOP2, 8, 2), - MUX(0, "mout_aclk266_g2d", group1_p, SRC_TOP2, 12, 2), - MUX(0, "mout_aclk_g3d", group5_p, SRC_TOP2, 16, 1), - MUX(0, "mout_aclk300_jpeg", group1_p, SRC_TOP2, 20, 2), - MUX(0, "mout_aclk300_disp1", group1_p, SRC_TOP2, 24, 2), - MUX(0, "mout_aclk300_gscl", group1_p, SRC_TOP2, 28, 2), - - MUX(0, "mout_user_aclk400_mscl", user_aclk400_mscl_p, + MUX(0, "mout_aclk200", mout_group1_p, SRC_TOP0, 8, 2), + MUX(0, "mout_aclk200_fsys2", mout_group1_p, SRC_TOP0, 12, 2), + MUX(0, "mout_aclk200_fsys", mout_group1_p, SRC_TOP0, 28, 2), + + MUX(0, "mout_aclk333_432_gscl", mout_group4_p, SRC_TOP1, 0, 2), + MUX(0, "mout_aclk66", mout_group1_p, SRC_TOP1, 8, 2), + MUX(0, "mout_aclk266", mout_group1_p, SRC_TOP1, 20, 2), + MUX(0, "mout_aclk166", mout_group1_p, SRC_TOP1, 24, 2), + MUX(0, "mout_aclk333", mout_group1_p, SRC_TOP1, 28, 2), + + MUX(0, "mout_aclk333_g2d", mout_group1_p, SRC_TOP2, 8, 2), + MUX(0, "mout_aclk266_g2d", mout_group1_p, SRC_TOP2, 12, 2), + MUX(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1), + MUX(0, "mout_aclk300_jpeg", mout_group1_p, SRC_TOP2, 20, 2), + MUX(0, "mout_aclk300_disp1", mout_group1_p, SRC_TOP2, 24, 2), + MUX(0, "mout_aclk300_gscl", mout_group1_p, SRC_TOP2, 28, 2), + + MUX(0, "mout_user_aclk400_mscl", mout_user_aclk400_mscl_p, SRC_TOP3, 4, 1), - MUX_A(0, "mout_aclk200_disp1", aclk200_disp1_p, - SRC_TOP3, 8, 1, "aclk200_disp1"), - MUX(0, "mout_user_aclk200_fsys2", user_aclk200_fsys2_p, + MUX(0, "mout_aclk200_disp1", mout_aclk200_disp1_p, SRC_TOP3, 8, 1), + MUX(0, "mout_user_aclk200_fsys2", mout_user_aclk200_fsys2_p, SRC_TOP3, 12, 1), - MUX(0, "mout_user_aclk200_fsys", user_aclk200_fsys_p, + MUX(0, "mout_user_aclk200_fsys", mout_user_aclk200_fsys_p, SRC_TOP3, 28, 1), - MUX(0, "mout_user_aclk333_432_gscl", user_aclk333_432_gscl_p, + MUX(0, "mout_user_aclk333_432_gscl", mout_user_aclk333_432_gscl_p, SRC_TOP4, 0, 1), - MUX(0, "mout_aclk66_peric", aclk66_peric_p, SRC_TOP4, 8, 1), - MUX(0, "mout_user_aclk266", user_aclk266_p, SRC_TOP4, 20, 1), - MUX(0, "mout_user_aclk166", user_aclk166_p, SRC_TOP4, 24, 1), - MUX(0, "mout_user_aclk333", user_aclk333_p, SRC_TOP4, 28, 1), - - MUX(0, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1), - MUX(0, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1), - MUX(0, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1), - MUX_A(CLK_MOUT_G3D, "mout_user_aclk_g3d", user_aclk_g3d_p, + MUX(0, "mout_aclk66_peric", mout_aclk66_peric_p, SRC_TOP4, 8, 1), + MUX(0, "mout_user_aclk266", mout_user_aclk266_p, SRC_TOP4, 20, 1), + MUX(0, "mout_user_aclk166", mout_user_aclk166_p, SRC_TOP4, 24, 1), + MUX(0, "mout_user_aclk333", mout_user_aclk333_p, SRC_TOP4, 28, 1), + + MUX(0, "mout_aclk66_psgen", mout_aclk66_peric_p, SRC_TOP5, 4, 1), + MUX(0, "mout_user_aclk333_g2d", mout_user_aclk333_g2d_p, SRC_TOP5, + 8, 1), + MUX(0, "mout_user_aclk266_g2d", mout_user_aclk266_g2d_p, SRC_TOP5, + 12, 1), + MUX_A(CLK_MOUT_G3D, "mout_user_aclk_g3d", mout_user_aclk_g3d_p, SRC_TOP5, 16, 1, "aclkg3d"), - MUX(0, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p, + MUX(0, "mout_user_aclk300_jpeg", mout_user_aclk300_jpeg_p, SRC_TOP5, 20, 1), - MUX(0, "mout_user_aclk300_disp1", user_aclk300_disp1_p, + MUX(0, "mout_user_aclk300_disp1", mout_user_aclk300_disp1_p, SRC_TOP5, 24, 1), - MUX(0, "mout_user_aclk300_gscl", user_aclk300_gscl_p, + MUX(0, "mout_user_aclk300_gscl", mout_user_aclk300_gscl_p, SRC_TOP5, 28, 1), - MUX(0, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1), - MUX(CLK_MOUT_VPLL, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1), - MUX(0, "sclk_spll", spll_p, SRC_TOP6, 8, 1), - MUX(0, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1), - MUX(0, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1), - MUX(0, "sclk_epll", epll_p, SRC_TOP6, 20, 1), - MUX(0, "sclk_dpll", dpll_p, SRC_TOP6, 24, 1), - MUX(0, "sclk_cpll", cpll_p, SRC_TOP6, 28, 1), - - MUX(0, "mout_sw_aclk400_mscl", sw_aclk400_mscl_p, SRC_TOP10, 4, 1), - MUX(0, "mout_sw_aclk200", sw_aclk200_p, SRC_TOP10, 8, 1), - MUX(0, "mout_sw_aclk200_fsys2", sw_aclk200_fsys2_p, + MUX(0, "mout_sclk_mpll", mout_mpll_p, SRC_TOP6, 0, 1), + MUX(CLK_MOUT_VPLL, "mout_sclk_vpll", mout_vpll_p, SRC_TOP6, 4, 1), + MUX(0, "mout_sclk_spll", mout_spll_p, SRC_TOP6, 8, 1), + MUX(0, "mout_sclk_ipll", mout_ipll_p, SRC_TOP6, 12, 1), + MUX(0, "mout_sclk_rpll", mout_rpll_p, SRC_TOP6, 16, 1), + MUX(0, "mout_sclk_epll", mout_epll_p, SRC_TOP6, 20, 1), + MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), + MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), + + MUX(0, "mout_sw_aclk400_mscl", mout_sw_aclk400_mscl_p, + SRC_TOP10, 4, 1), + MUX(0, "mout_sw_aclk200", mout_sw_aclk200_p, SRC_TOP10, 8, 1), + MUX(0, "mout_sw_aclk200_fsys2", mout_sw_aclk200_fsys2_p, SRC_TOP10, 12, 1), - MUX(0, "mout_sw_aclk200_fsys", sw_aclk200_fsys_p, SRC_TOP10, 28, 1), - - MUX(0, "mout_sw_aclk333_432_gscl", sw_aclk333_432_gscl_p, + MUX(0, "mout_sw_aclk200_fsys", mout_sw_aclk200_fsys_p, + SRC_TOP10, 28, 1), + MUX(0, "mout_sw_aclk333_432_gscl", mout_sw_aclk333_432_gscl_p, SRC_TOP11, 0, 1), - MUX(0, "mout_sw_aclk66", sw_aclk66_p, SRC_TOP11, 8, 1), - MUX(0, "mout_sw_aclk266", sw_aclk266_p, SRC_TOP11, 20, 1), - MUX(0, "mout_sw_aclk166", sw_aclk166_p, SRC_TOP11, 24, 1), - MUX(0, "mout_sw_aclk333", sw_aclk333_p, SRC_TOP11, 28, 1), - - MUX(0, "mout_sw_aclk333_g2d", sw_aclk333_g2d_p, SRC_TOP12, 8, 1), - MUX(0, "mout_sw_aclk266_g2d", sw_aclk266_g2d_p, SRC_TOP12, 12, 1), - MUX(0, "mout_sw_aclk_g3d", sw_aclk_g3d_p, SRC_TOP12, 16, 1), - MUX(0, "mout_sw_aclk300_jpeg", sw_aclk300_jpeg_p, SRC_TOP12, 20, 1), - MUX(0, "mout_sw_aclk300_disp1", sw_aclk300_disp1_p, + MUX(0, "mout_sw_aclk66", mout_sw_aclk66_p, SRC_TOP11, 8, 1), + MUX(0, "mout_sw_aclk266", mout_sw_aclk266_p, SRC_TOP11, 20, 1), + MUX(0, "mout_sw_aclk166", mout_sw_aclk166_p, SRC_TOP11, 24, 1), + MUX(0, "mout_sw_aclk333", mout_sw_aclk333_p, SRC_TOP11, 28, 1), + + MUX(0, "mout_sw_aclk333_g2d", mout_sw_aclk333_g2d_p, + SRC_TOP12, 8, 1), + MUX(0, "mout_sw_aclk266_g2d", mout_sw_aclk266_g2d_p, + SRC_TOP12, 12, 1), + MUX(0, "mout_sw_aclk_g3d", mout_sw_aclk_g3d_p, SRC_TOP12, 16, 1), + MUX(0, "mout_sw_aclk300_jpeg", mout_sw_aclk300_jpeg_p, + SRC_TOP12, 20, 1), + MUX(0, "mout_sw_aclk300_disp1", mout_sw_aclk300_disp1_p, SRC_TOP12, 24, 1), - MUX(0, "mout_sw_aclk300_gscl", sw_aclk300_gscl_p, SRC_TOP12, 28, 1), + MUX(0, "mout_sw_aclk300_gscl", mout_sw_aclk300_gscl_p, + SRC_TOP12, 28, 1), /* DISP1 Block */ - MUX(0, "mout_fimd1", group3_p, SRC_DISP10, 4, 1), - MUX(0, "mout_mipi1", group2_p, SRC_DISP10, 16, 3), - MUX(0, "mout_dp1", group2_p, SRC_DISP10, 20, 3), - MUX(0, "mout_pixel", group2_p, SRC_DISP10, 24, 3), - MUX(CLK_MOUT_HDMI, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1), + MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1), + MUX(0, "mout_mipi1", mout_group2_p, SRC_DISP10, 16, 3), + MUX(0, "mout_dp1", mout_group2_p, SRC_DISP10, 20, 3), + MUX(0, "mout_pixel", mout_group2_p, SRC_DISP10, 24, 3), + MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP10, 28, 1), /* MAU Block */ - MUX(0, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3), + MUX(0, "mout_maudio0", mout_maudio0_p, SRC_MAU, 28, 3), /* FSYS Block */ - MUX(0, "mout_usbd301", group2_p, SRC_FSYS, 4, 3), - MUX(0, "mout_mmc0", group2_p, SRC_FSYS, 8, 3), - MUX(0, "mout_mmc1", group2_p, SRC_FSYS, 12, 3), - MUX(0, "mout_mmc2", group2_p, SRC_FSYS, 16, 3), - MUX(0, "mout_usbd300", group2_p, SRC_FSYS, 20, 3), - MUX(0, "mout_unipro", group2_p, SRC_FSYS, 24, 3), + MUX(0, "mout_usbd301", mout_group2_p, SRC_FSYS, 4, 3), + MUX(0, "mout_mmc0", mout_group2_p, SRC_FSYS, 8, 3), + MUX(0, "mout_mmc1", mout_group2_p, SRC_FSYS, 12, 3), + MUX(0, "mout_mmc2", mout_group2_p, SRC_FSYS, 16, 3), + MUX(0, "mout_usbd300", mout_group2_p, SRC_FSYS, 20, 3), + MUX(0, "mout_unipro", mout_group2_p, SRC_FSYS, 24, 3), /* PERIC Block */ - MUX(0, "mout_uart0", group2_p, SRC_PERIC0, 4, 3), - MUX(0, "mout_uart1", group2_p, SRC_PERIC0, 8, 3), - MUX(0, "mout_uart2", group2_p, SRC_PERIC0, 12, 3), - MUX(0, "mout_uart3", group2_p, SRC_PERIC0, 16, 3), - MUX(0, "mout_pwm", group2_p, SRC_PERIC0, 24, 3), - MUX(0, "mout_spdif", spdif_p, SRC_PERIC0, 28, 3), - MUX(0, "mout_audio0", audio0_p, SRC_PERIC1, 8, 3), - MUX(0, "mout_audio1", audio1_p, SRC_PERIC1, 12, 3), - MUX(0, "mout_audio2", audio2_p, SRC_PERIC1, 16, 3), - MUX(0, "mout_spi0", group2_p, SRC_PERIC1, 20, 3), - MUX(0, "mout_spi1", group2_p, SRC_PERIC1, 24, 3), - MUX(0, "mout_spi2", group2_p, SRC_PERIC1, 28, 3), + MUX(0, "mout_uart0", mout_group2_p, SRC_PERIC0, 4, 3), + MUX(0, "mout_uart1", mout_group2_p, SRC_PERIC0, 8, 3), + MUX(0, "mout_uart2", mout_group2_p, SRC_PERIC0, 12, 3), + MUX(0, "mout_uart3", mout_group2_p, SRC_PERIC0, 16, 3), + MUX(0, "mout_pwm", mout_group2_p, SRC_PERIC0, 24, 3), + MUX(0, "mout_spdif", mout_spdif_p, SRC_PERIC0, 28, 3), + MUX(0, "mout_audio0", mout_audio0_p, SRC_PERIC1, 8, 3), + MUX(0, "mout_audio1", mout_audio1_p, SRC_PERIC1, 12, 3), + MUX(0, "mout_audio2", mout_audio2_p, SRC_PERIC1, 16, 3), + MUX(0, "mout_spi0", mout_group2_p, SRC_PERIC1, 20, 3), + MUX(0, "mout_spi1", mout_group2_p, SRC_PERIC1, 24, 3), + MUX(0, "mout_spi2", mout_group2_p, SRC_PERIC1, 28, 3), }; static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), DIV(0, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), DIV(0, "armclk2", "div_arm", DIV_CPU0, 28, 3), - DIV(0, "div_kfc", "mout_cpu_kfc", DIV_KFC0, 0, 3), + DIV(0, "div_kfc", "mout_kfc", DIV_KFC0, 0, 3), DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3), DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), -- cgit v1.2.2 From 3a767b35c6c2f2e5f75e22a429b4d6d8c6736626 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:51 +0530 Subject: clk: samsung: exynos5420: add clocks for ISP block This patch adds minimum set of clocks to gate ISP block for power saving. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 86 ++++++++++++++++++++++++++++++++++++ 1 file changed, 86 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 2ee7ef21909d..c7e66219434f 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -57,6 +57,7 @@ #define SRC_FSYS 0x10244 #define SRC_PERIC0 0x10250 #define SRC_PERIC1 0x10254 +#define SRC_ISP 0x10270 #define SRC_TOP10 0x10280 #define SRC_TOP11 0x10284 #define SRC_TOP12 0x10288 @@ -77,12 +78,15 @@ #define DIV_PERIC2 0x10560 #define DIV_PERIC3 0x10564 #define DIV_PERIC4 0x10568 +#define SCLK_DIV_ISP0 0x10580 +#define SCLK_DIV_ISP1 0x10584 #define GATE_BUS_TOP 0x10700 #define GATE_BUS_FSYS0 0x10740 #define GATE_BUS_PERIC 0x10750 #define GATE_BUS_PERIC1 0x10754 #define GATE_BUS_PERIS0 0x10760 #define GATE_BUS_PERIS1 0x10764 +#define GATE_TOP_SCLK_ISP 0x10870 #define GATE_IP_GSCL0 0x10910 #define GATE_IP_GSCL1 0x10920 #define GATE_IP_MFC 0x1092c @@ -145,6 +149,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { SRC_MASK_FSYS, SRC_MASK_PERIC0, SRC_MASK_PERIC1, + SRC_ISP, DIV_TOP0, DIV_TOP1, DIV_TOP2, @@ -158,12 +163,15 @@ static unsigned long exynos5420_clk_regs[] __initdata = { DIV_PERIC2, DIV_PERIC3, DIV_PERIC4, + SCLK_DIV_ISP0, + SCLK_DIV_ISP1, GATE_BUS_TOP, GATE_BUS_FSYS0, GATE_BUS_PERIC, GATE_BUS_PERIC1, GATE_BUS_PERIS0, GATE_BUS_PERIS1, + GATE_TOP_SCLK_ISP, GATE_IP_GSCL0, GATE_IP_GSCL1, GATE_IP_MFC, @@ -250,6 +258,15 @@ PNAME(mout_user_aclk200_fsys_p) = {"fin_pll", "mout_sw_aclk200_fsys"}; PNAME(mout_sw_aclk200_fsys2_p) = {"dout_aclk200_fsys2", "mout_sclk_spll"}; PNAME(mout_user_aclk200_fsys2_p) = {"fin_pll", "mout_sw_aclk200_fsys2"}; +PNAME(mout_sw_aclk400_isp_p) = {"dout_aclk400_isp", "mout_sclk_spll"}; +PNAME(mout_user_aclk400_isp_p) = {"fin_pll", "mout_sw_aclk400_isp"}; + +PNAME(mout_sw_aclk333_432_isp0_p) = {"dout_aclk333_432_isp0", + "mout_sclk_spll"}; +PNAME(mout_user_aclk333_432_isp0_p) = {"fin_pll", "mout_sw_aclk333_432_isp0"}; + +PNAME(mout_sw_aclk333_432_isp_p) = {"dout_aclk333_432_isp", "mout_sclk_spll"}; +PNAME(mout_user_aclk333_432_isp_p) = {"fin_pll", "mout_sw_aclk333_432_isp"}; PNAME(mout_sw_aclk200_p) = {"dout_aclk200", "mout_sclk_spll"}; PNAME(mout_aclk200_disp1_p) = {"fin_pll", "mout_sw_aclk200"}; @@ -265,6 +282,7 @@ PNAME(mout_user_aclk166_p) = {"fin_pll", "mout_sw_aclk166"}; PNAME(mout_sw_aclk266_p) = {"dout_aclk266", "mout_sclk_spll"}; PNAME(mout_user_aclk266_p) = {"fin_pll", "mout_sw_aclk266"}; +PNAME(mout_user_aclk266_isp_p) = {"fin_pll", "mout_sw_aclk266"}; PNAME(mout_sw_aclk333_432_gscl_p) = {"dout_aclk333_432_gscl", "mout_sclk_spll"}; PNAME(mout_user_aclk333_432_gscl_p) = {"fin_pll", "mout_sw_aclk333_432_gscl"}; @@ -332,6 +350,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), + MUX(0, "mout_aclk400_isp", mout_group1_p, SRC_TOP0, 0, 2), MUX_A(0, "mout_aclk400_mscl", mout_group1_p, SRC_TOP0, 4, 2, "aclk400_mscl"), MUX(0, "mout_aclk200", mout_group1_p, SRC_TOP0, 8, 2), @@ -339,7 +358,10 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_aclk200_fsys", mout_group1_p, SRC_TOP0, 28, 2), MUX(0, "mout_aclk333_432_gscl", mout_group4_p, SRC_TOP1, 0, 2), + MUX(0, "mout_aclk333_432_isp", mout_group4_p, + SRC_TOP1, 4, 2), MUX(0, "mout_aclk66", mout_group1_p, SRC_TOP1, 8, 2), + MUX(0, "mout_aclk333_432_isp0", mout_group4_p, SRC_TOP1, 12, 2), MUX(0, "mout_aclk266", mout_group1_p, SRC_TOP1, 20, 2), MUX(0, "mout_aclk166", mout_group1_p, SRC_TOP1, 24, 2), MUX(0, "mout_aclk333", mout_group1_p, SRC_TOP1, 28, 2), @@ -351,6 +373,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_aclk300_disp1", mout_group1_p, SRC_TOP2, 24, 2), MUX(0, "mout_aclk300_gscl", mout_group1_p, SRC_TOP2, 28, 2), + MUX(0, "mout_user_aclk400_isp", mout_user_aclk400_isp_p, + SRC_TOP3, 0, 1), MUX(0, "mout_user_aclk400_mscl", mout_user_aclk400_mscl_p, SRC_TOP3, 4, 1), MUX(0, "mout_aclk200_disp1", mout_aclk200_disp1_p, SRC_TOP3, 8, 1), @@ -361,7 +385,13 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_user_aclk333_432_gscl", mout_user_aclk333_432_gscl_p, SRC_TOP4, 0, 1), + MUX(0, "mout_user_aclk333_432_isp", mout_user_aclk333_432_isp_p, + SRC_TOP4, 4, 1), MUX(0, "mout_aclk66_peric", mout_aclk66_peric_p, SRC_TOP4, 8, 1), + MUX(0, "mout_user_aclk333_432_isp0", mout_user_aclk333_432_isp0_p, + SRC_TOP4, 12, 1), + MUX(0, "mout_user_aclk266_isp", mout_user_aclk266_isp_p, + SRC_TOP4, 16, 1), MUX(0, "mout_user_aclk266", mout_user_aclk266_p, SRC_TOP4, 20, 1), MUX(0, "mout_user_aclk166", mout_user_aclk166_p, SRC_TOP4, 24, 1), MUX(0, "mout_user_aclk333", mout_user_aclk333_p, SRC_TOP4, 28, 1), @@ -389,6 +419,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_sclk_dpll", mout_dpll_p, SRC_TOP6, 24, 1), MUX(0, "mout_sclk_cpll", mout_cpll_p, SRC_TOP6, 28, 1), + MUX(0, "mout_sw_aclk400_isp", mout_sw_aclk400_isp_p, + SRC_TOP10, 0, 1), MUX(0, "mout_sw_aclk400_mscl", mout_sw_aclk400_mscl_p, SRC_TOP10, 4, 1), MUX(0, "mout_sw_aclk200", mout_sw_aclk200_p, SRC_TOP10, 8, 1), @@ -396,9 +428,14 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP10, 12, 1), MUX(0, "mout_sw_aclk200_fsys", mout_sw_aclk200_fsys_p, SRC_TOP10, 28, 1), + MUX(0, "mout_sw_aclk333_432_gscl", mout_sw_aclk333_432_gscl_p, SRC_TOP11, 0, 1), + MUX(0, "mout_sw_aclk333_432_isp", mout_sw_aclk333_432_isp_p, + SRC_TOP11, 4, 1), MUX(0, "mout_sw_aclk66", mout_sw_aclk66_p, SRC_TOP11, 8, 1), + MUX(0, "mout_sw_aclk333_432_isp0", mout_sw_aclk333_432_isp0_p, + SRC_TOP11, 12, 1), MUX(0, "mout_sw_aclk266", mout_sw_aclk266_p, SRC_TOP11, 20, 1), MUX(0, "mout_sw_aclk166", mout_sw_aclk166_p, SRC_TOP11, 24, 1), MUX(0, "mout_sw_aclk333", mout_sw_aclk333_p, SRC_TOP11, 28, 1), @@ -446,6 +483,13 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_spi0", mout_group2_p, SRC_PERIC1, 20, 3), MUX(0, "mout_spi1", mout_group2_p, SRC_PERIC1, 24, 3), MUX(0, "mout_spi2", mout_group2_p, SRC_PERIC1, 28, 3), + + /* ISP Block */ + MUX(0, "mout_pwm_isp", mout_group2_p, SRC_ISP, 24, 3), + MUX(0, "mout_uart_isp", mout_group2_p, SRC_ISP, 20, 3), + MUX(0, "mout_spi0_isp", mout_group2_p, SRC_ISP, 12, 3), + MUX(0, "mout_spi1_isp", mout_group2_p, SRC_ISP, 16, 3), + MUX(0, "mout_isp_sensor", mout_group2_p, SRC_ISP, 28, 3), }; static struct samsung_div_clock exynos5420_div_clks[] __initdata = { @@ -455,6 +499,7 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "div_kfc", "mout_kfc", DIV_KFC0, 0, 3), DIV(0, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3), + DIV(0, "dout_aclk400_isp", "mout_aclk400_isp", DIV_TOP0, 0, 3), DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), @@ -463,7 +508,11 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl", DIV_TOP1, 0, 3), + DIV(0, "dout_aclk333_432_isp", "mout_aclk333_432_isp", + DIV_TOP1, 4, 3), DIV(0, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6), + DIV(0, "dout_aclk333_432_isp0", "mout_aclk333_432_isp0", + DIV_TOP1, 16, 3), DIV(0, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3), DIV(0, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3), DIV(0, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3), @@ -526,6 +575,19 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8), DIV(0, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8), DIV(0, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8), + + /* ISP Block */ + DIV(0, "dout_isp_sensor0", "mout_isp_sensor", SCLK_DIV_ISP0, 8, 8), + DIV(0, "dout_isp_sensor1", "mout_isp_sensor", SCLK_DIV_ISP0, 16, 8), + DIV(0, "dout_isp_sensor2", "mout_isp_sensor", SCLK_DIV_ISP0, 24, 8), + DIV(0, "dout_pwm_isp", "mout_pwm_isp", SCLK_DIV_ISP1, 28, 4), + DIV(0, "dout_uart_isp", "mout_uart_isp", SCLK_DIV_ISP1, 24, 4), + DIV(0, "dout_spi0_isp", "mout_spi0_isp", SCLK_DIV_ISP1, 16, 4), + DIV(0, "dout_spi1_isp", "mout_spi1_isp", SCLK_DIV_ISP1, 20, 4), + DIV_F(0, "dout_spi0_isp_pre", "dout_spi0_isp", SCLK_DIV_ISP1, 0, 8, + CLK_SET_RATE_PARENT, 0), + DIV_F(0, "dout_spi1_isp_pre", "dout_spi1_isp", SCLK_DIV_ISP1, 8, 8, + CLK_SET_RATE_PARENT, 0), }; static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { @@ -547,20 +609,28 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_BUS_TOP, 1, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk300_jpeg", "mout_user_aclk300_jpeg", GATE_BUS_TOP, 4, CLK_IGNORE_UNUSED, 0), + GATE(0, "aclk333_432_isp0", "mout_user_aclk333_432_isp0", + GATE_BUS_TOP, 5, 0, 0), GATE(0, "aclk300_gscl", "mout_user_aclk300_gscl", GATE_BUS_TOP, 6, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk333_432_gscl", "mout_user_aclk333_432_gscl", GATE_BUS_TOP, 7, CLK_IGNORE_UNUSED, 0), + GATE(0, "aclk333_432_isp", "mout_user_aclk333_432_isp", + GATE_BUS_TOP, 8, 0, 0), GATE(0, "pclk66_gpio", "mout_sw_aclk66", GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk66_psgen", "mout_aclk66_psgen", GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk66_peric", "mout_aclk66_peric", GATE_BUS_TOP, 11, 0, 0), + GATE(0, "aclk266_isp", "mout_user_aclk266_isp", + GATE_BUS_TOP, 13, 0, 0), GATE(0, "aclk166", "mout_user_aclk166", GATE_BUS_TOP, 14, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk333", "mout_aclk333", GATE_BUS_TOP, 15, CLK_IGNORE_UNUSED, 0), + GATE(0, "aclk400_isp", "mout_user_aclk400_isp", + GATE_BUS_TOP, 16, 0, 0), /* sclk */ GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", @@ -735,6 +805,22 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "aclk300_disp1", GATE_IP_DISP1, 8, 0, 0), + /* ISP */ + GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "dout_uart_isp", + GATE_TOP_SCLK_ISP, 0, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI0_ISP, "sclk_spi0_isp", "dout_spi0_isp_pre", + GATE_TOP_SCLK_ISP, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI1_ISP, "sclk_spi1_isp", "dout_spi1_isp_pre", + GATE_TOP_SCLK_ISP, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PWM_ISP, "sclk_pwm_isp", "dout_pwm_isp", + GATE_TOP_SCLK_ISP, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_ISP_SENSOR0, "sclk_isp_sensor0", "dout_isp_sensor0", + GATE_TOP_SCLK_ISP, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_ISP_SENSOR1, "sclk_isp_sensor1", "dout_isp_sensor1", + GATE_TOP_SCLK_ISP, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_ISP_SENSOR2, "sclk_isp_sensor2", "dout_isp_sensor2", + GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0), + GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), GATE(CLK_SMMU_MFCL, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0), GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0), -- cgit v1.2.2 From 02932381ca1d9ab894c893b28fed288d6bae011b Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:52 +0530 Subject: clk: samsung: exynos5420: update clocks for GSCL and MSCL blocks This patch adds the missing GSCL and MSCL block clocks and corrects some wrong parent-child relationships. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 71 ++++++++++++++++++++++-------------- 1 file changed, 44 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index c7e66219434f..cb7a63913e18 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -80,6 +80,7 @@ #define DIV_PERIC4 0x10568 #define SCLK_DIV_ISP0 0x10580 #define SCLK_DIV_ISP1 0x10584 +#define DIV2_RATIO0 0x10590 #define GATE_BUS_TOP 0x10700 #define GATE_BUS_FSYS0 0x10740 #define GATE_BUS_PERIC 0x10750 @@ -165,6 +166,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { DIV_PERIC4, SCLK_DIV_ISP0, SCLK_DIV_ISP1, + DIV2_RATIO0, GATE_BUS_TOP, GATE_BUS_FSYS0, GATE_BUS_PERIC, @@ -576,6 +578,11 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8), DIV(0, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8), + /* GSCL Block */ + DIV(0, "dout_gscl_blk_300", "mout_user_aclk300_gscl", + DIV2_RATIO0, 4, 2), + DIV(0, "dout_gscl_blk_333", "aclk333_432_gscl", DIV2_RATIO0, 6, 2), + /* ISP Block */ DIV(0, "dout_isp_sensor0", "mout_isp_sensor", SCLK_DIV_ISP0, 8, 8), DIV(0, "dout_isp_sensor1", "mout_isp_sensor", SCLK_DIV_ISP0, 16, 8), @@ -631,6 +638,8 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_BUS_TOP, 15, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk400_isp", "mout_user_aclk400_isp", GATE_BUS_TOP, 16, 0, 0), + GATE(0, "aclk400_mscl", "mout_user_aclk400_mscl", + GATE_BUS_TOP, 17, 0, 0), /* sclk */ GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", @@ -678,11 +687,6 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SCLK_USBD301, "sclk_unipro", "dout_unipro", SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa", "aclK333_432_gscl", - GATE_TOP_SCLK_GSCL, 6, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "aclk333_432_gscl", - GATE_TOP_SCLK_GSCL, 7, CLK_SET_RATE_PARENT, 0), - /* Display */ GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0), @@ -776,27 +780,49 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_BUS_PERIS1, 5, 0, 0), GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_BUS_PERIS1, 6, 0, 0), + /* GSCL Block */ + GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa", "mout_user_aclk333_432_gscl", + GATE_TOP_SCLK_GSCL, 6, 0, 0), + GATE(CLK_SCLK_GSCL_WB, "sclk_gscl_wb", "mout_user_aclk333_432_gscl", + GATE_TOP_SCLK_GSCL, 7, 0, 0), + GATE(CLK_GSCL0, "gscl0", "aclk300_gscl", GATE_IP_GSCL0, 0, 0, 0), GATE(CLK_GSCL1, "gscl1", "aclk300_gscl", GATE_IP_GSCL0, 1, 0, 0), - GATE(CLK_CLK_3AA, "clk_3aa", "aclk300_gscl", GATE_IP_GSCL0, 4, 0, 0), - - GATE(CLK_SMMU_3AA, "smmu_3aa", "aclk333_432_gscl", GATE_IP_GSCL1, 2, 0, - 0), - GATE(CLK_SMMU_FIMCL0, "smmu_fimcl0", "aclk333_432_gscl", + GATE(CLK_FIMC_3AA, "fimc_3aa", "aclk333_432_gscl", + GATE_IP_GSCL0, 4, 0, 0), + GATE(CLK_FIMC_LITE0, "fimc_lite0", "aclk333_432_gscl", + GATE_IP_GSCL0, 5, 0, 0), + GATE(CLK_FIMC_LITE1, "fimc_lite1", "aclk333_432_gscl", + GATE_IP_GSCL0, 6, 0, 0), + + GATE(CLK_SMMU_3AA, "smmu_3aa", "dout_gscl_blk_333", + GATE_IP_GSCL1, 2, 0, 0), + GATE(CLK_SMMU_FIMCL0, "smmu_fimcl0", "dout_gscl_blk_333", GATE_IP_GSCL1, 3, 0, 0), - GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "aclk333_432_gscl", + GATE(CLK_SMMU_FIMCL1, "smmu_fimcl1", "dout_gscl_blk_333", GATE_IP_GSCL1, 4, 0, 0), - GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "aclk300_gscl", GATE_IP_GSCL1, 6, 0, - 0), - GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "aclk300_gscl", GATE_IP_GSCL1, 7, 0, - 0), - GATE(CLK_GSCL_WA, "gscl_wa", "aclk300_gscl", GATE_IP_GSCL1, 12, 0, 0), - GATE(CLK_GSCL_WB, "gscl_wb", "aclk300_gscl", GATE_IP_GSCL1, 13, 0, 0), - GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "aclk333_432_gscl", + GATE(CLK_SMMU_GSCL0, "smmu_gscl0", "dout_gscl_blk_300", + GATE_IP_GSCL1, 6, 0, 0), + GATE(CLK_SMMU_GSCL1, "smmu_gscl1", "dout_gscl_blk_300", + GATE_IP_GSCL1, 7, 0, 0), + GATE(CLK_GSCL_WA, "gscl_wa", "sclk_gscl_wa", GATE_IP_GSCL1, 12, 0, 0), + GATE(CLK_GSCL_WB, "gscl_wb", "sclk_gscl_wb", GATE_IP_GSCL1, 13, 0, 0), + GATE(CLK_SMMU_FIMCL3, "smmu_fimcl3,", "dout_gscl_blk_333", GATE_IP_GSCL1, 16, 0, 0), GATE(CLK_FIMC_LITE3, "fimc_lite3", "aclk333_432_gscl", GATE_IP_GSCL1, 17, 0, 0), + /* MSCL Block */ + GATE(CLK_MSCL0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0), + GATE(CLK_MSCL1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0), + GATE(CLK_MSCL2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0), + GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "aclk400_mscl", + GATE_IP_MSCL, 8, 0, 0), + GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "aclk400_mscl", + GATE_IP_MSCL, 9, 0, 0), + GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "aclk400_mscl", + GATE_IP_MSCL, 10, 0, 0), + GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0), GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0), GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0), @@ -835,15 +861,6 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SMMU_JPEG, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0), GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0), - GATE(CLK_MSCL0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0), - GATE(CLK_MSCL1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0), - GATE(CLK_MSCL2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0), - GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "aclk400_mscl", GATE_IP_MSCL, 8, 0, - 0), - GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "aclk400_mscl", GATE_IP_MSCL, 9, 0, - 0), - GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "aclk400_mscl", GATE_IP_MSCL, 10, 0, - 0), GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1", GATE_IP_DISP1, 9, 0, 0), }; -- cgit v1.2.2 From 4549d93d9c0fb43ce656fe3b7f2be50df80197b4 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:53 +0530 Subject: clk: samsung: exynos5420: fix parent clocks for mscl sysmmu This patch fixes the parent clocks for mscl sysmmu. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index cb7a63913e18..48a5772dca89 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -583,6 +583,9 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV2_RATIO0, 4, 2), DIV(0, "dout_gscl_blk_333", "aclk333_432_gscl", DIV2_RATIO0, 6, 2), + /* MSCL Block */ + DIV(0, "dout_mscl_blk", "aclk400_mscl", DIV2_RATIO0, 28, 2), + /* ISP Block */ DIV(0, "dout_isp_sensor0", "mout_isp_sensor", SCLK_DIV_ISP0, 8, 8), DIV(0, "dout_isp_sensor1", "mout_isp_sensor", SCLK_DIV_ISP0, 16, 8), @@ -816,11 +819,11 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_MSCL0, "mscl0", "aclk400_mscl", GATE_IP_MSCL, 0, 0, 0), GATE(CLK_MSCL1, "mscl1", "aclk400_mscl", GATE_IP_MSCL, 1, 0, 0), GATE(CLK_MSCL2, "mscl2", "aclk400_mscl", GATE_IP_MSCL, 2, 0, 0), - GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "aclk400_mscl", + GATE(CLK_SMMU_MSCL0, "smmu_mscl0", "dout_mscl_blk", GATE_IP_MSCL, 8, 0, 0), - GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "aclk400_mscl", + GATE(CLK_SMMU_MSCL1, "smmu_mscl1", "dout_mscl_blk", GATE_IP_MSCL, 9, 0, 0), - GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "aclk400_mscl", + GATE(CLK_SMMU_MSCL2, "smmu_mscl2", "dout_mscl_blk", GATE_IP_MSCL, 10, 0, 0), GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0), -- cgit v1.2.2 From 3fac5941da6c3afacabf3cc01914583e5689622b Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:54 +0530 Subject: clk: samsung: exynos5420: update clocks for G2D and G3D blocks This patch adds missing clocks of G2D block. It also removes the aclkg3d alias from G3D block clocks. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 48a5772dca89..e263b7be5059 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -399,12 +399,12 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_user_aclk333", mout_user_aclk333_p, SRC_TOP4, 28, 1), MUX(0, "mout_aclk66_psgen", mout_aclk66_peric_p, SRC_TOP5, 4, 1), - MUX(0, "mout_user_aclk333_g2d", mout_user_aclk333_g2d_p, SRC_TOP5, - 8, 1), - MUX(0, "mout_user_aclk266_g2d", mout_user_aclk266_g2d_p, SRC_TOP5, - 12, 1), - MUX_A(CLK_MOUT_G3D, "mout_user_aclk_g3d", mout_user_aclk_g3d_p, - SRC_TOP5, 16, 1, "aclkg3d"), + MUX(0, "mout_user_aclk333_g2d", mout_user_aclk333_g2d_p, + SRC_TOP5, 8, 1), + MUX(0, "mout_user_aclk266_g2d", mout_user_aclk266_g2d_p, + SRC_TOP5, 12, 1), + MUX(CLK_MOUT_G3D, "mout_user_aclk_g3d", mout_user_aclk_g3d_p, + SRC_TOP5, 16, 1), MUX(0, "mout_user_aclk300_jpeg", mout_user_aclk300_jpeg_p, SRC_TOP5, 20, 1), MUX(0, "mout_user_aclk300_disp1", mout_user_aclk300_disp1_p, @@ -602,7 +602,11 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { /* G2D */ + GATE(CLK_MDMA0, "mdma0", "aclk266_g2d", GATE_IP_G2D, 1, 0, 0), GATE(CLK_SSS, "sss", "aclk266_g2d", GATE_IP_G2D, 2, 0, 0), + GATE(CLK_G2D, "g2d", "aclk333_g2d", GATE_IP_G2D, 3, 0, 0), + GATE(CLK_SMMU_MDMA0, "smmu_mdma0", "aclk266_g2d", GATE_IP_G2D, 5, 0, 0), + GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk333_g2d", GATE_IP_G2D, 7, 0, 0), /* TODO: Re-verify the CG bits for all the gate clocks */ GATE_A(CLK_MCT, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, @@ -854,7 +858,7 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SMMU_MFCL, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0), GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0), - GATE(CLK_G3D, "g3d", "aclkg3d", GATE_IP_G3D, 9, 0, 0), + GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), GATE(CLK_ROTATOR, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0), GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0), -- cgit v1.2.2 From 424b673a0557693fdc2ac6cff5289153d6fb8903 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:55 +0530 Subject: clk: samsung: exynos5420: update clocks for DISP1 block This patch corrects some child-parent clock relationships, and updates the clocks according to the latest datasheet. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 56 +++++++++++++++++++++++++----------- 1 file changed, 39 insertions(+), 17 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index e263b7be5059..32d16f5cff53 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -61,7 +61,8 @@ #define SRC_TOP10 0x10280 #define SRC_TOP11 0x10284 #define SRC_TOP12 0x10288 -#define SRC_MASK_DISP10 0x1032c +#define SRC_MASK_TOP2 0x10308 +#define SRC_MASK_DISP10 0x1032c #define SRC_MASK_FSYS 0x10340 #define SRC_MASK_PERIC0 0x10350 #define SRC_MASK_PERIC1 0x10354 @@ -100,6 +101,7 @@ #define GATE_TOP_SCLK_MAU 0x1083c #define GATE_TOP_SCLK_FSYS 0x10840 #define GATE_TOP_SCLK_PERIC 0x10850 +#define TOP_SPARE2 0x10b08 #define BPLL_LOCK 0x20010 #define BPLL_CON0 0x20110 #define SRC_CDREX 0x20200 @@ -146,6 +148,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { SRC_TOP10, SRC_TOP11, SRC_TOP12, + SRC_MASK_TOP2, SRC_MASK_DISP10, SRC_MASK_FSYS, SRC_MASK_PERIC0, @@ -186,6 +189,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { GATE_TOP_SCLK_MAU, GATE_TOP_SCLK_FSYS, GATE_TOP_SCLK_PERIC, + TOP_SPARE2, SRC_CDREX, SRC_KFC, DIV_KFC0, @@ -252,6 +256,7 @@ PNAME(mout_group3_p) = {"mout_sclk_rpll", "mout_sclk_spll"}; PNAME(mout_group4_p) = {"mout_sclk_ipll", "mout_sclk_dpll", "mout_sclk_mpll"}; PNAME(mout_group5_p) = {"mout_sclk_vpll", "mout_sclk_dpll"}; +PNAME(mout_fimd1_final_p) = {"mout_fimd1", "mout_fimd1_opt"}; PNAME(mout_sw_aclk66_p) = {"dout_aclk66", "mout_sclk_spll"}; PNAME(mout_aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66" }; @@ -271,7 +276,7 @@ PNAME(mout_sw_aclk333_432_isp_p) = {"dout_aclk333_432_isp", "mout_sclk_spll"}; PNAME(mout_user_aclk333_432_isp_p) = {"fin_pll", "mout_sw_aclk333_432_isp"}; PNAME(mout_sw_aclk200_p) = {"dout_aclk200", "mout_sclk_spll"}; -PNAME(mout_aclk200_disp1_p) = {"fin_pll", "mout_sw_aclk200"}; +PNAME(mout_user_aclk200_disp1_p) = {"fin_pll", "mout_sw_aclk200"}; PNAME(mout_sw_aclk400_mscl_p) = {"dout_aclk400_mscl", "mout_sclk_spll"}; PNAME(mout_user_aclk400_mscl_p) = {"fin_pll", "mout_sw_aclk400_mscl"}; @@ -293,7 +298,9 @@ PNAME(mout_sw_aclk300_gscl_p) = {"dout_aclk300_gscl", "mout_sclk_spll"}; PNAME(mout_user_aclk300_gscl_p) = {"fin_pll", "mout_sw_aclk300_gscl"}; PNAME(mout_sw_aclk300_disp1_p) = {"dout_aclk300_disp1", "mout_sclk_spll"}; +PNAME(mout_sw_aclk400_disp1_p) = {"dout_aclk400_disp1", "mout_sclk_spll"}; PNAME(mout_user_aclk300_disp1_p) = {"fin_pll", "mout_sw_aclk300_disp1"}; +PNAME(mout_user_aclk400_disp1_p) = {"fin_pll", "mout_sw_aclk400_disp1"}; PNAME(mout_sw_aclk300_jpeg_p) = {"dout_aclk300_jpeg", "mout_sclk_spll"}; PNAME(mout_user_aclk300_jpeg_p) = {"fin_pll", "mout_sw_aclk300_jpeg"}; @@ -368,6 +375,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_aclk166", mout_group1_p, SRC_TOP1, 24, 2), MUX(0, "mout_aclk333", mout_group1_p, SRC_TOP1, 28, 2), + MUX(0, "mout_aclk400_disp1", mout_group1_p, SRC_TOP2, 4, 2), MUX(0, "mout_aclk333_g2d", mout_group1_p, SRC_TOP2, 8, 2), MUX(0, "mout_aclk266_g2d", mout_group1_p, SRC_TOP2, 12, 2), MUX(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1), @@ -379,7 +387,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP3, 0, 1), MUX(0, "mout_user_aclk400_mscl", mout_user_aclk400_mscl_p, SRC_TOP3, 4, 1), - MUX(0, "mout_aclk200_disp1", mout_aclk200_disp1_p, SRC_TOP3, 8, 1), + MUX(0, "mout_user_aclk200_disp1", mout_user_aclk200_disp1_p, + SRC_TOP3, 8, 1), MUX(0, "mout_user_aclk200_fsys2", mout_user_aclk200_fsys2_p, SRC_TOP3, 12, 1), MUX(0, "mout_user_aclk200_fsys", mout_user_aclk200_fsys_p, @@ -398,6 +407,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_user_aclk166", mout_user_aclk166_p, SRC_TOP4, 24, 1), MUX(0, "mout_user_aclk333", mout_user_aclk333_p, SRC_TOP4, 28, 1), + MUX(0, "mout_user_aclk400_disp1", mout_user_aclk400_disp1_p, + SRC_TOP5, 0, 1), MUX(0, "mout_aclk66_psgen", mout_aclk66_peric_p, SRC_TOP5, 4, 1), MUX(0, "mout_user_aclk333_g2d", mout_user_aclk333_g2d_p, SRC_TOP5, 8, 1), @@ -442,6 +453,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_sw_aclk166", mout_sw_aclk166_p, SRC_TOP11, 24, 1), MUX(0, "mout_sw_aclk333", mout_sw_aclk333_p, SRC_TOP11, 28, 1), + MUX(0, "mout_sw_aclk400_disp1", mout_sw_aclk400_disp1_p, + SRC_TOP12, 4, 1), MUX(0, "mout_sw_aclk333_g2d", mout_sw_aclk333_g2d_p, SRC_TOP12, 8, 1), MUX(0, "mout_sw_aclk266_g2d", mout_sw_aclk266_g2d_p, @@ -460,6 +473,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_dp1", mout_group2_p, SRC_DISP10, 20, 3), MUX(0, "mout_pixel", mout_group2_p, SRC_DISP10, 24, 3), MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP10, 28, 1), + MUX(0, "mout_fimd1_opt", mout_group2_p, SRC_DISP10, 8, 3), + MUX(0, "mout_fimd1_final", mout_fimd1_final_p, TOP_SPARE2, 8, 1), /* MAU Block */ MUX(0, "mout_maudio0", mout_maudio0_p, SRC_MAU, 28, 3), @@ -523,15 +538,16 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), DIV(0, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3), DIV(0, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), - DIV_A(0, "dout_aclk300_disp1", "mout_aclk300_disp1", - DIV_TOP2, 24, 3, "aclk300_disp1"), + DIV(0, "dout_aclk300_disp1", "mout_aclk300_disp1", DIV_TOP2, 24, 3), DIV(0, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3), /* DISP1 Block */ - DIV(0, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4), + DIV(0, "dout_fimd1", "mout_fimd1_final", DIV_DISP10, 0, 4), DIV(0, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8), DIV(0, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), DIV(CLK_DOUT_PIXEL, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), + DIV(0, "dout_disp1_blk", "aclk200_disp1", DIV2_RATIO0, 16, 2), + DIV(0, "dout_aclk400_disp1", "mout_aclk400_disp1", DIV_TOP2, 4, 3), /* Audio Block */ DIV(0, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4), @@ -647,6 +663,11 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_BUS_TOP, 16, 0, 0), GATE(0, "aclk400_mscl", "mout_user_aclk400_mscl", GATE_BUS_TOP, 17, 0, 0), + GATE(0, "aclk200_disp1", "mout_user_aclk200_disp1", + GATE_BUS_TOP, 18, 0, 0), + + GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1", + SRC_MASK_TOP2, 24, 0, 0), /* sclk */ GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", @@ -696,15 +717,15 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { /* Display */ GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "dout_fimd1", - GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0), + GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_MIPI1, "sclk_mipi1", "dout_mipi1", - GATE_TOP_SCLK_DISP1, 3, CLK_SET_RATE_PARENT, 0), + GATE_TOP_SCLK_DISP1, 3, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_HDMI, "sclk_hdmi", "mout_hdmi", - GATE_TOP_SCLK_DISP1, 9, CLK_SET_RATE_PARENT, 0), + GATE_TOP_SCLK_DISP1, 9, 0, 0), GATE(CLK_SCLK_PIXEL, "sclk_pixel", "dout_hdmi_pixel", - GATE_TOP_SCLK_DISP1, 10, CLK_SET_RATE_PARENT, 0), + GATE_TOP_SCLK_DISP1, 10, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_DP1, "sclk_dp1", "dout_dp1", - GATE_TOP_SCLK_DISP1, 20, CLK_SET_RATE_PARENT, 0), + GATE_TOP_SCLK_DISP1, 20, CLK_SET_RATE_PARENT, 0), /* Maudio Block */ GATE(CLK_SCLK_MAUDIO0, "sclk_maudio0", "dout_maudio0", @@ -833,10 +854,14 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_FIMD1, "fimd1", "aclk300_disp1", GATE_IP_DISP1, 0, 0, 0), GATE(CLK_DSIM1, "dsim1", "aclk200_disp1", GATE_IP_DISP1, 3, 0, 0), GATE(CLK_DP1, "dp1", "aclk200_disp1", GATE_IP_DISP1, 4, 0, 0), - GATE(CLK_MIXER, "mixer", "aclk166", GATE_IP_DISP1, 5, 0, 0), + GATE(CLK_MIXER, "mixer", "aclk200_disp1", GATE_IP_DISP1, 5, 0, 0), GATE(CLK_HDMI, "hdmi", "aclk200_disp1", GATE_IP_DISP1, 6, 0, 0), - GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "aclk300_disp1", GATE_IP_DISP1, 8, 0, - 0), + GATE(CLK_SMMU_FIMD1M0, "smmu_fimd1m0", "dout_disp1_blk", + GATE_IP_DISP1, 7, 0, 0), + GATE(CLK_SMMU_FIMD1M1, "smmu_fimd1m1", "dout_disp1_blk", + GATE_IP_DISP1, 8, 0, 0), + GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1", + GATE_IP_DISP1, 9, 0, 0), /* ISP */ GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "dout_uart_isp", @@ -867,9 +892,6 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0), GATE(CLK_SMMU_JPEG, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0), GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0), - - GATE(CLK_SMMU_MIXER, "smmu_mixer", "aclk200_disp1", GATE_IP_DISP1, 9, 0, - 0), }; static struct samsung_pll_clock exynos5420_plls[nr_plls] __initdata = { -- cgit v1.2.2 From faec151b5006f832c8cefc76d01893496445a7ec Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:56 +0530 Subject: clk: samsung: exynos5420: update clocks for PERIC block This patch includes, 1] renaming of the HSI2C clocks 2] renaming of spi clocks according to the datasheet 3] fixes for child-parent relationships 4] adding of more clocks related to PERIC block 5] use GATE_IP_* offsets instead of GATE_BUS_* Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 92 +++++++++++++++++------------------- 1 file changed, 44 insertions(+), 48 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 32d16f5cff53..f38c0efaaa73 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -95,6 +95,7 @@ #define GATE_IP_DISP1 0x10928 #define GATE_IP_G3D 0x10930 #define GATE_IP_GEN 0x10934 +#define GATE_IP_PERIC 0x10950 #define GATE_IP_MSCL 0x10970 #define GATE_TOP_SCLK_GSCL 0x10820 #define GATE_TOP_SCLK_DISP1 0x10828 @@ -183,6 +184,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { GATE_IP_DISP1, GATE_IP_G3D, GATE_IP_GEN, + GATE_IP_PERIC, GATE_IP_MSCL, GATE_TOP_SCLK_GSCL, GATE_TOP_SCLK_DISP1, @@ -258,7 +260,7 @@ PNAME(mout_group5_p) = {"mout_sclk_vpll", "mout_sclk_dpll"}; PNAME(mout_fimd1_final_p) = {"mout_fimd1", "mout_fimd1_opt"}; PNAME(mout_sw_aclk66_p) = {"dout_aclk66", "mout_sclk_spll"}; -PNAME(mout_aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66" }; +PNAME(mout_user_aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66" }; PNAME(mout_sw_aclk200_fsys_p) = {"dout_aclk200_fsys", "mout_sclk_spll"}; PNAME(mout_user_aclk200_fsys_p) = {"fin_pll", "mout_sw_aclk200_fsys"}; @@ -398,7 +400,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP4, 0, 1), MUX(0, "mout_user_aclk333_432_isp", mout_user_aclk333_432_isp_p, SRC_TOP4, 4, 1), - MUX(0, "mout_aclk66_peric", mout_aclk66_peric_p, SRC_TOP4, 8, 1), + MUX(0, "mout_user_aclk66_peric", mout_user_aclk66_peric_p, + SRC_TOP4, 8, 1), MUX(0, "mout_user_aclk333_432_isp0", mout_user_aclk333_432_isp0_p, SRC_TOP4, 12, 1), MUX(0, "mout_user_aclk266_isp", mout_user_aclk266_isp_p, @@ -409,7 +412,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_user_aclk400_disp1", mout_user_aclk400_disp1_p, SRC_TOP5, 0, 1), - MUX(0, "mout_aclk66_psgen", mout_aclk66_peric_p, SRC_TOP5, 4, 1), + MUX(0, "mout_user_aclk66_psgen", mout_user_aclk66_peric_p, + SRC_TOP5, 4, 1), MUX(0, "mout_user_aclk333_g2d", mout_user_aclk333_g2d_p, SRC_TOP5, 8, 1), MUX(0, "mout_user_aclk266_g2d", mout_user_aclk266_g2d_p, @@ -590,9 +594,9 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_audio2", "mout_audio2", DIV_PERIC3, 28, 4), /* SPI Pre-Ratio */ - DIV(0, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8), - DIV(0, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8), - DIV(0, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8), + DIV(0, "dout_spi0_pre", "dout_spi0", DIV_PERIC4, 8, 8), + DIV(0, "dout_spi1_pre", "dout_spi1", DIV_PERIC4, 16, 8), + DIV(0, "dout_spi2_pre", "dout_spi2", DIV_PERIC4, 24, 8), /* GSCL Block */ DIV(0, "dout_gscl_blk_300", "mout_user_aclk300_gscl", @@ -649,10 +653,10 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_BUS_TOP, 8, 0, 0), GATE(0, "pclk66_gpio", "mout_sw_aclk66", GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0), - GATE(0, "aclk66_psgen", "mout_aclk66_psgen", + GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen", GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0), - GATE(0, "aclk66_peric", "mout_aclk66_peric", - GATE_BUS_TOP, 11, 0, 0), + GATE(CLK_ACLK66_PERIC, "aclk66_peric", "mout_user_aclk66_peric", + GATE_BUS_TOP, 11, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk266_isp", "mout_user_aclk266_isp", GATE_BUS_TOP, 13, 0, 0), GATE(0, "aclk166", "mout_user_aclk166", @@ -678,11 +682,11 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_TOP_SCLK_PERIC, 2, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_UART3, "sclk_uart3", "dout_uart3", GATE_TOP_SCLK_PERIC, 3, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_SPI0, "sclk_spi0", "dout_pre_spi0", + GATE(CLK_SCLK_SPI0, "sclk_spi0", "dout_spi0_pre", GATE_TOP_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_SPI1, "sclk_spi1", "dout_pre_spi1", + GATE(CLK_SCLK_SPI1, "sclk_spi1", "dout_spi1_pre", GATE_TOP_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_SPI2, "sclk_spi2", "dout_pre_spi2", + GATE(CLK_SCLK_SPI2, "sclk_spi2", "dout_spi2_pre", GATE_TOP_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_SPDIF, "sclk_spdif", "mout_spdif", GATE_TOP_SCLK_PERIC, 9, CLK_SET_RATE_PARENT, 0), @@ -747,43 +751,35 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_USBD300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0), GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0), - /* UART */ - GATE(CLK_UART0, "uart0", "aclk66_peric", GATE_BUS_PERIC, 4, 0, 0), - GATE(CLK_UART1, "uart1", "aclk66_peric", GATE_BUS_PERIC, 5, 0, 0), - GATE_A(CLK_UART2, "uart2", "aclk66_peric", - GATE_BUS_PERIC, 6, CLK_IGNORE_UNUSED, 0, "uart2"), - GATE(CLK_UART3, "uart3", "aclk66_peric", GATE_BUS_PERIC, 7, 0, 0), - /* I2C */ - GATE(CLK_I2C0, "i2c0", "aclk66_peric", GATE_BUS_PERIC, 9, 0, 0), - GATE(CLK_I2C1, "i2c1", "aclk66_peric", GATE_BUS_PERIC, 10, 0, 0), - GATE(CLK_I2C2, "i2c2", "aclk66_peric", GATE_BUS_PERIC, 11, 0, 0), - GATE(CLK_I2C3, "i2c3", "aclk66_peric", GATE_BUS_PERIC, 12, 0, 0), - GATE(CLK_I2C4, "i2c4", "aclk66_peric", GATE_BUS_PERIC, 13, 0, 0), - GATE(CLK_I2C5, "i2c5", "aclk66_peric", GATE_BUS_PERIC, 14, 0, 0), - GATE(CLK_I2C6, "i2c6", "aclk66_peric", GATE_BUS_PERIC, 15, 0, 0), - GATE(CLK_I2C7, "i2c7", "aclk66_peric", GATE_BUS_PERIC, 16, 0, 0), - GATE(CLK_I2C_HDMI, "i2c_hdmi", "aclk66_peric", GATE_BUS_PERIC, 17, 0, - 0), - GATE(CLK_TSADC, "tsadc", "aclk66_peric", GATE_BUS_PERIC, 18, 0, 0), - /* SPI */ - GATE(CLK_SPI0, "spi0", "aclk66_peric", GATE_BUS_PERIC, 19, 0, 0), - GATE(CLK_SPI1, "spi1", "aclk66_peric", GATE_BUS_PERIC, 20, 0, 0), - GATE(CLK_SPI2, "spi2", "aclk66_peric", GATE_BUS_PERIC, 21, 0, 0), + /* PERIC Block */ + GATE(CLK_UART0, "uart0", "aclk66_peric", GATE_IP_PERIC, 0, 0, 0), + GATE(CLK_UART1, "uart1", "aclk66_peric", GATE_IP_PERIC, 1, 0, 0), + GATE(CLK_UART2, "uart2", "aclk66_peric", GATE_IP_PERIC, 2, 0, 0), + GATE(CLK_UART3, "uart3", "aclk66_peric", GATE_IP_PERIC, 3, 0, 0), + GATE(CLK_I2C0, "i2c0", "aclk66_peric", GATE_IP_PERIC, 6, 0, 0), + GATE(CLK_I2C1, "i2c1", "aclk66_peric", GATE_IP_PERIC, 7, 0, 0), + GATE(CLK_I2C2, "i2c2", "aclk66_peric", GATE_IP_PERIC, 8, 0, 0), + GATE(CLK_I2C3, "i2c3", "aclk66_peric", GATE_IP_PERIC, 9, 0, 0), + GATE(CLK_USI0, "usi0", "aclk66_peric", GATE_IP_PERIC, 10, 0, 0), + GATE(CLK_USI1, "usi1", "aclk66_peric", GATE_IP_PERIC, 11, 0, 0), + GATE(CLK_USI2, "usi2", "aclk66_peric", GATE_IP_PERIC, 12, 0, 0), + GATE(CLK_USI3, "usi3", "aclk66_peric", GATE_IP_PERIC, 13, 0, 0), + GATE(CLK_I2C_HDMI, "i2c_hdmi", "aclk66_peric", GATE_IP_PERIC, 14, 0, 0), + GATE(CLK_TSADC, "tsadc", "aclk66_peric", GATE_IP_PERIC, 15, 0, 0), + GATE(CLK_SPI0, "spi0", "aclk66_peric", GATE_IP_PERIC, 16, 0, 0), + GATE(CLK_SPI1, "spi1", "aclk66_peric", GATE_IP_PERIC, 17, 0, 0), + GATE(CLK_SPI2, "spi2", "aclk66_peric", GATE_IP_PERIC, 18, 0, 0), + GATE(CLK_I2S1, "i2s1", "aclk66_peric", GATE_IP_PERIC, 20, 0, 0), + GATE(CLK_I2S2, "i2s2", "aclk66_peric", GATE_IP_PERIC, 21, 0, 0), + GATE(CLK_PCM1, "pcm1", "aclk66_peric", GATE_IP_PERIC, 22, 0, 0), + GATE(CLK_PCM2, "pcm2", "aclk66_peric", GATE_IP_PERIC, 23, 0, 0), + GATE(CLK_PWM, "pwm", "aclk66_peric", GATE_IP_PERIC, 24, 0, 0), + GATE(CLK_SPDIF, "spdif", "aclk66_peric", GATE_IP_PERIC, 26, 0, 0), + GATE(CLK_USI4, "usi4", "aclk66_peric", GATE_IP_PERIC, 28, 0, 0), + GATE(CLK_USI5, "usi5", "aclk66_peric", GATE_IP_PERIC, 30, 0, 0), + GATE(CLK_USI6, "usi6", "aclk66_peric", GATE_IP_PERIC, 31, 0, 0), + GATE(CLK_KEYIF, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0), - /* I2S */ - GATE(CLK_I2S1, "i2s1", "aclk66_peric", GATE_BUS_PERIC, 23, 0, 0), - GATE(CLK_I2S2, "i2s2", "aclk66_peric", GATE_BUS_PERIC, 24, 0, 0), - /* PCM */ - GATE(CLK_PCM1, "pcm1", "aclk66_peric", GATE_BUS_PERIC, 25, 0, 0), - GATE(CLK_PCM2, "pcm2", "aclk66_peric", GATE_BUS_PERIC, 26, 0, 0), - /* PWM */ - GATE(CLK_PWM, "pwm", "aclk66_peric", GATE_BUS_PERIC, 27, 0, 0), - /* SPDIF */ - GATE(CLK_SPDIF, "spdif", "aclk66_peric", GATE_BUS_PERIC, 29, 0, 0), - - GATE(CLK_I2C8, "i2c8", "aclk66_peric", GATE_BUS_PERIC1, 0, 0, 0), - GATE(CLK_I2C9, "i2c9", "aclk66_peric", GATE_BUS_PERIC1, 1, 0, 0), - GATE(CLK_I2C10, "i2c10", "aclk66_peric", GATE_BUS_PERIC1, 2, 0, 0), GATE(CLK_CHIPID, "chipid", "aclk66_psgen", GATE_BUS_PERIS0, 12, CLK_IGNORE_UNUSED, 0), -- cgit v1.2.2 From 0a22c3065333d3138475ff1d25851633e8dae722 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:57 +0530 Subject: clk: samsung: exynos5420: update clocks for PERIS and GEN blocks This patch fixes some parent-child relationships according to the latest datasheet and adds more clocks related to PERIS and GEN blocks. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 76 +++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 31 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index f38c0efaaa73..41af467719dc 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -83,6 +83,7 @@ #define SCLK_DIV_ISP1 0x10584 #define DIV2_RATIO0 0x10590 #define GATE_BUS_TOP 0x10700 +#define GATE_BUS_GEN 0x1073c #define GATE_BUS_FSYS0 0x10740 #define GATE_BUS_PERIC 0x10750 #define GATE_BUS_PERIC1 0x10754 @@ -96,6 +97,7 @@ #define GATE_IP_G3D 0x10930 #define GATE_IP_GEN 0x10934 #define GATE_IP_PERIC 0x10950 +#define GATE_IP_PERIS 0x10960 #define GATE_IP_MSCL 0x10970 #define GATE_TOP_SCLK_GSCL 0x10820 #define GATE_TOP_SCLK_DISP1 0x10828 @@ -172,6 +174,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { SCLK_DIV_ISP1, DIV2_RATIO0, GATE_BUS_TOP, + GATE_BUS_GEN, GATE_BUS_FSYS0, GATE_BUS_PERIC, GATE_BUS_PERIC1, @@ -185,6 +188,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { GATE_IP_G3D, GATE_IP_GEN, GATE_IP_PERIC, + GATE_IP_PERIS, GATE_IP_MSCL, GATE_TOP_SCLK_GSCL, GATE_TOP_SCLK_DISP1, @@ -606,6 +610,10 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { /* MSCL Block */ DIV(0, "dout_mscl_blk", "aclk400_mscl", DIV2_RATIO0, 28, 2), + /* PSGEN */ + DIV(0, "dout_gen_blk", "mout_user_aclk266", DIV2_RATIO0, 8, 1), + DIV(0, "dout_jpg_blk", "aclk166", DIV2_RATIO0, 20, 1), + /* ISP Block */ DIV(0, "dout_isp_sensor0", "mout_isp_sensor", SCLK_DIV_ISP0, 8, 8), DIV(0, "dout_isp_sensor1", "mout_isp_sensor", SCLK_DIV_ISP0, 16, 8), @@ -628,10 +636,6 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SMMU_MDMA0, "smmu_mdma0", "aclk266_g2d", GATE_IP_G2D, 5, 0, 0), GATE(CLK_SMMU_G2D, "smmu_g2d", "aclk333_g2d", GATE_IP_G2D, 7, 0, 0), - /* TODO: Re-verify the CG bits for all the gate clocks */ - GATE_A(CLK_MCT, "pclk_st", "aclk66_psgen", GATE_BUS_PERIS1, 2, 0, 0, - "mct"), - GATE(0, "aclk200_fsys", "mout_user_aclk200_fsys", GATE_BUS_FSYS0, 9, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk200_fsys2", "mout_user_aclk200_fsys2", @@ -781,28 +785,46 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_KEYIF, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0), + /* PERIS Block */ GATE(CLK_CHIPID, "chipid", "aclk66_psgen", - GATE_BUS_PERIS0, 12, CLK_IGNORE_UNUSED, 0), + GATE_IP_PERIS, 0, CLK_IGNORE_UNUSED, 0), GATE(CLK_SYSREG, "sysreg", "aclk66_psgen", - GATE_BUS_PERIS0, 13, CLK_IGNORE_UNUSED, 0), - GATE(CLK_TZPC0, "tzpc0", "aclk66_psgen", GATE_BUS_PERIS0, 18, 0, 0), - GATE(CLK_TZPC1, "tzpc1", "aclk66_psgen", GATE_BUS_PERIS0, 19, 0, 0), - GATE(CLK_TZPC2, "tzpc2", "aclk66_psgen", GATE_BUS_PERIS0, 20, 0, 0), - GATE(CLK_TZPC3, "tzpc3", "aclk66_psgen", GATE_BUS_PERIS0, 21, 0, 0), - GATE(CLK_TZPC4, "tzpc4", "aclk66_psgen", GATE_BUS_PERIS0, 22, 0, 0), - GATE(CLK_TZPC5, "tzpc5", "aclk66_psgen", GATE_BUS_PERIS0, 23, 0, 0), - GATE(CLK_TZPC6, "tzpc6", "aclk66_psgen", GATE_BUS_PERIS0, 24, 0, 0), - GATE(CLK_TZPC7, "tzpc7", "aclk66_psgen", GATE_BUS_PERIS0, 25, 0, 0), - GATE(CLK_TZPC8, "tzpc8", "aclk66_psgen", GATE_BUS_PERIS0, 26, 0, 0), - GATE(CLK_TZPC9, "tzpc9", "aclk66_psgen", GATE_BUS_PERIS0, 27, 0, 0), - - GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk66_psgen", GATE_BUS_PERIS1, 0, 0, - 0), + GATE_IP_PERIS, 1, CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC0, "tzpc0", "aclk66_psgen", GATE_IP_PERIS, 6, 0, 0), + GATE(CLK_TZPC1, "tzpc1", "aclk66_psgen", GATE_IP_PERIS, 7, 0, 0), + GATE(CLK_TZPC2, "tzpc2", "aclk66_psgen", GATE_IP_PERIS, 8, 0, 0), + GATE(CLK_TZPC3, "tzpc3", "aclk66_psgen", GATE_IP_PERIS, 9, 0, 0), + GATE(CLK_TZPC4, "tzpc4", "aclk66_psgen", GATE_IP_PERIS, 10, 0, 0), + GATE(CLK_TZPC5, "tzpc5", "aclk66_psgen", GATE_IP_PERIS, 11, 0, 0), + GATE(CLK_TZPC6, "tzpc6", "aclk66_psgen", GATE_IP_PERIS, 12, 0, 0), + GATE(CLK_TZPC7, "tzpc7", "aclk66_psgen", GATE_IP_PERIS, 13, 0, 0), + GATE(CLK_TZPC8, "tzpc8", "aclk66_psgen", GATE_IP_PERIS, 14, 0, 0), + GATE(CLK_TZPC9, "tzpc9", "aclk66_psgen", GATE_IP_PERIS, 15, 0, 0), + GATE(CLK_HDMI_CEC, "hdmi_cec", "aclk66_psgen", GATE_IP_PERIS, 16, 0, 0), + GATE(CLK_MCT, "mct", "aclk66_psgen", GATE_IP_PERIS, 18, 0, 0), + GATE(CLK_WDT, "wdt", "aclk66_psgen", GATE_IP_PERIS, 19, 0, 0), + GATE(CLK_RTC, "rtc", "aclk66_psgen", GATE_IP_PERIS, 20, 0, 0), + GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_IP_PERIS, 21, 0, 0), + GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_IP_PERIS, 22, 0, 0), + GATE(CLK_SECKEY, "seckey", "aclk66_psgen", GATE_BUS_PERIS1, 1, 0, 0), - GATE(CLK_WDT, "wdt", "aclk66_psgen", GATE_BUS_PERIS1, 3, 0, 0), - GATE(CLK_RTC, "rtc", "aclk66_psgen", GATE_BUS_PERIS1, 4, 0, 0), - GATE(CLK_TMU, "tmu", "aclk66_psgen", GATE_BUS_PERIS1, 5, 0, 0), - GATE(CLK_TMU_GPU, "tmu_gpu", "aclk66_psgen", GATE_BUS_PERIS1, 6, 0, 0), + + /* GEN Block */ + GATE(CLK_ROTATOR, "rotator", "mout_user_aclk266", GATE_IP_GEN, 1, 0, 0), + GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0), + GATE(CLK_JPEG2, "jpeg2", "aclk300_jpeg", GATE_IP_GEN, 3, 0, 0), + GATE(CLK_MDMA1, "mdma1", "mout_user_aclk266", GATE_IP_GEN, 4, 0, 0), + GATE(CLK_TOP_RTC, "top_rtc", "aclk66_psgen", GATE_IP_GEN, 5, 0, 0), + GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "dout_gen_blk", + GATE_IP_GEN, 6, 0, 0), + GATE(CLK_SMMU_JPEG, "smmu_jpeg", "dout_jpg_blk", GATE_IP_GEN, 7, 0, 0), + GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "dout_gen_blk", + GATE_IP_GEN, 9, 0, 0), + + /* GATE_IP_GEN doesn't list gates for smmu_jpeg2 and mc */ + GATE(CLK_SMMU_JPEG2, "smmu_jpeg2", "dout_jpg_blk", + GATE_BUS_GEN, 28, 0, 0), + GATE(CLK_MC, "mc", "aclk66_psgen", GATE_BUS_GEN, 12, 0, 0), /* GSCL Block */ GATE(CLK_SCLK_GSCL_WA, "sclk_gscl_wa", "mout_user_aclk333_432_gscl", @@ -880,14 +902,6 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0), GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), - - GATE(CLK_ROTATOR, "rotator", "aclk266", GATE_IP_GEN, 1, 0, 0), - GATE(CLK_JPEG, "jpeg", "aclk300_jpeg", GATE_IP_GEN, 2, 0, 0), - GATE(CLK_JPEG2, "jpeg2", "aclk300_jpeg", GATE_IP_GEN, 3, 0, 0), - GATE(CLK_MDMA1, "mdma1", "aclk266", GATE_IP_GEN, 4, 0, 0), - GATE(CLK_SMMU_ROTATOR, "smmu_rotator", "aclk266", GATE_IP_GEN, 6, 0, 0), - GATE(CLK_SMMU_JPEG, "smmu_jpeg", "aclk300_jpeg", GATE_IP_GEN, 7, 0, 0), - GATE(CLK_SMMU_MDMA1, "smmu_mdma1", "aclk266", GATE_IP_GEN, 9, 0, 0), }; static struct samsung_pll_clock exynos5420_plls[nr_plls] __initdata = { -- cgit v1.2.2 From 6575fa76c394d6f6c0ed3f35475324c8846984af Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:58 +0530 Subject: clk: samsung: exynos5420: update clocks for WCORE block This patch adds missing clocks for WCORE block. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 41af467719dc..a6c87d35c46d 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -89,6 +89,7 @@ #define GATE_BUS_PERIC1 0x10754 #define GATE_BUS_PERIS0 0x10760 #define GATE_BUS_PERIS1 0x10764 +#define GATE_BUS_NOC 0x10770 #define GATE_TOP_SCLK_ISP 0x10870 #define GATE_IP_GSCL0 0x10910 #define GATE_IP_GSCL1 0x10920 @@ -180,6 +181,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { GATE_BUS_PERIC1, GATE_BUS_PERIS0, GATE_BUS_PERIS1, + GATE_BUS_NOC, GATE_TOP_SCLK_ISP, GATE_IP_GSCL0, GATE_IP_GSCL1, @@ -271,6 +273,13 @@ PNAME(mout_user_aclk200_fsys_p) = {"fin_pll", "mout_sw_aclk200_fsys"}; PNAME(mout_sw_aclk200_fsys2_p) = {"dout_aclk200_fsys2", "mout_sclk_spll"}; PNAME(mout_user_aclk200_fsys2_p) = {"fin_pll", "mout_sw_aclk200_fsys2"}; +PNAME(mout_sw_aclk100_noc_p) = {"dout_aclk100_noc", "mout_sclk_spll"}; +PNAME(mout_user_aclk100_noc_p) = {"fin_pll", "mout_sw_aclk100_noc"}; + +PNAME(mout_sw_aclk400_wcore_p) = {"dout_aclk400_wcore", "mout_sclk_spll"}; +PNAME(mout_aclk400_wcore_bpll_p) = {"mout_aclk400_wcore", "sclk_bpll"}; +PNAME(mout_user_aclk400_wcore_p) = {"fin_pll", "mout_sw_aclk400_wcore"}; + PNAME(mout_sw_aclk400_isp_p) = {"dout_aclk400_isp", "mout_sclk_spll"}; PNAME(mout_user_aclk400_isp_p) = {"fin_pll", "mout_sw_aclk400_isp"}; @@ -370,6 +379,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP0, 4, 2, "aclk400_mscl"), MUX(0, "mout_aclk200", mout_group1_p, SRC_TOP0, 8, 2), MUX(0, "mout_aclk200_fsys2", mout_group1_p, SRC_TOP0, 12, 2), + MUX(0, "mout_aclk400_wcore", mout_group1_p, SRC_TOP0, 16, 2), + MUX(0, "mout_aclk100_noc", mout_group1_p, SRC_TOP0, 20, 2), MUX(0, "mout_aclk200_fsys", mout_group1_p, SRC_TOP0, 28, 2), MUX(0, "mout_aclk333_432_gscl", mout_group4_p, SRC_TOP1, 0, 2), @@ -397,6 +408,10 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP3, 8, 1), MUX(0, "mout_user_aclk200_fsys2", mout_user_aclk200_fsys2_p, SRC_TOP3, 12, 1), + MUX(0, "mout_user_aclk400_wcore", mout_user_aclk400_wcore_p, + SRC_TOP3, 16, 1), + MUX(0, "mout_user_aclk100_noc", mout_user_aclk100_noc_p, + SRC_TOP3, 20, 1), MUX(0, "mout_user_aclk200_fsys", mout_user_aclk200_fsys_p, SRC_TOP3, 28, 1), @@ -447,6 +462,10 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_sw_aclk200", mout_sw_aclk200_p, SRC_TOP10, 8, 1), MUX(0, "mout_sw_aclk200_fsys2", mout_sw_aclk200_fsys2_p, SRC_TOP10, 12, 1), + MUX(0, "mout_sw_aclk400_wcore", mout_sw_aclk400_wcore_p, + SRC_TOP10, 16, 1), + MUX(0, "mout_sw_aclk100_noc", mout_sw_aclk100_noc_p, + SRC_TOP10, 20, 1), MUX(0, "mout_sw_aclk200_fsys", mout_sw_aclk200_fsys_p, SRC_TOP10, 28, 1), @@ -482,6 +501,9 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_pixel", mout_group2_p, SRC_DISP10, 24, 3), MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP10, 28, 1), MUX(0, "mout_fimd1_opt", mout_group2_p, SRC_DISP10, 8, 3), + + MUX(0, "mout_aclk400_wcore_bpll", mout_aclk400_wcore_bpll_p, + TOP_SPARE2, 4, 1), MUX(0, "mout_fimd1_final", mout_fimd1_final_p, TOP_SPARE2, 8, 1), /* MAU Block */ @@ -528,6 +550,9 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), + DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll", + DIV_TOP0, 16, 3), + DIV(0, "dout_aclk100_noc", "mout_aclk100_noc", DIV_TOP0, 20, 3), DIV(0, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3), DIV(0, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3), -- cgit v1.2.2 From 6b5ae463e472ba2145766066e6e2d465a07074a5 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:57:59 +0530 Subject: clk: samsung: exynos5420: update clocks for FSYS and FSYS2 blocks This patch adds more clocks from FSYS and FSYS2 blocks and uses GATE_IP_* registers for gating IPs. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 37 ++++++++++++++++++++++++------------ 1 file changed, 25 insertions(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index a6c87d35c46d..980a3f2dd419 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -85,6 +85,7 @@ #define GATE_BUS_TOP 0x10700 #define GATE_BUS_GEN 0x1073c #define GATE_BUS_FSYS0 0x10740 +#define GATE_BUS_FSYS2 0x10748 #define GATE_BUS_PERIC 0x10750 #define GATE_BUS_PERIC1 0x10754 #define GATE_BUS_PERIS0 0x10760 @@ -97,6 +98,7 @@ #define GATE_IP_DISP1 0x10928 #define GATE_IP_G3D 0x10930 #define GATE_IP_GEN 0x10934 +#define GATE_IP_FSYS 0x10944 #define GATE_IP_PERIC 0x10950 #define GATE_IP_PERIS 0x10960 #define GATE_IP_MSCL 0x10970 @@ -177,6 +179,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { GATE_BUS_TOP, GATE_BUS_GEN, GATE_BUS_FSYS0, + GATE_BUS_FSYS2, GATE_BUS_PERIC, GATE_BUS_PERIC1, GATE_BUS_PERIS0, @@ -189,6 +192,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { GATE_IP_DISP1, GATE_IP_G3D, GATE_IP_GEN, + GATE_IP_FSYS, GATE_IP_PERIC, GATE_IP_PERIS, GATE_IP_MSCL, @@ -269,6 +273,8 @@ PNAME(mout_sw_aclk66_p) = {"dout_aclk66", "mout_sclk_spll"}; PNAME(mout_user_aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66" }; PNAME(mout_sw_aclk200_fsys_p) = {"dout_aclk200_fsys", "mout_sclk_spll"}; +PNAME(mout_sw_pclk200_fsys_p) = {"dout_pclk200_fsys", "mout_sclk_spll"}; +PNAME(mout_user_pclk200_fsys_p) = {"fin_pll", "mout_sw_pclk200_fsys"}; PNAME(mout_user_aclk200_fsys_p) = {"fin_pll", "mout_sw_aclk200_fsys"}; PNAME(mout_sw_aclk200_fsys2_p) = {"dout_aclk200_fsys2", "mout_sclk_spll"}; @@ -381,6 +387,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_aclk200_fsys2", mout_group1_p, SRC_TOP0, 12, 2), MUX(0, "mout_aclk400_wcore", mout_group1_p, SRC_TOP0, 16, 2), MUX(0, "mout_aclk100_noc", mout_group1_p, SRC_TOP0, 20, 2), + MUX(0, "mout_pclk200_fsys", mout_group1_p, SRC_TOP0, 24, 2), MUX(0, "mout_aclk200_fsys", mout_group1_p, SRC_TOP0, 28, 2), MUX(0, "mout_aclk333_432_gscl", mout_group4_p, SRC_TOP1, 0, 2), @@ -412,6 +419,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP3, 16, 1), MUX(0, "mout_user_aclk100_noc", mout_user_aclk100_noc_p, SRC_TOP3, 20, 1), + MUX(0, "mout_user_pclk200_fsys", mout_user_pclk200_fsys_p, + SRC_TOP3, 24, 1), MUX(0, "mout_user_aclk200_fsys", mout_user_aclk200_fsys_p, SRC_TOP3, 28, 1), @@ -466,6 +475,8 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP10, 16, 1), MUX(0, "mout_sw_aclk100_noc", mout_sw_aclk100_noc_p, SRC_TOP10, 20, 1), + MUX(0, "mout_sw_pclk200_fsys", mout_sw_pclk200_fsys_p, + SRC_TOP10, 24, 1), MUX(0, "mout_sw_aclk200_fsys", mout_sw_aclk200_fsys_p, SRC_TOP10, 28, 1), @@ -516,6 +527,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_mmc2", mout_group2_p, SRC_FSYS, 16, 3), MUX(0, "mout_usbd300", mout_group2_p, SRC_FSYS, 20, 3), MUX(0, "mout_unipro", mout_group2_p, SRC_FSYS, 24, 3), + MUX(0, "mout_mphy_refclk", mout_group2_p, SRC_FSYS, 28, 3), /* PERIC Block */ MUX(0, "mout_uart0", mout_group2_p, SRC_PERIC0, 4, 3), @@ -598,6 +610,7 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_mmc2", "mout_mmc2", DIV_FSYS1, 20, 10), DIV(0, "dout_unipro", "mout_unipro", DIV_FSYS2, 24, 8), + DIV(0, "dout_mphy_refclk", "mout_mphy_refclk", DIV_FSYS2, 16, 8), /* UART and PWM */ DIV(0, "dout_uart0", "mout_uart0", DIV_PERIC0, 8, 4), @@ -745,9 +758,6 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_SCLK_USBD301, "sclk_usbd301", "dout_usbd301", GATE_TOP_SCLK_FSYS, 10, CLK_SET_RATE_PARENT, 0), - GATE(CLK_SCLK_USBD301, "sclk_unipro", "dout_unipro", - SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), - /* Display */ GATE(CLK_SCLK_FIMD1, "sclk_fimd1", "dout_fimd1", GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0), @@ -765,20 +775,23 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0), GATE(CLK_SCLK_MAUPCM0, "sclk_maupcm0", "dout_maupcm0", GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0), - /* FSYS */ + + /* FSYS Block */ GATE(CLK_TSI, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0), GATE(CLK_PDMA0, "pdma0", "aclk200_fsys", GATE_BUS_FSYS0, 1, 0, 0), GATE(CLK_PDMA1, "pdma1", "aclk200_fsys", GATE_BUS_FSYS0, 2, 0, 0), GATE(CLK_UFS, "ufs", "aclk200_fsys2", GATE_BUS_FSYS0, 3, 0, 0), - GATE(CLK_RTIC, "rtic", "aclk200_fsys", GATE_BUS_FSYS0, 5, 0, 0), - GATE(CLK_MMC0, "mmc0", "aclk200_fsys2", GATE_BUS_FSYS0, 12, 0, 0), - GATE(CLK_MMC1, "mmc1", "aclk200_fsys2", GATE_BUS_FSYS0, 13, 0, 0), - GATE(CLK_MMC2, "mmc2", "aclk200_fsys2", GATE_BUS_FSYS0, 14, 0, 0), + GATE(CLK_RTIC, "rtic", "aclk200_fsys", GATE_IP_FSYS, 9, 0, 0), + GATE(CLK_MMC0, "mmc0", "aclk200_fsys2", GATE_IP_FSYS, 12, 0, 0), + GATE(CLK_MMC1, "mmc1", "aclk200_fsys2", GATE_IP_FSYS, 13, 0, 0), + GATE(CLK_MMC2, "mmc2", "aclk200_fsys2", GATE_IP_FSYS, 14, 0, 0), GATE(CLK_SROMC, "sromc", "aclk200_fsys2", - GATE_BUS_FSYS0, 19, CLK_IGNORE_UNUSED, 0), - GATE(CLK_USBH20, "usbh20", "aclk200_fsys", GATE_BUS_FSYS0, 20, 0, 0), - GATE(CLK_USBD300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0), - GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0), + GATE_IP_FSYS, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_USBH20, "usbh20", "aclk200_fsys", GATE_IP_FSYS, 18, 0, 0), + GATE(CLK_USBD300, "usbd300", "aclk200_fsys", GATE_IP_FSYS, 19, 0, 0), + GATE(CLK_USBD301, "usbd301", "aclk200_fsys", GATE_IP_FSYS, 20, 0, 0), + GATE(CLK_SCLK_UNIPRO, "sclk_unipro", "dout_unipro", + SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), /* PERIC Block */ GATE(CLK_UART0, "uart0", "aclk66_peric", GATE_IP_PERIC, 0, 0, 0), -- cgit v1.2.2 From 1d87db4d4e05f6f0c5343cfcafc4234fe59e3cd1 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:58:00 +0530 Subject: clk: samsung: exynos5420: correct sysmmu-mfc parent clocks This patch corrects the wrong parent-child relationship between sysmmu-mfc clocks. Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 980a3f2dd419..e48f6f8e796f 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -82,6 +82,7 @@ #define SCLK_DIV_ISP0 0x10580 #define SCLK_DIV_ISP1 0x10584 #define DIV2_RATIO0 0x10590 +#define DIV4_RATIO 0x105a0 #define GATE_BUS_TOP 0x10700 #define GATE_BUS_GEN 0x1073c #define GATE_BUS_FSYS0 0x10740 @@ -176,6 +177,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { SCLK_DIV_ISP0, SCLK_DIV_ISP1, DIV2_RATIO0, + DIV4_RATIO, GATE_BUS_TOP, GATE_BUS_GEN, GATE_BUS_FSYS0, @@ -624,6 +626,9 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4), DIV(0, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4), + /* Mfc Block */ + DIV(0, "dout_mfc_blk", "mout_user_aclk333", DIV4_RATIO, 0, 2), + /* PCM */ DIV(0, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8), DIV(0, "dout_pcm2", "dout_audio2", DIV_PERIC2, 24, 8), @@ -936,8 +941,8 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_TOP_SCLK_ISP, 12, CLK_SET_RATE_PARENT, 0), GATE(CLK_MFC, "mfc", "aclk333", GATE_IP_MFC, 0, 0, 0), - GATE(CLK_SMMU_MFCL, "smmu_mfcl", "aclk333", GATE_IP_MFC, 1, 0, 0), - GATE(CLK_SMMU_MFCR, "smmu_mfcr", "aclk333", GATE_IP_MFC, 2, 0, 0), + GATE(CLK_SMMU_MFCL, "smmu_mfcl", "dout_mfc_blk", GATE_IP_MFC, 1, 0, 0), + GATE(CLK_SMMU_MFCR, "smmu_mfcr", "dout_mfc_blk", GATE_IP_MFC, 2, 0, 0), GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), }; -- cgit v1.2.2 From 58ff8d038338bc0371da704f76faaa5769db68c3 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:58:01 +0530 Subject: clk: samsung: exynos5420: fix register offset for sclk_bpll This patch fixes the wrong register offset for sclk_bpll clock. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Reviewed-by: Alim Akhtar Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index e48f6f8e796f..2171366237af 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -111,7 +111,6 @@ #define TOP_SPARE2 0x10b08 #define BPLL_LOCK 0x20010 #define BPLL_CON0 0x20110 -#define SRC_CDREX 0x20200 #define KPLL_LOCK 0x28000 #define KPLL_CON0 0x28100 #define SRC_KFC 0x28200 @@ -204,7 +203,6 @@ static unsigned long exynos5420_clk_regs[] __initdata = { GATE_TOP_SCLK_FSYS, GATE_TOP_SCLK_PERIC, TOP_SPARE2, - SRC_CDREX, SRC_KFC, DIV_KFC0, }; @@ -380,7 +378,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1), MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1), - MUX(0, "sclk_bpll", mout_bpll_p, SRC_CDREX, 0, 1), + MUX(0, "sclk_bpll", mout_bpll_p, TOP_SPARE2, 0, 1), MUX(0, "mout_aclk400_isp", mout_group1_p, SRC_TOP0, 0, 2), MUX_A(0, "mout_aclk400_mscl", mout_group1_p, -- cgit v1.2.2 From 31116a642b148587b92928d37212a547d0ce10b5 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:58:02 +0530 Subject: clk: samsung: exynos5420: update clocks for MAU Block This patch adds the missing MAU block specific clocks. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 2171366237af..9ff36140bcdf 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -62,7 +62,9 @@ #define SRC_TOP11 0x10284 #define SRC_TOP12 0x10288 #define SRC_MASK_TOP2 0x10308 +#define SRC_MASK_TOP7 0x1031c #define SRC_MASK_DISP10 0x1032c +#define SRC_MASK_MAU 0x10334 #define SRC_MASK_FSYS 0x10340 #define SRC_MASK_PERIC0 0x10350 #define SRC_MASK_PERIC1 0x10354 @@ -155,6 +157,7 @@ static unsigned long exynos5420_clk_regs[] __initdata = { SRC_TOP11, SRC_TOP12, SRC_MASK_TOP2, + SRC_MASK_TOP7, SRC_MASK_DISP10, SRC_MASK_FSYS, SRC_MASK_PERIC0, @@ -351,6 +354,8 @@ PNAME(mout_hdmi_p) = {"dout_hdmi_pixel", "sclk_hdmiphy"}; PNAME(mout_maudio0_p) = {"fin_pll", "maudio_clk", "mout_sclk_dpll", "mout_sclk_mpll", "mout_sclk_spll", "mout_sclk_ipll", "mout_sclk_epll", "mout_sclk_rpll"}; +PNAME(mout_mau_epll_clk_p) = {"mout_sclk_epll", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll"}; /* fixed rate clocks generated outside the soc */ static struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = { @@ -373,6 +378,8 @@ static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initda static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2), MUX(0, "mout_mspll_cpu", mout_mspll_cpu_p, SRC_TOP7, 12, 2), + MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2), + MUX(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), MUX(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1), @@ -518,7 +525,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_fimd1_final", mout_fimd1_final_p, TOP_SPARE2, 8, 1), /* MAU Block */ - MUX(0, "mout_maudio0", mout_maudio0_p, SRC_MAU, 28, 3), + MUX(CLK_MOUT_MAUDIO0, "mout_maudio0", mout_maudio0_p, SRC_MAU, 28, 3), /* FSYS Block */ MUX(0, "mout_usbd301", mout_group2_p, SRC_FSYS, 4, 3), @@ -718,6 +725,9 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1", SRC_MASK_TOP2, 24, 0, 0), + GATE(CLK_MAU_EPLL, "mau_epll", "mout_mau_epll_clk", + SRC_MASK_TOP7, 20, 0, 0), + /* sclk */ GATE(CLK_SCLK_UART0, "sclk_uart0", "dout_uart0", GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0), -- cgit v1.2.2 From b31ca2a0176ee1d7f011f4cf0f6b33e1163e254b Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:58:03 +0530 Subject: clk: samsung: exynos5420: add misc clocks This patch adds some missing miscellaneous clocks specific to exynos5420. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 9ff36140bcdf..4bc94f1c53d1 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -273,7 +273,8 @@ PNAME(mout_group5_p) = {"mout_sclk_vpll", "mout_sclk_dpll"}; PNAME(mout_fimd1_final_p) = {"mout_fimd1", "mout_fimd1_opt"}; PNAME(mout_sw_aclk66_p) = {"dout_aclk66", "mout_sclk_spll"}; -PNAME(mout_user_aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66" }; +PNAME(mout_user_aclk66_peric_p) = { "fin_pll", "mout_sw_aclk66"}; +PNAME(mout_user_pclk66_gpio_p) = {"mout_sw_aclk66", "ff_sw_aclk66"}; PNAME(mout_sw_aclk200_fsys_p) = {"dout_aclk200_fsys", "mout_sclk_spll"}; PNAME(mout_sw_pclk200_fsys_p) = {"dout_pclk200_fsys", "mout_sclk_spll"}; @@ -372,10 +373,13 @@ static struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = }; static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = { - FFACTOR(0, "sclk_hsic_12m", "fin_pll", 1, 2, 0), + FFACTOR(0, "ff_hsic_12m", "fin_pll", 1, 2, 0), + FFACTOR(0, "ff_sw_aclk66", "mout_sw_aclk66", 1, 2, 0), }; static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { + MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p, + SRC_TOP7, 4, 1), MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2), MUX(0, "mout_mspll_cpu", mout_mspll_cpu_p, SRC_TOP7, 12, 2), MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2), @@ -703,7 +707,7 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_BUS_TOP, 7, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk333_432_isp", "mout_user_aclk333_432_isp", GATE_BUS_TOP, 8, 0, 0), - GATE(0, "pclk66_gpio", "mout_sw_aclk66", + GATE(CLK_PCLK66_GPIO, "pclk66_gpio", "mout_user_pclk66_gpio", GATE_BUS_TOP, 9, CLK_IGNORE_UNUSED, 0), GATE(0, "aclk66_psgen", "mout_user_aclk66_psgen", GATE_BUS_TOP, 10, CLK_IGNORE_UNUSED, 0), @@ -721,6 +725,10 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE_BUS_TOP, 17, 0, 0), GATE(0, "aclk200_disp1", "mout_user_aclk200_disp1", GATE_BUS_TOP, 18, 0, 0), + GATE(CLK_SCLK_MPHY_IXTAL24, "sclk_mphy_ixtal24", "mphy_refclk_ixtal24", + GATE_BUS_TOP, 28, 0, 0), + GATE(CLK_SCLK_HSIC_12M, "sclk_hsic_12m", "ff_hsic_12m", + GATE_BUS_TOP, 29, 0, 0), GATE(0, "aclk300_disp1", "mout_user_aclk300_disp1", SRC_MASK_TOP2, 24, 0, 0), -- cgit v1.2.2 From 773424326b51cc851b6e28ff22447ba5fcc5f429 Mon Sep 17 00:00:00 2001 From: Shaik Ameer Basha Date: Thu, 8 May 2014 16:58:04 +0530 Subject: clk: samsung: exynos5420: add more registers to restore list This patch adds more register offsets to the list for preserving their values during S2R. Signed-off-by: Rahul Sharma Signed-off-by: Shaik Ameer Basha Signed-off-by: Tomasz Figa --- drivers/clk/samsung/clk-exynos5420.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 4bc94f1c53d1..1c3674ecc0dc 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -27,6 +27,7 @@ #define DIV_CPU1 0x504 #define GATE_BUS_CPU 0x700 #define GATE_SCLK_CPU 0x800 +#define CLKOUT_CMU_CPU 0xa00 #define GATE_IP_G2D 0x8800 #define CPLL_LOCK 0x10020 #define DPLL_LOCK 0x10030 @@ -39,7 +40,11 @@ #define CPLL_CON0 0x10120 #define DPLL_CON0 0x10128 #define EPLL_CON0 0x10130 +#define EPLL_CON1 0x10134 +#define EPLL_CON2 0x10138 #define RPLL_CON0 0x10140 +#define RPLL_CON1 0x10144 +#define RPLL_CON2 0x10148 #define IPLL_CON0 0x10150 #define SPLL_CON0 0x10160 #define VPLL_CON0 0x10170 @@ -140,6 +145,13 @@ static unsigned long exynos5420_clk_regs[] __initdata = { DIV_CPU1, GATE_BUS_CPU, GATE_SCLK_CPU, + CLKOUT_CMU_CPU, + EPLL_CON0, + EPLL_CON1, + EPLL_CON2, + RPLL_CON0, + RPLL_CON1, + RPLL_CON2, SRC_TOP0, SRC_TOP1, SRC_TOP2, -- cgit v1.2.2 From 4ce9b85e48f4dc79ba0bc696bbb944428a142bc7 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Thu, 8 May 2014 13:07:08 +0900 Subject: clk: samsung: add new Kconfig for Samsung common clock option This patch adds new Kconfig file for adding new COMMON_CLK_SAMSUNG option. Samsung platforms can select this for using common clock infrastructure. CC: Mike Turquette Signed-off-by: Pankaj Dubey Signed-off-by: Tomasz Figa --- drivers/clk/Kconfig | 2 ++ drivers/clk/samsung/Kconfig | 3 +++ 2 files changed, 5 insertions(+) create mode 100644 drivers/clk/samsung/Kconfig (limited to 'drivers') diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index 6f56d3a4f010..ba2436622645 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -115,3 +115,5 @@ endmenu source "drivers/clk/bcm/Kconfig" source "drivers/clk/mvebu/Kconfig" + +source "drivers/clk/samsung/Kconfig" diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig new file mode 100644 index 000000000000..fc8696b0954f --- /dev/null +++ b/drivers/clk/samsung/Kconfig @@ -0,0 +1,3 @@ +config COMMON_CLK_SAMSUNG + bool + select COMMON_CLK -- cgit v1.2.2 From 1f4f2cfdb7145363aedb647a5ab6e7b658b379b9 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Thu, 8 May 2014 13:07:10 +0900 Subject: ARM: S3C24XX: move S3C24XX clock Kconfig options to Samsung clock Kconfig file This patch moves S3C24XX specific clock Kconfig options into "clk/samsung/Kconfig" and also removes COMMON_CLK selection from "mach-s3c24xx/Kconfig" as S3C24XX_COMMON_CLK is selecting it's dependency. CC: Ben Dooks CC: Kukjin Kim CC: Russell King Signed-off-by: Pankaj Dubey Signed-off-by: Tomasz Figa --- drivers/clk/samsung/Kconfig | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/Kconfig b/drivers/clk/samsung/Kconfig index fc8696b0954f..84196ecdaa12 100644 --- a/drivers/clk/samsung/Kconfig +++ b/drivers/clk/samsung/Kconfig @@ -1,3 +1,26 @@ config COMMON_CLK_SAMSUNG bool select COMMON_CLK + +config S3C2410_COMMON_CLK + bool + select COMMON_CLK_SAMSUNG + help + Build the s3c2410 clock driver based on the common clock framework. + +config S3C2410_COMMON_DCLK + bool + select COMMON_CLK_SAMSUNG + select REGMAP_MMIO + help + Temporary symbol to build the dclk driver based on the common clock + framework. + +config S3C2412_COMMON_CLK + bool + select COMMON_CLK_SAMSUNG + +config S3C2443_COMMON_CLK + bool + select COMMON_CLK_SAMSUNG + -- cgit v1.2.2 From 3bc0c5a16d65ef2a2edb7326f5b77d6a5bcf08a5 Mon Sep 17 00:00:00 2001 From: Pankaj Dubey Date: Thu, 8 May 2014 13:07:11 +0900 Subject: drivers: clk: use COMMON_CLK_SAMSUNG for Samsung clock support This patch replaces PLAT_SAMSUNG with COMMON_CLK_SAMSUNG for Samsung common clock support. Any Samsung SoC want to use Samsung common clock infrastructure can simply select COMMON_CLK_SAMSUNG. CC: Mike Turquette Signed-off-by: Pankaj Dubey Signed-off-by: Tomasz Figa --- drivers/clk/Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 5f8a28735c96..17d7f13d19a5 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -41,7 +41,7 @@ obj-$(CONFIG_PLAT_ORION) += mvebu/ obj-$(CONFIG_ARCH_MXS) += mxs/ obj-$(CONFIG_COMMON_CLK_QCOM) += qcom/ obj-$(CONFIG_ARCH_ROCKCHIP) += rockchip/ -obj-$(CONFIG_PLAT_SAMSUNG) += samsung/ +obj-$(CONFIG_COMMON_CLK_SAMSUNG) += samsung/ obj-$(CONFIG_ARCH_SHMOBILE_MULTI) += shmobile/ obj-$(CONFIG_ARCH_SIRF) += sirf/ obj-$(CONFIG_ARCH_SOCFPGA) += socfpga/ -- cgit v1.2.2 From 2ce16c53422a17c0afea8203dd96ac1e7a142cf9 Mon Sep 17 00:00:00 2001 From: Tomasz Figa Date: Tue, 13 May 2014 22:05:06 +0900 Subject: clk: samsung: exynos3250: Add clocks using common clock framework This patch add new the clock drvier of Exynos3250 SoC based on Cortex-A7 using common clock framework. The CMU (Clock Management Unit) of Exynos3250 control PLLs(Phase Locked Loops) and generate system clocks for CPU, buses, and function clocks for individual IPs. The CMU of Exynos3250 includes following clock doamins: - CPU block for Cortex-A7 MPCore processor - LEFTBUS/RIGHTBUS block - TOP block for G3D/MFC/LCD0/ISP/CAM/FSYS/MFC/PERIL/PERIR Signed-off-by: Tomasz Figa Signed-off-by: Chanwoo Choi Signed-off-by: Hyunhee Kim Signed-off-by: Sylwester Nawrocki Signed-off-by: Inki Dae Signed-off-by: Seung-Woo Kim Signed-off-by: Jaehoon Chung Signed-off-by: Karol Wrona Signed-off-by: YoungJun Cho Signed-off-by: Kyungmin Park Cc: Mike Turquette Cc: Kukjin Kim Cc: Rob Herring Cc: Pawel Moll Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos3250.c | 780 +++++++++++++++++++++++++++++++++++ 2 files changed, 781 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos3250.c (limited to 'drivers') diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 916049472ba3..25646c61a02b 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -3,6 +3,7 @@ # obj-$(CONFIG_COMMON_CLK) += clk.o clk-pll.o +obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o diff --git a/drivers/clk/samsung/clk-exynos3250.c b/drivers/clk/samsung/clk-exynos3250.c new file mode 100644 index 000000000000..7a17bd40d1dd --- /dev/null +++ b/drivers/clk/samsung/clk-exynos3250.c @@ -0,0 +1,780 @@ +/* + * Copyright (c) 2014 Samsung Electronics Co., Ltd. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Common Clock Framework support for Exynos3250 SoC. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "clk.h" +#include "clk-pll.h" + +#define SRC_LEFTBUS 0x4200 +#define DIV_LEFTBUS 0x4500 +#define GATE_IP_LEFTBUS 0x4800 +#define SRC_RIGHTBUS 0x8200 +#define DIV_RIGHTBUS 0x8500 +#define GATE_IP_RIGHTBUS 0x8800 +#define GATE_IP_PERIR 0x8960 +#define MPLL_LOCK 0xc010 +#define MPLL_CON0 0xc110 +#define VPLL_LOCK 0xc020 +#define VPLL_CON0 0xc120 +#define UPLL_LOCK 0xc030 +#define UPLL_CON0 0xc130 +#define SRC_TOP0 0xc210 +#define SRC_TOP1 0xc214 +#define SRC_CAM 0xc220 +#define SRC_MFC 0xc228 +#define SRC_G3D 0xc22c +#define SRC_LCD 0xc234 +#define SRC_ISP 0xc238 +#define SRC_FSYS 0xc240 +#define SRC_PERIL0 0xc250 +#define SRC_PERIL1 0xc254 +#define SRC_MASK_TOP 0xc310 +#define SRC_MASK_CAM 0xc320 +#define SRC_MASK_LCD 0xc334 +#define SRC_MASK_ISP 0xc338 +#define SRC_MASK_FSYS 0xc340 +#define SRC_MASK_PERIL0 0xc350 +#define SRC_MASK_PERIL1 0xc354 +#define DIV_TOP 0xc510 +#define DIV_CAM 0xc520 +#define DIV_MFC 0xc528 +#define DIV_G3D 0xc52c +#define DIV_LCD 0xc534 +#define DIV_ISP 0xc538 +#define DIV_FSYS0 0xc540 +#define DIV_FSYS1 0xc544 +#define DIV_FSYS2 0xc548 +#define DIV_PERIL0 0xc550 +#define DIV_PERIL1 0xc554 +#define DIV_PERIL3 0xc55c +#define DIV_PERIL4 0xc560 +#define DIV_PERIL5 0xc564 +#define DIV_CAM1 0xc568 +#define CLKDIV2_RATIO 0xc580 +#define GATE_SCLK_CAM 0xc820 +#define GATE_SCLK_MFC 0xc828 +#define GATE_SCLK_G3D 0xc82c +#define GATE_SCLK_LCD 0xc834 +#define GATE_SCLK_ISP_TOP 0xc838 +#define GATE_SCLK_FSYS 0xc840 +#define GATE_SCLK_PERIL 0xc850 +#define GATE_IP_CAM 0xc920 +#define GATE_IP_MFC 0xc928 +#define GATE_IP_G3D 0xc92c +#define GATE_IP_LCD 0xc934 +#define GATE_IP_ISP 0xc938 +#define GATE_IP_FSYS 0xc940 +#define GATE_IP_PERIL 0xc950 +#define GATE_BLOCK 0xc970 +#define APLL_LOCK 0x14000 +#define APLL_CON0 0x14100 +#define SRC_CPU 0x14200 +#define DIV_CPU0 0x14500 +#define DIV_CPU1 0x14504 + +/* list of PLLs to be registered */ +enum exynos3250_plls { + apll, mpll, vpll, upll, + nr_plls +}; + +static void __iomem *reg_base; + +/* + * Support for CMU save/restore across system suspends + */ +#ifdef CONFIG_PM_SLEEP +static struct samsung_clk_reg_dump *exynos3250_clk_regs; + +static unsigned long exynos3250_cmu_clk_regs[] __initdata = { + SRC_LEFTBUS, + DIV_LEFTBUS, + GATE_IP_LEFTBUS, + SRC_RIGHTBUS, + DIV_RIGHTBUS, + GATE_IP_RIGHTBUS, + GATE_IP_PERIR, + MPLL_LOCK, + MPLL_CON0, + VPLL_LOCK, + VPLL_CON0, + UPLL_LOCK, + UPLL_CON0, + SRC_TOP0, + SRC_TOP1, + SRC_CAM, + SRC_MFC, + SRC_G3D, + SRC_LCD, + SRC_ISP, + SRC_FSYS, + SRC_PERIL0, + SRC_PERIL1, + SRC_MASK_TOP, + SRC_MASK_CAM, + SRC_MASK_LCD, + SRC_MASK_ISP, + SRC_MASK_FSYS, + SRC_MASK_PERIL0, + SRC_MASK_PERIL1, + DIV_TOP, + DIV_CAM, + DIV_MFC, + DIV_G3D, + DIV_LCD, + DIV_ISP, + DIV_FSYS0, + DIV_FSYS1, + DIV_FSYS2, + DIV_PERIL0, + DIV_PERIL1, + DIV_PERIL3, + DIV_PERIL4, + DIV_PERIL5, + DIV_CAM1, + CLKDIV2_RATIO, + GATE_SCLK_CAM, + GATE_SCLK_MFC, + GATE_SCLK_G3D, + GATE_SCLK_LCD, + GATE_SCLK_ISP_TOP, + GATE_SCLK_FSYS, + GATE_SCLK_PERIL, + GATE_IP_CAM, + GATE_IP_MFC, + GATE_IP_G3D, + GATE_IP_LCD, + GATE_IP_ISP, + GATE_IP_FSYS, + GATE_IP_PERIL, + GATE_BLOCK, + APLL_LOCK, + SRC_CPU, + DIV_CPU0, + DIV_CPU1, +}; + +static int exynos3250_clk_suspend(void) +{ + samsung_clk_save(reg_base, exynos3250_clk_regs, + ARRAY_SIZE(exynos3250_cmu_clk_regs)); + return 0; +} + +static void exynos3250_clk_resume(void) +{ + samsung_clk_restore(reg_base, exynos3250_clk_regs, + ARRAY_SIZE(exynos3250_cmu_clk_regs)); +} + +static struct syscore_ops exynos3250_clk_syscore_ops = { + .suspend = exynos3250_clk_suspend, + .resume = exynos3250_clk_resume, +}; + +static void exynos3250_clk_sleep_init(void) +{ + exynos3250_clk_regs = + samsung_clk_alloc_reg_dump(exynos3250_cmu_clk_regs, + ARRAY_SIZE(exynos3250_cmu_clk_regs)); + if (!exynos3250_clk_regs) { + pr_warn("%s: Failed to allocate sleep save data\n", __func__); + goto err; + } + + register_syscore_ops(&exynos3250_clk_syscore_ops); + return; +err: + kfree(exynos3250_clk_regs); +} +#else +static inline void exynos3250_clk_sleep_init(void) { } +#endif + +/* list of all parent clock list */ +PNAME(mout_vpllsrc_p) = { "fin_pll", }; + +PNAME(mout_apll_p) = { "fin_pll", "fout_apll", }; +PNAME(mout_mpll_p) = { "fin_pll", "fout_mpll", }; +PNAME(mout_vpll_p) = { "fin_pll", "fout_vpll", }; +PNAME(mout_upll_p) = { "fin_pll", "fout_upll", }; + +PNAME(mout_mpll_user_p) = { "fin_pll", "div_mpll_pre", }; +PNAME(mout_epll_user_p) = { "fin_pll", "mout_epll", }; +PNAME(mout_core_p) = { "mout_apll", "mout_mpll_user_c", }; +PNAME(mout_hpm_p) = { "mout_apll", "mout_mpll_user_c", }; + +PNAME(mout_ebi_p) = { "div_aclk_200", "div_aclk_160", }; +PNAME(mout_ebi_1_p) = { "mout_ebi", "mout_vpll", }; + +PNAME(mout_gdl_p) = { "mout_mpll_user_l", }; +PNAME(mout_gdr_p) = { "mout_mpll_user_r", }; + +PNAME(mout_aclk_400_mcuisp_sub_p) + = { "fin_pll", "div_aclk_400_mcuisp", }; +PNAME(mout_aclk_266_0_p) = { "div_mpll_pre", "mout_vpll", }; +PNAME(mout_aclk_266_1_p) = { "mout_epll_user", }; +PNAME(mout_aclk_266_p) = { "mout_aclk_266_0", "mout_aclk_266_1", }; +PNAME(mout_aclk_266_sub_p) = { "fin_pll", "div_aclk_266", }; + +PNAME(group_div_mpll_pre_p) = { "div_mpll_pre", }; +PNAME(group_epll_vpll_p) = { "mout_epll_user", "mout_vpll" }; +PNAME(group_sclk_p) = { "xxti", "xusbxti", + "none", "none", + "none", "none", "div_mpll_pre", + "mout_epll_user", "mout_vpll", }; +PNAME(group_sclk_audio_p) = { "audiocdclk", "none", + "none", "none", + "xxti", "xusbxti", + "div_mpll_pre", "mout_epll_user", + "mout_vpll", }; +PNAME(group_sclk_cam_blk_p) = { "xxti", "xusbxti", + "none", "none", "none", + "none", "div_mpll_pre", + "mout_epll_user", "mout_vpll", + "div_cam_blk_320", }; +PNAME(group_sclk_fimd0_p) = { "xxti", "xusbxti", + "m_bitclkhsdiv4_2l", "none", + "none", "none", "div_mpll_pre", + "mout_epll_user", "mout_vpll", + "none", "none", "none", + "div_lcd_blk_145", }; + +PNAME(mout_mfc_p) = { "mout_mfc_0", "mout_mfc_1" }; +PNAME(mout_g3d_p) = { "mout_g3d_0", "mout_g3d_1" }; + +static struct samsung_fixed_factor_clock fixed_factor_clks[] __initdata = { + FFACTOR(0, "sclk_mpll_1600", "mout_mpll", 1, 1, 0), + FFACTOR(0, "sclk_mpll_mif", "mout_mpll", 1, 2, 0), + FFACTOR(0, "sclk_bpll", "fout_bpll", 1, 2, 0), + FFACTOR(0, "div_cam_blk_320", "sclk_mpll_1600", 1, 5, 0), + FFACTOR(0, "div_lcd_blk_145", "sclk_mpll_1600", 1, 11, 0), + + /* HACK: fin_pll hardcoded to xusbxti until detection is implemented. */ + FFACTOR(CLK_FIN_PLL, "fin_pll", "xusbxti", 1, 1, 0), +}; + +static struct samsung_mux_clock mux_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* SRC_LEFTBUS */ + MUX(CLK_MOUT_MPLL_USER_L, "mout_mpll_user_l", mout_mpll_user_p, + SRC_LEFTBUS, 4, 1), + MUX(CLK_MOUT_GDL, "mout_gdl", mout_gdl_p, SRC_LEFTBUS, 0, 1), + + /* SRC_RIGHTBUS */ + MUX(CLK_MOUT_MPLL_USER_R, "mout_mpll_user_r", mout_mpll_user_p, + SRC_RIGHTBUS, 4, 1), + MUX(CLK_MOUT_GDR, "mout_gdr", mout_gdr_p, SRC_RIGHTBUS, 0, 1), + + /* SRC_TOP0 */ + MUX(CLK_MOUT_EBI, "mout_ebi", mout_ebi_p, SRC_TOP0, 28, 1), + MUX(CLK_MOUT_ACLK_200, "mout_aclk_200", group_div_mpll_pre_p,SRC_TOP0, 24, 1), + MUX(CLK_MOUT_ACLK_160, "mout_aclk_160", group_div_mpll_pre_p, SRC_TOP0, 20, 1), + MUX(CLK_MOUT_ACLK_100, "mout_aclk_100", group_div_mpll_pre_p, SRC_TOP0, 16, 1), + MUX(CLK_MOUT_ACLK_266_1, "mout_aclk_266_1", mout_aclk_266_1_p, SRC_TOP0, 14, 1), + MUX(CLK_MOUT_ACLK_266_0, "mout_aclk_266_0", mout_aclk_266_0_p, SRC_TOP0, 13, 1), + MUX(CLK_MOUT_ACLK_266, "mout_aclk_266", mout_aclk_266_p, SRC_TOP0, 12, 1), + MUX(CLK_MOUT_VPLL, "mout_vpll", mout_vpll_p, SRC_TOP0, 8, 1), + MUX(CLK_MOUT_EPLL_USER, "mout_epll_user", mout_epll_user_p, SRC_TOP0, 4, 1), + MUX(CLK_MOUT_EBI_1, "mout_ebi_1", mout_ebi_1_p, SRC_TOP0, 0, 1), + + /* SRC_TOP1 */ + MUX(CLK_MOUT_UPLL, "mout_upll", mout_upll_p, SRC_TOP1, 28, 1), + MUX(CLK_MOUT_ACLK_400_MCUISP_SUB, "mout_aclk_400_mcuisp_sub", mout_aclk_400_mcuisp_sub_p, + SRC_TOP1, 24, 1), + MUX(CLK_MOUT_ACLK_266_SUB, "mout_aclk_266_sub", mout_aclk_266_sub_p, SRC_TOP1, 20, 1), + MUX(CLK_MOUT_MPLL, "mout_mpll", mout_mpll_p, SRC_TOP1, 12, 1), + MUX(CLK_MOUT_ACLK_400_MCUISP, "mout_aclk_400_mcuisp", group_div_mpll_pre_p, SRC_TOP1, 8, 1), + MUX(CLK_MOUT_VPLLSRC, "mout_vpllsrc", mout_vpllsrc_p, SRC_TOP1, 0, 1), + + /* SRC_CAM */ + MUX(CLK_MOUT_CAM1, "mout_cam1", group_sclk_p, SRC_CAM, 20, 4), + MUX(CLK_MOUT_CAM_BLK, "mout_cam_blk", group_sclk_cam_blk_p, SRC_CAM, 0, 4), + + /* SRC_MFC */ + MUX(CLK_MOUT_MFC, "mout_mfc", mout_mfc_p, SRC_MFC, 8, 1), + MUX(CLK_MOUT_MFC_1, "mout_mfc_1", group_epll_vpll_p, SRC_MFC, 4, 1), + MUX(CLK_MOUT_MFC_0, "mout_mfc_0", group_div_mpll_pre_p, SRC_MFC, 0, 1), + + /* SRC_G3D */ + MUX(CLK_MOUT_G3D, "mout_g3d", mout_g3d_p, SRC_G3D, 8, 1), + MUX(CLK_MOUT_G3D_1, "mout_g3d_1", group_epll_vpll_p, SRC_G3D, 4, 1), + MUX(CLK_MOUT_G3D_0, "mout_g3d_0", group_div_mpll_pre_p, SRC_G3D, 0, 1), + + /* SRC_LCD */ + MUX(CLK_MOUT_MIPI0, "mout_mipi0", group_sclk_p, SRC_LCD, 12, 4), + MUX(CLK_MOUT_FIMD0, "mout_fimd0", group_sclk_fimd0_p, SRC_LCD, 0, 4), + + /* SRC_ISP */ + MUX(CLK_MOUT_UART_ISP, "mout_uart_isp", group_sclk_p, SRC_ISP, 12, 4), + MUX(CLK_MOUT_SPI1_ISP, "mout_spi1_isp", group_sclk_p, SRC_ISP, 8, 4), + MUX(CLK_MOUT_SPI0_ISP, "mout_spi0_isp", group_sclk_p, SRC_ISP, 4, 4), + + /* SRC_FSYS */ + MUX(CLK_MOUT_TSADC, "mout_tsadc", group_sclk_p, SRC_FSYS, 28, 4), + MUX(CLK_MOUT_MMC1, "mout_mmc1", group_sclk_p, SRC_FSYS, 4, 3), + MUX(CLK_MOUT_MMC0, "mout_mmc0", group_sclk_p, SRC_FSYS, 0, 3), + + /* SRC_PERIL0 */ + MUX(CLK_MOUT_UART1, "mout_uart1", group_sclk_p, SRC_PERIL0, 4, 4), + MUX(CLK_MOUT_UART0, "mout_uart0", group_sclk_p, SRC_PERIL0, 0, 4), + + /* SRC_PERIL1 */ + MUX(CLK_MOUT_SPI1, "mout_spi1", group_sclk_p, SRC_PERIL1, 20, 4), + MUX(CLK_MOUT_SPI0, "mout_spi0", group_sclk_p, SRC_PERIL1, 16, 4), + MUX(CLK_MOUT_AUDIO, "mout_audio", group_sclk_audio_p, SRC_PERIL1, 4, 4), + + /* SRC_CPU */ + MUX(CLK_MOUT_MPLL_USER_C, "mout_mpll_user_c", mout_mpll_user_p, + SRC_CPU, 24, 1), + MUX(CLK_MOUT_HPM, "mout_hpm", mout_hpm_p, SRC_CPU, 20, 1), + MUX(CLK_MOUT_CORE, "mout_core", mout_core_p, SRC_CPU, 16, 1), + MUX(CLK_MOUT_APLL, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), +}; + +static struct samsung_div_clock div_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* DIV_LEFTBUS */ + DIV(CLK_DIV_GPL, "div_gpl", "div_gdl", DIV_LEFTBUS, 4, 3), + DIV(CLK_DIV_GDL, "div_gdl", "mout_gdl", DIV_LEFTBUS, 0, 4), + + /* DIV_RIGHTBUS */ + DIV(CLK_DIV_GPR, "div_gpr", "div_gdr", DIV_RIGHTBUS, 4, 3), + DIV(CLK_DIV_GDR, "div_gdr", "mout_gdr", DIV_RIGHTBUS, 0, 4), + + /* DIV_TOP */ + DIV(CLK_DIV_MPLL_PRE, "div_mpll_pre", "sclk_mpll_mif", DIV_TOP, 28, 2), + DIV(CLK_DIV_ACLK_400_MCUISP, "div_aclk_400_mcuisp", + "mout_aclk_400_mcuisp", DIV_TOP, 24, 3), + DIV(CLK_DIV_EBI, "div_ebi", "mout_ebi_1", DIV_TOP, 16, 3), + DIV(CLK_DIV_ACLK_200, "div_aclk_200", "mout_aclk_200", DIV_TOP, 12, 3), + DIV(CLK_DIV_ACLK_160, "div_aclk_160", "mout_aclk_160", DIV_TOP, 8, 3), + DIV(CLK_DIV_ACLK_100, "div_aclk_100", "mout_aclk_100", DIV_TOP, 4, 4), + DIV(CLK_DIV_ACLK_266, "div_aclk_266", "mout_aclk_266", DIV_TOP, 0, 3), + + /* DIV_CAM */ + DIV(CLK_DIV_CAM1, "div_cam1", "mout_cam1", DIV_CAM, 20, 4), + DIV(CLK_DIV_CAM_BLK, "div_cam_blk", "mout_cam_blk", DIV_CAM, 0, 4), + + /* DIV_MFC */ + DIV(CLK_DIV_MFC, "div_mfc", "mout_mfc", DIV_MFC, 0, 4), + + /* DIV_G3D */ + DIV(CLK_DIV_G3D, "div_g3d", "mout_g3d", DIV_G3D, 0, 4), + + /* DIV_LCD */ + DIV_F(CLK_DIV_MIPI0_PRE, "div_mipi0_pre", "div_mipi0", DIV_LCD, 20, 4, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MIPI0, "div_mipi0", "mout_mipi0", DIV_LCD, 16, 4), + DIV(CLK_DIV_FIMD0, "div_fimd0", "mout_fimd0", DIV_LCD, 0, 4), + + /* DIV_ISP */ + DIV(CLK_DIV_UART_ISP, "div_uart_isp", "mout_uart_isp", DIV_ISP, 28, 4), + DIV_F(CLK_DIV_SPI1_ISP_PRE, "div_spi1_isp_pre", "div_spi1_isp", + DIV_ISP, 20, 8, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI1_ISP, "div_spi1_isp", "mout_spi1_isp", DIV_ISP, 16, 4), + DIV_F(CLK_DIV_SPI0_ISP_PRE, "div_spi0_isp_pre", "div_spi0_isp", + DIV_ISP, 8, 8, CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI0_ISP, "div_spi0_isp", "mout_spi0_isp", DIV_ISP, 0, 4), + + /* DIV_FSYS0 */ + DIV_F(CLK_DIV_TSADC_PRE, "div_tsadc_pre", "div_tsadc", DIV_FSYS0, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_TSADC, "div_tsadc", "mout_tsadc", DIV_FSYS0, 0, 4), + + /* DIV_FSYS1 */ + DIV_F(CLK_DIV_MMC1_PRE, "div_mmc1_pre", "div_mmc1", DIV_FSYS1, 24, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MMC1, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV_F(CLK_DIV_MMC0_PRE, "div_mmc0_pre", "div_mmc0", DIV_FSYS1, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_MMC0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + + /* DIV_PERIL0 */ + DIV(CLK_DIV_UART1, "div_uart1", "mout_uart1", DIV_PERIL0, 4, 4), + DIV(CLK_DIV_UART0, "div_uart0", "mout_uart0", DIV_PERIL0, 0, 4), + + /* DIV_PERIL1 */ + DIV_F(CLK_DIV_SPI1_PRE, "div_spi1_pre", "div_spi1", DIV_PERIL1, 24, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI1, "div_spi1", "mout_spi1", DIV_PERIL1, 16, 4), + DIV_F(CLK_DIV_SPI0_PRE, "div_spi0_pre", "div_spi0", DIV_PERIL1, 8, 8, + CLK_SET_RATE_PARENT, 0), + DIV(CLK_DIV_SPI0, "div_spi0", "mout_spi0", DIV_PERIL1, 0, 4), + + /* DIV_PERIL4 */ + DIV(CLK_DIV_PCM, "div_pcm", "div_audio", DIV_PERIL4, 20, 8), + DIV(CLK_DIV_AUDIO, "div_audio", "mout_audio", DIV_PERIL4, 16, 4), + + /* DIV_PERIL5 */ + DIV(CLK_DIV_I2S, "div_i2s", "div_audio", DIV_PERIL5, 8, 6), + + /* DIV_CPU0 */ + DIV(CLK_DIV_CORE2, "div_core2", "div_core", DIV_CPU0, 28, 3), + DIV(CLK_DIV_APLL, "div_apll", "mout_apll", DIV_CPU0, 24, 3), + DIV(CLK_DIV_PCLK_DBG, "div_pclk_dbg", "div_core2", DIV_CPU0, 20, 3), + DIV(CLK_DIV_ATB, "div_atb", "div_core2", DIV_CPU0, 16, 3), + DIV(CLK_DIV_COREM, "div_corem", "div_core2", DIV_CPU0, 4, 3), + DIV(CLK_DIV_CORE, "div_core", "mout_core", DIV_CPU0, 0, 3), + + /* DIV_CPU1 */ + DIV(CLK_DIV_HPM, "div_hpm", "div_copy", DIV_CPU1, 4, 3), + DIV(CLK_DIV_COPY, "div_copy", "mout_hpm", DIV_CPU1, 0, 3), +}; + +static struct samsung_gate_clock gate_clks[] __initdata = { + /* + * NOTE: Following table is sorted by register address in ascending + * order and then bitfield shift in descending order, as it is done + * in the User's Manual. When adding new entries, please make sure + * that the order is preserved, to avoid merge conflicts and make + * further work with defined data easier. + */ + + /* GATE_IP_LEFTBUS */ + GATE(CLK_ASYNC_G3D, "async_g3d", "div_aclk_100", GATE_IP_LEFTBUS, 6, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_MFCL, "async_mfcl", "div_aclk_100", GATE_IP_LEFTBUS, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMULEFT, "ppmuleft", "div_aclk_100", GATE_IP_LEFTBUS, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_GPIO_LEFT, "gpio_left", "div_aclk_100", GATE_IP_LEFTBUS, 0, + CLK_IGNORE_UNUSED, 0), + + /* GATE_IP_RIGHTBUS */ + GATE(CLK_ASYNC_ISPMX, "async_ispmx", "div_aclk_100", + GATE_IP_RIGHTBUS, 9, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_FSYSD, "async_fsysd", "div_aclk_100", + GATE_IP_RIGHTBUS, 5, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_LCD0X, "async_lcd0x", "div_aclk_100", + GATE_IP_RIGHTBUS, 3, CLK_IGNORE_UNUSED, 0), + GATE(CLK_ASYNC_CAMX, "async_camx", "div_aclk_100", GATE_IP_RIGHTBUS, 2, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMURIGHT, "ppmuright", "div_aclk_100", GATE_IP_RIGHTBUS, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_GPIO_RIGHT, "gpio_right", "div_aclk_100", GATE_IP_RIGHTBUS, 0, + CLK_IGNORE_UNUSED, 0), + + /* GATE_IP_PERIR */ + GATE(CLK_MONOCNT, "monocnt", "div_aclk_100", GATE_IP_PERIR, 22, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC6, "tzpc6", "div_aclk_100", GATE_IP_PERIR, 21, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PROVISIONKEY1, "provisionkey1", "div_aclk_100", + GATE_IP_PERIR, 20, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PROVISIONKEY0, "provisionkey0", "div_aclk_100", + GATE_IP_PERIR, 19, CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_ISPPART, "cmu_isppart", "div_aclk_100", GATE_IP_PERIR, 18, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TMU_APBIF, "tmu_apbif", "div_aclk_100", + GATE_IP_PERIR, 17, 0, 0), + GATE(CLK_KEYIF, "keyif", "div_aclk_100", GATE_IP_PERIR, 16, 0, 0), + GATE(CLK_RTC, "rtc", "div_aclk_100", GATE_IP_PERIR, 15, 0, 0), + GATE(CLK_WDT, "wdt", "div_aclk_100", GATE_IP_PERIR, 14, 0, 0), + GATE(CLK_MCT, "mct", "div_aclk_100", GATE_IP_PERIR, 13, 0, 0), + GATE(CLK_SECKEY, "seckey", "div_aclk_100", GATE_IP_PERIR, 12, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC5, "tzpc5", "div_aclk_100", GATE_IP_PERIR, 10, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC4, "tzpc4", "div_aclk_100", GATE_IP_PERIR, 9, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC3, "tzpc3", "div_aclk_100", GATE_IP_PERIR, 8, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC2, "tzpc2", "div_aclk_100", GATE_IP_PERIR, 7, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC1, "tzpc1", "div_aclk_100", GATE_IP_PERIR, 6, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_TZPC0, "tzpc0", "div_aclk_100", GATE_IP_PERIR, 5, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_COREPART, "cmu_corepart", "div_aclk_100", GATE_IP_PERIR, 4, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CMU_TOPPART, "cmu_toppart", "div_aclk_100", GATE_IP_PERIR, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PMU_APBIF, "pmu_apbif", "div_aclk_100", GATE_IP_PERIR, 2, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SYSREG, "sysreg", "div_aclk_100", GATE_IP_PERIR, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_CHIP_ID, "chip_id", "div_aclk_100", GATE_IP_PERIR, 0, + CLK_IGNORE_UNUSED, 0), + + /* GATE_SCLK_CAM */ + GATE(CLK_SCLK_JPEG, "sclk_jpeg", "div_cam_blk", + GATE_SCLK_CAM, 8, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_M2MSCALER, "sclk_m2mscaler", "div_cam_blk", + GATE_SCLK_CAM, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_GSCALER1, "sclk_gscaler1", "div_cam_blk", + GATE_SCLK_CAM, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_GSCALER0, "sclk_gscaler0", "div_cam_blk", + GATE_SCLK_CAM, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_MFC */ + GATE(CLK_SCLK_MFC, "sclk_mfc", "div_mfc", + GATE_SCLK_MFC, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_G3D */ + GATE(CLK_SCLK_G3D, "sclk_g3d", "div_g3d", + GATE_SCLK_G3D, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_LCD */ + GATE(CLK_SCLK_MIPIDPHY2L, "sclk_mipidphy2l", "div_mipi0", + GATE_SCLK_LCD, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MIPI0, "sclk_mipi0", "div_mipi0_pre", + GATE_SCLK_LCD, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_FIMD0, "sclk_fimd0", "div_fimd0", + GATE_SCLK_LCD, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_ISP_TOP */ + GATE(CLK_SCLK_CAM1, "sclk_cam1", "div_cam1", + GATE_SCLK_ISP_TOP, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART_ISP, "sclk_uart_isp", "div_uart_isp", + GATE_SCLK_ISP_TOP, 3, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI1_ISP, "sclk_spi1_isp", "div_spi1_isp", + GATE_SCLK_ISP_TOP, 2, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI0_ISP, "sclk_spi0_isp", "div_spi0_isp", + GATE_SCLK_ISP_TOP, 1, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_FSYS */ + GATE(CLK_SCLK_UPLL, "sclk_upll", "mout_upll", GATE_SCLK_FSYS, 10, 0, 0), + GATE(CLK_SCLK_TSADC, "sclk_tsadc", "div_tsadc_pre", + GATE_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_EBI, "sclk_ebi", "div_ebi", + GATE_SCLK_FSYS, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc1_pre", + GATE_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc0_pre", + GATE_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_SCLK_PERIL */ + GATE(CLK_SCLK_I2S, "sclk_i2s", "div_i2s", + GATE_SCLK_PERIL, 18, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_PCM, "sclk_pcm", "div_pcm", + GATE_SCLK_PERIL, 16, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI1, "sclk_spi1", "div_spi1_pre", + GATE_SCLK_PERIL, 7, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_SPI0, "sclk_spi0", "div_spi0_pre", + GATE_SCLK_PERIL, 6, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1", + GATE_SCLK_PERIL, 1, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0", + GATE_SCLK_PERIL, 0, CLK_SET_RATE_PARENT, 0), + + /* GATE_IP_CAM */ + GATE(CLK_QEJPEG, "qejpeg", "div_cam_blk_320", GATE_IP_CAM, 19, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PIXELASYNCM1, "pixelasyncm1", "div_cam_blk_320", + GATE_IP_CAM, 18, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PIXELASYNCM0, "pixelasyncm0", "div_cam_blk_320", + GATE_IP_CAM, 17, CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMUCAMIF, "ppmucamif", "div_cam_blk_320", + GATE_IP_CAM, 16, CLK_IGNORE_UNUSED, 0), + GATE(CLK_QEM2MSCALER, "qem2mscaler", "div_cam_blk_320", + GATE_IP_CAM, 14, CLK_IGNORE_UNUSED, 0), + GATE(CLK_QEGSCALER1, "qegscaler1", "div_cam_blk_320", + GATE_IP_CAM, 13, CLK_IGNORE_UNUSED, 0), + GATE(CLK_QEGSCALER0, "qegscaler0", "div_cam_blk_320", + GATE_IP_CAM, 12, CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUJPEG, "smmujpeg", "div_cam_blk_320", + GATE_IP_CAM, 11, 0, 0), + GATE(CLK_SMMUM2M2SCALER, "smmum2m2scaler", "div_cam_blk_320", + GATE_IP_CAM, 9, 0, 0), + GATE(CLK_SMMUGSCALER1, "smmugscaler1", "div_cam_blk_320", + GATE_IP_CAM, 8, 0, 0), + GATE(CLK_SMMUGSCALER0, "smmugscaler0", "div_cam_blk_320", + GATE_IP_CAM, 7, 0, 0), + GATE(CLK_JPEG, "jpeg", "div_cam_blk_320", GATE_IP_CAM, 6, 0, 0), + GATE(CLK_M2MSCALER, "m2mscaler", "div_cam_blk_320", + GATE_IP_CAM, 2, 0, 0), + GATE(CLK_GSCALER1, "gscaler1", "div_cam_blk_320", GATE_IP_CAM, 1, 0, 0), + GATE(CLK_GSCALER0, "gscaler0", "div_cam_blk_320", GATE_IP_CAM, 0, 0, 0), + + /* GATE_IP_MFC */ + GATE(CLK_QEMFC, "qemfc", "div_aclk_200", GATE_IP_MFC, 5, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMUMFC_L, "ppmumfc_l", "div_aclk_200", GATE_IP_MFC, 3, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUMFC_L, "smmumfc_l", "div_aclk_200", GATE_IP_MFC, 1, 0, 0), + GATE(CLK_MFC, "mfc", "div_aclk_200", GATE_IP_MFC, 0, 0, 0), + + /* GATE_IP_G3D */ + GATE(CLK_SMMUG3D, "smmug3d", "div_aclk_200", GATE_IP_G3D, 3, 0, 0), + GATE(CLK_QEG3D, "qeg3d", "div_aclk_200", GATE_IP_G3D, 2, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMUG3D, "ppmug3d", "div_aclk_200", GATE_IP_G3D, 1, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_G3D, "g3d", "div_aclk_200", GATE_IP_G3D, 0, 0, 0), + + /* GATE_IP_LCD */ + GATE(CLK_QE_CH1_LCD, "qe_ch1_lcd", "div_aclk_160", GATE_IP_LCD, 7, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_QE_CH0_LCD, "qe_ch0_lcd", "div_aclk_160", GATE_IP_LCD, 6, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_PPMULCD0, "ppmulcd0", "div_aclk_160", GATE_IP_LCD, 5, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_SMMUFIMD0, "smmufimd0", "div_aclk_160", GATE_IP_LCD, 4, 0, 0), + GATE(CLK_DSIM0, "dsim0", "div_aclk_160", GATE_IP_LCD, 3, 0, 0), + GATE(CLK_SMIES, "smies", "div_aclk_160", GATE_IP_LCD, 2, 0, 0), + GATE(CLK_FIMD0, "fimd0", "div_aclk_160", GATE_IP_LCD, 0, 0, 0), + + /* GATE_IP_ISP */ + GATE(CLK_CAM1, "cam1", "mout_aclk_266_sub", GATE_IP_ISP, 5, 0, 0), + GATE(CLK_UART_ISP_TOP, "uart_isp_top", "mout_aclk_266_sub", + GATE_IP_ISP, 3, 0, 0), + GATE(CLK_SPI1_ISP_TOP, "spi1_isp_top", "mout_aclk_266_sub", + GATE_IP_ISP, 2, 0, 0), + GATE(CLK_SPI0_ISP_TOP, "spi0_isp_top", "mout_aclk_266_sub", + GATE_IP_ISP, 1, 0, 0), + + /* GATE_IP_FSYS */ + GATE(CLK_TSADC, "tsadc", "div_aclk_200", GATE_IP_FSYS, 20, 0, 0), + GATE(CLK_PPMUFILE, "ppmufile", "div_aclk_200", GATE_IP_FSYS, 17, + CLK_IGNORE_UNUSED, 0), + GATE(CLK_USBOTG, "usbotg", "div_aclk_200", GATE_IP_FSYS, 13, 0, 0), + GATE(CLK_USBHOST, "usbhost", "div_aclk_200", GATE_IP_FSYS, 12, 0, 0), + GATE(CLK_SROMC, "sromc", "div_aclk_200", GATE_IP_FSYS, 11, 0, 0), + GATE(CLK_SDMMC1, "sdmmc1", "div_aclk_200", GATE_IP_FSYS, 6, 0, 0), + GATE(CLK_SDMMC0, "sdmmc0", "div_aclk_200", GATE_IP_FSYS, 5, 0, 0), + GATE(CLK_PDMA1, "pdma1", "div_aclk_200", GATE_IP_FSYS, 1, 0, 0), + GATE(CLK_PDMA0, "pdma0", "div_aclk_200", GATE_IP_FSYS, 0, 0, 0), + + /* GATE_IP_PERIL */ + GATE(CLK_PWM, "pwm", "div_aclk_100", GATE_IP_PERIL, 24, 0, 0), + GATE(CLK_PCM, "pcm", "div_aclk_100", GATE_IP_PERIL, 23, 0, 0), + GATE(CLK_I2S, "i2s", "div_aclk_100", GATE_IP_PERIL, 21, 0, 0), + GATE(CLK_SPI1, "spi1", "div_aclk_100", GATE_IP_PERIL, 17, 0, 0), + GATE(CLK_SPI0, "spi0", "div_aclk_100", GATE_IP_PERIL, 16, 0, 0), + GATE(CLK_I2C7, "i2c7", "div_aclk_100", GATE_IP_PERIL, 13, 0, 0), + GATE(CLK_I2C6, "i2c6", "div_aclk_100", GATE_IP_PERIL, 12, 0, 0), + GATE(CLK_I2C5, "i2c5", "div_aclk_100", GATE_IP_PERIL, 11, 0, 0), + GATE(CLK_I2C4, "i2c4", "div_aclk_100", GATE_IP_PERIL, 10, 0, 0), + GATE(CLK_I2C3, "i2c3", "div_aclk_100", GATE_IP_PERIL, 9, 0, 0), + GATE(CLK_I2C2, "i2c2", "div_aclk_100", GATE_IP_PERIL, 8, 0, 0), + GATE(CLK_I2C1, "i2c1", "div_aclk_100", GATE_IP_PERIL, 7, 0, 0), + GATE(CLK_I2C0, "i2c0", "div_aclk_100", GATE_IP_PERIL, 6, 0, 0), + GATE(CLK_UART1, "uart1", "div_aclk_100", GATE_IP_PERIL, 1, 0, 0), + GATE(CLK_UART0, "uart0", "div_aclk_100", GATE_IP_PERIL, 0, 0, 0), +}; + +/* APLL & MPLL & BPLL & UPLL */ +static struct samsung_pll_rate_table exynos3250_pll_rates[] = { + PLL_35XX_RATE(1200000000, 400, 4, 1), + PLL_35XX_RATE(1100000000, 275, 3, 1), + PLL_35XX_RATE(1066000000, 533, 6, 1), + PLL_35XX_RATE(1000000000, 250, 3, 1), + PLL_35XX_RATE( 960000000, 320, 4, 1), + PLL_35XX_RATE( 900000000, 300, 4, 1), + PLL_35XX_RATE( 850000000, 425, 6, 1), + PLL_35XX_RATE( 800000000, 200, 3, 1), + PLL_35XX_RATE( 700000000, 175, 3, 1), + PLL_35XX_RATE( 667000000, 667, 12, 1), + PLL_35XX_RATE( 600000000, 400, 4, 2), + PLL_35XX_RATE( 533000000, 533, 6, 2), + PLL_35XX_RATE( 520000000, 260, 3, 2), + PLL_35XX_RATE( 500000000, 250, 3, 2), + PLL_35XX_RATE( 400000000, 200, 3, 2), + PLL_35XX_RATE( 200000000, 200, 3, 3), + PLL_35XX_RATE( 100000000, 200, 3, 4), + { /* sentinel */ } +}; + +/* VPLL */ +static struct samsung_pll_rate_table exynos3250_vpll_rates[] = { + PLL_36XX_RATE(600000000, 100, 2, 1, 0), + PLL_36XX_RATE(533000000, 266, 3, 2, 32768), + PLL_36XX_RATE(519230987, 173, 2, 2, 5046), + PLL_36XX_RATE(500000000, 250, 3, 2, 0), + PLL_36XX_RATE(445500000, 148, 2, 2, 32768), + PLL_36XX_RATE(445055007, 148, 2, 2, 23047), + PLL_36XX_RATE(400000000, 200, 3, 2, 0), + PLL_36XX_RATE(371250000, 123, 2, 2, 49152), + PLL_36XX_RATE(370878997, 185, 3, 2, 28803), + PLL_36XX_RATE(340000000, 170, 3, 2, 0), + PLL_36XX_RATE(335000015, 111, 2, 2, 43691), + PLL_36XX_RATE(333000000, 111, 2, 2, 0), + PLL_36XX_RATE(330000000, 110, 2, 2, 0), + PLL_36XX_RATE(320000015, 106, 2, 2, 43691), + PLL_36XX_RATE(300000000, 100, 2, 2, 0), + PLL_36XX_RATE(275000000, 275, 3, 3, 0), + PLL_36XX_RATE(222750000, 148, 2, 3, 32768), + PLL_36XX_RATE(222528007, 148, 2, 3, 23069), + PLL_36XX_RATE(160000000, 160, 3, 3, 0), + PLL_36XX_RATE(148500000, 99, 2, 3, 0), + PLL_36XX_RATE(148352005, 98, 2, 3, 59070), + PLL_36XX_RATE(108000000, 144, 2, 4, 0), + PLL_36XX_RATE( 74250000, 99, 2, 4, 0), + PLL_36XX_RATE( 74176002, 98, 3, 4, 59070), + PLL_36XX_RATE( 54054000, 216, 3, 5, 14156), + PLL_36XX_RATE( 54000000, 144, 2, 5, 0), + { /* sentinel */ } +}; + +static struct samsung_pll_clock exynos3250_plls[nr_plls] __initdata = { + [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", + APLL_LOCK, APLL_CON0, NULL), + [mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", + MPLL_LOCK, MPLL_CON0, NULL), + [vpll] = PLL(pll_36xx, CLK_FOUT_VPLL, "fout_vpll", "fin_pll", + VPLL_LOCK, VPLL_CON0, NULL), + [upll] = PLL(pll_35xx, CLK_FOUT_UPLL, "fout_upll", "fin_pll", + UPLL_LOCK, UPLL_CON0, NULL), +}; + +static void __init exynos3250_cmu_init(struct device_node *np) +{ + struct samsung_clk_provider *ctx; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + if (!ctx) + panic("%s: unable to allocate context.\n", __func__); + + samsung_clk_register_fixed_factor(ctx, fixed_factor_clks, + ARRAY_SIZE(fixed_factor_clks)); + + exynos3250_plls[apll].rate_table = exynos3250_pll_rates; + exynos3250_plls[mpll].rate_table = exynos3250_pll_rates; + exynos3250_plls[vpll].rate_table = exynos3250_vpll_rates; + exynos3250_plls[upll].rate_table = exynos3250_pll_rates; + + samsung_clk_register_pll(ctx, exynos3250_plls, + ARRAY_SIZE(exynos3250_plls), reg_base); + + samsung_clk_register_mux(ctx, mux_clks, ARRAY_SIZE(mux_clks)); + samsung_clk_register_div(ctx, div_clks, ARRAY_SIZE(div_clks)); + samsung_clk_register_gate(ctx, gate_clks, ARRAY_SIZE(gate_clks)); + + exynos3250_clk_sleep_init(); +} +CLK_OF_DECLARE(exynos3250_cmu, "samsung,exynos3250-cmu", exynos3250_cmu_init); -- cgit v1.2.2 From 6520e968eef4f88c076a84a80e026049d157132e Mon Sep 17 00:00:00 2001 From: Alim Akhtar Date: Mon, 19 May 2014 22:15:08 +0900 Subject: clk: exynos5420: Add 5800 specific clocks Exynos5800 clock structure is mostly similar to 5420 with only a small delta changes. So the 5420 clock file is re-used for 5800 also. The common clocks for both are seggreagated and few clocks which are different for both are separately initialized. Signed-off-by: Alim Akhtar Signed-off-by: Arun Kumar K Acked-by: Tomasz Figa Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos5420.c | 309 ++++++++++++++++++++++++++++------- 1 file changed, 253 insertions(+), 56 deletions(-) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c index 1c3674ecc0dc..9d7d7eed03fd 100644 --- a/drivers/clk/samsung/clk-exynos5420.c +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -57,15 +57,19 @@ #define SRC_TOP5 0x10214 #define SRC_TOP6 0x10218 #define SRC_TOP7 0x1021c +#define SRC_TOP8 0x10220 /* 5800 specific */ +#define SRC_TOP9 0x10224 /* 5800 specific */ #define SRC_DISP10 0x1022c #define SRC_MAU 0x10240 #define SRC_FSYS 0x10244 #define SRC_PERIC0 0x10250 #define SRC_PERIC1 0x10254 #define SRC_ISP 0x10270 +#define SRC_CAM 0x10274 /* 5800 specific */ #define SRC_TOP10 0x10280 #define SRC_TOP11 0x10284 #define SRC_TOP12 0x10288 +#define SRC_TOP13 0x1028c /* 5800 specific */ #define SRC_MASK_TOP2 0x10308 #define SRC_MASK_TOP7 0x1031c #define SRC_MASK_DISP10 0x1032c @@ -76,6 +80,8 @@ #define DIV_TOP0 0x10500 #define DIV_TOP1 0x10504 #define DIV_TOP2 0x10508 +#define DIV_TOP8 0x10520 /* 5800 specific */ +#define DIV_TOP9 0x10524 /* 5800 specific */ #define DIV_DISP10 0x1052c #define DIV_MAU 0x10544 #define DIV_FSYS0 0x10548 @@ -86,6 +92,7 @@ #define DIV_PERIC2 0x10560 #define DIV_PERIC3 0x10564 #define DIV_PERIC4 0x10568 +#define DIV_CAM 0x10574 /* 5800 specific */ #define SCLK_DIV_ISP0 0x10580 #define SCLK_DIV_ISP1 0x10584 #define DIV2_RATIO0 0x10590 @@ -102,6 +109,7 @@ #define GATE_TOP_SCLK_ISP 0x10870 #define GATE_IP_GSCL0 0x10910 #define GATE_IP_GSCL1 0x10920 +#define GATE_IP_CAM 0x10924 /* 5800 specific */ #define GATE_IP_MFC 0x1092c #define GATE_IP_DISP1 0x10928 #define GATE_IP_G3D 0x10930 @@ -123,23 +131,31 @@ #define SRC_KFC 0x28200 #define DIV_KFC0 0x28500 +/* Exynos5x SoC type */ +enum exynos5x_soc { + EXYNOS5420, + EXYNOS5800, +}; + /* list of PLLs */ -enum exynos5420_plls { +enum exynos5x_plls { apll, cpll, dpll, epll, rpll, ipll, spll, vpll, mpll, bpll, kpll, nr_plls /* number of PLLs */ }; static void __iomem *reg_base; +static enum exynos5x_soc exynos5x_soc; #ifdef CONFIG_PM_SLEEP -static struct samsung_clk_reg_dump *exynos5420_save; +static struct samsung_clk_reg_dump *exynos5x_save; +static struct samsung_clk_reg_dump *exynos5800_save; /* * list of controller registers to be saved and restored during a * suspend/resume cycle. */ -static unsigned long exynos5420_clk_regs[] __initdata = { +static unsigned long exynos5x_clk_regs[] __initdata = { SRC_CPU, DIV_CPU0, DIV_CPU1, @@ -222,18 +238,37 @@ static unsigned long exynos5420_clk_regs[] __initdata = { DIV_KFC0, }; +static unsigned long exynos5800_clk_regs[] __initdata = { + SRC_TOP8, + SRC_TOP9, + SRC_CAM, + SRC_TOP1, + DIV_TOP8, + DIV_TOP9, + DIV_CAM, + GATE_IP_CAM, +}; + static int exynos5420_clk_suspend(void) { - samsung_clk_save(reg_base, exynos5420_save, - ARRAY_SIZE(exynos5420_clk_regs)); + samsung_clk_save(reg_base, exynos5x_save, + ARRAY_SIZE(exynos5x_clk_regs)); + + if (exynos5x_soc == EXYNOS5800) + samsung_clk_save(reg_base, exynos5800_save, + ARRAY_SIZE(exynos5800_clk_regs)); return 0; } static void exynos5420_clk_resume(void) { - samsung_clk_restore(reg_base, exynos5420_save, - ARRAY_SIZE(exynos5420_clk_regs)); + samsung_clk_restore(reg_base, exynos5x_save, + ARRAY_SIZE(exynos5x_clk_regs)); + + if (exynos5x_soc == EXYNOS5800) + samsung_clk_restore(reg_base, exynos5800_save, + ARRAY_SIZE(exynos5800_clk_regs)); } static struct syscore_ops exynos5420_clk_syscore_ops = { @@ -243,15 +278,29 @@ static struct syscore_ops exynos5420_clk_syscore_ops = { static void exynos5420_clk_sleep_init(void) { - exynos5420_save = samsung_clk_alloc_reg_dump(exynos5420_clk_regs, - ARRAY_SIZE(exynos5420_clk_regs)); - if (!exynos5420_save) { + exynos5x_save = samsung_clk_alloc_reg_dump(exynos5x_clk_regs, + ARRAY_SIZE(exynos5x_clk_regs)); + if (!exynos5x_save) { pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", __func__); return; } + if (exynos5x_soc == EXYNOS5800) { + exynos5800_save = + samsung_clk_alloc_reg_dump(exynos5800_clk_regs, + ARRAY_SIZE(exynos5800_clk_regs)); + if (!exynos5800_save) + goto err_soc; + } + register_syscore_ops(&exynos5420_clk_syscore_ops); + return; +err_soc: + kfree(exynos5x_save); + pr_warn("%s: failed to allocate sleep save data, no sleep support!\n", + __func__); + return; } #else static void exynos5420_clk_sleep_init(void) {} @@ -369,14 +418,43 @@ PNAME(mout_maudio0_p) = {"fin_pll", "maudio_clk", "mout_sclk_dpll", "mout_sclk_epll", "mout_sclk_rpll"}; PNAME(mout_mau_epll_clk_p) = {"mout_sclk_epll", "mout_sclk_dpll", "mout_sclk_mpll", "mout_sclk_spll"}; +/* List of parents specific to exynos5800 */ +PNAME(mout_epll2_5800_p) = { "mout_sclk_epll", "ff_dout_epll2" }; +PNAME(mout_group1_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll", + "mout_sclk_mpll", "ff_dout_spll2" }; +PNAME(mout_group2_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll", + "mout_sclk_mpll", "ff_dout_spll2", + "mout_epll2", "mout_sclk_ipll" }; +PNAME(mout_group3_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll", + "mout_sclk_mpll", "ff_dout_spll2", + "mout_epll2" }; +PNAME(mout_group5_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll" }; +PNAME(mout_group6_5800_p) = { "mout_sclk_ipll", "mout_sclk_dpll", + "mout_sclk_mpll", "ff_dout_spll2" }; +PNAME(mout_group7_5800_p) = { "mout_sclk_cpll", "mout_sclk_dpll", + "mout_sclk_mpll", "mout_sclk_spll", + "mout_epll2", "mout_sclk_ipll" }; +PNAME(mout_mau_epll_clk_5800_p) = { "mout_sclk_epll", "mout_sclk_dpll", + "mout_sclk_mpll", + "ff_dout_spll2" }; +PNAME(mout_group8_5800_p) = { "dout_aclk432_scaler", "dout_sclk_sw" }; +PNAME(mout_group9_5800_p) = { "dout_osc_div", "mout_sw_aclk432_scaler" }; +PNAME(mout_group10_5800_p) = { "dout_aclk432_cam", "dout_sclk_sw" }; +PNAME(mout_group11_5800_p) = { "dout_osc_div", "mout_sw_aclk432_cam" }; +PNAME(mout_group12_5800_p) = { "dout_aclkfl1_550_cam", "dout_sclk_sw" }; +PNAME(mout_group13_5800_p) = { "dout_osc_div", "mout_sw_aclkfl1_550_cam" }; +PNAME(mout_group14_5800_p) = { "dout_aclk550_cam", "dout_sclk_sw" }; +PNAME(mout_group15_5800_p) = { "dout_osc_div", "mout_sw_aclk550_cam" }; /* fixed rate clocks generated outside the soc */ -static struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = { +static struct samsung_fixed_rate_clock + exynos5x_fixed_rate_ext_clks[] __initdata = { FRATE(CLK_FIN_PLL, "fin_pll", NULL, CLK_IS_ROOT, 0), }; /* fixed rate clocks generated inside the soc */ -static struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = { +static struct samsung_fixed_rate_clock exynos5x_fixed_rate_clks[] __initdata = { FRATE(CLK_SCLK_HDMIPHY, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), FRATE(0, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000), FRATE(0, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000), @@ -384,52 +462,146 @@ static struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = FRATE(0, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000), }; -static struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = { +static struct samsung_fixed_factor_clock + exynos5x_fixed_factor_clks[] __initdata = { FFACTOR(0, "ff_hsic_12m", "fin_pll", 1, 2, 0), FFACTOR(0, "ff_sw_aclk66", "mout_sw_aclk66", 1, 2, 0), }; -static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { - MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p, - SRC_TOP7, 4, 1), - MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2), - MUX(0, "mout_mspll_cpu", mout_mspll_cpu_p, SRC_TOP7, 12, 2), - MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2), +static struct samsung_fixed_factor_clock + exynos5800_fixed_factor_clks[] __initdata = { + FFACTOR(0, "ff_dout_epll2", "mout_sclk_epll", 1, 2, 0), + FFACTOR(0, "ff_dout_spll2", "mout_sclk_spll", 1, 2, 0), +}; - MUX(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), - MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), - MUX(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1), - MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1), +struct samsung_mux_clock exynos5800_mux_clks[] __initdata = { + MUX(0, "mout_aclk400_isp", mout_group3_5800_p, SRC_TOP0, 0, 3), + MUX(0, "mout_aclk400_mscl", mout_group3_5800_p, SRC_TOP0, 4, 3), + MUX(0, "mout_aclk400_wcore", mout_group2_5800_p, SRC_TOP0, 16, 3), + MUX(0, "mout_aclk100_noc", mout_group1_5800_p, SRC_TOP0, 20, 2), + + MUX(0, "mout_aclk333_432_gscl", mout_group6_5800_p, SRC_TOP1, 0, 2), + MUX(0, "mout_aclk333_432_isp", mout_group6_5800_p, SRC_TOP1, 4, 2), + MUX(0, "mout_aclk333_432_isp0", mout_group6_5800_p, SRC_TOP1, 12, 2), + MUX(0, "mout_aclk266", mout_group5_5800_p, SRC_TOP1, 20, 2), + MUX(0, "mout_aclk333", mout_group1_5800_p, SRC_TOP1, 28, 2), + + MUX(0, "mout_aclk400_disp1", mout_group7_5800_p, SRC_TOP2, 4, 3), + MUX(0, "mout_aclk333_g2d", mout_group5_5800_p, SRC_TOP2, 8, 2), + MUX(0, "mout_aclk266_g2d", mout_group5_5800_p, SRC_TOP2, 12, 2), + MUX(0, "mout_aclk300_jpeg", mout_group5_5800_p, SRC_TOP2, 20, 2), + MUX(0, "mout_aclk300_disp1", mout_group5_5800_p, SRC_TOP2, 24, 2), + MUX(0, "mout_aclk300_gscl", mout_group5_5800_p, SRC_TOP2, 28, 2), + + MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_5800_p, SRC_TOP7, + 20, 2), + MUX(0, "sclk_bpll", mout_bpll_p, SRC_TOP7, 24, 1), + MUX(0, "mout_epll2", mout_epll2_5800_p, SRC_TOP7, 28, 1), + + MUX(0, "mout_aclk550_cam", mout_group3_5800_p, SRC_TOP8, 16, 3), + MUX(0, "mout_aclkfl1_550_cam", mout_group3_5800_p, SRC_TOP8, 20, 3), + MUX(0, "mout_aclk432_cam", mout_group6_5800_p, SRC_TOP8, 24, 2), + MUX(0, "mout_aclk432_scaler", mout_group6_5800_p, SRC_TOP8, 28, 2), + + MUX(0, "mout_user_aclk550_cam", mout_group15_5800_p, + SRC_TOP9, 16, 1), + MUX(0, "mout_user_aclkfl1_550_cam", mout_group13_5800_p, + SRC_TOP9, 20, 1), + MUX(0, "mout_user_aclk432_cam", mout_group11_5800_p, + SRC_TOP9, 24, 1), + MUX(0, "mout_user_aclk432_scaler", mout_group9_5800_p, + SRC_TOP9, 28, 1), + + MUX(0, "mout_sw_aclk550_cam", mout_group14_5800_p, SRC_TOP13, 16, 1), + MUX(0, "mout_sw_aclkfl1_550_cam", mout_group12_5800_p, + SRC_TOP13, 20, 1), + MUX(0, "mout_sw_aclk432_cam", mout_group10_5800_p, + SRC_TOP13, 24, 1), + MUX(0, "mout_sw_aclk432_scaler", mout_group8_5800_p, + SRC_TOP13, 28, 1), + + MUX(0, "mout_fimd1", mout_group2_p, SRC_DISP10, 4, 3), +}; +struct samsung_div_clock exynos5800_div_clks[] __initdata = { + DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore", DIV_TOP0, 16, 3), + + DIV(0, "dout_aclk550_cam", "mout_aclk550_cam", + DIV_TOP8, 16, 3), + DIV(0, "dout_aclkfl1_550_cam", "mout_aclkfl1_550_cam", + DIV_TOP8, 20, 3), + DIV(0, "dout_aclk432_cam", "mout_aclk432_cam", + DIV_TOP8, 24, 3), + DIV(0, "dout_aclk432_scaler", "mout_aclk432_scaler", + DIV_TOP8, 28, 3), + + DIV(0, "dout_osc_div", "fin_pll", DIV_TOP9, 20, 3), + DIV(0, "dout_sclk_sw", "sclk_spll", DIV_TOP9, 24, 6), +}; + +struct samsung_gate_clock exynos5800_gate_clks[] __initdata = { + GATE(CLK_ACLK550_CAM, "aclk550_cam", "mout_user_aclk550_cam", + GATE_BUS_TOP, 24, 0, 0), + GATE(CLK_ACLK432_SCALER, "aclk432_scaler", "mout_user_aclk432_scaler", + GATE_BUS_TOP, 27, 0, 0), +}; + +struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "sclk_bpll", mout_bpll_p, TOP_SPARE2, 0, 1), + MUX(0, "mout_aclk400_wcore_bpll", mout_aclk400_wcore_bpll_p, + TOP_SPARE2, 4, 1), MUX(0, "mout_aclk400_isp", mout_group1_p, SRC_TOP0, 0, 2), MUX_A(0, "mout_aclk400_mscl", mout_group1_p, - SRC_TOP0, 4, 2, "aclk400_mscl"), - MUX(0, "mout_aclk200", mout_group1_p, SRC_TOP0, 8, 2), - MUX(0, "mout_aclk200_fsys2", mout_group1_p, SRC_TOP0, 12, 2), + SRC_TOP0, 4, 2, "aclk400_mscl"), MUX(0, "mout_aclk400_wcore", mout_group1_p, SRC_TOP0, 16, 2), MUX(0, "mout_aclk100_noc", mout_group1_p, SRC_TOP0, 20, 2), - MUX(0, "mout_pclk200_fsys", mout_group1_p, SRC_TOP0, 24, 2), - MUX(0, "mout_aclk200_fsys", mout_group1_p, SRC_TOP0, 28, 2), MUX(0, "mout_aclk333_432_gscl", mout_group4_p, SRC_TOP1, 0, 2), MUX(0, "mout_aclk333_432_isp", mout_group4_p, - SRC_TOP1, 4, 2), - MUX(0, "mout_aclk66", mout_group1_p, SRC_TOP1, 8, 2), + SRC_TOP1, 4, 2), MUX(0, "mout_aclk333_432_isp0", mout_group4_p, SRC_TOP1, 12, 2), MUX(0, "mout_aclk266", mout_group1_p, SRC_TOP1, 20, 2), - MUX(0, "mout_aclk166", mout_group1_p, SRC_TOP1, 24, 2), MUX(0, "mout_aclk333", mout_group1_p, SRC_TOP1, 28, 2), MUX(0, "mout_aclk400_disp1", mout_group1_p, SRC_TOP2, 4, 2), MUX(0, "mout_aclk333_g2d", mout_group1_p, SRC_TOP2, 8, 2), MUX(0, "mout_aclk266_g2d", mout_group1_p, SRC_TOP2, 12, 2), - MUX(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1), MUX(0, "mout_aclk300_jpeg", mout_group1_p, SRC_TOP2, 20, 2), MUX(0, "mout_aclk300_disp1", mout_group1_p, SRC_TOP2, 24, 2), MUX(0, "mout_aclk300_gscl", mout_group1_p, SRC_TOP2, 28, 2), + MUX(0, "mout_mau_epll_clk", mout_mau_epll_clk_p, SRC_TOP7, 20, 2), + + MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1), +}; + +struct samsung_div_clock exynos5420_div_clks[] __initdata = { + DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll", + DIV_TOP0, 16, 3), +}; + +static struct samsung_mux_clock exynos5x_mux_clks[] __initdata = { + MUX(0, "mout_user_pclk66_gpio", mout_user_pclk66_gpio_p, + SRC_TOP7, 4, 1), + MUX(0, "mout_mspll_kfc", mout_mspll_cpu_p, SRC_TOP7, 8, 2), + MUX(0, "mout_mspll_cpu", mout_mspll_cpu_p, SRC_TOP7, 12, 2), + + MUX(0, "mout_apll", mout_apll_p, SRC_CPU, 0, 1), + MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), + MUX(0, "mout_kpll", mout_kpll_p, SRC_KFC, 0, 1), + MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1), + + MUX(0, "mout_aclk200", mout_group1_p, SRC_TOP0, 8, 2), + MUX(0, "mout_aclk200_fsys2", mout_group1_p, SRC_TOP0, 12, 2), + MUX(0, "mout_pclk200_fsys", mout_group1_p, SRC_TOP0, 24, 2), + MUX(0, "mout_aclk200_fsys", mout_group1_p, SRC_TOP0, 28, 2), + + MUX(0, "mout_aclk66", mout_group1_p, SRC_TOP1, 8, 2), + MUX(0, "mout_aclk166", mout_group1_p, SRC_TOP1, 24, 2), + + MUX(0, "mout_aclk_g3d", mout_group5_p, SRC_TOP2, 16, 1), + MUX(0, "mout_user_aclk400_isp", mout_user_aclk400_isp_p, SRC_TOP3, 0, 1), MUX(0, "mout_user_aclk400_mscl", mout_user_aclk400_mscl_p, @@ -529,15 +701,12 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { SRC_TOP12, 28, 1), /* DISP1 Block */ - MUX(0, "mout_fimd1", mout_group3_p, SRC_DISP10, 4, 1), MUX(0, "mout_mipi1", mout_group2_p, SRC_DISP10, 16, 3), MUX(0, "mout_dp1", mout_group2_p, SRC_DISP10, 20, 3), MUX(0, "mout_pixel", mout_group2_p, SRC_DISP10, 24, 3), MUX(CLK_MOUT_HDMI, "mout_hdmi", mout_hdmi_p, SRC_DISP10, 28, 1), MUX(0, "mout_fimd1_opt", mout_group2_p, SRC_DISP10, 8, 3), - MUX(0, "mout_aclk400_wcore_bpll", mout_aclk400_wcore_bpll_p, - TOP_SPARE2, 4, 1), MUX(0, "mout_fimd1_final", mout_fimd1_final_p, TOP_SPARE2, 8, 1), /* MAU Block */ @@ -574,7 +743,7 @@ static struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { MUX(0, "mout_isp_sensor", mout_group2_p, SRC_ISP, 28, 3), }; -static struct samsung_div_clock exynos5420_div_clks[] __initdata = { +static struct samsung_div_clock exynos5x_div_clks[] __initdata = { DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), DIV(0, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), DIV(0, "armclk2", "div_arm", DIV_CPU0, 28, 3), @@ -585,8 +754,6 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { DIV(0, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), DIV(0, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), DIV(0, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), - DIV(0, "dout_aclk400_wcore", "mout_aclk400_wcore_bpll", - DIV_TOP0, 16, 3), DIV(0, "dout_aclk100_noc", "mout_aclk100_noc", DIV_TOP0, 20, 3), DIV(0, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3), DIV(0, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3), @@ -692,7 +859,7 @@ static struct samsung_div_clock exynos5420_div_clks[] __initdata = { CLK_SET_RATE_PARENT, 0), }; -static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { +static struct samsung_gate_clock exynos5x_gate_clks[] __initdata = { /* G2D */ GATE(CLK_MDMA0, "mdma0", "aclk266_g2d", GATE_IP_G2D, 1, 0, 0), GATE(CLK_SSS, "sss", "aclk266_g2d", GATE_IP_G2D, 2, 0, 0), @@ -975,7 +1142,7 @@ static struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { GATE(CLK_G3D, "g3d", "mout_user_aclk_g3d", GATE_IP_G3D, 9, 0, 0), }; -static struct samsung_pll_clock exynos5420_plls[nr_plls] __initdata = { +static struct samsung_pll_clock exynos5x_plls[nr_plls] __initdata = { [apll] = PLL(pll_2550, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, APLL_CON0, NULL), [cpll] = PLL(pll_2550, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK, @@ -1006,7 +1173,8 @@ static struct of_device_id ext_clk_match[] __initdata = { }; /* register exynos5420 clocks */ -static void __init exynos5420_clk_init(struct device_node *np) +static void __init exynos5x_clk_init(struct device_node *np, + enum exynos5x_soc soc) { struct samsung_clk_provider *ctx; @@ -1018,27 +1186,56 @@ static void __init exynos5420_clk_init(struct device_node *np) panic("%s: unable to determine soc\n", __func__); } + exynos5x_soc = soc; + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); if (!ctx) panic("%s: unable to allocate context.\n", __func__); - samsung_clk_of_register_fixed_ext(ctx, exynos5420_fixed_rate_ext_clks, - ARRAY_SIZE(exynos5420_fixed_rate_ext_clks), + samsung_clk_of_register_fixed_ext(ctx, exynos5x_fixed_rate_ext_clks, + ARRAY_SIZE(exynos5x_fixed_rate_ext_clks), ext_clk_match); - samsung_clk_register_pll(ctx, exynos5420_plls, - ARRAY_SIZE(exynos5420_plls), - reg_base); - samsung_clk_register_fixed_rate(ctx, exynos5420_fixed_rate_clks, - ARRAY_SIZE(exynos5420_fixed_rate_clks)); - samsung_clk_register_fixed_factor(ctx, exynos5420_fixed_factor_clks, - ARRAY_SIZE(exynos5420_fixed_factor_clks)); - samsung_clk_register_mux(ctx, exynos5420_mux_clks, - ARRAY_SIZE(exynos5420_mux_clks)); - samsung_clk_register_div(ctx, exynos5420_div_clks, - ARRAY_SIZE(exynos5420_div_clks)); - samsung_clk_register_gate(ctx, exynos5420_gate_clks, - ARRAY_SIZE(exynos5420_gate_clks)); + samsung_clk_register_pll(ctx, exynos5x_plls, ARRAY_SIZE(exynos5x_plls), + reg_base); + samsung_clk_register_fixed_rate(ctx, exynos5x_fixed_rate_clks, + ARRAY_SIZE(exynos5x_fixed_rate_clks)); + samsung_clk_register_fixed_factor(ctx, exynos5x_fixed_factor_clks, + ARRAY_SIZE(exynos5x_fixed_factor_clks)); + samsung_clk_register_mux(ctx, exynos5x_mux_clks, + ARRAY_SIZE(exynos5x_mux_clks)); + samsung_clk_register_div(ctx, exynos5x_div_clks, + ARRAY_SIZE(exynos5x_div_clks)); + samsung_clk_register_gate(ctx, exynos5x_gate_clks, + ARRAY_SIZE(exynos5x_gate_clks)); + + if (soc == EXYNOS5420) { + samsung_clk_register_mux(ctx, exynos5420_mux_clks, + ARRAY_SIZE(exynos5420_mux_clks)); + samsung_clk_register_div(ctx, exynos5420_div_clks, + ARRAY_SIZE(exynos5420_div_clks)); + } else { + samsung_clk_register_fixed_factor( + ctx, exynos5800_fixed_factor_clks, + ARRAY_SIZE(exynos5800_fixed_factor_clks)); + samsung_clk_register_mux(ctx, exynos5800_mux_clks, + ARRAY_SIZE(exynos5800_mux_clks)); + samsung_clk_register_div(ctx, exynos5800_div_clks, + ARRAY_SIZE(exynos5800_div_clks)); + samsung_clk_register_gate(ctx, exynos5800_gate_clks, + ARRAY_SIZE(exynos5800_gate_clks)); + } exynos5420_clk_sleep_init(); } + +static void __init exynos5420_clk_init(struct device_node *np) +{ + exynos5x_clk_init(np, EXYNOS5420); +} CLK_OF_DECLARE(exynos5420_clk, "samsung,exynos5420-clock", exynos5420_clk_init); + +static void __init exynos5800_clk_init(struct device_node *np) +{ + exynos5x_clk_init(np, EXYNOS5800); +} +CLK_OF_DECLARE(exynos5800_clk, "samsung,exynos5800-clock", exynos5800_clk_init); -- cgit v1.2.2 From 87ab4361beed9960687eb60f0da79f85293d1ade Mon Sep 17 00:00:00 2001 From: Michal Simek Date: Fri, 11 Apr 2014 15:39:29 +0200 Subject: clocksource: cadence_ttc: Use readl/writel_relaxed instead of __raw For supporting ARM big-endian is necessary to use proper IO endianess accessors. Based on Ben Dooks BE guide. Similar conversion is done here: "mv_xor: use {readl, writel}_relaxed instead of __raw_{readl, writel}" (sha1: 5733c38ae3473115ac7df3fe19bd2502149d8c51) Signed-off-by: Michal Simek --- drivers/clocksource/cadence_ttc_timer.c | 54 ++++++++++++++++----------------- 1 file changed, 27 insertions(+), 27 deletions(-) (limited to 'drivers') diff --git a/drivers/clocksource/cadence_ttc_timer.c b/drivers/clocksource/cadence_ttc_timer.c index 49fbe2847c84..7a08811df9aa 100644 --- a/drivers/clocksource/cadence_ttc_timer.c +++ b/drivers/clocksource/cadence_ttc_timer.c @@ -118,11 +118,11 @@ static void ttc_set_interval(struct ttc_timer *timer, u32 ctrl_reg; /* Disable the counter, set the counter value and re-enable counter */ - ctrl_reg = __raw_readl(timer->base_addr + TTC_CNT_CNTRL_OFFSET); + ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; - __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); + writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); - __raw_writel(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET); + writel_relaxed(cycles, timer->base_addr + TTC_INTR_VAL_OFFSET); /* * Reset the counter (0x10) so that it starts from 0, one-shot @@ -130,7 +130,7 @@ static void ttc_set_interval(struct ttc_timer *timer, */ ctrl_reg |= CNT_CNTRL_RESET; ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; - __raw_writel(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); + writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); } /** @@ -147,7 +147,7 @@ static irqreturn_t ttc_clock_event_interrupt(int irq, void *dev_id) struct ttc_timer *timer = &ttce->ttc; /* Acknowledge the interrupt and call event handler */ - __raw_readl(timer->base_addr + TTC_ISR_OFFSET); + readl_relaxed(timer->base_addr + TTC_ISR_OFFSET); ttce->ce.event_handler(&ttce->ce); @@ -163,13 +163,13 @@ static cycle_t __ttc_clocksource_read(struct clocksource *cs) { struct ttc_timer *timer = &to_ttc_timer_clksrc(cs)->ttc; - return (cycle_t)__raw_readl(timer->base_addr + + return (cycle_t)readl_relaxed(timer->base_addr + TTC_COUNT_VAL_OFFSET); } static u64 notrace ttc_sched_clock_read(void) { - return __raw_readl(ttc_sched_clock_val_reg); + return readl_relaxed(ttc_sched_clock_val_reg); } /** @@ -211,17 +211,17 @@ static void ttc_set_mode(enum clock_event_mode mode, case CLOCK_EVT_MODE_ONESHOT: case CLOCK_EVT_MODE_UNUSED: case CLOCK_EVT_MODE_SHUTDOWN: - ctrl_reg = __raw_readl(timer->base_addr + + ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); ctrl_reg |= TTC_CNT_CNTRL_DISABLE_MASK; - __raw_writel(ctrl_reg, + writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); break; case CLOCK_EVT_MODE_RESUME: - ctrl_reg = __raw_readl(timer->base_addr + + ctrl_reg = readl_relaxed(timer->base_addr + TTC_CNT_CNTRL_OFFSET); ctrl_reg &= ~TTC_CNT_CNTRL_DISABLE_MASK; - __raw_writel(ctrl_reg, + writel_relaxed(ctrl_reg, timer->base_addr + TTC_CNT_CNTRL_OFFSET); break; } @@ -266,8 +266,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, * of an abort. */ ttccs->scale_clk_ctrl_reg_old = - __raw_readl(ttccs->ttc.base_addr + - TTC_CLK_CNTRL_OFFSET); + readl_relaxed(ttccs->ttc.base_addr + + TTC_CLK_CNTRL_OFFSET); psv = (ttccs->scale_clk_ctrl_reg_old & TTC_CLK_CNTRL_PSV_MASK) >> @@ -291,8 +291,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, return NOTIFY_DONE; /* scale up: adjust divider now - before frequency change */ - __raw_writel(ttccs->scale_clk_ctrl_reg_new, - ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); + writel_relaxed(ttccs->scale_clk_ctrl_reg_new, + ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); break; } case POST_RATE_CHANGE: @@ -301,8 +301,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, return NOTIFY_OK; /* scale down: adjust divider now - after frequency change */ - __raw_writel(ttccs->scale_clk_ctrl_reg_new, - ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); + writel_relaxed(ttccs->scale_clk_ctrl_reg_new, + ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); break; case ABORT_RATE_CHANGE: @@ -311,8 +311,8 @@ static int ttc_rate_change_clocksource_cb(struct notifier_block *nb, return NOTIFY_OK; /* restore original register value */ - __raw_writel(ttccs->scale_clk_ctrl_reg_old, - ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); + writel_relaxed(ttccs->scale_clk_ctrl_reg_old, + ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); /* fall through */ default: return NOTIFY_DONE; @@ -359,10 +359,10 @@ static void __init ttc_setup_clocksource(struct clk *clk, void __iomem *base) * with no interrupt and it rolls over at 0xFFFF. Pre-scale * it by 32 also. Let it start running now. */ - __raw_writel(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET); - __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, + writel_relaxed(0x0, ttccs->ttc.base_addr + TTC_IER_OFFSET); + writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, ttccs->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); - __raw_writel(CNT_CNTRL_RESET, + writel_relaxed(CNT_CNTRL_RESET, ttccs->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); err = clocksource_register_hz(&ttccs->cs, ttccs->ttc.freq / PRESCALE); @@ -438,10 +438,10 @@ static void __init ttc_setup_clockevent(struct clk *clk, * is prescaled by 32 using the interval interrupt. Leave it * disabled for now. */ - __raw_writel(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); - __raw_writel(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, + writel_relaxed(0x23, ttcce->ttc.base_addr + TTC_CNT_CNTRL_OFFSET); + writel_relaxed(CLK_CNTRL_PRESCALE | CLK_CNTRL_PRESCALE_EN, ttcce->ttc.base_addr + TTC_CLK_CNTRL_OFFSET); - __raw_writel(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); + writel_relaxed(0x1, ttcce->ttc.base_addr + TTC_IER_OFFSET); err = request_irq(irq, ttc_clock_event_interrupt, IRQF_TIMER, ttcce->ce.name, ttcce); @@ -490,7 +490,7 @@ static void __init ttc_timer_init(struct device_node *timer) BUG(); } - clksel = __raw_readl(timer_baseaddr + TTC_CLK_CNTRL_OFFSET); + clksel = readl_relaxed(timer_baseaddr + TTC_CLK_CNTRL_OFFSET); clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); clk_cs = of_clk_get(timer, clksel); if (IS_ERR(clk_cs)) { @@ -498,7 +498,7 @@ static void __init ttc_timer_init(struct device_node *timer) BUG(); } - clksel = __raw_readl(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); + clksel = readl_relaxed(timer_baseaddr + 4 + TTC_CLK_CNTRL_OFFSET); clksel = !!(clksel & TTC_CLK_CNTRL_CSRC_MASK); clk_ce = of_clk_get(timer, clksel); if (IS_ERR(clk_ce)) { -- cgit v1.2.2 From 4a315e3457e008e0570c392822ae98cdf7761227 Mon Sep 17 00:00:00 2001 From: Anders Berg Date: Fri, 23 May 2014 11:08:38 +0200 Subject: power: reset: Add Axxia system reset driver Add Axxia (AXM55xx) SoC system reset driver. This driver handles only system reboot (and not power-off). Signed-off-by: Anders Berg Cc: Dmitry Eremin-Solenikov Cc: David Woodhouse Acked-by: Linus Walleij Signed-off-by: Arnd Bergmann --- drivers/power/reset/Kconfig | 8 ++++ drivers/power/reset/Makefile | 1 + drivers/power/reset/axxia-reset.c | 88 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 drivers/power/reset/axxia-reset.c (limited to 'drivers') diff --git a/drivers/power/reset/Kconfig b/drivers/power/reset/Kconfig index fa0e4e057b99..49b46e6ca959 100644 --- a/drivers/power/reset/Kconfig +++ b/drivers/power/reset/Kconfig @@ -12,6 +12,14 @@ config POWER_RESET_AS3722 help This driver supports turning off board via a ams AS3722 power-off. +config POWER_RESET_AXXIA + bool "LSI Axxia reset driver" + depends on POWER_RESET && ARCH_AXXIA + help + This driver supports restart for Axxia SoC. + + Say Y if you have an Axxia family SoC. + config POWER_RESET_GPIO bool "GPIO power-off driver" depends on OF_GPIO && POWER_RESET diff --git a/drivers/power/reset/Makefile b/drivers/power/reset/Makefile index a5b4a77d1a41..16c0516e5a19 100644 --- a/drivers/power/reset/Makefile +++ b/drivers/power/reset/Makefile @@ -1,4 +1,5 @@ obj-$(CONFIG_POWER_RESET_AS3722) += as3722-poweroff.o +obj-$(CONFIG_POWER_RESET_AXXIA) += axxia-reset.o obj-$(CONFIG_POWER_RESET_GPIO) += gpio-poweroff.o obj-$(CONFIG_POWER_RESET_MSM) += msm-poweroff.o obj-$(CONFIG_POWER_RESET_QNAP) += qnap-poweroff.o diff --git a/drivers/power/reset/axxia-reset.c b/drivers/power/reset/axxia-reset.c new file mode 100644 index 000000000000..3b1f8d601784 --- /dev/null +++ b/drivers/power/reset/axxia-reset.c @@ -0,0 +1,88 @@ +/* + * Reset driver for Axxia devices + * + * Copyright (C) 2014 LSI + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 and + * only version 2 as published by the Free Software Foundation. + * + * This program is distributed in the hope that 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + + +#define SC_CRIT_WRITE_KEY 0x1000 +#define SC_LATCH_ON_RESET 0x1004 +#define SC_RESET_CONTROL 0x1008 +#define RSTCTL_RST_ZERO (1<<3) +#define RSTCTL_RST_FAB (1<<2) +#define RSTCTL_RST_CHIP (1<<1) +#define RSTCTL_RST_SYS (1<<0) +#define SC_EFUSE_INT_STATUS 0x180c +#define EFUSE_READ_DONE (1<<31) + +static struct regmap *syscon; + +static void do_axxia_restart(enum reboot_mode reboot_mode, const char *cmd) +{ + /* Access Key (0xab) */ + regmap_write(syscon, SC_CRIT_WRITE_KEY, 0xab); + /* Select internal boot from 0xffff0000 */ + regmap_write(syscon, SC_LATCH_ON_RESET, 0x00000040); + /* Assert ResetReadDone (to avoid hanging in boot ROM) */ + regmap_write(syscon, SC_EFUSE_INT_STATUS, EFUSE_READ_DONE); + /* Assert chip reset */ + regmap_update_bits(syscon, SC_RESET_CONTROL, + RSTCTL_RST_CHIP, RSTCTL_RST_CHIP); +} + +static int axxia_reset_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + syscon = syscon_regmap_lookup_by_phandle(dev->of_node, "syscon"); + if (IS_ERR(syscon)) { + pr_err("%s: syscon lookup failed\n", dev->of_node->name); + return PTR_ERR(syscon); + } + + arm_pm_restart = do_axxia_restart; + + return 0; +} + +static const struct of_device_id of_axxia_reset_match[] = { + { .compatible = "lsi,axm55xx-reset", }, + {}, +}; +MODULE_DEVICE_TABLE(of, of_axxia_reset_match); + +static struct platform_driver axxia_reset_driver = { + .probe = axxia_reset_probe, + .driver = { + .name = "axxia-reset", + .of_match_table = of_match_ptr(of_axxia_reset_match), + }, +}; + +static int __init axxia_reset_init(void) +{ + return platform_driver_register(&axxia_reset_driver); +} +device_initcall(axxia_reset_init); -- cgit v1.2.2 From bfed1074f213051e94648bfad0d0611a16d81366 Mon Sep 17 00:00:00 2001 From: Cho KyongHo Date: Thu, 22 May 2014 07:23:19 +0900 Subject: clk: exynos5250: Add missing sysmmu clocks for DISP and ISP blocks This patch adds the missing sysmmu clocks for Display and ISP blocks. Signed-off-by: Cho KyongHo Signed-off-by: Shaik Ameer Basha Acked-by: Tomasz Figa Signed-off-by: Kukjin Kim --- drivers/clk/samsung/clk-exynos5250.c | 35 +++++++++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) (limited to 'drivers') diff --git a/drivers/clk/samsung/clk-exynos5250.c b/drivers/clk/samsung/clk-exynos5250.c index 88488596c00b..870e18b9a687 100644 --- a/drivers/clk/samsung/clk-exynos5250.c +++ b/drivers/clk/samsung/clk-exynos5250.c @@ -28,6 +28,8 @@ #define MPLL_CON0 0x4100 #define SRC_CORE1 0x4204 #define GATE_IP_ACP 0x8800 +#define GATE_IP_ISP0 0xc800 +#define GATE_IP_ISP1 0xc804 #define CPLL_LOCK 0x10020 #define EPLL_LOCK 0x10030 #define VPLL_LOCK 0x10040 @@ -145,6 +147,8 @@ static unsigned long exynos5250_clk_regs[] __initdata = { PLL_DIV2_SEL, GATE_IP_DISP1, GATE_IP_ACP, + GATE_IP_ISP0, + GATE_IP_ISP1, }; static int exynos5250_clk_suspend(void) @@ -202,6 +206,7 @@ PNAME(mout_aclk400_p) = { "mout_aclk400_g3d_mid", "mout_gpll" }; PNAME(mout_aclk200_sub_p) = { "fin_pll", "div_aclk200" }; PNAME(mout_aclk266_sub_p) = { "fin_pll", "div_aclk266" }; PNAME(mout_aclk333_sub_p) = { "fin_pll", "div_aclk333" }; +PNAME(mout_aclk400_isp_sub_p) = { "fin_pll", "div_aclk400_isp" }; PNAME(mout_hdmi_p) = { "div_hdmi_pixel", "sclk_hdmiphy" }; PNAME(mout_usb3_p) = { "mout_mpll_user", "mout_cpll" }; PNAME(mout_group1_p) = { "fin_pll", "fin_pll", "sclk_hdmi27m", @@ -281,6 +286,7 @@ static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { MUX(0, "mout_aclk333", mout_aclk166_p, SRC_TOP0, 16, 1), MUX(0, "mout_aclk400_g3d_mid", mout_aclk200_p, SRC_TOP0, 20, 1), + MUX(0, "mout_aclk400_isp", mout_aclk200_p, SRC_TOP1, 24, 1), MUX(0, "mout_aclk400_g3d", mout_aclk400_p, SRC_TOP1, 28, 1), MUX(0, "mout_cpll", mout_cpll_p, SRC_TOP2, 8, 1), @@ -292,6 +298,9 @@ static struct samsung_mux_clock exynos5250_mux_clks[] __initdata = { MUX(0, "mout_aclk200_disp1_sub", mout_aclk200_sub_p, SRC_TOP3, 4, 1), MUX(0, "mout_aclk266_gscl_sub", mout_aclk266_sub_p, SRC_TOP3, 8, 1), + MUX(0, "mout_aclk_266_isp_sub", mout_aclk266_sub_p, SRC_TOP3, 16, 1), + MUX(0, "mout_aclk_400_isp_sub", mout_aclk400_isp_sub_p, + SRC_TOP3, 20, 1), MUX(0, "mout_aclk333_sub", mout_aclk333_sub_p, SRC_TOP3, 24, 1), MUX(0, "mout_cam_bayer", mout_group1_p, SRC_GSCL, 12, 4), @@ -364,6 +373,7 @@ static struct samsung_div_clock exynos5250_div_clks[] __initdata = { DIV(0, "div_aclk400_g3d", "mout_aclk400_g3d", DIV_TOP0, 24, 3), + DIV(0, "div_aclk400_isp", "mout_aclk400_isp", DIV_TOP1, 20, 3), DIV(0, "div_aclk66_pre", "mout_mpll_user", DIV_TOP1, 24, 3), DIV(0, "div_cam_bayer", "mout_cam_bayer", DIV_GSCL, 12, 4), @@ -629,6 +639,31 @@ static struct samsung_gate_clock exynos5250_gate_clks[] __initdata = { GATE(CLK_WDT, "wdt", "div_aclk66", GATE_IP_PERIS, 19, 0, 0), GATE(CLK_RTC, "rtc", "div_aclk66", GATE_IP_PERIS, 20, 0, 0), GATE(CLK_TMU, "tmu", "div_aclk66", GATE_IP_PERIS, 21, 0, 0), + GATE(CLK_SMMU_TV, "smmu_tv", "mout_aclk200_disp1_sub", + GATE_IP_DISP1, 2, 0, 0), + GATE(CLK_SMMU_FIMD1, "smmu_fimd1", "mout_aclk200_disp1_sub", + GATE_IP_DISP1, 8, 0, 0), + GATE(CLK_SMMU_2D, "smmu_2d", "div_aclk200", GATE_IP_ACP, 7, 0, 0), + GATE(CLK_SMMU_FIMC_ISP, "smmu_fimc_isp", "mout_aclk_266_isp_sub", + GATE_IP_ISP0, 8, 0, 0), + GATE(CLK_SMMU_FIMC_DRC, "smmu_fimc_drc", "mout_aclk_266_isp_sub", + GATE_IP_ISP0, 9, 0, 0), + GATE(CLK_SMMU_FIMC_FD, "smmu_fimc_fd", "mout_aclk_266_isp_sub", + GATE_IP_ISP0, 10, 0, 0), + GATE(CLK_SMMU_FIMC_SCC, "smmu_fimc_scc", "mout_aclk_266_isp_sub", + GATE_IP_ISP0, 11, 0, 0), + GATE(CLK_SMMU_FIMC_SCP, "smmu_fimc_scp", "mout_aclk_266_isp_sub", + GATE_IP_ISP0, 12, 0, 0), + GATE(CLK_SMMU_FIMC_MCU, "smmu_fimc_mcu", "mout_aclk_400_isp_sub", + GATE_IP_ISP0, 13, 0, 0), + GATE(CLK_SMMU_FIMC_ODC, "smmu_fimc_odc", "mout_aclk_266_isp_sub", + GATE_IP_ISP1, 4, 0, 0), + GATE(CLK_SMMU_FIMC_DIS0, "smmu_fimc_dis0", "mout_aclk_266_isp_sub", + GATE_IP_ISP1, 5, 0, 0), + GATE(CLK_SMMU_FIMC_DIS1, "smmu_fimc_dis1", "mout_aclk_266_isp_sub", + GATE_IP_ISP1, 6, 0, 0), + GATE(CLK_SMMU_FIMC_3DNR, "smmu_fimc_3dnr", "mout_aclk_266_isp_sub", + GATE_IP_ISP1, 7, 0, 0), }; static struct samsung_pll_rate_table vpll_24mhz_tbl[] __initdata = { -- cgit v1.2.2 From e7ef0b632eb45b0c725629da3561ecde8935a398 Mon Sep 17 00:00:00 2001 From: Tarek Dakhran Date: Tue, 27 May 2014 06:54:12 +0900 Subject: clk: exynos5410: register clocks using common clock framework The EXYNOS5410 clocks are statically listed and registered using the Samsung specific common clock helper functions. Signed-off-by: Tarek Dakhran Signed-off-by: Vyacheslav Tyrtov Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos5410.c | 209 +++++++++++++++++++++++++++++++++++ 2 files changed, 210 insertions(+) create mode 100644 drivers/clk/samsung/clk-exynos5410.c (limited to 'drivers') diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 25646c61a02b..69e81773164e 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -7,6 +7,7 @@ obj-$(CONFIG_SOC_EXYNOS3250) += clk-exynos3250.o obj-$(CONFIG_ARCH_EXYNOS4) += clk-exynos4.o obj-$(CONFIG_SOC_EXYNOS5250) += clk-exynos5250.o obj-$(CONFIG_SOC_EXYNOS5260) += clk-exynos5260.o +obj-$(CONFIG_SOC_EXYNOS5410) += clk-exynos5410.o obj-$(CONFIG_SOC_EXYNOS5420) += clk-exynos5420.o obj-$(CONFIG_SOC_EXYNOS5440) += clk-exynos5440.o obj-$(CONFIG_ARCH_EXYNOS) += clk-exynos-audss.o diff --git a/drivers/clk/samsung/clk-exynos5410.c b/drivers/clk/samsung/clk-exynos5410.c new file mode 100644 index 000000000000..c9505ab9ee70 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5410.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Author: Tarek Dakhran + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * Common Clock Framework support for Exynos5410 SoC. +*/ + +#include + +#include +#include +#include +#include +#include + +#include "clk.h" + +#define APLL_LOCK 0x0 +#define APLL_CON0 0x100 +#define CPLL_LOCK 0x10020 +#define CPLL_CON0 0x10120 +#define MPLL_LOCK 0x4000 +#define MPLL_CON0 0x4100 +#define BPLL_LOCK 0x20010 +#define BPLL_CON0 0x20110 +#define KPLL_LOCK 0x28000 +#define KPLL_CON0 0x28100 + +#define SRC_CPU 0x200 +#define DIV_CPU0 0x500 +#define SRC_CPERI1 0x4204 +#define DIV_TOP0 0x10510 +#define DIV_TOP1 0x10514 +#define DIV_FSYS1 0x1054c +#define DIV_FSYS2 0x10550 +#define DIV_PERIC0 0x10558 +#define SRC_TOP0 0x10210 +#define SRC_TOP1 0x10214 +#define SRC_TOP2 0x10218 +#define SRC_FSYS 0x10244 +#define SRC_PERIC0 0x10250 +#define SRC_MASK_FSYS 0x10340 +#define SRC_MASK_PERIC0 0x10350 +#define GATE_BUS_FSYS0 0x10740 +#define GATE_IP_FSYS 0x10944 +#define GATE_IP_PERIC 0x10950 +#define GATE_IP_PERIS 0x10960 +#define SRC_CDREX 0x20200 +#define SRC_KFC 0x28200 +#define DIV_KFC0 0x28500 + +/* list of PLLs */ +enum exynos5410_plls { + apll, cpll, mpll, + bpll, kpll, + nr_plls /* number of PLLs */ +}; + +/* list of all parent clocks */ +PNAME(apll_p) = { "fin_pll", "fout_apll", }; +PNAME(bpll_p) = { "fin_pll", "fout_bpll", }; +PNAME(cpll_p) = { "fin_pll", "fout_cpll" }; +PNAME(mpll_p) = { "fin_pll", "fout_mpll", }; +PNAME(kpll_p) = { "fin_pll", "fout_kpll", }; + +PNAME(mout_cpu_p) = { "mout_apll", "sclk_mpll", }; +PNAME(mout_kfc_p) = { "mout_kpll", "sclk_mpll", }; + +PNAME(mpll_user_p) = { "fin_pll", "sclk_mpll", }; +PNAME(bpll_user_p) = { "fin_pll", "sclk_bpll", }; +PNAME(mpll_bpll_p) = { "sclk_mpll_muxed", "sclk_bpll_muxed", }; + +PNAME(group2_p) = { "fin_pll", "fin_pll", "none", "none", + "none", "none", "sclk_mpll_bpll", + "none", "none", "sclk_cpll" }; + +static struct samsung_mux_clock exynos5410_mux_clks[] __initdata = { + MUX(0, "mout_apll", apll_p, SRC_CPU, 0, 1), + MUX(0, "mout_cpu", mout_cpu_p, SRC_CPU, 16, 1), + + MUX(0, "mout_kpll", kpll_p, SRC_KFC, 0, 1), + MUX(0, "mout_kfc", mout_kfc_p, SRC_KFC, 16, 1), + + MUX(0, "sclk_mpll", mpll_p, SRC_CPERI1, 8, 1), + MUX(0, "sclk_mpll_muxed", mpll_user_p, SRC_TOP2, 20, 1), + + MUX(0, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1), + MUX(0, "sclk_bpll_muxed", bpll_user_p, SRC_TOP2, 24, 1), + + MUX(0, "sclk_cpll", cpll_p, SRC_TOP2, 8, 1), + + MUX(0, "sclk_mpll_bpll", mpll_bpll_p, SRC_TOP1, 20, 1), + + MUX(0, "mout_mmc0", group2_p, SRC_FSYS, 0, 4), + MUX(0, "mout_mmc1", group2_p, SRC_FSYS, 4, 4), + MUX(0, "mout_mmc2", group2_p, SRC_FSYS, 8, 4), + + MUX(0, "mout_uart0", group2_p, SRC_PERIC0, 0, 4), + MUX(0, "mout_uart1", group2_p, SRC_PERIC0, 4, 4), + MUX(0, "mout_uart2", group2_p, SRC_PERIC0, 8, 4), + + MUX(0, "mout_aclk200", mpll_bpll_p, SRC_TOP0, 12, 1), + MUX(0, "mout_aclk400", mpll_bpll_p, SRC_TOP0, 20, 1), +}; + +static struct samsung_div_clock exynos5410_div_clks[] __initdata = { + DIV(0, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), + DIV(0, "div_arm2", "div_arm", DIV_CPU0, 28, 3), + + DIV(0, "div_acp", "div_arm2", DIV_CPU0, 8, 3), + DIV(0, "div_cpud", "div_arm2", DIV_CPU0, 4, 3), + DIV(0, "div_atb", "div_arm2", DIV_CPU0, 16, 3), + DIV(0, "pclk_dbg", "div_arm2", DIV_CPU0, 20, 3), + + DIV(0, "div_kfc", "mout_kfc", DIV_KFC0, 0, 3), + DIV(0, "div_aclk", "div_kfc", DIV_KFC0, 4, 3), + DIV(0, "div_pclk", "div_kfc", DIV_KFC0, 20, 3), + + DIV(0, "aclk66_pre", "sclk_mpll_muxed", DIV_TOP1, 24, 3), + DIV(0, "aclk66", "aclk66_pre", DIV_TOP0, 0, 3), + + DIV(0, "div_mmc0", "mout_mmc0", DIV_FSYS1, 0, 4), + DIV(0, "div_mmc1", "mout_mmc1", DIV_FSYS1, 16, 4), + DIV(0, "div_mmc2", "mout_mmc2", DIV_FSYS2, 0, 4), + + DIV_F(0, "div_mmc_pre0", "div_mmc0", + DIV_FSYS1, 8, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(0, "div_mmc_pre1", "div_mmc1", + DIV_FSYS1, 24, 8, CLK_SET_RATE_PARENT, 0), + DIV_F(0, "div_mmc_pre2", "div_mmc2", + DIV_FSYS2, 8, 8, CLK_SET_RATE_PARENT, 0), + + DIV(0, "div_uart0", "mout_uart0", DIV_PERIC0, 0, 4), + DIV(0, "div_uart1", "mout_uart1", DIV_PERIC0, 4, 4), + DIV(0, "div_uart2", "mout_uart2", DIV_PERIC0, 8, 4), + DIV(0, "div_uart3", "mout_uart3", DIV_PERIC0, 12, 4), + + DIV(0, "aclk200", "mout_aclk200", DIV_TOP0, 12, 3), + DIV(0, "aclk400", "mout_aclk400", DIV_TOP0, 24, 3), +}; + +static struct samsung_gate_clock exynos5410_gate_clks[] __initdata = { + GATE(CLK_MCT, "mct", "aclk66", GATE_IP_PERIS, 18, 0, 0), + + GATE(CLK_SCLK_MMC0, "sclk_mmc0", "div_mmc_pre0", + SRC_MASK_FSYS, 0, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC1, "sclk_mmc1", "div_mmc_pre1", + SRC_MASK_FSYS, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_MMC2, "sclk_mmc2", "div_mmc_pre2", + SRC_MASK_FSYS, 8, CLK_SET_RATE_PARENT, 0), + + GATE(CLK_MMC0, "sdmmc0", "aclk200", GATE_BUS_FSYS0, 12, 0, 0), + GATE(CLK_MMC1, "sdmmc1", "aclk200", GATE_BUS_FSYS0, 13, 0, 0), + GATE(CLK_MMC2, "sdmmc2", "aclk200", GATE_BUS_FSYS0, 14, 0, 0), + + GATE(CLK_UART0, "uart0", "aclk66", GATE_IP_PERIC, 0, 0, 0), + GATE(CLK_UART1, "uart1", "aclk66", GATE_IP_PERIC, 1, 0, 0), + GATE(CLK_UART2, "uart2", "aclk66", GATE_IP_PERIC, 2, 0, 0), + + GATE(CLK_SCLK_UART0, "sclk_uart0", "div_uart0", + SRC_MASK_PERIC0, 0, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART1, "sclk_uart1", "div_uart1", + SRC_MASK_PERIC0, 4, CLK_SET_RATE_PARENT, 0), + GATE(CLK_SCLK_UART2, "sclk_uart2", "div_uart2", + SRC_MASK_PERIC0, 8, CLK_SET_RATE_PARENT, 0), +}; + +static struct samsung_pll_clock exynos5410_plls[nr_plls] __initdata = { + [apll] = PLL(pll_35xx, CLK_FOUT_APLL, "fout_apll", "fin_pll", APLL_LOCK, + APLL_CON0, NULL), + [cpll] = PLL(pll_35xx, CLK_FOUT_CPLL, "fout_cpll", "fin_pll", CPLL_LOCK, + CPLL_CON0, NULL), + [mpll] = PLL(pll_35xx, CLK_FOUT_MPLL, "fout_mpll", "fin_pll", MPLL_LOCK, + MPLL_CON0, NULL), + [bpll] = PLL(pll_35xx, CLK_FOUT_BPLL, "fout_bpll", "fin_pll", BPLL_LOCK, + BPLL_CON0, NULL), + [kpll] = PLL(pll_35xx, CLK_FOUT_KPLL, "fout_kpll", "fin_pll", KPLL_LOCK, + KPLL_CON0, NULL), +}; + +/* register exynos5410 clocks */ +static void __init exynos5410_clk_init(struct device_node *np) +{ + struct samsung_clk_provider *ctx; + void __iomem *reg_base; + + reg_base = of_iomap(np, 0); + if (!reg_base) + panic("%s: failed to map registers\n", __func__); + + ctx = samsung_clk_init(np, reg_base, CLK_NR_CLKS); + + samsung_clk_register_pll(ctx, exynos5410_plls, + ARRAY_SIZE(exynos5410_plls), reg_base); + + samsung_clk_register_mux(ctx, exynos5410_mux_clks, + ARRAY_SIZE(exynos5410_mux_clks)); + samsung_clk_register_div(ctx, exynos5410_div_clks, + ARRAY_SIZE(exynos5410_div_clks)); + samsung_clk_register_gate(ctx, exynos5410_gate_clks, + ARRAY_SIZE(exynos5410_gate_clks)); + + pr_debug("Exynos5410: clock setup completed.\n"); +} +CLK_OF_DECLARE(exynos5410_clk, "samsung,exynos5410-clock", exynos5410_clk_init); -- cgit v1.2.2