uboot/drivers/pinctrl/mvebu/pinctrl-armada-38x.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-or-later
   2// (C) 2022 Pali Rohár <pali@kernel.org>
   3
   4#include <common.h>
   5#include <config.h>
   6#include <dm.h>
   7#include <dm/devres.h>
   8#include <dm/lists.h>
   9#include <dm/pinctrl.h>
  10#include <dm/root.h>
  11#include <errno.h>
  12#include <asm/io.h>
  13
  14struct mvebu_mpp_ctrl_setting {
  15        const char *name;
  16        const char *subname;
  17        u8 val;
  18        u8 variant;
  19};
  20
  21struct mvebu_mpp_mode {
  22        const char *name;
  23        size_t nsettings;
  24        struct mvebu_mpp_ctrl_setting *settings;
  25};
  26
  27#define MPP_MODE(_name, ...)                                    \
  28        {                                                       \
  29                .name = _name,                                  \
  30                .nsettings = ARRAY_SIZE((                       \
  31                        (struct mvebu_mpp_ctrl_setting[])       \
  32                         { __VA_ARGS__ })),                     \
  33                .settings = (struct mvebu_mpp_ctrl_setting[]){  \
  34                        __VA_ARGS__ },                          \
  35        }
  36
  37#define MPP_VAR_FUNCTION(_val, _name, _subname, _mask)          \
  38        {                                                       \
  39                .val = _val,                                    \
  40                .name = _name,                                  \
  41                .subname = _subname,                            \
  42                .variant = _mask,                               \
  43        }
  44
  45#define MVEBU_MPPS_PER_REG      8
  46#define MVEBU_MPP_BITS          4
  47#define MVEBU_MPP_MASK          0xf
  48
  49enum {
  50        V_88F6810 = BIT(0),
  51        V_88F6820 = BIT(1),
  52        V_88F6828 = BIT(2),
  53        V_88F6810_PLUS = (V_88F6810 | V_88F6820 | V_88F6828),
  54        V_88F6820_PLUS = (V_88F6820 | V_88F6828),
  55};
  56
  57static struct mvebu_mpp_mode armada_38x_mpp_modes[] = {
  58        MPP_MODE("mpp0",
  59                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  60                 MPP_VAR_FUNCTION(1, "ua0",   "rxd",        V_88F6810_PLUS)),
  61        MPP_MODE("mpp1",
  62                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  63                 MPP_VAR_FUNCTION(1, "ua0",   "txd",        V_88F6810_PLUS)),
  64        MPP_MODE("mpp2",
  65                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  66                 MPP_VAR_FUNCTION(1, "i2c0",  "sck",        V_88F6810_PLUS)),
  67        MPP_MODE("mpp3",
  68                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  69                 MPP_VAR_FUNCTION(1, "i2c0",  "sda",        V_88F6810_PLUS)),
  70        MPP_MODE("mpp4",
  71                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  72                 MPP_VAR_FUNCTION(1, "ge",    "mdc",        V_88F6810_PLUS),
  73                 MPP_VAR_FUNCTION(2, "ua1",   "txd",        V_88F6810_PLUS),
  74                 MPP_VAR_FUNCTION(3, "ua0",   "rts",        V_88F6810_PLUS)),
  75        MPP_MODE("mpp5",
  76                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  77                 MPP_VAR_FUNCTION(1, "ge",    "mdio",       V_88F6810_PLUS),
  78                 MPP_VAR_FUNCTION(2, "ua1",   "rxd",        V_88F6810_PLUS),
  79                 MPP_VAR_FUNCTION(3, "ua0",   "cts",        V_88F6810_PLUS)),
  80        MPP_MODE("mpp6",
  81                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  82                 MPP_VAR_FUNCTION(1, "ge0",   "txclkout",   V_88F6810_PLUS),
  83                 MPP_VAR_FUNCTION(2, "ge0",   "crs",        V_88F6810_PLUS),
  84                 MPP_VAR_FUNCTION(5, "dev",   "cs3",        V_88F6810_PLUS)),
  85        MPP_MODE("mpp7",
  86                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  87                 MPP_VAR_FUNCTION(1, "ge0",   "txd0",       V_88F6810_PLUS),
  88                 MPP_VAR_FUNCTION(5, "dev",   "ad9",        V_88F6810_PLUS)),
  89        MPP_MODE("mpp8",
  90                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  91                 MPP_VAR_FUNCTION(1, "ge0",   "txd1",       V_88F6810_PLUS),
  92                 MPP_VAR_FUNCTION(5, "dev",   "ad10",       V_88F6810_PLUS)),
  93        MPP_MODE("mpp9",
  94                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  95                 MPP_VAR_FUNCTION(1, "ge0",   "txd2",       V_88F6810_PLUS),
  96                 MPP_VAR_FUNCTION(5, "dev",   "ad11",       V_88F6810_PLUS)),
  97        MPP_MODE("mpp10",
  98                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
  99                 MPP_VAR_FUNCTION(1, "ge0",   "txd3",       V_88F6810_PLUS),
 100                 MPP_VAR_FUNCTION(5, "dev",   "ad12",       V_88F6810_PLUS)),
 101        MPP_MODE("mpp11",
 102                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 103                 MPP_VAR_FUNCTION(1, "ge0",   "txctl",      V_88F6810_PLUS),
 104                 MPP_VAR_FUNCTION(5, "dev",   "ad13",       V_88F6810_PLUS)),
 105        MPP_MODE("mpp12",
 106                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 107                 MPP_VAR_FUNCTION(1, "ge0",   "rxd0",       V_88F6810_PLUS),
 108                 MPP_VAR_FUNCTION(2, "pcie0", "rstout",     V_88F6810_PLUS),
 109                 MPP_VAR_FUNCTION(4, "spi0",  "cs1",        V_88F6810_PLUS),
 110                 MPP_VAR_FUNCTION(5, "dev",   "ad14",       V_88F6810_PLUS),
 111                 MPP_VAR_FUNCTION(6, "pcie3", "clkreq",     V_88F6810_PLUS)),
 112        MPP_MODE("mpp13",
 113                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 114                 MPP_VAR_FUNCTION(1, "ge0",   "rxd1",       V_88F6810_PLUS),
 115                 MPP_VAR_FUNCTION(2, "pcie0", "clkreq",     V_88F6810_PLUS),
 116                 MPP_VAR_FUNCTION(3, "pcie1", "clkreq",     V_88F6820_PLUS),
 117                 MPP_VAR_FUNCTION(4, "spi0",  "cs2",        V_88F6810_PLUS),
 118                 MPP_VAR_FUNCTION(5, "dev",   "ad15",       V_88F6810_PLUS),
 119                 MPP_VAR_FUNCTION(6, "pcie2", "clkreq",     V_88F6810_PLUS)),
 120        MPP_MODE("mpp14",
 121                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 122                 MPP_VAR_FUNCTION(1, "ge0",   "rxd2",       V_88F6810_PLUS),
 123                 MPP_VAR_FUNCTION(2, "ptp",   "clk",        V_88F6810_PLUS),
 124                 MPP_VAR_FUNCTION(3, "dram",  "vttctrl",    V_88F6810_PLUS),
 125                 MPP_VAR_FUNCTION(4, "spi0",  "cs3",        V_88F6810_PLUS),
 126                 MPP_VAR_FUNCTION(5, "dev",   "we1",        V_88F6810_PLUS),
 127                 MPP_VAR_FUNCTION(6, "pcie3", "clkreq",     V_88F6810_PLUS)),
 128        MPP_MODE("mpp15",
 129                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 130                 MPP_VAR_FUNCTION(1, "ge0",   "rxd3",       V_88F6810_PLUS),
 131                 MPP_VAR_FUNCTION(2, "ge",    "mdc slave",  V_88F6810_PLUS),
 132                 MPP_VAR_FUNCTION(3, "pcie0", "rstout",     V_88F6810_PLUS),
 133                 MPP_VAR_FUNCTION(4, "spi0",  "mosi",       V_88F6810_PLUS)),
 134        MPP_MODE("mpp16",
 135                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 136                 MPP_VAR_FUNCTION(1, "ge0",   "rxctl",      V_88F6810_PLUS),
 137                 MPP_VAR_FUNCTION(2, "ge",    "mdio slave", V_88F6810_PLUS),
 138                 MPP_VAR_FUNCTION(3, "dram",  "deccerr",    V_88F6810_PLUS),
 139                 MPP_VAR_FUNCTION(4, "spi0",  "miso",       V_88F6810_PLUS),
 140                 MPP_VAR_FUNCTION(5, "pcie0", "clkreq",     V_88F6810_PLUS),
 141                 MPP_VAR_FUNCTION(6, "pcie1", "clkreq",     V_88F6820_PLUS)),
 142        MPP_MODE("mpp17",
 143                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 144                 MPP_VAR_FUNCTION(1, "ge0",   "rxclk",      V_88F6810_PLUS),
 145                 MPP_VAR_FUNCTION(2, "ptp",   "clk",        V_88F6810_PLUS),
 146                 MPP_VAR_FUNCTION(3, "ua1",   "rxd",        V_88F6810_PLUS),
 147                 MPP_VAR_FUNCTION(4, "spi0",  "sck",        V_88F6810_PLUS),
 148                 MPP_VAR_FUNCTION(5, "sata1", "prsnt",      V_88F6810_PLUS),
 149                 MPP_VAR_FUNCTION(6, "sata0", "prsnt",      V_88F6810_PLUS)),
 150        MPP_MODE("mpp18",
 151                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 152                 MPP_VAR_FUNCTION(1, "ge0",   "rxerr",      V_88F6810_PLUS),
 153                 MPP_VAR_FUNCTION(2, "ptp",   "trig",       V_88F6810_PLUS),
 154                 MPP_VAR_FUNCTION(3, "ua1",   "txd",        V_88F6810_PLUS),
 155                 MPP_VAR_FUNCTION(4, "spi0",  "cs0",        V_88F6810_PLUS)),
 156        MPP_MODE("mpp19",
 157                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 158                 MPP_VAR_FUNCTION(1, "ge0",   "col",        V_88F6810_PLUS),
 159                 MPP_VAR_FUNCTION(2, "ptp",   "evreq",      V_88F6810_PLUS),
 160                 MPP_VAR_FUNCTION(3, "ge0",   "txerr",      V_88F6810_PLUS),
 161                 MPP_VAR_FUNCTION(4, "sata1", "prsnt",      V_88F6810_PLUS),
 162                 MPP_VAR_FUNCTION(5, "ua0",   "cts",        V_88F6810_PLUS),
 163                 MPP_VAR_FUNCTION(6, "ua1",   "rxd",        V_88F6810_PLUS)),
 164        MPP_MODE("mpp20",
 165                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 166                 MPP_VAR_FUNCTION(1, "ge0",   "txclk",      V_88F6810_PLUS),
 167                 MPP_VAR_FUNCTION(2, "ptp",   "clk",        V_88F6810_PLUS),
 168                 MPP_VAR_FUNCTION(4, "sata0", "prsnt",      V_88F6810_PLUS),
 169                 MPP_VAR_FUNCTION(5, "ua0",   "rts",        V_88F6810_PLUS),
 170                 MPP_VAR_FUNCTION(6, "ua1",   "txd",        V_88F6810_PLUS)),
 171        MPP_MODE("mpp21",
 172                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 173                 MPP_VAR_FUNCTION(1, "spi0",  "cs1",        V_88F6810_PLUS),
 174                 MPP_VAR_FUNCTION(2, "ge1",   "rxd0",       V_88F6810_PLUS),
 175                 MPP_VAR_FUNCTION(3, "sata0", "prsnt",      V_88F6810_PLUS),
 176                 MPP_VAR_FUNCTION(4, "sd0",   "cmd",        V_88F6810_PLUS),
 177                 MPP_VAR_FUNCTION(5, "dev",   "bootcs",     V_88F6810_PLUS),
 178                 MPP_VAR_FUNCTION(6, "sata1", "prsnt",      V_88F6810_PLUS)),
 179        MPP_MODE("mpp22",
 180                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 181                 MPP_VAR_FUNCTION(1, "spi0",  "mosi",       V_88F6810_PLUS),
 182                 MPP_VAR_FUNCTION(5, "dev",   "ad0",        V_88F6810_PLUS)),
 183        MPP_MODE("mpp23",
 184                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 185                 MPP_VAR_FUNCTION(1, "spi0",  "sck",        V_88F6810_PLUS),
 186                 MPP_VAR_FUNCTION(5, "dev",   "ad2",        V_88F6810_PLUS)),
 187        MPP_MODE("mpp24",
 188                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 189                 MPP_VAR_FUNCTION(1, "spi0",  "miso",       V_88F6810_PLUS),
 190                 MPP_VAR_FUNCTION(2, "ua0",   "cts",        V_88F6810_PLUS),
 191                 MPP_VAR_FUNCTION(3, "ua1",   "rxd",        V_88F6810_PLUS),
 192                 MPP_VAR_FUNCTION(4, "sd0",   "d4",         V_88F6810_PLUS),
 193                 MPP_VAR_FUNCTION(5, "dev",   "ready",      V_88F6810_PLUS)),
 194        MPP_MODE("mpp25",
 195                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 196                 MPP_VAR_FUNCTION(1, "spi0",  "cs0",        V_88F6810_PLUS),
 197                 MPP_VAR_FUNCTION(2, "ua0",   "rts",        V_88F6810_PLUS),
 198                 MPP_VAR_FUNCTION(3, "ua1",   "txd",        V_88F6810_PLUS),
 199                 MPP_VAR_FUNCTION(4, "sd0",   "d5",         V_88F6810_PLUS),
 200                 MPP_VAR_FUNCTION(5, "dev",   "cs0",        V_88F6810_PLUS)),
 201        MPP_MODE("mpp26",
 202                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 203                 MPP_VAR_FUNCTION(1, "spi0",  "cs2",        V_88F6810_PLUS),
 204                 MPP_VAR_FUNCTION(3, "i2c1",  "sck",        V_88F6810_PLUS),
 205                 MPP_VAR_FUNCTION(4, "sd0",   "d6",         V_88F6810_PLUS),
 206                 MPP_VAR_FUNCTION(5, "dev",   "cs1",        V_88F6810_PLUS)),
 207        MPP_MODE("mpp27",
 208                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 209                 MPP_VAR_FUNCTION(1, "spi0",  "cs3",        V_88F6810_PLUS),
 210                 MPP_VAR_FUNCTION(2, "ge1",   "txclkout",   V_88F6810_PLUS),
 211                 MPP_VAR_FUNCTION(3, "i2c1",  "sda",        V_88F6810_PLUS),
 212                 MPP_VAR_FUNCTION(4, "sd0",   "d7",         V_88F6810_PLUS),
 213                 MPP_VAR_FUNCTION(5, "dev",   "cs2",        V_88F6810_PLUS)),
 214        MPP_MODE("mpp28",
 215                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 216                 MPP_VAR_FUNCTION(2, "ge1",   "txd0",       V_88F6810_PLUS),
 217                 MPP_VAR_FUNCTION(4, "sd0",   "clk",        V_88F6810_PLUS),
 218                 MPP_VAR_FUNCTION(5, "dev",   "ad5",        V_88F6810_PLUS)),
 219        MPP_MODE("mpp29",
 220                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 221                 MPP_VAR_FUNCTION(2, "ge1",   "txd1",       V_88F6810_PLUS),
 222                 MPP_VAR_FUNCTION(5, "dev",   "ale0",       V_88F6810_PLUS)),
 223        MPP_MODE("mpp30",
 224                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 225                 MPP_VAR_FUNCTION(2, "ge1",   "txd2",       V_88F6810_PLUS),
 226                 MPP_VAR_FUNCTION(5, "dev",   "oe",         V_88F6810_PLUS)),
 227        MPP_MODE("mpp31",
 228                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 229                 MPP_VAR_FUNCTION(2, "ge1",   "txd3",       V_88F6810_PLUS),
 230                 MPP_VAR_FUNCTION(5, "dev",   "ale1",       V_88F6810_PLUS)),
 231        MPP_MODE("mpp32",
 232                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 233                 MPP_VAR_FUNCTION(2, "ge1",   "txctl",      V_88F6810_PLUS),
 234                 MPP_VAR_FUNCTION(5, "dev",   "we0",        V_88F6810_PLUS)),
 235        MPP_MODE("mpp33",
 236                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 237                 MPP_VAR_FUNCTION(1, "dram",  "deccerr",    V_88F6810_PLUS),
 238                 MPP_VAR_FUNCTION(5, "dev",   "ad3",        V_88F6810_PLUS)),
 239        MPP_MODE("mpp34",
 240                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 241                 MPP_VAR_FUNCTION(5, "dev",   "ad1",        V_88F6810_PLUS)),
 242        MPP_MODE("mpp35",
 243                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 244                 MPP_VAR_FUNCTION(1, "ref",   "clk_out1",   V_88F6810_PLUS),
 245                 MPP_VAR_FUNCTION(5, "dev",   "a1",         V_88F6810_PLUS)),
 246        MPP_MODE("mpp36",
 247                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 248                 MPP_VAR_FUNCTION(1, "ptp",   "trig",       V_88F6810_PLUS),
 249                 MPP_VAR_FUNCTION(5, "dev",   "a0",         V_88F6810_PLUS)),
 250        MPP_MODE("mpp37",
 251                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 252                 MPP_VAR_FUNCTION(1, "ptp",   "clk",        V_88F6810_PLUS),
 253                 MPP_VAR_FUNCTION(2, "ge1",   "rxclk",      V_88F6810_PLUS),
 254                 MPP_VAR_FUNCTION(4, "sd0",   "d3",         V_88F6810_PLUS),
 255                 MPP_VAR_FUNCTION(5, "dev",   "ad8",        V_88F6810_PLUS)),
 256        MPP_MODE("mpp38",
 257                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 258                 MPP_VAR_FUNCTION(1, "ptp",   "evreq",      V_88F6810_PLUS),
 259                 MPP_VAR_FUNCTION(2, "ge1",   "rxd1",       V_88F6810_PLUS),
 260                 MPP_VAR_FUNCTION(3, "ref",   "clk_out0",   V_88F6810_PLUS),
 261                 MPP_VAR_FUNCTION(4, "sd0",   "d0",         V_88F6810_PLUS),
 262                 MPP_VAR_FUNCTION(5, "dev",   "ad4",        V_88F6810_PLUS)),
 263        MPP_MODE("mpp39",
 264                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 265                 MPP_VAR_FUNCTION(1, "i2c1",  "sck",        V_88F6810_PLUS),
 266                 MPP_VAR_FUNCTION(2, "ge1",   "rxd2",       V_88F6810_PLUS),
 267                 MPP_VAR_FUNCTION(3, "ua0",   "cts",        V_88F6810_PLUS),
 268                 MPP_VAR_FUNCTION(4, "sd0",   "d1",         V_88F6810_PLUS),
 269                 MPP_VAR_FUNCTION(5, "dev",   "a2",         V_88F6810_PLUS)),
 270        MPP_MODE("mpp40",
 271                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 272                 MPP_VAR_FUNCTION(1, "i2c1",  "sda",        V_88F6810_PLUS),
 273                 MPP_VAR_FUNCTION(2, "ge1",   "rxd3",       V_88F6810_PLUS),
 274                 MPP_VAR_FUNCTION(3, "ua0",   "rts",        V_88F6810_PLUS),
 275                 MPP_VAR_FUNCTION(4, "sd0",   "d2",         V_88F6810_PLUS),
 276                 MPP_VAR_FUNCTION(5, "dev",   "ad6",        V_88F6810_PLUS)),
 277        MPP_MODE("mpp41",
 278                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 279                 MPP_VAR_FUNCTION(1, "ua1",   "rxd",        V_88F6810_PLUS),
 280                 MPP_VAR_FUNCTION(2, "ge1",   "rxctl",      V_88F6810_PLUS),
 281                 MPP_VAR_FUNCTION(3, "ua0",   "cts",        V_88F6810_PLUS),
 282                 MPP_VAR_FUNCTION(4, "spi1",  "cs3",        V_88F6810_PLUS),
 283                 MPP_VAR_FUNCTION(5, "dev",   "burst/last", V_88F6810_PLUS),
 284                 MPP_VAR_FUNCTION(6, "nand",  "rb0",        V_88F6810_PLUS)),
 285        MPP_MODE("mpp42",
 286                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 287                 MPP_VAR_FUNCTION(1, "ua1",   "txd",        V_88F6810_PLUS),
 288                 MPP_VAR_FUNCTION(3, "ua0",   "rts",        V_88F6810_PLUS),
 289                 MPP_VAR_FUNCTION(5, "dev",   "ad7",        V_88F6810_PLUS)),
 290        MPP_MODE("mpp43",
 291                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 292                 MPP_VAR_FUNCTION(1, "pcie0", "clkreq",     V_88F6810_PLUS),
 293                 MPP_VAR_FUNCTION(2, "dram",  "vttctrl",    V_88F6810_PLUS),
 294                 MPP_VAR_FUNCTION(3, "dram",  "deccerr",    V_88F6810_PLUS),
 295                 MPP_VAR_FUNCTION(4, "spi1",  "cs2",        V_88F6810_PLUS),
 296                 MPP_VAR_FUNCTION(5, "dev",   "clkout",     V_88F6810_PLUS),
 297                 MPP_VAR_FUNCTION(6, "nand",  "rb1",        V_88F6810_PLUS)),
 298        MPP_MODE("mpp44",
 299                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 300                 MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
 301                 MPP_VAR_FUNCTION(2, "sata1", "prsnt",      V_88F6810_PLUS),
 302                 MPP_VAR_FUNCTION(3, "sata2", "prsnt",      V_88F6828),
 303                 MPP_VAR_FUNCTION(4, "sata3", "prsnt",      V_88F6828)),
 304        MPP_MODE("mpp45",
 305                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 306                 MPP_VAR_FUNCTION(1, "ref",   "clk_out0",   V_88F6810_PLUS),
 307                 MPP_VAR_FUNCTION(2, "pcie0", "rstout",     V_88F6810_PLUS),
 308                 MPP_VAR_FUNCTION(6, "ua1",   "rxd",        V_88F6810_PLUS)),
 309        MPP_MODE("mpp46",
 310                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 311                 MPP_VAR_FUNCTION(1, "ref",   "clk_out1",   V_88F6810_PLUS),
 312                 MPP_VAR_FUNCTION(2, "pcie0", "rstout",     V_88F6810_PLUS),
 313                 MPP_VAR_FUNCTION(6, "ua1",   "txd",        V_88F6810_PLUS)),
 314        MPP_MODE("mpp47",
 315                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 316                 MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
 317                 MPP_VAR_FUNCTION(2, "sata1", "prsnt",      V_88F6810_PLUS),
 318                 MPP_VAR_FUNCTION(3, "sata2", "prsnt",      V_88F6828),
 319                 MPP_VAR_FUNCTION(5, "sata3", "prsnt",      V_88F6828)),
 320        MPP_MODE("mpp48",
 321                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 322                 MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
 323                 MPP_VAR_FUNCTION(2, "dram",  "vttctrl",    V_88F6810_PLUS),
 324                 MPP_VAR_FUNCTION(3, "tdm",   "pclk",       V_88F6810_PLUS),
 325                 MPP_VAR_FUNCTION(4, "audio", "mclk",       V_88F6810_PLUS),
 326                 MPP_VAR_FUNCTION(5, "sd0",   "d4",         V_88F6810_PLUS),
 327                 MPP_VAR_FUNCTION(6, "pcie0", "clkreq",     V_88F6810_PLUS)),
 328        MPP_MODE("mpp49",
 329                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 330                 MPP_VAR_FUNCTION(1, "sata2", "prsnt",      V_88F6828),
 331                 MPP_VAR_FUNCTION(2, "sata3", "prsnt",      V_88F6828),
 332                 MPP_VAR_FUNCTION(3, "tdm",   "fsync",      V_88F6810_PLUS),
 333                 MPP_VAR_FUNCTION(4, "audio", "lrclk",      V_88F6810_PLUS),
 334                 MPP_VAR_FUNCTION(5, "sd0",   "d5",         V_88F6810_PLUS),
 335                 MPP_VAR_FUNCTION(6, "pcie1", "clkreq",     V_88F6820_PLUS)),
 336        MPP_MODE("mpp50",
 337                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 338                 MPP_VAR_FUNCTION(1, "pcie0", "rstout",     V_88F6810_PLUS),
 339                 MPP_VAR_FUNCTION(3, "tdm",   "drx",        V_88F6810_PLUS),
 340                 MPP_VAR_FUNCTION(4, "audio", "extclk",     V_88F6810_PLUS),
 341                 MPP_VAR_FUNCTION(5, "sd0",   "cmd",        V_88F6810_PLUS)),
 342        MPP_MODE("mpp51",
 343                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 344                 MPP_VAR_FUNCTION(3, "tdm",   "dtx",        V_88F6810_PLUS),
 345                 MPP_VAR_FUNCTION(4, "audio", "sdo",        V_88F6810_PLUS),
 346                 MPP_VAR_FUNCTION(5, "dram",  "deccerr",    V_88F6810_PLUS),
 347                 MPP_VAR_FUNCTION(6, "ptp",   "trig",       V_88F6810_PLUS)),
 348        MPP_MODE("mpp52",
 349                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 350                 MPP_VAR_FUNCTION(1, "pcie0", "rstout",     V_88F6810_PLUS),
 351                 MPP_VAR_FUNCTION(3, "tdm",   "int",        V_88F6810_PLUS),
 352                 MPP_VAR_FUNCTION(4, "audio", "sdi",        V_88F6810_PLUS),
 353                 MPP_VAR_FUNCTION(5, "sd0",   "d6",         V_88F6810_PLUS),
 354                 MPP_VAR_FUNCTION(6, "ptp",   "clk",        V_88F6810_PLUS)),
 355        MPP_MODE("mpp53",
 356                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 357                 MPP_VAR_FUNCTION(1, "sata1", "prsnt",      V_88F6810_PLUS),
 358                 MPP_VAR_FUNCTION(2, "sata0", "prsnt",      V_88F6810_PLUS),
 359                 MPP_VAR_FUNCTION(3, "tdm",   "rst",        V_88F6810_PLUS),
 360                 MPP_VAR_FUNCTION(4, "audio", "bclk",       V_88F6810_PLUS),
 361                 MPP_VAR_FUNCTION(5, "sd0",   "d7",         V_88F6810_PLUS),
 362                 MPP_VAR_FUNCTION(6, "ptp",   "evreq",      V_88F6810_PLUS)),
 363        MPP_MODE("mpp54",
 364                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 365                 MPP_VAR_FUNCTION(1, "sata0", "prsnt",      V_88F6810_PLUS),
 366                 MPP_VAR_FUNCTION(2, "sata1", "prsnt",      V_88F6810_PLUS),
 367                 MPP_VAR_FUNCTION(3, "pcie0", "rstout",     V_88F6810_PLUS),
 368                 MPP_VAR_FUNCTION(4, "ge0",   "txerr",      V_88F6810_PLUS),
 369                 MPP_VAR_FUNCTION(5, "sd0",   "d3",         V_88F6810_PLUS)),
 370        MPP_MODE("mpp55",
 371                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 372                 MPP_VAR_FUNCTION(1, "ua1",   "cts",        V_88F6810_PLUS),
 373                 MPP_VAR_FUNCTION(2, "ge",    "mdio",       V_88F6810_PLUS),
 374                 MPP_VAR_FUNCTION(3, "pcie1", "clkreq",     V_88F6820_PLUS),
 375                 MPP_VAR_FUNCTION(4, "spi1",  "cs1",        V_88F6810_PLUS),
 376                 MPP_VAR_FUNCTION(5, "sd0",   "d0",         V_88F6810_PLUS),
 377                 MPP_VAR_FUNCTION(6, "ua1",   "rxd",        V_88F6810_PLUS)),
 378        MPP_MODE("mpp56",
 379                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 380                 MPP_VAR_FUNCTION(1, "ua1",   "rts",        V_88F6810_PLUS),
 381                 MPP_VAR_FUNCTION(2, "ge",    "mdc",        V_88F6810_PLUS),
 382                 MPP_VAR_FUNCTION(3, "dram",  "deccerr",    V_88F6810_PLUS),
 383                 MPP_VAR_FUNCTION(4, "spi1",  "mosi",       V_88F6810_PLUS),
 384                 MPP_VAR_FUNCTION(6, "ua1",   "txd",        V_88F6810_PLUS)),
 385        MPP_MODE("mpp57",
 386                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 387                 MPP_VAR_FUNCTION(4, "spi1",  "sck",        V_88F6810_PLUS),
 388                 MPP_VAR_FUNCTION(5, "sd0",   "clk",        V_88F6810_PLUS),
 389                 MPP_VAR_FUNCTION(6, "ua1",   "txd",        V_88F6810_PLUS)),
 390        MPP_MODE("mpp58",
 391                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 392                 MPP_VAR_FUNCTION(1, "pcie1", "clkreq",     V_88F6820_PLUS),
 393                 MPP_VAR_FUNCTION(2, "i2c1",  "sck",        V_88F6810_PLUS),
 394                 MPP_VAR_FUNCTION(3, "pcie2", "clkreq",     V_88F6810_PLUS),
 395                 MPP_VAR_FUNCTION(4, "spi1",  "miso",       V_88F6810_PLUS),
 396                 MPP_VAR_FUNCTION(5, "sd0",   "d1",         V_88F6810_PLUS),
 397                 MPP_VAR_FUNCTION(6, "ua1",   "rxd",        V_88F6810_PLUS)),
 398        MPP_MODE("mpp59",
 399                 MPP_VAR_FUNCTION(0, "gpio",  NULL,         V_88F6810_PLUS),
 400                 MPP_VAR_FUNCTION(1, "pcie0", "rstout",     V_88F6810_PLUS),
 401                 MPP_VAR_FUNCTION(2, "i2c1",  "sda",        V_88F6810_PLUS),
 402                 MPP_VAR_FUNCTION(4, "spi1",  "cs0",        V_88F6810_PLUS),
 403                 MPP_VAR_FUNCTION(5, "sd0",   "d2",         V_88F6810_PLUS)),
 404};
 405
 406static const char * const armada_38x_mpp_function_names[] = {
 407        "gpio", /* make gpio always as function 0 */
 408
 409        "audio",
 410        "dev",
 411        "dram",
 412        "ge",
 413        "ge0",
 414        "ge1",
 415        "i2c0",
 416        "i2c1",
 417        "nand",
 418        "pcie0",
 419        "pcie1",
 420        "pcie2",
 421        "pcie3",
 422        "ptp",
 423        "ref",
 424        "sata0",
 425        "sata1",
 426        "sata2",
 427        "sata3",
 428        "sd0",
 429        "spi0",
 430        "spi1",
 431        "tdm",
 432        "ua0",
 433        "ua1",
 434};
 435
 436struct armada_38x_pinctrl {
 437        void __iomem *base;
 438        u8 variant;
 439};
 440
 441static int armada_38x_pinctrl_get_pins_count(struct udevice *dev)
 442{
 443        return ARRAY_SIZE(armada_38x_mpp_modes);
 444}
 445
 446static const char *armada_38x_pinctrl_get_pin_name(struct udevice *dev, unsigned int selector)
 447{
 448        return armada_38x_mpp_modes[selector].name;
 449}
 450
 451static int armada_38x_pinctrl_get_functions_count(struct udevice *dev)
 452{
 453        return ARRAY_SIZE(armada_38x_mpp_function_names);
 454}
 455
 456static const char *armada_38x_pinctrl_get_function_name(struct udevice *dev, unsigned int selector)
 457{
 458        return armada_38x_mpp_function_names[selector];
 459}
 460
 461static int armada_38x_pinctrl_get_pin_muxing(struct udevice *dev, unsigned int selector,
 462                                             char *buf, int size)
 463{
 464        struct armada_38x_pinctrl *info = dev_get_priv(dev);
 465        unsigned int off = (selector / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
 466        unsigned int shift = (selector % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
 467        const char *func_name = NULL;
 468        const char *sub_name = NULL;
 469        unsigned long config;
 470        int i;
 471
 472        config = (readl(info->base + off) >> shift) & MVEBU_MPP_MASK;
 473
 474        for (i = 0; i < armada_38x_mpp_modes[selector].nsettings; i++) {
 475                if (armada_38x_mpp_modes[selector].settings[i].val == config)
 476                        break;
 477        }
 478
 479        if (i < armada_38x_mpp_modes[selector].nsettings) {
 480                func_name = armada_38x_mpp_modes[selector].settings[i].name;
 481                sub_name = armada_38x_mpp_modes[selector].settings[i].subname;
 482        }
 483
 484        snprintf(buf, size, "%s%s%s",
 485                 func_name ? func_name : "unknown",
 486                 sub_name ? "_" : "",
 487                 sub_name ? sub_name : "");
 488        return 0;
 489}
 490
 491static int armada_38x_pinctrl_pinmux_set(struct udevice *dev, unsigned int pin_selector,
 492                                         unsigned int func_selector)
 493{
 494        struct armada_38x_pinctrl *info = dev_get_priv(dev);
 495        unsigned int off = (pin_selector / MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
 496        unsigned int shift = (pin_selector % MVEBU_MPPS_PER_REG) * MVEBU_MPP_BITS;
 497        const char *func_name = armada_38x_mpp_function_names[func_selector];
 498        unsigned long config, reg;
 499        int i;
 500
 501        for (i = 0; i < armada_38x_mpp_modes[pin_selector].nsettings; i++) {
 502                if (strcmp(armada_38x_mpp_modes[pin_selector].settings[i].name, func_name) == 0)
 503                        break;
 504        }
 505
 506        if (i >= armada_38x_mpp_modes[pin_selector].nsettings)
 507                return -EINVAL;
 508
 509        if (!(info->variant & armada_38x_mpp_modes[pin_selector].settings[i].variant))
 510                return -EINVAL;
 511
 512        reg = readl(info->base + off) & ~(MVEBU_MPP_MASK << shift);
 513        config = armada_38x_mpp_modes[pin_selector].settings[i].val;
 514        writel(reg | (config << shift), info->base + off);
 515
 516        return 0;
 517}
 518
 519static int armada_38x_pinctrl_gpio_request_enable(struct udevice *dev, unsigned int selector)
 520{
 521        char buf[20];
 522
 523        armada_38x_pinctrl_get_pin_muxing(dev, selector, buf, sizeof(buf));
 524        if (strcmp(buf, "gpio") != 0)
 525                printf("Warning: Changing mpp%u function from %s to gpio...\n", selector, buf);
 526
 527        return armada_38x_pinctrl_pinmux_set(dev, selector, 0); /* gpio is always function 0 */
 528}
 529
 530static int armada_38x_pinctrl_gpio_disable_free(struct udevice *dev, unsigned int selector)
 531{
 532        /* nothing to do */
 533        return 0;
 534}
 535
 536static int armada_38x_pinctrl_set_state(struct udevice *dev, struct udevice *config)
 537{
 538        return pinctrl_generic_set_state_prefix(dev, config, "marvell,");
 539}
 540
 541static int armada_38x_pinctrl_probe(struct udevice *dev)
 542{
 543        struct armada_38x_pinctrl *info = dev_get_priv(dev);
 544
 545        info->variant = (u8)dev_get_driver_data(dev);
 546        info->base = dev_read_addr_ptr(dev);
 547
 548        if (!info->base)
 549                return -EINVAL;
 550
 551        return 0;
 552}
 553
 554struct pinctrl_ops armada_37xx_pinctrl_ops = {
 555        .get_pins_count = armada_38x_pinctrl_get_pins_count,
 556        .get_pin_name = armada_38x_pinctrl_get_pin_name,
 557        .get_functions_count = armada_38x_pinctrl_get_functions_count,
 558        .get_function_name = armada_38x_pinctrl_get_function_name,
 559        .get_pin_muxing = armada_38x_pinctrl_get_pin_muxing,
 560        .pinmux_set = armada_38x_pinctrl_pinmux_set,
 561        .gpio_request_enable = armada_38x_pinctrl_gpio_request_enable,
 562        .gpio_disable_free = armada_38x_pinctrl_gpio_disable_free,
 563        .set_state = armada_38x_pinctrl_set_state,
 564};
 565
 566static const struct udevice_id armada_38x_pinctrl_of_match[] = {
 567        {
 568                .compatible = "marvell,mv88f6810-pinctrl",
 569                .data       = V_88F6810,
 570        },
 571        {
 572                .compatible = "marvell,mv88f6820-pinctrl",
 573                .data       = V_88F6820,
 574        },
 575        {
 576                .compatible = "marvell,mv88f6828-pinctrl",
 577                .data       = V_88F6828,
 578        },
 579        { },
 580};
 581
 582U_BOOT_DRIVER(armada_38x_pinctrl) = {
 583        .name = "armada-38x-pinctrl",
 584        .id = UCLASS_PINCTRL,
 585        .of_match = of_match_ptr(armada_38x_pinctrl_of_match),
 586        .probe = armada_38x_pinctrl_probe,
 587        .priv_auto = sizeof(struct armada_38x_pinctrl),
 588        .ops = &armada_37xx_pinctrl_ops,
 589};
 590