brintos

brintos / linux-shallow public Read only

0
0
Text · 78.4 KiB · 5b3e355 Raw
3093 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * DB8500 PRCM Unit driver4 *5 * Copyright (C) STMicroelectronics 20096 * Copyright (C) ST-Ericsson SA 20107 *8 * Author: Kumar Sanghvi <kumar.sanghvi@stericsson.com>9 * Author: Sundar Iyer <sundar.iyer@stericsson.com>10 * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>11 *12 * U8500 PRCM Unit interface driver13 */14#include <linux/init.h>15#include <linux/export.h>16#include <linux/kernel.h>17#include <linux/delay.h>18#include <linux/errno.h>19#include <linux/err.h>20#include <linux/spinlock.h>21#include <linux/io.h>22#include <linux/slab.h>23#include <linux/mutex.h>24#include <linux/completion.h>25#include <linux/irq.h>26#include <linux/jiffies.h>27#include <linux/bitops.h>28#include <linux/fs.h>29#include <linux/of.h>30#include <linux/of_address.h>31#include <linux/of_irq.h>32#include <linux/platform_device.h>33#include <linux/uaccess.h>34#include <linux/mfd/core.h>35#include <linux/mfd/dbx500-prcmu.h>36#include <linux/mfd/abx500/ab8500.h>37#include <linux/regulator/db8500-prcmu.h>38#include <linux/regulator/machine.h>39#include "db8500-prcmu-regs.h"40 41/* Index of different voltages to be used when accessing AVSData */42#define PRCM_AVS_BASE		0x2FC43#define PRCM_AVS_VBB_RET	(PRCM_AVS_BASE + 0x0)44#define PRCM_AVS_VBB_MAX_OPP	(PRCM_AVS_BASE + 0x1)45#define PRCM_AVS_VBB_100_OPP	(PRCM_AVS_BASE + 0x2)46#define PRCM_AVS_VBB_50_OPP	(PRCM_AVS_BASE + 0x3)47#define PRCM_AVS_VARM_MAX_OPP	(PRCM_AVS_BASE + 0x4)48#define PRCM_AVS_VARM_100_OPP	(PRCM_AVS_BASE + 0x5)49#define PRCM_AVS_VARM_50_OPP	(PRCM_AVS_BASE + 0x6)50#define PRCM_AVS_VARM_RET	(PRCM_AVS_BASE + 0x7)51#define PRCM_AVS_VAPE_100_OPP	(PRCM_AVS_BASE + 0x8)52#define PRCM_AVS_VAPE_50_OPP	(PRCM_AVS_BASE + 0x9)53#define PRCM_AVS_VMOD_100_OPP	(PRCM_AVS_BASE + 0xA)54#define PRCM_AVS_VMOD_50_OPP	(PRCM_AVS_BASE + 0xB)55#define PRCM_AVS_VSAFE		(PRCM_AVS_BASE + 0xC)56 57#define PRCM_AVS_VOLTAGE		058#define PRCM_AVS_VOLTAGE_MASK		0x3f59#define PRCM_AVS_ISSLOWSTARTUP		660#define PRCM_AVS_ISSLOWSTARTUP_MASK	(1 << PRCM_AVS_ISSLOWSTARTUP)61#define PRCM_AVS_ISMODEENABLE		762#define PRCM_AVS_ISMODEENABLE_MASK	(1 << PRCM_AVS_ISMODEENABLE)63 64#define PRCM_BOOT_STATUS	0xFFF65#define PRCM_ROMCODE_A2P	0xFFE66#define PRCM_ROMCODE_P2A	0xFFD67#define PRCM_XP70_CUR_PWR_STATE 0xFFC      /* 4 BYTES */68 69#define PRCM_SW_RST_REASON 0xFF8 /* 2 bytes */70 71#define _PRCM_MBOX_HEADER		0xFE8 /* 16 bytes */72#define PRCM_MBOX_HEADER_REQ_MB0	(_PRCM_MBOX_HEADER + 0x0)73#define PRCM_MBOX_HEADER_REQ_MB1	(_PRCM_MBOX_HEADER + 0x1)74#define PRCM_MBOX_HEADER_REQ_MB2	(_PRCM_MBOX_HEADER + 0x2)75#define PRCM_MBOX_HEADER_REQ_MB3	(_PRCM_MBOX_HEADER + 0x3)76#define PRCM_MBOX_HEADER_REQ_MB4	(_PRCM_MBOX_HEADER + 0x4)77#define PRCM_MBOX_HEADER_REQ_MB5	(_PRCM_MBOX_HEADER + 0x5)78#define PRCM_MBOX_HEADER_ACK_MB0	(_PRCM_MBOX_HEADER + 0x8)79 80/* Req Mailboxes */81#define PRCM_REQ_MB0 0xFDC /* 12 bytes  */82#define PRCM_REQ_MB1 0xFD0 /* 12 bytes  */83#define PRCM_REQ_MB2 0xFC0 /* 16 bytes  */84#define PRCM_REQ_MB3 0xE4C /* 372 bytes  */85#define PRCM_REQ_MB4 0xE48 /* 4 bytes  */86#define PRCM_REQ_MB5 0xE44 /* 4 bytes  */87 88/* Ack Mailboxes */89#define PRCM_ACK_MB0 0xE08 /* 52 bytes  */90#define PRCM_ACK_MB1 0xE04 /* 4 bytes */91#define PRCM_ACK_MB2 0xE00 /* 4 bytes */92#define PRCM_ACK_MB3 0xDFC /* 4 bytes */93#define PRCM_ACK_MB4 0xDF8 /* 4 bytes */94#define PRCM_ACK_MB5 0xDF4 /* 4 bytes */95 96/* Mailbox 0 headers */97#define MB0H_POWER_STATE_TRANS		098#define MB0H_CONFIG_WAKEUPS_EXE		199#define MB0H_READ_WAKEUP_ACK		3100#define MB0H_CONFIG_WAKEUPS_SLEEP	4101 102#define MB0H_WAKEUP_EXE 2103#define MB0H_WAKEUP_SLEEP 5104 105/* Mailbox 0 REQs */106#define PRCM_REQ_MB0_AP_POWER_STATE	(PRCM_REQ_MB0 + 0x0)107#define PRCM_REQ_MB0_AP_PLL_STATE	(PRCM_REQ_MB0 + 0x1)108#define PRCM_REQ_MB0_ULP_CLOCK_STATE	(PRCM_REQ_MB0 + 0x2)109#define PRCM_REQ_MB0_DO_NOT_WFI		(PRCM_REQ_MB0 + 0x3)110#define PRCM_REQ_MB0_WAKEUP_8500	(PRCM_REQ_MB0 + 0x4)111#define PRCM_REQ_MB0_WAKEUP_4500	(PRCM_REQ_MB0 + 0x8)112 113/* Mailbox 0 ACKs */114#define PRCM_ACK_MB0_AP_PWRSTTR_STATUS	(PRCM_ACK_MB0 + 0x0)115#define PRCM_ACK_MB0_READ_POINTER	(PRCM_ACK_MB0 + 0x1)116#define PRCM_ACK_MB0_WAKEUP_0_8500	(PRCM_ACK_MB0 + 0x4)117#define PRCM_ACK_MB0_WAKEUP_0_4500	(PRCM_ACK_MB0 + 0x8)118#define PRCM_ACK_MB0_WAKEUP_1_8500	(PRCM_ACK_MB0 + 0x1C)119#define PRCM_ACK_MB0_WAKEUP_1_4500	(PRCM_ACK_MB0 + 0x20)120#define PRCM_ACK_MB0_EVENT_4500_NUMBERS	20121 122/* Mailbox 1 headers */123#define MB1H_ARM_APE_OPP 0x0124#define MB1H_RESET_MODEM 0x2125#define MB1H_REQUEST_APE_OPP_100_VOLT 0x3126#define MB1H_RELEASE_APE_OPP_100_VOLT 0x4127#define MB1H_RELEASE_USB_WAKEUP 0x5128#define MB1H_PLL_ON_OFF 0x6129 130/* Mailbox 1 Requests */131#define PRCM_REQ_MB1_ARM_OPP			(PRCM_REQ_MB1 + 0x0)132#define PRCM_REQ_MB1_APE_OPP			(PRCM_REQ_MB1 + 0x1)133#define PRCM_REQ_MB1_PLL_ON_OFF			(PRCM_REQ_MB1 + 0x4)134#define PLL_SOC0_OFF	0x1135#define PLL_SOC0_ON	0x2136#define PLL_SOC1_OFF	0x4137#define PLL_SOC1_ON	0x8138 139/* Mailbox 1 ACKs */140#define PRCM_ACK_MB1_CURRENT_ARM_OPP	(PRCM_ACK_MB1 + 0x0)141#define PRCM_ACK_MB1_CURRENT_APE_OPP	(PRCM_ACK_MB1 + 0x1)142#define PRCM_ACK_MB1_APE_VOLTAGE_STATUS	(PRCM_ACK_MB1 + 0x2)143#define PRCM_ACK_MB1_DVFS_STATUS	(PRCM_ACK_MB1 + 0x3)144 145/* Mailbox 2 headers */146#define MB2H_DPS	0x0147#define MB2H_AUTO_PWR	0x1148 149/* Mailbox 2 REQs */150#define PRCM_REQ_MB2_SVA_MMDSP		(PRCM_REQ_MB2 + 0x0)151#define PRCM_REQ_MB2_SVA_PIPE		(PRCM_REQ_MB2 + 0x1)152#define PRCM_REQ_MB2_SIA_MMDSP		(PRCM_REQ_MB2 + 0x2)153#define PRCM_REQ_MB2_SIA_PIPE		(PRCM_REQ_MB2 + 0x3)154#define PRCM_REQ_MB2_SGA		(PRCM_REQ_MB2 + 0x4)155#define PRCM_REQ_MB2_B2R2_MCDE		(PRCM_REQ_MB2 + 0x5)156#define PRCM_REQ_MB2_ESRAM12		(PRCM_REQ_MB2 + 0x6)157#define PRCM_REQ_MB2_ESRAM34		(PRCM_REQ_MB2 + 0x7)158#define PRCM_REQ_MB2_AUTO_PM_SLEEP	(PRCM_REQ_MB2 + 0x8)159#define PRCM_REQ_MB2_AUTO_PM_IDLE	(PRCM_REQ_MB2 + 0xC)160 161/* Mailbox 2 ACKs */162#define PRCM_ACK_MB2_DPS_STATUS (PRCM_ACK_MB2 + 0x0)163#define HWACC_PWR_ST_OK 0xFE164 165/* Mailbox 3 headers */166#define MB3H_ANC	0x0167#define MB3H_SIDETONE	0x1168#define MB3H_SYSCLK	0xE169 170/* Mailbox 3 Requests */171#define PRCM_REQ_MB3_ANC_FIR_COEFF	(PRCM_REQ_MB3 + 0x0)172#define PRCM_REQ_MB3_ANC_IIR_COEFF	(PRCM_REQ_MB3 + 0x20)173#define PRCM_REQ_MB3_ANC_SHIFTER	(PRCM_REQ_MB3 + 0x60)174#define PRCM_REQ_MB3_ANC_WARP		(PRCM_REQ_MB3 + 0x64)175#define PRCM_REQ_MB3_SIDETONE_FIR_GAIN	(PRCM_REQ_MB3 + 0x68)176#define PRCM_REQ_MB3_SIDETONE_FIR_COEFF	(PRCM_REQ_MB3 + 0x6C)177#define PRCM_REQ_MB3_SYSCLK_MGT		(PRCM_REQ_MB3 + 0x16C)178 179/* Mailbox 4 headers */180#define MB4H_DDR_INIT	0x0181#define MB4H_MEM_ST	0x1182#define MB4H_HOTDOG	0x12183#define MB4H_HOTMON	0x13184#define MB4H_HOT_PERIOD	0x14185#define MB4H_A9WDOG_CONF 0x16186#define MB4H_A9WDOG_EN   0x17187#define MB4H_A9WDOG_DIS  0x18188#define MB4H_A9WDOG_LOAD 0x19189#define MB4H_A9WDOG_KICK 0x20190 191/* Mailbox 4 Requests */192#define PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE	(PRCM_REQ_MB4 + 0x0)193#define PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE	(PRCM_REQ_MB4 + 0x1)194#define PRCM_REQ_MB4_ESRAM0_ST			(PRCM_REQ_MB4 + 0x3)195#define PRCM_REQ_MB4_HOTDOG_THRESHOLD		(PRCM_REQ_MB4 + 0x0)196#define PRCM_REQ_MB4_HOTMON_LOW			(PRCM_REQ_MB4 + 0x0)197#define PRCM_REQ_MB4_HOTMON_HIGH		(PRCM_REQ_MB4 + 0x1)198#define PRCM_REQ_MB4_HOTMON_CONFIG		(PRCM_REQ_MB4 + 0x2)199#define PRCM_REQ_MB4_HOT_PERIOD			(PRCM_REQ_MB4 + 0x0)200#define HOTMON_CONFIG_LOW			BIT(0)201#define HOTMON_CONFIG_HIGH			BIT(1)202#define PRCM_REQ_MB4_A9WDOG_0			(PRCM_REQ_MB4 + 0x0)203#define PRCM_REQ_MB4_A9WDOG_1			(PRCM_REQ_MB4 + 0x1)204#define PRCM_REQ_MB4_A9WDOG_2			(PRCM_REQ_MB4 + 0x2)205#define PRCM_REQ_MB4_A9WDOG_3			(PRCM_REQ_MB4 + 0x3)206#define A9WDOG_AUTO_OFF_EN			BIT(7)207#define A9WDOG_AUTO_OFF_DIS			0208#define A9WDOG_ID_MASK				0xf209 210/* Mailbox 5 Requests */211#define PRCM_REQ_MB5_I2C_SLAVE_OP	(PRCM_REQ_MB5 + 0x0)212#define PRCM_REQ_MB5_I2C_HW_BITS	(PRCM_REQ_MB5 + 0x1)213#define PRCM_REQ_MB5_I2C_REG		(PRCM_REQ_MB5 + 0x2)214#define PRCM_REQ_MB5_I2C_VAL		(PRCM_REQ_MB5 + 0x3)215#define PRCMU_I2C_WRITE(slave) (((slave) << 1) | BIT(6))216#define PRCMU_I2C_READ(slave) (((slave) << 1) | BIT(0) | BIT(6))217#define PRCMU_I2C_STOP_EN		BIT(3)218 219/* Mailbox 5 ACKs */220#define PRCM_ACK_MB5_I2C_STATUS	(PRCM_ACK_MB5 + 0x1)221#define PRCM_ACK_MB5_I2C_VAL	(PRCM_ACK_MB5 + 0x3)222#define I2C_WR_OK 0x1223#define I2C_RD_OK 0x2224 225#define NUM_MB 8226#define MBOX_BIT BIT227#define ALL_MBOX_BITS (MBOX_BIT(NUM_MB) - 1)228 229/*230 * Wakeups/IRQs231 */232 233#define WAKEUP_BIT_RTC BIT(0)234#define WAKEUP_BIT_RTT0 BIT(1)235#define WAKEUP_BIT_RTT1 BIT(2)236#define WAKEUP_BIT_HSI0 BIT(3)237#define WAKEUP_BIT_HSI1 BIT(4)238#define WAKEUP_BIT_CA_WAKE BIT(5)239#define WAKEUP_BIT_USB BIT(6)240#define WAKEUP_BIT_ABB BIT(7)241#define WAKEUP_BIT_ABB_FIFO BIT(8)242#define WAKEUP_BIT_SYSCLK_OK BIT(9)243#define WAKEUP_BIT_CA_SLEEP BIT(10)244#define WAKEUP_BIT_AC_WAKE_ACK BIT(11)245#define WAKEUP_BIT_SIDE_TONE_OK BIT(12)246#define WAKEUP_BIT_ANC_OK BIT(13)247#define WAKEUP_BIT_SW_ERROR BIT(14)248#define WAKEUP_BIT_AC_SLEEP_ACK BIT(15)249#define WAKEUP_BIT_ARM BIT(17)250#define WAKEUP_BIT_HOTMON_LOW BIT(18)251#define WAKEUP_BIT_HOTMON_HIGH BIT(19)252#define WAKEUP_BIT_MODEM_SW_RESET_REQ BIT(20)253#define WAKEUP_BIT_GPIO0 BIT(23)254#define WAKEUP_BIT_GPIO1 BIT(24)255#define WAKEUP_BIT_GPIO2 BIT(25)256#define WAKEUP_BIT_GPIO3 BIT(26)257#define WAKEUP_BIT_GPIO4 BIT(27)258#define WAKEUP_BIT_GPIO5 BIT(28)259#define WAKEUP_BIT_GPIO6 BIT(29)260#define WAKEUP_BIT_GPIO7 BIT(30)261#define WAKEUP_BIT_GPIO8 BIT(31)262 263static struct {264	bool valid;265	struct prcmu_fw_version version;266} fw_info;267 268static struct irq_domain *db8500_irq_domain;269 270/*271 * This vector maps irq numbers to the bits in the bit field used in272 * communication with the PRCMU firmware.273 *274 * The reason for having this is to keep the irq numbers contiguous even though275 * the bits in the bit field are not. (The bits also have a tendency to move276 * around, to further complicate matters.)277 */278#define IRQ_INDEX(_name) ((IRQ_PRCMU_##_name))279#define IRQ_ENTRY(_name)[IRQ_INDEX(_name)] = (WAKEUP_BIT_##_name)280 281#define IRQ_PRCMU_RTC 0282#define IRQ_PRCMU_RTT0 1283#define IRQ_PRCMU_RTT1 2284#define IRQ_PRCMU_HSI0 3285#define IRQ_PRCMU_HSI1 4286#define IRQ_PRCMU_CA_WAKE 5287#define IRQ_PRCMU_USB 6288#define IRQ_PRCMU_ABB 7289#define IRQ_PRCMU_ABB_FIFO 8290#define IRQ_PRCMU_ARM 9291#define IRQ_PRCMU_MODEM_SW_RESET_REQ 10292#define IRQ_PRCMU_GPIO0 11293#define IRQ_PRCMU_GPIO1 12294#define IRQ_PRCMU_GPIO2 13295#define IRQ_PRCMU_GPIO3 14296#define IRQ_PRCMU_GPIO4 15297#define IRQ_PRCMU_GPIO5 16298#define IRQ_PRCMU_GPIO6 17299#define IRQ_PRCMU_GPIO7 18300#define IRQ_PRCMU_GPIO8 19301#define IRQ_PRCMU_CA_SLEEP 20302#define IRQ_PRCMU_HOTMON_LOW 21303#define IRQ_PRCMU_HOTMON_HIGH 22304#define NUM_PRCMU_WAKEUPS 23305 306static u32 prcmu_irq_bit[NUM_PRCMU_WAKEUPS] = {307	IRQ_ENTRY(RTC),308	IRQ_ENTRY(RTT0),309	IRQ_ENTRY(RTT1),310	IRQ_ENTRY(HSI0),311	IRQ_ENTRY(HSI1),312	IRQ_ENTRY(CA_WAKE),313	IRQ_ENTRY(USB),314	IRQ_ENTRY(ABB),315	IRQ_ENTRY(ABB_FIFO),316	IRQ_ENTRY(CA_SLEEP),317	IRQ_ENTRY(ARM),318	IRQ_ENTRY(HOTMON_LOW),319	IRQ_ENTRY(HOTMON_HIGH),320	IRQ_ENTRY(MODEM_SW_RESET_REQ),321	IRQ_ENTRY(GPIO0),322	IRQ_ENTRY(GPIO1),323	IRQ_ENTRY(GPIO2),324	IRQ_ENTRY(GPIO3),325	IRQ_ENTRY(GPIO4),326	IRQ_ENTRY(GPIO5),327	IRQ_ENTRY(GPIO6),328	IRQ_ENTRY(GPIO7),329	IRQ_ENTRY(GPIO8)330};331 332#define VALID_WAKEUPS (BIT(NUM_PRCMU_WAKEUP_INDICES) - 1)333#define WAKEUP_ENTRY(_name)[PRCMU_WAKEUP_INDEX_##_name] = (WAKEUP_BIT_##_name)334static u32 prcmu_wakeup_bit[NUM_PRCMU_WAKEUP_INDICES] = {335	WAKEUP_ENTRY(RTC),336	WAKEUP_ENTRY(RTT0),337	WAKEUP_ENTRY(RTT1),338	WAKEUP_ENTRY(HSI0),339	WAKEUP_ENTRY(HSI1),340	WAKEUP_ENTRY(USB),341	WAKEUP_ENTRY(ABB),342	WAKEUP_ENTRY(ABB_FIFO),343	WAKEUP_ENTRY(ARM)344};345 346/*347 * mb0_transfer - state needed for mailbox 0 communication.348 * @lock:		The transaction lock.349 * @dbb_events_lock:	A lock used to handle concurrent access to (parts of)350 *			the request data.351 * @mask_work:		Work structure used for (un)masking wakeup interrupts.352 * @req:		Request data that need to persist between requests.353 */354static struct {355	spinlock_t lock;356	spinlock_t dbb_irqs_lock;357	struct work_struct mask_work;358	struct mutex ac_wake_lock;359	struct completion ac_wake_work;360	struct {361		u32 dbb_irqs;362		u32 dbb_wakeups;363		u32 abb_events;364	} req;365} mb0_transfer;366 367/*368 * mb1_transfer - state needed for mailbox 1 communication.369 * @lock:	The transaction lock.370 * @work:	The transaction completion structure.371 * @ape_opp:	The current APE OPP.372 * @ack:	Reply ("acknowledge") data.373 */374static struct {375	struct mutex lock;376	struct completion work;377	u8 ape_opp;378	struct {379		u8 header;380		u8 arm_opp;381		u8 ape_opp;382		u8 ape_voltage_status;383	} ack;384} mb1_transfer;385 386/*387 * mb2_transfer - state needed for mailbox 2 communication.388 * @lock:            The transaction lock.389 * @work:            The transaction completion structure.390 * @auto_pm_lock:    The autonomous power management configuration lock.391 * @auto_pm_enabled: A flag indicating whether autonomous PM is enabled.392 * @req:             Request data that need to persist between requests.393 * @ack:             Reply ("acknowledge") data.394 */395static struct {396	struct mutex lock;397	struct completion work;398	spinlock_t auto_pm_lock;399	bool auto_pm_enabled;400	struct {401		u8 status;402	} ack;403} mb2_transfer;404 405/*406 * mb3_transfer - state needed for mailbox 3 communication.407 * @lock:		The request lock.408 * @sysclk_lock:	A lock used to handle concurrent sysclk requests.409 * @sysclk_work:	Work structure used for sysclk requests.410 */411static struct {412	spinlock_t lock;413	struct mutex sysclk_lock;414	struct completion sysclk_work;415} mb3_transfer;416 417/*418 * mb4_transfer - state needed for mailbox 4 communication.419 * @lock:	The transaction lock.420 * @work:	The transaction completion structure.421 */422static struct {423	struct mutex lock;424	struct completion work;425} mb4_transfer;426 427/*428 * mb5_transfer - state needed for mailbox 5 communication.429 * @lock:	The transaction lock.430 * @work:	The transaction completion structure.431 * @ack:	Reply ("acknowledge") data.432 */433static struct {434	struct mutex lock;435	struct completion work;436	struct {437		u8 status;438		u8 value;439	} ack;440} mb5_transfer;441 442static atomic_t ac_wake_req_state = ATOMIC_INIT(0);443 444/* Spinlocks */445static DEFINE_SPINLOCK(prcmu_lock);446static DEFINE_SPINLOCK(clkout_lock);447 448/* Global var to runtime determine TCDM base for v2 or v1 */449static __iomem void *tcdm_base;450static __iomem void *prcmu_base;451 452struct clk_mgt {453	u32 offset;454	u32 pllsw;455	int branch;456	bool clk38div;457};458 459enum {460	PLL_RAW,461	PLL_FIX,462	PLL_DIV463};464 465static DEFINE_SPINLOCK(clk_mgt_lock);466 467#define CLK_MGT_ENTRY(_name, _branch, _clk38div)[PRCMU_##_name] = \468	{ (PRCM_##_name##_MGT), 0 , _branch, _clk38div}469static struct clk_mgt clk_mgt[PRCMU_NUM_REG_CLOCKS] = {470	CLK_MGT_ENTRY(SGACLK, PLL_DIV, false),471	CLK_MGT_ENTRY(UARTCLK, PLL_FIX, true),472	CLK_MGT_ENTRY(MSP02CLK, PLL_FIX, true),473	CLK_MGT_ENTRY(MSP1CLK, PLL_FIX, true),474	CLK_MGT_ENTRY(I2CCLK, PLL_FIX, true),475	CLK_MGT_ENTRY(SDMMCCLK, PLL_DIV, true),476	CLK_MGT_ENTRY(SLIMCLK, PLL_FIX, true),477	CLK_MGT_ENTRY(PER1CLK, PLL_DIV, true),478	CLK_MGT_ENTRY(PER2CLK, PLL_DIV, true),479	CLK_MGT_ENTRY(PER3CLK, PLL_DIV, true),480	CLK_MGT_ENTRY(PER5CLK, PLL_DIV, true),481	CLK_MGT_ENTRY(PER6CLK, PLL_DIV, true),482	CLK_MGT_ENTRY(PER7CLK, PLL_DIV, true),483	CLK_MGT_ENTRY(LCDCLK, PLL_FIX, true),484	CLK_MGT_ENTRY(BMLCLK, PLL_DIV, true),485	CLK_MGT_ENTRY(HSITXCLK, PLL_DIV, true),486	CLK_MGT_ENTRY(HSIRXCLK, PLL_DIV, true),487	CLK_MGT_ENTRY(HDMICLK, PLL_FIX, false),488	CLK_MGT_ENTRY(APEATCLK, PLL_DIV, true),489	CLK_MGT_ENTRY(APETRACECLK, PLL_DIV, true),490	CLK_MGT_ENTRY(MCDECLK, PLL_DIV, true),491	CLK_MGT_ENTRY(IPI2CCLK, PLL_FIX, true),492	CLK_MGT_ENTRY(DSIALTCLK, PLL_FIX, false),493	CLK_MGT_ENTRY(DMACLK, PLL_DIV, true),494	CLK_MGT_ENTRY(B2R2CLK, PLL_DIV, true),495	CLK_MGT_ENTRY(TVCLK, PLL_FIX, true),496	CLK_MGT_ENTRY(SSPCLK, PLL_FIX, true),497	CLK_MGT_ENTRY(RNGCLK, PLL_FIX, true),498	CLK_MGT_ENTRY(UICCCLK, PLL_FIX, false),499};500 501struct dsiclk {502	u32 divsel_mask;503	u32 divsel_shift;504	u32 divsel;505};506 507static struct dsiclk dsiclk[2] = {508	{509		.divsel_mask = PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_MASK,510		.divsel_shift = PRCM_DSI_PLLOUT_SEL_DSI0_PLLOUT_DIVSEL_SHIFT,511		.divsel = PRCM_DSI_PLLOUT_SEL_PHI,512	},513	{514		.divsel_mask = PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_MASK,515		.divsel_shift = PRCM_DSI_PLLOUT_SEL_DSI1_PLLOUT_DIVSEL_SHIFT,516		.divsel = PRCM_DSI_PLLOUT_SEL_PHI,517	}518};519 520struct dsiescclk {521	u32 en;522	u32 div_mask;523	u32 div_shift;524};525 526static struct dsiescclk dsiescclk[3] = {527	{528		.en = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_EN,529		.div_mask = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_MASK,530		.div_shift = PRCM_DSITVCLK_DIV_DSI0_ESC_CLK_DIV_SHIFT,531	},532	{533		.en = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_EN,534		.div_mask = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_MASK,535		.div_shift = PRCM_DSITVCLK_DIV_DSI1_ESC_CLK_DIV_SHIFT,536	},537	{538		.en = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_EN,539		.div_mask = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_MASK,540		.div_shift = PRCM_DSITVCLK_DIV_DSI2_ESC_CLK_DIV_SHIFT,541	}542};543 544u32 db8500_prcmu_read(unsigned int reg)545{546	return readl(prcmu_base + reg);547}548 549void db8500_prcmu_write(unsigned int reg, u32 value)550{551	unsigned long flags;552 553	spin_lock_irqsave(&prcmu_lock, flags);554	writel(value, (prcmu_base + reg));555	spin_unlock_irqrestore(&prcmu_lock, flags);556}557 558void db8500_prcmu_write_masked(unsigned int reg, u32 mask, u32 value)559{560	u32 val;561	unsigned long flags;562 563	spin_lock_irqsave(&prcmu_lock, flags);564	val = readl(prcmu_base + reg);565	val = ((val & ~mask) | (value & mask));566	writel(val, (prcmu_base + reg));567	spin_unlock_irqrestore(&prcmu_lock, flags);568}569 570struct prcmu_fw_version *prcmu_get_fw_version(void)571{572	return fw_info.valid ? &fw_info.version : NULL;573}574 575static bool prcmu_is_ulppll_disabled(void)576{577	struct prcmu_fw_version *ver;578 579	ver = prcmu_get_fw_version();580	return ver && ver->project == PRCMU_FW_PROJECT_U8420_SYSCLK;581}582 583bool prcmu_has_arm_maxopp(void)584{585	return (readb(tcdm_base + PRCM_AVS_VARM_MAX_OPP) &586		PRCM_AVS_ISMODEENABLE_MASK) == PRCM_AVS_ISMODEENABLE_MASK;587}588 589/**590 * prcmu_set_rc_a2p - This function is used to run few power state sequences591 * @val: Value to be set, i.e. transition requested592 * Returns: 0 on success, -EINVAL on invalid argument593 *594 * This function is used to run the following power state sequences -595 * any state to ApReset,  ApDeepSleep to ApExecute, ApExecute to ApDeepSleep596 */597int prcmu_set_rc_a2p(enum romcode_write val)598{599	if (val < RDY_2_DS || val > RDY_2_XP70_RST)600		return -EINVAL;601	writeb(val, (tcdm_base + PRCM_ROMCODE_A2P));602	return 0;603}604 605/**606 * prcmu_get_rc_p2a - This function is used to get power state sequences607 * Returns: the power transition that has last happened608 *609 * This function can return the following transitions-610 * any state to ApReset,  ApDeepSleep to ApExecute, ApExecute to ApDeepSleep611 */612enum romcode_read prcmu_get_rc_p2a(void)613{614	return readb(tcdm_base + PRCM_ROMCODE_P2A);615}616 617/**618 * prcmu_get_xp70_current_state - Return the current XP70 power mode619 * Returns: Returns the current AP(ARM) power mode: init,620 * apBoot, apExecute, apDeepSleep, apSleep, apIdle, apReset621 */622enum ap_pwrst prcmu_get_xp70_current_state(void)623{624	return readb(tcdm_base + PRCM_XP70_CUR_PWR_STATE);625}626 627/**628 * prcmu_config_clkout - Configure one of the programmable clock outputs.629 * @clkout:	The CLKOUT number (0 or 1).630 * @source:	The clock to be used (one of the PRCMU_CLKSRC_*).631 * @div:	The divider to be applied.632 *633 * Configures one of the programmable clock outputs (CLKOUTs).634 * @div should be in the range [1,63] to request a configuration, or 0 to635 * inform that the configuration is no longer requested.636 */637int prcmu_config_clkout(u8 clkout, u8 source, u8 div)638{639	static int requests[2];640	int r = 0;641	unsigned long flags;642	u32 val;643	u32 bits;644	u32 mask;645	u32 div_mask;646 647	BUG_ON(clkout > 1);648	BUG_ON(div > 63);649	BUG_ON((clkout == 0) && (source > PRCMU_CLKSRC_CLK009));650 651	if (!div && !requests[clkout])652		return -EINVAL;653 654	if (clkout == 0) {655		div_mask = PRCM_CLKOCR_CLKODIV0_MASK;656		mask = (PRCM_CLKOCR_CLKODIV0_MASK | PRCM_CLKOCR_CLKOSEL0_MASK);657		bits = ((source << PRCM_CLKOCR_CLKOSEL0_SHIFT) |658			(div << PRCM_CLKOCR_CLKODIV0_SHIFT));659	} else {660		div_mask = PRCM_CLKOCR_CLKODIV1_MASK;661		mask = (PRCM_CLKOCR_CLKODIV1_MASK | PRCM_CLKOCR_CLKOSEL1_MASK |662			PRCM_CLKOCR_CLK1TYPE);663		bits = ((source << PRCM_CLKOCR_CLKOSEL1_SHIFT) |664			(div << PRCM_CLKOCR_CLKODIV1_SHIFT));665	}666	bits &= mask;667 668	spin_lock_irqsave(&clkout_lock, flags);669 670	val = readl(PRCM_CLKOCR);671	if (val & div_mask) {672		if (div) {673			if ((val & mask) != bits) {674				r = -EBUSY;675				goto unlock_and_return;676			}677		} else {678			if ((val & mask & ~div_mask) != bits) {679				r = -EINVAL;680				goto unlock_and_return;681			}682		}683	}684	writel((bits | (val & ~mask)), PRCM_CLKOCR);685	requests[clkout] += (div ? 1 : -1);686 687unlock_and_return:688	spin_unlock_irqrestore(&clkout_lock, flags);689 690	return r;691}692 693int db8500_prcmu_set_power_state(u8 state, bool keep_ulp_clk, bool keep_ap_pll)694{695	unsigned long flags;696 697	BUG_ON((state < PRCMU_AP_SLEEP) || (PRCMU_AP_DEEP_IDLE < state));698 699	spin_lock_irqsave(&mb0_transfer.lock, flags);700 701	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))702		cpu_relax();703 704	writeb(MB0H_POWER_STATE_TRANS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0));705	writeb(state, (tcdm_base + PRCM_REQ_MB0_AP_POWER_STATE));706	writeb((keep_ap_pll ? 1 : 0), (tcdm_base + PRCM_REQ_MB0_AP_PLL_STATE));707	writeb((keep_ulp_clk ? 1 : 0),708		(tcdm_base + PRCM_REQ_MB0_ULP_CLOCK_STATE));709	writeb(0, (tcdm_base + PRCM_REQ_MB0_DO_NOT_WFI));710	writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET);711 712	spin_unlock_irqrestore(&mb0_transfer.lock, flags);713 714	return 0;715}716 717u8 db8500_prcmu_get_power_state_result(void)718{719	return readb(tcdm_base + PRCM_ACK_MB0_AP_PWRSTTR_STATUS);720}721 722/* This function should only be called while mb0_transfer.lock is held. */723static void config_wakeups(void)724{725	const u8 header[2] = {726		MB0H_CONFIG_WAKEUPS_EXE,727		MB0H_CONFIG_WAKEUPS_SLEEP728	};729	static u32 last_dbb_events;730	static u32 last_abb_events;731	u32 dbb_events;732	u32 abb_events;733	unsigned int i;734 735	dbb_events = mb0_transfer.req.dbb_irqs | mb0_transfer.req.dbb_wakeups;736	dbb_events |= (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK);737 738	abb_events = mb0_transfer.req.abb_events;739 740	if ((dbb_events == last_dbb_events) && (abb_events == last_abb_events))741		return;742 743	for (i = 0; i < 2; i++) {744		while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))745			cpu_relax();746		writel(dbb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_8500));747		writel(abb_events, (tcdm_base + PRCM_REQ_MB0_WAKEUP_4500));748		writeb(header[i], (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0));749		writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET);750	}751	last_dbb_events = dbb_events;752	last_abb_events = abb_events;753}754 755void db8500_prcmu_enable_wakeups(u32 wakeups)756{757	unsigned long flags;758	u32 bits;759	int i;760 761	BUG_ON(wakeups != (wakeups & VALID_WAKEUPS));762 763	for (i = 0, bits = 0; i < NUM_PRCMU_WAKEUP_INDICES; i++) {764		if (wakeups & BIT(i))765			bits |= prcmu_wakeup_bit[i];766	}767 768	spin_lock_irqsave(&mb0_transfer.lock, flags);769 770	mb0_transfer.req.dbb_wakeups = bits;771	config_wakeups();772 773	spin_unlock_irqrestore(&mb0_transfer.lock, flags);774}775 776void db8500_prcmu_config_abb_event_readout(u32 abb_events)777{778	unsigned long flags;779 780	spin_lock_irqsave(&mb0_transfer.lock, flags);781 782	mb0_transfer.req.abb_events = abb_events;783	config_wakeups();784 785	spin_unlock_irqrestore(&mb0_transfer.lock, flags);786}787 788void db8500_prcmu_get_abb_event_buffer(void __iomem **buf)789{790	if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1)791		*buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_1_4500);792	else793		*buf = (tcdm_base + PRCM_ACK_MB0_WAKEUP_0_4500);794}795 796/**797 * db8500_prcmu_set_arm_opp - set the appropriate ARM OPP798 * @opp: The new ARM operating point to which transition is to be made799 * Returns: 0 on success, non-zero on failure800 *801 * This function sets the operating point of the ARM.802 */803int db8500_prcmu_set_arm_opp(u8 opp)804{805	int r;806 807	if (opp < ARM_NO_CHANGE || opp > ARM_EXTCLK)808		return -EINVAL;809 810	r = 0;811 812	mutex_lock(&mb1_transfer.lock);813 814	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))815		cpu_relax();816 817	writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));818	writeb(opp, (tcdm_base + PRCM_REQ_MB1_ARM_OPP));819	writeb(APE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_APE_OPP));820 821	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);822	wait_for_completion(&mb1_transfer.work);823 824	if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) ||825		(mb1_transfer.ack.arm_opp != opp))826		r = -EIO;827 828	mutex_unlock(&mb1_transfer.lock);829 830	return r;831}832 833/**834 * db8500_prcmu_get_arm_opp - get the current ARM OPP835 *836 * Returns: the current ARM OPP837 */838int db8500_prcmu_get_arm_opp(void)839{840	return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_ARM_OPP);841}842 843/**844 * db8500_prcmu_get_ddr_opp - get the current DDR OPP845 *846 * Returns: the current DDR OPP847 */848int db8500_prcmu_get_ddr_opp(void)849{850	return readb(PRCM_DDR_SUBSYS_APE_MINBW);851}852 853/* Divide the frequency of certain clocks by 2 for APE_50_PARTLY_25_OPP. */854static void request_even_slower_clocks(bool enable)855{856	u32 clock_reg[] = {857		PRCM_ACLK_MGT,858		PRCM_DMACLK_MGT859	};860	unsigned long flags;861	unsigned int i;862 863	spin_lock_irqsave(&clk_mgt_lock, flags);864 865	/* Grab the HW semaphore. */866	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)867		cpu_relax();868 869	for (i = 0; i < ARRAY_SIZE(clock_reg); i++) {870		u32 val;871		u32 div;872 873		val = readl(prcmu_base + clock_reg[i]);874		div = (val & PRCM_CLK_MGT_CLKPLLDIV_MASK);875		if (enable) {876			if ((div <= 1) || (div > 15)) {877				pr_err("prcmu: Bad clock divider %d in %s\n",878					div, __func__);879				goto unlock_and_return;880			}881			div <<= 1;882		} else {883			if (div <= 2)884				goto unlock_and_return;885			div >>= 1;886		}887		val = ((val & ~PRCM_CLK_MGT_CLKPLLDIV_MASK) |888			(div & PRCM_CLK_MGT_CLKPLLDIV_MASK));889		writel(val, prcmu_base + clock_reg[i]);890	}891 892unlock_and_return:893	/* Release the HW semaphore. */894	writel(0, PRCM_SEM);895 896	spin_unlock_irqrestore(&clk_mgt_lock, flags);897}898 899/**900 * db8500_prcmu_set_ape_opp - set the appropriate APE OPP901 * @opp: The new APE operating point to which transition is to be made902 * Returns: 0 on success, non-zero on failure903 *904 * This function sets the operating point of the APE.905 */906int db8500_prcmu_set_ape_opp(u8 opp)907{908	int r = 0;909 910	if (opp == mb1_transfer.ape_opp)911		return 0;912 913	mutex_lock(&mb1_transfer.lock);914 915	if (mb1_transfer.ape_opp == APE_50_PARTLY_25_OPP)916		request_even_slower_clocks(false);917 918	if ((opp != APE_100_OPP) && (mb1_transfer.ape_opp != APE_100_OPP))919		goto skip_message;920 921	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))922		cpu_relax();923 924	writeb(MB1H_ARM_APE_OPP, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));925	writeb(ARM_NO_CHANGE, (tcdm_base + PRCM_REQ_MB1_ARM_OPP));926	writeb(((opp == APE_50_PARTLY_25_OPP) ? APE_50_OPP : opp),927		(tcdm_base + PRCM_REQ_MB1_APE_OPP));928 929	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);930	wait_for_completion(&mb1_transfer.work);931 932	if ((mb1_transfer.ack.header != MB1H_ARM_APE_OPP) ||933		(mb1_transfer.ack.ape_opp != opp))934		r = -EIO;935 936skip_message:937	if ((!r && (opp == APE_50_PARTLY_25_OPP)) ||938		(r && (mb1_transfer.ape_opp == APE_50_PARTLY_25_OPP)))939		request_even_slower_clocks(true);940	if (!r)941		mb1_transfer.ape_opp = opp;942 943	mutex_unlock(&mb1_transfer.lock);944 945	return r;946}947 948/**949 * db8500_prcmu_get_ape_opp - get the current APE OPP950 *951 * Returns: the current APE OPP952 */953int db8500_prcmu_get_ape_opp(void)954{955	return readb(tcdm_base + PRCM_ACK_MB1_CURRENT_APE_OPP);956}957 958/**959 * db8500_prcmu_request_ape_opp_100_voltage - Request APE OPP 100% voltage960 * @enable: true to request the higher voltage, false to drop a request.961 *962 * Calls to this function to enable and disable requests must be balanced.963 */964int db8500_prcmu_request_ape_opp_100_voltage(bool enable)965{966	int r = 0;967	u8 header;968	static unsigned int requests;969 970	mutex_lock(&mb1_transfer.lock);971 972	if (enable) {973		if (0 != requests++)974			goto unlock_and_return;975		header = MB1H_REQUEST_APE_OPP_100_VOLT;976	} else {977		if (requests == 0) {978			r = -EIO;979			goto unlock_and_return;980		} else if (1 != requests--) {981			goto unlock_and_return;982		}983		header = MB1H_RELEASE_APE_OPP_100_VOLT;984	}985 986	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))987		cpu_relax();988 989	writeb(header, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));990 991	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);992	wait_for_completion(&mb1_transfer.work);993 994	if ((mb1_transfer.ack.header != header) ||995		((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0))996		r = -EIO;997 998unlock_and_return:999	mutex_unlock(&mb1_transfer.lock);1000 1001	return r;1002}1003 1004/**1005 * prcmu_release_usb_wakeup_state - release the state required by a USB wakeup1006 *1007 * This function releases the power state requirements of a USB wakeup.1008 */1009int prcmu_release_usb_wakeup_state(void)1010{1011	int r = 0;1012 1013	mutex_lock(&mb1_transfer.lock);1014 1015	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))1016		cpu_relax();1017 1018	writeb(MB1H_RELEASE_USB_WAKEUP,1019		(tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));1020 1021	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);1022	wait_for_completion(&mb1_transfer.work);1023 1024	if ((mb1_transfer.ack.header != MB1H_RELEASE_USB_WAKEUP) ||1025		((mb1_transfer.ack.ape_voltage_status & BIT(0)) != 0))1026		r = -EIO;1027 1028	mutex_unlock(&mb1_transfer.lock);1029 1030	return r;1031}1032 1033static int request_pll(u8 clock, bool enable)1034{1035	int r = 0;1036 1037	if (clock == PRCMU_PLLSOC0)1038		clock = (enable ? PLL_SOC0_ON : PLL_SOC0_OFF);1039	else if (clock == PRCMU_PLLSOC1)1040		clock = (enable ? PLL_SOC1_ON : PLL_SOC1_OFF);1041	else1042		return -EINVAL;1043 1044	mutex_lock(&mb1_transfer.lock);1045 1046	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))1047		cpu_relax();1048 1049	writeb(MB1H_PLL_ON_OFF, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));1050	writeb(clock, (tcdm_base + PRCM_REQ_MB1_PLL_ON_OFF));1051 1052	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);1053	wait_for_completion(&mb1_transfer.work);1054 1055	if (mb1_transfer.ack.header != MB1H_PLL_ON_OFF)1056		r = -EIO;1057 1058	mutex_unlock(&mb1_transfer.lock);1059 1060	return r;1061}1062 1063/**1064 * db8500_prcmu_set_epod - set the state of a EPOD (power domain)1065 * @epod_id: The EPOD to set1066 * @epod_state: The new EPOD state1067 *1068 * This function sets the state of a EPOD (power domain). It may not be called1069 * from interrupt context.1070 */1071int db8500_prcmu_set_epod(u16 epod_id, u8 epod_state)1072{1073	int r = 0;1074	bool ram_retention = false;1075	int i;1076 1077	/* check argument */1078	BUG_ON(epod_id >= NUM_EPOD_ID);1079 1080	/* set flag if retention is possible */1081	switch (epod_id) {1082	case EPOD_ID_SVAMMDSP:1083	case EPOD_ID_SIAMMDSP:1084	case EPOD_ID_ESRAM12:1085	case EPOD_ID_ESRAM34:1086		ram_retention = true;1087		break;1088	}1089 1090	/* check argument */1091	BUG_ON(epod_state > EPOD_STATE_ON);1092	BUG_ON(epod_state == EPOD_STATE_RAMRET && !ram_retention);1093 1094	/* get lock */1095	mutex_lock(&mb2_transfer.lock);1096 1097	/* wait for mailbox */1098	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(2))1099		cpu_relax();1100 1101	/* fill in mailbox */1102	for (i = 0; i < NUM_EPOD_ID; i++)1103		writeb(EPOD_STATE_NO_CHANGE, (tcdm_base + PRCM_REQ_MB2 + i));1104	writeb(epod_state, (tcdm_base + PRCM_REQ_MB2 + epod_id));1105 1106	writeb(MB2H_DPS, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB2));1107 1108	writel(MBOX_BIT(2), PRCM_MBOX_CPU_SET);1109 1110	/*1111	 * The current firmware version does not handle errors correctly,1112	 * and we cannot recover if there is an error.1113	 * This is expected to change when the firmware is updated.1114	 */1115	if (!wait_for_completion_timeout(&mb2_transfer.work,1116			msecs_to_jiffies(20000))) {1117		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",1118			__func__);1119		r = -EIO;1120		goto unlock_and_return;1121	}1122 1123	if (mb2_transfer.ack.status != HWACC_PWR_ST_OK)1124		r = -EIO;1125 1126unlock_and_return:1127	mutex_unlock(&mb2_transfer.lock);1128	return r;1129}1130 1131/**1132 * prcmu_configure_auto_pm - Configure autonomous power management.1133 * @sleep: Configuration for ApSleep.1134 * @idle:  Configuration for ApIdle.1135 */1136void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,1137	struct prcmu_auto_pm_config *idle)1138{1139	u32 sleep_cfg;1140	u32 idle_cfg;1141	unsigned long flags;1142 1143	BUG_ON((sleep == NULL) || (idle == NULL));1144 1145	sleep_cfg = (sleep->sva_auto_pm_enable & 0xF);1146	sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_auto_pm_enable & 0xF));1147	sleep_cfg = ((sleep_cfg << 8) | (sleep->sva_power_on & 0xFF));1148	sleep_cfg = ((sleep_cfg << 8) | (sleep->sia_power_on & 0xFF));1149	sleep_cfg = ((sleep_cfg << 4) | (sleep->sva_policy & 0xF));1150	sleep_cfg = ((sleep_cfg << 4) | (sleep->sia_policy & 0xF));1151 1152	idle_cfg = (idle->sva_auto_pm_enable & 0xF);1153	idle_cfg = ((idle_cfg << 4) | (idle->sia_auto_pm_enable & 0xF));1154	idle_cfg = ((idle_cfg << 8) | (idle->sva_power_on & 0xFF));1155	idle_cfg = ((idle_cfg << 8) | (idle->sia_power_on & 0xFF));1156	idle_cfg = ((idle_cfg << 4) | (idle->sva_policy & 0xF));1157	idle_cfg = ((idle_cfg << 4) | (idle->sia_policy & 0xF));1158 1159	spin_lock_irqsave(&mb2_transfer.auto_pm_lock, flags);1160 1161	/*1162	 * The autonomous power management configuration is done through1163	 * fields in mailbox 2, but these fields are only used as shared1164	 * variables - i.e. there is no need to send a message.1165	 */1166	writel(sleep_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_SLEEP));1167	writel(idle_cfg, (tcdm_base + PRCM_REQ_MB2_AUTO_PM_IDLE));1168 1169	mb2_transfer.auto_pm_enabled =1170		((sleep->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) ||1171		 (sleep->sia_auto_pm_enable == PRCMU_AUTO_PM_ON) ||1172		 (idle->sva_auto_pm_enable == PRCMU_AUTO_PM_ON) ||1173		 (idle->sia_auto_pm_enable == PRCMU_AUTO_PM_ON));1174 1175	spin_unlock_irqrestore(&mb2_transfer.auto_pm_lock, flags);1176}1177EXPORT_SYMBOL(prcmu_configure_auto_pm);1178 1179bool prcmu_is_auto_pm_enabled(void)1180{1181	return mb2_transfer.auto_pm_enabled;1182}1183 1184static int request_sysclk(bool enable)1185{1186	int r;1187	unsigned long flags;1188 1189	r = 0;1190 1191	mutex_lock(&mb3_transfer.sysclk_lock);1192 1193	spin_lock_irqsave(&mb3_transfer.lock, flags);1194 1195	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(3))1196		cpu_relax();1197 1198	writeb((enable ? ON : OFF), (tcdm_base + PRCM_REQ_MB3_SYSCLK_MGT));1199 1200	writeb(MB3H_SYSCLK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB3));1201	writel(MBOX_BIT(3), PRCM_MBOX_CPU_SET);1202 1203	spin_unlock_irqrestore(&mb3_transfer.lock, flags);1204 1205	/*1206	 * The firmware only sends an ACK if we want to enable the1207	 * SysClk, and it succeeds.1208	 */1209	if (enable && !wait_for_completion_timeout(&mb3_transfer.sysclk_work,1210			msecs_to_jiffies(20000))) {1211		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",1212			__func__);1213		r = -EIO;1214	}1215 1216	mutex_unlock(&mb3_transfer.sysclk_lock);1217 1218	return r;1219}1220 1221static int request_timclk(bool enable)1222{1223	u32 val;1224 1225	/*1226	 * On the U8420_CLKSEL firmware, the ULP (Ultra Low Power)1227	 * PLL is disabled so we cannot use doze mode, this will1228	 * stop the clock on this firmware.1229	 */1230	if (prcmu_is_ulppll_disabled())1231		val = 0;1232	else1233		val = (PRCM_TCR_DOZE_MODE | PRCM_TCR_TENSEL_MASK);1234 1235	if (!enable)1236		val |= PRCM_TCR_STOP_TIMERS |1237			PRCM_TCR_DOZE_MODE |1238			PRCM_TCR_TENSEL_MASK;1239 1240	writel(val, PRCM_TCR);1241 1242	return 0;1243}1244 1245static int request_clock(u8 clock, bool enable)1246{1247	u32 val;1248	unsigned long flags;1249 1250	spin_lock_irqsave(&clk_mgt_lock, flags);1251 1252	/* Grab the HW semaphore. */1253	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)1254		cpu_relax();1255 1256	val = readl(prcmu_base + clk_mgt[clock].offset);1257	if (enable) {1258		val |= (PRCM_CLK_MGT_CLKEN | clk_mgt[clock].pllsw);1259	} else {1260		clk_mgt[clock].pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK);1261		val &= ~(PRCM_CLK_MGT_CLKEN | PRCM_CLK_MGT_CLKPLLSW_MASK);1262	}1263	writel(val, prcmu_base + clk_mgt[clock].offset);1264 1265	/* Release the HW semaphore. */1266	writel(0, PRCM_SEM);1267 1268	spin_unlock_irqrestore(&clk_mgt_lock, flags);1269 1270	return 0;1271}1272 1273static int request_sga_clock(u8 clock, bool enable)1274{1275	u32 val;1276	int ret;1277 1278	if (enable) {1279		val = readl(PRCM_CGATING_BYPASS);1280		writel(val | PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS);1281	}1282 1283	ret = request_clock(clock, enable);1284 1285	if (!ret && !enable) {1286		val = readl(PRCM_CGATING_BYPASS);1287		writel(val & ~PRCM_CGATING_BYPASS_ICN2, PRCM_CGATING_BYPASS);1288	}1289 1290	return ret;1291}1292 1293static inline bool plldsi_locked(void)1294{1295	return (readl(PRCM_PLLDSI_LOCKP) &1296		(PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 |1297		 PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3)) ==1298		(PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP10 |1299		 PRCM_PLLDSI_LOCKP_PRCM_PLLDSI_LOCKP3);1300}1301 1302static int request_plldsi(bool enable)1303{1304	int r = 0;1305	u32 val;1306 1307	writel((PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP |1308		PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI), (enable ?1309		PRCM_MMIP_LS_CLAMP_CLR : PRCM_MMIP_LS_CLAMP_SET));1310 1311	val = readl(PRCM_PLLDSI_ENABLE);1312	if (enable)1313		val |= PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE;1314	else1315		val &= ~PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE;1316	writel(val, PRCM_PLLDSI_ENABLE);1317 1318	if (enable) {1319		unsigned int i;1320		bool locked = plldsi_locked();1321 1322		for (i = 10; !locked && (i > 0); --i) {1323			udelay(100);1324			locked = plldsi_locked();1325		}1326		if (locked) {1327			writel(PRCM_APE_RESETN_DSIPLL_RESETN,1328				PRCM_APE_RESETN_SET);1329		} else {1330			writel((PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMP |1331				PRCM_MMIP_LS_CLAMP_DSIPLL_CLAMPI),1332				PRCM_MMIP_LS_CLAMP_SET);1333			val &= ~PRCM_PLLDSI_ENABLE_PRCM_PLLDSI_ENABLE;1334			writel(val, PRCM_PLLDSI_ENABLE);1335			r = -EAGAIN;1336		}1337	} else {1338		writel(PRCM_APE_RESETN_DSIPLL_RESETN, PRCM_APE_RESETN_CLR);1339	}1340	return r;1341}1342 1343static int request_dsiclk(u8 n, bool enable)1344{1345	u32 val;1346 1347	val = readl(PRCM_DSI_PLLOUT_SEL);1348	val &= ~dsiclk[n].divsel_mask;1349	val |= ((enable ? dsiclk[n].divsel : PRCM_DSI_PLLOUT_SEL_OFF) <<1350		dsiclk[n].divsel_shift);1351	writel(val, PRCM_DSI_PLLOUT_SEL);1352	return 0;1353}1354 1355static int request_dsiescclk(u8 n, bool enable)1356{1357	u32 val;1358 1359	val = readl(PRCM_DSITVCLK_DIV);1360	enable ? (val |= dsiescclk[n].en) : (val &= ~dsiescclk[n].en);1361	writel(val, PRCM_DSITVCLK_DIV);1362	return 0;1363}1364 1365/**1366 * db8500_prcmu_request_clock() - Request for a clock to be enabled or disabled.1367 * @clock:      The clock for which the request is made.1368 * @enable:     Whether the clock should be enabled (true) or disabled (false).1369 *1370 * This function should only be used by the clock implementation.1371 * Do not use it from any other place!1372 */1373int db8500_prcmu_request_clock(u8 clock, bool enable)1374{1375	if (clock == PRCMU_SGACLK)1376		return request_sga_clock(clock, enable);1377	else if (clock < PRCMU_NUM_REG_CLOCKS)1378		return request_clock(clock, enable);1379	else if (clock == PRCMU_TIMCLK)1380		return request_timclk(enable);1381	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))1382		return request_dsiclk((clock - PRCMU_DSI0CLK), enable);1383	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))1384		return request_dsiescclk((clock - PRCMU_DSI0ESCCLK), enable);1385	else if (clock == PRCMU_PLLDSI)1386		return request_plldsi(enable);1387	else if (clock == PRCMU_SYSCLK)1388		return request_sysclk(enable);1389	else if ((clock == PRCMU_PLLSOC0) || (clock == PRCMU_PLLSOC1))1390		return request_pll(clock, enable);1391	else1392		return -EINVAL;1393}1394 1395static unsigned long pll_rate(void __iomem *reg, unsigned long src_rate,1396	int branch)1397{1398	u64 rate;1399	u32 val;1400	u32 d;1401	u32 div = 1;1402 1403	val = readl(reg);1404 1405	rate = src_rate;1406	rate *= ((val & PRCM_PLL_FREQ_D_MASK) >> PRCM_PLL_FREQ_D_SHIFT);1407 1408	d = ((val & PRCM_PLL_FREQ_N_MASK) >> PRCM_PLL_FREQ_N_SHIFT);1409	if (d > 1)1410		div *= d;1411 1412	d = ((val & PRCM_PLL_FREQ_R_MASK) >> PRCM_PLL_FREQ_R_SHIFT);1413	if (d > 1)1414		div *= d;1415 1416	if (val & PRCM_PLL_FREQ_SELDIV2)1417		div *= 2;1418 1419	if ((branch == PLL_FIX) || ((branch == PLL_DIV) &&1420		(val & PRCM_PLL_FREQ_DIV2EN) &&1421		((reg == PRCM_PLLSOC0_FREQ) ||1422		 (reg == PRCM_PLLARM_FREQ) ||1423		 (reg == PRCM_PLLDDR_FREQ))))1424		div *= 2;1425 1426	(void)do_div(rate, div);1427 1428	return (unsigned long)rate;1429}1430 1431#define ROOT_CLOCK_RATE 384000001432 1433static unsigned long clock_rate(u8 clock)1434{1435	u32 val;1436	u32 pllsw;1437	unsigned long rate = ROOT_CLOCK_RATE;1438 1439	val = readl(prcmu_base + clk_mgt[clock].offset);1440 1441	if (val & PRCM_CLK_MGT_CLK38) {1442		if (clk_mgt[clock].clk38div && (val & PRCM_CLK_MGT_CLK38DIV))1443			rate /= 2;1444		return rate;1445	}1446 1447	val |= clk_mgt[clock].pllsw;1448	pllsw = (val & PRCM_CLK_MGT_CLKPLLSW_MASK);1449 1450	if (pllsw == PRCM_CLK_MGT_CLKPLLSW_SOC0)1451		rate = pll_rate(PRCM_PLLSOC0_FREQ, rate, clk_mgt[clock].branch);1452	else if (pllsw == PRCM_CLK_MGT_CLKPLLSW_SOC1)1453		rate = pll_rate(PRCM_PLLSOC1_FREQ, rate, clk_mgt[clock].branch);1454	else if (pllsw == PRCM_CLK_MGT_CLKPLLSW_DDR)1455		rate = pll_rate(PRCM_PLLDDR_FREQ, rate, clk_mgt[clock].branch);1456	else1457		return 0;1458 1459	if ((clock == PRCMU_SGACLK) &&1460		(val & PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN)) {1461		u64 r = (rate * 10);1462 1463		(void)do_div(r, 25);1464		return (unsigned long)r;1465	}1466	val &= PRCM_CLK_MGT_CLKPLLDIV_MASK;1467	if (val)1468		return rate / val;1469	else1470		return 0;1471}1472 1473static unsigned long armss_rate(void)1474{1475	u32 r;1476	unsigned long rate;1477 1478	r = readl(PRCM_ARM_CHGCLKREQ);1479 1480	if (r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_CHGCLKREQ) {1481		/* External ARMCLKFIX clock */1482 1483		rate = pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_FIX);1484 1485		/* Check PRCM_ARM_CHGCLKREQ divider */1486		if (!(r & PRCM_ARM_CHGCLKREQ_PRCM_ARM_DIVSEL))1487			rate /= 2;1488 1489		/* Check PRCM_ARMCLKFIX_MGT divider */1490		r = readl(PRCM_ARMCLKFIX_MGT);1491		r &= PRCM_CLK_MGT_CLKPLLDIV_MASK;1492		rate /= r;1493 1494	} else {/* ARM PLL */1495		rate = pll_rate(PRCM_PLLARM_FREQ, ROOT_CLOCK_RATE, PLL_DIV);1496	}1497 1498	return rate;1499}1500 1501static unsigned long dsiclk_rate(u8 n)1502{1503	u32 divsel;1504	u32 div = 1;1505 1506	divsel = readl(PRCM_DSI_PLLOUT_SEL);1507	divsel = ((divsel & dsiclk[n].divsel_mask) >> dsiclk[n].divsel_shift);1508 1509	if (divsel == PRCM_DSI_PLLOUT_SEL_OFF)1510		divsel = dsiclk[n].divsel;1511	else1512		dsiclk[n].divsel = divsel;1513 1514	switch (divsel) {1515	case PRCM_DSI_PLLOUT_SEL_PHI_4:1516		div *= 2;1517		fallthrough;1518	case PRCM_DSI_PLLOUT_SEL_PHI_2:1519		div *= 2;1520		fallthrough;1521	case PRCM_DSI_PLLOUT_SEL_PHI:1522		return pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK),1523			PLL_RAW) / div;1524	default:1525		return 0;1526	}1527}1528 1529static unsigned long dsiescclk_rate(u8 n)1530{1531	u32 div;1532 1533	div = readl(PRCM_DSITVCLK_DIV);1534	div = ((div & dsiescclk[n].div_mask) >> (dsiescclk[n].div_shift));1535	return clock_rate(PRCMU_TVCLK) / max((u32)1, div);1536}1537 1538unsigned long prcmu_clock_rate(u8 clock)1539{1540	if (clock < PRCMU_NUM_REG_CLOCKS)1541		return clock_rate(clock);1542	else if (clock == PRCMU_TIMCLK)1543		return prcmu_is_ulppll_disabled() ?1544			32768 : ROOT_CLOCK_RATE / 16;1545	else if (clock == PRCMU_SYSCLK)1546		return ROOT_CLOCK_RATE;1547	else if (clock == PRCMU_PLLSOC0)1548		return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, PLL_RAW);1549	else if (clock == PRCMU_PLLSOC1)1550		return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, PLL_RAW);1551	else if (clock == PRCMU_ARMSS)1552		return armss_rate();1553	else if (clock == PRCMU_PLLDDR)1554		return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, PLL_RAW);1555	else if (clock == PRCMU_PLLDSI)1556		return pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK),1557			PLL_RAW);1558	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))1559		return dsiclk_rate(clock - PRCMU_DSI0CLK);1560	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))1561		return dsiescclk_rate(clock - PRCMU_DSI0ESCCLK);1562	else1563		return 0;1564}1565 1566static unsigned long clock_source_rate(u32 clk_mgt_val, int branch)1567{1568	if (clk_mgt_val & PRCM_CLK_MGT_CLK38)1569		return ROOT_CLOCK_RATE;1570	clk_mgt_val &= PRCM_CLK_MGT_CLKPLLSW_MASK;1571	if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_SOC0)1572		return pll_rate(PRCM_PLLSOC0_FREQ, ROOT_CLOCK_RATE, branch);1573	else if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_SOC1)1574		return pll_rate(PRCM_PLLSOC1_FREQ, ROOT_CLOCK_RATE, branch);1575	else if (clk_mgt_val == PRCM_CLK_MGT_CLKPLLSW_DDR)1576		return pll_rate(PRCM_PLLDDR_FREQ, ROOT_CLOCK_RATE, branch);1577	else1578		return 0;1579}1580 1581static u32 clock_divider(unsigned long src_rate, unsigned long rate)1582{1583	u32 div;1584 1585	div = (src_rate / rate);1586	if (div == 0)1587		return 1;1588	if (rate < (src_rate / div))1589		div++;1590	return div;1591}1592 1593static long round_clock_rate(u8 clock, unsigned long rate)1594{1595	u32 val;1596	u32 div;1597	unsigned long src_rate;1598	long rounded_rate;1599 1600	val = readl(prcmu_base + clk_mgt[clock].offset);1601	src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),1602		clk_mgt[clock].branch);1603	div = clock_divider(src_rate, rate);1604	if (val & PRCM_CLK_MGT_CLK38) {1605		if (clk_mgt[clock].clk38div) {1606			if (div > 2)1607				div = 2;1608		} else {1609			div = 1;1610		}1611	} else if ((clock == PRCMU_SGACLK) && (div == 3)) {1612		u64 r = (src_rate * 10);1613 1614		(void)do_div(r, 25);1615		if (r <= rate)1616			return (unsigned long)r;1617	}1618	rounded_rate = (src_rate / min(div, (u32)31));1619 1620	return rounded_rate;1621}1622 1623static const unsigned long db8500_armss_freqs[] = {1624	199680000,1625	399360000,1626	798720000,1627	9984000001628};1629 1630/* The DB8520 has slightly higher ARMSS max frequency */1631static const unsigned long db8520_armss_freqs[] = {1632	199680000,1633	399360000,1634	798720000,1635	11520000001636};1637 1638static long round_armss_rate(unsigned long rate)1639{1640	unsigned long freq = 0;1641	const unsigned long *freqs;1642	int nfreqs;1643	int i;1644 1645	if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) {1646		freqs = db8520_armss_freqs;1647		nfreqs = ARRAY_SIZE(db8520_armss_freqs);1648	} else {1649		freqs = db8500_armss_freqs;1650		nfreqs = ARRAY_SIZE(db8500_armss_freqs);1651	}1652 1653	/* Find the corresponding arm opp from the cpufreq table. */1654	for (i = 0; i < nfreqs; i++) {1655		freq = freqs[i];1656		if (rate <= freq)1657			break;1658	}1659 1660	/* Return the last valid value, even if a match was not found. */1661	return freq;1662}1663 1664#define MIN_PLL_VCO_RATE 600000000ULL1665#define MAX_PLL_VCO_RATE 1680640000ULL1666 1667static long round_plldsi_rate(unsigned long rate)1668{1669	long rounded_rate = 0;1670	unsigned long src_rate;1671	unsigned long rem;1672	u32 r;1673 1674	src_rate = clock_rate(PRCMU_HDMICLK);1675	rem = rate;1676 1677	for (r = 7; (rem > 0) && (r > 0); r--) {1678		u64 d;1679 1680		d = (r * rate);1681		(void)do_div(d, src_rate);1682		if (d < 6)1683			d = 6;1684		else if (d > 255)1685			d = 255;1686		d *= src_rate;1687		if (((2 * d) < (r * MIN_PLL_VCO_RATE)) ||1688			((r * MAX_PLL_VCO_RATE) < (2 * d)))1689			continue;1690		(void)do_div(d, r);1691		if (rate < d) {1692			if (rounded_rate == 0)1693				rounded_rate = (long)d;1694			break;1695		}1696		if ((rate - d) < rem) {1697			rem = (rate - d);1698			rounded_rate = (long)d;1699		}1700	}1701	return rounded_rate;1702}1703 1704static long round_dsiclk_rate(unsigned long rate)1705{1706	u32 div;1707	unsigned long src_rate;1708	long rounded_rate;1709 1710	src_rate = pll_rate(PRCM_PLLDSI_FREQ, clock_rate(PRCMU_HDMICLK),1711		PLL_RAW);1712	div = clock_divider(src_rate, rate);1713	rounded_rate = (src_rate / ((div > 2) ? 4 : div));1714 1715	return rounded_rate;1716}1717 1718static long round_dsiescclk_rate(unsigned long rate)1719{1720	u32 div;1721	unsigned long src_rate;1722	long rounded_rate;1723 1724	src_rate = clock_rate(PRCMU_TVCLK);1725	div = clock_divider(src_rate, rate);1726	rounded_rate = (src_rate / min(div, (u32)255));1727 1728	return rounded_rate;1729}1730 1731long prcmu_round_clock_rate(u8 clock, unsigned long rate)1732{1733	if (clock < PRCMU_NUM_REG_CLOCKS)1734		return round_clock_rate(clock, rate);1735	else if (clock == PRCMU_ARMSS)1736		return round_armss_rate(rate);1737	else if (clock == PRCMU_PLLDSI)1738		return round_plldsi_rate(rate);1739	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))1740		return round_dsiclk_rate(rate);1741	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))1742		return round_dsiescclk_rate(rate);1743	else1744		return (long)prcmu_clock_rate(clock);1745}1746 1747static void set_clock_rate(u8 clock, unsigned long rate)1748{1749	u32 val;1750	u32 div;1751	unsigned long src_rate;1752	unsigned long flags;1753 1754	spin_lock_irqsave(&clk_mgt_lock, flags);1755 1756	/* Grab the HW semaphore. */1757	while ((readl(PRCM_SEM) & PRCM_SEM_PRCM_SEM) != 0)1758		cpu_relax();1759 1760	val = readl(prcmu_base + clk_mgt[clock].offset);1761	src_rate = clock_source_rate((val | clk_mgt[clock].pllsw),1762		clk_mgt[clock].branch);1763	div = clock_divider(src_rate, rate);1764	if (val & PRCM_CLK_MGT_CLK38) {1765		if (clk_mgt[clock].clk38div) {1766			if (div > 1)1767				val |= PRCM_CLK_MGT_CLK38DIV;1768			else1769				val &= ~PRCM_CLK_MGT_CLK38DIV;1770		}1771	} else if (clock == PRCMU_SGACLK) {1772		val &= ~(PRCM_CLK_MGT_CLKPLLDIV_MASK |1773			PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN);1774		if (div == 3) {1775			u64 r = (src_rate * 10);1776 1777			(void)do_div(r, 25);1778			if (r <= rate) {1779				val |= PRCM_SGACLK_MGT_SGACLKDIV_BY_2_5_EN;1780				div = 0;1781			}1782		}1783		val |= min(div, (u32)31);1784	} else {1785		val &= ~PRCM_CLK_MGT_CLKPLLDIV_MASK;1786		val |= min(div, (u32)31);1787	}1788	writel(val, prcmu_base + clk_mgt[clock].offset);1789 1790	/* Release the HW semaphore. */1791	writel(0, PRCM_SEM);1792 1793	spin_unlock_irqrestore(&clk_mgt_lock, flags);1794}1795 1796static int set_armss_rate(unsigned long rate)1797{1798	unsigned long freq;1799	u8 opps[] = { ARM_EXTCLK, ARM_50_OPP, ARM_100_OPP, ARM_MAX_OPP };1800	const unsigned long *freqs;1801	int nfreqs;1802	int i;1803 1804	if (fw_info.version.project == PRCMU_FW_PROJECT_U8520) {1805		freqs = db8520_armss_freqs;1806		nfreqs = ARRAY_SIZE(db8520_armss_freqs);1807	} else {1808		freqs = db8500_armss_freqs;1809		nfreqs = ARRAY_SIZE(db8500_armss_freqs);1810	}1811 1812	/* Find the corresponding arm opp from the cpufreq table. */1813	for (i = 0; i < nfreqs; i++) {1814		freq = freqs[i];1815		if (rate == freq)1816			break;1817	}1818 1819	if (rate != freq)1820		return -EINVAL;1821 1822	/* Set the new arm opp. */1823	pr_debug("SET ARM OPP 0x%02x\n", opps[i]);1824	return db8500_prcmu_set_arm_opp(opps[i]);1825}1826 1827static int set_plldsi_rate(unsigned long rate)1828{1829	unsigned long src_rate;1830	unsigned long rem;1831	u32 pll_freq = 0;1832	u32 r;1833 1834	src_rate = clock_rate(PRCMU_HDMICLK);1835	rem = rate;1836 1837	for (r = 7; (rem > 0) && (r > 0); r--) {1838		u64 d;1839		u64 hwrate;1840 1841		d = (r * rate);1842		(void)do_div(d, src_rate);1843		if (d < 6)1844			d = 6;1845		else if (d > 255)1846			d = 255;1847		hwrate = (d * src_rate);1848		if (((2 * hwrate) < (r * MIN_PLL_VCO_RATE)) ||1849			((r * MAX_PLL_VCO_RATE) < (2 * hwrate)))1850			continue;1851		(void)do_div(hwrate, r);1852		if (rate < hwrate) {1853			if (pll_freq == 0)1854				pll_freq = (((u32)d << PRCM_PLL_FREQ_D_SHIFT) |1855					(r << PRCM_PLL_FREQ_R_SHIFT));1856			break;1857		}1858		if ((rate - hwrate) < rem) {1859			rem = (rate - hwrate);1860			pll_freq = (((u32)d << PRCM_PLL_FREQ_D_SHIFT) |1861				(r << PRCM_PLL_FREQ_R_SHIFT));1862		}1863	}1864	if (pll_freq == 0)1865		return -EINVAL;1866 1867	pll_freq |= (1 << PRCM_PLL_FREQ_N_SHIFT);1868	writel(pll_freq, PRCM_PLLDSI_FREQ);1869 1870	return 0;1871}1872 1873static void set_dsiclk_rate(u8 n, unsigned long rate)1874{1875	u32 val;1876	u32 div;1877 1878	div = clock_divider(pll_rate(PRCM_PLLDSI_FREQ,1879			clock_rate(PRCMU_HDMICLK), PLL_RAW), rate);1880 1881	dsiclk[n].divsel = (div == 1) ? PRCM_DSI_PLLOUT_SEL_PHI :1882			   (div == 2) ? PRCM_DSI_PLLOUT_SEL_PHI_2 :1883			   /* else */	PRCM_DSI_PLLOUT_SEL_PHI_4;1884 1885	val = readl(PRCM_DSI_PLLOUT_SEL);1886	val &= ~dsiclk[n].divsel_mask;1887	val |= (dsiclk[n].divsel << dsiclk[n].divsel_shift);1888	writel(val, PRCM_DSI_PLLOUT_SEL);1889}1890 1891static void set_dsiescclk_rate(u8 n, unsigned long rate)1892{1893	u32 val;1894	u32 div;1895 1896	div = clock_divider(clock_rate(PRCMU_TVCLK), rate);1897	val = readl(PRCM_DSITVCLK_DIV);1898	val &= ~dsiescclk[n].div_mask;1899	val |= (min(div, (u32)255) << dsiescclk[n].div_shift);1900	writel(val, PRCM_DSITVCLK_DIV);1901}1902 1903int prcmu_set_clock_rate(u8 clock, unsigned long rate)1904{1905	if (clock < PRCMU_NUM_REG_CLOCKS)1906		set_clock_rate(clock, rate);1907	else if (clock == PRCMU_ARMSS)1908		return set_armss_rate(rate);1909	else if (clock == PRCMU_PLLDSI)1910		return set_plldsi_rate(rate);1911	else if ((clock == PRCMU_DSI0CLK) || (clock == PRCMU_DSI1CLK))1912		set_dsiclk_rate((clock - PRCMU_DSI0CLK), rate);1913	else if ((PRCMU_DSI0ESCCLK <= clock) && (clock <= PRCMU_DSI2ESCCLK))1914		set_dsiescclk_rate((clock - PRCMU_DSI0ESCCLK), rate);1915	return 0;1916}1917 1918int db8500_prcmu_config_esram0_deep_sleep(u8 state)1919{1920	if ((state > ESRAM0_DEEP_SLEEP_STATE_RET) ||1921	    (state < ESRAM0_DEEP_SLEEP_STATE_OFF))1922		return -EINVAL;1923 1924	mutex_lock(&mb4_transfer.lock);1925 1926	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))1927		cpu_relax();1928 1929	writeb(MB4H_MEM_ST, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));1930	writeb(((DDR_PWR_STATE_OFFHIGHLAT << 4) | DDR_PWR_STATE_ON),1931	       (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_SLEEP_IDLE));1932	writeb(DDR_PWR_STATE_ON,1933	       (tcdm_base + PRCM_REQ_MB4_DDR_ST_AP_DEEP_IDLE));1934	writeb(state, (tcdm_base + PRCM_REQ_MB4_ESRAM0_ST));1935 1936	writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET);1937	wait_for_completion(&mb4_transfer.work);1938 1939	mutex_unlock(&mb4_transfer.lock);1940 1941	return 0;1942}1943 1944int db8500_prcmu_config_hotdog(u8 threshold)1945{1946	mutex_lock(&mb4_transfer.lock);1947 1948	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))1949		cpu_relax();1950 1951	writeb(threshold, (tcdm_base + PRCM_REQ_MB4_HOTDOG_THRESHOLD));1952	writeb(MB4H_HOTDOG, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));1953 1954	writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET);1955	wait_for_completion(&mb4_transfer.work);1956 1957	mutex_unlock(&mb4_transfer.lock);1958 1959	return 0;1960}1961 1962int db8500_prcmu_config_hotmon(u8 low, u8 high)1963{1964	mutex_lock(&mb4_transfer.lock);1965 1966	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))1967		cpu_relax();1968 1969	writeb(low, (tcdm_base + PRCM_REQ_MB4_HOTMON_LOW));1970	writeb(high, (tcdm_base + PRCM_REQ_MB4_HOTMON_HIGH));1971	writeb((HOTMON_CONFIG_LOW | HOTMON_CONFIG_HIGH),1972		(tcdm_base + PRCM_REQ_MB4_HOTMON_CONFIG));1973	writeb(MB4H_HOTMON, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));1974 1975	writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET);1976	wait_for_completion(&mb4_transfer.work);1977 1978	mutex_unlock(&mb4_transfer.lock);1979 1980	return 0;1981}1982EXPORT_SYMBOL_GPL(db8500_prcmu_config_hotmon);1983 1984static int config_hot_period(u16 val)1985{1986	mutex_lock(&mb4_transfer.lock);1987 1988	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))1989		cpu_relax();1990 1991	writew(val, (tcdm_base + PRCM_REQ_MB4_HOT_PERIOD));1992	writeb(MB4H_HOT_PERIOD, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));1993 1994	writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET);1995	wait_for_completion(&mb4_transfer.work);1996 1997	mutex_unlock(&mb4_transfer.lock);1998 1999	return 0;2000}2001 2002int db8500_prcmu_start_temp_sense(u16 cycles32k)2003{2004	if (cycles32k == 0xFFFF)2005		return -EINVAL;2006 2007	return config_hot_period(cycles32k);2008}2009EXPORT_SYMBOL_GPL(db8500_prcmu_start_temp_sense);2010 2011int db8500_prcmu_stop_temp_sense(void)2012{2013	return config_hot_period(0xFFFF);2014}2015EXPORT_SYMBOL_GPL(db8500_prcmu_stop_temp_sense);2016 2017static int prcmu_a9wdog(u8 cmd, u8 d0, u8 d1, u8 d2, u8 d3)2018{2019 2020	mutex_lock(&mb4_transfer.lock);2021 2022	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(4))2023		cpu_relax();2024 2025	writeb(d0, (tcdm_base + PRCM_REQ_MB4_A9WDOG_0));2026	writeb(d1, (tcdm_base + PRCM_REQ_MB4_A9WDOG_1));2027	writeb(d2, (tcdm_base + PRCM_REQ_MB4_A9WDOG_2));2028	writeb(d3, (tcdm_base + PRCM_REQ_MB4_A9WDOG_3));2029 2030	writeb(cmd, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB4));2031 2032	writel(MBOX_BIT(4), PRCM_MBOX_CPU_SET);2033	wait_for_completion(&mb4_transfer.work);2034 2035	mutex_unlock(&mb4_transfer.lock);2036 2037	return 0;2038 2039}2040 2041int db8500_prcmu_config_a9wdog(u8 num, bool sleep_auto_off)2042{2043	BUG_ON(num == 0 || num > 0xf);2044	return prcmu_a9wdog(MB4H_A9WDOG_CONF, num, 0, 0,2045			    sleep_auto_off ? A9WDOG_AUTO_OFF_EN :2046			    A9WDOG_AUTO_OFF_DIS);2047}2048EXPORT_SYMBOL(db8500_prcmu_config_a9wdog);2049 2050int db8500_prcmu_enable_a9wdog(u8 id)2051{2052	return prcmu_a9wdog(MB4H_A9WDOG_EN, id, 0, 0, 0);2053}2054EXPORT_SYMBOL(db8500_prcmu_enable_a9wdog);2055 2056int db8500_prcmu_disable_a9wdog(u8 id)2057{2058	return prcmu_a9wdog(MB4H_A9WDOG_DIS, id, 0, 0, 0);2059}2060EXPORT_SYMBOL(db8500_prcmu_disable_a9wdog);2061 2062int db8500_prcmu_kick_a9wdog(u8 id)2063{2064	return prcmu_a9wdog(MB4H_A9WDOG_KICK, id, 0, 0, 0);2065}2066EXPORT_SYMBOL(db8500_prcmu_kick_a9wdog);2067 2068/*2069 * timeout is 28 bit, in ms.2070 */2071int db8500_prcmu_load_a9wdog(u8 id, u32 timeout)2072{2073	return prcmu_a9wdog(MB4H_A9WDOG_LOAD,2074			    (id & A9WDOG_ID_MASK) |2075			    /*2076			     * Put the lowest 28 bits of timeout at2077			     * offset 4. Four first bits are used for id.2078			     */2079			    (u8)((timeout << 4) & 0xf0),2080			    (u8)((timeout >> 4) & 0xff),2081			    (u8)((timeout >> 12) & 0xff),2082			    (u8)((timeout >> 20) & 0xff));2083}2084EXPORT_SYMBOL(db8500_prcmu_load_a9wdog);2085 2086/**2087 * prcmu_abb_read() - Read register value(s) from the ABB.2088 * @slave:	The I2C slave address.2089 * @reg:	The (start) register address.2090 * @value:	The read out value(s).2091 * @size:	The number of registers to read.2092 *2093 * Reads register value(s) from the ABB.2094 * @size has to be 1 for the current firmware version.2095 */2096int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)2097{2098	int r;2099 2100	if (size != 1)2101		return -EINVAL;2102 2103	mutex_lock(&mb5_transfer.lock);2104 2105	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))2106		cpu_relax();2107 2108	writeb(0, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB5));2109	writeb(PRCMU_I2C_READ(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP));2110	writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS));2111	writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG));2112	writeb(0, (tcdm_base + PRCM_REQ_MB5_I2C_VAL));2113 2114	writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);2115 2116	if (!wait_for_completion_timeout(&mb5_transfer.work,2117				msecs_to_jiffies(20000))) {2118		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",2119			__func__);2120		r = -EIO;2121	} else {2122		r = ((mb5_transfer.ack.status == I2C_RD_OK) ? 0 : -EIO);2123	}2124 2125	if (!r)2126		*value = mb5_transfer.ack.value;2127 2128	mutex_unlock(&mb5_transfer.lock);2129 2130	return r;2131}2132 2133/**2134 * prcmu_abb_write_masked() - Write masked register value(s) to the ABB.2135 * @slave:	The I2C slave address.2136 * @reg:	The (start) register address.2137 * @value:	The value(s) to write.2138 * @mask:	The mask(s) to use.2139 * @size:	The number of registers to write.2140 *2141 * Writes masked register value(s) to the ABB.2142 * For each @value, only the bits set to 1 in the corresponding @mask2143 * will be written. The other bits are not changed.2144 * @size has to be 1 for the current firmware version.2145 */2146int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value, u8 *mask, u8 size)2147{2148	int r;2149 2150	if (size != 1)2151		return -EINVAL;2152 2153	mutex_lock(&mb5_transfer.lock);2154 2155	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(5))2156		cpu_relax();2157 2158	writeb(~*mask, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB5));2159	writeb(PRCMU_I2C_WRITE(slave), (tcdm_base + PRCM_REQ_MB5_I2C_SLAVE_OP));2160	writeb(PRCMU_I2C_STOP_EN, (tcdm_base + PRCM_REQ_MB5_I2C_HW_BITS));2161	writeb(reg, (tcdm_base + PRCM_REQ_MB5_I2C_REG));2162	writeb(*value, (tcdm_base + PRCM_REQ_MB5_I2C_VAL));2163 2164	writel(MBOX_BIT(5), PRCM_MBOX_CPU_SET);2165 2166	if (!wait_for_completion_timeout(&mb5_transfer.work,2167				msecs_to_jiffies(20000))) {2168		pr_err("prcmu: %s timed out (20 s) waiting for a reply.\n",2169			__func__);2170		r = -EIO;2171	} else {2172		r = ((mb5_transfer.ack.status == I2C_WR_OK) ? 0 : -EIO);2173	}2174 2175	mutex_unlock(&mb5_transfer.lock);2176 2177	return r;2178}2179 2180/**2181 * prcmu_abb_write() - Write register value(s) to the ABB.2182 * @slave:	The I2C slave address.2183 * @reg:	The (start) register address.2184 * @value:	The value(s) to write.2185 * @size:	The number of registers to write.2186 *2187 * Writes register value(s) to the ABB.2188 * @size has to be 1 for the current firmware version.2189 */2190int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)2191{2192	u8 mask = ~0;2193 2194	return prcmu_abb_write_masked(slave, reg, value, &mask, size);2195}2196 2197/**2198 * prcmu_ac_wake_req - should be called whenever ARM wants to wakeup Modem2199 */2200int prcmu_ac_wake_req(void)2201{2202	u32 val;2203	int ret = 0;2204 2205	mutex_lock(&mb0_transfer.ac_wake_lock);2206 2207	val = readl(PRCM_HOSTACCESS_REQ);2208	if (val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ)2209		goto unlock_and_return;2210 2211	atomic_set(&ac_wake_req_state, 1);2212 2213	/*2214	 * Force Modem Wake-up before hostaccess_req ping-pong.2215	 * It prevents Modem to enter in Sleep while acking the hostaccess2216	 * request. The 31us delay has been calculated by HWI.2217	 */2218	val |= PRCM_HOSTACCESS_REQ_WAKE_REQ;2219	writel(val, PRCM_HOSTACCESS_REQ);2220 2221	udelay(31);2222 2223	val |= PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ;2224	writel(val, PRCM_HOSTACCESS_REQ);2225 2226	if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work,2227			msecs_to_jiffies(5000))) {2228		pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n",2229			__func__);2230		ret = -EFAULT;2231	}2232 2233unlock_and_return:2234	mutex_unlock(&mb0_transfer.ac_wake_lock);2235	return ret;2236}2237 2238/**2239 * prcmu_ac_sleep_req - called when ARM no longer needs to talk to modem2240 */2241void prcmu_ac_sleep_req(void)2242{2243	u32 val;2244 2245	mutex_lock(&mb0_transfer.ac_wake_lock);2246 2247	val = readl(PRCM_HOSTACCESS_REQ);2248	if (!(val & PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ))2249		goto unlock_and_return;2250 2251	writel((val & ~PRCM_HOSTACCESS_REQ_HOSTACCESS_REQ),2252		PRCM_HOSTACCESS_REQ);2253 2254	if (!wait_for_completion_timeout(&mb0_transfer.ac_wake_work,2255			msecs_to_jiffies(5000))) {2256		pr_crit("prcmu: %s timed out (5 s) waiting for a reply.\n",2257			__func__);2258	}2259 2260	atomic_set(&ac_wake_req_state, 0);2261 2262unlock_and_return:2263	mutex_unlock(&mb0_transfer.ac_wake_lock);2264}2265 2266bool db8500_prcmu_is_ac_wake_requested(void)2267{2268	return (atomic_read(&ac_wake_req_state) != 0);2269}2270 2271/**2272 * db8500_prcmu_system_reset - System reset2273 *2274 * Saves the reset reason code and then sets the APE_SOFTRST register which2275 * fires interrupt to fw2276 *2277 * @reset_code: The reason for system reset2278 */2279void db8500_prcmu_system_reset(u16 reset_code)2280{2281	writew(reset_code, (tcdm_base + PRCM_SW_RST_REASON));2282	writel(1, PRCM_APE_SOFTRST);2283}2284 2285/**2286 * db8500_prcmu_get_reset_code - Retrieve SW reset reason code2287 *2288 * Retrieves the reset reason code stored by prcmu_system_reset() before2289 * last restart.2290 */2291u16 db8500_prcmu_get_reset_code(void)2292{2293	return readw(tcdm_base + PRCM_SW_RST_REASON);2294}2295 2296/**2297 * db8500_prcmu_modem_reset - ask the PRCMU to reset modem2298 */2299void db8500_prcmu_modem_reset(void)2300{2301	mutex_lock(&mb1_transfer.lock);2302 2303	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(1))2304		cpu_relax();2305 2306	writeb(MB1H_RESET_MODEM, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB1));2307	writel(MBOX_BIT(1), PRCM_MBOX_CPU_SET);2308	wait_for_completion(&mb1_transfer.work);2309 2310	/*2311	 * No need to check return from PRCMU as modem should go in reset state2312	 * This state is already managed by upper layer2313	 */2314 2315	mutex_unlock(&mb1_transfer.lock);2316}2317 2318static void ack_dbb_wakeup(void)2319{2320	unsigned long flags;2321 2322	spin_lock_irqsave(&mb0_transfer.lock, flags);2323 2324	while (readl(PRCM_MBOX_CPU_VAL) & MBOX_BIT(0))2325		cpu_relax();2326 2327	writeb(MB0H_READ_WAKEUP_ACK, (tcdm_base + PRCM_MBOX_HEADER_REQ_MB0));2328	writel(MBOX_BIT(0), PRCM_MBOX_CPU_SET);2329 2330	spin_unlock_irqrestore(&mb0_transfer.lock, flags);2331}2332 2333static inline void print_unknown_header_warning(u8 n, u8 header)2334{2335	pr_warn("prcmu: Unknown message header (%d) in mailbox %d\n",2336		header, n);2337}2338 2339static bool read_mailbox_0(void)2340{2341	bool r;2342	u32 ev;2343	unsigned int n;2344	u8 header;2345 2346	header = readb(tcdm_base + PRCM_MBOX_HEADER_ACK_MB0);2347	switch (header) {2348	case MB0H_WAKEUP_EXE:2349	case MB0H_WAKEUP_SLEEP:2350		if (readb(tcdm_base + PRCM_ACK_MB0_READ_POINTER) & 1)2351			ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_1_8500);2352		else2353			ev = readl(tcdm_base + PRCM_ACK_MB0_WAKEUP_0_8500);2354 2355		if (ev & (WAKEUP_BIT_AC_WAKE_ACK | WAKEUP_BIT_AC_SLEEP_ACK))2356			complete(&mb0_transfer.ac_wake_work);2357		if (ev & WAKEUP_BIT_SYSCLK_OK)2358			complete(&mb3_transfer.sysclk_work);2359 2360		ev &= mb0_transfer.req.dbb_irqs;2361 2362		for (n = 0; n < NUM_PRCMU_WAKEUPS; n++) {2363			if (ev & prcmu_irq_bit[n])2364				generic_handle_domain_irq(db8500_irq_domain, n);2365		}2366		r = true;2367		break;2368	default:2369		print_unknown_header_warning(0, header);2370		r = false;2371		break;2372	}2373	writel(MBOX_BIT(0), PRCM_ARM_IT1_CLR);2374	return r;2375}2376 2377static bool read_mailbox_1(void)2378{2379	mb1_transfer.ack.header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB1);2380	mb1_transfer.ack.arm_opp = readb(tcdm_base +2381		PRCM_ACK_MB1_CURRENT_ARM_OPP);2382	mb1_transfer.ack.ape_opp = readb(tcdm_base +2383		PRCM_ACK_MB1_CURRENT_APE_OPP);2384	mb1_transfer.ack.ape_voltage_status = readb(tcdm_base +2385		PRCM_ACK_MB1_APE_VOLTAGE_STATUS);2386	writel(MBOX_BIT(1), PRCM_ARM_IT1_CLR);2387	complete(&mb1_transfer.work);2388	return false;2389}2390 2391static bool read_mailbox_2(void)2392{2393	mb2_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB2_DPS_STATUS);2394	writel(MBOX_BIT(2), PRCM_ARM_IT1_CLR);2395	complete(&mb2_transfer.work);2396	return false;2397}2398 2399static bool read_mailbox_3(void)2400{2401	writel(MBOX_BIT(3), PRCM_ARM_IT1_CLR);2402	return false;2403}2404 2405static bool read_mailbox_4(void)2406{2407	u8 header;2408	bool do_complete = true;2409 2410	header = readb(tcdm_base + PRCM_MBOX_HEADER_REQ_MB4);2411	switch (header) {2412	case MB4H_MEM_ST:2413	case MB4H_HOTDOG:2414	case MB4H_HOTMON:2415	case MB4H_HOT_PERIOD:2416	case MB4H_A9WDOG_CONF:2417	case MB4H_A9WDOG_EN:2418	case MB4H_A9WDOG_DIS:2419	case MB4H_A9WDOG_LOAD:2420	case MB4H_A9WDOG_KICK:2421		break;2422	default:2423		print_unknown_header_warning(4, header);2424		do_complete = false;2425		break;2426	}2427 2428	writel(MBOX_BIT(4), PRCM_ARM_IT1_CLR);2429 2430	if (do_complete)2431		complete(&mb4_transfer.work);2432 2433	return false;2434}2435 2436static bool read_mailbox_5(void)2437{2438	mb5_transfer.ack.status = readb(tcdm_base + PRCM_ACK_MB5_I2C_STATUS);2439	mb5_transfer.ack.value = readb(tcdm_base + PRCM_ACK_MB5_I2C_VAL);2440	writel(MBOX_BIT(5), PRCM_ARM_IT1_CLR);2441	complete(&mb5_transfer.work);2442	return false;2443}2444 2445static bool read_mailbox_6(void)2446{2447	writel(MBOX_BIT(6), PRCM_ARM_IT1_CLR);2448	return false;2449}2450 2451static bool read_mailbox_7(void)2452{2453	writel(MBOX_BIT(7), PRCM_ARM_IT1_CLR);2454	return false;2455}2456 2457static bool (* const read_mailbox[NUM_MB])(void) = {2458	read_mailbox_0,2459	read_mailbox_1,2460	read_mailbox_2,2461	read_mailbox_3,2462	read_mailbox_4,2463	read_mailbox_5,2464	read_mailbox_6,2465	read_mailbox_72466};2467 2468static irqreturn_t prcmu_irq_handler(int irq, void *data)2469{2470	u32 bits;2471	u8 n;2472	irqreturn_t r;2473 2474	bits = (readl(PRCM_ARM_IT1_VAL) & ALL_MBOX_BITS);2475	if (unlikely(!bits))2476		return IRQ_NONE;2477 2478	r = IRQ_HANDLED;2479	for (n = 0; bits; n++) {2480		if (bits & MBOX_BIT(n)) {2481			bits -= MBOX_BIT(n);2482			if (read_mailbox[n]())2483				r = IRQ_WAKE_THREAD;2484		}2485	}2486	return r;2487}2488 2489static irqreturn_t prcmu_irq_thread_fn(int irq, void *data)2490{2491	ack_dbb_wakeup();2492	return IRQ_HANDLED;2493}2494 2495static void prcmu_mask_work(struct work_struct *work)2496{2497	unsigned long flags;2498 2499	spin_lock_irqsave(&mb0_transfer.lock, flags);2500 2501	config_wakeups();2502 2503	spin_unlock_irqrestore(&mb0_transfer.lock, flags);2504}2505 2506static void prcmu_irq_mask(struct irq_data *d)2507{2508	unsigned long flags;2509 2510	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);2511 2512	mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->hwirq];2513 2514	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);2515 2516	if (d->irq != IRQ_PRCMU_CA_SLEEP)2517		schedule_work(&mb0_transfer.mask_work);2518}2519 2520static void prcmu_irq_unmask(struct irq_data *d)2521{2522	unsigned long flags;2523 2524	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);2525 2526	mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->hwirq];2527 2528	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);2529 2530	if (d->irq != IRQ_PRCMU_CA_SLEEP)2531		schedule_work(&mb0_transfer.mask_work);2532}2533 2534static void noop(struct irq_data *d)2535{2536}2537 2538static struct irq_chip prcmu_irq_chip = {2539	.name		= "prcmu",2540	.irq_disable	= prcmu_irq_mask,2541	.irq_ack	= noop,2542	.irq_mask	= prcmu_irq_mask,2543	.irq_unmask	= prcmu_irq_unmask,2544};2545 2546static char *fw_project_name(u32 project)2547{2548	switch (project) {2549	case PRCMU_FW_PROJECT_U8500:2550		return "U8500";2551	case PRCMU_FW_PROJECT_U8400:2552		return "U8400";2553	case PRCMU_FW_PROJECT_U9500:2554		return "U9500";2555	case PRCMU_FW_PROJECT_U8500_MBB:2556		return "U8500 MBB";2557	case PRCMU_FW_PROJECT_U8500_C1:2558		return "U8500 C1";2559	case PRCMU_FW_PROJECT_U8500_C2:2560		return "U8500 C2";2561	case PRCMU_FW_PROJECT_U8500_C3:2562		return "U8500 C3";2563	case PRCMU_FW_PROJECT_U8500_C4:2564		return "U8500 C4";2565	case PRCMU_FW_PROJECT_U9500_MBL:2566		return "U9500 MBL";2567	case PRCMU_FW_PROJECT_U8500_SSG1:2568		return "U8500 Samsung 1";2569	case PRCMU_FW_PROJECT_U8500_MBL2:2570		return "U8500 MBL2";2571	case PRCMU_FW_PROJECT_U8520:2572		return "U8520 MBL";2573	case PRCMU_FW_PROJECT_U8420:2574		return "U8420";2575	case PRCMU_FW_PROJECT_U8500_SSG2:2576		return "U8500 Samsung 2";2577	case PRCMU_FW_PROJECT_U8420_SYSCLK:2578		return "U8420-sysclk";2579	case PRCMU_FW_PROJECT_U9540:2580		return "U9540";2581	case PRCMU_FW_PROJECT_A9420:2582		return "A9420";2583	case PRCMU_FW_PROJECT_L8540:2584		return "L8540";2585	case PRCMU_FW_PROJECT_L8580:2586		return "L8580";2587	default:2588		return "Unknown";2589	}2590}2591 2592static int db8500_irq_map(struct irq_domain *d, unsigned int virq,2593				irq_hw_number_t hwirq)2594{2595	irq_set_chip_and_handler(virq, &prcmu_irq_chip,2596				handle_simple_irq);2597 2598	return 0;2599}2600 2601static const struct irq_domain_ops db8500_irq_ops = {2602	.map    = db8500_irq_map,2603	.xlate  = irq_domain_xlate_twocell,2604};2605 2606static int db8500_irq_init(struct device_node *np)2607{2608	int i;2609 2610	db8500_irq_domain = irq_domain_add_simple(2611		np, NUM_PRCMU_WAKEUPS, 0,2612		&db8500_irq_ops, NULL);2613 2614	if (!db8500_irq_domain) {2615		pr_err("Failed to create irqdomain\n");2616		return -ENOSYS;2617	}2618 2619	/* All wakeups will be used, so create mappings for all */2620	for (i = 0; i < NUM_PRCMU_WAKEUPS; i++)2621		irq_create_mapping(db8500_irq_domain, i);2622 2623	return 0;2624}2625 2626static void dbx500_fw_version_init(struct device_node *np)2627{2628	void __iomem *tcpm_base;2629	u32 version;2630 2631	tcpm_base = of_iomap(np, 1);2632	if (!tcpm_base) {2633		pr_err("no prcmu tcpm mem region provided\n");2634		return;2635	}2636 2637	version = readl(tcpm_base + DB8500_PRCMU_FW_VERSION_OFFSET);2638	fw_info.version.project = (version & 0xFF);2639	fw_info.version.api_version = (version >> 8) & 0xFF;2640	fw_info.version.func_version = (version >> 16) & 0xFF;2641	fw_info.version.errata = (version >> 24) & 0xFF;2642	strscpy(fw_info.version.project_name,2643		fw_project_name(fw_info.version.project),2644		sizeof(fw_info.version.project_name));2645	fw_info.valid = true;2646	pr_info("PRCMU firmware: %s(%d), version %d.%d.%d\n",2647		fw_info.version.project_name,2648		fw_info.version.project,2649		fw_info.version.api_version,2650		fw_info.version.func_version,2651		fw_info.version.errata);2652	iounmap(tcpm_base);2653}2654 2655void __init db8500_prcmu_early_init(void)2656{2657	/*2658	 * This is a temporary remap to bring up the clocks. It is2659	 * subsequently replaces with a real remap. After the merge of2660	 * the mailbox subsystem all of this early code goes away, and the2661	 * clock driver can probe independently. An early initcall will2662	 * still be needed, but it can be diverted into drivers/clk/ux500.2663	 */2664	struct device_node *np;2665 2666	np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu");2667	prcmu_base = of_iomap(np, 0);2668	if (!prcmu_base) {2669		of_node_put(np);2670		pr_err("%s: ioremap() of prcmu registers failed!\n", __func__);2671		return;2672	}2673	dbx500_fw_version_init(np);2674	of_node_put(np);2675 2676	spin_lock_init(&mb0_transfer.lock);2677	spin_lock_init(&mb0_transfer.dbb_irqs_lock);2678	mutex_init(&mb0_transfer.ac_wake_lock);2679	init_completion(&mb0_transfer.ac_wake_work);2680	mutex_init(&mb1_transfer.lock);2681	init_completion(&mb1_transfer.work);2682	mb1_transfer.ape_opp = APE_NO_CHANGE;2683	mutex_init(&mb2_transfer.lock);2684	init_completion(&mb2_transfer.work);2685	spin_lock_init(&mb2_transfer.auto_pm_lock);2686	spin_lock_init(&mb3_transfer.lock);2687	mutex_init(&mb3_transfer.sysclk_lock);2688	init_completion(&mb3_transfer.sysclk_work);2689	mutex_init(&mb4_transfer.lock);2690	init_completion(&mb4_transfer.work);2691	mutex_init(&mb5_transfer.lock);2692	init_completion(&mb5_transfer.work);2693 2694	INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);2695}2696 2697static void init_prcm_registers(void)2698{2699	u32 val;2700 2701	val = readl(PRCM_A9PL_FORCE_CLKEN);2702	val &= ~(PRCM_A9PL_FORCE_CLKEN_PRCM_A9PL_FORCE_CLKEN |2703		PRCM_A9PL_FORCE_CLKEN_PRCM_A9AXI_FORCE_CLKEN);2704	writel(val, (PRCM_A9PL_FORCE_CLKEN));2705}2706 2707/*2708 * Power domain switches (ePODs) modeled as regulators for the DB8500 SoC2709 */2710static struct regulator_consumer_supply db8500_vape_consumers[] = {2711	REGULATOR_SUPPLY("v-ape", NULL),2712	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.0"),2713	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.1"),2714	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.2"),2715	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.3"),2716	REGULATOR_SUPPLY("v-i2c", "nmk-i2c.4"),2717	/* "v-mmc" changed to "vcore" in the mainline kernel */2718	REGULATOR_SUPPLY("vcore", "sdi0"),2719	REGULATOR_SUPPLY("vcore", "sdi1"),2720	REGULATOR_SUPPLY("vcore", "sdi2"),2721	REGULATOR_SUPPLY("vcore", "sdi3"),2722	REGULATOR_SUPPLY("vcore", "sdi4"),2723	REGULATOR_SUPPLY("v-dma", "dma40.0"),2724	REGULATOR_SUPPLY("v-ape", "ab8500-usb.0"),2725	/* "v-uart" changed to "vcore" in the mainline kernel */2726	REGULATOR_SUPPLY("vcore", "uart0"),2727	REGULATOR_SUPPLY("vcore", "uart1"),2728	REGULATOR_SUPPLY("vcore", "uart2"),2729	REGULATOR_SUPPLY("v-ape", "nmk-ske-keypad.0"),2730	REGULATOR_SUPPLY("v-hsi", "ste_hsi.0"),2731	REGULATOR_SUPPLY("vddvario", "smsc911x.0"),2732};2733 2734static struct regulator_consumer_supply db8500_vsmps2_consumers[] = {2735	REGULATOR_SUPPLY("musb_1v8", "ab8500-usb.0"),2736	/* AV8100 regulator */2737	REGULATOR_SUPPLY("hdmi_1v8", "0-0070"),2738};2739 2740static struct regulator_consumer_supply db8500_b2r2_mcde_consumers[] = {2741	REGULATOR_SUPPLY("vsupply", "b2r2_bus"),2742	REGULATOR_SUPPLY("vsupply", "mcde"),2743};2744 2745/* SVA MMDSP regulator switch */2746static struct regulator_consumer_supply db8500_svammdsp_consumers[] = {2747	REGULATOR_SUPPLY("sva-mmdsp", "cm_control"),2748};2749 2750/* SVA pipe regulator switch */2751static struct regulator_consumer_supply db8500_svapipe_consumers[] = {2752	REGULATOR_SUPPLY("sva-pipe", "cm_control"),2753};2754 2755/* SIA MMDSP regulator switch */2756static struct regulator_consumer_supply db8500_siammdsp_consumers[] = {2757	REGULATOR_SUPPLY("sia-mmdsp", "cm_control"),2758};2759 2760/* SIA pipe regulator switch */2761static struct regulator_consumer_supply db8500_siapipe_consumers[] = {2762	REGULATOR_SUPPLY("sia-pipe", "cm_control"),2763};2764 2765static struct regulator_consumer_supply db8500_sga_consumers[] = {2766	REGULATOR_SUPPLY("v-mali", NULL),2767};2768 2769/* ESRAM1 and 2 regulator switch */2770static struct regulator_consumer_supply db8500_esram12_consumers[] = {2771	REGULATOR_SUPPLY("esram12", "cm_control"),2772};2773 2774/* ESRAM3 and 4 regulator switch */2775static struct regulator_consumer_supply db8500_esram34_consumers[] = {2776	REGULATOR_SUPPLY("v-esram34", "mcde"),2777	REGULATOR_SUPPLY("esram34", "cm_control"),2778	REGULATOR_SUPPLY("lcla_esram", "dma40.0"),2779};2780 2781static struct regulator_init_data db8500_regulators[DB8500_NUM_REGULATORS] = {2782	[DB8500_REGULATOR_VAPE] = {2783		.constraints = {2784			.name = "db8500-vape",2785			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2786			.always_on = true,2787		},2788		.consumer_supplies = db8500_vape_consumers,2789		.num_consumer_supplies = ARRAY_SIZE(db8500_vape_consumers),2790	},2791	[DB8500_REGULATOR_VARM] = {2792		.constraints = {2793			.name = "db8500-varm",2794			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2795		},2796	},2797	[DB8500_REGULATOR_VMODEM] = {2798		.constraints = {2799			.name = "db8500-vmodem",2800			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2801		},2802	},2803	[DB8500_REGULATOR_VPLL] = {2804		.constraints = {2805			.name = "db8500-vpll",2806			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2807		},2808	},2809	[DB8500_REGULATOR_VSMPS1] = {2810		.constraints = {2811			.name = "db8500-vsmps1",2812			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2813		},2814	},2815	[DB8500_REGULATOR_VSMPS2] = {2816		.constraints = {2817			.name = "db8500-vsmps2",2818			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2819		},2820		.consumer_supplies = db8500_vsmps2_consumers,2821		.num_consumer_supplies = ARRAY_SIZE(db8500_vsmps2_consumers),2822	},2823	[DB8500_REGULATOR_VSMPS3] = {2824		.constraints = {2825			.name = "db8500-vsmps3",2826			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2827		},2828	},2829	[DB8500_REGULATOR_VRF1] = {2830		.constraints = {2831			.name = "db8500-vrf1",2832			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2833		},2834	},2835	[DB8500_REGULATOR_SWITCH_SVAMMDSP] = {2836		/* dependency to u8500-vape is handled outside regulator framework */2837		.constraints = {2838			.name = "db8500-sva-mmdsp",2839			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2840		},2841		.consumer_supplies = db8500_svammdsp_consumers,2842		.num_consumer_supplies = ARRAY_SIZE(db8500_svammdsp_consumers),2843	},2844	[DB8500_REGULATOR_SWITCH_SVAMMDSPRET] = {2845		.constraints = {2846			/* "ret" means "retention" */2847			.name = "db8500-sva-mmdsp-ret",2848			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2849		},2850	},2851	[DB8500_REGULATOR_SWITCH_SVAPIPE] = {2852		/* dependency to u8500-vape is handled outside regulator framework */2853		.constraints = {2854			.name = "db8500-sva-pipe",2855			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2856		},2857		.consumer_supplies = db8500_svapipe_consumers,2858		.num_consumer_supplies = ARRAY_SIZE(db8500_svapipe_consumers),2859	},2860	[DB8500_REGULATOR_SWITCH_SIAMMDSP] = {2861		/* dependency to u8500-vape is handled outside regulator framework */2862		.constraints = {2863			.name = "db8500-sia-mmdsp",2864			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2865		},2866		.consumer_supplies = db8500_siammdsp_consumers,2867		.num_consumer_supplies = ARRAY_SIZE(db8500_siammdsp_consumers),2868	},2869	[DB8500_REGULATOR_SWITCH_SIAMMDSPRET] = {2870		.constraints = {2871			.name = "db8500-sia-mmdsp-ret",2872			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2873		},2874	},2875	[DB8500_REGULATOR_SWITCH_SIAPIPE] = {2876		/* dependency to u8500-vape is handled outside regulator framework */2877		.constraints = {2878			.name = "db8500-sia-pipe",2879			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2880		},2881		.consumer_supplies = db8500_siapipe_consumers,2882		.num_consumer_supplies = ARRAY_SIZE(db8500_siapipe_consumers),2883	},2884	[DB8500_REGULATOR_SWITCH_SGA] = {2885		.supply_regulator = "db8500-vape",2886		.constraints = {2887			.name = "db8500-sga",2888			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2889		},2890		.consumer_supplies = db8500_sga_consumers,2891		.num_consumer_supplies = ARRAY_SIZE(db8500_sga_consumers),2892 2893	},2894	[DB8500_REGULATOR_SWITCH_B2R2_MCDE] = {2895		.supply_regulator = "db8500-vape",2896		.constraints = {2897			.name = "db8500-b2r2-mcde",2898			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2899		},2900		.consumer_supplies = db8500_b2r2_mcde_consumers,2901		.num_consumer_supplies = ARRAY_SIZE(db8500_b2r2_mcde_consumers),2902	},2903	[DB8500_REGULATOR_SWITCH_ESRAM12] = {2904		/*2905		 * esram12 is set in retention and supplied by Vsafe when Vape is off,2906		 * no need to hold Vape2907		 */2908		.constraints = {2909			.name = "db8500-esram12",2910			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2911		},2912		.consumer_supplies = db8500_esram12_consumers,2913		.num_consumer_supplies = ARRAY_SIZE(db8500_esram12_consumers),2914	},2915	[DB8500_REGULATOR_SWITCH_ESRAM12RET] = {2916		.constraints = {2917			.name = "db8500-esram12-ret",2918			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2919		},2920	},2921	[DB8500_REGULATOR_SWITCH_ESRAM34] = {2922		/*2923		 * esram34 is set in retention and supplied by Vsafe when Vape is off,2924		 * no need to hold Vape2925		 */2926		.constraints = {2927			.name = "db8500-esram34",2928			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2929		},2930		.consumer_supplies = db8500_esram34_consumers,2931		.num_consumer_supplies = ARRAY_SIZE(db8500_esram34_consumers),2932	},2933	[DB8500_REGULATOR_SWITCH_ESRAM34RET] = {2934		.constraints = {2935			.name = "db8500-esram34-ret",2936			.valid_ops_mask = REGULATOR_CHANGE_STATUS,2937		},2938	},2939};2940 2941static const struct mfd_cell common_prcmu_devs[] = {2942	MFD_CELL_NAME("db8500_wdt"),2943	MFD_CELL_NAME("db8500-cpuidle"),2944};2945 2946static const struct mfd_cell db8500_prcmu_devs[] = {2947	MFD_CELL_OF("db8500-prcmu-regulators", NULL,2948		    &db8500_regulators, sizeof(db8500_regulators), 0,2949		    "stericsson,db8500-prcmu-regulator"),2950	MFD_CELL_OF("db8500-thermal",2951		    NULL, NULL, 0, 0, "stericsson,db8500-thermal"),2952};2953 2954static int db8500_prcmu_register_ab8500(struct device *parent)2955{2956	struct device_node *np;2957	struct resource ab850x_resource;2958	const struct mfd_cell ab8500_cell = {2959		.name = "ab8500-core",2960		.of_compatible = "stericsson,ab8500",2961		.id = AB8500_VERSION_AB8500,2962		.resources = &ab850x_resource,2963		.num_resources = 1,2964	};2965	const struct mfd_cell ab8505_cell = {2966		.name = "ab8505-core",2967		.of_compatible = "stericsson,ab8505",2968		.id = AB8500_VERSION_AB8505,2969		.resources = &ab850x_resource,2970		.num_resources = 1,2971	};2972	const struct mfd_cell *ab850x_cell;2973 2974	if (!parent->of_node)2975		return -ENODEV;2976 2977	/* Look up the device node, sneak the IRQ out of it */2978	for_each_child_of_node(parent->of_node, np) {2979		if (of_device_is_compatible(np, ab8500_cell.of_compatible)) {2980			ab850x_cell = &ab8500_cell;2981			break;2982		}2983		if (of_device_is_compatible(np, ab8505_cell.of_compatible)) {2984			ab850x_cell = &ab8505_cell;2985			break;2986		}2987	}2988	if (!np) {2989		dev_info(parent, "could not find AB850X node in the device tree\n");2990		return -ENODEV;2991	}2992	of_irq_to_resource_table(np, &ab850x_resource, 1);2993 2994	return mfd_add_devices(parent, 0, ab850x_cell, 1, NULL, 0, NULL);2995}2996 2997static int db8500_prcmu_probe(struct platform_device *pdev)2998{2999	struct device_node *np = pdev->dev.of_node;3000	int irq = 0, err = 0;3001	struct resource *res;3002 3003	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu");3004	if (!res) {3005		dev_err(&pdev->dev, "no prcmu memory region provided\n");3006		return -EINVAL;3007	}3008	prcmu_base = devm_ioremap(&pdev->dev, res->start, resource_size(res));3009	if (!prcmu_base) {3010		dev_err(&pdev->dev,3011			"failed to ioremap prcmu register memory\n");3012		return -ENOMEM;3013	}3014	init_prcm_registers();3015	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "prcmu-tcdm");3016	if (!res) {3017		dev_err(&pdev->dev, "no prcmu tcdm region provided\n");3018		return -EINVAL;3019	}3020	tcdm_base = devm_ioremap(&pdev->dev, res->start,3021			resource_size(res));3022	if (!tcdm_base) {3023		dev_err(&pdev->dev,3024			"failed to ioremap prcmu-tcdm register memory\n");3025		return -ENOMEM;3026	}3027 3028	/* Clean up the mailbox interrupts after pre-kernel code. */3029	writel(ALL_MBOX_BITS, PRCM_ARM_IT1_CLR);3030 3031	irq = platform_get_irq(pdev, 0);3032	if (irq <= 0)3033		return irq;3034 3035	err = request_threaded_irq(irq, prcmu_irq_handler,3036	        prcmu_irq_thread_fn, IRQF_NO_SUSPEND, "prcmu", NULL);3037	if (err < 0) {3038		pr_err("prcmu: Failed to allocate IRQ_DB8500_PRCMU1.\n");3039		return err;3040	}3041 3042	db8500_irq_init(np);3043 3044	prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);3045 3046	err = mfd_add_devices(&pdev->dev, 0, common_prcmu_devs,3047			      ARRAY_SIZE(common_prcmu_devs), NULL, 0, db8500_irq_domain);3048	if (err) {3049		pr_err("prcmu: Failed to add subdevices\n");3050		return err;3051	}3052 3053	/* TODO: Remove restriction when clk definitions are available. */3054	if (!of_machine_is_compatible("st-ericsson,u8540")) {3055		err = mfd_add_devices(&pdev->dev, 0, db8500_prcmu_devs,3056				      ARRAY_SIZE(db8500_prcmu_devs), NULL, 0,3057				      db8500_irq_domain);3058		if (err) {3059			mfd_remove_devices(&pdev->dev);3060			pr_err("prcmu: Failed to add subdevices\n");3061			return err;3062		}3063	}3064 3065	err = db8500_prcmu_register_ab8500(&pdev->dev);3066	if (err) {3067		mfd_remove_devices(&pdev->dev);3068		pr_err("prcmu: Failed to add ab8500 subdevice\n");3069		return err;3070	}3071 3072	pr_info("DB8500 PRCMU initialized\n");3073	return err;3074}3075static const struct of_device_id db8500_prcmu_match[] = {3076	{ .compatible = "stericsson,db8500-prcmu"},3077	{ },3078};3079 3080static struct platform_driver db8500_prcmu_driver = {3081	.driver = {3082		.name = "db8500-prcmu",3083		.of_match_table = db8500_prcmu_match,3084	},3085	.probe = db8500_prcmu_probe,3086};3087 3088static int __init db8500_prcmu_init(void)3089{3090	return platform_driver_register(&db8500_prcmu_driver);3091}3092core_initcall(db8500_prcmu_init);3093