linux/drivers/phy/samsung/phy-samsung-ufs.h
<<
>>
Prefs
   1/* SPDX-License-Identifier: GPL-2.0-only */
   2/*
   3 * UFS PHY driver for Samsung EXYNOS SoC
   4 *
   5 * Copyright (C) 2020 Samsung Electronics Co., Ltd.
   6 * Author: Seungwon Jeon <essuuj@gmail.com>
   7 * Author: Alim Akhtar <alim.akhtar@samsung.com>
   8 *
   9 */
  10#ifndef _PHY_SAMSUNG_UFS_
  11#define _PHY_SAMSUNG_UFS_
  12
  13#define PHY_COMN_BLK    1
  14#define PHY_TRSV_BLK    2
  15#define END_UFS_PHY_CFG { 0 }
  16#define PHY_TRSV_CH_OFFSET      0x30
  17#define PHY_APB_ADDR(off)       ((off) << 2)
  18
  19#define PHY_COMN_REG_CFG(o, v, d) {     \
  20        .off_0 = PHY_APB_ADDR((o)),     \
  21        .off_1 = 0,             \
  22        .val = (v),             \
  23        .desc = (d),            \
  24        .id = PHY_COMN_BLK,     \
  25}
  26
  27#define PHY_TRSV_REG_CFG(o, v, d) {     \
  28        .off_0 = PHY_APB_ADDR((o)),     \
  29        .off_1 = PHY_APB_ADDR((o) + PHY_TRSV_CH_OFFSET),        \
  30        .val = (v),             \
  31        .desc = (d),            \
  32        .id = PHY_TRSV_BLK,     \
  33}
  34
  35/* UFS PHY registers */
  36#define PHY_PLL_LOCK_STATUS     0x1e
  37#define PHY_CDR_LOCK_STATUS     0x5e
  38
  39#define PHY_PLL_LOCK_BIT        BIT(5)
  40#define PHY_CDR_LOCK_BIT        BIT(4)
  41
  42/* description for PHY calibration */
  43enum {
  44        /* applicable to any */
  45        PWR_DESC_ANY    = 0,
  46        /* mode */
  47        PWR_DESC_PWM    = 1,
  48        PWR_DESC_HS     = 2,
  49        /* series */
  50        PWR_DESC_SER_A  = 1,
  51        PWR_DESC_SER_B  = 2,
  52        /* gear */
  53        PWR_DESC_G1     = 1,
  54        PWR_DESC_G2     = 2,
  55        PWR_DESC_G3     = 3,
  56        /* field mask */
  57        MD_MASK         = 0x3,
  58        SR_MASK         = 0x3,
  59        GR_MASK         = 0x7,
  60};
  61
  62#define PWR_MODE_HS_G1_ANY      PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_ANY)
  63#define PWR_MODE_HS_G1_SER_A    PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_A)
  64#define PWR_MODE_HS_G1_SER_B    PWR_MODE_HS(PWR_DESC_G1, PWR_DESC_SER_B)
  65#define PWR_MODE_HS_G2_ANY      PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_ANY)
  66#define PWR_MODE_HS_G2_SER_A    PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_A)
  67#define PWR_MODE_HS_G2_SER_B    PWR_MODE_HS(PWR_DESC_G2, PWR_DESC_SER_B)
  68#define PWR_MODE_HS_G3_ANY      PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_ANY)
  69#define PWR_MODE_HS_G3_SER_A    PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_A)
  70#define PWR_MODE_HS_G3_SER_B    PWR_MODE_HS(PWR_DESC_G3, PWR_DESC_SER_B)
  71#define PWR_MODE(g, s, m)       ((((g) & GR_MASK) << 4) |\
  72                                 (((s) & SR_MASK) << 2) | ((m) & MD_MASK))
  73#define PWR_MODE_PWM_ANY        PWR_MODE(PWR_DESC_ANY,\
  74                                         PWR_DESC_ANY, PWR_DESC_PWM)
  75#define PWR_MODE_HS(g, s)       ((((g) & GR_MASK) << 4) |\
  76                                 (((s) & SR_MASK) << 2) | PWR_DESC_HS)
  77#define PWR_MODE_HS_ANY         PWR_MODE(PWR_DESC_ANY,\
  78                                         PWR_DESC_ANY, PWR_DESC_HS)
  79#define PWR_MODE_ANY            PWR_MODE(PWR_DESC_ANY,\
  80                                         PWR_DESC_ANY, PWR_DESC_ANY)
  81/* PHY calibration point/state */
  82enum {
  83        CFG_PRE_INIT,
  84        CFG_POST_INIT,
  85        CFG_PRE_PWR_HS,
  86        CFG_POST_PWR_HS,
  87        CFG_TAG_MAX,
  88};
  89
  90struct samsung_ufs_phy_cfg {
  91        u32 off_0;
  92        u32 off_1;
  93        u32 val;
  94        u8 desc;
  95        u8 id;
  96};
  97
  98struct samsung_ufs_phy_drvdata {
  99        const struct samsung_ufs_phy_cfg **cfg;
 100        struct pmu_isol {
 101                u32 offset;
 102                u32 mask;
 103                u32 en;
 104        } isol;
 105        bool has_symbol_clk;
 106};
 107
 108struct samsung_ufs_phy {
 109        struct device *dev;
 110        void __iomem *reg_pma;
 111        struct regmap *reg_pmu;
 112        struct clk *ref_clk;
 113        struct clk *ref_clk_parent;
 114        struct clk *tx0_symbol_clk;
 115        struct clk *rx0_symbol_clk;
 116        struct clk *rx1_symbol_clk;
 117        const struct samsung_ufs_phy_drvdata *drvdata;
 118        struct samsung_ufs_phy_cfg **cfg;
 119        const struct pmu_isol *isol;
 120        u8 lane_cnt;
 121        int ufs_phy_state;
 122        enum phy_mode mode;
 123};
 124
 125static inline struct samsung_ufs_phy *get_samsung_ufs_phy(struct phy *phy)
 126{
 127        return (struct samsung_ufs_phy *)phy_get_drvdata(phy);
 128}
 129
 130static inline void samsung_ufs_phy_ctrl_isol(
 131                struct samsung_ufs_phy *phy, u32 isol)
 132{
 133        regmap_update_bits(phy->reg_pmu, phy->isol->offset,
 134                           phy->isol->mask, isol ? 0 : phy->isol->en);
 135}
 136
 137#include "phy-exynos7-ufs.h"
 138
 139#endif /* _PHY_SAMSUNG_UFS_ */
 140