From f9094c526bca3cc50ef7d409c22976fa0f47bbba Mon Sep 17 00:00:00 2001 From: Kuninori Morimoto Date: Wed, 12 Jun 2013 02:03:59 +0000 Subject: ARM: shmobile: r8a7790: add __initdata on resource and device data These data will be kmemdup()'ed on platform_device_add_resources() and platform_device_add_data() This patch removed "const" to avoid section type conflict with r8a7790_boards_compat_dt Signed-off-by: Kuninori Morimoto Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7790.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index b461d93431ed..196bd7325df0 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -30,17 +30,17 @@ #include #include -static const struct resource pfc_resources[] = { +static struct resource pfc_resources[] __initdata = { DEFINE_RES_MEM(0xe6060000, 0x250), }; #define R8A7790_GPIO(idx) \ -static struct resource r8a7790_gpio##idx##_resources[] = { \ +static struct resource r8a7790_gpio##idx##_resources[] __initdata = { \ DEFINE_RES_MEM(0xe6050000 + 0x1000 * (idx), 0x50), \ DEFINE_RES_IRQ(gic_spi(4 + (idx))), \ }; \ \ -static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data = { \ +static struct gpio_rcar_config r8a7790_gpio##idx##_platform_data __initdata = { \ .gpio_base = 32 * (idx), \ .irq_base = 0, \ .number_of_pins = 32, \ @@ -103,7 +103,7 @@ void __init r8a7790_pinmux_init(void) enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1 }; -static const struct plat_sci_port scif[] = { +static struct plat_sci_port scif[] __initdata = { SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ SCIFA_DATA(SCIFA1, 0xe6c50000, gic_spi(145)), /* SCIFA1 */ SCIFB_DATA(SCIFB0, 0xe6c20000, gic_spi(148)), /* SCIFB0 */ @@ -120,11 +120,11 @@ static inline void r8a7790_register_scif(int idx) sizeof(struct plat_sci_port)); } -static struct renesas_irqc_config irqc0_data = { +static struct renesas_irqc_config irqc0_data __initdata = { .irq_base = irq_pin(0), /* IRQ0 -> IRQ3 */ }; -static struct resource irqc0_resources[] = { +static struct resource irqc0_resources[] __initdata = { DEFINE_RES_MEM(0xe61c0000, 0x200), /* IRQC Event Detector Block_0 */ DEFINE_RES_IRQ(gic_spi(0)), /* IRQ0 */ DEFINE_RES_IRQ(gic_spi(1)), /* IRQ1 */ -- cgit v1.2.3 From f303b364b41d3fc5bf879799128958400b7859aa Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 31 May 2013 17:57:01 +0200 Subject: serial: sh-sci: HSCIF support Adds support for "High Speed Serial Communications Interface with FIFO", essentially a SCIF with 128-byte FIFOs and more accurate baud rate generator. Signed-off-by: Ulrich Hecht Acked-by: Paul Mundt Acked-by: Greg Kroah-Hartman Signed-off-by: Simon Horman --- drivers/tty/serial/sh-sci.c | 102 ++++++++++++++++++++++++++++++++++++--- include/linux/serial_sci.h | 12 +++-- include/uapi/linux/serial_core.h | 3 ++ 3 files changed, 106 insertions(+), 11 deletions(-) diff --git a/drivers/tty/serial/sh-sci.c b/drivers/tty/serial/sh-sci.c index 156418619949..931d6c3a792c 100644 --- a/drivers/tty/serial/sh-sci.c +++ b/drivers/tty/serial/sh-sci.c @@ -146,6 +146,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -165,6 +166,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -183,6 +185,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -201,6 +204,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x3c, 16 }, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -220,6 +224,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -238,6 +243,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, /* @@ -256,6 +262,26 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = { 0x20, 16 }, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, + }, + + /* + * Common HSCIF definitions. + */ + [SCIx_HSCIF_REGTYPE] = { + [SCSMR] = { 0x00, 16 }, + [SCBRR] = { 0x04, 8 }, + [SCSCR] = { 0x08, 16 }, + [SCxTDR] = { 0x0c, 8 }, + [SCxSR] = { 0x10, 16 }, + [SCxRDR] = { 0x14, 8 }, + [SCFCR] = { 0x18, 16 }, + [SCFDR] = { 0x1c, 16 }, + [SCTFDR] = sci_reg_invalid, + [SCRFDR] = sci_reg_invalid, + [SCSPTR] = { 0x20, 16 }, + [SCLSR] = { 0x24, 16 }, + [HSSRR] = { 0x40, 16 }, }, /* @@ -275,6 +301,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = { 0x24, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -294,6 +321,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = { 0x20, 16 }, [SCSPTR] = { 0x24, 16 }, [SCLSR] = { 0x28, 16 }, + [HSSRR] = sci_reg_invalid, }, /* @@ -313,6 +341,7 @@ static struct plat_sci_reg sci_regmap[SCIx_NR_REGTYPES][SCIx_NR_REGS] = { [SCRFDR] = sci_reg_invalid, [SCSPTR] = sci_reg_invalid, [SCLSR] = sci_reg_invalid, + [HSSRR] = sci_reg_invalid, }, }; @@ -374,6 +403,9 @@ static int sci_probe_regmap(struct plat_sci_port *cfg) */ cfg->regtype = SCIx_SH4_SCIF_REGTYPE; break; + case PORT_HSCIF: + cfg->regtype = SCIx_HSCIF_REGTYPE; + break; default: printk(KERN_ERR "Can't probe register map for given port\n"); return -EINVAL; @@ -1798,6 +1830,42 @@ static unsigned int sci_scbrr_calc(unsigned int algo_id, unsigned int bps, return ((freq + 16 * bps) / (32 * bps) - 1); } +/* calculate sample rate, BRR, and clock select for HSCIF */ +static void sci_baud_calc_hscif(unsigned int bps, unsigned long freq, + int *brr, unsigned int *srr, + unsigned int *cks) +{ + int sr, c, br, err; + int min_err = 1000; /* 100% */ + + /* Find the combination of sample rate and clock select with the + smallest deviation from the desired baud rate. */ + for (sr = 8; sr <= 32; sr++) { + for (c = 0; c <= 3; c++) { + /* integerized formulas from HSCIF documentation */ + br = freq / (sr * (1 << (2 * c + 1)) * bps) - 1; + if (br < 0 || br > 255) + continue; + err = freq / ((br + 1) * bps * sr * + (1 << (2 * c + 1)) / 1000) - 1000; + if (min_err > err) { + min_err = err; + *brr = br; + *srr = sr - 1; + *cks = c; + } + } + } + + if (min_err == 1000) { + WARN_ON(1); + /* use defaults */ + *brr = 255; + *srr = 15; + *cks = 0; + } +} + static void sci_reset(struct uart_port *port) { struct plat_sci_reg *reg; @@ -1821,6 +1889,7 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, struct plat_sci_reg *reg; unsigned int baud, smr_val, max_baud, cks; int t = -1; + unsigned int srr; /* * earlyprintk comes here early on with port->uartclk set to zero. @@ -1833,8 +1902,17 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, max_baud = port->uartclk ? port->uartclk / 16 : 115200; baud = uart_get_baud_rate(port, termios, old, 0, max_baud); - if (likely(baud && port->uartclk)) - t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, port->uartclk); + if (likely(baud && port->uartclk)) { + if (s->cfg->scbrr_algo_id == SCBRR_ALGO_6) { + sci_baud_calc_hscif(baud, port->uartclk, &t, &srr, + &cks); + } else { + t = sci_scbrr_calc(s->cfg->scbrr_algo_id, baud, + port->uartclk); + for (cks = 0; t >= 256 && cks <= 3; cks++) + t >>= 2; + } + } sci_port_enable(s); @@ -1853,15 +1931,15 @@ static void sci_set_termios(struct uart_port *port, struct ktermios *termios, uart_update_timeout(port, termios->c_cflag, baud); - for (cks = 0; t >= 256 && cks <= 3; cks++) - t >>= 2; - dev_dbg(port->dev, "%s: SMR %x, cks %x, t %x, SCSCR %x\n", __func__, smr_val, cks, t, s->cfg->scscr); if (t >= 0) { serial_port_out(port, SCSMR, (smr_val & ~3) | cks); serial_port_out(port, SCBRR, t); + reg = sci_getreg(port, HSSRR); + if (reg->size) + serial_port_out(port, HSSRR, srr | HSCIF_SRE); udelay((1000000+(baud-1)) / baud); /* Wait one bit interval */ } else serial_port_out(port, SCSMR, smr_val); @@ -1947,6 +2025,8 @@ static const char *sci_type(struct uart_port *port) return "scifa"; case PORT_SCIFB: return "scifb"; + case PORT_HSCIF: + return "hscif"; } return NULL; @@ -1960,7 +2040,10 @@ static inline unsigned long sci_port_size(struct uart_port *port) * from platform resource data at such a time that ports begin to * behave more erratically. */ - return 64; + if (port->type == PORT_HSCIF) + return 96; + else + return 64; } static int sci_remap_port(struct uart_port *port) @@ -2085,6 +2168,9 @@ static int sci_init_single(struct platform_device *dev, case PORT_SCIFB: port->fifosize = 256; break; + case PORT_HSCIF: + port->fifosize = 128; + break; case PORT_SCIFA: port->fifosize = 64; break; @@ -2325,7 +2411,7 @@ static inline int sci_probe_earlyprintk(struct platform_device *pdev) #endif /* CONFIG_SERIAL_SH_SCI_CONSOLE */ static char banner[] __initdata = - KERN_INFO "SuperH SCI(F) driver initialized\n"; + KERN_INFO "SuperH (H)SCI(F) driver initialized\n"; static struct uart_driver sci_uart_driver = { .owner = THIS_MODULE, @@ -2484,4 +2570,4 @@ module_exit(sci_exit); MODULE_LICENSE("GPL"); MODULE_ALIAS("platform:sh-sci"); MODULE_AUTHOR("Paul Mundt"); -MODULE_DESCRIPTION("SuperH SCI(F) serial driver"); +MODULE_DESCRIPTION("SuperH (H)SCI(F) serial driver"); diff --git a/include/linux/serial_sci.h b/include/linux/serial_sci.h index eb763adf9815..d34049712a4d 100644 --- a/include/linux/serial_sci.h +++ b/include/linux/serial_sci.h @@ -5,7 +5,7 @@ #include /* - * Generic header for SuperH SCI(F) (used by sh/sh64/h8300 and related parts) + * Generic header for SuperH (H)SCI(F) (used by sh/sh64/h8300 and related parts) */ #define SCIx_NOT_SUPPORTED (-1) @@ -16,6 +16,7 @@ enum { SCBRR_ALGO_3, /* (((clk * 2) + 16 * bps) / (16 * bps) - 1) */ SCBRR_ALGO_4, /* (((clk * 2) + 16 * bps) / (32 * bps) - 1) */ SCBRR_ALGO_5, /* (((clk * 1000 / 32) / bps) - 1) */ + SCBRR_ALGO_6, /* HSCIF variable sample rate algorithm */ }; #define SCSCR_TIE (1 << 7) @@ -37,7 +38,7 @@ enum { #define SCI_DEFAULT_ERROR_MASK (SCI_PER | SCI_FER) -/* SCxSR SCIF */ +/* SCxSR SCIF, HSCIF */ #define SCIF_ER 0x0080 #define SCIF_TEND 0x0040 #define SCIF_TDFE 0x0020 @@ -55,6 +56,9 @@ enum { #define SCSPTR_SPB2IO (1 << 1) #define SCSPTR_SPB2DT (1 << 0) +/* HSSRR HSCIF */ +#define HSCIF_SRE 0x8000 + /* Offsets into the sci_port->irqs array */ enum { SCIx_ERI_IRQ, @@ -90,6 +94,7 @@ enum { SCIx_SH4_SCIF_NO_SCSPTR_REGTYPE, SCIx_SH4_SCIF_FIFODATA_REGTYPE, SCIx_SH7705_SCIF_REGTYPE, + SCIx_HSCIF_REGTYPE, SCIx_NR_REGTYPES, }; @@ -115,6 +120,7 @@ enum { SCSMR, SCBRR, SCSCR, SCxSR, SCFCR, SCFDR, SCxTDR, SCxRDR, SCLSR, SCTFDR, SCRFDR, SCSPTR, + HSSRR, SCIx_NR_REGS, }; @@ -137,7 +143,7 @@ struct plat_sci_port { unsigned long mapbase; /* resource base */ unsigned int irqs[SCIx_NR_IRQS]; /* ERI, RXI, TXI, BRI */ unsigned int gpios[SCIx_NR_FNS]; /* SCK, RXD, TXD, CTS, RTS */ - unsigned int type; /* SCI / SCIF / IRDA */ + unsigned int type; /* SCI / SCIF / IRDA / HSCIF */ upf_t flags; /* UPF_* flags */ unsigned long capabilities; /* Port features/capabilities */ diff --git a/include/uapi/linux/serial_core.h b/include/uapi/linux/serial_core.h index 74c2bf7211f8..26eee07eeb24 100644 --- a/include/uapi/linux/serial_core.h +++ b/include/uapi/linux/serial_core.h @@ -226,4 +226,7 @@ /* Rocketport EXPRESS/INFINITY */ #define PORT_RP2 102 +/* SH-SCI */ +#define PORT_HSCIF 103 + #endif /* _UAPILINUX_SERIAL_CORE_H */ -- cgit v1.2.3 From d44f8308cf7a65f4c97a041da07d872aefe47ca7 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 31 May 2013 17:57:02 +0200 Subject: ARM: shmobile: r8a7790: HSCIF support Adds support for HSCIF0 and HSCIF1 on the r8a7790. Signed-off-by: Ulrich Hecht [ horms+renesas@verge.net.au this is the setup-r8a7790.c which I somehow miss-applied as part of another patch. The clock-r8a7790.c portion of this patch has already been merged. ] Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7790.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 49de2d56f86d..896d374b9a32 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -67,7 +67,15 @@ void __init r8a7790_pinmux_init(void) .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \ } -enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1 }; +#define HSCIF_DATA(index, baseaddr, irq) \ +[index] = { \ + SCIF_COMMON(PORT_HSCIF, baseaddr, irq), \ + .scbrr_algo_id = SCBRR_ALGO_6, \ + .scscr = SCSCR_RE | SCSCR_TE, \ +} + +enum { SCIFA0, SCIFA1, SCIFB0, SCIFB1, SCIFB2, SCIFA2, SCIF0, SCIF1, + HSCIF0, HSCIF1 }; static const struct plat_sci_port scif[] = { SCIFA_DATA(SCIFA0, 0xe6c40000, gic_spi(144)), /* SCIFA0 */ @@ -78,6 +86,8 @@ static const struct plat_sci_port scif[] = { SCIFA_DATA(SCIFA2, 0xe6c60000, gic_spi(151)), /* SCIFA2 */ SCIF_DATA(SCIF0, 0xe6e60000, gic_spi(152)), /* SCIF0 */ SCIF_DATA(SCIF1, 0xe6e68000, gic_spi(153)), /* SCIF1 */ + HSCIF_DATA(HSCIF0, 0xe62c0000, gic_spi(154)), /* HSCIF0 */ + HSCIF_DATA(HSCIF1, 0xe62c8000, gic_spi(155)), /* HSCIF1 */ }; static inline void r8a7790_register_scif(int idx) @@ -115,6 +125,8 @@ void __init r8a7790_add_standard_devices(void) r8a7790_register_scif(SCIFA2); r8a7790_register_scif(SCIF0); r8a7790_register_scif(SCIF1); + r8a7790_register_scif(HSCIF0); + r8a7790_register_scif(HSCIF1); r8a7790_register_irqc(0); } -- cgit v1.2.3 From c972f024c1097fa0798beafc21be1eeeba21ac34 Mon Sep 17 00:00:00 2001 From: Ulrich Hecht Date: Fri, 31 May 2013 17:57:04 +0200 Subject: ARM: shmobile: r8a7790: don't use external clock for SCIFs This is an external component and may or may not be there, while the internal clock always works. Signed-off-by: Ulrich Hecht Signed-off-by: Simon Horman --- arch/arm/mach-shmobile/setup-r8a7790.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-shmobile/setup-r8a7790.c b/arch/arm/mach-shmobile/setup-r8a7790.c index 896d374b9a32..6531f3d3a696 100644 --- a/arch/arm/mach-shmobile/setup-r8a7790.c +++ b/arch/arm/mach-shmobile/setup-r8a7790.c @@ -64,7 +64,7 @@ void __init r8a7790_pinmux_init(void) [index] = { \ SCIF_COMMON(PORT_SCIF, baseaddr, irq), \ .scbrr_algo_id = SCBRR_ALGO_2, \ - .scscr = SCSCR_RE | SCSCR_TE | SCSCR_CKE1, \ + .scscr = SCSCR_RE | SCSCR_TE, \ } #define HSCIF_DATA(index, baseaddr, irq) \ -- cgit v1.2.3 From e6c21cbab5d6ac410676b9db36b9f1915a15a8d9 Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Wed, 19 Jun 2013 00:29:34 +0900 Subject: ARM: dts: fork out common EXYNOS5 nodes In preparation of adding support for EXYNOS5420, which has many peripherals similar to EXYNOS5250, a new common EXYNOS5 device tree source file is created out of the exising EXYNOS5250 device tree source file. Only the common nodes required for basic boot up on EXYNOS5420 based boards are moved into this new file and the rest of the common nodes would be moved subsequently. EXYNOS5440 SoC is quite different from EXYNOS5250 and EXYNOS5420. Hence it is not possible to reuse "exynos5.dtsi" for EXYNOS5440. Signed-off-by: Chander Kashyap Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- arch/arm/boot/dts/exynos5.dtsi | 111 ++++++++++++++++++++++++++++++++++++++ arch/arm/boot/dts/exynos5250.dtsi | 66 +---------------------- 2 files changed, 112 insertions(+), 65 deletions(-) create mode 100644 arch/arm/boot/dts/exynos5.dtsi diff --git a/arch/arm/boot/dts/exynos5.dtsi b/arch/arm/boot/dts/exynos5.dtsi new file mode 100644 index 000000000000..f65e124c04a6 --- /dev/null +++ b/arch/arm/boot/dts/exynos5.dtsi @@ -0,0 +1,111 @@ +/* + * Samsung's Exynos5 SoC series common device tree source + * + * Copyright (c) 2012-2013 Samsung Electronics Co., Ltd. + * http://www.samsung.com + * + * Samsung's Exynos5 SoC series device nodes are listed in this file. Particular + * SoCs from Exynos5 series can include this file and provide values for SoCs + * specfic bindings. + * + * 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 "skeleton.dtsi" + +/ { + interrupt-parent = <&gic>; + + chipid@10000000 { + compatible = "samsung,exynos4210-chipid"; + reg = <0x10000000 0x100>; + }; + + combiner:interrupt-controller@10440000 { + compatible = "samsung,exynos4210-combiner"; + #interrupt-cells = <2>; + interrupt-controller; + samsung,combiner-nr = <32>; + reg = <0x10440000 0x1000>; + interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, + <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, + <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, + <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>, + <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, + <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>, + <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, + <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; + }; + + gic:interrupt-controller@10481000 { + compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; + #interrupt-cells = <3>; + interrupt-controller; + reg = <0x10481000 0x1000>, + <0x10482000 0x1000>, + <0x10484000 0x2000>, + <0x10486000 0x2000>; + interrupts = <1 9 0xf04>; + }; + + dwmmc_0: dwmmc0@12200000 { + compatible = "samsung,exynos5250-dw-mshc"; + interrupts = <0 75 0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + dwmmc_1: dwmmc1@12210000 { + compatible = "samsung,exynos5250-dw-mshc"; + interrupts = <0 76 0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + dwmmc_2: dwmmc2@12220000 { + compatible = "samsung,exynos5250-dw-mshc"; + interrupts = <0 77 0>; + #address-cells = <1>; + #size-cells = <0>; + }; + + serial@12C00000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C00000 0x100>; + interrupts = <0 51 0>; + }; + + serial@12C10000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C10000 0x100>; + interrupts = <0 52 0>; + }; + + serial@12C20000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C20000 0x100>; + interrupts = <0 53 0>; + }; + + serial@12C30000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x12C30000 0x100>; + interrupts = <0 54 0>; + }; + + rtc { + compatible = "samsung,s3c6410-rtc"; + reg = <0x101E0000 0x100>; + interrupts = <0 43 0>, <0 44 0>; + status = "disabled"; + }; + + watchdog { + compatible = "samsung,s3c2410-wdt"; + reg = <0x101D0000 0x100>; + interrupts = <0 42 0>; + status = "disabled"; + }; +}; diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 0aa9091ed7c5..1e215fed037b 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -17,14 +17,13 @@ * published by the Free Software Foundation. */ -#include "skeleton.dtsi" +#include "exynos5.dtsi" #include "exynos5250-pinctrl.dtsi" #include / { compatible = "samsung,exynos5250"; - interrupt-parent = <&gic>; aliases { spi0 = &spi_0; @@ -53,11 +52,6 @@ pinctrl3 = &pinctrl_3; }; - chipid@10000000 { - compatible = "samsung,exynos4210-chipid"; - reg = <0x10000000 0x100>; - }; - pd_gsc: gsc-power-domain@0x10044000 { compatible = "samsung,exynos4210-pd"; reg = <0x10044000 0x20>; @@ -80,17 +74,6 @@ #clock-cells = <1>; }; - gic:interrupt-controller@10481000 { - compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; - #interrupt-cells = <3>; - interrupt-controller; - reg = <0x10481000 0x1000>, - <0x10482000 0x1000>, - <0x10484000 0x2000>, - <0x10486000 0x2000>; - interrupts = <1 9 0xf04>; - }; - timer { compatible = "arm,armv7-timer"; interrupts = <1 13 0xf08>, @@ -99,22 +82,6 @@ <1 10 0xf08>; }; - combiner:interrupt-controller@10440000 { - compatible = "samsung,exynos4210-combiner"; - #interrupt-cells = <2>; - interrupt-controller; - samsung,combiner-nr = <32>; - reg = <0x10440000 0x1000>; - interrupts = <0 0 0>, <0 1 0>, <0 2 0>, <0 3 0>, - <0 4 0>, <0 5 0>, <0 6 0>, <0 7 0>, - <0 8 0>, <0 9 0>, <0 10 0>, <0 11 0>, - <0 12 0>, <0 13 0>, <0 14 0>, <0 15 0>, - <0 16 0>, <0 17 0>, <0 18 0>, <0 19 0>, - <0 20 0>, <0 21 0>, <0 22 0>, <0 23 0>, - <0 24 0>, <0 25 0>, <0 26 0>, <0 27 0>, - <0 28 0>, <0 29 0>, <0 30 0>, <0 31 0>; - }; - mct@101C0000 { compatible = "samsung,exynos4210-mct"; reg = <0x101C0000 0x800>; @@ -176,9 +143,6 @@ }; watchdog { - compatible = "samsung,s3c2410-wdt"; - reg = <0x101D0000 0x100>; - interrupts = <0 42 0>; clocks = <&clock 336>; clock-names = "watchdog"; }; @@ -191,12 +155,8 @@ }; rtc { - compatible = "samsung,s3c6410-rtc"; - reg = <0x101E0000 0x100>; - interrupts = <0 43 0>, <0 44 0>; clocks = <&clock 337>; clock-names = "rtc"; - status = "disabled"; }; tmu@10060000 { @@ -208,33 +168,21 @@ }; serial@12C00000 { - compatible = "samsung,exynos4210-uart"; - reg = <0x12C00000 0x100>; - interrupts = <0 51 0>; clocks = <&clock 289>, <&clock 146>; clock-names = "uart", "clk_uart_baud0"; }; serial@12C10000 { - compatible = "samsung,exynos4210-uart"; - reg = <0x12C10000 0x100>; - interrupts = <0 52 0>; clocks = <&clock 290>, <&clock 147>; clock-names = "uart", "clk_uart_baud0"; }; serial@12C20000 { - compatible = "samsung,exynos4210-uart"; - reg = <0x12C20000 0x100>; - interrupts = <0 53 0>; clocks = <&clock 291>, <&clock 148>; clock-names = "uart", "clk_uart_baud0"; }; serial@12C30000 { - compatible = "samsung,exynos4210-uart"; - reg = <0x12C30000 0x100>; - interrupts = <0 54 0>; clocks = <&clock 292>, <&clock 149>; clock-names = "uart", "clk_uart_baud0"; }; @@ -413,31 +361,19 @@ }; dwmmc_0: dwmmc0@12200000 { - compatible = "samsung,exynos5250-dw-mshc"; reg = <0x12200000 0x1000>; - interrupts = <0 75 0>; - #address-cells = <1>; - #size-cells = <0>; clocks = <&clock 280>, <&clock 139>; clock-names = "biu", "ciu"; }; dwmmc_1: dwmmc1@12210000 { - compatible = "samsung,exynos5250-dw-mshc"; reg = <0x12210000 0x1000>; - interrupts = <0 76 0>; - #address-cells = <1>; - #size-cells = <0>; clocks = <&clock 281>, <&clock 140>; clock-names = "biu", "ciu"; }; dwmmc_2: dwmmc2@12220000 { - compatible = "samsung,exynos5250-dw-mshc"; reg = <0x12220000 0x1000>; - interrupts = <0 77 0>; - #address-cells = <1>; - #size-cells = <0>; clocks = <&clock 282>, <&clock 141>; clock-names = "biu", "ciu"; }; -- cgit v1.2.3 From 1897d2f32fef9cb5caa9951b2cdc79b05bfb512d Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Wed, 19 Jun 2013 00:29:34 +0900 Subject: ARM: dts: list the CPU nodes for EXYNOS5250 Instead of having to specify the number for CPUs in EXYNOS5250 in platsmp.c file, let the number of CPUs be determined by having this information listed in EXYNOS5250 device tree file. Signed-off-by: Chander Kashyap Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- arch/arm/boot/dts/exynos5250.dtsi | 16 ++++++++++++++++ arch/arm/mach-exynos/platsmp.c | 10 +++++++--- 2 files changed, 23 insertions(+), 3 deletions(-) diff --git a/arch/arm/boot/dts/exynos5250.dtsi b/arch/arm/boot/dts/exynos5250.dtsi index 1e215fed037b..d04ab0ad791a 100644 --- a/arch/arm/boot/dts/exynos5250.dtsi +++ b/arch/arm/boot/dts/exynos5250.dtsi @@ -52,6 +52,22 @@ pinctrl3 = &pinctrl_3; }; + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <0>; + }; + cpu@1 { + device_type = "cpu"; + compatible = "arm,cortex-a15"; + reg = <1>; + }; + }; + pd_gsc: gsc-power-domain@0x10044000 { compatible = "samsung,exynos4210-pd"; reg = <0x10044000 0x20>; diff --git a/arch/arm/mach-exynos/platsmp.c b/arch/arm/mach-exynos/platsmp.c index a0e8ff7758a4..ab1d2d5f3709 100644 --- a/arch/arm/mach-exynos/platsmp.c +++ b/arch/arm/mach-exynos/platsmp.c @@ -180,10 +180,14 @@ static void __init exynos_smp_init_cpus(void) void __iomem *scu_base = scu_base_addr(); unsigned int i, ncores; - if (soc_is_exynos5250()) - ncores = 2; - else + if (read_cpuid_part_number() == ARM_CPU_PART_CORTEX_A9) ncores = scu_base ? scu_get_core_count(scu_base) : 1; + else + /* + * CPU Nodes are passed thru DT and set_cpu_possible + * is set by "arm_dt_init_cpu_maps". + */ + return; /* sanity check */ if (ncores > nr_cpu_ids) { -- cgit v1.2.3 From 191d754f5bfd99d682cd496759f56d97294bfdf0 Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Wed, 19 Jun 2013 00:29:34 +0900 Subject: ARM: EXYNOS: Add support for EXYNOS5420 SoC EXYNOS5420 is new SoC in Samsung's Exynos5 SoC series. Add initial support for this new SoC. Signed-off-by: Chander Kashyap Signed-off-by: Thomas Abraham Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/Kconfig | 10 ++++++++++ arch/arm/mach-exynos/common.c | 7 +++++++ arch/arm/mach-exynos/mach-exynos5-dt.c | 1 + arch/arm/plat-samsung/include/plat/cpu.h | 8 ++++++++ 4 files changed, 26 insertions(+) diff --git a/arch/arm/mach-exynos/Kconfig b/arch/arm/mach-exynos/Kconfig index ff18fc2ea46f..5ae41ecb0a02 100644 --- a/arch/arm/mach-exynos/Kconfig +++ b/arch/arm/mach-exynos/Kconfig @@ -71,6 +71,16 @@ config SOC_EXYNOS5250 help Enable EXYNOS5250 SoC support +config SOC_EXYNOS5420 + bool "SAMSUNG EXYNOS5420" + default y + depends on ARCH_EXYNOS5 + select PM_GENERIC_DOMAINS if PM + select S5P_PM if PM + select S5P_SLEEP if PM + help + Enable EXYNOS5420 SoC support + config SOC_EXYNOS5440 bool "SAMSUNG EXYNOS5440" default y diff --git a/arch/arm/mach-exynos/common.c b/arch/arm/mach-exynos/common.c index f7e504b7874d..f323655737fb 100644 --- a/arch/arm/mach-exynos/common.c +++ b/arch/arm/mach-exynos/common.c @@ -64,6 +64,7 @@ static const char name_exynos4210[] = "EXYNOS4210"; static const char name_exynos4212[] = "EXYNOS4212"; static const char name_exynos4412[] = "EXYNOS4412"; static const char name_exynos5250[] = "EXYNOS5250"; +static const char name_exynos5420[] = "EXYNOS5420"; static const char name_exynos5440[] = "EXYNOS5440"; static void exynos4_map_io(void); @@ -102,6 +103,12 @@ static struct cpu_table cpu_ids[] __initdata = { .map_io = exynos5_map_io, .init = exynos_init, .name = name_exynos5250, + }, { + .idcode = EXYNOS5420_SOC_ID, + .idmask = EXYNOS5_SOC_MASK, + .map_io = exynos5_map_io, + .init = exynos_init, + .name = name_exynos5420, }, { .idcode = EXYNOS5440_SOC_ID, .idmask = EXYNOS5_SOC_MASK, diff --git a/arch/arm/mach-exynos/mach-exynos5-dt.c b/arch/arm/mach-exynos/mach-exynos5-dt.c index 753b94f3fca7..050a5b1247ef 100644 --- a/arch/arm/mach-exynos/mach-exynos5-dt.c +++ b/arch/arm/mach-exynos/mach-exynos5-dt.c @@ -57,6 +57,7 @@ static void __init exynos5_dt_machine_init(void) static char const *exynos5_dt_compat[] __initdata = { "samsung,exynos5250", + "samsung,exynos5420", "samsung,exynos5440", NULL }; diff --git a/arch/arm/plat-samsung/include/plat/cpu.h b/arch/arm/plat-samsung/include/plat/cpu.h index 989fefe18be6..4fb1f03a10d1 100644 --- a/arch/arm/plat-samsung/include/plat/cpu.h +++ b/arch/arm/plat-samsung/include/plat/cpu.h @@ -46,6 +46,7 @@ extern unsigned long samsung_cpu_id; #define EXYNOS4_CPU_MASK 0xFFFE0000 #define EXYNOS5250_SOC_ID 0x43520000 +#define EXYNOS5420_SOC_ID 0xE5420000 #define EXYNOS5440_SOC_ID 0xE5440000 #define EXYNOS5_SOC_MASK 0xFFFFF000 @@ -67,6 +68,7 @@ IS_SAMSUNG_CPU(exynos4210, EXYNOS4210_CPU_ID, EXYNOS4_CPU_MASK) IS_SAMSUNG_CPU(exynos4212, EXYNOS4212_CPU_ID, EXYNOS4_CPU_MASK) IS_SAMSUNG_CPU(exynos4412, EXYNOS4412_CPU_ID, EXYNOS4_CPU_MASK) IS_SAMSUNG_CPU(exynos5250, EXYNOS5250_SOC_ID, EXYNOS5_SOC_MASK) +IS_SAMSUNG_CPU(exynos5420, EXYNOS5420_SOC_ID, EXYNOS5_SOC_MASK) IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK) #if defined(CONFIG_CPU_S3C2410) || defined(CONFIG_CPU_S3C2412) || \ @@ -142,6 +144,12 @@ IS_SAMSUNG_CPU(exynos5440, EXYNOS5440_SOC_ID, EXYNOS5_SOC_MASK) # define soc_is_exynos5250() 0 #endif +#if defined(CONFIG_SOC_EXYNOS5420) +# define soc_is_exynos5420() is_samsung_exynos5420() +#else +# define soc_is_exynos5420() 0 +#endif + #if defined(CONFIG_SOC_EXYNOS5440) # define soc_is_exynos5440() is_samsung_exynos5440() #else -- cgit v1.2.3 From 33f881365f212a59b83b9cb2e66e15aceee99ddb Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Wed, 19 Jun 2013 00:29:34 +0900 Subject: serial: samsung: select EXYNOS specific driver data if ARCH_EXYNOS is defined All EXYNOS4/5 SoCs share a common driver data in the samsung serial driver. Hence, let the driver data inclusion be based on ARCH_EXYNOS instead of SOC specific definition. Signed-off-by: Chander Kashyap Reviewed-by: Tomasz Figa Reviewed by: Girish K S Signed-off-by: Kukjin Kim --- drivers/tty/serial/samsung.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/drivers/tty/serial/samsung.c b/drivers/tty/serial/samsung.c index 0c8a9fa2be6c..94a91c2b7ca0 100644 --- a/drivers/tty/serial/samsung.c +++ b/drivers/tty/serial/samsung.c @@ -1713,9 +1713,7 @@ static struct s3c24xx_serial_drv_data s5pv210_serial_drv_data = { #define S5PV210_SERIAL_DRV_DATA (kernel_ulong_t)NULL #endif -#if defined(CONFIG_CPU_EXYNOS4210) || defined(CONFIG_SOC_EXYNOS4212) || \ - defined(CONFIG_SOC_EXYNOS4412) || defined(CONFIG_SOC_EXYNOS5250) || \ - defined(CONFIG_SOC_EXYNOS5440) +#if defined(CONFIG_ARCH_EXYNOS) static struct s3c24xx_serial_drv_data exynos4210_serial_drv_data = { .info = &(struct s3c24xx_uart_info) { .name = "Samsung Exynos4 UART", -- cgit v1.2.3 From c6fd0fe85ab761829102b60d590d0fdd71a649bd Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Wed, 19 Jun 2013 00:29:34 +0900 Subject: ARM: EXYNOS: use four additional chipid bits to identify EXYNOS family Use chipid[27:20] bits to identify the EXYNOS family while setting up the serial port during the uncompression setup. This uses four additional bits of chipid to identify the EXYNOS family since this is required for identifying EXYNOS5420 SoC. Signed-off-by: Chander Kashyap Signed-off-by: Thomas Abraham Reviewed-by: Tomasz Figa Signed-off-by: Kukjin Kim --- arch/arm/mach-exynos/include/mach/uncompress.h | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-exynos/include/mach/uncompress.h b/arch/arm/mach-exynos/include/mach/uncompress.h index 2979995d5a6a..1937e0fb7375 100644 --- a/arch/arm/mach-exynos/include/mach/uncompress.h +++ b/arch/arm/mach-exynos/include/mach/uncompress.h @@ -31,13 +31,12 @@ static void arch_detect_cpu(void) /* * product_id is bits 31:12 - * bits 23:20 describe the exynosX family - * + * bits 23:20 describe the exynosX family + * bits 27:24 describe the exynosX family in exynos5420 */ chip_id >>= 20; - chip_id &= 0xf; - if (chip_id == 0x5) + if ((chip_id & 0x0f) == 0x5 || (chip_id & 0xf0) == 0x50) uart_base = (volatile u8 *)EXYNOS5_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT); else uart_base = (volatile u8 *)EXYNOS4_PA_UART + (S3C_UART_OFFSET * CONFIG_S3C_LOWLEVEL_UART_PORT); -- cgit v1.2.3 From 1609027fc2f4e3784c64a57654c16b9c4f2d10db Mon Sep 17 00:00:00 2001 From: Chander Kashyap Date: Wed, 19 Jun 2013 00:29:34 +0900 Subject: clk: exynos5420: register clocks using common clock framework The EXYNOS5420 clocks are statically listed and registered using the Samsung specific common clock helper functions. Signed-off-by: Chander Kashyap Signed-off-by: Thomas Abraham Reviewed-by: Tomasz Figa Cc: Mike Turquette Signed-off-by: Kukjin Kim --- .../devicetree/bindings/clock/exynos5420-clock.txt | 201 ++++++ drivers/clk/samsung/Makefile | 1 + drivers/clk/samsung/clk-exynos5420.c | 762 +++++++++++++++++++++ 3 files changed, 964 insertions(+) create mode 100644 Documentation/devicetree/bindings/clock/exynos5420-clock.txt create mode 100644 drivers/clk/samsung/clk-exynos5420.c diff --git a/Documentation/devicetree/bindings/clock/exynos5420-clock.txt b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt new file mode 100644 index 000000000000..9bcc4b1bff51 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/exynos5420-clock.txt @@ -0,0 +1,201 @@ +* Samsung Exynos5420 Clock Controller + +The Exynos5420 clock controller generates and supplies clock to various +controllers within the Exynos5420 SoC. + +Required Properties: + +- comptible: should be one of the following. + - "samsung,exynos5420-clock" - controller compatible with Exynos5420 SoC. + +- reg: physical base address of the controller and length of memory mapped + region. + +- #clock-cells: should be 1. + +The following is the list of clocks generated by the controller. Each clock is +assigned an identifier and client nodes use this identifier to specify the +clock which they consume. + + + [Core Clocks] + + Clock ID + ---------------------------- + + fin_pll 1 + + [Clock Gate for Special Clocks] + + Clock ID + ---------------------------- + sclk_uart0 128 + sclk_uart1 129 + sclk_uart2 130 + sclk_uart3 131 + sclk_mmc0 132 + sclk_mmc1 133 + sclk_mmc2 134 + sclk_spi0 135 + sclk_spi1 136 + sclk_spi2 137 + sclk_i2s1 138 + sclk_i2s2 139 + sclk_pcm1 140 + sclk_pcm2 141 + sclk_spdif 142 + sclk_hdmi 143 + sclk_pixel 144 + sclk_dp1 145 + sclk_mipi1 146 + sclk_fimd1 147 + sclk_maudio0 148 + sclk_maupcm0 149 + sclk_usbd300 150 + sclk_usbd301 151 + sclk_usbphy300 152 + sclk_usbphy301 153 + sclk_unipro 154 + sclk_pwm 155 + sclk_gscl_wa 156 + sclk_gscl_wb 157 + + [Peripheral Clock Gates] + + Clock ID + ---------------------------- + + aclk66_peric 256 + uart0 257 + uart1 258 + uart2 259 + uart3 260 + i2c0 261 + i2c1 262 + i2c2 263 + i2c3 264 + i2c4 265 + i2c5 266 + i2c6 267 + i2c7 268 + i2c_hdmi 269 + tsadc 270 + spi0 271 + spi1 272 + spi2 273 + keyif 274 + i2s1 275 + i2s2 276 + pcm1 277 + pcm2 278 + pwm 279 + spdif 280 + i2c8 281 + i2c9 282 + i2c10 283 + aclk66_psgen 300 + chipid 301 + sysreg 302 + tzpc0 303 + tzpc1 304 + tzpc2 305 + tzpc3 306 + tzpc4 307 + tzpc5 308 + tzpc6 309 + tzpc7 310 + tzpc8 311 + tzpc9 312 + hdmi_cec 313 + seckey 314 + mct 315 + wdt 316 + rtc 317 + tmu 318 + tmu_gpu 319 + pclk66_gpio 330 + aclk200_fsys2 350 + mmc0 351 + mmc1 352 + mmc2 353 + sromc 354 + ufs 355 + aclk200_fsys 360 + tsi 361 + pdma0 362 + pdma1 363 + rtic 364 + usbh20 365 + usbd300 366 + usbd301 377 + aclk400_mscl 380 + mscl0 381 + mscl1 382 + mscl2 383 + smmu_mscl0 384 + smmu_mscl1 385 + smmu_mscl2 386 + aclk333 400 + mfc 401 + smmu_mfcl 402 + smmu_mfcr 403 + aclk200_disp1 410 + dsim1 411 + dp1 412 + hdmi 413 + aclk300_disp1 420 + fimd1 421 + smmu_fimd1 422 + aclk166 430 + mixer 431 + aclk266 440 + rotator 441 + mdma1 442 + smmu_rotator 443 + smmu_mdma1 444 + aclk300_jpeg 450 + jpeg 451 + jpeg2 452 + smmu_jpeg 453 + aclk300_gscl 460 + smmu_gscl0 461 + smmu_gscl1 462 + gscl_wa 463 + gscl_wb 464 + gscl0 465 + gscl1 466 + clk_3aa 467 + aclk266_g2d 470 + sss 471 + slim_sss 472 + mdma0 473 + aclk333_g2d 480 + g2d 481 + aclk333_432_gscl 490 + smmu_3aa 491 + smmu_fimcl0 492 + smmu_fimcl1 493 + smmu_fimcl3 494 + fimc_lite3 495 + aclk_g3d 500 + g3d 501 + +Example 1: An example of a clock controller node is listed below. + + clock: clock-controller@0x10010000 { + compatible = "samsung,exynos5420-clock"; + reg = <0x10010000 0x30000>; + #clock-cells = <1>; + }; + +Example 2: UART controller node that consumes the clock generated by the clock + controller. Refer to the standard clock bindings for information + about 'clocks' and 'clock-names' property. + + serial@13820000 { + compatible = "samsung,exynos4210-uart"; + reg = <0x13820000 0x100>; + interrupts = <0 54 0>; + clocks = <&clock 259>, <&clock 130>; + clock-names = "uart", "clk_uart_baud0"; + }; diff --git a/drivers/clk/samsung/Makefile b/drivers/clk/samsung/Makefile index 187681013bdb..5d4d432cc4ac 100644 --- a/drivers/clk/samsung/Makefile +++ b/drivers/clk/samsung/Makefile @@ -5,5 +5,6 @@ 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_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-exynos5420.c b/drivers/clk/samsung/clk-exynos5420.c new file mode 100644 index 000000000000..68a96cbd4936 --- /dev/null +++ b/drivers/clk/samsung/clk-exynos5420.c @@ -0,0 +1,762 @@ +/* + * Copyright (c) 2013 Samsung Electronics Co., Ltd. + * Authors: Thomas Abraham + * Chander Kashyap + * + * 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 Exynos5420 SoC. +*/ + +#include +#include +#include +#include +#include + +#include "clk.h" +#include "clk-pll.h" + +#define SRC_CPU 0x200 +#define DIV_CPU0 0x500 +#define DIV_CPU1 0x504 +#define GATE_BUS_CPU 0x700 +#define GATE_SCLK_CPU 0x800 +#define SRC_TOP0 0x10200 +#define SRC_TOP1 0x10204 +#define SRC_TOP2 0x10208 +#define SRC_TOP3 0x1020c +#define SRC_TOP4 0x10210 +#define SRC_TOP5 0x10214 +#define SRC_TOP6 0x10218 +#define SRC_TOP7 0x1021c +#define SRC_DISP10 0x1022c +#define SRC_MAU 0x10240 +#define SRC_FSYS 0x10244 +#define SRC_PERIC0 0x10250 +#define SRC_PERIC1 0x10254 +#define SRC_TOP10 0x10280 +#define SRC_TOP11 0x10284 +#define SRC_TOP12 0x10288 +#define SRC_MASK_DISP10 0x1032c +#define SRC_MASK_FSYS 0x10340 +#define SRC_MASK_PERIC0 0x10350 +#define SRC_MASK_PERIC1 0x10354 +#define DIV_TOP0 0x10500 +#define DIV_TOP1 0x10504 +#define DIV_TOP2 0x10508 +#define DIV_DISP10 0x1052c +#define DIV_MAU 0x10544 +#define DIV_FSYS0 0x10548 +#define DIV_FSYS1 0x1054c +#define DIV_FSYS2 0x10550 +#define DIV_PERIC0 0x10558 +#define DIV_PERIC1 0x1055c +#define DIV_PERIC2 0x10560 +#define DIV_PERIC3 0x10564 +#define DIV_PERIC4 0x10568 +#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_IP_GSCL0 0x10910 +#define GATE_IP_GSCL1 0x10920 +#define GATE_IP_MFC 0x1092c +#define GATE_IP_DISP1 0x10928 +#define GATE_IP_G3D 0x10930 +#define GATE_IP_GEN 0x10934 +#define GATE_IP_MSCL 0x10970 +#define GATE_TOP_SCLK_GSCL 0x10820 +#define GATE_TOP_SCLK_DISP1 0x10828 +#define GATE_TOP_SCLK_MAU 0x1083c +#define GATE_TOP_SCLK_FSYS 0x10840 +#define GATE_TOP_SCLK_PERIC 0x10850 +#define SRC_CDREX 0x20200 +#define SRC_KFC 0x28200 +#define DIV_KFC0 0x28500 + +enum exynos5420_clks { + none, + + /* core clocks */ + fin_pll, + + /* gate for special clocks (sclk) */ + sclk_uart0 = 128, sclk_uart1, sclk_uart2, sclk_uart3, sclk_mmc0, + sclk_mmc1, sclk_mmc2, sclk_spi0, sclk_spi1, sclk_spi2, sclk_i2s1, + sclk_i2s2, sclk_pcm1, sclk_pcm2, sclk_spdif, sclk_hdmi, sclk_pixel, + sclk_dp1, sclk_mipi1, sclk_fimd1, sclk_maudio0, sclk_maupcm0, + sclk_usbd300, sclk_usbd301, sclk_usbphy300, sclk_usbphy301, sclk_unipro, + sclk_pwm, sclk_gscl_wa, sclk_gscl_wb, + + /* gate clocks */ + aclk66_peric = 256, uart0, uart1, uart2, uart3, i2c0, i2c1, i2c2, i2c3, + i2c4, i2c5, i2c6, i2c7, i2c_hdmi, tsadc, spi0, spi1, spi2, keyif, i2s1, + i2s2, pcm1, pcm2, pwm, spdif, i2c8, i2c9, i2c10, aclk66_psgen = 300, + chipid, sysreg, tzpc0, tzpc1, tzpc2, tzpc3, tzpc4, tzpc5, tzpc6, tzpc7, + tzpc8, tzpc9, hdmi_cec, seckey, mct, wdt, rtc, tmu, tmu_gpu, + pclk66_gpio = 330, aclk200_fsys2 = 350, mmc0, mmc1, mmc2, sromc, ufs, + aclk200_fsys = 360, tsi, pdma0, pdma1, rtic, usbh20, usbd300, usbd301, + aclk400_mscl = 380, mscl0, mscl1, mscl2, smmu_mscl0, smmu_mscl1, + smmu_mscl2, aclk333 = 400, mfc, smmu_mfcl, smmu_mfcr, + aclk200_disp1 = 410, dsim1, dp1, hdmi, aclk300_disp1 = 420, fimd1, + smmu_fimd1, aclk166 = 430, mixer, aclk266 = 440, rotator, mdma1, + smmu_rotator, smmu_mdma1, aclk300_jpeg = 450, jpeg, jpeg2, smmu_jpeg, + aclk300_gscl = 460, smmu_gscl0, smmu_gscl1, gscl_wa, gscl_wb, gscl0, + gscl1, clk_3aa, aclk266_g2d = 470, sss, slim_sss, mdma0, + aclk333_g2d = 480, g2d, aclk333_432_gscl = 490, smmu_3aa, smmu_fimcl0, + smmu_fimcl1, smmu_fimcl3, fimc_lite3, aclk_g3d = 500, g3d, + + nr_clks, +}; + +/* + * list of controller registers to be saved and restored during a + * suspend/resume cycle. + */ +static __initdata unsigned long exynos5420_clk_regs[] = { + SRC_CPU, + DIV_CPU0, + DIV_CPU1, + GATE_BUS_CPU, + GATE_SCLK_CPU, + SRC_TOP0, + SRC_TOP1, + SRC_TOP2, + SRC_TOP3, + SRC_TOP4, + SRC_TOP5, + SRC_TOP6, + SRC_TOP7, + SRC_DISP10, + SRC_MAU, + SRC_FSYS, + SRC_PERIC0, + SRC_PERIC1, + SRC_TOP10, + SRC_TOP11, + SRC_TOP12, + SRC_MASK_DISP10, + SRC_MASK_FSYS, + SRC_MASK_PERIC0, + SRC_MASK_PERIC1, + DIV_TOP0, + DIV_TOP1, + DIV_TOP2, + DIV_DISP10, + DIV_MAU, + DIV_FSYS0, + DIV_FSYS1, + DIV_FSYS2, + DIV_PERIC0, + DIV_PERIC1, + DIV_PERIC2, + DIV_PERIC3, + DIV_PERIC4, + GATE_BUS_TOP, + GATE_BUS_FSYS0, + GATE_BUS_PERIC, + GATE_BUS_PERIC1, + GATE_BUS_PERIS0, + GATE_BUS_PERIS1, + GATE_IP_GSCL0, + GATE_IP_GSCL1, + GATE_IP_MFC, + GATE_IP_DISP1, + GATE_IP_G3D, + GATE_IP_GEN, + GATE_IP_MSCL, + GATE_TOP_SCLK_GSCL, + GATE_TOP_SCLK_DISP1, + GATE_TOP_SCLK_MAU, + GATE_TOP_SCLK_FSYS, + GATE_TOP_SCLK_PERIC, + SRC_CDREX, + SRC_KFC, + DIV_KFC0, +}; + +/* 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) = { "sclk_hdmiphy", "dout_hdmi_pixel" }; +PNAME(maudio0_p) = { "fin_pll", "maudio_clk", "sclk_dpll", "sclk_mpll", + "sclk_spll", "sclk_ipll", "sclk_epll", "sclk_rpll" }; + +/* fixed rate clocks generated outside the soc */ +struct samsung_fixed_rate_clock exynos5420_fixed_rate_ext_clks[] __initdata = { + FRATE(fin_pll, "fin_pll", NULL, CLK_IS_ROOT, 0), +}; + +/* fixed rate clocks generated inside the soc */ +struct samsung_fixed_rate_clock exynos5420_fixed_rate_clks[] __initdata = { + FRATE(none, "sclk_hdmiphy", NULL, CLK_IS_ROOT, 24000000), + FRATE(none, "sclk_pwi", NULL, CLK_IS_ROOT, 24000000), + FRATE(none, "sclk_usbh20", NULL, CLK_IS_ROOT, 48000000), + FRATE(none, "mphy_refclk_ixtal24", NULL, CLK_IS_ROOT, 48000000), + FRATE(none, "sclk_usbh20_scan_clk", NULL, CLK_IS_ROOT, 480000000), +}; + +struct samsung_fixed_factor_clock exynos5420_fixed_factor_clks[] __initdata = { + FFACTOR(none, "sclk_hsic_12m", "fin_pll", 1, 2, 0), +}; + +struct samsung_mux_clock exynos5420_mux_clks[] __initdata = { + MUX(none, "mout_mspll_kfc", mspll_cpu_p, SRC_TOP7, 8, 2), + MUX(none, "mout_mspll_cpu", mspll_cpu_p, SRC_TOP7, 12, 2), + MUX(none, "mout_apll", apll_p, SRC_CPU, 0, 1), + MUX(none, "mout_cpu", cpu_p, SRC_CPU, 16, 1), + MUX(none, "mout_kpll", kpll_p, SRC_KFC, 0, 1), + MUX(none, "mout_cpu_kfc", kfc_p, SRC_KFC, 16, 1), + + MUX(none, "sclk_bpll", bpll_p, SRC_CDREX, 0, 1), + + MUX_A(none, "mout_aclk400_mscl", group1_p, + SRC_TOP0, 4, 2, "aclk400_mscl"), + MUX(none, "mout_aclk200", group1_p, SRC_TOP0, 8, 2), + MUX(none, "mout_aclk200_fsys2", group1_p, SRC_TOP0, 12, 2), + MUX(none, "mout_aclk200_fsys", group1_p, SRC_TOP0, 28, 2), + + MUX(none, "mout_aclk333_432_gscl", group4_p, SRC_TOP1, 0, 2), + MUX(none, "mout_aclk66", group1_p, SRC_TOP1, 8, 2), + MUX(none, "mout_aclk266", group1_p, SRC_TOP1, 20, 2), + MUX(none, "mout_aclk166", group1_p, SRC_TOP1, 24, 2), + MUX(none, "mout_aclk333", group1_p, SRC_TOP1, 28, 2), + + MUX(none, "mout_aclk333_g2d", group1_p, SRC_TOP2, 8, 2), + MUX(none, "mout_aclk266_g2d", group1_p, SRC_TOP2, 12, 2), + MUX(none, "mout_aclk_g3d", group5_p, SRC_TOP2, 16, 1), + MUX(none, "mout_aclk300_jpeg", group1_p, SRC_TOP2, 20, 2), + MUX(none, "mout_aclk300_disp1", group1_p, SRC_TOP2, 24, 2), + MUX(none, "mout_aclk300_gscl", group1_p, SRC_TOP2, 28, 2), + + MUX(none, "mout_user_aclk400_mscl", user_aclk400_mscl_p, + SRC_TOP3, 4, 1), + MUX_A(none, "mout_aclk200_disp1", aclk200_disp1_p, + SRC_TOP3, 8, 1, "aclk200_disp1"), + MUX(none, "mout_user_aclk200_fsys2", user_aclk200_fsys2_p, + SRC_TOP3, 12, 1), + MUX(none, "mout_user_aclk200_fsys", user_aclk200_fsys_p, + SRC_TOP3, 28, 1), + + MUX(none, "mout_user_aclk333_432_gscl", user_aclk333_432_gscl_p, + SRC_TOP4, 0, 1), + MUX(none, "mout_aclk66_peric", aclk66_peric_p, SRC_TOP4, 8, 1), + MUX(none, "mout_user_aclk266", user_aclk266_p, SRC_TOP4, 20, 1), + MUX(none, "mout_user_aclk166", user_aclk166_p, SRC_TOP4, 24, 1), + MUX(none, "mout_user_aclk333", user_aclk333_p, SRC_TOP4, 28, 1), + + MUX(none, "mout_aclk66_psgen", aclk66_peric_p, SRC_TOP5, 4, 1), + MUX(none, "mout_user_aclk333_g2d", user_aclk333_g2d_p, SRC_TOP5, 8, 1), + MUX(none, "mout_user_aclk266_g2d", user_aclk266_g2d_p, SRC_TOP5, 12, 1), + MUX_A(none, "mout_user_aclk_g3d", user_aclk_g3d_p, + SRC_TOP5, 16, 1, "aclkg3d"), + MUX(none, "mout_user_aclk300_jpeg", user_aclk300_jpeg_p, + SRC_TOP5, 20, 1), + MUX(none, "mout_user_aclk300_disp1", user_aclk300_disp1_p, + SRC_TOP5, 24, 1), + MUX(none, "mout_user_aclk300_gscl", user_aclk300_gscl_p, + SRC_TOP5, 28, 1), + + MUX(none, "sclk_mpll", mpll_p, SRC_TOP6, 0, 1), + MUX(none, "sclk_vpll", vpll_p, SRC_TOP6, 4, 1), + MUX(none, "sclk_spll", spll_p, SRC_TOP6, 8, 1), + MUX(none, "sclk_ipll", ipll_p, SRC_TOP6, 12, 1), + MUX(none, "sclk_rpll", rpll_p, SRC_TOP6, 16, 1), + MUX(none, "sclk_epll", epll_p, SRC_TOP6, 20, 1), + MUX(none, "sclk_dpll", dpll_p, SRC_TOP6, 24, 1), + MUX(none, "sclk_cpll", cpll_p, SRC_TOP6, 28, 1), + + MUX(none, "mout_sw_aclk400_mscl", sw_aclk400_mscl_p, SRC_TOP10, 4, 1), + MUX(none, "mout_sw_aclk200", sw_aclk200_p, SRC_TOP10, 8, 1), + MUX(none, "mout_sw_aclk200_fsys2", sw_aclk200_fsys2_p, + SRC_TOP10, 12, 1), + MUX(none, "mout_sw_aclk200_fsys", sw_aclk200_fsys_p, SRC_TOP10, 28, 1), + + MUX(none, "mout_sw_aclk333_432_gscl", sw_aclk333_432_gscl_p, + SRC_TOP11, 0, 1), + MUX(none, "mout_sw_aclk66", sw_aclk66_p, SRC_TOP11, 8, 1), + MUX(none, "mout_sw_aclk266", sw_aclk266_p, SRC_TOP11, 20, 1), + MUX(none, "mout_sw_aclk166", sw_aclk166_p, SRC_TOP11, 24, 1), + MUX(none, "mout_sw_aclk333", sw_aclk333_p, SRC_TOP11, 28, 1), + + MUX(none, "mout_sw_aclk333_g2d", sw_aclk333_g2d_p, SRC_TOP12, 8, 1), + MUX(none, "mout_sw_aclk266_g2d", sw_aclk266_g2d_p, SRC_TOP12, 12, 1), + MUX(none, "mout_sw_aclk_g3d", sw_aclk_g3d_p, SRC_TOP12, 16, 1), + MUX(none, "mout_sw_aclk300_jpeg", sw_aclk300_jpeg_p, SRC_TOP12, 20, 1), + MUX(none, "mout_sw_aclk300_disp1", sw_aclk300_disp1_p, + SRC_TOP12, 24, 1), + MUX(none, "mout_sw_aclk300_gscl", sw_aclk300_gscl_p, SRC_TOP12, 28, 1), + + /* DISP1 Block */ + MUX(none, "mout_fimd1", group3_p, SRC_DISP10, 4, 1), + MUX(none, "mout_mipi1", group2_p, SRC_DISP10, 16, 3), + MUX(none, "mout_dp1", group2_p, SRC_DISP10, 20, 3), + MUX(none, "mout_pixel", group2_p, SRC_DISP10, 24, 3), + MUX(none, "mout_hdmi", hdmi_p, SRC_DISP10, 28, 1), + + /* MAU Block */ + MUX(none, "mout_maudio0", maudio0_p, SRC_MAU, 28, 3), + + /* FSYS Block */ + MUX(none, "mout_usbd301", group2_p, SRC_FSYS, 4, 3), + MUX(none, "mout_mmc0", group2_p, SRC_FSYS, 8, 3), + MUX(none, "mout_mmc1", group2_p, SRC_FSYS, 12, 3), + MUX(none, "mout_mmc2", group2_p, SRC_FSYS, 16, 3), + MUX(none, "mout_usbd300", group2_p, SRC_FSYS, 20, 3), + MUX(none, "mout_unipro", group2_p, SRC_FSYS, 24, 3), + + /* PERIC Block */ + MUX(none, "mout_uart0", group2_p, SRC_PERIC0, 4, 3), + MUX(none, "mout_uart1", group2_p, SRC_PERIC0, 8, 3), + MUX(none, "mout_uart2", group2_p, SRC_PERIC0, 12, 3), + MUX(none, "mout_uart3", group2_p, SRC_PERIC0, 16, 3), + MUX(none, "mout_pwm", group2_p, SRC_PERIC0, 24, 3), + MUX(none, "mout_spdif", spdif_p, SRC_PERIC0, 28, 3), + MUX(none, "mout_audio0", audio0_p, SRC_PERIC1, 8, 3), + MUX(none, "mout_audio1", audio1_p, SRC_PERIC1, 12, 3), + MUX(none, "mout_audio2", audio2_p, SRC_PERIC1, 16, 3), + MUX(none, "mout_spi0", group2_p, SRC_PERIC1, 20, 3), + MUX(none, "mout_spi1", group2_p, SRC_PERIC1, 24, 3), + MUX(none, "mout_spi2", group2_p, SRC_PERIC1, 28, 3), +}; + +struct samsung_div_clock exynos5420_div_clks[] __initdata = { + DIV(none, "div_arm", "mout_cpu", DIV_CPU0, 0, 3), + DIV(none, "sclk_apll", "mout_apll", DIV_CPU0, 24, 3), + DIV(none, "armclk2", "div_arm", DIV_CPU0, 28, 3), + DIV(none, "div_kfc", "mout_cpu_kfc", DIV_KFC0, 0, 3), + DIV(none, "sclk_kpll", "mout_kpll", DIV_KFC0, 24, 3), + + DIV(none, "dout_aclk400_mscl", "mout_aclk400_mscl", DIV_TOP0, 4, 3), + DIV(none, "dout_aclk200", "mout_aclk200", DIV_TOP0, 8, 3), + DIV(none, "dout_aclk200_fsys2", "mout_aclk200_fsys2", DIV_TOP0, 12, 3), + DIV(none, "dout_pclk200_fsys", "mout_pclk200_fsys", DIV_TOP0, 24, 3), + DIV(none, "dout_aclk200_fsys", "mout_aclk200_fsys", DIV_TOP0, 28, 3), + + DIV(none, "dout_aclk333_432_gscl", "mout_aclk333_432_gscl", + DIV_TOP1, 0, 3), + DIV(none, "dout_aclk66", "mout_aclk66", DIV_TOP1, 8, 6), + DIV(none, "dout_aclk266", "mout_aclk266", DIV_TOP1, 20, 3), + DIV(none, "dout_aclk166", "mout_aclk166", DIV_TOP1, 24, 3), + DIV(none, "dout_aclk333", "mout_aclk333", DIV_TOP1, 28, 3), + + DIV(none, "dout_aclk333_g2d", "mout_aclk333_g2d", DIV_TOP2, 8, 3), + DIV(none, "dout_aclk266_g2d", "mout_aclk266_g2d", DIV_TOP2, 12, 3), + DIV(none, "dout_aclk_g3d", "mout_aclk_g3d", DIV_TOP2, 16, 3), + DIV(none, "dout_aclk300_jpeg", "mout_aclk300_jpeg", DIV_TOP2, 20, 3), + DIV_A(none, "dout_aclk300_disp1", "mout_aclk300_disp1", + DIV_TOP2, 24, 3, "aclk300_disp1"), + DIV(none, "dout_aclk300_gscl", "mout_aclk300_gscl", DIV_TOP2, 28, 3), + + /* DISP1 Block */ + DIV(none, "dout_fimd1", "mout_fimd1", DIV_DISP10, 0, 4), + DIV(none, "dout_mipi1", "mout_mipi1", DIV_DISP10, 16, 8), + DIV(none, "dout_dp1", "mout_dp1", DIV_DISP10, 24, 4), + DIV(none, "dout_hdmi_pixel", "mout_pixel", DIV_DISP10, 28, 4), + + /* Audio Block */ + DIV(none, "dout_maudio0", "mout_maudio0", DIV_MAU, 20, 4), + DIV(none, "dout_maupcm0", "dout_maudio0", DIV_MAU, 24, 8), + + /* USB3.0 */ + DIV(none, "dout_usbphy301", "mout_usbd301", DIV_FSYS0, 12, 4), + DIV(none, "dout_usbphy300", "mout_usbd300", DIV_FSYS0, 16, 4), + DIV(none, "dout_usbd301", "mout_usbd301", DIV_FSYS0, 20, 4), + DIV(none, "dout_usbd300", "mout_usbd300", DIV_FSYS0, 24, 4), + + /* MMC */ + DIV(none, "dout_mmc0", "mout_mmc0", DIV_FSYS1, 0, 10), + DIV(none, "dout_mmc1", "mout_mmc1", DIV_FSYS1, 10, 10), + DIV(none, "dout_mmc2", "mout_mmc2", DIV_FSYS1, 20, 10), + + DIV(none, "dout_unipro", "mout_unipro", DIV_FSYS2, 24, 8), + + /* UART and PWM */ + DIV(none, "dout_uart0", "mout_uart0", DIV_PERIC0, 8, 4), + DIV(none, "dout_uart1", "mout_uart1", DIV_PERIC0, 12, 4), + DIV(none, "dout_uart2", "mout_uart2", DIV_PERIC0, 16, 4), + DIV(none, "dout_uart3", "mout_uart3", DIV_PERIC0, 20, 4), + DIV(none, "dout_pwm", "mout_pwm", DIV_PERIC0, 28, 4), + + /* SPI */ + DIV(none, "dout_spi0", "mout_spi0", DIV_PERIC1, 20, 4), + DIV(none, "dout_spi1", "mout_spi1", DIV_PERIC1, 24, 4), + DIV(none, "dout_spi2", "mout_spi2", DIV_PERIC1, 28, 4), + + /* PCM */ + DIV(none, "dout_pcm1", "dout_audio1", DIV_PERIC2, 16, 8), + DIV(none, "dout_pcm2", "dout_audio2", DIV_PERIC2, 24, 8), + + /* Audio - I2S */ + DIV(none, "dout_i2s1", "dout_audio1", DIV_PERIC3, 6, 6), + DIV(none, "dout_i2s2", "dout_audio2", DIV_PERIC3, 12, 6), + DIV(none, "dout_audio0", "mout_audio0", DIV_PERIC3, 20, 4), + DIV(none, "dout_audio1", "mout_audio1", DIV_PERIC3, 24, 4), + DIV(none, "dout_audio2", "mout_audio2", DIV_PERIC3, 28, 4), + + /* SPI Pre-Ratio */ + DIV(none, "dout_pre_spi0", "dout_spi0", DIV_PERIC4, 8, 8), + DIV(none, "dout_pre_spi1", "dout_spi1", DIV_PERIC4, 16, 8), + DIV(none, "dout_pre_spi2", "dout_spi2", DIV_PERIC4, 24, 8), +}; + +struct samsung_gate_clock exynos5420_gate_clks[] __initdata = { + /* TODO: Re-verify the CG bits for all the gate clocks */ + GATE_A(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", + GATE_BUS_FSYS0, 10, CLK_IGNORE_UNUSED, 0), + + GATE(0, "aclk333_g2d", "mout_user_aclk333_g2d", + GATE_BUS_TOP, 0, CLK_IGNORE_UNUSED, 0), + GATE(0, "aclk266_g2d", "mout_user_aclk266_g2d", + 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, "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, "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, "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), + + /* sclk */ + GATE(sclk_uart0, "sclk_uart0", "dout_uart0", + GATE_TOP_SCLK_PERIC, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart1, "sclk_uart1", "dout_uart1", + GATE_TOP_SCLK_PERIC, 1, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart2, "sclk_uart2", "dout_uart2", + GATE_TOP_SCLK_PERIC, 2, CLK_SET_RATE_PARENT, 0), + GATE(sclk_uart3, "sclk_uart3", "dout_uart3", + GATE_TOP_SCLK_PERIC, 3, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spi0, "sclk_spi0", "dout_pre_spi0", + GATE_TOP_SCLK_PERIC, 6, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spi1, "sclk_spi1", "dout_pre_spi1", + GATE_TOP_SCLK_PERIC, 7, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spi2, "sclk_spi2", "dout_pre_spi2", + GATE_TOP_SCLK_PERIC, 8, CLK_SET_RATE_PARENT, 0), + GATE(sclk_spdif, "sclk_spdif", "mout_spdif", + GATE_TOP_SCLK_PERIC, 9, CLK_SET_RATE_PARENT, 0), + GATE(sclk_pwm, "sclk_pwm", "dout_pwm", + GATE_TOP_SCLK_PERIC, 11, CLK_SET_RATE_PARENT, 0), + GATE(sclk_pcm1, "sclk_pcm1", "dout_pcm1", + GATE_TOP_SCLK_PERIC, 15, CLK_SET_RATE_PARENT, 0), + GATE(sclk_pcm2, "sclk_pcm2", "dout_pcm2", + GATE_TOP_SCLK_PERIC, 16, CLK_SET_RATE_PARENT, 0), + GATE(sclk_i2s1, "sclk_i2s1", "dout_i2s1", + GATE_TOP_SCLK_PERIC, 17, CLK_SET_RATE_PARENT, 0), + GATE(sclk_i2s2, "sclk_i2s2", "dout_i2s2", + GATE_TOP_SCLK_PERIC, 18, CLK_SET_RATE_PARENT, 0), + + GATE(sclk_mmc0, "sclk_mmc0", "dout_mmc0", + GATE_TOP_SCLK_FSYS, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mmc1, "sclk_mmc1", "dout_mmc1", + GATE_TOP_SCLK_FSYS, 1, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mmc2, "sclk_mmc2", "dout_mmc2", + GATE_TOP_SCLK_FSYS, 2, CLK_SET_RATE_PARENT, 0), + GATE(sclk_usbphy301, "sclk_usbphy301", "dout_usbphy301", + GATE_TOP_SCLK_FSYS, 7, CLK_SET_RATE_PARENT, 0), + GATE(sclk_usbphy300, "sclk_usbphy300", "dout_usbphy300", + GATE_TOP_SCLK_FSYS, 8, CLK_SET_RATE_PARENT, 0), + GATE(sclk_usbd300, "sclk_usbd300", "dout_usbd300", + GATE_TOP_SCLK_FSYS, 9, CLK_SET_RATE_PARENT, 0), + GATE(sclk_usbd301, "sclk_usbd301", "dout_usbd301", + GATE_TOP_SCLK_FSYS, 10, CLK_SET_RATE_PARENT, 0), + + GATE(sclk_usbd301, "sclk_unipro", "dout_unipro", + SRC_MASK_FSYS, 24, CLK_SET_RATE_PARENT, 0), + + GATE(sclk_gscl_wa, "sclk_gscl_wa", "aclK333_432_gscl", + GATE_TOP_SCLK_GSCL, 6, CLK_SET_RATE_PARENT, 0), + GATE(sclk_gscl_wb, "sclk_gscl_wb", "aclk333_432_gscl", + GATE_TOP_SCLK_GSCL, 7, CLK_SET_RATE_PARENT, 0), + + /* Display */ + GATE(sclk_fimd1, "sclk_fimd1", "dout_fimd1", + GATE_TOP_SCLK_DISP1, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_mipi1, "sclk_mipi1", "dout_mipi1", + GATE_TOP_SCLK_DISP1, 3, CLK_SET_RATE_PARENT, 0), + GATE(sclk_hdmi, "sclk_hdmi", "mout_hdmi", + GATE_TOP_SCLK_DISP1, 9, CLK_SET_RATE_PARENT, 0), + GATE(sclk_pixel, "sclk_pixel", "dout_hdmi_pixel", + GATE_TOP_SCLK_DISP1, 10, CLK_SET_RATE_PARENT, 0), + GATE(sclk_dp1, "sclk_dp1", "dout_dp1", + GATE_TOP_SCLK_DISP1, 20, CLK_SET_RATE_PARENT, 0), + + /* Maudio Block */ + GATE(sclk_maudio0, "sclk_maudio0", "dout_maudio0", + GATE_TOP_SCLK_MAU, 0, CLK_SET_RATE_PARENT, 0), + GATE(sclk_maupcm0, "sclk_maupcm0", "dout_maupcm0", + GATE_TOP_SCLK_MAU, 1, CLK_SET_RATE_PARENT, 0), + /* FSYS */ + GATE(tsi, "tsi", "aclk200_fsys", GATE_BUS_FSYS0, 0, 0, 0), + GATE(pdma0, "pdma0", "aclk200_fsys", GATE_BUS_FSYS0, 1, 0, 0), + GATE(pdma1, "pdma1", "aclk200_fsys", GATE_BUS_FSYS0, 2, 0, 0), + GATE(ufs, "ufs", "aclk200_fsys2", GATE_BUS_FSYS0, 3, 0, 0), + GATE(rtic, "rtic", "aclk200_fsys", GATE_BUS_FSYS0, 5, 0, 0), + GATE(mmc0, "mmc0", "aclk200_fsys2", GATE_BUS_FSYS0, 12, 0, 0), + GATE(mmc1, "mmc1", "aclk200_fsys2", GATE_BUS_FSYS0, 13, 0, 0), + GATE(mmc2, "mmc2", "aclk200_fsys2", GATE_BUS_FSYS0, 14, 0, 0), + GATE(sromc, "sromc", "aclk200_fsys2", + GATE_BUS_FSYS0, 19, CLK_IGNORE_UNUSED, 0), + GATE(usbh20, "usbh20", "aclk200_fsys", GATE_BUS_FSYS0, 20, 0, 0), + GATE(usbd300, "usbd300", "aclk200_fsys", GATE_BUS_FSYS0, 21, 0, 0), + GATE(usbd301, "usbd301", "aclk200_fsys", GATE_BUS_FSYS0, 28, 0, 0), + + /* UART */ + GATE(uart0, "uart0", "aclk66_peric", GATE_BUS_PERIC, 4, 0, 0), + GATE(uart1, "uart1", "aclk66_peric", GATE_BUS_PERIC, 5, 0, 0), + GATE_A(uart2, "uart2", "aclk66_peric", + GATE_BUS_PERIC, 6, CLK_IGNORE_UNUSED, 0, "uart2"), + GATE(uart3, "uart3", "aclk66_peric", GATE_BUS_PERIC, 7, 0, 0), + /* I2C */ + GATE(i2c0, "i2c0", "aclk66_peric", GATE_BUS_PERIC, 9, 0, 0), + GATE(i2c1, "i2c1", "aclk66_peric", GATE_BUS_PERIC, 10, 0, 0), + GATE(i2c2, "i2c2", "aclk66_peric", GATE_BUS_PERIC, 11, 0, 0), + GATE(i2c3, "i2c3", "aclk66_peric", GATE_BUS_PERIC, 12, 0, 0), + GATE(i2c4, "i2c4", "aclk66_peric", GATE_BUS_PERIC, 13, 0, 0), + GATE(i2c5, "i2c5", "aclk66_peric", GATE_BUS_PERIC, 14, 0, 0), + GATE(i2c6, "i2c6", "aclk66_peric", GATE_BUS_PERIC, 15, 0, 0), + GATE(i2c7, "i2c7", "aclk66_peric", GATE_BUS_PERIC, 16, 0, 0), + GATE(i2c_hdmi, "i2c_hdmi", "aclk66_peric", GATE_BUS_PERIC, 17, 0, 0), + GATE(tsadc, "tsadc", "aclk66_peric", GATE_BUS_PERIC, 18, 0, 0), + /* SPI */ + GATE(spi0, "spi0", "aclk66_peric", GATE_BUS_PERIC, 19, 0, 0), + GATE(spi1, "spi1", "aclk66_peric", GATE_BUS_PERIC, 20, 0, 0), + GATE(spi2, "spi2", "aclk66_peric", GATE_BUS_PERIC, 21, 0, 0), + GATE(keyif, "keyif", "aclk66_peric", GATE_BUS_PERIC, 22, 0, 0), + /* I2S */ + GATE(i2s1, "i2s1", "aclk66_peric", GATE_BUS_PERIC, 23, 0, 0), + GATE(i2s2, "i2s2", "aclk66_peric", GATE_BUS_PERIC, 24, 0, 0), + /* PCM */ + GATE(pcm1, "pcm1", "aclk66_peric", GATE_BUS_PERIC, 25, 0, 0), + GATE(pcm2, "pcm2", "aclk66_peric", GATE_BUS_PERIC, 26, 0, 0), + /* PWM */ + GATE(pwm, "pwm", "aclk66_peric", GATE_BUS_PERIC, 27, 0, 0), + /* SPDIF */ + GATE(spdif, "spdif", "aclk66_peric", GATE_BUS_PERIC, 29, 0, 0), + + GATE(i2c8, "i2c8", "aclk66_peric", GATE_BUS_PERIC1, 0, 0, 0), + GATE(i2c9, "i2c9", "aclk66_peric", GATE_BUS_PERIC1, 1, 0, 0), + GATE(i2c10, "i2c10", "aclk66_peric", GATE_BUS_PERIC1, 2, 0, 0), + + GATE(chipid, "chipid", "aclk66_psgen", + GATE_BUS_PERIS0, 12, CLK_IGNORE_UNUSED, 0), + GATE(sysreg, "sysreg", "aclk66_psgen", + GATE_BUS_PERIS0, 13, CLK_IGNORE_UNUSED, 0), + GATE(tzp