linux/drivers/net/phy/mdio-mux-meson-g12a.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/* Copyright (c) 2019 Baylibre, SAS.
   3 * Author: Jerome Brunet <jbrunet@baylibre.com>
   4 */
   5
   6#include <linux/bitfield.h>
   7#include <linux/clk.h>
   8#include <linux/clk-provider.h>
   9#include <linux/device.h>
  10#include <linux/io.h>
  11#include <linux/iopoll.h>
  12#include <linux/mdio-mux.h>
  13#include <linux/module.h>
  14#include <linux/phy.h>
  15#include <linux/platform_device.h>
  16
  17#define ETH_PLL_STS             0x40
  18#define ETH_PLL_CTL0            0x44
  19#define  PLL_CTL0_LOCK_DIG      BIT(30)
  20#define  PLL_CTL0_RST           BIT(29)
  21#define  PLL_CTL0_EN            BIT(28)
  22#define  PLL_CTL0_SEL           BIT(23)
  23#define  PLL_CTL0_N             GENMASK(14, 10)
  24#define  PLL_CTL0_M             GENMASK(8, 0)
  25#define  PLL_LOCK_TIMEOUT       1000000
  26#define  PLL_MUX_NUM_PARENT     2
  27#define ETH_PLL_CTL1            0x48
  28#define ETH_PLL_CTL2            0x4c
  29#define ETH_PLL_CTL3            0x50
  30#define ETH_PLL_CTL4            0x54
  31#define ETH_PLL_CTL5            0x58
  32#define ETH_PLL_CTL6            0x5c
  33#define ETH_PLL_CTL7            0x60
  34
  35#define ETH_PHY_CNTL0           0x80
  36#define   EPHY_G12A_ID          0x33010180
  37#define ETH_PHY_CNTL1           0x84
  38#define  PHY_CNTL1_ST_MODE      GENMASK(2, 0)
  39#define  PHY_CNTL1_ST_PHYADD    GENMASK(7, 3)
  40#define   EPHY_DFLT_ADD         8
  41#define  PHY_CNTL1_MII_MODE     GENMASK(15, 14)
  42#define   EPHY_MODE_RMII        0x1
  43#define  PHY_CNTL1_CLK_EN       BIT(16)
  44#define  PHY_CNTL1_CLKFREQ      BIT(17)
  45#define  PHY_CNTL1_PHY_ENB      BIT(18)
  46#define ETH_PHY_CNTL2           0x88
  47#define  PHY_CNTL2_USE_INTERNAL BIT(5)
  48#define  PHY_CNTL2_SMI_SRC_MAC  BIT(6)
  49#define  PHY_CNTL2_RX_CLK_EPHY  BIT(9)
  50
  51#define MESON_G12A_MDIO_EXTERNAL_ID 0
  52#define MESON_G12A_MDIO_INTERNAL_ID 1
  53
  54struct g12a_mdio_mux {
  55        bool pll_is_enabled;
  56        void __iomem *regs;
  57        void *mux_handle;
  58        struct clk *pclk;
  59        struct clk *pll;
  60};
  61
  62struct g12a_ephy_pll {
  63        void __iomem *base;
  64        struct clk_hw hw;
  65};
  66
  67#define g12a_ephy_pll_to_dev(_hw)                       \
  68        container_of(_hw, struct g12a_ephy_pll, hw)
  69
  70static unsigned long g12a_ephy_pll_recalc_rate(struct clk_hw *hw,
  71                                               unsigned long parent_rate)
  72{
  73        struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
  74        u32 val, m, n;
  75
  76        val = readl(pll->base + ETH_PLL_CTL0);
  77        m = FIELD_GET(PLL_CTL0_M, val);
  78        n = FIELD_GET(PLL_CTL0_N, val);
  79
  80        return parent_rate * m / n;
  81}
  82
  83static int g12a_ephy_pll_enable(struct clk_hw *hw)
  84{
  85        struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
  86        u32 val = readl(pll->base + ETH_PLL_CTL0);
  87
  88        /* Apply both enable an reset */
  89        val |= PLL_CTL0_RST | PLL_CTL0_EN;
  90        writel(val, pll->base + ETH_PLL_CTL0);
  91
  92        /* Clear the reset to let PLL lock */
  93        val &= ~PLL_CTL0_RST;
  94        writel(val, pll->base + ETH_PLL_CTL0);
  95
  96        /* Poll on the digital lock instead of the usual analog lock
  97         * This is done because bit 31 is unreliable on some SoC. Bit
  98         * 31 may indicate that the PLL is not lock eventhough the clock
  99         * is actually running
 100         */
 101        return readl_poll_timeout(pll->base + ETH_PLL_CTL0, val,
 102                                  val & PLL_CTL0_LOCK_DIG, 0, PLL_LOCK_TIMEOUT);
 103}
 104
 105static void g12a_ephy_pll_disable(struct clk_hw *hw)
 106{
 107        struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
 108        u32 val;
 109
 110        val = readl(pll->base + ETH_PLL_CTL0);
 111        val &= ~PLL_CTL0_EN;
 112        val |= PLL_CTL0_RST;
 113        writel(val, pll->base + ETH_PLL_CTL0);
 114}
 115
 116static int g12a_ephy_pll_is_enabled(struct clk_hw *hw)
 117{
 118        struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
 119        unsigned int val;
 120
 121        val = readl(pll->base + ETH_PLL_CTL0);
 122
 123        return (val & PLL_CTL0_LOCK_DIG) ? 1 : 0;
 124}
 125
 126static void g12a_ephy_pll_init(struct clk_hw *hw)
 127{
 128        struct g12a_ephy_pll *pll = g12a_ephy_pll_to_dev(hw);
 129
 130        /* Apply PLL HW settings */
 131        writel(0x29c0040a, pll->base + ETH_PLL_CTL0);
 132        writel(0x927e0000, pll->base + ETH_PLL_CTL1);
 133        writel(0xac5f49e5, pll->base + ETH_PLL_CTL2);
 134        writel(0x00000000, pll->base + ETH_PLL_CTL3);
 135        writel(0x00000000, pll->base + ETH_PLL_CTL4);
 136        writel(0x20200000, pll->base + ETH_PLL_CTL5);
 137        writel(0x0000c002, pll->base + ETH_PLL_CTL6);
 138        writel(0x00000023, pll->base + ETH_PLL_CTL7);
 139}
 140
 141static const struct clk_ops g12a_ephy_pll_ops = {
 142        .recalc_rate    = g12a_ephy_pll_recalc_rate,
 143        .is_enabled     = g12a_ephy_pll_is_enabled,
 144        .enable         = g12a_ephy_pll_enable,
 145        .disable        = g12a_ephy_pll_disable,
 146        .init           = g12a_ephy_pll_init,
 147};
 148
 149static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
 150{
 151        int ret;
 152
 153        /* Enable the phy clock */
 154        if (!priv->pll_is_enabled) {
 155                ret = clk_prepare_enable(priv->pll);
 156                if (ret)
 157                        return ret;
 158        }
 159
 160        priv->pll_is_enabled = true;
 161
 162        /* Initialize ephy control */
 163        writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0);
 164        writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
 165               FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
 166               FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
 167               PHY_CNTL1_CLK_EN |
 168               PHY_CNTL1_CLKFREQ |
 169               PHY_CNTL1_PHY_ENB,
 170               priv->regs + ETH_PHY_CNTL1);
 171        writel(PHY_CNTL2_USE_INTERNAL |
 172               PHY_CNTL2_SMI_SRC_MAC |
 173               PHY_CNTL2_RX_CLK_EPHY,
 174               priv->regs + ETH_PHY_CNTL2);
 175
 176        return 0;
 177}
 178
 179static int g12a_enable_external_mdio(struct g12a_mdio_mux *priv)
 180{
 181        /* Reset the mdio bus mux */
 182        writel_relaxed(0x0, priv->regs + ETH_PHY_CNTL2);
 183
 184        /* Disable the phy clock if enabled */
 185        if (priv->pll_is_enabled) {
 186                clk_disable_unprepare(priv->pll);
 187                priv->pll_is_enabled = false;
 188        }
 189
 190        return 0;
 191}
 192
 193static int g12a_mdio_switch_fn(int current_child, int desired_child,
 194                               void *data)
 195{
 196        struct g12a_mdio_mux *priv = dev_get_drvdata(data);
 197
 198        if (current_child == desired_child)
 199                return 0;
 200
 201        switch (desired_child) {
 202        case MESON_G12A_MDIO_EXTERNAL_ID:
 203                return g12a_enable_external_mdio(priv);
 204        case MESON_G12A_MDIO_INTERNAL_ID:
 205                return g12a_enable_internal_mdio(priv);
 206        default:
 207                return -EINVAL;
 208        }
 209}
 210
 211static const struct of_device_id g12a_mdio_mux_match[] = {
 212        { .compatible = "amlogic,g12a-mdio-mux", },
 213        {},
 214};
 215MODULE_DEVICE_TABLE(of, g12a_mdio_mux_match);
 216
 217static int g12a_ephy_glue_clk_register(struct device *dev)
 218{
 219        struct g12a_mdio_mux *priv = dev_get_drvdata(dev);
 220        const char *parent_names[PLL_MUX_NUM_PARENT];
 221        struct clk_init_data init;
 222        struct g12a_ephy_pll *pll;
 223        struct clk_mux *mux;
 224        struct clk *clk;
 225        char *name;
 226        int i;
 227
 228        /* get the mux parents */
 229        for (i = 0; i < PLL_MUX_NUM_PARENT; i++) {
 230                char in_name[8];
 231
 232                snprintf(in_name, sizeof(in_name), "clkin%d", i);
 233                clk = devm_clk_get(dev, in_name);
 234                if (IS_ERR(clk)) {
 235                        if (PTR_ERR(clk) != -EPROBE_DEFER)
 236                                dev_err(dev, "Missing clock %s\n", in_name);
 237                        return PTR_ERR(clk);
 238                }
 239
 240                parent_names[i] = __clk_get_name(clk);
 241        }
 242
 243        /* create the input mux */
 244        mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
 245        if (!mux)
 246                return -ENOMEM;
 247
 248        name = kasprintf(GFP_KERNEL, "%s#mux", dev_name(dev));
 249        if (!name)
 250                return -ENOMEM;
 251
 252        init.name = name;
 253        init.ops = &clk_mux_ro_ops;
 254        init.flags = 0;
 255        init.parent_names = parent_names;
 256        init.num_parents = PLL_MUX_NUM_PARENT;
 257
 258        mux->reg = priv->regs + ETH_PLL_CTL0;
 259        mux->shift = __ffs(PLL_CTL0_SEL);
 260        mux->mask = PLL_CTL0_SEL >> mux->shift;
 261        mux->hw.init = &init;
 262
 263        clk = devm_clk_register(dev, &mux->hw);
 264        kfree(name);
 265        if (IS_ERR(clk)) {
 266                dev_err(dev, "failed to register input mux\n");
 267                return PTR_ERR(clk);
 268        }
 269
 270        /* create the pll */
 271        pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
 272        if (!pll)
 273                return -ENOMEM;
 274
 275        name = kasprintf(GFP_KERNEL, "%s#pll", dev_name(dev));
 276        if (!name)
 277                return -ENOMEM;
 278
 279        init.name = name;
 280        init.ops = &g12a_ephy_pll_ops;
 281        init.flags = 0;
 282        parent_names[0] = __clk_get_name(clk);
 283        init.parent_names = parent_names;
 284        init.num_parents = 1;
 285
 286        pll->base = priv->regs;
 287        pll->hw.init = &init;
 288
 289        clk = devm_clk_register(dev, &pll->hw);
 290        kfree(name);
 291        if (IS_ERR(clk)) {
 292                dev_err(dev, "failed to register input mux\n");
 293                return PTR_ERR(clk);
 294        }
 295
 296        priv->pll = clk;
 297
 298        return 0;
 299}
 300
 301static int g12a_mdio_mux_probe(struct platform_device *pdev)
 302{
 303        struct device *dev = &pdev->dev;
 304        struct g12a_mdio_mux *priv;
 305        struct resource *res;
 306        int ret;
 307
 308        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 309        if (!priv)
 310                return -ENOMEM;
 311
 312        platform_set_drvdata(pdev, priv);
 313
 314        res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 315        priv->regs = devm_ioremap_resource(dev, res);
 316        if (IS_ERR(priv->regs))
 317                return PTR_ERR(priv->regs);
 318
 319        priv->pclk = devm_clk_get(dev, "pclk");
 320        if (IS_ERR(priv->pclk)) {
 321                ret = PTR_ERR(priv->pclk);
 322                if (ret != -EPROBE_DEFER)
 323                        dev_err(dev, "failed to get peripheral clock\n");
 324                return ret;
 325        }
 326
 327        /* Make sure the device registers are clocked */
 328        ret = clk_prepare_enable(priv->pclk);
 329        if (ret) {
 330                dev_err(dev, "failed to enable peripheral clock");
 331                return ret;
 332        }
 333
 334        /* Register PLL in CCF */
 335        ret = g12a_ephy_glue_clk_register(dev);
 336        if (ret)
 337                goto err;
 338
 339        ret = mdio_mux_init(dev, dev->of_node, g12a_mdio_switch_fn,
 340                            &priv->mux_handle, dev, NULL);
 341        if (ret) {
 342                if (ret != -EPROBE_DEFER)
 343                        dev_err(dev, "mdio multiplexer init failed: %d", ret);
 344                goto err;
 345        }
 346
 347        return 0;
 348
 349err:
 350        clk_disable_unprepare(priv->pclk);
 351        return ret;
 352}
 353
 354static int g12a_mdio_mux_remove(struct platform_device *pdev)
 355{
 356        struct g12a_mdio_mux *priv = platform_get_drvdata(pdev);
 357
 358        mdio_mux_uninit(priv->mux_handle);
 359
 360        if (priv->pll_is_enabled)
 361                clk_disable_unprepare(priv->pll);
 362
 363        clk_disable_unprepare(priv->pclk);
 364
 365        return 0;
 366}
 367
 368static struct platform_driver g12a_mdio_mux_driver = {
 369        .probe          = g12a_mdio_mux_probe,
 370        .remove         = g12a_mdio_mux_remove,
 371        .driver         = {
 372                .name   = "g12a-mdio_mux",
 373                .of_match_table = g12a_mdio_mux_match,
 374        },
 375};
 376module_platform_driver(g12a_mdio_mux_driver);
 377
 378MODULE_DESCRIPTION("Amlogic G12a MDIO multiplexer driver");
 379MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
 380MODULE_LICENSE("GPL v2");
 381