uboot/drivers/usb/dwc3/dwc3-meson-g12a.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Amlogic G12A DWC3 Glue layer
   4 *
   5 * Copyright (C) 2019 BayLibre, SAS
   6 * Author: Neil Armstrong <narmstrong@baylibre.com>
   7 */
   8
   9#include <common.h>
  10#include <log.h>
  11#include <asm-generic/io.h>
  12#include <dm.h>
  13#include <dm/device-internal.h>
  14#include <dm/lists.h>
  15#include <dwc3-uboot.h>
  16#include <generic-phy.h>
  17#include <linux/delay.h>
  18#include <linux/usb/ch9.h>
  19#include <linux/usb/gadget.h>
  20#include <malloc.h>
  21#include <regmap.h>
  22#include <usb.h>
  23#include "core.h"
  24#include "gadget.h"
  25#include <reset.h>
  26#include <clk.h>
  27#include <power/regulator.h>
  28#include <linux/bitfield.h>
  29#include <linux/bitops.h>
  30#include <linux/compat.h>
  31
  32/* USB2 Ports Control Registers */
  33
  34#define U2P_REG_SIZE                                            0x20
  35
  36#define U2P_R0                                                  0x0
  37        #define U2P_R0_HOST_DEVICE                              BIT(0)
  38        #define U2P_R0_POWER_OK                                 BIT(1)
  39        #define U2P_R0_HAST_MODE                                BIT(2)
  40        #define U2P_R0_POWER_ON_RESET                           BIT(3)
  41        #define U2P_R0_ID_PULLUP                                BIT(4)
  42        #define U2P_R0_DRV_VBUS                                 BIT(5)
  43
  44#define U2P_R1                                                  0x4
  45        #define U2P_R1_PHY_READY                                BIT(0)
  46        #define U2P_R1_ID_DIG                                   BIT(1)
  47        #define U2P_R1_OTG_SESSION_VALID                        BIT(2)
  48        #define U2P_R1_VBUS_VALID                               BIT(3)
  49
  50/* USB Glue Control Registers */
  51
  52#define USB_R0                                                  0x80
  53        #define USB_R0_P30_LANE0_TX2RX_LOOPBACK                 BIT(17)
  54        #define USB_R0_P30_LANE0_EXT_PCLK_REQ                   BIT(18)
  55        #define USB_R0_P30_PCS_RX_LOS_MASK_VAL_MASK             GENMASK(28, 19)
  56        #define USB_R0_U2D_SS_SCALEDOWN_MODE_MASK               GENMASK(30, 29)
  57        #define USB_R0_U2D_ACT                                  BIT(31)
  58
  59#define USB_R1                                                  0x84
  60        #define USB_R1_U3H_BIGENDIAN_GS                         BIT(0)
  61        #define USB_R1_U3H_PME_ENABLE                           BIT(1)
  62        #define USB_R1_U3H_HUB_PORT_OVERCURRENT_MASK            GENMASK(4, 2)
  63        #define USB_R1_U3H_HUB_PORT_PERM_ATTACH_MASK            GENMASK(9, 7)
  64        #define USB_R1_U3H_HOST_U2_PORT_DISABLE_MASK            GENMASK(13, 12)
  65        #define USB_R1_U3H_HOST_U3_PORT_DISABLE                 BIT(16)
  66        #define USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT      BIT(17)
  67        #define USB_R1_U3H_HOST_MSI_ENABLE                      BIT(18)
  68        #define USB_R1_U3H_FLADJ_30MHZ_REG_MASK                 GENMASK(24, 19)
  69        #define USB_R1_P30_PCS_TX_SWING_FULL_MASK               GENMASK(31, 25)
  70
  71#define USB_R2                                                  0x88
  72        #define USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK             GENMASK(25, 20)
  73        #define USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK               GENMASK(31, 26)
  74
  75#define USB_R3                                                  0x8c
  76        #define USB_R3_P30_SSC_ENABLE                           BIT(0)
  77        #define USB_R3_P30_SSC_RANGE_MASK                       GENMASK(3, 1)
  78        #define USB_R3_P30_SSC_REF_CLK_SEL_MASK                 GENMASK(12, 4)
  79        #define USB_R3_P30_REF_SSP_EN                           BIT(13)
  80
  81#define USB_R4                                                  0x90
  82        #define USB_R4_P21_PORT_RESET_0                         BIT(0)
  83        #define USB_R4_P21_SLEEP_M0                             BIT(1)
  84        #define USB_R4_MEM_PD_MASK                              GENMASK(3, 2)
  85        #define USB_R4_P21_ONLY                                 BIT(4)
  86
  87#define USB_R5                                                  0x94
  88        #define USB_R5_ID_DIG_SYNC                              BIT(0)
  89        #define USB_R5_ID_DIG_REG                               BIT(1)
  90        #define USB_R5_ID_DIG_CFG_MASK                          GENMASK(3, 2)
  91        #define USB_R5_ID_DIG_EN_0                              BIT(4)
  92        #define USB_R5_ID_DIG_EN_1                              BIT(5)
  93        #define USB_R5_ID_DIG_CURR                              BIT(6)
  94        #define USB_R5_ID_DIG_IRQ                               BIT(7)
  95        #define USB_R5_ID_DIG_TH_MASK                           GENMASK(15, 8)
  96        #define USB_R5_ID_DIG_CNT_MASK                          GENMASK(23, 16)
  97
  98enum {
  99        USB2_HOST_PHY = 0,
 100        USB2_OTG_PHY,
 101        USB3_HOST_PHY,
 102        PHY_COUNT,
 103};
 104
 105static const char *phy_names[PHY_COUNT] = {
 106        "usb2-phy0", "usb2-phy1", "usb3-phy0",
 107};
 108
 109struct dwc3_meson_g12a {
 110        struct udevice          *dev;
 111        struct regmap           *regmap;
 112        struct clk              clk;
 113        struct reset_ctl        reset;
 114        struct phy              phys[PHY_COUNT];
 115        enum usb_dr_mode        otg_mode;
 116        enum usb_dr_mode        otg_phy_mode;
 117        unsigned int            usb2_ports;
 118        unsigned int            usb3_ports;
 119#if CONFIG_IS_ENABLED(DM_REGULATOR)
 120        struct udevice          *vbus_supply;
 121#endif
 122};
 123
 124#define U2P_REG_SIZE                                            0x20
 125#define USB_REG_OFFSET                                          0x80
 126
 127static void dwc3_meson_g12a_usb2_set_mode(struct dwc3_meson_g12a *priv,
 128                                          int i, enum usb_dr_mode mode)
 129{
 130        switch (mode) {
 131        case USB_DR_MODE_HOST:
 132        case USB_DR_MODE_OTG:
 133        case USB_DR_MODE_UNKNOWN:
 134                regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
 135                                U2P_R0_HOST_DEVICE,
 136                                U2P_R0_HOST_DEVICE);
 137                break;
 138
 139        case USB_DR_MODE_PERIPHERAL:
 140                regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
 141                                U2P_R0_HOST_DEVICE, 0);
 142                break;
 143        }
 144}
 145
 146static int dwc3_meson_g12a_usb2_init(struct dwc3_meson_g12a *priv)
 147{
 148        int i;
 149
 150        if (priv->otg_mode == USB_DR_MODE_PERIPHERAL)
 151                priv->otg_phy_mode = USB_DR_MODE_PERIPHERAL;
 152        else
 153                priv->otg_phy_mode = USB_DR_MODE_HOST;
 154
 155        for (i = 0 ; i < USB3_HOST_PHY ; ++i) {
 156                if (!priv->phys[i].dev)
 157                        continue;
 158
 159                regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
 160                                   U2P_R0_POWER_ON_RESET,
 161                                   U2P_R0_POWER_ON_RESET);
 162
 163                if (i == USB2_OTG_PHY) {
 164                        regmap_update_bits(priv->regmap,
 165                                           U2P_R0 + (U2P_REG_SIZE * i),
 166                                           U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS,
 167                                           U2P_R0_ID_PULLUP | U2P_R0_DRV_VBUS);
 168
 169                        dwc3_meson_g12a_usb2_set_mode(priv, i,
 170                                                      priv->otg_phy_mode);
 171                } else
 172                        dwc3_meson_g12a_usb2_set_mode(priv, i,
 173                                                      USB_DR_MODE_HOST);
 174
 175                regmap_update_bits(priv->regmap, U2P_R0 + (U2P_REG_SIZE * i),
 176                                   U2P_R0_POWER_ON_RESET, 0);
 177        }
 178
 179        return 0;
 180}
 181
 182static void dwc3_meson_g12a_usb3_init(struct dwc3_meson_g12a *priv)
 183{
 184        regmap_update_bits(priv->regmap, USB_R3,
 185                        USB_R3_P30_SSC_RANGE_MASK |
 186                        USB_R3_P30_REF_SSP_EN,
 187                        USB_R3_P30_SSC_ENABLE |
 188                        FIELD_PREP(USB_R3_P30_SSC_RANGE_MASK, 2) |
 189                        USB_R3_P30_REF_SSP_EN);
 190        udelay(2);
 191
 192        regmap_update_bits(priv->regmap, USB_R2,
 193                        USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK,
 194                        FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_3P5DB_MASK, 0x15));
 195
 196        regmap_update_bits(priv->regmap, USB_R2,
 197                        USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK,
 198                        FIELD_PREP(USB_R2_P30_PCS_TX_DEEMPH_6DB_MASK, 0x20));
 199
 200        udelay(2);
 201
 202        regmap_update_bits(priv->regmap, USB_R1,
 203                        USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT,
 204                        USB_R1_U3H_HOST_PORT_POWER_CONTROL_PRESENT);
 205
 206        regmap_update_bits(priv->regmap, USB_R1,
 207                        USB_R1_P30_PCS_TX_SWING_FULL_MASK,
 208                        FIELD_PREP(USB_R1_P30_PCS_TX_SWING_FULL_MASK, 127));
 209}
 210
 211static void dwc3_meson_g12a_usb_init_mode(struct dwc3_meson_g12a *priv)
 212{
 213        if (priv->otg_phy_mode == USB_DR_MODE_PERIPHERAL) {
 214                regmap_update_bits(priv->regmap, USB_R0,
 215                                USB_R0_U2D_ACT, USB_R0_U2D_ACT);
 216                regmap_update_bits(priv->regmap, USB_R0,
 217                                USB_R0_U2D_SS_SCALEDOWN_MODE_MASK, 0);
 218                regmap_update_bits(priv->regmap, USB_R4,
 219                                USB_R4_P21_SLEEP_M0, USB_R4_P21_SLEEP_M0);
 220        } else {
 221                regmap_update_bits(priv->regmap, USB_R0,
 222                                USB_R0_U2D_ACT, 0);
 223                regmap_update_bits(priv->regmap, USB_R4,
 224                                USB_R4_P21_SLEEP_M0, 0);
 225        }
 226}
 227
 228static int dwc3_meson_g12a_usb_init(struct dwc3_meson_g12a *priv)
 229{
 230        int ret;
 231
 232        ret = dwc3_meson_g12a_usb2_init(priv);
 233        if (ret)
 234                return ret;
 235
 236        regmap_update_bits(priv->regmap, USB_R1,
 237                        USB_R1_U3H_FLADJ_30MHZ_REG_MASK,
 238                        FIELD_PREP(USB_R1_U3H_FLADJ_30MHZ_REG_MASK, 0x20));
 239
 240        regmap_update_bits(priv->regmap, USB_R5,
 241                        USB_R5_ID_DIG_EN_0,
 242                        USB_R5_ID_DIG_EN_0);
 243        regmap_update_bits(priv->regmap, USB_R5,
 244                        USB_R5_ID_DIG_EN_1,
 245                        USB_R5_ID_DIG_EN_1);
 246        regmap_update_bits(priv->regmap, USB_R5,
 247                        USB_R5_ID_DIG_TH_MASK,
 248                        FIELD_PREP(USB_R5_ID_DIG_TH_MASK, 0xff));
 249
 250        /* If we have an actual SuperSpeed port, initialize it */
 251        if (priv->usb3_ports)
 252                dwc3_meson_g12a_usb3_init(priv);
 253
 254        dwc3_meson_g12a_usb_init_mode(priv);
 255
 256        return 0;
 257}
 258
 259int dwc3_meson_g12a_force_mode(struct udevice *dev, enum usb_dr_mode mode)
 260{
 261        struct dwc3_meson_g12a *priv = dev_get_plat(dev);
 262
 263        if (!priv)
 264                return -EINVAL;
 265
 266        if (mode != USB_DR_MODE_HOST && mode != USB_DR_MODE_PERIPHERAL)
 267                return -EINVAL;
 268
 269        if (!priv->phys[USB2_OTG_PHY].dev)
 270                return -EINVAL;
 271
 272        if (mode == USB_DR_MODE_HOST)
 273                debug("%s: switching to Host Mode\n", __func__);
 274        else
 275                debug("%s: switching to Device Mode\n", __func__);
 276
 277#if CONFIG_IS_ENABLED(DM_REGULATOR)
 278        if (priv->vbus_supply) {
 279                int ret = regulator_set_enable(priv->vbus_supply,
 280                                        (mode == USB_DR_MODE_PERIPHERAL));
 281                if (ret)
 282                        return ret;
 283        }
 284#endif
 285        priv->otg_phy_mode = mode;
 286
 287        dwc3_meson_g12a_usb2_set_mode(priv, USB2_OTG_PHY, mode);
 288
 289        dwc3_meson_g12a_usb_init_mode(priv);
 290
 291        return 0;
 292}
 293
 294static int dwc3_meson_g12a_get_phys(struct dwc3_meson_g12a *priv)
 295{
 296        int i, ret;
 297
 298        for (i = 0 ; i < PHY_COUNT ; ++i) {
 299                ret = generic_phy_get_by_name(priv->dev, phy_names[i],
 300                                              &priv->phys[i]);
 301                if (ret == -ENOENT || ret == -ENODATA)
 302                        continue;
 303
 304                if (ret)
 305                        return ret;
 306
 307                if (i == USB3_HOST_PHY)
 308                        priv->usb3_ports++;
 309                else
 310                        priv->usb2_ports++;
 311        }
 312
 313        debug("%s: usb2 ports: %d\n", __func__, priv->usb2_ports);
 314        debug("%s: usb3 ports: %d\n", __func__, priv->usb3_ports);
 315
 316        return 0;
 317}
 318
 319static int dwc3_meson_g12a_reset_init(struct dwc3_meson_g12a *priv)
 320{
 321        int ret;
 322
 323        ret = reset_get_by_index(priv->dev, 0, &priv->reset);
 324        if (ret)
 325                return ret;
 326
 327        ret = reset_assert(&priv->reset);
 328        udelay(1);
 329        ret |= reset_deassert(&priv->reset);
 330        if (ret) {
 331                reset_free(&priv->reset);
 332                return ret;
 333        }
 334
 335        return 0;
 336}
 337
 338static int dwc3_meson_g12a_clk_init(struct dwc3_meson_g12a *priv)
 339{
 340        int ret;
 341
 342        ret = clk_get_by_index(priv->dev, 0, &priv->clk);
 343        if (ret)
 344                return ret;
 345
 346#if CONFIG_IS_ENABLED(CLK)
 347        ret = clk_enable(&priv->clk);
 348        if (ret) {
 349                clk_free(&priv->clk);
 350                return ret;
 351        }
 352#endif
 353
 354        return 0;
 355}
 356
 357static int dwc3_meson_g12a_probe(struct udevice *dev)
 358{
 359        struct dwc3_meson_g12a *priv = dev_get_plat(dev);
 360        int ret, i;
 361
 362        priv->dev = dev;
 363
 364        ret = regmap_init_mem(dev_ofnode(dev), &priv->regmap);
 365        if (ret)
 366                return ret;
 367
 368        ret = dwc3_meson_g12a_clk_init(priv);
 369        if (ret)
 370                return ret;
 371
 372        ret = dwc3_meson_g12a_reset_init(priv);
 373        if (ret)
 374                return ret;
 375
 376        ret = dwc3_meson_g12a_get_phys(priv);
 377        if (ret)
 378                return ret;
 379
 380#if CONFIG_IS_ENABLED(DM_REGULATOR)
 381        ret = device_get_supply_regulator(dev, "vbus-supply",
 382                                          &priv->vbus_supply);
 383        if (ret && ret != -ENOENT) {
 384                pr_err("Failed to get PHY regulator\n");
 385                return ret;
 386        }
 387
 388        if (priv->vbus_supply) {
 389                ret = regulator_set_enable(priv->vbus_supply, true);
 390                if (ret)
 391                        return ret;
 392        }
 393#endif
 394
 395        priv->otg_mode = usb_get_dr_mode(dev_ofnode(dev));
 396
 397        ret = dwc3_meson_g12a_usb_init(priv);
 398        if (ret)
 399                return ret;
 400
 401        for (i = 0 ; i < PHY_COUNT ; ++i) {
 402                if (!priv->phys[i].dev)
 403                        continue;
 404
 405                ret = generic_phy_init(&priv->phys[i]);
 406                if (ret)
 407                        goto err_phy_init;
 408        }
 409
 410        for (i = 0; i < PHY_COUNT; ++i) {
 411                if (!priv->phys[i].dev)
 412                        continue;
 413
 414                ret = generic_phy_power_on(&priv->phys[i]);
 415                if (ret)
 416                        goto err_phy_init;
 417        }
 418
 419        return 0;
 420
 421err_phy_init:
 422        for (i = 0 ; i < PHY_COUNT ; ++i) {
 423                if (!priv->phys[i].dev)
 424                        continue;
 425
 426                 generic_phy_exit(&priv->phys[i]);
 427        }
 428
 429        return ret;
 430}
 431
 432static int dwc3_meson_g12a_remove(struct udevice *dev)
 433{
 434        struct dwc3_meson_g12a *priv = dev_get_plat(dev);
 435        int i;
 436
 437        reset_release_all(&priv->reset, 1);
 438
 439        clk_release_all(&priv->clk, 1);
 440
 441        for (i = 0; i < PHY_COUNT; ++i) {
 442                if (!priv->phys[i].dev)
 443                        continue;
 444
 445                 generic_phy_power_off(&priv->phys[i]);
 446        }
 447
 448        for (i = 0 ; i < PHY_COUNT ; ++i) {
 449                if (!priv->phys[i].dev)
 450                        continue;
 451
 452                 generic_phy_exit(&priv->phys[i]);
 453        }
 454
 455        return dm_scan_fdt_dev(dev);
 456}
 457
 458static const struct udevice_id dwc3_meson_g12a_ids[] = {
 459        { .compatible = "amlogic,meson-g12a-usb-ctrl" },
 460        { }
 461};
 462
 463U_BOOT_DRIVER(dwc3_generic_wrapper) = {
 464        .name   = "dwc3-meson-g12a",
 465        .id     = UCLASS_SIMPLE_BUS,
 466        .of_match = dwc3_meson_g12a_ids,
 467        .probe = dwc3_meson_g12a_probe,
 468        .remove = dwc3_meson_g12a_remove,
 469        .plat_auto      = sizeof(struct dwc3_meson_g12a),
 470
 471};
 472