#include <asm/unaligned.h>
#include <crypto/aes.h>
#include <linux/arm-smccc.h>
#include <linux/clk.h>
#include <linux/delay.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/mfd/syscon.h>
#include <linux/phy/phy.h>
#include <linux/platform_device.h>
#include <linux/regmap.h>
#include <ufs/ufshcd.h>
#include "ufshcd-pltfrm.h"
#include <ufs/ufshci.h>
#include <ufs/unipro.h>
#include "ufs-exynos.h"
#define DATA_UNIT_SIZE …
#define HCI_TXPRDT_ENTRY_SIZE …
#define PRDT_PREFECT_EN …
#define HCI_RXPRDT_ENTRY_SIZE …
#define HCI_1US_TO_CNT_VAL …
#define CNT_VAL_1US_MASK …
#define HCI_UTRL_NEXUS_TYPE …
#define HCI_UTMRL_NEXUS_TYPE …
#define HCI_SW_RST …
#define UFS_LINK_SW_RST …
#define UFS_UNIPRO_SW_RST …
#define UFS_SW_RST_MASK …
#define HCI_DATA_REORDER …
#define HCI_UNIPRO_APB_CLK_CTRL …
#define UNIPRO_APB_CLK(v, x) …
#define HCI_AXIDMA_RWDATA_BURST_LEN …
#define HCI_GPIO_OUT …
#define HCI_ERR_EN_PA_LAYER …
#define HCI_ERR_EN_DL_LAYER …
#define HCI_ERR_EN_N_LAYER …
#define HCI_ERR_EN_T_LAYER …
#define HCI_ERR_EN_DME_LAYER …
#define HCI_V2P1_CTRL …
#define IA_TICK_SEL …
#define HCI_CLKSTOP_CTRL …
#define REFCLKOUT_STOP …
#define MPHY_APBCLK_STOP …
#define REFCLK_STOP …
#define UNIPRO_MCLK_STOP …
#define UNIPRO_PCLK_STOP …
#define CLK_STOP_MASK …
#define HCI_MISC …
#define REFCLK_CTRL_EN …
#define UNIPRO_PCLK_CTRL_EN …
#define UNIPRO_MCLK_CTRL_EN …
#define HCI_CORECLK_CTRL_EN …
#define CLK_CTRL_EN_MASK …
#define DFES_ERR_EN …
#define DFES_DEF_L2_ERRS …
#define DFES_DEF_L3_ERRS …
#define DFES_DEF_L4_ERRS …
#define UFS_WR_SHARABLE …
#define UFS_RD_SHARABLE …
#define UFS_SHARABLE …
#define UFS_SHAREABILITY_OFFSET …
#define MHCTRL …
#define MHCTRL_EN_VH_MASK …
#define MHCTRL_EN_VH(vh) …
#define PH2VH_MBOX …
#define MH_MSG_MASK …
#define MH_MSG(id, msg) …
#define MH_MSG_PH_READY …
#define MH_MSG_VH_READY …
#define ALLOW_INQUIRY …
#define ALLOW_MODE_SELECT …
#define ALLOW_MODE_SENSE …
#define ALLOW_PRE_FETCH …
#define ALLOW_READ_CMD_ALL …
#define ALLOW_READ_BUFFER …
#define ALLOW_READ_CAPACITY …
#define ALLOW_REPORT_LUNS …
#define ALLOW_REQUEST_SENSE …
#define ALLOW_SYNCHRONIZE_CACHE …
#define ALLOW_TEST_UNIT_READY …
#define ALLOW_UNMAP …
#define ALLOW_VERIFY …
#define ALLOW_WRITE_CMD_ALL …
#define ALLOW_TRANS_VH_DEFAULT …
#define HCI_MH_ALLOWABLE_TRAN_OF_VH …
#define HCI_MH_IID_IN_TASK_TAG …
#define PH_READY_TIMEOUT_MS …
enum { … };
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER0 …
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER1 …
#define UNIPRO_DME_POWERMODE_REQ_LOCALL2TIMER2 …
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER0 …
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER1 …
#define UNIPRO_DME_POWERMODE_REQ_REMOTEL2TIMER2 …
#define UFSPRSECURITY …
#define NSSMU …
#define UFSPSBEGIN0 …
#define UFSPSEND0 …
#define UFSPSLUN0 …
#define UFSPSCTRL0 …
#define CNTR_DIV_VAL …
static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en);
static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en);
static inline void exynos_ufs_enable_auto_ctrl_hcc(struct exynos_ufs *ufs)
{ … }
static inline void exynos_ufs_disable_auto_ctrl_hcc(struct exynos_ufs *ufs)
{ … }
static inline void exynos_ufs_disable_auto_ctrl_hcc_save(
struct exynos_ufs *ufs, u32 *val)
{ … }
static inline void exynos_ufs_auto_ctrl_hcc_restore(
struct exynos_ufs *ufs, u32 *val)
{ … }
static inline void exynos_ufs_gate_clks(struct exynos_ufs *ufs)
{ … }
static inline void exynos_ufs_ungate_clks(struct exynos_ufs *ufs)
{ … }
static int exynos7_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs)
{ … }
static int exynosauto_ufs_drv_init(struct device *dev, struct exynos_ufs *ufs)
{ … }
static int exynosauto_ufs_post_hce_enable(struct exynos_ufs *ufs)
{ … }
static int exynosauto_ufs_pre_link(struct exynos_ufs *ufs)
{ … }
static int exynosauto_ufs_pre_pwr_change(struct exynos_ufs *ufs,
struct ufs_pa_layer_attr *pwr)
{ … }
static int exynosauto_ufs_post_pwr_change(struct exynos_ufs *ufs,
struct ufs_pa_layer_attr *pwr)
{ … }
static int exynos7_ufs_pre_link(struct exynos_ufs *ufs)
{ … }
static int exynos7_ufs_post_link(struct exynos_ufs *ufs)
{ … }
static int exynos7_ufs_pre_pwr_change(struct exynos_ufs *ufs,
struct ufs_pa_layer_attr *pwr)
{ … }
static int exynos7_ufs_post_pwr_change(struct exynos_ufs *ufs,
struct ufs_pa_layer_attr *pwr)
{ … }
static void exynos_ufs_auto_ctrl_hcc(struct exynos_ufs *ufs, bool en)
{ … }
static void exynos_ufs_ctrl_clkstop(struct exynos_ufs *ufs, bool en)
{ … }
static int exynos_ufs_get_clk_info(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_set_unipro_pclk_div(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_set_pwm_clk_div(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_calc_pwm_clk_div(struct exynos_ufs *ufs)
{ … }
long exynos_ufs_calc_time_cntr(struct exynos_ufs *ufs, long period)
{ … }
static void exynos_ufs_specify_phy_time_attr(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_config_phy_time_attr(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_config_phy_cap_attr(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_establish_connt(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_config_smu(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_config_sync_pattern_mask(struct exynos_ufs *ufs,
struct ufs_pa_layer_attr *pwr)
{ … }
static int exynos_ufs_pre_pwr_mode(struct ufs_hba *hba,
struct ufs_pa_layer_attr *dev_max_params,
struct ufs_pa_layer_attr *dev_req_params)
{ … }
#define PWR_MODE_STR_LEN …
static int exynos_ufs_post_pwr_mode(struct ufs_hba *hba,
struct ufs_pa_layer_attr *pwr_req)
{ … }
static void exynos_ufs_specify_nexus_t_xfer_req(struct ufs_hba *hba,
int tag, bool is_scsi_cmd)
{ … }
static void exynos_ufs_specify_nexus_t_tm_req(struct ufs_hba *hba,
int tag, u8 func)
{ … }
static int exynos_ufs_phy_init(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_config_unipro(struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_config_intr(struct exynos_ufs *ufs, u32 errs, u8 index)
{ … }
static int exynos_ufs_setup_clocks(struct ufs_hba *hba, bool on,
enum ufs_notify_change_status status)
{ … }
static int exynos_ufs_pre_link(struct ufs_hba *hba)
{ … }
static void exynos_ufs_fit_aggr_timeout(struct exynos_ufs *ufs)
{ … }
static int exynos_ufs_post_link(struct ufs_hba *hba)
{ … }
static int exynos_ufs_parse_dt(struct device *dev, struct exynos_ufs *ufs)
{ … }
static inline void exynos_ufs_priv_init(struct ufs_hba *hba,
struct exynos_ufs *ufs)
{ … }
#ifdef CONFIG_SCSI_UFS_CRYPTO
enum fmp_crypto_algo_mode { … };
enum fmp_crypto_key_length { … };
struct fmp_sg_entry { … };
#define SMC_CMD_FMP_SECURITY …
#define SMC_CMD_SMU …
#define SMC_CMD_FMP_SMU_RESUME …
#define SMU_EMBEDDED …
#define SMU_INIT …
#define CFG_DESCTYPE_3 …
static void exynos_ufs_fmp_init(struct ufs_hba *hba, struct exynos_ufs *ufs)
{ … }
static void exynos_ufs_fmp_resume(struct ufs_hba *hba)
{ … }
static inline __be64 fmp_key_word(const u8 *key, int j)
{ … }
static int exynos_ufs_fmp_fill_prdt(struct ufs_hba *hba,
const struct bio_crypt_ctx *crypt_ctx,
void *prdt, unsigned int num_segments)
{ … }
#else
static void exynos_ufs_fmp_init(struct ufs_hba *hba, struct exynos_ufs *ufs)
{
}
static void exynos_ufs_fmp_resume(struct ufs_hba *hba)
{
}
#define exynos_ufs_fmp_fill_prdt …
#endif
static int exynos_ufs_init(struct ufs_hba *hba)
{ … }
static int exynos_ufs_host_reset(struct ufs_hba *hba)
{ … }
static void exynos_ufs_dev_hw_reset(struct ufs_hba *hba)
{ … }
static void exynos_ufs_pre_hibern8(struct ufs_hba *hba, u8 enter)
{ … }
static void exynos_ufs_post_hibern8(struct ufs_hba *hba, u8 enter)
{ … }
static int exynos_ufs_hce_enable_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status)
{ … }
static int exynos_ufs_link_startup_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status)
{ … }
static int exynos_ufs_pwr_change_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status,
struct ufs_pa_layer_attr *dev_max_params,
struct ufs_pa_layer_attr *dev_req_params)
{ … }
static void exynos_ufs_hibern8_notify(struct ufs_hba *hba,
enum uic_cmd_dme enter,
enum ufs_notify_change_status notify)
{ … }
static int exynos_ufs_suspend(struct ufs_hba *hba, enum ufs_pm_op pm_op,
enum ufs_notify_change_status status)
{ … }
static int exynos_ufs_resume(struct ufs_hba *hba, enum ufs_pm_op pm_op)
{ … }
static int exynosauto_ufs_vh_link_startup_notify(struct ufs_hba *hba,
enum ufs_notify_change_status status)
{ … }
static int exynosauto_ufs_vh_wait_ph_ready(struct ufs_hba *hba)
{ … }
static int exynosauto_ufs_vh_init(struct ufs_hba *hba)
{ … }
static int fsd_ufs_pre_link(struct exynos_ufs *ufs)
{ … }
static int fsd_ufs_post_link(struct exynos_ufs *ufs)
{ … }
static int fsd_ufs_pre_pwr_change(struct exynos_ufs *ufs,
struct ufs_pa_layer_attr *pwr)
{ … }
static inline u32 get_mclk_period_unipro_18(struct exynos_ufs *ufs)
{ … }
static int gs101_ufs_pre_link(struct exynos_ufs *ufs)
{ … }
static int gs101_ufs_post_link(struct exynos_ufs *ufs)
{ … }
static int gs101_ufs_pre_pwr_change(struct exynos_ufs *ufs,
struct ufs_pa_layer_attr *pwr)
{ … }
static const struct ufs_hba_variant_ops ufs_hba_exynos_ops = …;
static struct ufs_hba_variant_ops ufs_hba_exynosauto_vh_ops = …;
static int exynos_ufs_probe(struct platform_device *pdev)
{ … }
static void exynos_ufs_remove(struct platform_device *pdev)
{ … }
static struct exynos_ufs_uic_attr exynos7_uic_attr = …;
static const struct exynos_ufs_drv_data exynosauto_ufs_drvs = …;
static const struct exynos_ufs_drv_data exynosauto_ufs_vh_drvs = …;
static const struct exynos_ufs_drv_data exynos_ufs_drvs = …;
static struct exynos_ufs_uic_attr gs101_uic_attr = …;
static struct exynos_ufs_uic_attr fsd_uic_attr = …;
static const struct exynos_ufs_drv_data fsd_ufs_drvs = …;
static const struct exynos_ufs_drv_data gs101_ufs_drvs = …;
static const struct of_device_id exynos_ufs_of_match[] = …;
MODULE_DEVICE_TABLE(of, exynos_ufs_of_match);
static const struct dev_pm_ops exynos_ufs_pm_ops = …;
static struct platform_driver exynos_ufs_pltform = …;
module_platform_driver(…) …;
MODULE_AUTHOR(…) …;
MODULE_AUTHOR(…) …;
MODULE_DESCRIPTION(…) …;
MODULE_LICENSE(…) …;