1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <device/mmio.h>
4 #include <gpio.h>
5 #include <assert.h>
6 #include <soc/spi.h>
7
8 enum {
9 EN_OFFSET = 0x60,
10 SEL_OFFSET = 0x80,
11 EH_RSEL_OFFSET = 0xF0,
12 GPIO_DRV0_OFFSET = 0xA0,
13 GPIO_DRV1_OFFSET = 0xB0,
14 };
15
gpio_set_pull_pupd(gpio_t gpio,enum pull_enable enable,enum pull_select select)16 static void gpio_set_pull_pupd(gpio_t gpio, enum pull_enable enable,
17 enum pull_select select)
18 {
19 void *reg = GPIO_TO_IOCFG_BASE(gpio.base) + gpio.offset;
20 int bit = gpio.bit;
21
22 if (enable == GPIO_PULL_ENABLE) {
23 if (select == GPIO_PULL_DOWN)
24 setbits32(reg, 1 << (bit + 2));
25 else
26 clrbits32(reg, 1 << (bit + 2));
27 }
28
29 if (enable == GPIO_PULL_ENABLE)
30 clrsetbits32(reg, 3 << bit, 1 << bit);
31 else
32 clrbits32(reg, 3 << bit);
33 }
34
gpio_set_pull_en_sel(gpio_t gpio,enum pull_enable enable,enum pull_select select)35 static void gpio_set_pull_en_sel(gpio_t gpio, enum pull_enable enable,
36 enum pull_select select)
37 {
38 void *reg = GPIO_TO_IOCFG_BASE(gpio.base) + gpio.offset;
39 int bit = gpio.bit;
40
41 if (enable == GPIO_PULL_ENABLE) {
42 if (select == GPIO_PULL_DOWN)
43 clrbits32(reg + SEL_OFFSET, 1 << bit);
44 else
45 setbits32(reg + SEL_OFFSET, 1 << bit);
46 }
47
48 if (enable == GPIO_PULL_ENABLE)
49 setbits32(reg + EN_OFFSET, 1 << bit);
50 else
51 clrbits32(reg + EN_OFFSET, 1 << bit);
52 }
53
gpio_set_pull(gpio_t gpio,enum pull_enable enable,enum pull_select select)54 void gpio_set_pull(gpio_t gpio, enum pull_enable enable,
55 enum pull_select select)
56 {
57 if (gpio.flag)
58 gpio_set_pull_pupd(gpio, enable, select);
59 else
60 gpio_set_pull_en_sel(gpio, enable, select);
61 }
62
63 enum {
64 EH_VAL = 0x0,
65 RSEL_VAL = 0x3,
66 EH_MASK = 0x7,
67 RSEL_MASK = 0x3,
68 SCL0_EH = 19,
69 SCL0_RSEL = 15,
70 SDA0_EH = 9,
71 SDA0_RSEL = 5,
72 SCL1_EH = 22,
73 SCL1_RSEL = 17,
74 SDA1_EH = 12,
75 SDA1_RSEL = 7,
76 SCL2_EH = 24,
77 SCL2_RSEL = 20,
78 SDA2_EH = 14,
79 SDA2_RSEL = 10,
80 SCL3_EH = 12,
81 SCL3_RSEL = 10,
82 SDA3_EH = 7,
83 SDA3_RSEL = 5,
84 SCL4_EH = 27,
85 SCL4_RSEL = 22,
86 SDA4_EH = 17,
87 SDA4_RSEL = 12,
88 SCL5_EH = 20,
89 SCL5_RSEL = 18,
90 SDA5_EH = 15,
91 SDA5_RSEL = 13,
92 };
93
94 #define I2C_EH_RSL_MASK(name) \
95 (EH_MASK << name##_EH | RSEL_MASK << name##_RSEL)
96
97 #define I2C_EH_RSL_VAL(name) \
98 (EH_VAL << name##_EH | RSEL_VAL << name##_RSEL)
99
gpio_set_i2c_eh_rsel(void)100 void gpio_set_i2c_eh_rsel(void)
101 {
102 clrsetbits32((void *)IOCFG_RB_BASE + EH_RSEL_OFFSET,
103 I2C_EH_RSL_MASK(SCL0) | I2C_EH_RSL_MASK(SDA0) |
104 I2C_EH_RSL_MASK(SCL1) | I2C_EH_RSL_MASK(SDA1),
105 I2C_EH_RSL_VAL(SCL0) | I2C_EH_RSL_VAL(SDA0) |
106 I2C_EH_RSL_VAL(SCL1) | I2C_EH_RSL_VAL(SDA1));
107
108 clrsetbits32((void *)IOCFG_RM_BASE + EH_RSEL_OFFSET,
109 I2C_EH_RSL_MASK(SCL2) | I2C_EH_RSL_MASK(SDA2) |
110 I2C_EH_RSL_MASK(SCL4) | I2C_EH_RSL_MASK(SDA4),
111 I2C_EH_RSL_VAL(SCL2) | I2C_EH_RSL_VAL(SDA2) |
112 I2C_EH_RSL_VAL(SCL4) | I2C_EH_RSL_VAL(SDA4));
113
114 clrsetbits32((void *)IOCFG_BL_BASE + EH_RSEL_OFFSET,
115 I2C_EH_RSL_MASK(SCL3) | I2C_EH_RSL_MASK(SDA3),
116 I2C_EH_RSL_VAL(SCL3) | I2C_EH_RSL_VAL(SDA3));
117
118 clrsetbits32((void *)IOCFG_LB_BASE + EH_RSEL_OFFSET,
119 I2C_EH_RSL_MASK(SCL5) | I2C_EH_RSL_MASK(SDA5),
120 I2C_EH_RSL_VAL(SCL5) | I2C_EH_RSL_VAL(SDA5));
121 }
122
gpio_set_spi_driving(unsigned int bus,enum spi_pad_mask pad_select,unsigned int milliamps)123 void gpio_set_spi_driving(unsigned int bus, enum spi_pad_mask pad_select,
124 unsigned int milliamps)
125 {
126 void *reg = NULL;
127 unsigned int reg_val = milliamps / 2 - 1, offset = 0;
128
129 assert(bus < SPI_BUS_NUMBER);
130 assert(milliamps >= 2 && milliamps <= 16);
131 assert(pad_select <= SPI_PAD1_MASK);
132
133 switch (bus) {
134 case 0:
135 reg = (void *)(IOCFG_RB_BASE + GPIO_DRV1_OFFSET);
136 offset = 0;
137 break;
138 case 1:
139 if (pad_select == SPI_PAD0_MASK) {
140 reg = (void *)(IOCFG_LM_BASE + GPIO_DRV0_OFFSET);
141 offset = 0;
142 } else if (pad_select == SPI_PAD1_MASK) {
143 clrsetbits32((void *)IOCFG_RM_BASE +
144 GPIO_DRV0_OFFSET, 0xf | 0xf << 20,
145 reg_val | reg_val << 20);
146 clrsetbits32((void *)IOCFG_RM_BASE +
147 GPIO_DRV1_OFFSET, 0xf << 16,
148 reg_val << 16);
149 return;
150 }
151 break;
152 case 2:
153 clrsetbits32((void *)IOCFG_RM_BASE + GPIO_DRV0_OFFSET,
154 0xf << 8 | 0xf << 12,
155 reg_val << 8 | reg_val << 12);
156 return;
157 case 3:
158 reg = (void *)(IOCFG_LM_BASE + GPIO_DRV0_OFFSET);
159 offset = 16;
160 break;
161 case 4:
162 reg = (void *)(IOCFG_LM_BASE + GPIO_DRV0_OFFSET);
163 offset = 12;
164 break;
165 case 5:
166 reg = (void *)(IOCFG_LM_BASE + GPIO_DRV0_OFFSET);
167 offset = 8;
168 break;
169 }
170
171 clrsetbits32(reg, 0xf << offset, reg_val << offset);
172 }
173