1 /* 2 * Copyright (c) 2020, MediaTek Inc. All rights reserved. 3 * 4 * SPDX-License-Identifier: BSD-3-Clause 5 */ 6 7 #include <assert.h> 8 #include <common/debug.h> 9 #include <drivers/delay_timer.h> 10 #include <drivers/gpio.h> 11 #include <lib/mmio.h> 12 #include <mtgpio.h> 13 #include <platform_def.h> 14 15 /****************************************************************************** 16 *Macro Definition 17 ******************************************************************************/ 18 #define GPIO_MODE_BITS 4 19 #define MAX_GPIO_MODE_PER_REG 8 20 #define MAX_GPIO_REG_BITS 32 21 #define DIR_BASE (GPIO_BASE + 0x000) 22 #define DOUT_BASE (GPIO_BASE + 0x100) 23 #define DIN_BASE (GPIO_BASE + 0x200) 24 #define MODE_BASE (GPIO_BASE + 0x300) 25 #define SET 0x4 26 #define CLR 0x8 27 28 static void mt_set_gpio_dir_chip(uint32_t pin, int dir) 29 { 30 uint32_t pos, bit; 31 32 assert(pin < MAX_GPIO_PIN); 33 assert(dir < MT_GPIO_DIR_MAX); 34 35 pos = pin / MAX_GPIO_REG_BITS; 36 bit = pin % MAX_GPIO_REG_BITS; 37 38 if (dir == MT_GPIO_DIR_IN) { 39 mmio_write_32(DIR_BASE + 0x10U * pos + CLR, 1U << bit); 40 } else { 41 mmio_write_32(DIR_BASE + 0x10U * pos + SET, 1U << bit); 42 } 43 } 44 45 static int mt_get_gpio_dir_chip(uint32_t pin) 46 { 47 uint32_t pos, bit; 48 uint32_t reg; 49 50 assert(pin < MAX_GPIO_PIN); 51 52 pos = pin / MAX_GPIO_REG_BITS; 53 bit = pin % MAX_GPIO_REG_BITS; 54 55 reg = mmio_read_32(DIR_BASE + 0x10U * pos); 56 return (((reg & (1U << bit)) != 0U) ? MT_GPIO_DIR_OUT : MT_GPIO_DIR_IN); 57 } 58 59 static void mt_set_gpio_out_chip(uint32_t pin, int output) 60 { 61 uint32_t pos, bit; 62 63 assert(pin < MAX_GPIO_PIN); 64 assert(output < MT_GPIO_OUT_MAX); 65 66 pos = pin / MAX_GPIO_REG_BITS; 67 bit = pin % MAX_GPIO_REG_BITS; 68 69 if (output == MT_GPIO_OUT_ZERO) { 70 mmio_write_32(DOUT_BASE + 0x10U * pos + CLR, 1U << bit); 71 } else { 72 mmio_write_32(DOUT_BASE + 0x10U * pos + SET, 1U << bit); 73 } 74 } 75 76 static int mt_get_gpio_in_chip(uint32_t pin) 77 { 78 uint32_t pos, bit; 79 uint32_t reg; 80 81 assert(pin < MAX_GPIO_PIN); 82 83 pos = pin / MAX_GPIO_REG_BITS; 84 bit = pin % MAX_GPIO_REG_BITS; 85 86 reg = mmio_read_32(DIN_BASE + 0x10U * pos); 87 return (((reg & (1U << bit)) != 0U) ? 1 : 0); 88 } 89 90 static uintptr_t mt_gpio_find_reg_addr(uint32_t pin) 91 { 92 uintptr_t reg_addr = 0U; 93 struct mt_pin_info gpio_info; 94 95 gpio_info = mt8192_pin_infos[pin]; 96 97 switch (gpio_info.base & 0x0f) { 98 case 0: 99 reg_addr = IOCFG_RM_BASE; 100 break; 101 case 1: 102 reg_addr = IOCFG_BM_BASE; 103 break; 104 case 2: 105 reg_addr = IOCFG_BL_BASE; 106 break; 107 case 3: 108 reg_addr = IOCFG_BR_BASE; 109 break; 110 case 4: 111 reg_addr = IOCFG_LM_BASE; 112 break; 113 case 5: 114 reg_addr = IOCFG_LB_BASE; 115 break; 116 case 6: 117 reg_addr = IOCFG_RT_BASE; 118 break; 119 case 7: 120 reg_addr = IOCFG_LT_BASE; 121 break; 122 case 8: 123 reg_addr = IOCFG_TL_BASE; 124 break; 125 default: 126 break; 127 } 128 129 return reg_addr; 130 } 131 132 static void mt_gpio_set_spec_pull_pupd(uint32_t pin, int enable, 133 int select) 134 { 135 uintptr_t reg1; 136 uintptr_t reg2; 137 struct mt_pin_info gpio_info; 138 139 gpio_info = mt8192_pin_infos[pin]; 140 uint32_t bit = gpio_info.bit; 141 142 reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; 143 reg2 = reg1 + (gpio_info.base & 0xf0); 144 if (enable == MT_GPIO_PULL_ENABLE) { 145 mmio_write_32(reg2 + SET, (1U << bit)); 146 if (select == MT_GPIO_PULL_DOWN) { 147 mmio_write_32(reg1 + SET, (1U << bit)); 148 } else { 149 mmio_write_32(reg1 + CLR, (1U << bit)); 150 } 151 } else { 152 mmio_write_32(reg2 + CLR, (1U << bit)); 153 mmio_write_32((reg2 + 0x010U) + CLR, (1U << bit)); 154 } 155 } 156 157 static void mt_gpio_set_pull_pu_pd(uint32_t pin, int enable, 158 int select) 159 { 160 uintptr_t reg1; 161 uintptr_t reg2; 162 struct mt_pin_info gpio_info; 163 164 gpio_info = mt8192_pin_infos[pin]; 165 uint32_t bit = gpio_info.bit; 166 167 reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; 168 reg2 = reg1 - (gpio_info.base & 0xf0); 169 170 if (enable == MT_GPIO_PULL_ENABLE) { 171 if (select == MT_GPIO_PULL_DOWN) { 172 mmio_write_32(reg1 + CLR, (1U << bit)); 173 mmio_write_32(reg2 + SET, (1U << bit)); 174 } else { 175 mmio_write_32(reg2 + CLR, (1U << bit)); 176 mmio_write_32(reg1 + SET, (1U << bit)); 177 } 178 } else { 179 mmio_write_32(reg1 + CLR, (1U << bit)); 180 mmio_write_32(reg2 + CLR, (1U << bit)); 181 } 182 } 183 184 static void mt_gpio_set_pull_chip(uint32_t pin, int enable, 185 int select) 186 { 187 struct mt_pin_info gpio_info; 188 189 gpio_info = mt8192_pin_infos[pin]; 190 if (gpio_info.flag) { 191 mt_gpio_set_spec_pull_pupd(pin, enable, select); 192 } else { 193 mt_gpio_set_pull_pu_pd(pin, enable, select); 194 } 195 } 196 197 static int mt_gpio_get_spec_pull_pupd(uint32_t pin) 198 { 199 uintptr_t reg1; 200 uintptr_t reg2; 201 uint32_t r0; 202 uint32_t r1; 203 204 struct mt_pin_info gpio_info; 205 206 gpio_info = mt8192_pin_infos[pin]; 207 uint32_t bit = gpio_info.bit; 208 209 reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; 210 reg2 = reg1 + (gpio_info.base & 0xf0); 211 212 r0 = (mmio_read_32(reg2) >> bit) & 1U; 213 r1 = (mmio_read_32(reg2 + 0x010) >> bit) & 1U; 214 if (r0 == 0U && r1 == 0U) { 215 return MT_GPIO_PULL_NONE; 216 } else { 217 if (mmio_read_32(reg1) & (1U << bit)) { 218 return MT_GPIO_PULL_DOWN; 219 } else { 220 return MT_GPIO_PULL_UP; 221 } 222 } 223 } 224 225 static int mt_gpio_get_pull_pu_pd(uint32_t pin) 226 { 227 uintptr_t reg1; 228 uintptr_t reg2; 229 uint32_t pu; 230 uint32_t pd; 231 232 struct mt_pin_info gpio_info; 233 234 gpio_info = mt8192_pin_infos[pin]; 235 uint32_t bit = gpio_info.bit; 236 237 reg1 = mt_gpio_find_reg_addr(pin) + gpio_info.offset; 238 reg2 = reg1 - (gpio_info.base & 0xf0); 239 pu = (mmio_read_32(reg1) >> bit) & 1U; 240 pd = (mmio_read_32(reg2) >> bit) & 1U; 241 if (pu == 1U) { 242 return MT_GPIO_PULL_UP; 243 } else if (pd == 1U) { 244 return MT_GPIO_PULL_DOWN; 245 } else { 246 return MT_GPIO_PULL_NONE; 247 } 248 } 249 250 static int mt_gpio_get_pull_chip(uint32_t pin) 251 { 252 struct mt_pin_info gpio_info; 253 254 gpio_info = mt8192_pin_infos[pin]; 255 if (gpio_info.flag) { 256 return mt_gpio_get_spec_pull_pupd(pin); 257 } else { 258 return mt_gpio_get_pull_pu_pd(pin); 259 } 260 } 261 262 static void mt_set_gpio_pull_select_chip(uint32_t pin, int sel) 263 { 264 assert(pin < MAX_GPIO_PIN); 265 266 if (sel == MT_GPIO_PULL_NONE) { 267 mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_DISABLE, MT_GPIO_PULL_DOWN); 268 } else if (sel == MT_GPIO_PULL_UP) { 269 mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_UP); 270 } else if (sel == MT_GPIO_PULL_DOWN) { 271 mt_gpio_set_pull_chip(pin, MT_GPIO_PULL_ENABLE, MT_GPIO_PULL_DOWN); 272 } 273 } 274 275 /* get pull-up or pull-down, regardless of resistor value */ 276 static int mt_get_gpio_pull_select_chip(uint32_t pin) 277 { 278 assert(pin < MAX_GPIO_PIN); 279 280 return mt_gpio_get_pull_chip(pin); 281 } 282 283 static void mt_set_gpio_dir(int gpio, int direction) 284 { 285 mt_set_gpio_dir_chip((uint32_t)gpio, direction); 286 } 287 288 static int mt_get_gpio_dir(int gpio) 289 { 290 uint32_t pin; 291 292 pin = (uint32_t)gpio; 293 return mt_get_gpio_dir_chip(pin); 294 } 295 296 static void mt_set_gpio_pull(int gpio, int pull) 297 { 298 uint32_t pin; 299 300 pin = (uint32_t)gpio; 301 mt_set_gpio_pull_select_chip(pin, pull); 302 } 303 304 static int mt_get_gpio_pull(int gpio) 305 { 306 uint32_t pin; 307 308 pin = (uint32_t)gpio; 309 return mt_get_gpio_pull_select_chip(pin); 310 } 311 312 static void mt_set_gpio_out(int gpio, int value) 313 { 314 uint32_t pin; 315 316 pin = (uint32_t)gpio; 317 mt_set_gpio_out_chip(pin, value); 318 } 319 320 static int mt_get_gpio_in(int gpio) 321 { 322 uint32_t pin; 323 324 pin = (uint32_t)gpio; 325 return mt_get_gpio_in_chip(pin); 326 } 327 328 const gpio_ops_t mtgpio_ops = { 329 .get_direction = mt_get_gpio_dir, 330 .set_direction = mt_set_gpio_dir, 331 .get_value = mt_get_gpio_in, 332 .set_value = mt_set_gpio_out, 333 .set_pull = mt_set_gpio_pull, 334 .get_pull = mt_get_gpio_pull, 335 }; 336 337 void plat_mt8192_gpio_init(void) 338 { 339 gpio_init(&mtgpio_ops); 340 } 341