linux/drivers/net/mdio/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 int 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        return 0;
 141}
 142
 143static const struct clk_ops g12a_ephy_pll_ops = {
 144        .recalc_rate    = g12a_ephy_pll_recalc_rate,
 145        .is_enabled     = g12a_ephy_pll_is_enabled,
 146        .enable         = g12a_ephy_pll_enable,
 147        .disable        = g12a_ephy_pll_disable,
 148        .init           = g12a_ephy_pll_init,
 149};
 150
 151static int g12a_enable_internal_mdio(struct g12a_mdio_mux *priv)
 152{
 153        int ret;
 154
 155        /* Enable the phy clock */
 156        if (!priv->pll_is_enabled) {
 157                ret = clk_prepare_enable(priv->pll);
 158                if (ret)
 159                        return ret;
 160        }
 161
 162        priv->pll_is_enabled = true;
 163
 164        /* Initialize ephy control */
 165        writel(EPHY_G12A_ID, priv->regs + ETH_PHY_CNTL0);
 166        writel(FIELD_PREP(PHY_CNTL1_ST_MODE, 3) |
 167               FIELD_PREP(PHY_CNTL1_ST_PHYADD, EPHY_DFLT_ADD) |
 168               FIELD_PREP(PHY_CNTL1_MII_MODE, EPHY_MODE_RMII) |
 169               PHY_CNTL1_CLK_EN |
 170               PHY_CNTL1_CLKFREQ |
 171               PHY_CNTL1_PHY_ENB,
 172               priv->regs + ETH_PHY_CNTL1);
 173        writel(PHY_CNTL2_USE_INTERNAL |
 174               PHY_CNTL2_SMI_SRC_MAC |
 175               PHY_CNTL2_RX_CLK_EPHY,
 176               priv->regs + ETH_PHY_CNTL2);
 177
 178        return 0;
 179}
 180
 181static int g12a_enable_external_mdio(struct g12a_mdio_mux *priv)
 182{
 183        /* Reset the mdio bus mux */
 184        writel_relaxed(0x0, priv->regs + ETH_PHY_CNTL2);
 185
 186        /* Disable the phy clock if enabled */
 187        if (priv->pll_is_enabled) {
 188                clk_disable_unprepare(priv->pll);
 189                priv->pll_is_enabled = false;
 190        }
 191
 192        return 0;
 193}
 194
 195static int g12a_mdio_switch_fn(int current_child, int desired_child,
 196                               void *data)
 197{
 198        struct g12a_mdio_mux *priv = dev_get_drvdata(data);
 199
 200        if (current_child == desired_child)
 201                return 0;
 202
 203        switch (desired_child) {
 204        case MESON_G12A_MDIO_EXTERNAL_ID:
 205                return g12a_enable_external_mdio(priv);
 206        case MESON_G12A_MDIO_INTERNAL_ID:
 207                return g12a_enable_internal_mdio(priv);
 208        default:
 209                return -EINVAL;
 210        }
 211}
 212
 213static const struct of_device_id g12a_mdio_mux_match[] = {
 214        { .compatible = "amlogic,g12a-mdio-mux", },
 215        {},
 216};
 217MODULE_DEVICE_TABLE(of, g12a_mdio_mux_match);
 218
 219static int g12a_ephy_glue_clk_register(struct device *dev)
 220{
 221        struct g12a_mdio_mux *priv = dev_get_drvdata(dev);
 222        const char *parent_names[PLL_MUX_NUM_PARENT];
 223        struct clk_init_data init;
 224        struct g12a_ephy_pll *pll;
 225        struct clk_mux *mux;
 226        struct clk *clk;
 227        char *name;
 228        int i;
 229
 230        /* get the mux parents */
 231        for (i = 0; i < PLL_MUX_NUM_PARENT; i++) {
 232                char in_name[8];
 233
 234                snprintf(in_name, sizeof(in_name), "clkin%d", i);
 235                clk = devm_clk_get(dev, in_name);
 236                if (IS_ERR(clk)) {
 237                        if (PTR_ERR(clk) != -EPROBE_DEFER)
 238                                dev_err(dev, "Missing clock %s\n", in_name);
 239                        return PTR_ERR(clk);
 240                }
 241
 242                parent_names[i] = __clk_get_name(clk);
 243        }
 244
 245        /* create the input mux */
 246        mux = devm_kzalloc(dev, sizeof(*mux), GFP_KERNEL);
 247        if (!mux)
 248                return -ENOMEM;
 249
 250        name = kasprintf(GFP_KERNEL, "%s#mux", dev_name(dev));
 251        if (!name)
 252                return -ENOMEM;
 253
 254        init.name = name;
 255        init.ops = &clk_mux_ro_ops;
 256        init.flags = 0;
 257        init.parent_names = parent_names;
 258        init.num_parents = PLL_MUX_NUM_PARENT;
 259
 260        mux->reg = priv->regs + ETH_PLL_CTL0;
 261        mux->shift = __ffs(PLL_CTL0_SEL);
 262        mux->mask = PLL_CTL0_SEL >> mux->shift;
 263        mux->hw.init = &init;
 264
 265        clk = devm_clk_register(dev, &mux->hw);
 266        kfree(name);
 267        if (IS_ERR(clk)) {
 268                dev_err(dev, "failed to register input mux\n");
 269                return PTR_ERR(clk);
 270        }
 271
 272        /* create the pll */
 273        pll = devm_kzalloc(dev, sizeof(*pll), GFP_KERNEL);
 274        if (!pll)
 275                return -ENOMEM;
 276
 277        name = kasprintf(GFP_KERNEL, "%s#pll", dev_name(dev));
 278        if (!name)
 279                return -ENOMEM;
 280
 281        init.name = name;
 282        init.ops = &g12a_ephy_pll_ops;
 283        init.flags = 0;
 284        parent_names[0] = __clk_get_name(clk);
 285        init.parent_names = parent_names;
 286        init.num_parents = 1;
 287
 288        pll->base = priv->regs;
 289        pll->hw.init = &init;
 290
 291        clk = devm_clk_register(dev, &pll->hw);
 292        kfree(name);
 293        if (IS_ERR(clk)) {
 294                dev_err(dev, "failed to register input mux\n");
 295                return PTR_ERR(clk);
 296        }
 297
 298        priv->pll = clk;
 299
 300        return 0;
 301}
 302
 303static int g12a_mdio_mux_probe(struct platform_device *pdev)
 304{
 305        struct device *dev = &pdev->dev;
 306        struct g12a_mdio_mux *priv;
 307        int ret;
 308
 309        priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
 310        if (!priv)
 311                return -ENOMEM;
 312
 313        platform_set_drvdata(pdev, priv);
 314
 315        priv->regs = devm_platform_ioremap_resource(pdev, 0);
 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