cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

pinctrl-bcm6362.c (14639B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * Driver for BCM6362 GPIO unit (pinctrl + GPIO)
      4 *
      5 * Copyright (C) 2021 Álvaro Fernández Rojas <noltari@gmail.com>
      6 * Copyright (C) 2016 Jonas Gorski <jonas.gorski@gmail.com>
      7 */
      8
      9#include <linux/bits.h>
     10#include <linux/gpio/driver.h>
     11#include <linux/kernel.h>
     12#include <linux/of.h>
     13#include <linux/pinctrl/pinmux.h>
     14#include <linux/platform_device.h>
     15#include <linux/regmap.h>
     16
     17#include "../pinctrl-utils.h"
     18
     19#include "pinctrl-bcm63xx.h"
     20
     21#define BCM6362_BANK_GPIOS	32
     22#define BCM6362_NUM_GPIOS	48
     23#define BCM6362_NUM_LEDS	24
     24
     25#define BCM6362_LED_REG		0x10
     26#define BCM6362_MODE_REG	0x18
     27#define BCM6362_CTRL_REG	0x1c
     28#define BCM6362_BASEMODE_REG	0x38
     29#define  BASEMODE_NAND		BIT(2)
     30
     31enum bcm6362_pinctrl_reg {
     32	BCM6362_LEDCTRL,
     33	BCM6362_MODE,
     34	BCM6362_CTRL,
     35	BCM6362_BASEMODE,
     36};
     37
     38struct bcm6362_pingroup {
     39	const char *name;
     40	const unsigned * const pins;
     41	const unsigned num_pins;
     42};
     43
     44struct bcm6362_function {
     45	const char *name;
     46	const char * const *groups;
     47	const unsigned num_groups;
     48
     49	enum bcm6362_pinctrl_reg reg;
     50	uint32_t basemode_mask;
     51};
     52
     53#define BCM6362_PIN(a, b, mask)			\
     54	{					\
     55		.number = a,			\
     56		.name = b,			\
     57		.drv_data = (void *)(mask),	\
     58	}
     59
     60static const struct pinctrl_pin_desc bcm6362_pins[] = {
     61	PINCTRL_PIN(0, "gpio0"),
     62	PINCTRL_PIN(1, "gpio1"),
     63	PINCTRL_PIN(2, "gpio2"),
     64	PINCTRL_PIN(3, "gpio3"),
     65	PINCTRL_PIN(4, "gpio4"),
     66	PINCTRL_PIN(5, "gpio5"),
     67	PINCTRL_PIN(6, "gpio6"),
     68	PINCTRL_PIN(7, "gpio7"),
     69	BCM6362_PIN(8, "gpio8", BASEMODE_NAND),
     70	PINCTRL_PIN(9, "gpio9"),
     71	PINCTRL_PIN(10, "gpio10"),
     72	PINCTRL_PIN(11, "gpio11"),
     73	BCM6362_PIN(12, "gpio12", BASEMODE_NAND),
     74	BCM6362_PIN(13, "gpio13", BASEMODE_NAND),
     75	BCM6362_PIN(14, "gpio14", BASEMODE_NAND),
     76	BCM6362_PIN(15, "gpio15", BASEMODE_NAND),
     77	BCM6362_PIN(16, "gpio16", BASEMODE_NAND),
     78	BCM6362_PIN(17, "gpio17", BASEMODE_NAND),
     79	BCM6362_PIN(18, "gpio18", BASEMODE_NAND),
     80	BCM6362_PIN(19, "gpio19", BASEMODE_NAND),
     81	BCM6362_PIN(20, "gpio20", BASEMODE_NAND),
     82	BCM6362_PIN(21, "gpio21", BASEMODE_NAND),
     83	BCM6362_PIN(22, "gpio22", BASEMODE_NAND),
     84	BCM6362_PIN(23, "gpio23", BASEMODE_NAND),
     85	PINCTRL_PIN(24, "gpio24"),
     86	PINCTRL_PIN(25, "gpio25"),
     87	PINCTRL_PIN(26, "gpio26"),
     88	BCM6362_PIN(27, "gpio27", BASEMODE_NAND),
     89	PINCTRL_PIN(28, "gpio28"),
     90	PINCTRL_PIN(29, "gpio29"),
     91	PINCTRL_PIN(30, "gpio30"),
     92	PINCTRL_PIN(31, "gpio31"),
     93	PINCTRL_PIN(32, "gpio32"),
     94	PINCTRL_PIN(33, "gpio33"),
     95	PINCTRL_PIN(34, "gpio34"),
     96	PINCTRL_PIN(35, "gpio35"),
     97	PINCTRL_PIN(36, "gpio36"),
     98	PINCTRL_PIN(37, "gpio37"),
     99	PINCTRL_PIN(38, "gpio38"),
    100	PINCTRL_PIN(39, "gpio39"),
    101	PINCTRL_PIN(40, "gpio40"),
    102	PINCTRL_PIN(41, "gpio41"),
    103	PINCTRL_PIN(42, "gpio42"),
    104	PINCTRL_PIN(43, "gpio43"),
    105	PINCTRL_PIN(44, "gpio44"),
    106	PINCTRL_PIN(45, "gpio45"),
    107	PINCTRL_PIN(46, "gpio46"),
    108	PINCTRL_PIN(47, "gpio47"),
    109};
    110
    111static unsigned gpio0_pins[] = { 0 };
    112static unsigned gpio1_pins[] = { 1 };
    113static unsigned gpio2_pins[] = { 2 };
    114static unsigned gpio3_pins[] = { 3 };
    115static unsigned gpio4_pins[] = { 4 };
    116static unsigned gpio5_pins[] = { 5 };
    117static unsigned gpio6_pins[] = { 6 };
    118static unsigned gpio7_pins[] = { 7 };
    119static unsigned gpio8_pins[] = { 8 };
    120static unsigned gpio9_pins[] = { 9 };
    121static unsigned gpio10_pins[] = { 10 };
    122static unsigned gpio11_pins[] = { 11 };
    123static unsigned gpio12_pins[] = { 12 };
    124static unsigned gpio13_pins[] = { 13 };
    125static unsigned gpio14_pins[] = { 14 };
    126static unsigned gpio15_pins[] = { 15 };
    127static unsigned gpio16_pins[] = { 16 };
    128static unsigned gpio17_pins[] = { 17 };
    129static unsigned gpio18_pins[] = { 18 };
    130static unsigned gpio19_pins[] = { 19 };
    131static unsigned gpio20_pins[] = { 20 };
    132static unsigned gpio21_pins[] = { 21 };
    133static unsigned gpio22_pins[] = { 22 };
    134static unsigned gpio23_pins[] = { 23 };
    135static unsigned gpio24_pins[] = { 24 };
    136static unsigned gpio25_pins[] = { 25 };
    137static unsigned gpio26_pins[] = { 26 };
    138static unsigned gpio27_pins[] = { 27 };
    139static unsigned gpio28_pins[] = { 28 };
    140static unsigned gpio29_pins[] = { 29 };
    141static unsigned gpio30_pins[] = { 30 };
    142static unsigned gpio31_pins[] = { 31 };
    143static unsigned gpio32_pins[] = { 32 };
    144static unsigned gpio33_pins[] = { 33 };
    145static unsigned gpio34_pins[] = { 34 };
    146static unsigned gpio35_pins[] = { 35 };
    147static unsigned gpio36_pins[] = { 36 };
    148static unsigned gpio37_pins[] = { 37 };
    149static unsigned gpio38_pins[] = { 38 };
    150static unsigned gpio39_pins[] = { 39 };
    151static unsigned gpio40_pins[] = { 40 };
    152static unsigned gpio41_pins[] = { 41 };
    153static unsigned gpio42_pins[] = { 42 };
    154static unsigned gpio43_pins[] = { 43 };
    155static unsigned gpio44_pins[] = { 44 };
    156static unsigned gpio45_pins[] = { 45 };
    157static unsigned gpio46_pins[] = { 46 };
    158static unsigned gpio47_pins[] = { 47 };
    159
    160static unsigned nand_grp_pins[] = {
    161	8, 12, 13, 14, 15, 16, 17,
    162	18, 19, 20, 21, 22, 23, 27,
    163};
    164
    165#define BCM6362_GROUP(n)				\
    166	{						\
    167		.name = #n,				\
    168		.pins = n##_pins,			\
    169		.num_pins = ARRAY_SIZE(n##_pins),	\
    170	}
    171
    172static struct bcm6362_pingroup bcm6362_groups[] = {
    173	BCM6362_GROUP(gpio0),
    174	BCM6362_GROUP(gpio1),
    175	BCM6362_GROUP(gpio2),
    176	BCM6362_GROUP(gpio3),
    177	BCM6362_GROUP(gpio4),
    178	BCM6362_GROUP(gpio5),
    179	BCM6362_GROUP(gpio6),
    180	BCM6362_GROUP(gpio7),
    181	BCM6362_GROUP(gpio8),
    182	BCM6362_GROUP(gpio9),
    183	BCM6362_GROUP(gpio10),
    184	BCM6362_GROUP(gpio11),
    185	BCM6362_GROUP(gpio12),
    186	BCM6362_GROUP(gpio13),
    187	BCM6362_GROUP(gpio14),
    188	BCM6362_GROUP(gpio15),
    189	BCM6362_GROUP(gpio16),
    190	BCM6362_GROUP(gpio17),
    191	BCM6362_GROUP(gpio18),
    192	BCM6362_GROUP(gpio19),
    193	BCM6362_GROUP(gpio20),
    194	BCM6362_GROUP(gpio21),
    195	BCM6362_GROUP(gpio22),
    196	BCM6362_GROUP(gpio23),
    197	BCM6362_GROUP(gpio24),
    198	BCM6362_GROUP(gpio25),
    199	BCM6362_GROUP(gpio26),
    200	BCM6362_GROUP(gpio27),
    201	BCM6362_GROUP(gpio28),
    202	BCM6362_GROUP(gpio29),
    203	BCM6362_GROUP(gpio30),
    204	BCM6362_GROUP(gpio31),
    205	BCM6362_GROUP(gpio32),
    206	BCM6362_GROUP(gpio33),
    207	BCM6362_GROUP(gpio34),
    208	BCM6362_GROUP(gpio35),
    209	BCM6362_GROUP(gpio36),
    210	BCM6362_GROUP(gpio37),
    211	BCM6362_GROUP(gpio38),
    212	BCM6362_GROUP(gpio39),
    213	BCM6362_GROUP(gpio40),
    214	BCM6362_GROUP(gpio41),
    215	BCM6362_GROUP(gpio42),
    216	BCM6362_GROUP(gpio43),
    217	BCM6362_GROUP(gpio44),
    218	BCM6362_GROUP(gpio45),
    219	BCM6362_GROUP(gpio46),
    220	BCM6362_GROUP(gpio47),
    221	BCM6362_GROUP(nand_grp),
    222};
    223
    224static const char * const led_groups[] = {
    225	"gpio0",
    226	"gpio1",
    227	"gpio2",
    228	"gpio3",
    229	"gpio4",
    230	"gpio5",
    231	"gpio6",
    232	"gpio7",
    233	"gpio8",
    234	"gpio9",
    235	"gpio10",
    236	"gpio11",
    237	"gpio12",
    238	"gpio13",
    239	"gpio14",
    240	"gpio15",
    241	"gpio16",
    242	"gpio17",
    243	"gpio18",
    244	"gpio19",
    245	"gpio20",
    246	"gpio21",
    247	"gpio22",
    248	"gpio23",
    249};
    250
    251static const char * const usb_device_led_groups[] = {
    252	"gpio0",
    253};
    254
    255static const char * const sys_irq_groups[] = {
    256	"gpio1",
    257};
    258
    259static const char * const serial_led_clk_groups[] = {
    260	"gpio2",
    261};
    262
    263static const char * const serial_led_data_groups[] = {
    264	"gpio3",
    265};
    266
    267static const char * const robosw_led_data_groups[] = {
    268	"gpio4",
    269};
    270
    271static const char * const robosw_led_clk_groups[] = {
    272	"gpio5",
    273};
    274
    275static const char * const robosw_led0_groups[] = {
    276	"gpio6",
    277};
    278
    279static const char * const robosw_led1_groups[] = {
    280	"gpio7",
    281};
    282
    283static const char * const inet_led_groups[] = {
    284	"gpio8",
    285};
    286
    287static const char * const spi_cs2_groups[] = {
    288	"gpio9",
    289};
    290
    291static const char * const spi_cs3_groups[] = {
    292	"gpio10",
    293};
    294
    295static const char * const ntr_pulse_groups[] = {
    296	"gpio11",
    297};
    298
    299static const char * const uart1_scts_groups[] = {
    300	"gpio12",
    301};
    302
    303static const char * const uart1_srts_groups[] = {
    304	"gpio13",
    305};
    306
    307static const char * const uart1_sdin_groups[] = {
    308	"gpio14",
    309};
    310
    311static const char * const uart1_sdout_groups[] = {
    312	"gpio15",
    313};
    314
    315static const char * const adsl_spi_miso_groups[] = {
    316	"gpio16",
    317};
    318
    319static const char * const adsl_spi_mosi_groups[] = {
    320	"gpio17",
    321};
    322
    323static const char * const adsl_spi_clk_groups[] = {
    324	"gpio18",
    325};
    326
    327static const char * const adsl_spi_cs_groups[] = {
    328	"gpio19",
    329};
    330
    331static const char * const ephy0_led_groups[] = {
    332	"gpio20",
    333};
    334
    335static const char * const ephy1_led_groups[] = {
    336	"gpio21",
    337};
    338
    339static const char * const ephy2_led_groups[] = {
    340	"gpio22",
    341};
    342
    343static const char * const ephy3_led_groups[] = {
    344	"gpio23",
    345};
    346
    347static const char * const ext_irq0_groups[] = {
    348	"gpio24",
    349};
    350
    351static const char * const ext_irq1_groups[] = {
    352	"gpio25",
    353};
    354
    355static const char * const ext_irq2_groups[] = {
    356	"gpio26",
    357};
    358
    359static const char * const ext_irq3_groups[] = {
    360	"gpio27",
    361};
    362
    363static const char * const wifi_groups[] = {
    364	"gpio32",
    365	"gpio33",
    366	"gpio34",
    367	"gpio35",
    368	"gpio36",
    369	"gpio37",
    370	"gpio38",
    371	"gpio39",
    372	"gpio40",
    373	"gpio41",
    374	"gpio42",
    375	"gpio43",
    376	"gpio44",
    377	"gpio45",
    378	"gpio46",
    379	"gpio47",
    380};
    381
    382static const char * const nand_groups[] = {
    383	"nand_grp",
    384};
    385
    386#define BCM6362_LED_FUN(n)				\
    387	{						\
    388		.name = #n,				\
    389		.groups = n##_groups,			\
    390		.num_groups = ARRAY_SIZE(n##_groups),	\
    391		.reg = BCM6362_LEDCTRL,			\
    392	}
    393
    394#define BCM6362_MODE_FUN(n)				\
    395	{						\
    396		.name = #n,				\
    397		.groups = n##_groups,			\
    398		.num_groups = ARRAY_SIZE(n##_groups),	\
    399		.reg = BCM6362_MODE,			\
    400	}
    401
    402#define BCM6362_CTRL_FUN(n)				\
    403	{						\
    404		.name = #n,				\
    405		.groups = n##_groups,			\
    406		.num_groups = ARRAY_SIZE(n##_groups),	\
    407		.reg = BCM6362_CTRL,			\
    408	}
    409
    410#define BCM6362_BASEMODE_FUN(n, mask)			\
    411	{						\
    412		.name = #n,				\
    413		.groups = n##_groups,			\
    414		.num_groups = ARRAY_SIZE(n##_groups),	\
    415		.reg = BCM6362_BASEMODE,		\
    416		.basemode_mask = (mask),		\
    417	}
    418
    419static const struct bcm6362_function bcm6362_funcs[] = {
    420	BCM6362_LED_FUN(led),
    421	BCM6362_MODE_FUN(usb_device_led),
    422	BCM6362_MODE_FUN(sys_irq),
    423	BCM6362_MODE_FUN(serial_led_clk),
    424	BCM6362_MODE_FUN(serial_led_data),
    425	BCM6362_MODE_FUN(robosw_led_data),
    426	BCM6362_MODE_FUN(robosw_led_clk),
    427	BCM6362_MODE_FUN(robosw_led0),
    428	BCM6362_MODE_FUN(robosw_led1),
    429	BCM6362_MODE_FUN(inet_led),
    430	BCM6362_MODE_FUN(spi_cs2),
    431	BCM6362_MODE_FUN(spi_cs3),
    432	BCM6362_MODE_FUN(ntr_pulse),
    433	BCM6362_MODE_FUN(uart1_scts),
    434	BCM6362_MODE_FUN(uart1_srts),
    435	BCM6362_MODE_FUN(uart1_sdin),
    436	BCM6362_MODE_FUN(uart1_sdout),
    437	BCM6362_MODE_FUN(adsl_spi_miso),
    438	BCM6362_MODE_FUN(adsl_spi_mosi),
    439	BCM6362_MODE_FUN(adsl_spi_clk),
    440	BCM6362_MODE_FUN(adsl_spi_cs),
    441	BCM6362_MODE_FUN(ephy0_led),
    442	BCM6362_MODE_FUN(ephy1_led),
    443	BCM6362_MODE_FUN(ephy2_led),
    444	BCM6362_MODE_FUN(ephy3_led),
    445	BCM6362_MODE_FUN(ext_irq0),
    446	BCM6362_MODE_FUN(ext_irq1),
    447	BCM6362_MODE_FUN(ext_irq2),
    448	BCM6362_MODE_FUN(ext_irq3),
    449	BCM6362_CTRL_FUN(wifi),
    450	BCM6362_BASEMODE_FUN(nand, BASEMODE_NAND),
    451};
    452
    453static int bcm6362_pinctrl_get_group_count(struct pinctrl_dev *pctldev)
    454{
    455	return ARRAY_SIZE(bcm6362_groups);
    456}
    457
    458static const char *bcm6362_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
    459						  unsigned group)
    460{
    461	return bcm6362_groups[group].name;
    462}
    463
    464static int bcm6362_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
    465					  unsigned group, const unsigned **pins,
    466					  unsigned *num_pins)
    467{
    468	*pins = bcm6362_groups[group].pins;
    469	*num_pins = bcm6362_groups[group].num_pins;
    470
    471	return 0;
    472}
    473
    474static int bcm6362_pinctrl_get_func_count(struct pinctrl_dev *pctldev)
    475{
    476	return ARRAY_SIZE(bcm6362_funcs);
    477}
    478
    479static const char *bcm6362_pinctrl_get_func_name(struct pinctrl_dev *pctldev,
    480						 unsigned selector)
    481{
    482	return bcm6362_funcs[selector].name;
    483}
    484
    485static int bcm6362_pinctrl_get_groups(struct pinctrl_dev *pctldev,
    486				      unsigned selector,
    487				      const char * const **groups,
    488				      unsigned * const num_groups)
    489{
    490	*groups = bcm6362_funcs[selector].groups;
    491	*num_groups = bcm6362_funcs[selector].num_groups;
    492
    493	return 0;
    494}
    495
    496static void bcm6362_set_gpio(struct bcm63xx_pinctrl *pc, unsigned pin)
    497{
    498	const struct pinctrl_pin_desc *desc = &bcm6362_pins[pin];
    499	unsigned int basemode = (uintptr_t)desc->drv_data;
    500	unsigned int mask = bcm63xx_bank_pin(pin);
    501
    502	if (basemode)
    503		regmap_update_bits(pc->regs, BCM6362_BASEMODE_REG, basemode, 0);
    504
    505	if (pin < BCM63XX_BANK_GPIOS) {
    506		/* base mode 0 => gpio 1 => mux function */
    507		regmap_update_bits(pc->regs, BCM6362_MODE_REG, mask, 0);
    508
    509		/* pins 0-23 might be muxed to led */
    510		if (pin < BCM6362_NUM_LEDS)
    511			regmap_update_bits(pc->regs, BCM6362_LED_REG, mask, 0);
    512	} else {
    513		/* ctrl reg 0 => wifi function 1 => gpio */
    514		regmap_update_bits(pc->regs, BCM6362_CTRL_REG, mask, mask);
    515	}
    516}
    517
    518static int bcm6362_pinctrl_set_mux(struct pinctrl_dev *pctldev,
    519				   unsigned selector, unsigned group)
    520{
    521	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
    522	const struct bcm6362_pingroup *pg = &bcm6362_groups[group];
    523	const struct bcm6362_function *f = &bcm6362_funcs[selector];
    524	unsigned i;
    525	unsigned int reg;
    526	unsigned int val, mask;
    527
    528	for (i = 0; i < pg->num_pins; i++)
    529		bcm6362_set_gpio(pc, pg->pins[i]);
    530
    531	switch (f->reg) {
    532	case BCM6362_LEDCTRL:
    533		reg = BCM6362_LED_REG;
    534		mask = BIT(pg->pins[0]);
    535		val = BIT(pg->pins[0]);
    536		break;
    537	case BCM6362_MODE:
    538		reg = BCM6362_MODE_REG;
    539		mask = BIT(pg->pins[0]);
    540		val = BIT(pg->pins[0]);
    541		break;
    542	case BCM6362_CTRL:
    543		reg = BCM6362_CTRL_REG;
    544		mask = BIT(pg->pins[0]);
    545		val = 0;
    546		break;
    547	case BCM6362_BASEMODE:
    548		reg = BCM6362_BASEMODE_REG;
    549		mask = f->basemode_mask;
    550		val = f->basemode_mask;
    551		break;
    552	default:
    553		WARN_ON(1);
    554		return -EINVAL;
    555	}
    556
    557	regmap_update_bits(pc->regs, reg, mask, val);
    558
    559	return 0;
    560}
    561
    562static int bcm6362_gpio_request_enable(struct pinctrl_dev *pctldev,
    563				       struct pinctrl_gpio_range *range,
    564				       unsigned offset)
    565{
    566	struct bcm63xx_pinctrl *pc = pinctrl_dev_get_drvdata(pctldev);
    567
    568	/* disable all functions using this pin */
    569	bcm6362_set_gpio(pc, offset);
    570
    571	return 0;
    572}
    573
    574static const struct pinctrl_ops bcm6362_pctl_ops = {
    575	.dt_free_map = pinctrl_utils_free_map,
    576	.dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
    577	.get_group_name = bcm6362_pinctrl_get_group_name,
    578	.get_group_pins = bcm6362_pinctrl_get_group_pins,
    579	.get_groups_count = bcm6362_pinctrl_get_group_count,
    580};
    581
    582static const struct pinmux_ops bcm6362_pmx_ops = {
    583	.get_function_groups = bcm6362_pinctrl_get_groups,
    584	.get_function_name = bcm6362_pinctrl_get_func_name,
    585	.get_functions_count = bcm6362_pinctrl_get_func_count,
    586	.gpio_request_enable = bcm6362_gpio_request_enable,
    587	.set_mux = bcm6362_pinctrl_set_mux,
    588	.strict = true,
    589};
    590
    591static const struct bcm63xx_pinctrl_soc bcm6362_soc = {
    592	.ngpios = BCM6362_NUM_GPIOS,
    593	.npins = ARRAY_SIZE(bcm6362_pins),
    594	.pctl_ops = &bcm6362_pctl_ops,
    595	.pins = bcm6362_pins,
    596	.pmx_ops = &bcm6362_pmx_ops,
    597};
    598
    599static int bcm6362_pinctrl_probe(struct platform_device *pdev)
    600{
    601	return bcm63xx_pinctrl_probe(pdev, &bcm6362_soc, NULL);
    602}
    603
    604static const struct of_device_id bcm6362_pinctrl_match[] = {
    605	{ .compatible = "brcm,bcm6362-pinctrl", },
    606	{ /* sentinel */ }
    607};
    608
    609static struct platform_driver bcm6362_pinctrl_driver = {
    610	.probe = bcm6362_pinctrl_probe,
    611	.driver = {
    612		.name = "bcm6362-pinctrl",
    613		.of_match_table = bcm6362_pinctrl_match,
    614	},
    615};
    616
    617builtin_platform_driver(bcm6362_pinctrl_driver);