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)  * UFS Host Controller driver for Exynos specific extensions
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    4)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    5)  * Copyright (C) 2014-2015 Samsung Electronics Co., Ltd.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    6)  * Author: Seungwon Jeon  <essuuj@gmail.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    7)  * Author: Alim Akhtar <alim.akhtar@samsung.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    8)  *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300    9)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   10) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   11) #include <linux/clk.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   12) #include <linux/module.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   13) #include <linux/of.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   14) #include <linux/of_address.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   15) #include <linux/phy/phy.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   16) #include <linux/platform_device.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   17) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   18) #include "ufshcd.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   19) #include "ufshcd-pltfrm.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   20) #include "ufshci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   21) #include "unipro.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   22) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   23) #include "ufs-exynos.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   24) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   25) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   26)  * Exynos's Vendor specific registers for UFSHCI
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   27)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   28) #define HCI_TXPRDT_ENTRY_SIZE	0x00
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   29) #define PRDT_PREFECT_EN		BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   30) #define PRDT_SET_SIZE(x)	((x) & 0x1F)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   31) #define HCI_RXPRDT_ENTRY_SIZE	0x04
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   32) #define HCI_1US_TO_CNT_VAL	0x0C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   33) #define CNT_VAL_1US_MASK	0x3FF
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   34) #define HCI_UTRL_NEXUS_TYPE	0x40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   35) #define HCI_UTMRL_NEXUS_TYPE	0x44
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   36) #define HCI_SW_RST		0x50
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   37) #define UFS_LINK_SW_RST		BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   38) #define UFS_UNIPRO_SW_RST	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   39) #define UFS_SW_RST_MASK		(UFS_UNIPRO_SW_RST | UFS_LINK_SW_RST)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   40) #define HCI_DATA_REORDER	0x60
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   41) #define HCI_UNIPRO_APB_CLK_CTRL	0x68
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   42) #define UNIPRO_APB_CLK(v, x)	(((v) & ~0xF) | ((x) & 0xF))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   43) #define HCI_AXIDMA_RWDATA_BURST_LEN	0x6C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   44) #define HCI_GPIO_OUT		0x70
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   45) #define HCI_ERR_EN_PA_LAYER	0x78
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   46) #define HCI_ERR_EN_DL_LAYER	0x7C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   47) #define HCI_ERR_EN_N_LAYER	0x80
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   48) #define HCI_ERR_EN_T_LAYER	0x84
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   49) #define HCI_ERR_EN_DME_LAYER	0x88
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   50) #define HCI_CLKSTOP_CTRL	0xB0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   51) #define REFCLK_STOP		BIT(2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   52) #define UNIPRO_MCLK_STOP	BIT(1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   53) #define UNIPRO_PCLK_STOP	BIT(0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   54) #define CLK_STOP_MASK		(REFCLK_STOP |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   55) 				 UNIPRO_MCLK_STOP |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   56) 				 UNIPRO_PCLK_STOP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   57) #define HCI_MISC		0xB4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   58) #define REFCLK_CTRL_EN		BIT(7)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   59) #define UNIPRO_PCLK_CTRL_EN	BIT(6)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   60) #define UNIPRO_MCLK_CTRL_EN	BIT(5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   61) #define HCI_CORECLK_CTRL_EN	BIT(4)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   62) #define CLK_CTRL_EN_MASK	(REFCLK_CTRL_EN |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   63) 				 UNIPRO_PCLK_CTRL_EN |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   64) 				 UNIPRO_MCLK_CTRL_EN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   65) /* Device fatal error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   66) #define DFES_ERR_EN		BIT(31)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   67) #define DFES_DEF_L2_ERRS	(UIC_DATA_LINK_LAYER_ERROR_RX_BUF_OF |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   68) 				 UIC_DATA_LINK_LAYER_ERROR_PA_INIT)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   69) #define DFES_DEF_L3_ERRS	(UIC_NETWORK_UNSUPPORTED_HEADER_TYPE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   70) 				 UIC_NETWORK_BAD_DEVICEID_ENC |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   71) 				 UIC_NETWORK_LHDR_TRAP_PACKET_DROPPING)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   72) #define DFES_DEF_L4_ERRS	(UIC_TRANSPORT_UNSUPPORTED_HEADER_TYPE |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   73) 				 UIC_TRANSPORT_UNKNOWN_CPORTID |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   74) 				 UIC_TRANSPORT_NO_CONNECTION_RX |\
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   75) 				 UIC_TRANSPORT_BAD_TC)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   76) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   77) enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   78) 	UNIPRO_L1_5 = 0,/* PHY Adapter */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   79) 	UNIPRO_L2,	/* Data Link */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   80) 	UNIPRO_L3,	/* Network */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   81) 	UNIPRO_L4,	/* Transport */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   82) 	UNIPRO_DME,	/* DME */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   83) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   84) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   85) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   86)  * UNIPRO registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   87)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   88) #define UNIPRO_COMP_VERSION			0x000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   89) #define UNIPRO_DME_PWR_REQ			0x090
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   90) #define UNIPRO_DME_PWR_REQ_POWERMODE		0x094
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   91) #define UNIPRO_DME_PWR_REQ_LOCALL2TIMER0	0x098
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   92) #define UNIPRO_DME_PWR_REQ_LOCALL2TIMER1	0x09C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   93) #define UNIPRO_DME_PWR_REQ_LOCALL2TIMER2	0x0A0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   94) #define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER0	0x0A4
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   95) #define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER1	0x0A8
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   96) #define UNIPRO_DME_PWR_REQ_REMOTEL2TIMER2	0x0AC
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   97) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   98) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300   99)  * UFS Protector registers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  100)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  101) #define UFSPRSECURITY	0x010
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  102) #define NSSMU		BIT(14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  103) #define UFSPSBEGIN0	0x200
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  104) #define UFSPSEND0	0x204
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  105) #define UFSPSLUN0	0x208
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  106) #define UFSPSCTRL0	0x20C
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  108) #define CNTR_DIV_VAL 40
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  109) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  110) static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  111) static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  112) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  113) static inline void exynos_ufs_enable_auto_ctrl_hcc(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  114) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  115) 	exynos_ufs_auto_ctrl_hcc(ufs, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  118) static inline void exynos_ufs_disable_auto_ctrl_hcc(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  119) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  120) 	exynos_ufs_auto_ctrl_hcc(ufs, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  122) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  123) static inline void exynos_ufs_disable_auto_ctrl_hcc_save(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  124) 					struct exynos_ufs *ufs, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  125) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  126) 	*val = hci_readl(ufs, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  127) 	exynos_ufs_auto_ctrl_hcc(ufs, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  128) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  129) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  130) static inline void exynos_ufs_auto_ctrl_hcc_restore(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  131) 					struct exynos_ufs *ufs, u32 *val)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  132) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  133) 	hci_writel(ufs, *val, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  134) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  135) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  136) static inline void exynos_ufs_gate_clks(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  137) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  138) 	exynos_ufs_ctrl_clkstop(ufs, true);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  141) static inline void exynos_ufs_ungate_clks(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  142) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  143) 	exynos_ufs_ctrl_clkstop(ufs, false);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  144) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  146) static int exynos7_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  147) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  148) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  149) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  150) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  151) static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  152) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  153) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  154) 	u32 val = ufs->drv_data->uic_attr->pa_dbg_option_suite;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  155) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  156) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  157) 	exynos_ufs_enable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  158) 	for_each_ufs_tx_lane(ufs, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  159) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x297, i), 0x17);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  160) 	for_each_ufs_rx_lane(ufs, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  161) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x362, i), 0xff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  162) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x363, i), 0x00);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  163) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  164) 	exynos_ufs_disable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  165) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  166) 	for_each_ufs_tx_lane(ufs, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  167) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  168) 			UIC_ARG_MIB_SEL(TX_HIBERN8_CONTROL, i), 0x0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  169) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_TXPHY_CFGUPDT), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  170) 	udelay(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  171) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val | (1 << 12));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  172) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_RESET_PHY), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  173) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_SKIP_LINE_RESET), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  174) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_LINE_RESET_REQ), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  175) 	udelay(1600);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  176) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE), val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  178) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  179) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  180) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  181) static int exynos7_ufs_post_link(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  182) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  183) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  184) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  185) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  186) 	exynos_ufs_enable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  187) 	for_each_ufs_tx_lane(ufs, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  188) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x28b, i), 0x83);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  189) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x29a, i), 0x07);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  190) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(0x277, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  191) 			TX_LINERESET_N(exynos_ufs_calc_time_cntr(ufs, 200000)));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  192) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  193) 	exynos_ufs_disable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  194) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  195) 	exynos_ufs_enable_dbg_mode(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  196) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_SAVECONFIGTIME), 0xbb8);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  197) 	exynos_ufs_disable_dbg_mode(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  199) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  202) static int exynos7_ufs_pre_pwr_change(struct exynos_ufs *ufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  203) 						struct ufs_pa_layer_attr *pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  204) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  205) 	unipro_writel(ufs, 0x22, UNIPRO_DBG_FORCE_DME_CTRL_STATE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  206) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  207) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  208) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  209) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  210) static int exynos7_ufs_post_pwr_change(struct exynos_ufs *ufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  211) 						struct ufs_pa_layer_attr *pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  212) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  213) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  214) 	int lanes = max_t(u32, pwr->lane_rx, pwr->lane_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  215) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  216) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_RXPHY_CFGUPDT), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  217) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  218) 	if (lanes == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  219) 		exynos_ufs_enable_dbg_mode(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  220) 		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES), 0x1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  221) 		exynos_ufs_disable_dbg_mode(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  222) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  223) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  224) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  225) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  226) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  227) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  228)  * exynos_ufs_auto_ctrl_hcc - HCI core clock control by h/w
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  229)  * Control should be disabled in the below cases
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  230)  * - Before host controller S/W reset
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  231)  * - Access to UFS protector's register
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  232)  */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  233) static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  234) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  235) 	u32 misc = hci_readl(ufs, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  236) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  237) 	if (en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  238) 		hci_writel(ufs, misc | HCI_CORECLK_CTRL_EN, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  239) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  240) 		hci_writel(ufs, misc & ~HCI_CORECLK_CTRL_EN, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  241) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  243) static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  245) 	u32 ctrl = hci_readl(ufs, HCI_CLKSTOP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  246) 	u32 misc = hci_readl(ufs, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  248) 	if (en) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  249) 		hci_writel(ufs, misc | CLK_CTRL_EN_MASK, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  250) 		hci_writel(ufs, ctrl | CLK_STOP_MASK, HCI_CLKSTOP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  251) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  252) 		hci_writel(ufs, ctrl & ~CLK_STOP_MASK, HCI_CLKSTOP_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  253) 		hci_writel(ufs, misc & ~CLK_CTRL_EN_MASK, HCI_MISC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  254) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  255) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  256) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  257) static int exynos_ufs_get_clk_info(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  258) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  259) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  260) 	struct list_head *head = &hba->clk_list_head;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  261) 	struct ufs_clk_info *clki;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  262) 	unsigned long pclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  263) 	u32 f_min, f_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  264) 	u8 div = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  265) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  266) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  267) 	if (list_empty(head))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  268) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  269) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  270) 	list_for_each_entry(clki, head, list) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  271) 		if (!IS_ERR(clki->clk)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  272) 			if (!strcmp(clki->name, "core_clk"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  273) 				ufs->clk_hci_core = clki->clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  274) 			else if (!strcmp(clki->name, "sclk_unipro_main"))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  275) 				ufs->clk_unipro_main = clki->clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  276) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  277) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  279) 	if (!ufs->clk_hci_core || !ufs->clk_unipro_main) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  280) 		dev_err(hba->dev, "failed to get clk info\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  281) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  282) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  283) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  284) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  285) 	ufs->mclk_rate = clk_get_rate(ufs->clk_unipro_main);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  286) 	pclk_rate = clk_get_rate(ufs->clk_hci_core);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  287) 	f_min = ufs->pclk_avail_min;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  288) 	f_max = ufs->pclk_avail_max;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  289) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  290) 	if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  291) 		do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  292) 			pclk_rate /= (div + 1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  293) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  294) 			if (pclk_rate <= f_max)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  295) 				break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  296) 			div++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  297) 		} while (pclk_rate >= f_min);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  298) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  299) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  300) 	if (unlikely(pclk_rate < f_min || pclk_rate > f_max)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  301) 		dev_err(hba->dev, "not available pclk range %lu\n", pclk_rate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  302) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  303) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  304) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  305) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  306) 	ufs->pclk_rate = pclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  307) 	ufs->pclk_div = div;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  308) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  309) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  310) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  311) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  312) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  313) static void exynos_ufs_set_unipro_pclk_div(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  314) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  315) 	if (ufs->opts & EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  316) 		u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  317) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  318) 		val = hci_readl(ufs, HCI_UNIPRO_APB_CLK_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  319) 		hci_writel(ufs, UNIPRO_APB_CLK(val, ufs->pclk_div),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  320) 			   HCI_UNIPRO_APB_CLK_CTRL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  321) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  322) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  323) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  324) static void exynos_ufs_set_pwm_clk_div(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  325) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  326) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  327) 	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  328) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  329) 	ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  330) 		UIC_ARG_MIB(CMN_PWM_CLK_CTRL), attr->cmn_pwm_clk_ctrl);
^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) static void exynos_ufs_calc_pwm_clk_div(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  334) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  335) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  336) 	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  337) 	const unsigned int div = 30, mult = 20;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  338) 	const unsigned long pwm_min = 3 * 1000 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  339) 	const unsigned long pwm_max = 9 * 1000 * 1000;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  340) 	const int divs[] = {32, 16, 8, 4};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  341) 	unsigned long clk = 0, _clk, clk_period;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  342) 	int i = 0, clk_idx = -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  343) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  344) 	clk_period = UNIPRO_PCLK_PERIOD(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  345) 	for (i = 0; i < ARRAY_SIZE(divs); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  346) 		_clk = NSEC_PER_SEC * mult / (clk_period * divs[i] * div);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  347) 		if (_clk >= pwm_min && _clk <= pwm_max) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  348) 			if (_clk > clk) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  349) 				clk_idx = i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  350) 				clk = _clk;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  351) 			}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  352) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  353) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  354) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  355) 	if (clk_idx == -1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  356) 		ufshcd_dme_get(hba, UIC_ARG_MIB(CMN_PWM_CLK_CTRL), &clk_idx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  357) 		dev_err(hba->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  358) 			"failed to decide pwm clock divider, will not change\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  359) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  360) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  361) 	attr->cmn_pwm_clk_ctrl = clk_idx & PWM_CLK_CTRL_MASK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  362) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  363) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  364) long exynos_ufs_calc_time_cntr(struct exynos_ufs *ufs, long period)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  365) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  366) 	const int precise = 10;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  367) 	long pclk_rate = ufs->pclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  368) 	long clk_period, fraction;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  369) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  370) 	clk_period = UNIPRO_PCLK_PERIOD(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  371) 	fraction = ((NSEC_PER_SEC % pclk_rate) * precise) / pclk_rate;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  372) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  373) 	return (period * precise) / ((clk_period * precise) + fraction);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  374) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  375) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  376) static void exynos_ufs_specify_phy_time_attr(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  377) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  378) 	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  379) 	struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  380) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  381) 	t_cfg->tx_linereset_p =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  382) 		exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_p_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  383) 	t_cfg->tx_linereset_n =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  384) 		exynos_ufs_calc_time_cntr(ufs, attr->tx_dif_n_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  385) 	t_cfg->tx_high_z_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  386) 		exynos_ufs_calc_time_cntr(ufs, attr->tx_high_z_cnt_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  387) 	t_cfg->tx_base_n_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  388) 		exynos_ufs_calc_time_cntr(ufs, attr->tx_base_unit_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  389) 	t_cfg->tx_gran_n_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  390) 		exynos_ufs_calc_time_cntr(ufs, attr->tx_gran_unit_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  391) 	t_cfg->tx_sleep_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  392) 		exynos_ufs_calc_time_cntr(ufs, attr->tx_sleep_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  393) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  394) 	t_cfg->rx_linereset =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  395) 		exynos_ufs_calc_time_cntr(ufs, attr->rx_dif_p_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  396) 	t_cfg->rx_hibern8_wait =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  397) 		exynos_ufs_calc_time_cntr(ufs, attr->rx_hibern8_wait_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  398) 	t_cfg->rx_base_n_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  399) 		exynos_ufs_calc_time_cntr(ufs, attr->rx_base_unit_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  400) 	t_cfg->rx_gran_n_val =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  401) 		exynos_ufs_calc_time_cntr(ufs, attr->rx_gran_unit_nsec);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  402) 	t_cfg->rx_sleep_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  403) 		exynos_ufs_calc_time_cntr(ufs, attr->rx_sleep_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  404) 	t_cfg->rx_stall_cnt =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  405) 		exynos_ufs_calc_time_cntr(ufs, attr->rx_stall_cnt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  406) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  407) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  408) static void exynos_ufs_config_phy_time_attr(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  409) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  410) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  411) 	struct ufs_phy_time_cfg *t_cfg = &ufs->t_cfg;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  412) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  413) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  414) 	exynos_ufs_set_pwm_clk_div(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  415) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  416) 	exynos_ufs_enable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  417) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  418) 	for_each_ufs_rx_lane(ufs, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  419) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_FILLER_ENABLE, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  420) 				ufs->drv_data->uic_attr->rx_filler_enable);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  421) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_LINERESET_VAL, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  422) 				RX_LINERESET(t_cfg->rx_linereset));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  423) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_BASE_NVAL_07_00, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  424) 				RX_BASE_NVAL_L(t_cfg->rx_base_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  425) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_BASE_NVAL_15_08, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  426) 				RX_BASE_NVAL_H(t_cfg->rx_base_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  427) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_GRAN_NVAL_07_00, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  428) 				RX_GRAN_NVAL_L(t_cfg->rx_gran_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  429) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_GRAN_NVAL_10_08, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  430) 				RX_GRAN_NVAL_H(t_cfg->rx_gran_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  431) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_OV_SLEEP_CNT_TIMER, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  432) 				RX_OV_SLEEP_CNT(t_cfg->rx_sleep_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  433) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(RX_OV_STALL_CNT_TIMER, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  434) 				RX_OV_STALL_CNT(t_cfg->rx_stall_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  435) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  436) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  437) 	for_each_ufs_tx_lane(ufs, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  438) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_LINERESET_P_VAL, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  439) 				TX_LINERESET_P(t_cfg->tx_linereset_p));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  440) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HIGH_Z_CNT_07_00, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  441) 				TX_HIGH_Z_CNT_L(t_cfg->tx_high_z_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  442) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_HIGH_Z_CNT_11_08, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  443) 				TX_HIGH_Z_CNT_H(t_cfg->tx_high_z_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  444) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_BASE_NVAL_07_00, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  445) 				TX_BASE_NVAL_L(t_cfg->tx_base_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  446) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_BASE_NVAL_15_08, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  447) 				TX_BASE_NVAL_H(t_cfg->tx_base_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  448) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_GRAN_NVAL_07_00, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  449) 				TX_GRAN_NVAL_L(t_cfg->tx_gran_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  450) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_GRAN_NVAL_10_08, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  451) 				TX_GRAN_NVAL_H(t_cfg->tx_gran_n_val));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  452) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_OV_SLEEP_CNT_TIMER, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  453) 				TX_OV_H8_ENTER_EN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  454) 				TX_OV_SLEEP_CNT(t_cfg->tx_sleep_cnt));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  455) 		ufshcd_dme_set(hba, UIC_ARG_MIB_SEL(TX_MIN_ACTIVATETIME, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  456) 				ufs->drv_data->uic_attr->tx_min_activatetime);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  457) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  458) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  459) 	exynos_ufs_disable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  460) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  461) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  462) static void exynos_ufs_config_phy_cap_attr(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  463) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  464) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  465) 	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  466) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  467) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  468) 	exynos_ufs_enable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  469) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  470) 	for_each_ufs_rx_lane(ufs, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  471) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  472) 				UIC_ARG_MIB_SEL(RX_HS_G1_SYNC_LENGTH_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  473) 				attr->rx_hs_g1_sync_len_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  474) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  475) 				UIC_ARG_MIB_SEL(RX_HS_G2_SYNC_LENGTH_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  476) 				attr->rx_hs_g2_sync_len_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  477) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  478) 				UIC_ARG_MIB_SEL(RX_HS_G3_SYNC_LENGTH_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  479) 				attr->rx_hs_g3_sync_len_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  480) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  481) 				UIC_ARG_MIB_SEL(RX_HS_G1_PREP_LENGTH_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  482) 				attr->rx_hs_g1_prep_sync_len_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  483) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  484) 				UIC_ARG_MIB_SEL(RX_HS_G2_PREP_LENGTH_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  485) 				attr->rx_hs_g2_prep_sync_len_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  486) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  487) 				UIC_ARG_MIB_SEL(RX_HS_G3_PREP_LENGTH_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  488) 				attr->rx_hs_g3_prep_sync_len_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  489) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  490) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  491) 	if (attr->rx_adv_fine_gran_sup_en == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  492) 		for_each_ufs_rx_lane(ufs, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  493) 			ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  494) 				UIC_ARG_MIB_SEL(RX_ADV_GRANULARITY_CAP, i), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  495) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  496) 			if (attr->rx_min_actv_time_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  497) 				ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  498) 					UIC_ARG_MIB_SEL(RX_MIN_ACTIVATETIME_CAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  499) 						i), attr->rx_min_actv_time_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  500) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  501) 			if (attr->rx_hibern8_time_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  502) 				ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  503) 					UIC_ARG_MIB_SEL(RX_HIBERN8TIME_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  504) 						attr->rx_hibern8_time_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  505) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  506) 	} else if (attr->rx_adv_fine_gran_sup_en == 1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  507) 		for_each_ufs_rx_lane(ufs, i) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  508) 			if (attr->rx_adv_fine_gran_step)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  509) 				ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  510) 					UIC_ARG_MIB_SEL(RX_ADV_GRANULARITY_CAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  511) 						i), RX_ADV_FINE_GRAN_STEP(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  512) 						attr->rx_adv_fine_gran_step));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  513) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  514) 			if (attr->rx_adv_min_actv_time_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  515) 				ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  516) 					UIC_ARG_MIB_SEL(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  517) 						RX_ADV_MIN_ACTIVATETIME_CAP, i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  518) 						attr->rx_adv_min_actv_time_cap);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  519) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  520) 			if (attr->rx_adv_hibern8_time_cap)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  521) 				ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  522) 					UIC_ARG_MIB_SEL(RX_ADV_HIBERN8TIME_CAP,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  523) 						i),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  524) 						attr->rx_adv_hibern8_time_cap);
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  528) 	exynos_ufs_disable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  529) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  530) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  531) static void exynos_ufs_establish_connt(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  532) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  533) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  534) 	enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  535) 		DEV_ID		= 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  536) 		PEER_DEV_ID	= 0x01,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  537) 		PEER_CPORT_ID	= 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  538) 		TRAFFIC_CLASS	= 0x00,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  539) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  540) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  541) 	/* allow cport attributes to be set */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  542) 	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_IDLE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  543) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  544) 	/* local unipro attributes */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  545) 	ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID), DEV_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  546) 	ufshcd_dme_set(hba, UIC_ARG_MIB(N_DEVICEID_VALID), TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  547) 	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERDEVICEID), PEER_DEV_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  548) 	ufshcd_dme_set(hba, UIC_ARG_MIB(T_PEERCPORTID), PEER_CPORT_ID);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  549) 	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CPORTFLAGS), CPORT_DEF_FLAGS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  550) 	ufshcd_dme_set(hba, UIC_ARG_MIB(T_TRAFFICCLASS), TRAFFIC_CLASS);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  551) 	ufshcd_dme_set(hba, UIC_ARG_MIB(T_CONNECTIONSTATE), CPORT_CONNECTED);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  552) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  553) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  554) static void exynos_ufs_config_smu(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  555) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  556) 	u32 reg, val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  557) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  558) 	exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  559) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  560) 	/* make encryption disabled by default */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  561) 	reg = ufsp_readl(ufs, UFSPRSECURITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  562) 	ufsp_writel(ufs, reg | NSSMU, UFSPRSECURITY);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  563) 	ufsp_writel(ufs, 0x0, UFSPSBEGIN0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  564) 	ufsp_writel(ufs, 0xffffffff, UFSPSEND0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  565) 	ufsp_writel(ufs, 0xff, UFSPSLUN0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  566) 	ufsp_writel(ufs, 0xf1, UFSPSCTRL0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  567) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  568) 	exynos_ufs_auto_ctrl_hcc_restore(ufs, &val);
^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) static void exynos_ufs_config_sync_pattern_mask(struct exynos_ufs *ufs,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  572) 					struct ufs_pa_layer_attr *pwr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  573) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  574) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  575) 	u8 g = max_t(u32, pwr->gear_rx, pwr->gear_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  576) 	u32 mask, sync_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  577) 	enum {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  578) 		SYNC_LEN_G1 = 80 * 1000, /* 80us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  579) 		SYNC_LEN_G2 = 40 * 1000, /* 44us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  580) 		SYNC_LEN_G3 = 20 * 1000, /* 20us */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  581) 	};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  582) 	int i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  583) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  584) 	if (g == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  585) 		sync_len = SYNC_LEN_G1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  586) 	else if (g == 2)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  587) 		sync_len = SYNC_LEN_G2;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  588) 	else if (g == 3)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  589) 		sync_len = SYNC_LEN_G3;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  590) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  591) 		return;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  592) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  593) 	mask = exynos_ufs_calc_time_cntr(ufs, sync_len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  594) 	mask = (mask >> 8) & 0xff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  595) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  596) 	exynos_ufs_enable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  597) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  598) 	for_each_ufs_rx_lane(ufs, i)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  599) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  600) 			UIC_ARG_MIB_SEL(RX_SYNC_MASK_LENGTH, i), mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  601) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  602) 	exynos_ufs_disable_ov_tm(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  603) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  604) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  605) static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  606) 				struct ufs_pa_layer_attr *dev_max_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  607) 				struct ufs_pa_layer_attr *dev_req_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  608) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  609) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  610) 	struct phy *generic_phy = ufs->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  611) 	struct ufs_dev_params ufs_exynos_cap;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  612) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  613) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  614) 	if (!dev_req_params) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  615) 		pr_err("%s: incoming dev_req_params is NULL\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  616) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  617) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  618) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  619) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  620) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  621) 	ufs_exynos_cap.tx_lanes = UFS_EXYNOS_LIMIT_NUM_LANES_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  622) 	ufs_exynos_cap.rx_lanes = UFS_EXYNOS_LIMIT_NUM_LANES_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  623) 	ufs_exynos_cap.hs_rx_gear = UFS_EXYNOS_LIMIT_HSGEAR_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  624) 	ufs_exynos_cap.hs_tx_gear = UFS_EXYNOS_LIMIT_HSGEAR_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  625) 	ufs_exynos_cap.pwm_rx_gear = UFS_EXYNOS_LIMIT_PWMGEAR_RX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  626) 	ufs_exynos_cap.pwm_tx_gear = UFS_EXYNOS_LIMIT_PWMGEAR_TX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  627) 	ufs_exynos_cap.rx_pwr_pwm = UFS_EXYNOS_LIMIT_RX_PWR_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  628) 	ufs_exynos_cap.tx_pwr_pwm = UFS_EXYNOS_LIMIT_TX_PWR_PWM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  629) 	ufs_exynos_cap.rx_pwr_hs = UFS_EXYNOS_LIMIT_RX_PWR_HS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  630) 	ufs_exynos_cap.tx_pwr_hs = UFS_EXYNOS_LIMIT_TX_PWR_HS;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  631) 	ufs_exynos_cap.hs_rate = UFS_EXYNOS_LIMIT_HS_RATE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  632) 	ufs_exynos_cap.desired_working_mode =
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  633) 				UFS_EXYNOS_LIMIT_DESIRED_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  634) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  635) 	ret = ufshcd_get_pwr_dev_param(&ufs_exynos_cap,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  636) 				       dev_max_params, dev_req_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  637) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  638) 		pr_err("%s: failed to determine capabilities\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  639) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  640) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  641) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  642) 	if (ufs->drv_data->pre_pwr_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  643) 		ufs->drv_data->pre_pwr_change(ufs, dev_req_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  644) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  645) 	if (ufshcd_is_hs_mode(dev_req_params)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  646) 		exynos_ufs_config_sync_pattern_mask(ufs, dev_req_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  647) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  648) 		switch (dev_req_params->hs_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  649) 		case PA_HS_MODE_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  650) 		case PA_HS_MODE_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  651) 			phy_calibrate(generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  652) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  653) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  654) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  655) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  656) 	/* setting for three timeout values for traffic class #0 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  657) 	ufshcd_dme_set(hba, UIC_ARG_MIB(DL_FC0PROTTIMEOUTVAL), 8064);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  658) 	ufshcd_dme_set(hba, UIC_ARG_MIB(DL_TC0REPLAYTIMEOUTVAL), 28224);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  659) 	ufshcd_dme_set(hba, UIC_ARG_MIB(DL_AFC0REQTIMEOUTVAL), 20160);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  660) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  661) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  662) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  663) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  664) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  665) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  666) #define PWR_MODE_STR_LEN	64
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  667) static int exynos_ufs_post_pwr_mode(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  668) 				struct ufs_pa_layer_attr *pwr_max,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  669) 				struct ufs_pa_layer_attr *pwr_req)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  670) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  671) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  672) 	struct phy *generic_phy = ufs->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  673) 	int gear = max_t(u32, pwr_req->gear_rx, pwr_req->gear_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  674) 	int lanes = max_t(u32, pwr_req->lane_rx, pwr_req->lane_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  675) 	char pwr_str[PWR_MODE_STR_LEN] = "";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  676) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  677) 	/* let default be PWM Gear 1, Lane 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  678) 	if (!gear)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  679) 		gear = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  680) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  681) 	if (!lanes)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  682) 		lanes = 1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  683) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  684) 	if (ufs->drv_data->post_pwr_change)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  685) 		ufs->drv_data->post_pwr_change(ufs, pwr_req);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  686) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  687) 	if ((ufshcd_is_hs_mode(pwr_req))) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  688) 		switch (pwr_req->hs_rate) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  689) 		case PA_HS_MODE_A:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  690) 		case PA_HS_MODE_B:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  691) 			phy_calibrate(generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  692) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  693) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  694) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  695) 		snprintf(pwr_str, PWR_MODE_STR_LEN, "%s series_%s G_%d L_%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  696) 			"FAST",	pwr_req->hs_rate == PA_HS_MODE_A ? "A" : "B",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  697) 			gear, lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  698) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  699) 		snprintf(pwr_str, PWR_MODE_STR_LEN, "%s G_%d L_%d",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  700) 			"SLOW", gear, lanes);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  701) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  702) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  703) 	dev_info(hba->dev, "Power mode changed to : %s\n", pwr_str);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  704) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  705) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  706) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  707) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  708) static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  709) 						int tag, bool op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  710) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  711) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  712) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  713) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  714) 	type =  hci_readl(ufs, HCI_UTRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  715) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  716) 	if (op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  717) 		hci_writel(ufs, type | (1 << tag), HCI_UTRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  718) 	else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  719) 		hci_writel(ufs, type & ~(1 << tag), HCI_UTRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  720) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  721) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  722) static void exynos_ufs_specify_nexus_t_tm_req(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  723) 						int tag, u8 func)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  724) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  725) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  726) 	u32 type;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  727) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  728) 	type =  hci_readl(ufs, HCI_UTMRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  729) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  730) 	switch (func) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  731) 	case UFS_ABORT_TASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  732) 	case UFS_QUERY_TASK:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  733) 		hci_writel(ufs, type | (1 << tag), HCI_UTMRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  734) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  735) 	case UFS_ABORT_TASK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  736) 	case UFS_CLEAR_TASK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  737) 	case UFS_LOGICAL_RESET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  738) 	case UFS_QUERY_TASK_SET:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  739) 		hci_writel(ufs, type & ~(1 << tag), HCI_UTMRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  740) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  741) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  742) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  743) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  744) static int exynos_ufs_phy_init(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  745) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  746) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  747) 	struct phy *generic_phy = ufs->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  748) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  749) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  750) 	if (ufs->avail_ln_rx == 0 || ufs->avail_ln_tx == 0) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  751) 		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILRXDATALANES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  752) 			&ufs->avail_ln_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  753) 		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_AVAILTXDATALANES),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  754) 			&ufs->avail_ln_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  755) 		WARN(ufs->avail_ln_rx != ufs->avail_ln_tx,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  756) 			"available data lane is not equal(rx:%d, tx:%d)\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  757) 			ufs->avail_ln_rx, ufs->avail_ln_tx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  758) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  759) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  760) 	phy_set_bus_width(generic_phy, ufs->avail_ln_rx);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  761) 	ret = phy_init(generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  762) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  763) 		dev_err(hba->dev, "%s: phy init failed, ret = %d\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  764) 			__func__, ret);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  765) 		goto out_exit_phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  766) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  767) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  768) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  769) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  770) out_exit_phy:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  771) 	phy_exit(generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  772) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  773) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  774) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  775) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  776) static void exynos_ufs_config_unipro(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  777) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  778) 	struct ufs_hba *hba = ufs->hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  779) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  780) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_CLK_PERIOD),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  781) 		DIV_ROUND_UP(NSEC_PER_SEC, ufs->mclk_rate));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  782) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TXTRAILINGCLOCKS),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  783) 			ufs->drv_data->uic_attr->tx_trailingclks);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  784) 	ufshcd_dme_set(hba, UIC_ARG_MIB(PA_DBG_OPTION_SUITE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  785) 			ufs->drv_data->uic_attr->pa_dbg_option_suite);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  786) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  787) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  788) static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  789) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  790) 	switch (index) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  791) 	case UNIPRO_L1_5:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  792) 		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_PA_LAYER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  793) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  794) 	case UNIPRO_L2:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  795) 		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DL_LAYER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  796) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  797) 	case UNIPRO_L3:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  798) 		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_N_LAYER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  799) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  800) 	case UNIPRO_L4:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  801) 		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_T_LAYER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  802) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  803) 	case UNIPRO_DME:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  804) 		hci_writel(ufs, DFES_ERR_EN | errs, HCI_ERR_EN_DME_LAYER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  805) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  806) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  807) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  808) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  809) static int exynos_ufs_pre_link(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  810) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  811) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  812) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  813) 	/* hci */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  814) 	exynos_ufs_config_intr(ufs, DFES_DEF_L2_ERRS, UNIPRO_L2);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  815) 	exynos_ufs_config_intr(ufs, DFES_DEF_L3_ERRS, UNIPRO_L3);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  816) 	exynos_ufs_config_intr(ufs, DFES_DEF_L4_ERRS, UNIPRO_L4);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  817) 	exynos_ufs_set_unipro_pclk_div(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  818) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  819) 	/* unipro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  820) 	exynos_ufs_config_unipro(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  821) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  822) 	/* m-phy */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  823) 	exynos_ufs_phy_init(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  824) 	exynos_ufs_config_phy_time_attr(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  825) 	exynos_ufs_config_phy_cap_attr(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  826) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  827) 	if (ufs->drv_data->pre_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  828) 		ufs->drv_data->pre_link(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  829) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  830) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  831) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  832) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  833) static void exynos_ufs_fit_aggr_timeout(struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  834) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  835) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  836) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  837) 	val = exynos_ufs_calc_time_cntr(ufs, IATOVAL_NSEC / CNTR_DIV_VAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  838) 	hci_writel(ufs, val & CNT_VAL_1US_MASK, HCI_1US_TO_CNT_VAL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  839) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  840) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  841) static int exynos_ufs_post_link(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  842) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  843) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  844) 	struct phy *generic_phy = ufs->phy;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  845) 	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  846) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  847) 	exynos_ufs_establish_connt(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  848) 	exynos_ufs_fit_aggr_timeout(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  849) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  850) 	hci_writel(ufs, 0xa, HCI_DATA_REORDER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  851) 	hci_writel(ufs, PRDT_SET_SIZE(12), HCI_TXPRDT_ENTRY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  852) 	hci_writel(ufs, PRDT_SET_SIZE(12), HCI_RXPRDT_ENTRY_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  853) 	hci_writel(ufs, (1 << hba->nutrs) - 1, HCI_UTRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  854) 	hci_writel(ufs, (1 << hba->nutmrs) - 1, HCI_UTMRL_NEXUS_TYPE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  855) 	hci_writel(ufs, 0xf, HCI_AXIDMA_RWDATA_BURST_LEN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  856) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  857) 	if (ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  858) 		ufshcd_dme_set(hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  859) 			UIC_ARG_MIB(T_DBG_SKIP_INIT_HIBERN8_EXIT), TRUE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  860) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  861) 	if (attr->pa_granularity) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  862) 		exynos_ufs_enable_dbg_mode(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  863) 		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_GRANULARITY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  864) 				attr->pa_granularity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  865) 		exynos_ufs_disable_dbg_mode(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  866) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  867) 		if (attr->pa_tactivate)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  868) 			ufshcd_dme_set(hba, UIC_ARG_MIB(PA_TACTIVATE),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  869) 					attr->pa_tactivate);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  870) 		if (attr->pa_hibern8time &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  871) 		    !(ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  872) 			ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  873) 					attr->pa_hibern8time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  874) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  875) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  876) 	if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  877) 		if (!attr->pa_granularity)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  878) 			ufshcd_dme_get(hba, UIC_ARG_MIB(PA_GRANULARITY),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  879) 					&attr->pa_granularity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  880) 		if (!attr->pa_hibern8time)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  881) 			ufshcd_dme_get(hba, UIC_ARG_MIB(PA_HIBERN8TIME),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  882) 					&attr->pa_hibern8time);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  883) 		/*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  884) 		 * not wait for HIBERN8 time to exit hibernation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  885) 		 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  886) 		ufshcd_dme_set(hba, UIC_ARG_MIB(PA_HIBERN8TIME), 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  887) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  888) 		if (attr->pa_granularity < 1 || attr->pa_granularity > 6) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  889) 			/* Valid range for granularity: 1 ~ 6 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  890) 			dev_warn(hba->dev,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  891) 				"%s: pa_granularity %d is invalid, assuming backwards compatibility\n",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  892) 				__func__,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  893) 				attr->pa_granularity);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  894) 			attr->pa_granularity = 6;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  895) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  896) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  897) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  898) 	phy_calibrate(generic_phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  899) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  900) 	if (ufs->drv_data->post_link)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  901) 		ufs->drv_data->post_link(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  902) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  903) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  904) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  905) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  906) static int exynos_ufs_parse_dt(struct device *dev, struct exynos_ufs *ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  907) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  908) 	struct device_node *np = dev->of_node;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  909) 	struct exynos_ufs_drv_data *drv_data = &exynos_ufs_drvs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  910) 	struct exynos_ufs_uic_attr *attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  911) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  912) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  913) 	while (drv_data->compatible) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  914) 		if (of_device_is_compatible(np, drv_data->compatible)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  915) 			ufs->drv_data = drv_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  916) 			break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  917) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  918) 		drv_data++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  919) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  920) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  921) 	if (ufs->drv_data && ufs->drv_data->uic_attr) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  922) 		attr = ufs->drv_data->uic_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  923) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  924) 		dev_err(dev, "failed to get uic attributes\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  925) 		ret = -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  926) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  927) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  928) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  929) 	ufs->pclk_avail_min = PCLK_AVAIL_MIN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  930) 	ufs->pclk_avail_max = PCLK_AVAIL_MAX;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  931) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  932) 	attr->rx_adv_fine_gran_sup_en = RX_ADV_FINE_GRAN_SUP_EN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  933) 	attr->rx_adv_fine_gran_step = RX_ADV_FINE_GRAN_STEP_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  934) 	attr->rx_adv_min_actv_time_cap = RX_ADV_MIN_ACTV_TIME_CAP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  935) 	attr->pa_granularity = PA_GRANULARITY_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  936) 	attr->pa_tactivate = PA_TACTIVATE_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  937) 	attr->pa_hibern8time = PA_HIBERN8TIME_VAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  938) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  939) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  940) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  941) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  942) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  943) static int exynos_ufs_init(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  944) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  945) 	struct device *dev = hba->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  946) 	struct platform_device *pdev = to_platform_device(dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  947) 	struct exynos_ufs *ufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  948) 	int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  949) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  950) 	ufs = devm_kzalloc(dev, sizeof(*ufs), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  951) 	if (!ufs)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  952) 		return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  953) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  954) 	/* exynos-specific hci */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  955) 	ufs->reg_hci = devm_platform_ioremap_resource_byname(pdev, "vs_hci");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  956) 	if (IS_ERR(ufs->reg_hci)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  957) 		dev_err(dev, "cannot ioremap for hci vendor register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  958) 		return PTR_ERR(ufs->reg_hci);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  959) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  960) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  961) 	/* unipro */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  962) 	ufs->reg_unipro = devm_platform_ioremap_resource_byname(pdev, "unipro");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  963) 	if (IS_ERR(ufs->reg_unipro)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  964) 		dev_err(dev, "cannot ioremap for unipro register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  965) 		return PTR_ERR(ufs->reg_unipro);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  966) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  967) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  968) 	/* ufs protector */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  969) 	ufs->reg_ufsp = devm_platform_ioremap_resource_byname(pdev, "ufsp");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  970) 	if (IS_ERR(ufs->reg_ufsp)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  971) 		dev_err(dev, "cannot ioremap for ufs protector register\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  972) 		return PTR_ERR(ufs->reg_ufsp);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  973) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  974) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  975) 	ret = exynos_ufs_parse_dt(dev, ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  976) 	if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  977) 		dev_err(dev, "failed to get dt info.\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  978) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  979) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  980) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  981) 	ufs->phy = devm_phy_get(dev, "ufs-phy");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  982) 	if (IS_ERR(ufs->phy)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  983) 		ret = PTR_ERR(ufs->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  984) 		dev_err(dev, "failed to get ufs-phy\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  985) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  986) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  987) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  988) 	ret = phy_power_on(ufs->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  989) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  990) 		goto phy_off;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  991) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  992) 	ufs->hba = hba;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  993) 	ufs->opts = ufs->drv_data->opts;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  994) 	ufs->rx_sel_idx = PA_MAXDATALANES;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  995) 	if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  996) 		ufs->rx_sel_idx = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  997) 	hba->priv = (void *)ufs;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  998) 	hba->quirks = ufs->drv_data->quirks;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300  999) 	if (ufs->drv_data->drv_init) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1000) 		ret = ufs->drv_data->drv_init(dev, ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1001) 		if (ret) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1002) 			dev_err(dev, "failed to init drv-data\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1003) 			goto out;
^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) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1007) 	ret = exynos_ufs_get_clk_info(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1008) 	if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1009) 		goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1010) 	exynos_ufs_specify_phy_time_attr(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1011) 	exynos_ufs_config_smu(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1012) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1013) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1014) phy_off:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1015) 	phy_power_off(ufs->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1016) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1017) 	hba->priv = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1018) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1019) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1020) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1021) static int exynos_ufs_host_reset(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1022) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1023) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1024) 	unsigned long timeout = jiffies + msecs_to_jiffies(1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1025) 	u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1026) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1027) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1028) 	exynos_ufs_disable_auto_ctrl_hcc_save(ufs, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1029) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1030) 	hci_writel(ufs, UFS_SW_RST_MASK, HCI_SW_RST);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1031) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1032) 	do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1033) 		if (!(hci_readl(ufs, HCI_SW_RST) & UFS_SW_RST_MASK))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1034) 			goto out;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1035) 	} while (time_before(jiffies, timeout));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1036) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1037) 	dev_err(hba->dev, "timeout host sw-reset\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1038) 	ret = -ETIMEDOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1039) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1040) out:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1041) 	exynos_ufs_auto_ctrl_hcc_restore(ufs, &val);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1042) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1043) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1044) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1045) static void exynos_ufs_dev_hw_reset(struct ufs_hba *hba)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1046) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1047) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1048) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1049) 	hci_writel(ufs, 0 << 0, HCI_GPIO_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1050) 	udelay(5);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1051) 	hci_writel(ufs, 1 << 0, HCI_GPIO_OUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1052) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1053) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1054) static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1055) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1056) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1057) 	struct exynos_ufs_uic_attr *attr = ufs->drv_data->uic_attr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1058) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1059) 	if (!enter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1060) 		if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1061) 			exynos_ufs_disable_auto_ctrl_hcc(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1062) 		exynos_ufs_ungate_clks(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1063) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1064) 		if (ufs->opts & EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1065) 			const unsigned int granularity_tbl[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1066) 				1, 4, 8, 16, 32, 100
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1067) 			};
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1068) 			int h8_time = attr->pa_hibern8time *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1069) 				granularity_tbl[attr->pa_granularity - 1];
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1070) 			unsigned long us;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1071) 			s64 delta;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1072) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1073) 			do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1074) 				delta = h8_time - ktime_us_delta(ktime_get(),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1075) 							ufs->entry_hibern8_t);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1076) 				if (delta <= 0)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1077) 					break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1078) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1079) 				us = min_t(s64, delta, USEC_PER_MSEC);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1080) 				if (us >= 10)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1081) 					usleep_range(us, us + 10);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1082) 			} while (1);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1083) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1084) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1085) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1086) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1087) static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1088) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1089) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1090) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1091) 	if (!enter) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1092) 		u32 cur_mode = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1093) 		u32 pwrmode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1094) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1095) 		if (ufshcd_is_hs_mode(&ufs->dev_req_params))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1096) 			pwrmode = FAST_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1097) 		else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1098) 			pwrmode = SLOW_MODE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1099) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1100) 		ufshcd_dme_get(hba, UIC_ARG_MIB(PA_PWRMODE), &cur_mode);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1101) 		if (cur_mode != (pwrmode << 4 | pwrmode)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1102) 			dev_warn(hba->dev, "%s: power mode change\n", __func__);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1103) 			hba->pwr_info.pwr_rx = (cur_mode >> 4) & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1104) 			hba->pwr_info.pwr_tx = cur_mode & 0xf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1105) 			ufshcd_config_pwr_mode(hba, &hba->max_pwr_info.info);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1106) 		}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1107) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1108) 		if (!(ufs->opts & EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1109) 			exynos_ufs_establish_connt(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1110) 	} else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1111) 		ufs->entry_hibern8_t = ktime_get();
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1112) 		exynos_ufs_gate_clks(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1113) 		if (ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1114) 			exynos_ufs_enable_auto_ctrl_hcc(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1115) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1116) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1117) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1118) static int exynos_ufs_hce_enable_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1119) 					enum ufs_notify_change_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1120) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1121) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1122) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1123) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1124) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1125) 	case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1126) 		ret = exynos_ufs_host_reset(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1127) 		if (ret)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1128) 			return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1129) 		exynos_ufs_dev_hw_reset(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1130) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1131) 	case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1132) 		exynos_ufs_calc_pwm_clk_div(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1133) 		if (!(ufs->opts & EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1134) 			exynos_ufs_enable_auto_ctrl_hcc(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1135) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1136) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1137) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1138) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1139) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1140) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1141) static int exynos_ufs_link_startup_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1142) 					  enum ufs_notify_change_status status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1143) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1144) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1145) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1146) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1147) 	case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1148) 		ret = exynos_ufs_pre_link(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1149) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1150) 	case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1151) 		ret = exynos_ufs_post_link(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1152) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1153) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1154) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1155) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1156) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1157) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1158) static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1159) 				enum ufs_notify_change_status status,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1160) 				struct ufs_pa_layer_attr *dev_max_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1161) 				struct ufs_pa_layer_attr *dev_req_params)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1162) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1163) 	int ret = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1164) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1165) 	switch (status) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1166) 	case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1167) 		ret = exynos_ufs_pre_pwr_mode(hba, dev_max_params,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1168) 					      dev_req_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1169) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1170) 	case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1171) 		ret = exynos_ufs_post_pwr_mode(hba, NULL, dev_req_params);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1172) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1173) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1174) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1175) 	return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1176) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1177) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1178) static void exynos_ufs_hibern8_notify(struct ufs_hba *hba,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1179) 				     enum uic_cmd_dme enter,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1180) 				     enum ufs_notify_change_status notify)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1181) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1182) 	switch ((u8)notify) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1183) 	case PRE_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1184) 		exynos_ufs_pre_hibern8(hba, enter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1185) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1186) 	case POST_CHANGE:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1187) 		exynos_ufs_post_hibern8(hba, enter);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1188) 		break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1189) 	}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1191) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1192) static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1193) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1194) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1195) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1196) 	if (!ufshcd_is_link_active(hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1197) 		phy_power_off(ufs->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1198) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1199) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1201) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1202) static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1203) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1204) 	struct exynos_ufs *ufs = ufshcd_get_variant(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1205) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1206) 	if (!ufshcd_is_link_active(hba))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1207) 		phy_power_on(ufs->phy);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1208) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1209) 	exynos_ufs_config_smu(ufs);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1210) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1211) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1212) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1213) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1214) static struct ufs_hba_variant_ops ufs_hba_exynos_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1215) 	.name				= "exynos_ufs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1216) 	.init				= exynos_ufs_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1217) 	.hce_enable_notify		= exynos_ufs_hce_enable_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1218) 	.link_startup_notify		= exynos_ufs_link_startup_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1219) 	.pwr_change_notify		= exynos_ufs_pwr_change_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1220) 	.setup_xfer_req			= exynos_ufs_specify_nexus_t_xfer_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1221) 	.setup_task_mgmt		= exynos_ufs_specify_nexus_t_tm_req,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1222) 	.hibern8_notify			= exynos_ufs_hibern8_notify,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1223) 	.suspend			= exynos_ufs_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1224) 	.resume				= exynos_ufs_resume,
^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) static int exynos_ufs_probe(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1228) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1229) 	int err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1230) 	struct device *dev = &pdev->dev;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1231) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1232) 	err = ufshcd_pltfrm_init(pdev, &ufs_hba_exynos_ops);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1233) 	if (err)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1234) 		dev_err(dev, "ufshcd_pltfrm_init() failed %d\n", err);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1235) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1236) 	return err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1237) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1238) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1239) static int exynos_ufs_remove(struct platform_device *pdev)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1240) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1241) 	struct ufs_hba *hba =  platform_get_drvdata(pdev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1242) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1243) 	pm_runtime_get_sync(&(pdev)->dev);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1244) 	ufshcd_remove(hba);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1245) 	return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1246) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1247) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1248) struct exynos_ufs_drv_data exynos_ufs_drvs = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1249) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1250) 	.compatible		= "samsung,exynos7-ufs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1251) 	.uic_attr		= &exynos7_uic_attr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1252) 	.quirks			= UFSHCD_QUIRK_PRDT_BYTE_GRAN |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1253) 				  UFSHCI_QUIRK_BROKEN_REQ_LIST_CLR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1254) 				  UFSHCI_QUIRK_BROKEN_HCE |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1255) 				  UFSHCI_QUIRK_SKIP_RESET_INTR_AGGR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1256) 				  UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1257) 				  UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1258) 				  UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1259) 				  UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1260) 	.opts			= EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1261) 				  EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1262) 				  EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1263) 				  EXYNOS_UFS_OPT_SKIP_CONNECTION_ESTAB |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1264) 				  EXYNOS_UFS_OPT_USE_SW_HIBERN8_TIMER |
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1265) 				  UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1266) 	.drv_init		= exynos7_ufs_drv_init,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1267) 	.pre_link		= exynos7_ufs_pre_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1268) 	.post_link		= exynos7_ufs_post_link,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1269) 	.pre_pwr_change		= exynos7_ufs_pre_pwr_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1270) 	.post_pwr_change	= exynos7_ufs_post_pwr_change,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1271) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1272) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1273) static const struct of_device_id exynos_ufs_of_match[] = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1274) 	{ .compatible = "samsung,exynos7-ufs",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1275) 	  .data	      = &exynos_ufs_drvs },
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1276) 	{},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1277) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1278) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1279) static const struct dev_pm_ops exynos_ufs_pm_ops = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1280) 	.suspend	= ufshcd_pltfrm_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1281) 	.resume		= ufshcd_pltfrm_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1282) 	.runtime_suspend = ufshcd_pltfrm_runtime_suspend,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1283) 	.runtime_resume  = ufshcd_pltfrm_runtime_resume,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1284) 	.runtime_idle    = ufshcd_pltfrm_runtime_idle,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1285) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1286) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1287) static struct platform_driver exynos_ufs_pltform = {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1288) 	.probe	= exynos_ufs_probe,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1289) 	.remove	= exynos_ufs_remove,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1290) 	.shutdown = ufshcd_pltfrm_shutdown,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1291) 	.driver	= {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1292) 		.name	= "exynos-ufshc",
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1293) 		.pm	= &exynos_ufs_pm_ops,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1294) 		.of_match_table = of_match_ptr(exynos_ufs_of_match),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1295) 	},
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1296) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1297) module_platform_driver(exynos_ufs_pltform);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1298) 
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1299) MODULE_AUTHOR("Alim Akhtar <alim.akhtar@samsung.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1300) MODULE_AUTHOR("Seungwon Jeon  <essuuj@gmail.com>");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1301) MODULE_DESCRIPTION("Exynos UFS HCI Driver");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1302) MODULE_LICENSE("GPL v2");