162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Copyright (C) 2019 MediaTek Inc.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef _UFS_MEDIATEK_H
762306a36Sopenharmony_ci#define _UFS_MEDIATEK_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include <linux/bitops.h>
1062306a36Sopenharmony_ci#include <linux/pm_qos.h>
1162306a36Sopenharmony_ci#include <linux/soc/mediatek/mtk_sip_svc.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/*
1462306a36Sopenharmony_ci * MCQ define and struct
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci#define UFSHCD_MAX_Q_NR 8
1762306a36Sopenharmony_ci#define MTK_MCQ_INVALID_IRQ	0xFFFF
1862306a36Sopenharmony_ci
1962306a36Sopenharmony_ci/* REG_UFS_MMIO_OPT_CTRL_0 160h */
2062306a36Sopenharmony_ci#define EHS_EN                  BIT(0)
2162306a36Sopenharmony_ci#define PFM_IMPV                BIT(1)
2262306a36Sopenharmony_ci#define MCQ_MULTI_INTR_EN       BIT(2)
2362306a36Sopenharmony_ci#define MCQ_CMB_INTR_EN         BIT(3)
2462306a36Sopenharmony_ci#define MCQ_AH8                 BIT(4)
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci#define MCQ_INTR_EN_MSK         (MCQ_MULTI_INTR_EN | MCQ_CMB_INTR_EN)
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_ci/*
2962306a36Sopenharmony_ci * Vendor specific UFSHCI Registers
3062306a36Sopenharmony_ci */
3162306a36Sopenharmony_ci#define REG_UFS_XOUFS_CTRL          0x140
3262306a36Sopenharmony_ci#define REG_UFS_REFCLK_CTRL         0x144
3362306a36Sopenharmony_ci#define REG_UFS_MMIO_OPT_CTRL_0     0x160
3462306a36Sopenharmony_ci#define REG_UFS_EXTREG              0x2100
3562306a36Sopenharmony_ci#define REG_UFS_MPHYCTRL            0x2200
3662306a36Sopenharmony_ci#define REG_UFS_MTK_IP_VER          0x2240
3762306a36Sopenharmony_ci#define REG_UFS_REJECT_MON          0x22AC
3862306a36Sopenharmony_ci#define REG_UFS_DEBUG_SEL           0x22C0
3962306a36Sopenharmony_ci#define REG_UFS_PROBE               0x22C8
4062306a36Sopenharmony_ci#define REG_UFS_DEBUG_SEL_B0        0x22D0
4162306a36Sopenharmony_ci#define REG_UFS_DEBUG_SEL_B1        0x22D4
4262306a36Sopenharmony_ci#define REG_UFS_DEBUG_SEL_B2        0x22D8
4362306a36Sopenharmony_ci#define REG_UFS_DEBUG_SEL_B3        0x22DC
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci#define REG_UFS_MTK_SQD             0x2800
4662306a36Sopenharmony_ci#define REG_UFS_MTK_SQIS            0x2814
4762306a36Sopenharmony_ci#define REG_UFS_MTK_CQD             0x281C
4862306a36Sopenharmony_ci#define REG_UFS_MTK_CQIS            0x2824
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_ci#define REG_UFS_MCQ_STRIDE          0x30
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci/*
5362306a36Sopenharmony_ci * Ref-clk control
5462306a36Sopenharmony_ci *
5562306a36Sopenharmony_ci * Values for register REG_UFS_REFCLK_CTRL
5662306a36Sopenharmony_ci */
5762306a36Sopenharmony_ci#define REFCLK_RELEASE              0x0
5862306a36Sopenharmony_ci#define REFCLK_REQUEST              BIT(0)
5962306a36Sopenharmony_ci#define REFCLK_ACK                  BIT(1)
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci#define REFCLK_REQ_TIMEOUT_US       3000
6262306a36Sopenharmony_ci#define REFCLK_DEFAULT_WAIT_US      32
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/*
6562306a36Sopenharmony_ci * Other attributes
6662306a36Sopenharmony_ci */
6762306a36Sopenharmony_ci#define VS_DEBUGCLOCKENABLE         0xD0A1
6862306a36Sopenharmony_ci#define VS_SAVEPOWERCONTROL         0xD0A6
6962306a36Sopenharmony_ci#define VS_UNIPROPOWERDOWNCONTROL   0xD0A8
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_ci/*
7262306a36Sopenharmony_ci * Vendor specific link state
7362306a36Sopenharmony_ci */
7462306a36Sopenharmony_cienum {
7562306a36Sopenharmony_ci	VS_LINK_DISABLED            = 0,
7662306a36Sopenharmony_ci	VS_LINK_DOWN                = 1,
7762306a36Sopenharmony_ci	VS_LINK_UP                  = 2,
7862306a36Sopenharmony_ci	VS_LINK_HIBERN8             = 3,
7962306a36Sopenharmony_ci	VS_LINK_LOST                = 4,
8062306a36Sopenharmony_ci	VS_LINK_CFG                 = 5,
8162306a36Sopenharmony_ci};
8262306a36Sopenharmony_ci
8362306a36Sopenharmony_ci/*
8462306a36Sopenharmony_ci * Vendor specific host controller state
8562306a36Sopenharmony_ci */
8662306a36Sopenharmony_cienum {
8762306a36Sopenharmony_ci	VS_HCE_RESET                = 0,
8862306a36Sopenharmony_ci	VS_HCE_BASE                 = 1,
8962306a36Sopenharmony_ci	VS_HCE_OOCPR_WAIT           = 2,
9062306a36Sopenharmony_ci	VS_HCE_DME_RESET            = 3,
9162306a36Sopenharmony_ci	VS_HCE_MIDDLE               = 4,
9262306a36Sopenharmony_ci	VS_HCE_DME_ENABLE           = 5,
9362306a36Sopenharmony_ci	VS_HCE_DEFAULTS             = 6,
9462306a36Sopenharmony_ci	VS_HIB_IDLEEN               = 7,
9562306a36Sopenharmony_ci	VS_HIB_ENTER                = 8,
9662306a36Sopenharmony_ci	VS_HIB_ENTER_CONF           = 9,
9762306a36Sopenharmony_ci	VS_HIB_MIDDLE               = 10,
9862306a36Sopenharmony_ci	VS_HIB_WAITTIMER            = 11,
9962306a36Sopenharmony_ci	VS_HIB_EXIT_CONF            = 12,
10062306a36Sopenharmony_ci	VS_HIB_EXIT                 = 13,
10162306a36Sopenharmony_ci};
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_ci/*
10462306a36Sopenharmony_ci * SiP commands
10562306a36Sopenharmony_ci */
10662306a36Sopenharmony_ci#define MTK_SIP_UFS_CONTROL               MTK_SIP_SMC_CMD(0x276)
10762306a36Sopenharmony_ci#define UFS_MTK_SIP_VA09_PWR_CTRL         BIT(0)
10862306a36Sopenharmony_ci#define UFS_MTK_SIP_DEVICE_RESET          BIT(1)
10962306a36Sopenharmony_ci#define UFS_MTK_SIP_CRYPTO_CTRL           BIT(2)
11062306a36Sopenharmony_ci#define UFS_MTK_SIP_REF_CLK_NOTIFICATION  BIT(3)
11162306a36Sopenharmony_ci#define UFS_MTK_SIP_HOST_PWR_CTRL         BIT(5)
11262306a36Sopenharmony_ci#define UFS_MTK_SIP_GET_VCC_NUM           BIT(6)
11362306a36Sopenharmony_ci#define UFS_MTK_SIP_DEVICE_PWR_CTRL       BIT(7)
11462306a36Sopenharmony_ci
11562306a36Sopenharmony_ci/*
11662306a36Sopenharmony_ci * VS_DEBUGCLOCKENABLE
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_cienum {
11962306a36Sopenharmony_ci	TX_SYMBOL_CLK_REQ_FORCE = 5,
12062306a36Sopenharmony_ci};
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_ci/*
12362306a36Sopenharmony_ci * VS_SAVEPOWERCONTROL
12462306a36Sopenharmony_ci */
12562306a36Sopenharmony_cienum {
12662306a36Sopenharmony_ci	RX_SYMBOL_CLK_GATE_EN   = 0,
12762306a36Sopenharmony_ci	SYS_CLK_GATE_EN         = 2,
12862306a36Sopenharmony_ci	TX_CLK_GATE_EN          = 3,
12962306a36Sopenharmony_ci};
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci/*
13262306a36Sopenharmony_ci * Host capability
13362306a36Sopenharmony_ci */
13462306a36Sopenharmony_cienum ufs_mtk_host_caps {
13562306a36Sopenharmony_ci	UFS_MTK_CAP_BOOST_CRYPT_ENGINE         = 1 << 0,
13662306a36Sopenharmony_ci	UFS_MTK_CAP_VA09_PWR_CTRL              = 1 << 1,
13762306a36Sopenharmony_ci	UFS_MTK_CAP_DISABLE_AH8                = 1 << 2,
13862306a36Sopenharmony_ci	UFS_MTK_CAP_BROKEN_VCC                 = 1 << 3,
13962306a36Sopenharmony_ci	UFS_MTK_CAP_PMC_VIA_FASTAUTO           = 1 << 6,
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_cistruct ufs_mtk_crypt_cfg {
14362306a36Sopenharmony_ci	struct regulator *reg_vcore;
14462306a36Sopenharmony_ci	struct clk *clk_crypt_perf;
14562306a36Sopenharmony_ci	struct clk *clk_crypt_mux;
14662306a36Sopenharmony_ci	struct clk *clk_crypt_lp;
14762306a36Sopenharmony_ci	int vcore_volt;
14862306a36Sopenharmony_ci};
14962306a36Sopenharmony_ci
15062306a36Sopenharmony_cistruct ufs_mtk_clk {
15162306a36Sopenharmony_ci	struct ufs_clk_info *ufs_sel_clki; /* Mux */
15262306a36Sopenharmony_ci	struct ufs_clk_info *ufs_sel_max_clki; /* Max src */
15362306a36Sopenharmony_ci	struct ufs_clk_info *ufs_sel_min_clki; /* Min src */
15462306a36Sopenharmony_ci};
15562306a36Sopenharmony_ci
15662306a36Sopenharmony_cistruct ufs_mtk_hw_ver {
15762306a36Sopenharmony_ci	u8 step;
15862306a36Sopenharmony_ci	u8 minor;
15962306a36Sopenharmony_ci	u8 major;
16062306a36Sopenharmony_ci};
16162306a36Sopenharmony_ci
16262306a36Sopenharmony_cistruct ufs_mtk_mcq_intr_info {
16362306a36Sopenharmony_ci	struct ufs_hba *hba;
16462306a36Sopenharmony_ci	u32 irq;
16562306a36Sopenharmony_ci	u8 qid;
16662306a36Sopenharmony_ci};
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistruct ufs_mtk_host {
16962306a36Sopenharmony_ci	struct phy *mphy;
17062306a36Sopenharmony_ci	struct pm_qos_request pm_qos_req;
17162306a36Sopenharmony_ci	struct regulator *reg_va09;
17262306a36Sopenharmony_ci	struct reset_control *hci_reset;
17362306a36Sopenharmony_ci	struct reset_control *unipro_reset;
17462306a36Sopenharmony_ci	struct reset_control *crypto_reset;
17562306a36Sopenharmony_ci	struct ufs_hba *hba;
17662306a36Sopenharmony_ci	struct ufs_mtk_crypt_cfg *crypt;
17762306a36Sopenharmony_ci	struct ufs_mtk_clk mclk;
17862306a36Sopenharmony_ci	struct ufs_mtk_hw_ver hw_ver;
17962306a36Sopenharmony_ci	enum ufs_mtk_host_caps caps;
18062306a36Sopenharmony_ci	bool mphy_powered_on;
18162306a36Sopenharmony_ci	bool pm_qos_init;
18262306a36Sopenharmony_ci	bool unipro_lpm;
18362306a36Sopenharmony_ci	bool ref_clk_enabled;
18462306a36Sopenharmony_ci	u16 ref_clk_ungating_wait_us;
18562306a36Sopenharmony_ci	u16 ref_clk_gating_wait_us;
18662306a36Sopenharmony_ci	u32 ip_ver;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	bool mcq_set_intr;
18962306a36Sopenharmony_ci	int mcq_nr_intr;
19062306a36Sopenharmony_ci	struct ufs_mtk_mcq_intr_info mcq_intr_info[UFSHCD_MAX_Q_NR];
19162306a36Sopenharmony_ci};
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci/*
19462306a36Sopenharmony_ci * Multi-VCC by Numbering
19562306a36Sopenharmony_ci */
19662306a36Sopenharmony_cienum ufs_mtk_vcc_num {
19762306a36Sopenharmony_ci	UFS_VCC_NONE = 0,
19862306a36Sopenharmony_ci	UFS_VCC_1,
19962306a36Sopenharmony_ci	UFS_VCC_2,
20062306a36Sopenharmony_ci	UFS_VCC_MAX
20162306a36Sopenharmony_ci};
20262306a36Sopenharmony_ci
20362306a36Sopenharmony_ci/*
20462306a36Sopenharmony_ci * Host Power Control options
20562306a36Sopenharmony_ci */
20662306a36Sopenharmony_cienum {
20762306a36Sopenharmony_ci	HOST_PWR_HCI = 0,
20862306a36Sopenharmony_ci	HOST_PWR_MPHY
20962306a36Sopenharmony_ci};
21062306a36Sopenharmony_ci
21162306a36Sopenharmony_ci/*
21262306a36Sopenharmony_ci * SMC call wrapper function
21362306a36Sopenharmony_ci */
21462306a36Sopenharmony_cistruct ufs_mtk_smc_arg {
21562306a36Sopenharmony_ci	unsigned long cmd;
21662306a36Sopenharmony_ci	struct arm_smccc_res *res;
21762306a36Sopenharmony_ci	unsigned long v1;
21862306a36Sopenharmony_ci	unsigned long v2;
21962306a36Sopenharmony_ci	unsigned long v3;
22062306a36Sopenharmony_ci	unsigned long v4;
22162306a36Sopenharmony_ci	unsigned long v5;
22262306a36Sopenharmony_ci	unsigned long v6;
22362306a36Sopenharmony_ci	unsigned long v7;
22462306a36Sopenharmony_ci};
22562306a36Sopenharmony_ci
22662306a36Sopenharmony_cistatic void _ufs_mtk_smc(struct ufs_mtk_smc_arg s)
22762306a36Sopenharmony_ci{
22862306a36Sopenharmony_ci	arm_smccc_smc(MTK_SIP_UFS_CONTROL,
22962306a36Sopenharmony_ci		      s.cmd, s.v1, s.v2, s.v3, s.v4, s.v5, s.v6, s.res);
23062306a36Sopenharmony_ci}
23162306a36Sopenharmony_ci
23262306a36Sopenharmony_ci#define ufs_mtk_smc(...) \
23362306a36Sopenharmony_ci	_ufs_mtk_smc((struct ufs_mtk_smc_arg) {__VA_ARGS__})
23462306a36Sopenharmony_ci
23562306a36Sopenharmony_ci/*
23662306a36Sopenharmony_ci * SMC call interface
23762306a36Sopenharmony_ci */
23862306a36Sopenharmony_ci#define ufs_mtk_va09_pwr_ctrl(res, on) \
23962306a36Sopenharmony_ci	ufs_mtk_smc(UFS_MTK_SIP_VA09_PWR_CTRL, &(res), on)
24062306a36Sopenharmony_ci
24162306a36Sopenharmony_ci#define ufs_mtk_crypto_ctrl(res, enable) \
24262306a36Sopenharmony_ci	ufs_mtk_smc(UFS_MTK_SIP_CRYPTO_CTRL, &(res), enable)
24362306a36Sopenharmony_ci
24462306a36Sopenharmony_ci#define ufs_mtk_ref_clk_notify(on, stage, res) \
24562306a36Sopenharmony_ci	ufs_mtk_smc(UFS_MTK_SIP_REF_CLK_NOTIFICATION, &(res), on, stage)
24662306a36Sopenharmony_ci
24762306a36Sopenharmony_ci#define ufs_mtk_device_reset_ctrl(high, res) \
24862306a36Sopenharmony_ci	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_RESET, &(res), high)
24962306a36Sopenharmony_ci
25062306a36Sopenharmony_ci#define ufs_mtk_host_pwr_ctrl(opt, on, res) \
25162306a36Sopenharmony_ci	ufs_mtk_smc(UFS_MTK_SIP_HOST_PWR_CTRL, &(res), opt, on)
25262306a36Sopenharmony_ci
25362306a36Sopenharmony_ci#define ufs_mtk_get_vcc_num(res) \
25462306a36Sopenharmony_ci	ufs_mtk_smc(UFS_MTK_SIP_GET_VCC_NUM, &(res))
25562306a36Sopenharmony_ci
25662306a36Sopenharmony_ci#define ufs_mtk_device_pwr_ctrl(on, ufs_ver, res) \
25762306a36Sopenharmony_ci	ufs_mtk_smc(UFS_MTK_SIP_DEVICE_PWR_CTRL, &(res), on, ufs_ver)
25862306a36Sopenharmony_ci
25962306a36Sopenharmony_ci#endif /* !_UFS_MEDIATEK_H */
260