^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");