From 520f7bd73354f003a9a59937b28e4903d985c420 Mon Sep 17 00:00:00 2001 From: Rob Herring Date: Thu, 27 Dec 2012 13:10:24 -0600 Subject: irqchip: Move ARM gic.h to include/linux/irqchip/arm-gic.h Now that we have GIC moved to drivers/irqchip and all GIC DT init for platforms using irqchip_init, move gic.h and update the remaining includes. Signed-off-by: Rob Herring Cc: Thomas Gleixner Cc: Russell King Cc: Anton Vorontsov Cc: Kukjin Kim Cc: Sascha Hauer Cc: David Brown Cc: Daniel Walker Cc: Bryan Huntsman Cc: Tony Lindgren Cc: Paul Mundt Cc: Magnus Damm Cc: Viresh Kumar Cc: Shiraz Hashim Cc: Stephen Warren Cc: Srinidhi Kasagar Cc: Linus Walleij Cc: Samuel Ortiz --- drivers/mfd/db8500-prcmu.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/mfd') diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index dc8826d8d69d..13f4ccf2612d 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -26,13 +26,13 @@ #include #include #include +#include #include #include #include #include #include #include -#include #include #include #include -- cgit v1.2.3 From 7a4f26097d389c16c9956bc03b81532698d97d64 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Wed, 19 Sep 2012 19:31:19 +0200 Subject: ARM: ux500: de-globalize This removes the file from the global kernel include scope, making it a pure mach-ux500 detail. All ASIC specifics needed by drivers shall henceforth be passed from either platform data or the device tree. Cc: Rafael J. Wysocki Acked-by: Samuel Ortiz Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500-uib.c | 1 + arch/arm/mach-ux500/cache-l2x0.c | 3 +- arch/arm/mach-ux500/cpu-db8500.c | 2 + arch/arm/mach-ux500/cpu.c | 1 + arch/arm/mach-ux500/id.c | 2 + arch/arm/mach-ux500/id.h | 144 ++++++++++++++++++++++++++++ arch/arm/mach-ux500/include/mach/hardware.h | 1 - arch/arm/mach-ux500/include/mach/id.h | 144 ---------------------------- arch/arm/mach-ux500/platsmp.c | 3 + arch/arm/mach-ux500/timer.c | 2 + drivers/cpufreq/db8500-cpufreq.c | 3 - drivers/mfd/db8500-prcmu.c | 17 ++-- include/linux/mfd/dbx500-prcmu.h | 2 - 13 files changed, 163 insertions(+), 162 deletions(-) create mode 100644 arch/arm/mach-ux500/id.h delete mode 100644 arch/arm/mach-ux500/include/mach/id.h (limited to 'drivers/mfd') diff --git a/arch/arm/mach-ux500/board-mop500-uib.c b/arch/arm/mach-ux500/board-mop500-uib.c index 1f47d962e3a1..7037d3687e9f 100644 --- a/arch/arm/mach-ux500/board-mop500-uib.c +++ b/arch/arm/mach-ux500/board-mop500-uib.c @@ -13,6 +13,7 @@ #include #include "board-mop500.h" +#include "id.h" enum mop500_uib { STUIB, diff --git a/arch/arm/mach-ux500/cache-l2x0.c b/arch/arm/mach-ux500/cache-l2x0.c index 75d5b512a3d5..1c1609da76ce 100644 --- a/arch/arm/mach-ux500/cache-l2x0.c +++ b/arch/arm/mach-ux500/cache-l2x0.c @@ -10,7 +10,8 @@ #include #include #include -#include + +#include "id.h" static void __iomem *l2x0_base; diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index db0bb75e2c76..09c3fee726d4 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -37,7 +37,9 @@ #include "devices-db8500.h" #include "ste-dma40-db8500.h" + #include "board-mop500.h" +#include "id.h" /* minimum static i/o mapping required to boot U8500 platforms */ static struct map_desc u8500_uart_io_desc[] __initdata = { diff --git a/arch/arm/mach-ux500/cpu.c b/arch/arm/mach-ux500/cpu.c index 721e7b4275f3..14b7d686f527 100644 --- a/arch/arm/mach-ux500/cpu.c +++ b/arch/arm/mach-ux500/cpu.c @@ -27,6 +27,7 @@ #include #include "board-mop500.h" +#include "id.h" void __iomem *_PRCMU_BASE; diff --git a/arch/arm/mach-ux500/id.c b/arch/arm/mach-ux500/id.c index d1579920139f..9f951842e1e5 100644 --- a/arch/arm/mach-ux500/id.c +++ b/arch/arm/mach-ux500/id.c @@ -17,6 +17,8 @@ #include #include +#include "id.h" + struct dbx500_asic_id dbx500_id; static unsigned int ux500_read_asicid(phys_addr_t addr) diff --git a/arch/arm/mach-ux500/id.h b/arch/arm/mach-ux500/id.h new file mode 100644 index 000000000000..bcc58a8cccbc --- /dev/null +++ b/arch/arm/mach-ux500/id.h @@ -0,0 +1,144 @@ +/* + * Copyright (C) ST-Ericsson SA 2010 + * + * Author: Rabin Vincent for ST-Ericsson + * License terms: GNU General Public License (GPL) version 2 + */ + +#ifndef __MACH_UX500_ID +#define __MACH_UX500_ID + +/** + * struct dbx500_asic_id - fields of the ASIC ID + * @process: the manufacturing process, 0x40 is 40 nm 0x00 is "standard" + * @partnumber: hithereto 0x8500 for DB8500 + * @revision: version code in the series + */ +struct dbx500_asic_id { + u16 partnumber; + u8 revision; + u8 process; +}; + +extern struct dbx500_asic_id dbx500_id; + +static inline unsigned int __attribute_const__ dbx500_partnumber(void) +{ + return dbx500_id.partnumber; +} + +static inline unsigned int __attribute_const__ dbx500_revision(void) +{ + return dbx500_id.revision; +} + +/* + * SOCs + */ + +static inline bool __attribute_const__ cpu_is_u8500(void) +{ + return dbx500_partnumber() == 0x8500; +} + +static inline bool __attribute_const__ cpu_is_u8520(void) +{ + return dbx500_partnumber() == 0x8520; +} + +static inline bool cpu_is_u8500_family(void) +{ + return cpu_is_u8500() || cpu_is_u8520(); +} + +static inline bool __attribute_const__ cpu_is_u9540(void) +{ + return dbx500_partnumber() == 0x9540; +} + +static inline bool __attribute_const__ cpu_is_u8540(void) +{ + return dbx500_partnumber() == 0x8540; +} + +static inline bool __attribute_const__ cpu_is_u8580(void) +{ + return dbx500_partnumber() == 0x8580; +} + +static inline bool cpu_is_ux540_family(void) +{ + return cpu_is_u9540() || cpu_is_u8540() || cpu_is_u8580(); +} + +/* + * 8500 revisions + */ + +static inline bool __attribute_const__ cpu_is_u8500ed(void) +{ + return cpu_is_u8500() && dbx500_revision() == 0x00; +} + +static inline bool __attribute_const__ cpu_is_u8500v1(void) +{ + return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0; +} + +static inline bool __attribute_const__ cpu_is_u8500v10(void) +{ + return cpu_is_u8500() && dbx500_revision() == 0xA0; +} + +static inline bool __attribute_const__ cpu_is_u8500v11(void) +{ + return cpu_is_u8500() && dbx500_revision() == 0xA1; +} + +static inline bool __attribute_const__ cpu_is_u8500v2(void) +{ + return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0); +} + +static inline bool cpu_is_u8500v20(void) +{ + return cpu_is_u8500() && (dbx500_revision() == 0xB0); +} + +static inline bool cpu_is_u8500v21(void) +{ + return cpu_is_u8500() && (dbx500_revision() == 0xB1); +} + +static inline bool cpu_is_u8500v22(void) +{ + return cpu_is_u8500() && (dbx500_revision() == 0xB2); +} + +static inline bool cpu_is_u8500v20_or_later(void) +{ + return (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11()); +} + +/* + * 8540 revisions + */ + +static inline bool __attribute_const__ cpu_is_u8540v10(void) +{ + return cpu_is_u8540() && dbx500_revision() == 0xA0; +} + +static inline bool __attribute_const__ cpu_is_u8580v10(void) +{ + return cpu_is_u8580() && dbx500_revision() == 0xA0; +} + +static inline bool ux500_is_svp(void) +{ + return false; +} + +#define ux500_unknown_soc() BUG() + +#endif diff --git a/arch/arm/mach-ux500/include/mach/hardware.h b/arch/arm/mach-ux500/include/mach/hardware.h index 28d16e744bfd..5201ddace503 100644 --- a/arch/arm/mach-ux500/include/mach/hardware.h +++ b/arch/arm/mach-ux500/include/mach/hardware.h @@ -39,7 +39,6 @@ #ifndef __ASSEMBLY__ -#include extern void __iomem *_PRCMU_BASE; #define ARRAY_AND_SIZE(x) (x), ARRAY_SIZE(x) diff --git a/arch/arm/mach-ux500/include/mach/id.h b/arch/arm/mach-ux500/include/mach/id.h deleted file mode 100644 index bcc58a8cccbc..000000000000 --- a/arch/arm/mach-ux500/include/mach/id.h +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (C) ST-Ericsson SA 2010 - * - * Author: Rabin Vincent for ST-Ericsson - * License terms: GNU General Public License (GPL) version 2 - */ - -#ifndef __MACH_UX500_ID -#define __MACH_UX500_ID - -/** - * struct dbx500_asic_id - fields of the ASIC ID - * @process: the manufacturing process, 0x40 is 40 nm 0x00 is "standard" - * @partnumber: hithereto 0x8500 for DB8500 - * @revision: version code in the series - */ -struct dbx500_asic_id { - u16 partnumber; - u8 revision; - u8 process; -}; - -extern struct dbx500_asic_id dbx500_id; - -static inline unsigned int __attribute_const__ dbx500_partnumber(void) -{ - return dbx500_id.partnumber; -} - -static inline unsigned int __attribute_const__ dbx500_revision(void) -{ - return dbx500_id.revision; -} - -/* - * SOCs - */ - -static inline bool __attribute_const__ cpu_is_u8500(void) -{ - return dbx500_partnumber() == 0x8500; -} - -static inline bool __attribute_const__ cpu_is_u8520(void) -{ - return dbx500_partnumber() == 0x8520; -} - -static inline bool cpu_is_u8500_family(void) -{ - return cpu_is_u8500() || cpu_is_u8520(); -} - -static inline bool __attribute_const__ cpu_is_u9540(void) -{ - return dbx500_partnumber() == 0x9540; -} - -static inline bool __attribute_const__ cpu_is_u8540(void) -{ - return dbx500_partnumber() == 0x8540; -} - -static inline bool __attribute_const__ cpu_is_u8580(void) -{ - return dbx500_partnumber() == 0x8580; -} - -static inline bool cpu_is_ux540_family(void) -{ - return cpu_is_u9540() || cpu_is_u8540() || cpu_is_u8580(); -} - -/* - * 8500 revisions - */ - -static inline bool __attribute_const__ cpu_is_u8500ed(void) -{ - return cpu_is_u8500() && dbx500_revision() == 0x00; -} - -static inline bool __attribute_const__ cpu_is_u8500v1(void) -{ - return cpu_is_u8500() && (dbx500_revision() & 0xf0) == 0xA0; -} - -static inline bool __attribute_const__ cpu_is_u8500v10(void) -{ - return cpu_is_u8500() && dbx500_revision() == 0xA0; -} - -static inline bool __attribute_const__ cpu_is_u8500v11(void) -{ - return cpu_is_u8500() && dbx500_revision() == 0xA1; -} - -static inline bool __attribute_const__ cpu_is_u8500v2(void) -{ - return cpu_is_u8500() && ((dbx500_revision() & 0xf0) == 0xB0); -} - -static inline bool cpu_is_u8500v20(void) -{ - return cpu_is_u8500() && (dbx500_revision() == 0xB0); -} - -static inline bool cpu_is_u8500v21(void) -{ - return cpu_is_u8500() && (dbx500_revision() == 0xB1); -} - -static inline bool cpu_is_u8500v22(void) -{ - return cpu_is_u8500() && (dbx500_revision() == 0xB2); -} - -static inline bool cpu_is_u8500v20_or_later(void) -{ - return (cpu_is_u8500() && !cpu_is_u8500v10() && !cpu_is_u8500v11()); -} - -/* - * 8540 revisions - */ - -static inline bool __attribute_const__ cpu_is_u8540v10(void) -{ - return cpu_is_u8540() && dbx500_revision() == 0xA0; -} - -static inline bool __attribute_const__ cpu_is_u8580v10(void) -{ - return cpu_is_u8580() && dbx500_revision() == 0xA0; -} - -static inline bool ux500_is_svp(void) -{ - return false; -} - -#define ux500_unknown_soc() BUG() - -#endif diff --git a/arch/arm/mach-ux500/platsmp.c b/arch/arm/mach-ux500/platsmp.c index 3db7782f3afb..1a92e071bd61 100644 --- a/arch/arm/mach-ux500/platsmp.c +++ b/arch/arm/mach-ux500/platsmp.c @@ -21,9 +21,12 @@ #include #include #include + #include #include +#include "id.h" + /* This is called from headsmp.S to wakeup the secondary core */ extern void u8500_secondary_startup(void); diff --git a/arch/arm/mach-ux500/timer.c b/arch/arm/mach-ux500/timer.c index 875309acb022..c685ad1a2099 100644 --- a/arch/arm/mach-ux500/timer.c +++ b/arch/arm/mach-ux500/timer.c @@ -17,6 +17,8 @@ #include #include +#include "id.h" + #ifdef CONFIG_HAVE_ARM_TWD static DEFINE_TWD_LOCAL_TIMER(u8500_twd_local_timer, U8500_TWD_BASE, IRQ_LOCALTIMER); diff --git a/drivers/cpufreq/db8500-cpufreq.c b/drivers/cpufreq/db8500-cpufreq.c index 4f154bc0ebe4..523c9403bfce 100644 --- a/drivers/cpufreq/db8500-cpufreq.c +++ b/drivers/cpufreq/db8500-cpufreq.c @@ -167,9 +167,6 @@ static struct platform_driver db8500_cpufreq_plat_driver = { static int __init db8500_cpufreq_register(void) { - if (!cpu_is_u8500_family()) - return -ENODEV; - pr_info("cpufreq for DB8500 started\n"); return platform_driver_register(&db8500_cpufreq_plat_driver); } diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index dc8826d8d69d..67d8b25d183e 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -36,7 +36,6 @@ #include #include #include -#include #include "dbx500-prcmu-regs.h" /* Offset for the firmware version within the TCPM */ @@ -216,10 +215,8 @@ #define PRCM_REQ_MB5_I2C_HW_BITS (PRCM_REQ_MB5 + 0x1) #define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 0x2) #define PRCM_REQ_MB5_I2C_VAL (PRCM_REQ_MB5 + 0x3) -#define PRCMU_I2C_WRITE(slave) \ - (((slave) << 1) | (cpu_is_u8500v2() ? BIT(6) : 0)) -#define PRCMU_I2C_READ(slave) \ - (((slave) << 1) | BIT(0) | (cpu_is_u8500v2() ? BIT(6) : 0)) +#define PRCMU_I2C_WRITE(slave) (((slave) << 1) | BIT(6)) +#define PRCMU_I2C_READ(slave) (((slave) << 1) | BIT(0) | BIT(6)) #define PRCMU_I2C_STOP_EN BIT(3) /* Mailbox 5 ACKs */ @@ -1049,12 +1046,13 @@ int db8500_prcmu_get_ddr_opp(void) * * This function sets the operating point of the DDR. */ +static bool enable_set_ddr_opp; int db8500_prcmu_set_ddr_opp(u8 opp) { if (opp < DDR_100_OPP || opp > DDR_25_OPP) return -EINVAL; /* Changing the DDR OPP can hang the hardware pre-v21 */ - if (cpu_is_u8500v20_or_later() && !cpu_is_u8500v20()) + if (enable_set_ddr_opp) writeb(opp, PRCM_DDR_SUBSYS_APE_MINBW); return 0; @@ -2790,6 +2788,7 @@ void __init db8500_prcmu_early_init(void) pr_err("prcmu: Unsupported chip version\n"); BUG(); } + tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); spin_lock_init(&mb0_transfer.lock); spin_lock_init(&mb0_transfer.dbb_irqs_lock); @@ -3104,9 +3103,6 @@ static int db8500_prcmu_probe(struct platform_device *pdev) struct device_node *np = pdev->dev.of_node; int irq = 0, err = 0, i; - if (ux500_is_svp()) - return -ENODEV; - init_prcm_registers(); /* Clean up the mailbox interrupts after pre-kernel code. */ @@ -3135,8 +3131,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev) } } - if (cpu_is_u8500v20_or_later()) - prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); + prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET); db8500_prcmu_update_cpufreq(); diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index ac601470962c..155280642583 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -218,8 +218,6 @@ enum ddr_pwrst { #if defined(CONFIG_UX500_SOC_DB8500) -#include - static inline void __init prcmu_early_init(void) { return db8500_prcmu_early_init(); -- cgit v1.2.3 From 05ec260edecaf3dc214cff49d43b1ad9b2cbb710 Mon Sep 17 00:00:00 2001 From: Linus Walleij Date: Thu, 7 Feb 2013 10:17:31 +0100 Subject: mfd: db8500-prcmu: update resource passing When trying to get rid of the cross-includes of from different drivers, so we can localize ASIC/CPU detection to the mach-ux500 folder, we run into the way the PRCMU handles base addresses and firmware detection. This patch updates the firmware version detection to pass the required information as platform data instead of relying on cpu_is_* macros. Now the PRCMU base address, the secondary TCDM area, the TCPM area and the IRQ are passed as resources instead of being grabbed from files. Incidentally this also removes part of the reliance on . Further it updates the firmware version detection, since the location of the firmware ID bytes in the designated memory are is now passed from the platform data instead. There is no reason not to include the nice split-off of a struct to hold the firmware information and a separate function to populate it. The patch actually rids the need to use the external db8500_prcmu_early_init call at all, but I'm keepin back that removal as I don't want the patch to be too big. Cc: arm@kernel.org Cc: Michel Jaoen Cc: Lee Jones Acked-by: Samuel Ortiz Acked-by: Loic Pallardy Acked-by: Fabio Baltieri Signed-off-by: Linus Walleij --- arch/arm/mach-ux500/board-mop500.c | 5 +- arch/arm/mach-ux500/cpu-db8500.c | 7 +- arch/arm/mach-ux500/devices-db8500.c | 44 +++++++++++++ arch/arm/mach-ux500/devices-db8500.h | 5 ++ drivers/mfd/db8500-prcmu.c | 122 +++++++++++++++++++++++------------ include/linux/mfd/db8500-prcmu.h | 14 ---- include/linux/mfd/dbx500-prcmu.h | 46 +++++++++++++ 7 files changed, 180 insertions(+), 63 deletions(-) (limited to 'drivers/mfd') diff --git a/arch/arm/mach-ux500/board-mop500.c b/arch/arm/mach-ux500/board-mop500.c index d453522edb0d..6cb1407961e0 100644 --- a/arch/arm/mach-ux500/board-mop500.c +++ b/arch/arm/mach-ux500/board-mop500.c @@ -215,7 +215,7 @@ static struct platform_device snowball_sbnet_dev = { }, }; -static struct ab8500_platform_data ab8500_platdata = { +struct ab8500_platform_data ab8500_platdata = { .irq_base = MOP500_AB8500_IRQ_BASE, .regulator_reg_init = ab8500_regulator_reg_init, .num_regulator_reg_init = ARRAY_SIZE(ab8500_regulator_reg_init), @@ -651,6 +651,7 @@ static void __init mop500_init_machine(void) int i2c0_devs; int i; + platform_device_register(&db8500_prcmu_device); mop500_gpio_keys[0].gpio = GPIO_PROX_SENSOR; mop500_pinmaps_init(); @@ -685,6 +686,7 @@ static void __init snowball_init_machine(void) struct device *parent = NULL; int i; + platform_device_register(&db8500_prcmu_device); snowball_pinmaps_init(); parent = u8500_init_devices(&ab8500_platdata); @@ -710,6 +712,7 @@ static void __init hrefv60_init_machine(void) int i2c0_devs; int i; + platform_device_register(&db8500_prcmu_device); /* * The HREFv60 board removed a GPIO expander and routed * all these GPIO pins to the internal GPIO controller diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c index 09c3fee726d4..8501970641bc 100644 --- a/arch/arm/mach-ux500/cpu-db8500.c +++ b/arch/arm/mach-ux500/cpu-db8500.c @@ -139,14 +139,9 @@ static struct platform_device db8500_pmu_device = { .dev.platform_data = &db8500_pmu_platdata, }; -static struct platform_device db8500_prcmu_device = { - .name = "db8500-prcmu", -}; - static struct platform_device *platform_devs[] __initdata = { &u8500_dma40_device, &db8500_pmu_device, - &db8500_prcmu_device, }; static resource_size_t __initdata db8500_gpio_base[] = { @@ -286,6 +281,8 @@ static struct of_dev_auxdata u8500_auxdata_lookup[] __initdata = { OF_DEV_AUXDATA("st,nomadik-i2c", 0x80128000, "nmk-i2c.2", NULL), OF_DEV_AUXDATA("st,nomadik-i2c", 0x80110000, "nmk-i2c.3", NULL), OF_DEV_AUXDATA("st,nomadik-i2c", 0x8012a000, "nmk-i2c.4", NULL), + OF_DEV_AUXDATA("stericsson,db8500-prcmu", 0x80157000, "db8500-prcmu", + &db8500_prcmu_pdata), /* Requires device name bindings. */ OF_DEV_AUXDATA("stericsson,nmk_pinctrl", 0, "pinctrl-db8500", NULL), /* Requires clock name and DMA bindings. */ diff --git a/arch/arm/mach-ux500/devices-db8500.c b/arch/arm/mach-ux500/devices-db8500.c index 318d49020894..f3d9419f75d3 100644 --- a/arch/arm/mach-ux500/devices-db8500.c +++ b/arch/arm/mach-ux500/devices-db8500.c @@ -13,11 +13,13 @@ #include #include #include +#include #include #include #include +#include "devices-db8500.h" #include "ste-dma40-db8500.h" static struct resource dma40_resources[] = { @@ -194,3 +196,45 @@ struct platform_device u8500_ske_keypad_device = { .num_resources = ARRAY_SIZE(keypad_resources), .resource = keypad_resources, }; + +struct prcmu_pdata db8500_prcmu_pdata = { + .ab_platdata = &ab8500_platdata, + .version_offset = DB8500_PRCMU_FW_VERSION_OFFSET, + .legacy_offset = DB8500_PRCMU_LEGACY_OFFSET, +}; + +static struct resource db8500_prcmu_res[] = { + { + .name = "prcmu", + .start = U8500_PRCMU_BASE, + .end = U8500_PRCMU_BASE + SZ_8K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "prcmu-tcdm", + .start = U8500_PRCMU_TCDM_BASE, + .end = U8500_PRCMU_TCDM_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, + { + .name = "irq", + .start = IRQ_DB8500_PRCMU1, + .end = IRQ_DB8500_PRCMU1, + .flags = IORESOURCE_IRQ, + }, + { + .name = "prcmu-tcpm", + .start = U8500_PRCMU_TCPM_BASE, + .end = U8500_PRCMU_TCPM_BASE + SZ_4K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +struct platform_device db8500_prcmu_device = { + .name = "db8500-prcmu", + .resource = db8500_prcmu_res, + .num_resources = ARRAY_SIZE(db8500_prcmu_res), + .dev = { + .platform_data = &db8500_prcmu_pdata, + }, +}; diff --git a/arch/arm/mach-ux500/devices-db8500.h b/arch/arm/mach-ux500/devices-db8500.h index a5e05f6e256f..dbcb35c48f06 100644 --- a/arch/arm/mach-ux500/devices-db8500.h +++ b/arch/arm/mach-ux500/devices-db8500.h @@ -14,6 +14,11 @@ struct ske_keypad_platform_data; struct pl022_ssp_controller; +struct platform_device; + +extern struct ab8500_platform_data ab8500_platdata; +extern struct prcmu_pdata db8500_prcmu_pdata; +extern struct platform_device db8500_prcmu_device; static inline struct platform_device * db8500_add_ske_keypad(struct device *parent, diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c index 67d8b25d183e..eba03d2329dd 100644 --- a/drivers/mfd/db8500-prcmu.c +++ b/drivers/mfd/db8500-prcmu.c @@ -38,9 +38,6 @@ #include #include "dbx500-prcmu-regs.h" -/* Offset for the firmware version within the TCPM */ -#define PRCMU_FW_VERSION_OFFSET 0xA4 - /* Index of different voltages to be used when accessing AVSData */ #define PRCM_AVS_BASE 0x2FC #define PRCM_AVS_VBB_RET (PRCM_AVS_BASE + 0x0) @@ -2704,21 +2701,43 @@ static struct irq_chip prcmu_irq_chip = { .irq_unmask = prcmu_irq_unmask, }; -static char *fw_project_name(u8 project) +static __init char *fw_project_name(u32 project) { switch (project) { case PRCMU_FW_PROJECT_U8500: return "U8500"; - case PRCMU_FW_PROJECT_U8500_C2: - return "U8500 C2"; + case PRCMU_FW_PROJECT_U8400: + return "U8400"; case PRCMU_FW_PROJECT_U9500: return "U9500"; - case PRCMU_FW_PROJECT_U9500_C2: - return "U9500 C2"; + case PRCMU_FW_PROJECT_U8500_MBB: + return "U8500 MBB"; + case PRCMU_FW_PROJECT_U8500_C1: + return "U8500 C1"; + case PRCMU_FW_PROJECT_U8500_C2: + return "U8500 C2"; + case PRCMU_FW_PROJECT_U8500_C3: + return "U8500 C3"; + case PRCMU_FW_PROJECT_U8500_C4: + return "U8500 C4"; + case PRCMU_FW_PROJECT_U9500_MBL: + return "U9500 MBL"; + case PRCMU_FW_PROJECT_U8500_MBL: + return "U8500 MBL"; + case PRCMU_FW_PROJECT_U8500_MBL2: + return "U8500 MBL2"; case PRCMU_FW_PROJECT_U8520: - return "U8520"; + return "U8520 MBL"; case PRCMU_FW_PROJECT_U8420: return "U8420"; + case PRCMU_FW_PROJECT_U9540: + return "U9540"; + case PRCMU_FW_PROJECT_A9420: + return "A9420"; + case PRCMU_FW_PROJECT_L8540: + return "L8540"; + case PRCMU_FW_PROJECT_L8580: + return "L8580"; default: return "Unknown"; } @@ -2759,37 +2778,44 @@ static int db8500_irq_init(struct device_node *np) return 0; } -void __init db8500_prcmu_early_init(void) +static void dbx500_fw_version_init(struct platform_device *pdev, + u32 version_offset) { - if (cpu_is_u8500v2() || cpu_is_u9540()) { - void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K); - - if (tcpm_base != NULL) { - u32 version; - version = readl(tcpm_base + PRCMU_FW_VERSION_OFFSET); - fw_info.version.project = version & 0xFF; - fw_info.version.api_version = (version >> 8) & 0xFF; - fw_info.version.func_version = (version >> 16) & 0xFF; - fw_info.version.errata = (version >> 24) & 0xFF; - fw_info.valid = true; - pr_info("PRCMU firmware: %s, version %d.%d.%d\n", - fw_project_name(fw_info.version.project), - (version >> 8) & 0xFF, (version >> 16) & 0xFF, - (version >> 24) & 0xFF); - iounmap(tcpm_base); - } + struct resource *res; + void __iomem *tcpm_base; - if (cpu_is_u9540()) - tcdm_base = ioremap_nocache(U8500_PRCMU_TCDM_BASE, - SZ_4K + SZ_8K) + SZ_8K; - else - tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); - } else { - pr_err("prcmu: Unsupported chip version\n"); - BUG(); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, + "prcmu-tcpm"); + if (!res) { + dev_err(&pdev->dev, + "Error: no prcmu tcpm memory region provided\n"); + return; + } + tcpm_base = ioremap(res->start, resource_size(res)); + if (tcpm_base != NULL) { + u32 version; + + version = readl(tcpm_base + version_offset); + fw_info.version.project = (version & 0xFF); + fw_info.version.api_version = (version >> 8) & 0xFF; + fw_info.version.func_version = (version >> 16) & 0xFF; + fw_info.version.errata = (version >> 24) & 0xFF; + strncpy(fw_info.version.project_name, + fw_project_name(fw_info.version.project), + PRCMU_FW_PROJECT_NAME_LEN); + fw_info.valid = true; + pr_info("PRCMU firmware: %s(%d), version %d.%d.%d\n", + fw_info.version.project_name, + fw_info.version.project, + fw_info.version.api_version, + fw_info.version.func_version, + fw_info.version.errata); + iounmap(tcpm_base); } - tcdm_base = __io_address(U8500_PRCMU_TCDM_BASE); +} +void __init db8500_prcmu_early_init(void) +{ spin_lock_init(&mb0_transfer.lock); spin_lock_init(&mb0_transfer.dbb_irqs_lock); mutex_init(&mb0_transfer.ac_wake_lock); @@ -3099,20 +3125,30 @@ static void db8500_prcmu_update_cpufreq(void) */ static int db8500_prcmu_probe(struct platform_device *pdev) { - struct ab8500_platform_data *ab8500_platdata = pdev->dev.platform_data; struct device_node *np = pdev->dev.of_node; + struct prcmu_pdata *pdata = dev_get_platdata(&pdev->dev); int irq = 0, err = 0, i; + struct resource *res; init_prcm_registers(); + dbx500_fw_version_init(pdev, pdata->version_offset); + res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm"); + if (!res) { + dev_err(&pdev->dev, "no prcmu tcdm region provided\n"); + return -ENOENT; + } + tcdm_base = devm_ioremap(&pdev->dev, res->start, + resource_size(res)); + /* Clean up the mailbox interrupts after pre-kernel code. */ writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR); - if (np) - irq = platform_get_irq(pdev, 0); - - if (!np || irq <= 0) - irq = IRQ_DB8500_PRCMU1; + irq = platform_get_irq(pdev, 0); + if (irq <= 0) { + dev_err(&pdev->dev, "no prcmu irq provided\n"); + return -ENOENT; + } err = request_threaded_irq(irq, prcmu_irq_handler, prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL); @@ -3126,7 +3162,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev) for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) { if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) { - db8500_prcmu_devs[i].platform_data = ab8500_platdata; + db8500_prcmu_devs[i].platform_data = pdata->ab_platdata; db8500_prcmu_devs[i].pdata_size = sizeof(struct ab8500_platform_data); } } diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h index a65deddede2f..77a46ae2fc17 100644 --- a/include/linux/mfd/db8500-prcmu.h +++ b/include/linux/mfd/db8500-prcmu.h @@ -487,20 +487,6 @@ struct prcmu_auto_pm_config { u8 sva_policy; }; -#define PRCMU_FW_PROJECT_U8500 2 -#define PRCMU_FW_PROJECT_U9500 4 -#define PRCMU_FW_PROJECT_U8500_C2 7 -#define PRCMU_FW_PROJECT_U9500_C2 11 -#define PRCMU_FW_PROJECT_U8520 13 -#define PRCMU_FW_PROJECT_U8420 14 - -struct prcmu_fw_version { - u8 project; - u8 api_version; - u8 func_version; - u8 errata; -}; - #ifdef CONFIG_MFD_DB8500_PRCMU void db8500_prcmu_early_init(void); diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h index 155280642583..f8bac7cfc25f 100644 --- a/include/linux/mfd/dbx500-prcmu.h +++ b/include/linux/mfd/dbx500-prcmu.h @@ -12,6 +12,10 @@ #include #include +/* Offset for the firmware version within the TCPM */ +#define DB8500_PRCMU_FW_VERSION_OFFSET 0xA4 +#define DBX540_PRCMU_FW_VERSION_OFFSET 0xA8 + /* PRCMU Wakeup defines */ enum prcmu_wakeup_index { PRCMU_WAKEUP_INDEX_RTC, @@ -214,6 +218,48 @@ enum ddr_pwrst { DDR_PWR_STATE_OFFHIGHLAT = 0x03 }; +#define DB8500_PRCMU_LEGACY_OFFSET 0xDD4 + +struct prcmu_pdata +{ + bool enable_set_ddr_opp; + bool enable_ape_opp_100_voltage; + struct ab8500_platform_data *ab_platdata; + u32 version_offset; + u32 legacy_offset; + u32 adt_offset; +}; + +#define PRCMU_FW_PROJECT_U8500 2 +#define PRCMU_FW_PROJECT_U8400 3 +#define PRCMU_FW_PROJECT_U9500 4 /* Customer specific */ +#define PRCMU_FW_PROJECT_U8500_MBB 5 +#define PRCMU_FW_PROJECT_U8500_C1 6 +#define PRCMU_FW_PROJECT_U8500_C2 7 +#define PRCMU_FW_PROJECT_U8500_C3 8 +#define PRCMU_FW_PROJECT_U8500_C4 9 +#define PRCMU_FW_PROJECT_U9500_MBL 10 +#define PRCMU_FW_PROJECT_U8500_MBL 11 /* Customer specific */ +#define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */ +#define PRCMU_FW_PROJECT_U8520 13 +#define PRCMU_FW_PROJECT_U8420 14 +#define PRCMU_FW_PROJECT_A9420 20 +/* [32..63] 9540 and derivatives */ +#define PRCMU_FW_PROJECT_U9540 32 +/* [64..95] 8540 and derivatives */ +#define PRCMU_FW_PROJECT_L8540 64 +/* [96..126] 8580 and derivatives */ +#define PRCMU_FW_PROJECT_L8580 96 + +#define PRCMU_FW_PROJECT_NAME_LEN 20 +struct prcmu_fw_version { + u32 project; /* Notice, project shifted with 8 on ux540 */ + u8 api_version; + u8 func_version; + u8 errata; + char project_name[PRCMU_FW_PROJECT_NAME_LEN]; +}; + #include #if defined(CONFIG_UX500_SOC_DB8500) -- cgit v1.2.3