Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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