uboot/drivers/phy/phy-stm32-usbphyc.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0+ OR BSD-3-Clause
   2/*
   3 * Copyright (C) 2018, STMicroelectronics - All Rights Reserved
   4 */
   5
   6#include <common.h>
   7#include <clk.h>
   8#include <div64.h>
   9#include <dm.h>
  10#include <fdtdec.h>
  11#include <generic-phy.h>
  12#include <log.h>
  13#include <reset.h>
  14#include <syscon.h>
  15#include <usb.h>
  16#include <asm/io.h>
  17#include <dm/device_compat.h>
  18#include <linux/bitops.h>
  19#include <linux/delay.h>
  20#include <power/regulator.h>
  21
  22/* USBPHYC registers */
  23#define STM32_USBPHYC_PLL       0x0
  24#define STM32_USBPHYC_MISC      0x8
  25
  26/* STM32_USBPHYC_PLL bit fields */
  27#define PLLNDIV                 GENMASK(6, 0)
  28#define PLLNDIV_SHIFT           0
  29#define PLLFRACIN               GENMASK(25, 10)
  30#define PLLFRACIN_SHIFT         10
  31#define PLLEN                   BIT(26)
  32#define PLLSTRB                 BIT(27)
  33#define PLLSTRBYP               BIT(28)
  34#define PLLFRACCTL              BIT(29)
  35#define PLLDITHEN0              BIT(30)
  36#define PLLDITHEN1              BIT(31)
  37
  38/* STM32_USBPHYC_MISC bit fields */
  39#define SWITHOST                BIT(0)
  40
  41#define MAX_PHYS                2
  42
  43/* max 100 us for PLL lock and 100 us for PHY init */
  44#define PLL_INIT_TIME_US        200
  45#define PLL_PWR_DOWN_TIME_US    5
  46#define PLL_FVCO                2880     /* in MHz */
  47#define PLL_INFF_MIN_RATE       19200000 /* in Hz */
  48#define PLL_INFF_MAX_RATE       38400000 /* in Hz */
  49
  50struct pll_params {
  51        u8 ndiv;
  52        u16 frac;
  53};
  54
  55struct stm32_usbphyc {
  56        fdt_addr_t base;
  57        struct clk clk;
  58        struct udevice *vdda1v1;
  59        struct udevice *vdda1v8;
  60        struct stm32_usbphyc_phy {
  61                struct udevice *vdd;
  62                bool init;
  63                bool powered;
  64        } phys[MAX_PHYS];
  65};
  66
  67static void stm32_usbphyc_get_pll_params(u32 clk_rate,
  68                                         struct pll_params *pll_params)
  69{
  70        unsigned long long fvco, ndiv, frac;
  71
  72        /*
  73         *    | FVCO = INFF*2*(NDIV + FRACT/2^16 ) when DITHER_DISABLE[1] = 1
  74         *    | FVCO = 2880MHz
  75         *    | NDIV = integer part of input bits to set the LDF
  76         *    | FRACT = fractional part of input bits to set the LDF
  77         *  =>  PLLNDIV = integer part of (FVCO / (INFF*2))
  78         *  =>  PLLFRACIN = fractional part of(FVCO / INFF*2) * 2^16
  79         * <=>  PLLFRACIN = ((FVCO / (INFF*2)) - PLLNDIV) * 2^16
  80         */
  81        fvco = (unsigned long long)PLL_FVCO * 1000000; /* In Hz */
  82
  83        ndiv = fvco;
  84        do_div(ndiv, (clk_rate * 2));
  85        pll_params->ndiv = (u8)ndiv;
  86
  87        frac = fvco * (1 << 16);
  88        do_div(frac, (clk_rate * 2));
  89        frac = frac - (ndiv * (1 << 16));
  90        pll_params->frac = (u16)frac;
  91}
  92
  93static int stm32_usbphyc_pll_init(struct stm32_usbphyc *usbphyc)
  94{
  95        struct pll_params pll_params;
  96        u32 clk_rate = clk_get_rate(&usbphyc->clk);
  97        u32 usbphyc_pll;
  98
  99        if ((clk_rate < PLL_INFF_MIN_RATE) || (clk_rate > PLL_INFF_MAX_RATE)) {
 100                pr_debug("%s: input clk freq (%dHz) out of range\n",
 101                         __func__, clk_rate);
 102                return -EINVAL;
 103        }
 104
 105        stm32_usbphyc_get_pll_params(clk_rate, &pll_params);
 106
 107        usbphyc_pll = PLLDITHEN1 | PLLDITHEN0 | PLLSTRBYP;
 108        usbphyc_pll |= ((pll_params.ndiv << PLLNDIV_SHIFT) & PLLNDIV);
 109
 110        if (pll_params.frac) {
 111                usbphyc_pll |= PLLFRACCTL;
 112                usbphyc_pll |= ((pll_params.frac << PLLFRACIN_SHIFT)
 113                                 & PLLFRACIN);
 114        }
 115
 116        writel(usbphyc_pll, usbphyc->base + STM32_USBPHYC_PLL);
 117
 118        pr_debug("%s: input clk freq=%dHz, ndiv=%d, frac=%d\n", __func__,
 119                 clk_rate, pll_params.ndiv, pll_params.frac);
 120
 121        return 0;
 122}
 123
 124static bool stm32_usbphyc_is_init(struct stm32_usbphyc *usbphyc)
 125{
 126        int i;
 127
 128        for (i = 0; i < MAX_PHYS; i++) {
 129                if (usbphyc->phys[i].init)
 130                        return true;
 131        }
 132
 133        return false;
 134}
 135
 136static bool stm32_usbphyc_is_powered(struct stm32_usbphyc *usbphyc)
 137{
 138        int i;
 139
 140        for (i = 0; i < MAX_PHYS; i++) {
 141                if (usbphyc->phys[i].powered)
 142                        return true;
 143        }
 144
 145        return false;
 146}
 147
 148static int stm32_usbphyc_phy_init(struct phy *phy)
 149{
 150        struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
 151        struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
 152        bool pllen = readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN ?
 153                     true : false;
 154        int ret;
 155
 156        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
 157        /* Check if one phy port has already configured the pll */
 158        if (pllen && stm32_usbphyc_is_init(usbphyc))
 159                goto initialized;
 160
 161        if (usbphyc->vdda1v1) {
 162                ret = regulator_set_enable(usbphyc->vdda1v1, true);
 163                if (ret)
 164                        return ret;
 165        }
 166
 167        if (usbphyc->vdda1v8) {
 168                ret = regulator_set_enable(usbphyc->vdda1v8, true);
 169                if (ret)
 170                        return ret;
 171        }
 172
 173        if (pllen) {
 174                clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
 175                udelay(PLL_PWR_DOWN_TIME_US);
 176        }
 177
 178        ret = stm32_usbphyc_pll_init(usbphyc);
 179        if (ret)
 180                return ret;
 181
 182        setbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
 183
 184        /* We must wait PLL_INIT_TIME_US before using PHY */
 185        udelay(PLL_INIT_TIME_US);
 186
 187        if (!(readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN))
 188                return -EIO;
 189
 190initialized:
 191        usbphyc_phy->init = true;
 192
 193        return 0;
 194}
 195
 196static int stm32_usbphyc_phy_exit(struct phy *phy)
 197{
 198        struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
 199        struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
 200        int ret;
 201
 202        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
 203        usbphyc_phy->init = false;
 204
 205        /* Check if other phy port requires pllen */
 206        if (stm32_usbphyc_is_init(usbphyc))
 207                return 0;
 208
 209        clrbits_le32(usbphyc->base + STM32_USBPHYC_PLL, PLLEN);
 210
 211        /*
 212         * We must wait PLL_PWR_DOWN_TIME_US before checking that PLLEN
 213         * bit is still clear
 214         */
 215        udelay(PLL_PWR_DOWN_TIME_US);
 216
 217        if (readl(usbphyc->base + STM32_USBPHYC_PLL) & PLLEN)
 218                return -EIO;
 219
 220        if (usbphyc->vdda1v1) {
 221                ret = regulator_set_enable(usbphyc->vdda1v1, false);
 222                if (ret)
 223                        return ret;
 224        }
 225
 226        if (usbphyc->vdda1v8) {
 227                ret = regulator_set_enable(usbphyc->vdda1v8, false);
 228                if (ret)
 229                        return ret;
 230        }
 231
 232        return 0;
 233}
 234
 235static int stm32_usbphyc_phy_power_on(struct phy *phy)
 236{
 237        struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
 238        struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
 239        int ret;
 240
 241        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
 242        if (usbphyc_phy->vdd) {
 243                ret = regulator_set_enable(usbphyc_phy->vdd, true);
 244                if (ret)
 245                        return ret;
 246        }
 247
 248        usbphyc_phy->powered = true;
 249
 250        return 0;
 251}
 252
 253static int stm32_usbphyc_phy_power_off(struct phy *phy)
 254{
 255        struct stm32_usbphyc *usbphyc = dev_get_priv(phy->dev);
 256        struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + phy->id;
 257        int ret;
 258
 259        pr_debug("%s phy ID = %lu\n", __func__, phy->id);
 260        usbphyc_phy->powered = false;
 261
 262        if (stm32_usbphyc_is_powered(usbphyc))
 263                return 0;
 264
 265        if (usbphyc_phy->vdd) {
 266                ret = regulator_set_enable(usbphyc_phy->vdd, false);
 267                if (ret)
 268                        return ret;
 269        }
 270
 271        return 0;
 272}
 273
 274static int stm32_usbphyc_get_regulator(struct udevice *dev, ofnode node,
 275                                       char *supply_name,
 276                                       struct udevice **regulator)
 277{
 278        struct ofnode_phandle_args regulator_phandle;
 279        int ret;
 280
 281        ret = ofnode_parse_phandle_with_args(node, supply_name,
 282                                             NULL, 0, 0,
 283                                             &regulator_phandle);
 284        if (ret) {
 285                dev_err(dev, "Can't find %s property (%d)\n", supply_name, ret);
 286                return ret;
 287        }
 288
 289        ret = uclass_get_device_by_ofnode(UCLASS_REGULATOR,
 290                                          regulator_phandle.node,
 291                                          regulator);
 292
 293        if (ret) {
 294                dev_err(dev, "Can't get %s regulator (%d)\n", supply_name, ret);
 295                return ret;
 296        }
 297
 298        return 0;
 299}
 300
 301static int stm32_usbphyc_of_xlate(struct phy *phy,
 302                                  struct ofnode_phandle_args *args)
 303{
 304        if (args->args_count < 1)
 305                return -ENODEV;
 306
 307        if (args->args[0] >= MAX_PHYS)
 308                return -ENODEV;
 309
 310        phy->id = args->args[0];
 311
 312        if ((phy->id == 0 && args->args_count != 1) ||
 313            (phy->id == 1 && args->args_count != 2)) {
 314                dev_err(dev, "invalid number of cells for phy port%ld\n",
 315                        phy->id);
 316                return -EINVAL;
 317        }
 318
 319        return 0;
 320}
 321
 322static const struct phy_ops stm32_usbphyc_phy_ops = {
 323        .init = stm32_usbphyc_phy_init,
 324        .exit = stm32_usbphyc_phy_exit,
 325        .power_on = stm32_usbphyc_phy_power_on,
 326        .power_off = stm32_usbphyc_phy_power_off,
 327        .of_xlate = stm32_usbphyc_of_xlate,
 328};
 329
 330static int stm32_usbphyc_probe(struct udevice *dev)
 331{
 332        struct stm32_usbphyc *usbphyc = dev_get_priv(dev);
 333        struct reset_ctl reset;
 334        ofnode node;
 335        int i, ret;
 336
 337        usbphyc->base = dev_read_addr(dev);
 338        if (usbphyc->base == FDT_ADDR_T_NONE)
 339                return -EINVAL;
 340
 341        /* Enable clock */
 342        ret = clk_get_by_index(dev, 0, &usbphyc->clk);
 343        if (ret)
 344                return ret;
 345
 346        ret = clk_enable(&usbphyc->clk);
 347        if (ret)
 348                return ret;
 349
 350        /* Reset */
 351        ret = reset_get_by_index(dev, 0, &reset);
 352        if (!ret) {
 353                reset_assert(&reset);
 354                udelay(2);
 355                reset_deassert(&reset);
 356        }
 357
 358        /* get usbphyc regulator */
 359        ret = device_get_supply_regulator(dev, "vdda1v1-supply",
 360                                          &usbphyc->vdda1v1);
 361        if (ret) {
 362                dev_err(dev, "Can't get vdda1v1-supply regulator\n");
 363                return ret;
 364        }
 365
 366        ret = device_get_supply_regulator(dev, "vdda1v8-supply",
 367                                          &usbphyc->vdda1v8);
 368        if (ret) {
 369                dev_err(dev, "Can't get vdda1v8-supply regulator\n");
 370                return ret;
 371        }
 372
 373        /*
 374         * parse all PHY subnodes in order to populate regulator associated
 375         * to each PHY port
 376         */
 377        node = dev_read_first_subnode(dev);
 378        for (i = 0; i < MAX_PHYS; i++) {
 379                struct stm32_usbphyc_phy *usbphyc_phy = usbphyc->phys + i;
 380
 381                usbphyc_phy->init = false;
 382                usbphyc_phy->powered = false;
 383                ret = stm32_usbphyc_get_regulator(dev, node, "phy-supply",
 384                                                  &usbphyc_phy->vdd);
 385                if (ret)
 386                        return ret;
 387
 388                node = dev_read_next_subnode(node);
 389        }
 390
 391        /* Check if second port has to be used for host controller */
 392        if (dev_read_bool(dev, "st,port2-switch-to-host"))
 393                setbits_le32(usbphyc->base + STM32_USBPHYC_MISC, SWITHOST);
 394
 395        return 0;
 396}
 397
 398static const struct udevice_id stm32_usbphyc_of_match[] = {
 399        { .compatible = "st,stm32mp1-usbphyc", },
 400        { },
 401};
 402
 403U_BOOT_DRIVER(stm32_usb_phyc) = {
 404        .name = "stm32-usbphyc",
 405        .id = UCLASS_PHY,
 406        .of_match = stm32_usbphyc_of_match,
 407        .ops = &stm32_usbphyc_phy_ops,
 408        .probe = stm32_usbphyc_probe,
 409        .priv_auto_alloc_size = sizeof(struct stm32_usbphyc),
 410};
 411