Changeset View
Changeset View
Standalone View
Standalone View
sys/arm64/rockchip/rk_pinctrl.c
Show First 20 Lines • Show All 72 Lines • ▼ Show 20 Lines | struct rk_pinctrl_pin_fixup { | ||||
uint32_t bank; | uint32_t bank; | ||||
uint32_t subbank; | uint32_t subbank; | ||||
uint32_t pin; | uint32_t pin; | ||||
uint32_t reg; | uint32_t reg; | ||||
uint32_t bit; | uint32_t bit; | ||||
uint32_t mask; | uint32_t mask; | ||||
}; | }; | ||||
struct rk_pinctrl_softc; | |||||
struct rk_pinctrl_conf { | struct rk_pinctrl_conf { | ||||
struct rk_pinctrl_bank *iomux_conf; | struct rk_pinctrl_bank *iomux_conf; | ||||
uint32_t iomux_nbanks; | uint32_t iomux_nbanks; | ||||
struct rk_pinctrl_pin_fixup *pin_fixup; | struct rk_pinctrl_pin_fixup *pin_fixup; | ||||
uint32_t npin_fixup; | uint32_t npin_fixup; | ||||
struct rk_pinctrl_pin_drive *pin_drive; | struct rk_pinctrl_pin_drive *pin_drive; | ||||
uint32_t npin_drive; | uint32_t npin_drive; | ||||
uint32_t pd_offset; | uint32_t pd_offset; | ||||
uint32_t drive_offset; | uint32_t drive_offset; | ||||
struct syscon *(*get_syscon)(struct rk_pinctrl_softc *, uint32_t); | |||||
ganbold: This probably goes over 80 chars | |||||
}; | }; | ||||
struct rk_pinctrl_softc { | struct rk_pinctrl_softc { | ||||
struct simplebus_softc simplebus_sc; | struct simplebus_softc simplebus_sc; | ||||
device_t dev; | device_t dev; | ||||
struct syscon *grf; | struct syscon *grf; | ||||
struct syscon *pmu; | |||||
struct rk_pinctrl_conf *conf; | struct rk_pinctrl_conf *conf; | ||||
}; | }; | ||||
static struct rk_pinctrl_bank rk3328_iomux_bank[] = { | static struct rk_pinctrl_bank rk3328_iomux_bank[] = { | ||||
{ | { | ||||
.bank_num = 0, | .bank_num = 0, | ||||
.subbank_num = 0, | .subbank_num = 0, | ||||
.offset = 0x00, | .offset = 0x00, | ||||
▲ Show 20 Lines • Show All 129 Lines • ▼ Show 20 Lines | static struct rk_pinctrl_pin_drive rk3328_pin_drive[] = { | ||||
.ma = 8, | .ma = 8, | ||||
}, | }, | ||||
{ | { | ||||
.value = 3, | .value = 3, | ||||
.ma = 12, | .ma = 12, | ||||
}, | }, | ||||
}; | }; | ||||
static struct syscon * | |||||
Not Done Inline ActionsMaybe you meant following? static struct syscon * ganbold: Maybe you meant following?
static struct syscon *
rk3328_get_syscon(struct rk_pinctrl_softc… | |||||
rk3328_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) | |||||
{ | |||||
Not Done Inline Actionsblank line before it and return (sc->grf); ganbold: blank line before it and return (sc->grf); | |||||
return (sc->grf); | |||||
} | |||||
struct rk_pinctrl_conf rk3328_conf = { | struct rk_pinctrl_conf rk3328_conf = { | ||||
.iomux_conf = rk3328_iomux_bank, | .iomux_conf = rk3328_iomux_bank, | ||||
.iomux_nbanks = nitems(rk3328_iomux_bank), | .iomux_nbanks = nitems(rk3328_iomux_bank), | ||||
.pin_fixup = rk3328_pin_fixup, | .pin_fixup = rk3328_pin_fixup, | ||||
.npin_fixup = nitems(rk3328_pin_fixup), | .npin_fixup = nitems(rk3328_pin_fixup), | ||||
.pin_drive = rk3328_pin_drive, | .pin_drive = rk3328_pin_drive, | ||||
.npin_drive = nitems(rk3328_pin_drive), | .npin_drive = nitems(rk3328_pin_drive), | ||||
.pd_offset = 0x100, | .pd_offset = 0x100, | ||||
.drive_offset = 0x200, | .drive_offset = 0x200, | ||||
.get_syscon = rk3328_get_syscon, | |||||
}; | }; | ||||
static struct rk_pinctrl_bank rk3399_iomux_bank[] = { | |||||
{ | |||||
.bank_num = 0, | |||||
.subbank_num = 0, | |||||
.offset = 0x00, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 0, | |||||
.subbank_num = 1, | |||||
.offset = 0x04, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 0, | |||||
.subbank_num = 2, | |||||
.offset = 0x08, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 0, | |||||
.subbank_num = 3, | |||||
.offset = 0x0c, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 1, | |||||
.subbank_num = 0, | |||||
.offset = 0x10, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 1, | |||||
.subbank_num = 1, | |||||
.offset = 0x14, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 1, | |||||
.subbank_num = 2, | |||||
.offset = 0x18, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 1, | |||||
.subbank_num = 3, | |||||
.offset = 0x1c, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 2, | |||||
.subbank_num = 0, | |||||
.offset = 0x20, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 2, | |||||
.subbank_num = 1, | |||||
.offset = 0x24, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 2, | |||||
.subbank_num = 2, | |||||
.offset = 0x28, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 2, | |||||
.subbank_num = 3, | |||||
.offset = 0x2c, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 3, | |||||
.subbank_num = 0, | |||||
.offset = 0x30, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 3, | |||||
.subbank_num = 1, | |||||
.offset = 0x34, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 3, | |||||
.subbank_num = 2, | |||||
.offset = 0x38, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 3, | |||||
.subbank_num = 3, | |||||
.offset = 0x3c, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 4, | |||||
.subbank_num = 0, | |||||
.offset = 0x40, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 4, | |||||
.subbank_num = 1, | |||||
.offset = 0x44, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 4, | |||||
.subbank_num = 2, | |||||
.offset = 0x48, | |||||
.nbits = 2, | |||||
}, | |||||
{ | |||||
.bank_num = 4, | |||||
.subbank_num = 3, | |||||
.offset = 0x4c, | |||||
.nbits = 2, | |||||
}, | |||||
}; | |||||
static struct rk_pinctrl_pin_fixup rk3399_pin_fixup[] = {}; | |||||
static struct syscon * | |||||
Not Done Inline Actionssame here as above ganbold: same here as above | |||||
rk3399_get_syscon(struct rk_pinctrl_softc *sc, uint32_t bank) | |||||
{ | |||||
Not Done Inline Actionsblank line before it ganbold: blank line before it | |||||
if (bank < 2) | |||||
return (sc->pmu); | |||||
Not Done Inline Actionswrap return values with () ganbold: wrap return values with () | |||||
return (sc->grf); | |||||
} | |||||
struct rk_pinctrl_conf rk3399_conf = { | |||||
.iomux_conf = rk3399_iomux_bank, | |||||
.iomux_nbanks = nitems(rk3399_iomux_bank), | |||||
.pin_fixup = rk3399_pin_fixup, | |||||
Not Done Inline Actionscomments rather with /* XXX */ style ganbold: comments rather with /* XXX */ style | |||||
.npin_fixup = nitems(rk3399_pin_fixup), | |||||
/* XXX: pin drive is not used on RK3399 */ | |||||
.pin_drive = rk3328_pin_drive, | |||||
.npin_drive = nitems(rk3328_pin_drive), | |||||
.pd_offset = 0x40, | |||||
.drive_offset = 0, | |||||
.get_syscon = rk3399_get_syscon, | |||||
}; | |||||
static struct ofw_compat_data compat_data[] = { | static struct ofw_compat_data compat_data[] = { | ||||
#ifdef SOC_ROCKCHIP_RK3328 | #ifdef SOC_ROCKCHIP_RK3328 | ||||
{"rockchip,rk3328-pinctrl", (uintptr_t)&rk3328_conf}, | {"rockchip,rk3328-pinctrl", (uintptr_t)&rk3328_conf}, | ||||
#endif | #endif | ||||
#ifdef SOC_ROCKCHIP_RK3399 | |||||
{"rockchip,rk3399-pinctrl", (uintptr_t)&rk3399_conf}, | |||||
#endif | |||||
{NULL, 0} | {NULL, 0} | ||||
}; | }; | ||||
static int | static int | ||||
rk_pinctrl_parse_bias(phandle_t node) | rk_pinctrl_parse_bias(phandle_t node) | ||||
{ | { | ||||
if (OF_hasprop(node, "bias-disable")) | if (OF_hasprop(node, "bias-disable")) | ||||
return (0); | return (0); | ||||
▲ Show 20 Lines • Show All 41 Lines • ▼ Show 20 Lines | if (sc->conf->pin_fixup[i].bank == bank && | ||||
return; | return; | ||||
} | } | ||||
} | } | ||||
static void | static void | ||||
rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, uint32_t *pindata) | rk_pinctrl_configure_pin(struct rk_pinctrl_softc *sc, uint32_t *pindata) | ||||
{ | { | ||||
phandle_t pin_conf; | phandle_t pin_conf; | ||||
struct syscon *syscon; | |||||
uint32_t bank, subbank, pin, function, bias; | uint32_t bank, subbank, pin, function, bias; | ||||
uint32_t bit, mask, reg, drive; | uint32_t bit, mask, reg, drive; | ||||
int i; | int i; | ||||
bank = pindata[0]; | bank = pindata[0]; | ||||
pin = pindata[1]; | pin = pindata[1]; | ||||
function = pindata[2]; | function = pindata[2]; | ||||
pin_conf = OF_node_from_xref(pindata[3]); | pin_conf = OF_node_from_xref(pindata[3]); | ||||
subbank = pin / 8; | subbank = pin / 8; | ||||
for (i = 0; i < sc->conf->iomux_nbanks; i++) | for (i = 0; i < sc->conf->iomux_nbanks; i++) | ||||
if (sc->conf->iomux_conf[i].bank_num == bank && | if (sc->conf->iomux_conf[i].bank_num == bank && | ||||
sc->conf->iomux_conf[i].subbank_num == subbank) | sc->conf->iomux_conf[i].subbank_num == subbank) | ||||
break; | break; | ||||
if (i == sc->conf->iomux_nbanks) { | if (i == sc->conf->iomux_nbanks) { | ||||
device_printf(sc->dev, "Unknown pin %d in bank %d\n", pin, | device_printf(sc->dev, "Unknown pin %d in bank %d\n", pin, | ||||
bank); | bank); | ||||
return; | return; | ||||
} | } | ||||
/* Find syscon */ | |||||
syscon = sc->conf->get_syscon(sc, bank); | |||||
/* Parse pin function */ | /* Parse pin function */ | ||||
reg = sc->conf->iomux_conf[i].offset; | reg = sc->conf->iomux_conf[i].offset; | ||||
switch (sc->conf->iomux_conf[i].nbits) { | switch (sc->conf->iomux_conf[i].nbits) { | ||||
case 3: | case 3: | ||||
if ((pin % 8) >= 5) | if ((pin % 8) >= 5) | ||||
reg += 4; | reg += 4; | ||||
bit = (pin % 8 % 5) * 3; | bit = (pin % 8 % 5) * 3; | ||||
mask = (0x7 << bit) << 16; | mask = (0x7 << bit) << 16; | ||||
break; | break; | ||||
case 2: | case 2: | ||||
default: | default: | ||||
bit = (pin % 8) * 2; | bit = (pin % 8) * 2; | ||||
mask = (0x3 << bit) << 16; | mask = (0x3 << bit) << 16; | ||||
break; | break; | ||||
} | } | ||||
rk_pinctrl_get_fixup(sc, bank, pin, ®, &mask, &bit); | rk_pinctrl_get_fixup(sc, bank, pin, ®, &mask, &bit); | ||||
SYSCON_WRITE_4(sc->grf, reg, function << bit | mask); | SYSCON_WRITE_4(syscon, reg, function << bit | mask); | ||||
/* Pull-Up/Down */ | /* Pull-Up/Down */ | ||||
bias = rk_pinctrl_parse_bias(pin_conf); | bias = rk_pinctrl_parse_bias(pin_conf); | ||||
if (bias >= 0) { | if (bias >= 0) { | ||||
reg = sc->conf->pd_offset; | reg = sc->conf->pd_offset; | ||||
reg += bank * 0x10 + ((pin / 8) * 0x4); | reg += bank * 0x10 + ((pin / 8) * 0x4); | ||||
bit = (pin % 8) * 2; | bit = (pin % 8) * 2; | ||||
mask = (0x3 << bit) << 16; | mask = (0x3 << bit) << 16; | ||||
SYSCON_WRITE_4(sc->grf, reg, bias << bit | mask); | SYSCON_WRITE_4(syscon, reg, bias << bit | mask); | ||||
} | } | ||||
/* Drive Strength */ | /* Drive Strength */ | ||||
if (rk_pinctrl_parse_drive(sc, pin_conf, &drive) == 0) { | if (rk_pinctrl_parse_drive(sc, pin_conf, &drive) == 0) { | ||||
reg = sc->conf->drive_offset; | reg = sc->conf->drive_offset; | ||||
reg += bank * 0x10 + ((pin / 8) * 0x4); | reg += bank * 0x10 + ((pin / 8) * 0x4); | ||||
bit = (pin % 8) * 2; | bit = (pin % 8) * 2; | ||||
mask = (0x3 << bit) << 16; | mask = (0x3 << bit) << 16; | ||||
SYSCON_WRITE_4(sc->grf, reg, bias << bit | mask); | SYSCON_WRITE_4(syscon, reg, bias << bit | mask); | ||||
} | } | ||||
} | } | ||||
static int | static int | ||||
rk_pinctrl_configure_pins(device_t dev, phandle_t cfgxref) | rk_pinctrl_configure_pins(device_t dev, phandle_t cfgxref) | ||||
{ | { | ||||
struct rk_pinctrl_softc *sc; | struct rk_pinctrl_softc *sc; | ||||
phandle_t node; | phandle_t node; | ||||
Show All 40 Lines | rk_pinctrl_attach(device_t dev) | ||||
node = ofw_bus_get_node(dev); | node = ofw_bus_get_node(dev); | ||||
if (OF_hasprop(node, "rockchip,grf") && | if (OF_hasprop(node, "rockchip,grf") && | ||||
syscon_get_by_ofw_property(dev, node, | syscon_get_by_ofw_property(dev, node, | ||||
"rockchip,grf", &sc->grf) != 0) { | "rockchip,grf", &sc->grf) != 0) { | ||||
device_printf(dev, "cannot get grf driver handle\n"); | device_printf(dev, "cannot get grf driver handle\n"); | ||||
return (ENXIO); | return (ENXIO); | ||||
} | |||||
// RK3399 has banks in PMU. RK3328 does not have a PMU. | |||||
if (ofw_bus_node_is_compatible(node, "rockchip,rk3399-pinctrl")) { | |||||
if (OF_hasprop(node, "rockchip,pmu") && | |||||
syscon_get_by_ofw_property(dev, node, | |||||
"rockchip,pmu", &sc->pmu) != 0) { | |||||
device_printf(dev, "cannot get pmu driver handle\n"); | |||||
return (ENXIO); | |||||
} | |||||
} | } | ||||
sc->conf = (struct rk_pinctrl_conf *)ofw_bus_search_compatible(dev, | sc->conf = (struct rk_pinctrl_conf *)ofw_bus_search_compatible(dev, | ||||
compat_data)->ocd_data; | compat_data)->ocd_data; | ||||
fdt_pinctrl_register(dev, "rockchip,pins"); | fdt_pinctrl_register(dev, "rockchip,pins"); | ||||
fdt_pinctrl_configure_tree(dev); | fdt_pinctrl_configure_tree(dev); | ||||
▲ Show 20 Lines • Show All 43 Lines • Show Last 20 Lines |
This probably goes over 80 chars