root/sys/arch/arm/rockchip/rk3588_iomux.c
/*      $NetBSD: rk3588_iomux.c,v 1.2 2024/02/07 04:20:27 msaitoh Exp $ */

/*-
 * Copyright (c) 2022 Ryo Shimizu
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions
 * are met:
 * 1. Redistributions of source code must retain the above copyright
 *    notice, this list of conditions and the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright
 *    notice, this list of conditions and the following disclaimer in the
 *    documentation and/or other materials provided with the distribution.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS
 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT,
 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
 * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <sys/cdefs.h>
__KERNEL_RCSID(0, "$NetBSD: rk3588_iomux.c,v 1.2 2024/02/07 04:20:27 msaitoh Exp $");

#include <sys/param.h>
#include <sys/device.h>

#include <dev/fdt/fdtvar.h>
#include <dev/fdt/syscon.h>

/* #define RK3588_IOMUX_DEBUG */

struct rk3588_iomux_softc {
        device_t sc_dev;
        struct syscon *sc_grf;
};

static int rk3588_iomux_match(device_t, cfdata_t, void *);
static void rk3588_iomux_attach(device_t, device_t, void *);

CFATTACH_DECL_NEW(rk3588_iomux, sizeof(struct rk3588_iomux_softc),
    rk3588_iomux_match, rk3588_iomux_attach, NULL, NULL);

static const struct device_compatible_entry compat_data[] = {
        { .compat = "rockchip,rk3588-pinctrl" },
        DEVICE_COMPAT_EOL
};

/* GRF offsets */
#define RK3588_PMU1_IOC_REG             0x00000000
#define RK3588_PMU2_IOC_REG             0x00004000
#define RK3588_BUS_IOC_REG              0x00008000
#define RK3588_VCCIO1_4_IOC_REG         0x00009000
#define RK3588_VCCIO3_5_IOC_REG         0x0000a000
#define RK3588_VCCIO2_IOC_REG           0x0000b000
#define RK3588_VCCIO6_IOC_REG           0x0000c000
#define RK3588_EMMC_IOC_REG             0x0000d000

#define NBANKS                          5
#define NPINPERBANK                     32
#define NPINS                           (NBANKS * NPINPERBANK)

#define PIN(bank, idx)                  (((bank) * NPINPERBANK) + (idx))

struct regmask {
        bus_size_t reg;
        uint32_t mask;
};

struct regmaskreg {
        bus_size_t reg;
        uint32_t mask;
        bus_size_t reg0;
};

static const struct regmask rk3588_drive_regmap[NBANKS * NPINPERBANK] = {
        /* GPIO0_A[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0010,         __BITS(3,0)     },
        { RK3588_PMU1_IOC_REG + 0x0010,         __BITS(7,4)     },
        { RK3588_PMU1_IOC_REG + 0x0010,         __BITS(11,8)    },
        { RK3588_PMU1_IOC_REG + 0x0010,         __BITS(15,12)   },
        { RK3588_PMU1_IOC_REG + 0x0014,         __BITS(3,0)     },
        { RK3588_PMU1_IOC_REG + 0x0014,         __BITS(7,4)     },
        { RK3588_PMU1_IOC_REG + 0x0014,         __BITS(11,8)    },
        { RK3588_PMU1_IOC_REG + 0x0014,         __BITS(15,12)   },
        /* GPIO0_B[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0018,         __BITS(3,0)     },
        { RK3588_PMU1_IOC_REG + 0x0018,         __BITS(7,4)     },
        { RK3588_PMU1_IOC_REG + 0x0018,         __BITS(11,8)    },
        { RK3588_PMU1_IOC_REG + 0x0018,         __BITS(15,12)   },
        { RK3588_PMU2_IOC_REG + 0x0014,         __BITS(3,0)     },
        { RK3588_PMU2_IOC_REG + 0x0014,         __BITS(7,4)     },
        { RK3588_PMU2_IOC_REG + 0x0014,         __BITS(11,8)    },
        { RK3588_PMU2_IOC_REG + 0x0014,         __BITS(15,12)   },
        /* GPIO0_C[0-7] */
        { RK3588_PMU2_IOC_REG + 0x0018,         __BITS(3,0)     },
        { RK3588_PMU2_IOC_REG + 0x0018,         __BITS(7,4)     },
        { RK3588_PMU2_IOC_REG + 0x0018,         __BITS(11,8)    },
        { RK3588_PMU2_IOC_REG + 0x0018,         __BITS(15,12)   },
        { RK3588_PMU2_IOC_REG + 0x001c,         __BITS(3,0)     },
        { RK3588_PMU2_IOC_REG + 0x001c,         __BITS(7,4)     },
        { RK3588_PMU2_IOC_REG + 0x001c,         __BITS(11,8)    },
        { RK3588_PMU2_IOC_REG + 0x001c,         __BITS(15,12)   },
        /* GPIO0_D[0-7] */
        { RK3588_PMU2_IOC_REG + 0x0020,         __BITS(3,0)     },
        { RK3588_PMU2_IOC_REG + 0x0020,         __BITS(7,4)     },
        { RK3588_PMU2_IOC_REG + 0x0020,         __BITS(11,8)    },
        { RK3588_PMU2_IOC_REG + 0x0020,         __BITS(15,12)   },
        { RK3588_PMU2_IOC_REG + 0x0024,         __BITS(3,0)     },
        { RK3588_PMU2_IOC_REG + 0x0024,         __BITS(7,4)     },
        { RK3588_PMU2_IOC_REG + 0x0024,         __BITS(11,8)    },
        { RK3588_PMU2_IOC_REG + 0x0024,         __BITS(15,12)   },

        /* GPIO1_A[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0020,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0020,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0020,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x0020,     __BITS(15,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0024,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0024,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0024,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x0024,     __BITS(15,12)   },
        /* GPIO1_B[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0028,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0028,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0028,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x0028,     __BITS(15,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x002c,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x002c,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x002c,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x002c,     __BITS(15,12)   },
        /* GPIO1_C[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0030,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0030,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0030,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x0030,     __BITS(15,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0034,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0034,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0034,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x0034,     __BITS(15,12)   },
        /* GPIO1_D[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0038,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0038,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0038,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x0038,     __BITS(15,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x003c,     __BITS(3,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x003c,     __BITS(7,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x003c,     __BITS(11,8)    },
        { RK3588_VCCIO1_4_IOC_REG + 0x003c,     __BITS(15,12)   },

        /* GPIO2_A[0-7] */
        { RK3588_EMMC_IOC_REG + 0x0040,         __BITS(3,0)     },
        { RK3588_EMMC_IOC_REG + 0x0040,         __BITS(7,4)     },
        { RK3588_EMMC_IOC_REG + 0x0040,         __BITS(11,8)    },
        { RK3588_EMMC_IOC_REG + 0x0040,         __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0044,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0044,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0044,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0044,     __BITS(15,12)   },
        /* GPIO2_B[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0048,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0048,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0048,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0048,     __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x004c,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x004c,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x004c,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x004c,     __BITS(15,12)   },
        /* GPIO2_C[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0050,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0050,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0050,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0050,     __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0054,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0054,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0054,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0054,     __BITS(15,12)   },
        /* GPIO2_D[0-7] */
        { RK3588_EMMC_IOC_REG + 0x0058,         __BITS(3,0)     },
        { RK3588_EMMC_IOC_REG + 0x0058,         __BITS(7,4)     },
        { RK3588_EMMC_IOC_REG + 0x0058,         __BITS(11,8)    },
        { RK3588_EMMC_IOC_REG + 0x0058,         __BITS(15,12)   },
        { RK3588_EMMC_IOC_REG + 0x005c,         __BITS(3,0)     },
        { RK3588_EMMC_IOC_REG + 0x005c,         __BITS(7,4)     },
        { RK3588_EMMC_IOC_REG + 0x005c,         __BITS(11,8)    },
        { RK3588_EMMC_IOC_REG + 0x005c,         __BITS(15,12)   },

        /* GPIO3_A[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0060,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0060,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0060,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0060,     __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0064,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0064,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0064,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0064,     __BITS(15,12)   },
        /* GPIO3_B[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0068,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0068,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0068,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0068,     __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x006c,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x006c,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x006c,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x006c,     __BITS(15,12)   },
        /* GPIO3_C[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0070,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0070,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0070,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0070,     __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0074,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0074,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0074,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0074,     __BITS(15,12)   },
        /* GPIO3_D[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0078,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0078,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0078,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0078,     __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x007c,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x007c,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x007c,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x007c,     __BITS(15,12)   },

        /* GPIO4_A[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0080,       __BITS(3,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x0080,       __BITS(7,4)     },
        { RK3588_VCCIO6_IOC_REG + 0x0080,       __BITS(11,8)    },
        { RK3588_VCCIO6_IOC_REG + 0x0080,       __BITS(15,12)   },
        { RK3588_VCCIO6_IOC_REG + 0x0084,       __BITS(3,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x0084,       __BITS(7,4)     },
        { RK3588_VCCIO6_IOC_REG + 0x0084,       __BITS(11,8)    },
        { RK3588_VCCIO6_IOC_REG + 0x0084,       __BITS(15,12)   },
        /* GPIO4_B[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0088,       __BITS(3,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x0088,       __BITS(7,4)     },
        { RK3588_VCCIO6_IOC_REG + 0x0088,       __BITS(11,8)    },
        { RK3588_VCCIO6_IOC_REG + 0x0088,       __BITS(15,12)   },
        { RK3588_VCCIO6_IOC_REG + 0x008c,       __BITS(3,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x008c,       __BITS(7,4)     },
        { RK3588_VCCIO6_IOC_REG + 0x008c,       __BITS(11,8)    },
        { RK3588_VCCIO6_IOC_REG + 0x008c,       __BITS(15,12)   },
        /* GPIO4_C[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0090,       __BITS(3,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x0090,       __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0090,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0090,     __BITS(15,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0094,     __BITS(3,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0094,     __BITS(7,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0094,     __BITS(11,8)    },
        { RK3588_VCCIO3_5_IOC_REG + 0x0094,     __BITS(15,12)   },
        /* GPIO4_D[0-7] */
        { RK3588_VCCIO2_IOC_REG + 0x0098,       __BITS(3,0)     },
        { RK3588_VCCIO2_IOC_REG + 0x0098,       __BITS(7,4)     },
        { RK3588_VCCIO2_IOC_REG + 0x0098,       __BITS(11,8)    },
        { RK3588_VCCIO2_IOC_REG + 0x0098,       __BITS(15,12)   },
        { RK3588_VCCIO2_IOC_REG + 0x009c,       __BITS(3,0)     },
        { RK3588_VCCIO2_IOC_REG + 0x009c,       __BITS(7,4)     },
        { RK3588_VCCIO2_IOC_REG + 0x009c,       __BITS(11,8)    },
        { RK3588_VCCIO2_IOC_REG + 0x009c,       __BITS(15,12)   }
};

#define RK3588_GPIO_P_CTL_Z     0
#define RK3588_GPIO_P_PULLDOWN  1
#define RK3588_GPIO_P_DISABLE   2
#define RK3588_GPIO_P_PULLUP    3

static const struct regmask rk3588_pull_regmap[NBANKS * NPINPERBANK] = {
        /* GPIO0_A[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(1,0)     },
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(3,2)     },
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(5,4)     },
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(7,6)     },
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(9,8)     },
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(11,10)   },
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(13,12)   },
        { RK3588_PMU1_IOC_REG + 0x0020,         __BITS(15,14)   },
        /* GPIO0_B[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0024,         __BITS(1,0)     },
        { RK3588_PMU1_IOC_REG + 0x0024,         __BITS(3,2)     },
        { RK3588_PMU1_IOC_REG + 0x0024,         __BITS(5,4)     },
        { RK3588_PMU1_IOC_REG + 0x0024,         __BITS(7,6)     },
        { RK3588_PMU1_IOC_REG + 0x0024,         __BITS(9,8)     },
        { RK3588_PMU2_IOC_REG + 0x0028,         __BITS(11,10)   },
        { RK3588_PMU2_IOC_REG + 0x0028,         __BITS(13,12)   },
        { RK3588_PMU2_IOC_REG + 0x0028,         __BITS(15,14)   },
        /* GPIO0_C[0-7] */
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(1,0)     },
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(3,2)     },
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(5,4)     },
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(7,6)     },
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(9,8)     },
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(11,10)   },
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(13,12)   },
        { RK3588_PMU2_IOC_REG + 0x002c,         __BITS(15,14)   },
        /* GPIO0_D[0-7] */
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(1,0)     },
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(3,2)     },
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(5,4)     },
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(7,6)     },
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(9,8)     },
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(11,10)   },
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(13,12)   },
        { RK3588_PMU2_IOC_REG + 0x0030,         __BITS(15,14)   },

        /* GPIO1_A[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(1,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(3,2)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(5,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(7,6)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(9,8)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(11,10)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(13,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0110,     __BITS(15,14)   },
        /* GPIO1_B[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(1,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(3,2)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(5,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(7,6)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(9,8)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(11,10)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(13,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0114,     __BITS(15,14)   },
        /* GPIO1_C[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(1,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(3,2)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(5,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(7,6)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(9,8)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(11,10)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(13,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x0118,     __BITS(15,14)   },
        /* GPIO1_D[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(1,0)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(3,2)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(5,4)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(7,6)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(9,8)     },
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(11,10)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(13,12)   },
        { RK3588_VCCIO1_4_IOC_REG + 0x011c,     __BITS(15,14)   },

        /* GPIO2_A[0-7] */
        { RK3588_EMMC_IOC_REG + 0x0120,         __BITS(1,0)     },
        { RK3588_EMMC_IOC_REG + 0x0120,         __BITS(3,2)     },
        { RK3588_EMMC_IOC_REG + 0x0120,         __BITS(5,4)     },
        { RK3588_EMMC_IOC_REG + 0x0120,         __BITS(7,6)     },
        { RK3588_EMMC_IOC_REG + 0x0120,         __BITS(9,8)     },
        { RK3588_EMMC_IOC_REG + 0x0120,         __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0120,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0120,     __BITS(15,14)   },
        /* GPIO2_B[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(1,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(3,2)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(5,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(7,6)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(9,8)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0124,     __BITS(15,14)   },
        /* GPIO2_C[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(1,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(3,2)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(5,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(7,6)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(9,8)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0128,     __BITS(15,14)   },
        /* GPIO2_D[0-7] */
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(1,0)     },
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(3,2)     },
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(5,4)     },
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(7,6)     },
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(9,8)     },
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(11,10)   },
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(13,12)   },
        { RK3588_EMMC_IOC_REG + 0x012c,         __BITS(15,14)   },

        /* GPIO3_A[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(1,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(3,2)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(5,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(7,6)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(9,8)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0130,     __BITS(15,14)   },
        /* GPIO3_B[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(1,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(3,2)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(5,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(7,6)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(9,8)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0134,     __BITS(15,14)   },
        /* GPIO3_C[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(1,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(3,2)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(5,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(7,6)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(9,8)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0138,     __BITS(15,14)   },
        /* GPIO3_D[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(1,0)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(3,2)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(5,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(7,6)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(9,8)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x013c,     __BITS(15,14)   },

        /* GPIO4_A[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(1,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(3,2)     },
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(5,4)     },
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(7,6)     },
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(9,8)     },
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(11,10)   },
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(13,12)   },
        { RK3588_VCCIO6_IOC_REG + 0x0140,       __BITS(15,14)   },
        /* GPIO4_B[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(1,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(3,2)     },
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(5,4)     },
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(7,6)     },
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(9,8)     },
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(11,10)   },
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(13,12)   },
        { RK3588_VCCIO6_IOC_REG + 0x0144,       __BITS(15,14)   },
        /* GPIO4_C[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0148,       __BITS(1,0)     },
        { RK3588_VCCIO6_IOC_REG + 0x0148,       __BITS(3,2)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0148,     __BITS(5,4)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0148,     __BITS(7,6)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0148,     __BITS(9,8)     },
        { RK3588_VCCIO3_5_IOC_REG + 0x0148,     __BITS(11,10)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0148,     __BITS(13,12)   },
        { RK3588_VCCIO3_5_IOC_REG + 0x0148,     __BITS(15,14)   },
        /* GPIO4_D[0-7] */
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(1,0)     },
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(3,2)     },
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(5,4)     },
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(7,6)     },
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(9,8)     },
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(11,10)   },
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(13,12)   },
        { RK3588_VCCIO2_IOC_REG + 0x014c,       __BITS(15,14)   }
};

#if notyet
static const struct regmask rk3588_schmitt_regmap[NBANKS * NPINPERBANK] = {
        /* GPIO0_A[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(0)        },
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(1)        },
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(2)        },
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(3)        },
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(4)        },
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(5)        },
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(6)        },
        { RK3588_PMU1_IOC_REG + 0x0030,         __BIT(7)        },
        /* GPIO0_B[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0034,         __BIT(0)        },
        { RK3588_PMU1_IOC_REG + 0x0034,         __BIT(1)        },
        { RK3588_PMU1_IOC_REG + 0x0034,         __BIT(2)        },
        { RK3588_PMU1_IOC_REG + 0x0034,         __BIT(3)        },
        { RK3588_PMU1_IOC_REG + 0x0034,         __BIT(4)        },
        { RK3588_PMU2_IOC_REG + 0x0040,         __BIT(5)        },
        { RK3588_PMU2_IOC_REG + 0x0040,         __BIT(6)        },
        { RK3588_PMU2_IOC_REG + 0x0040,         __BIT(7)        },
        /* GPIO0_C[0-7] */
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(0)        },
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(1)        },
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(2)        },
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(3)        },
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(4)        },
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(5)        },
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(6)        },
        { RK3588_PMU2_IOC_REG + 0x0044,         __BIT(7)        },
        /* GPIO0_D[0-7] */
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(0)        },
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(1)        },
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(2)        },
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(3)        },
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(4)        },
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(5)        },
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(6)        },
        { RK3588_PMU2_IOC_REG + 0x0048,         __BIT(7)        },

        /* GPIO1_A[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(0)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(1)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(2)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(3)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(4)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(5)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(6)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0210,     __BIT(7)        },
        /* GPIO1_B[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(0)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(1)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(2)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(3)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(4)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(5)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(6)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0214,     __BIT(7)        },
        /* GPIO1_C[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(0)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(1)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(2)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(3)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(4)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(5)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(6)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x0218,     __BIT(7)        },
        /* GPIO1_D[0-7] */
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(0)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(1)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(2)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(3)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(4)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(5)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(6)        },
        { RK3588_VCCIO1_4_IOC_REG + 0x021c,     __BIT(7)        },

        /* GPIO2_A[0-7] */
        { RK3588_EMMC_IOC_REG + 0x0220,         __BIT(0)        },
        { RK3588_EMMC_IOC_REG + 0x0220,         __BIT(1)        },
        { RK3588_EMMC_IOC_REG + 0x0220,         __BIT(2)        },
        { RK3588_EMMC_IOC_REG + 0x0220,         __BIT(3)        },
        { RK3588_EMMC_IOC_REG + 0x0220,         __BIT(4)        },
        { RK3588_EMMC_IOC_REG + 0x0220,         __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0220,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0220,     __BIT(7)        },
        /* GPIO2_B[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(0)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(1)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(2)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(3)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(4)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0224,     __BIT(7)        },
        /* GPIO2_C[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(0)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(1)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(2)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(3)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(4)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0228,     __BIT(7)        },
        /* GPIO2_D[0-7] */
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(0)        },
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(1)        },
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(2)        },
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(3)        },
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(4)        },
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(5)        },
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(6)        },
        { RK3588_EMMC_IOC_REG + 0x022c,         __BIT(7)        },

        /* GPIO3_A[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(0)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(1)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(2)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(3)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(4)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0230,     __BIT(7)        },
        /* GPIO3_B[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(0)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(1)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(2)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(3)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(4)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0234,     __BIT(7)        },
        /* GPIO3_C[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(0)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(1)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(2)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(3)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(4)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0238,     __BIT(7)        },
        /* GPIO3_D[0-7] */
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(0)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(1)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(2)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(3)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(4)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x023c,     __BIT(7)        },

        /* GPIO4_A[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(0)        },
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(1)        },
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(2)        },
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(3)        },
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(4)        },
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(5)        },
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(6)        },
        { RK3588_VCCIO6_IOC_REG + 0x0240,       __BIT(7)        },
        /* GPIO4_B[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(0)        },
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(1)        },
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(2)        },
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(3)        },
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(4)        },
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(5)        },
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(6)        },
        { RK3588_VCCIO6_IOC_REG + 0x0244,       __BIT(7)        },
        /* GPIO4_C[0-7] */
        { RK3588_VCCIO6_IOC_REG + 0x0248,       __BIT(0)        },
        { RK3588_VCCIO6_IOC_REG + 0x0248,       __BIT(1)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0248,     __BIT(2)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0248,     __BIT(3)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0248,     __BIT(4)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0248,     __BIT(5)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0248,     __BIT(6)        },
        { RK3588_VCCIO3_5_IOC_REG + 0x0248,     __BIT(7)        },
        /* GPIO4_D[0-7] */
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(0)        },
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(1)        },
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(2)        },
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(3)        },
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(4)        },
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(5)        },
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(6)        },
        { RK3588_VCCIO2_IOC_REG + 0x024c,       __BIT(7)        }
};
#endif

static const struct regmaskreg rk3588_iomux_regmap[NBANKS * NPINPERBANK] = {
        /* GPIO0_A[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0000, __BITS(3,0)     },
        { RK3588_PMU1_IOC_REG + 0x0000, __BITS(7,4)     },
        { RK3588_PMU1_IOC_REG + 0x0000, __BITS(11,8)    },
        { RK3588_PMU1_IOC_REG + 0x0000, __BITS(15,12)   },
        { RK3588_PMU1_IOC_REG + 0x0004, __BITS(3,0)     },
        { RK3588_PMU1_IOC_REG + 0x0004, __BITS(7,4)     },
        { RK3588_PMU1_IOC_REG + 0x0004, __BITS(11,8)    },
        { RK3588_PMU1_IOC_REG + 0x0004, __BITS(15,12)   },
        /* GPIO0_B[0-7] */
        { RK3588_PMU1_IOC_REG + 0x0008, __BITS(3,0)     },
        { RK3588_PMU1_IOC_REG + 0x0008, __BITS(7,4)     },
        { RK3588_PMU1_IOC_REG + 0x0008, __BITS(11,8)    },
        { RK3588_PMU1_IOC_REG + 0x0008, __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x000c,  __BITS(3,0),    RK3588_PMU2_IOC_REG + 0x0000 },
        { RK3588_BUS_IOC_REG + 0x000c,  __BITS(7,4),    RK3588_PMU2_IOC_REG + 0x0000 },
        { RK3588_BUS_IOC_REG + 0x000c,  __BITS(11,8),   RK3588_PMU2_IOC_REG + 0x0000 },
        { RK3588_BUS_IOC_REG + 0x000c,  __BITS(15,12),  RK3588_PMU2_IOC_REG + 0x0000 },
        /* GPIO0_C[0-7] */
        { RK3588_BUS_IOC_REG + 0x0010,  __BITS(3,0),    RK3588_PMU2_IOC_REG + 0x0004 },
        { RK3588_BUS_IOC_REG + 0x0010,  __BITS(7,4),    RK3588_PMU2_IOC_REG + 0x0004 },
        { RK3588_BUS_IOC_REG + 0x0010,  __BITS(11,8),   RK3588_PMU2_IOC_REG + 0x0004 },
        { RK3588_BUS_IOC_REG + 0x0010,  __BITS(15,12),  RK3588_PMU2_IOC_REG + 0x0004 },
        { RK3588_BUS_IOC_REG + 0x0014,  __BITS(3,0),    RK3588_PMU2_IOC_REG + 0x0008 },
        { RK3588_BUS_IOC_REG + 0x0014,  __BITS(7,4),    RK3588_PMU2_IOC_REG + 0x0008 },
        { RK3588_BUS_IOC_REG + 0x0014,  __BITS(11,8),   RK3588_PMU2_IOC_REG + 0x0008 },
        { RK3588_BUS_IOC_REG + 0x0014,  __BITS(15,12),  RK3588_PMU2_IOC_REG + 0x0008 },
        /* GPIO0_D[0-7] */
        { RK3588_BUS_IOC_REG + 0x0018,  __BITS(3,0),    RK3588_PMU2_IOC_REG + 0x000c },
        { RK3588_BUS_IOC_REG + 0x0018,  __BITS(7,4),    RK3588_PMU2_IOC_REG + 0x000c },
        { RK3588_BUS_IOC_REG + 0x0018,  __BITS(11,8),   RK3588_PMU2_IOC_REG + 0x000c },
        { RK3588_BUS_IOC_REG + 0x0018,  __BITS(15,12),  RK3588_PMU2_IOC_REG + 0x000c },
        { RK3588_BUS_IOC_REG + 0x001c,  __BITS(3,0),    RK3588_PMU2_IOC_REG + 0x0010 },
        { RK3588_BUS_IOC_REG + 0x001c,  __BITS(7,4),    RK3588_PMU2_IOC_REG + 0x0010 },
        { RK3588_BUS_IOC_REG + 0x001c,  __BITS(11,8),   RK3588_PMU2_IOC_REG + 0x0010 },
        { RK3588_BUS_IOC_REG + 0x001c,  __BITS(15,12),  RK3588_PMU2_IOC_REG + 0x0010 },

        /* GPIO1_A[0-7] */
        { RK3588_BUS_IOC_REG + 0x0020,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0020,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0020,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0020,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0024,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0024,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0024,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0024,  __BITS(15,12)   },
        /* GPIO1_B[0-7] */
        { RK3588_BUS_IOC_REG + 0x0028,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0028,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0028,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0028,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x002c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x002c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x002c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x002c,  __BITS(15,12)   },
        /* GPIO1_C[0-7] */
        { RK3588_BUS_IOC_REG + 0x0030,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0030,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0030,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0030,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0034,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0034,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0034,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0034,  __BITS(15,12)   },
        /* GPIO1_D[0-7] */
        { RK3588_BUS_IOC_REG + 0x0038,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0038,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0038,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0038,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x003c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x003c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x003c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x003c,  __BITS(15,12)   },

        /* GPIO2_A[0-7] */
        { RK3588_BUS_IOC_REG + 0x0040,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0040,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0040,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0040,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0044,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0044,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0044,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0044,  __BITS(15,12)   },
        /* GPIO2_B[0-7] */
        { RK3588_BUS_IOC_REG + 0x0048,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0048,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0048,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0048,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x004c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x004c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x004c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x004c,  __BITS(15,12)   },
        /* GPIO2_C[0-7] */
        { RK3588_BUS_IOC_REG + 0x0050,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0050,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0050,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0050,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0054,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0054,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0054,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0054,  __BITS(15,12)   },
        /* GPIO2_D[0-7] */
        { RK3588_BUS_IOC_REG + 0x0058,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0058,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0058,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0058,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x005c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x005c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x005c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x005c,  __BITS(15,12)   },

        /* GPIO3_A[0-7] */
        { RK3588_BUS_IOC_REG + 0x0060,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0060,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0060,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0060,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0064,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0064,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0064,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0064,  __BITS(15,12)   },
        /* GPIO3_B[0-7] */
        { RK3588_BUS_IOC_REG + 0x0068,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0068,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0068,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0068,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x006c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x006c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x006c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x006c,  __BITS(15,12)   },
        /* GPIO3_C[0-7] */
        { RK3588_BUS_IOC_REG + 0x0070,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0070,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0070,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0070,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0074,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0074,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0074,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0074,  __BITS(15,12)   },
        /* GPIO3_D[0-7] */
        { RK3588_BUS_IOC_REG + 0x0078,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0078,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0078,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0078,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x007c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x007c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x007c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x007c,  __BITS(15,12)   },

        /* GPIO4_A[0-7] */
        { RK3588_BUS_IOC_REG + 0x0080,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0080,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0080,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0080,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0084,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0084,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0084,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0084,  __BITS(15,12)   },
        /* GPIO4_B[0-7] */
        { RK3588_BUS_IOC_REG + 0x0088,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0088,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0088,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0088,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x008c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x008c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x008c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x008c,  __BITS(15,12)   },
        /* GPIO4_C[0-7] */
        { RK3588_BUS_IOC_REG + 0x0090,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0090,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0090,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0090,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x0094,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0094,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0094,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0094,  __BITS(15,12)   },
        /* GPIO4_D[0-7] */
        { RK3588_BUS_IOC_REG + 0x0098,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x0098,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x0098,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x0098,  __BITS(15,12)   },
        { RK3588_BUS_IOC_REG + 0x009c,  __BITS(3,0)     },
        { RK3588_BUS_IOC_REG + 0x009c,  __BITS(7,4)     },
        { RK3588_BUS_IOC_REG + 0x009c,  __BITS(11,8)    },
        { RK3588_BUS_IOC_REG + 0x009c,  __BITS(15,12)   }
};

#ifdef RK3588_IOMUX_DEBUG
static char *
rk3588_iomux_pinname(int pin)
{
        static char buf[16];

        int bank = pin / 32;
        int group = (pin / 8) & 3;
        int idx = pin & 7;
        snprintf(buf, sizeof(buf), "%d=[%d-RK_P%c%d]",
            pin, bank, 'A' + group, idx);
        return buf;
}
#endif

static void
rk3588_iomux_set_bias(struct rk3588_iomux_softc *sc, int pin, int bias)
{
        uint32_t val;

        switch (bias) {
        case 0:
                val = RK3588_GPIO_P_CTL_Z;
                break;
        case GPIO_PIN_PULLUP:
                val = RK3588_GPIO_P_PULLUP;
                break;
        case GPIO_PIN_PULLDOWN:
                val = RK3588_GPIO_P_PULLDOWN;
                break;
        default:
                return;
        }

        bus_size_t reg = rk3588_pull_regmap[pin].reg;
        uint32_t mask = rk3588_pull_regmap[pin].mask;
        val = (mask << 16) | __SHIFTIN(val, mask);

        syscon_write_4(sc->sc_grf, reg, val);

#ifdef RK3588_IOMUX_DEBUG
        printf("%s: pin=%s bias %s (reg:%08lx -> %08x)\n", __func__,
            rk3588_iomux_pinname(pin), (bias == 0) ? "Z" :
            (bias == GPIO_PIN_PULLUP) ? "PULLUP" : "PULLDOWN",
            reg, val);
#endif
}

static void
rk3588_iomux_set_drive_strength(struct rk3588_iomux_softc *sc, int pin, int drv)
{
        if (drv < 0 || drv > 15)
                return;

        /* Amperage (mA) corresponds directly to register values 0-15 */
        bus_size_t reg = rk3588_drive_regmap[pin].reg;
        uint32_t mask = rk3588_drive_regmap[pin].mask;
        uint32_t val = (mask << 16) | __SHIFTIN(drv, mask);

        syscon_write_4(sc->sc_grf, reg, val);

#ifdef RK3588_IOMUX_DEBUG
        printf("%s: pin=%s strength %d (reg:%08lx -> %08x)\n", __func__,
            rk3588_iomux_pinname(pin), drv, reg, val);
#endif
}

static void
rk3588_iomux_set_mux(struct rk3588_iomux_softc *sc, int pin, u_int mux)
{
        bus_size_t reg = rk3588_iomux_regmap[pin].reg;
        bus_size_t reg0 = rk3588_iomux_regmap[pin].reg0;
        uint32_t mask = rk3588_iomux_regmap[pin].mask;
        uint32_t val;

        if (reg0 != 0) {
                val = (mask << 16) | __SHIFTIN(__BIT(3), mask);
                syscon_write_4(sc->sc_grf, reg0, val);
        }

        val = (mask << 16) | __SHIFTIN(mux, mask);
        syscon_write_4(sc->sc_grf, reg, val);

#ifdef RK3588_IOMUX_DEBUG
        printf("%s: pin=%s mux %d (reg:%08lx -> %08x)\n", __func__,
            rk3588_iomux_pinname(pin), mux, reg, val);
#endif
}

static void
rk3588_iomux_set_direction(struct rk3588_iomux_softc *sc, int pin, int dir,
    int value)
{
        /* XXX: notyet */
        panic("%s:%d: pin=%d, dir=%d: not supported\n", __func__, __LINE__, pin, dir);

#ifdef RK3588_IOMUX_DEBUG
        printf("%s: pin=%s dir %d, value %08x\n", __func__,
            rk3588_iomux_pinname(pin), dir, value);
#endif
}

static int
rk3588_iomux_config(struct rk3588_iomux_softc *sc, const int phandle,
    u_int bank, u_int idx, u_int mux)
{
        const int pin = PIN(bank, idx);

        if (pin < 0 || pin >= NPINS)
                return EINVAL;

        int bias = fdtbus_pinctrl_parse_bias(phandle, NULL);
        if (bias != -1)
                rk3588_iomux_set_bias(sc, pin, bias);

        int drv = fdtbus_pinctrl_parse_drive_strength(phandle);
        if (drv != -1)
                rk3588_iomux_set_drive_strength(sc, pin, drv);

        int output_value;
        int dir = fdtbus_pinctrl_parse_input_output(phandle, &output_value);
        if (dir != -1)
                rk3588_iomux_set_direction(sc, pin, dir, output_value);

        rk3588_iomux_set_mux(sc, pin, mux);

        return 0;
}

static int
rk3588_iomux_pinctrl_set_config(device_t dev, const void *data, size_t len)
{
        struct rk3588_iomux_softc * const sc = device_private(dev);
        int pins_len = 0;

        if (len != 4)
                return -1;

        const int phandle = fdtbus_get_phandle_from_native(be32dec(data));
        const u_int *pins = fdtbus_get_prop(phandle, "rockchip,pins",
            &pins_len);

        for (; pins_len >= 16; pins_len -= 16, pins += 4) {
                const u_int bank = be32toh(pins[0]);
                const u_int idx = be32toh(pins[1]);
                const u_int mux = be32toh(pins[2]);
                const int cfg =
                    fdtbus_get_phandle_from_native(be32toh(pins[3]));

                syscon_lock(sc->sc_grf);
                rk3588_iomux_config(sc, cfg, bank, idx, mux);
                syscon_unlock(sc->sc_grf);
        }

        return 0;
}

static struct fdtbus_pinctrl_controller_func rk3588_iomux_pinctrl_funcs = {
        .set_config = rk3588_iomux_pinctrl_set_config
};

static int
rk3588_iomux_match(device_t parent, cfdata_t cf, void *aux)
{
        struct fdt_attach_args * const faa = aux;
        return of_compatible_match(faa->faa_phandle, compat_data);
}

static void
rk3588_iomux_attach(device_t parent, device_t self, void *aux)
{
        struct rk3588_iomux_softc * const sc = device_private(self);
        struct fdt_attach_args * const faa = aux;
        const int phandle = faa->faa_phandle;

        sc->sc_dev = self;
        sc->sc_grf = fdtbus_syscon_acquire(phandle, "rockchip,grf");
        if (sc->sc_grf == NULL) {
                aprint_error(": couldn't acquire grf syscon\n");
                return;
        }

        aprint_naive("\n");
        aprint_normal(": RK3588 IOMUX control\n");

        for (int child = OF_child(phandle); child; child = OF_peer(child)) {
                for (int sub = OF_child(child); sub; sub = OF_peer(sub)) {
                        if (!of_hasprop(sub, "rockchip,pins"))
                                continue;
                        fdtbus_register_pinctrl_config(self, sub,
                            &rk3588_iomux_pinctrl_funcs);
                }
        }

        for (int child = OF_child(phandle); child; child = OF_peer(child)) {
                struct fdt_attach_args cfaa = *faa;
                cfaa.faa_phandle = child;
                cfaa.faa_name = fdtbus_get_string(child, "name");
                cfaa.faa_quiet = false;

                config_found(self, &cfaa, NULL, CFARGS_NONE);
        }
}