linux/drivers/usb/phy/phy-samsung-usb.h
<<
>>
Prefs
   1/* linux/drivers/usb/phy/phy-samsung-usb.h
   2 *
   3 * Copyright (c) 2012 Samsung Electronics Co., Ltd.
   4 *              http://www.samsung.com
   5 *
   6 * Samsung USB-PHY transceiver; talks to S3C HS OTG controller, EHCI-S5P and
   7 * OHCI-EXYNOS controllers.
   8 *
   9 * This program is free software; you can redistribute it and/or modify
  10 * it under the terms of the GNU General Public License version 2 as
  11 * published by the Free Software Foundation.
  12 *
  13 * This program is distributed in the hope that it will be useful,
  14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16 * GNU General Public License for more details.
  17 */
  18
  19#include <linux/usb/phy.h>
  20
  21/* Register definitions */
  22
  23#define SAMSUNG_PHYPWR                          (0x00)
  24
  25#define PHYPWR_NORMAL_MASK                      (0x19 << 0)
  26#define PHYPWR_OTG_DISABLE                      (0x1 << 4)
  27#define PHYPWR_ANALOG_POWERDOWN                 (0x1 << 3)
  28#define PHYPWR_FORCE_SUSPEND                    (0x1 << 1)
  29/* For Exynos4 */
  30#define PHYPWR_NORMAL_MASK_PHY0                 (0x39 << 0)
  31#define PHYPWR_SLEEP_PHY0                       (0x1 << 5)
  32
  33#define SAMSUNG_PHYCLK                          (0x04)
  34
  35#define PHYCLK_MODE_USB11                       (0x1 << 6)
  36#define PHYCLK_EXT_OSC                          (0x1 << 5)
  37#define PHYCLK_COMMON_ON_N                      (0x1 << 4)
  38#define PHYCLK_ID_PULL                          (0x1 << 2)
  39#define PHYCLK_CLKSEL_MASK                      (0x3 << 0)
  40#define PHYCLK_CLKSEL_48M                       (0x0 << 0)
  41#define PHYCLK_CLKSEL_12M                       (0x2 << 0)
  42#define PHYCLK_CLKSEL_24M                       (0x3 << 0)
  43
  44#define SAMSUNG_RSTCON                          (0x08)
  45
  46#define RSTCON_PHYLINK_SWRST                    (0x1 << 2)
  47#define RSTCON_HLINK_SWRST                      (0x1 << 1)
  48#define RSTCON_SWRST                            (0x1 << 0)
  49
  50/* EXYNOS4X12 */
  51#define EXYNOS4X12_PHY_HSIC_CTRL0               (0x04)
  52#define EXYNOS4X12_PHY_HSIC_CTRL1               (0x08)
  53
  54#define PHYPWR_NORMAL_MASK_HSIC1                (0x7 << 12)
  55#define PHYPWR_NORMAL_MASK_HSIC0                (0x7 << 9)
  56#define PHYPWR_NORMAL_MASK_PHY1                 (0x7 << 6)
  57
  58#define RSTCON_HOSTPHY_SWRST                    (0xf << 3)
  59
  60/* EXYNOS5 */
  61#define EXYNOS5_PHY_HOST_CTRL0                  (0x00)
  62
  63#define HOST_CTRL0_PHYSWRSTALL                  (0x1 << 31)
  64
  65#define HOST_CTRL0_REFCLKSEL_MASK               (0x3 << 19)
  66#define HOST_CTRL0_REFCLKSEL_XTAL               (0x0 << 19)
  67#define HOST_CTRL0_REFCLKSEL_EXTL               (0x1 << 19)
  68#define HOST_CTRL0_REFCLKSEL_CLKCORE            (0x2 << 19)
  69
  70#define HOST_CTRL0_FSEL_MASK                    (0x7 << 16)
  71#define HOST_CTRL0_FSEL(_x)                     ((_x) << 16)
  72
  73#define FSEL_CLKSEL_50M                         (0x7)
  74#define FSEL_CLKSEL_24M                         (0x5)
  75#define FSEL_CLKSEL_20M                         (0x4)
  76#define FSEL_CLKSEL_19200K                      (0x3)
  77#define FSEL_CLKSEL_12M                         (0x2)
  78#define FSEL_CLKSEL_10M                         (0x1)
  79#define FSEL_CLKSEL_9600K                       (0x0)
  80
  81#define HOST_CTRL0_TESTBURNIN                   (0x1 << 11)
  82#define HOST_CTRL0_RETENABLE                    (0x1 << 10)
  83#define HOST_CTRL0_COMMONON_N                   (0x1 << 9)
  84#define HOST_CTRL0_SIDDQ                        (0x1 << 6)
  85#define HOST_CTRL0_FORCESLEEP                   (0x1 << 5)
  86#define HOST_CTRL0_FORCESUSPEND                 (0x1 << 4)
  87#define HOST_CTRL0_WORDINTERFACE                (0x1 << 3)
  88#define HOST_CTRL0_UTMISWRST                    (0x1 << 2)
  89#define HOST_CTRL0_LINKSWRST                    (0x1 << 1)
  90#define HOST_CTRL0_PHYSWRST                     (0x1 << 0)
  91
  92#define EXYNOS5_PHY_HOST_TUNE0                  (0x04)
  93
  94#define EXYNOS5_PHY_HSIC_CTRL1                  (0x10)
  95
  96#define EXYNOS5_PHY_HSIC_TUNE1                  (0x14)
  97
  98#define EXYNOS5_PHY_HSIC_CTRL2                  (0x20)
  99
 100#define EXYNOS5_PHY_HSIC_TUNE2                  (0x24)
 101
 102#define HSIC_CTRL_REFCLKSEL_MASK                (0x3 << 23)
 103#define HSIC_CTRL_REFCLKSEL                     (0x2 << 23)
 104
 105#define HSIC_CTRL_REFCLKDIV_MASK                (0x7f << 16)
 106#define HSIC_CTRL_REFCLKDIV(_x)                 ((_x) << 16)
 107#define HSIC_CTRL_REFCLKDIV_12                  (0x24 << 16)
 108#define HSIC_CTRL_REFCLKDIV_15                  (0x1c << 16)
 109#define HSIC_CTRL_REFCLKDIV_16                  (0x1a << 16)
 110#define HSIC_CTRL_REFCLKDIV_19_2                (0x15 << 16)
 111#define HSIC_CTRL_REFCLKDIV_20                  (0x14 << 16)
 112
 113#define HSIC_CTRL_SIDDQ                         (0x1 << 6)
 114#define HSIC_CTRL_FORCESLEEP                    (0x1 << 5)
 115#define HSIC_CTRL_FORCESUSPEND                  (0x1 << 4)
 116#define HSIC_CTRL_WORDINTERFACE                 (0x1 << 3)
 117#define HSIC_CTRL_UTMISWRST                     (0x1 << 2)
 118#define HSIC_CTRL_PHYSWRST                      (0x1 << 0)
 119
 120#define EXYNOS5_PHY_HOST_EHCICTRL               (0x30)
 121
 122#define HOST_EHCICTRL_ENAINCRXALIGN             (0x1 << 29)
 123#define HOST_EHCICTRL_ENAINCR4                  (0x1 << 28)
 124#define HOST_EHCICTRL_ENAINCR8                  (0x1 << 27)
 125#define HOST_EHCICTRL_ENAINCR16                 (0x1 << 26)
 126
 127#define EXYNOS5_PHY_HOST_OHCICTRL               (0x34)
 128
 129#define HOST_OHCICTRL_SUSPLGCY                  (0x1 << 3)
 130#define HOST_OHCICTRL_APPSTARTCLK               (0x1 << 2)
 131#define HOST_OHCICTRL_CNTSEL                    (0x1 << 1)
 132#define HOST_OHCICTRL_CLKCKTRST                 (0x1 << 0)
 133
 134#define EXYNOS5_PHY_OTG_SYS                     (0x38)
 135
 136#define OTG_SYS_PHYLINK_SWRESET                 (0x1 << 14)
 137#define OTG_SYS_LINKSWRST_UOTG                  (0x1 << 13)
 138#define OTG_SYS_PHY0_SWRST                      (0x1 << 12)
 139
 140#define OTG_SYS_REFCLKSEL_MASK                  (0x3 << 9)
 141#define OTG_SYS_REFCLKSEL_XTAL                  (0x0 << 9)
 142#define OTG_SYS_REFCLKSEL_EXTL                  (0x1 << 9)
 143#define OTG_SYS_REFCLKSEL_CLKCORE               (0x2 << 9)
 144
 145#define OTG_SYS_IDPULLUP_UOTG                   (0x1 << 8)
 146#define OTG_SYS_COMMON_ON                       (0x1 << 7)
 147
 148#define OTG_SYS_FSEL_MASK                       (0x7 << 4)
 149#define OTG_SYS_FSEL(_x)                        ((_x) << 4)
 150
 151#define OTG_SYS_FORCESLEEP                      (0x1 << 3)
 152#define OTG_SYS_OTGDISABLE                      (0x1 << 2)
 153#define OTG_SYS_SIDDQ_UOTG                      (0x1 << 1)
 154#define OTG_SYS_FORCESUSPEND                    (0x1 << 0)
 155
 156#define EXYNOS5_PHY_OTG_TUNE                    (0x40)
 157
 158/* EXYNOS5: USB 3.0 DRD */
 159#define EXYNOS5_DRD_LINKSYSTEM                  (0x04)
 160
 161#define LINKSYSTEM_FLADJ_MASK                   (0x3f << 1)
 162#define LINKSYSTEM_FLADJ(_x)                    ((_x) << 1)
 163#define LINKSYSTEM_XHCI_VERSION_CONTROL         (0x1 << 27)
 164
 165#define EXYNOS5_DRD_PHYUTMI                     (0x08)
 166
 167#define PHYUTMI_OTGDISABLE                      (0x1 << 6)
 168#define PHYUTMI_FORCESUSPEND                    (0x1 << 1)
 169#define PHYUTMI_FORCESLEEP                      (0x1 << 0)
 170
 171#define EXYNOS5_DRD_PHYPIPE                     (0x0c)
 172
 173#define EXYNOS5_DRD_PHYCLKRST                   (0x10)
 174
 175#define PHYCLKRST_SSC_REFCLKSEL_MASK            (0xff << 23)
 176#define PHYCLKRST_SSC_REFCLKSEL(_x)             ((_x) << 23)
 177
 178#define PHYCLKRST_SSC_RANGE_MASK                (0x03 << 21)
 179#define PHYCLKRST_SSC_RANGE(_x)                 ((_x) << 21)
 180
 181#define PHYCLKRST_SSC_EN                        (0x1 << 20)
 182#define PHYCLKRST_REF_SSP_EN                    (0x1 << 19)
 183#define PHYCLKRST_REF_CLKDIV2                   (0x1 << 18)
 184
 185#define PHYCLKRST_MPLL_MULTIPLIER_MASK          (0x7f << 11)
 186#define PHYCLKRST_MPLL_MULTIPLIER_100MHZ_REF    (0x19 << 11)
 187#define PHYCLKRST_MPLL_MULTIPLIER_50M_REF       (0x02 << 11)
 188#define PHYCLKRST_MPLL_MULTIPLIER_24MHZ_REF     (0x68 << 11)
 189#define PHYCLKRST_MPLL_MULTIPLIER_20MHZ_REF     (0x7d << 11)
 190#define PHYCLKRST_MPLL_MULTIPLIER_19200KHZ_REF  (0x02 << 11)
 191
 192#define PHYCLKRST_FSEL_MASK                     (0x3f << 5)
 193#define PHYCLKRST_FSEL(_x)                      ((_x) << 5)
 194#define PHYCLKRST_FSEL_PAD_100MHZ               (0x27 << 5)
 195#define PHYCLKRST_FSEL_PAD_24MHZ                (0x2a << 5)
 196#define PHYCLKRST_FSEL_PAD_20MHZ                (0x31 << 5)
 197#define PHYCLKRST_FSEL_PAD_19_2MHZ              (0x38 << 5)
 198
 199#define PHYCLKRST_RETENABLEN                    (0x1 << 4)
 200
 201#define PHYCLKRST_REFCLKSEL_MASK                (0x03 << 2)
 202#define PHYCLKRST_REFCLKSEL_PAD_REFCLK          (0x2 << 2)
 203#define PHYCLKRST_REFCLKSEL_EXT_REFCLK          (0x3 << 2)
 204
 205#define PHYCLKRST_PORTRESET                     (0x1 << 1)
 206#define PHYCLKRST_COMMONONN                     (0x1 << 0)
 207
 208#define EXYNOS5_DRD_PHYREG0                     (0x14)
 209#define EXYNOS5_DRD_PHYREG1                     (0x18)
 210
 211#define EXYNOS5_DRD_PHYPARAM0                   (0x1c)
 212
 213#define PHYPARAM0_REF_USE_PAD                   (0x1 << 31)
 214#define PHYPARAM0_REF_LOSLEVEL_MASK             (0x1f << 26)
 215#define PHYPARAM0_REF_LOSLEVEL                  (0x9 << 26)
 216
 217#define EXYNOS5_DRD_PHYPARAM1                   (0x20)
 218
 219#define PHYPARAM1_PCS_TXDEEMPH_MASK             (0x1f << 0)
 220#define PHYPARAM1_PCS_TXDEEMPH                  (0x1c)
 221
 222#define EXYNOS5_DRD_PHYTERM                     (0x24)
 223
 224#define EXYNOS5_DRD_PHYTEST                     (0x28)
 225
 226#define PHYTEST_POWERDOWN_SSP                   (0x1 << 3)
 227#define PHYTEST_POWERDOWN_HSP                   (0x1 << 2)
 228
 229#define EXYNOS5_DRD_PHYADP                      (0x2c)
 230
 231#define EXYNOS5_DRD_PHYBATCHG                   (0x30)
 232
 233#define PHYBATCHG_UTMI_CLKSEL                   (0x1 << 2)
 234
 235#define EXYNOS5_DRD_PHYRESUME                   (0x34)
 236#define EXYNOS5_DRD_LINKPORT                    (0x44)
 237
 238#ifndef MHZ
 239#define MHZ (1000*1000)
 240#endif
 241
 242#ifndef KHZ
 243#define KHZ (1000)
 244#endif
 245
 246#define EXYNOS_USBHOST_PHY_CTRL_OFFSET          (0x4)
 247#define S3C64XX_USBPHY_ENABLE                   (0x1 << 16)
 248#define EXYNOS_USBPHY_ENABLE                    (0x1 << 0)
 249#define EXYNOS_USB20PHY_CFG_HOST_LINK           (0x1 << 0)
 250
 251enum samsung_cpu_type {
 252        TYPE_S3C64XX,
 253        TYPE_EXYNOS4210,
 254        TYPE_EXYNOS4X12,
 255        TYPE_EXYNOS5250,
 256};
 257
 258struct samsung_usbphy;
 259
 260/*
 261 * struct samsung_usbphy_drvdata - driver data for various SoC variants
 262 * @cpu_type: machine identifier
 263 * @devphy_en_mask: device phy enable mask for PHY CONTROL register
 264 * @hostphy_en_mask: host phy enable mask for PHY CONTROL register
 265 * @devphy_reg_offset: offset to DEVICE PHY CONTROL register from
 266 *                     mapped address of system controller.
 267 * @hostphy_reg_offset: offset to HOST PHY CONTROL register from
 268 *                     mapped address of system controller.
 269 *
 270 *      Here we have a separate mask for device type phy.
 271 *      Having different masks for host and device type phy helps
 272 *      in setting independent masks in case of SoCs like S5PV210,
 273 *      in which PHY0 and PHY1 enable bits belong to same register
 274 *      placed at position 0 and 1 respectively.
 275 *      Although for newer SoCs like exynos these bits belong to
 276 *      different registers altogether placed at position 0.
 277 */
 278struct samsung_usbphy_drvdata {
 279        int cpu_type;
 280        int devphy_en_mask;
 281        int hostphy_en_mask;
 282        u32 devphy_reg_offset;
 283        u32 hostphy_reg_offset;
 284        int (*rate_to_clksel)(struct samsung_usbphy *, unsigned long);
 285        void (*set_isolation)(struct samsung_usbphy *, bool);
 286        void (*phy_enable)(struct samsung_usbphy *);
 287        void (*phy_disable)(struct samsung_usbphy *);
 288};
 289
 290/*
 291 * struct samsung_usbphy - transceiver driver state
 292 * @phy: transceiver structure
 293 * @plat: platform data
 294 * @dev: The parent device supplied to the probe function
 295 * @clk: usb phy clock
 296 * @regs: usb phy controller registers memory base
 297 * @pmuregs: USB device PHY_CONTROL register memory base
 298 * @sysreg: USB2.0 PHY_CFG register memory base
 299 * @ref_clk_freq: reference clock frequency selection
 300 * @drv_data: driver data available for different SoCs
 301 * @phy_type: Samsung SoCs specific phy types:  #HOST
 302 *                                              #DEVICE
 303 * @phy_usage: usage count for phy
 304 * @lock: lock for phy operations
 305 */
 306struct samsung_usbphy {
 307        struct usb_phy  phy;
 308        struct samsung_usbphy_data *plat;
 309        struct device   *dev;
 310        struct clk      *clk;
 311        void __iomem    *regs;
 312        void __iomem    *pmuregs;
 313        void __iomem    *sysreg;
 314        int             ref_clk_freq;
 315        const struct samsung_usbphy_drvdata *drv_data;
 316        enum samsung_usb_phy_type phy_type;
 317        atomic_t        phy_usage;
 318        spinlock_t      lock;
 319};
 320
 321#define phy_to_sphy(x)          container_of((x), struct samsung_usbphy, phy)
 322
 323static const struct of_device_id samsung_usbphy_dt_match[];
 324
 325static inline const struct samsung_usbphy_drvdata
 326*samsung_usbphy_get_driver_data(struct platform_device *pdev)
 327{
 328        if (pdev->dev.of_node) {
 329                const struct of_device_id *match;
 330                match = of_match_node(samsung_usbphy_dt_match,
 331                                                        pdev->dev.of_node);
 332                return match->data;
 333        }
 334
 335        return (struct samsung_usbphy_drvdata *)
 336                                platform_get_device_id(pdev)->driver_data;
 337}
 338
 339extern int samsung_usbphy_parse_dt(struct samsung_usbphy *sphy);
 340extern void samsung_usbphy_set_isolation_4210(struct samsung_usbphy *sphy,
 341                                                                bool on);
 342extern void samsung_usbphy_cfg_sel(struct samsung_usbphy *sphy);
 343extern int samsung_usbphy_set_type(struct usb_phy *phy,
 344                                        enum samsung_usb_phy_type phy_type);
 345extern int samsung_usbphy_get_refclk_freq(struct samsung_usbphy *sphy);
 346extern int samsung_usbphy_rate_to_clksel_64xx(struct samsung_usbphy *sphy,
 347                                                        unsigned long rate);
 348extern int samsung_usbphy_rate_to_clksel_4x12(struct samsung_usbphy *sphy,
 349                                                        unsigned long rate);
 350