blob: 0c0b54d73a402e8397fd26814cf58e2ce7d79ce6 [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Po Xuf71f1792018-07-16 18:41:49 +08002
Kyösti Mälkki13f66502019-03-03 08:01:05 +02003#include <device/mmio.h>
Po Xuf71f1792018-07-16 18:41:49 +08004#include <gpio.h>
Mengqi Zhang89b17532019-04-24 10:14:52 +08005#include <assert.h>
6#include <soc/spi.h>
Po Xuf71f1792018-07-16 18:41:49 +08007
8enum {
9 EN_OFFSET = 0x60,
10 SEL_OFFSET = 0x80,
jg_poxu9e21b2d2019-01-31 15:46:03 +080011 EH_RSEL_OFFSET = 0xF0,
Mengqi Zhang89b17532019-04-24 10:14:52 +080012 GPIO_DRV0_OFFSET = 0xA0,
Subrata Banik8e6d5f22020-08-30 13:51:44 +053013 GPIO_DRV1_OFFSET = 0xB0,
Po Xuf71f1792018-07-16 18:41:49 +080014};
15
16static 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)
Julius Werner55009af2019-12-02 22:03:27 -080024 setbits32(reg, 1 << (bit + 2));
Po Xuf71f1792018-07-16 18:41:49 +080025 else
Julius Werner55009af2019-12-02 22:03:27 -080026 clrbits32(reg, 1 << (bit + 2));
Po Xuf71f1792018-07-16 18:41:49 +080027 }
28
29 if (enable == GPIO_PULL_ENABLE)
Julius Werner55009af2019-12-02 22:03:27 -080030 clrsetbits32(reg, 3 << bit, 1 << bit);
Po Xuf71f1792018-07-16 18:41:49 +080031 else
Julius Werner55009af2019-12-02 22:03:27 -080032 clrbits32(reg, 3 << bit);
Po Xuf71f1792018-07-16 18:41:49 +080033}
34
35static 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)
Julius Werner55009af2019-12-02 22:03:27 -080043 clrbits32(reg + SEL_OFFSET, 1 << bit);
Po Xuf71f1792018-07-16 18:41:49 +080044 else
Julius Werner55009af2019-12-02 22:03:27 -080045 setbits32(reg + SEL_OFFSET, 1 << bit);
Po Xuf71f1792018-07-16 18:41:49 +080046 }
47
48 if (enable == GPIO_PULL_ENABLE)
Julius Werner55009af2019-12-02 22:03:27 -080049 setbits32(reg + EN_OFFSET, 1 << bit);
Po Xuf71f1792018-07-16 18:41:49 +080050 else
Julius Werner55009af2019-12-02 22:03:27 -080051 clrbits32(reg + EN_OFFSET, 1 << bit);
Po Xuf71f1792018-07-16 18:41:49 +080052}
53
54void 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}
jg_poxu9e21b2d2019-01-31 15:46:03 +080062
63enum {
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
100void gpio_set_i2c_eh_rsel(void)
101{
Julius Werner55009af2019-12-02 22:03:27 -0800102 clrsetbits32((void *)IOCFG_RB_BASE + EH_RSEL_OFFSET,
jg_poxu9e21b2d2019-01-31 15:46:03 +0800103 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
Julius Werner55009af2019-12-02 22:03:27 -0800108 clrsetbits32((void *)IOCFG_RM_BASE + EH_RSEL_OFFSET,
jg_poxu9e21b2d2019-01-31 15:46:03 +0800109 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
Julius Werner55009af2019-12-02 22:03:27 -0800114 clrsetbits32((void *)IOCFG_BL_BASE + EH_RSEL_OFFSET,
jg_poxu9e21b2d2019-01-31 15:46:03 +0800115 I2C_EH_RSL_MASK(SCL3) | I2C_EH_RSL_MASK(SDA3),
116 I2C_EH_RSL_VAL(SCL3) | I2C_EH_RSL_VAL(SDA3));
117
Julius Werner55009af2019-12-02 22:03:27 -0800118 clrsetbits32((void *)IOCFG_LB_BASE + EH_RSEL_OFFSET,
jg_poxu9e21b2d2019-01-31 15:46:03 +0800119 I2C_EH_RSL_MASK(SCL5) | I2C_EH_RSL_MASK(SDA5),
120 I2C_EH_RSL_VAL(SCL5) | I2C_EH_RSL_VAL(SDA5));
121}
Mengqi Zhang89b17532019-04-24 10:14:52 +0800122
123void 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) {
Julius Werner55009af2019-12-02 22:03:27 -0800143 clrsetbits32((void *)IOCFG_RM_BASE +
Mengqi Zhang89b17532019-04-24 10:14:52 +0800144 GPIO_DRV0_OFFSET, 0xf | 0xf << 20,
145 reg_val | reg_val << 20);
Julius Werner55009af2019-12-02 22:03:27 -0800146 clrsetbits32((void *)IOCFG_RM_BASE +
Mengqi Zhang89b17532019-04-24 10:14:52 +0800147 GPIO_DRV1_OFFSET, 0xf << 16,
148 reg_val << 16);
149 return;
150 }
151 break;
152 case 2:
Julius Werner55009af2019-12-02 22:03:27 -0800153 clrsetbits32((void *)IOCFG_RM_BASE + GPIO_DRV0_OFFSET,
Mengqi Zhang89b17532019-04-24 10:14:52 +0800154 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
Julius Werner55009af2019-12-02 22:03:27 -0800171 clrsetbits32(reg, 0xf << offset, reg_val << offset);
Mengqi Zhang89b17532019-04-24 10:14:52 +0800172}