1 // Copyright 2018 The Fuchsia Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include <soc/aml-s905/s905-gpio.h> 6 7 #include "aml-gxl-gpio.h" 8 9 namespace gpio { 10 11 constexpr AmlGpioBlock s905_gpio_blocks[] = { 12 // GPIOX Block 13 { 14 .pin_count = S905_GPIOX_PINS, 15 .oen_offset = S905_GPIOX_0EN, 16 .input_offset = S905_GPIOX_IN, 17 .output_offset = S905_GPIOX_OUT, 18 .output_shift = 0, 19 .mmio_index = 0, 20 .pull_offset = S905_PULL_UP_REG4, 21 .pull_en_offset = S905_PULL_UP_EN_REG4, 22 .pin_start = S905_GPIOX_PIN_START, 23 }, 24 // GPIOY Block 25 { 26 .pin_count = S905_GPIOY_PINS, 27 .oen_offset = S905_GPIOY_0EN, 28 .input_offset = S905_GPIOY_IN, 29 .output_offset = S905_GPIOY_OUT, 30 .output_shift = 0, 31 .mmio_index = 0, 32 .pull_offset = S905_PULL_UP_REG1, 33 .pull_en_offset = S905_PULL_UP_EN_REG1, 34 .pin_start = S905_GPIOY_PIN_START, 35 }, 36 // GPIOZ Block 37 { 38 .pin_count = S905_GPIOZ_PINS, 39 .oen_offset = S905_GPIOZ_0EN, 40 .input_offset = S905_GPIOZ_IN, 41 .output_offset = S905_GPIOZ_OUT, 42 .output_shift = 0, 43 .mmio_index = 0, 44 .pull_offset = 0, // not supported 45 .pull_en_offset = 0, // not supported 46 .pin_start = S905_GPIOZ_PIN_START, 47 }, 48 // GPIODV Block 49 { 50 .pin_count = S905_GPIODV_PINS, 51 .oen_offset = S905_GPIODV_0EN, 52 .input_offset = S905_GPIODV_IN, 53 .output_offset = S905_GPIODV_OUT, 54 .output_shift = 0, 55 .mmio_index = 0, 56 .pull_offset = S905_PULL_UP_REG0, 57 .pull_en_offset = S905_PULL_UP_EN_REG0, 58 .pin_start = S905_GPIODV_PIN_START, 59 }, 60 // GPIOH Block 61 { 62 .pin_count = S905_GPIOH_PINS, 63 .oen_offset = S905_GPIOH_0EN, 64 .input_offset = S905_GPIOH_IN, 65 .output_offset = S905_GPIOH_OUT, 66 .output_shift = 20, 67 .mmio_index = 0, 68 .pull_offset = S905_PULL_UP_REG1, 69 .pull_en_offset = S905_PULL_UP_EN_REG1, 70 .pin_start = S905_GPIOH_PIN_START, 71 }, 72 // GPIOCLK Block 73 { 74 .pin_count = S905_GPIOCLK_PINS, 75 .oen_offset = S905_GPIOCLK_0EN, 76 .input_offset = S905_GPIOCLK_IN, 77 .output_offset = S905_GPIOCLK_OUT, 78 .output_shift = 28, 79 .mmio_index = 0, 80 .pull_offset = S905_PULL_UP_REG3, 81 .pull_en_offset = S905_PULL_UP_EN_REG3, 82 .pin_start = S905_GPIOCLK_PIN_START, 83 }, 84 // GPIOBOOT Block 85 { 86 .pin_count = S905_GPIOBOOT_PINS, 87 .oen_offset = S905_GPIOBOOT_0EN, 88 .input_offset = S905_GPIOBOOT_IN, 89 .output_offset = S905_GPIOBOOT_OUT, 90 .output_shift = 0, 91 .mmio_index = 0, 92 .pull_offset = S905_PULL_UP_REG2, 93 .pull_en_offset = S905_PULL_UP_EN_REG2, 94 .pin_start = S905_GPIOBOOT_PIN_START, 95 }, 96 // GPIOCARD Block 97 { 98 .pin_count = S905_GPIOCARD_PINS, 99 .oen_offset = S905_GPIOCARD_0EN, 100 .input_offset = S905_GPIOCARD_IN, 101 .output_offset = S905_GPIOCARD_OUT, 102 .output_shift = 20, 103 .mmio_index = 0, 104 .pull_offset = S905_PULL_UP_REG2, 105 .pull_en_offset = S905_PULL_UP_EN_REG2, 106 .pin_start = S905_GPIOCARD_PIN_START, 107 }, 108 // GPIOAO Block 109 { 110 .pin_count = S905_GPIOAO_PINS, 111 .oen_offset = S905_AO_GPIO_OEN_OUT, 112 .input_offset = S905_AO_GPIO_IN, 113 .output_offset = S905_AO_GPIO_OEN_OUT, 114 .output_shift = 0, 115 .output_write_shift = 16, // output is shared with OEN 116 .mmio_index = 1, 117 .pull_offset = S905_PULL_UP_REG_AO, 118 .pull_en_offset = S905_PULL_UP_EN_REGAO, 119 .pin_start = S905_GPIOA0_PIN_START, 120 }, 121 }; 122 123 #define REG_0 S905_PERIPHS_PIN_MUX_0 124 #define REG_1 S905_PERIPHS_PIN_MUX_1 125 #define REG_2 S905_PERIPHS_PIN_MUX_2 126 #define REG_3 S905_PERIPHS_PIN_MUX_3 127 #define REG_4 S905_PERIPHS_PIN_MUX_4 128 #define REG_5 S905_PERIPHS_PIN_MUX_5 129 #define REG_6 S905_PERIPHS_PIN_MUX_6 130 #define REG_7 S905_PERIPHS_PIN_MUX_7 131 #define REG_8 S905_PERIPHS_PIN_MUX_8 132 #define REG_9 S905_PERIPHS_PIN_MUX_9 133 #define AO_REG S905_AO_RTI_PIN_MUX_REG 134 #define AO_REG_2 S905_AO_RTI_PIN_MUX_REG2 135 136 constexpr AmlGpioInterrupt s905_interrupt_block = { 137 .pin_0_3_select_offset = S905_GPIO_0_3_PIN_SELECT, 138 .pin_4_7_select_offset = S905_GPIO_4_7_PIN_SELECT, 139 .edge_polarity_offset = S905_GPIO_INT_EDGE_POLARITY, 140 .filter_select_offset = S905_GPIO_FILTER_SELECT, 141 .status_offset = S905_GPIO_INT_STATUS, 142 .mask_offset = S905_GPIO_INT_MASK, 143 }; 144 145 constexpr AmlPinMuxBlock s905_pinmux_blocks[] = { 146 // GPIOX Block 147 { 148 .mux = { 149 { .regs = { REG_8 }, .bits = { 5 }, }, 150 { .regs = { REG_8 }, .bits = { 4 }, }, 151 { .regs = { REG_8 }, .bits = { 3 }, }, 152 { .regs = { REG_8 }, .bits = { 2 }, }, 153 { .regs = { REG_8 }, .bits = { 1 }, }, 154 { .regs = { REG_8 }, .bits = { 0 }, }, 155 { .regs = { 0, 0, 0, REG_3, REG_3 }, .bits = { 0, 0, 0, 9, 17 }, }, 156 { .regs = { REG_8, 0, 0, REG_3, REG_3 }, .bits = { 11, 0, 0, 8, 18 }, }, 157 { .regs = { REG_4, 0, REG_3, REG_3 }, .bits = { 7, 0, 30, 10 }, }, 158 { .regs = { REG_4, 0, REG_3, REG_3 }, .bits = { 6, 0, 29, 7 }, }, 159 { .regs = { 0, 0, REG_3 }, .bits = { 0, 0, 28 }, }, 160 { .regs = { 0, 0, REG_3 }, .bits = { 0, 0, 27 }, }, 161 { .regs = { 0, REG_4, REG_4 }, .bits = { 0, 13, 17 }, }, 162 { .regs = { 0, REG_4, REG_4 }, .bits = { 0, 12, 16 }, }, 163 { .regs = { 0, REG_4, REG_4 }, .bits = { 0, 11, 15 }, }, 164 { .regs = { 0, REG_4, REG_4 }, .bits = { 0, 10, 14 }, }, 165 { .regs = { 0, REG_2, 0, 0, REG_2 }, .bits = { 0, 22, 0, 0, 30 }, }, 166 }, 167 }, 168 // GPIOY Block 169 { 170 .mux = { 171 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 19, 2, 0, 0, 0 }, }, 172 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 18, 1, 0, 0, 1 }, }, 173 { .regs = { REG_2, REG_3 }, .bits = { 17, 0 }, }, 174 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 16, 4, 0, 0, 1 }, }, 175 { .regs = { REG_2, REG_3, 0, REG_1 }, .bits = { 16, 5, 0, 12 }, }, 176 { .regs = { REG_2, REG_3, 0, REG_1 }, .bits = { 16, 5, 0, 13 }, }, 177 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 16, 5, 0, 0, 3 }, }, 178 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 16, 5, 0, 0, 4 }, }, 179 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 16, 5, 0, 0, 5 }, }, 180 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 16, 5, 0, 0, 6 }, }, 181 { .regs = { REG_2, REG_3, 0, 0, REG_1 }, .bits = { 16, 5, 0, 0, 7 }, }, 182 { .regs = { 0, REG_3, REG_1, 0, REG_1 }, .bits = { 0, 3, 19, 0, 8 }, }, 183 { .regs = { 0, 0, REG_1, 0, REG_1 }, .bits = { 0, 0, 18, 0, 9 }, }, 184 { .regs = { 0, 0, REG_1, 0, REG_1 }, .bits = { 0, 0, 17, 0, 10 }, }, 185 { .regs = { 0, 0, REG_1, 0, REG_1 }, .bits = { 0, 0, 16, 0, 11 }, }, 186 { .regs = { REG_2, 0, 0, REG_1, REG_1 }, .bits = { 20, 0, 0, 20, 22 }, }, 187 { .regs = { REG_2, 0, 0, REG_1 }, .bits = { 21, 0, 0, 21 }, }, 188 }, 189 }, 190 // GPIOZ Block 191 { 192 .mux = { 193 { .regs = { REG_6, REG_5 }, .bits = { 1, 5 }, }, 194 { .regs = { REG_6, REG_5 }, .bits = { 0, 6 }, }, 195 { .regs = { REG_6 }, .bits = { 13 }, }, 196 { .regs = { REG_6, REG_5 }, .bits = { 12, 7 }, }, 197 { .regs = { REG_6, REG_5 }, .bits = { 11, 4 }, }, 198 { .regs = { REG_6, REG_5 }, .bits = { 10, 4 }, }, 199 { .regs = { REG_6, REG_5, REG_5, REG_5, REG_4 }, .bits = { 9, 4, 27, 9 }, }, 200 { .regs = { REG_6, REG_5, REG_5, REG_5, REG_4 }, .bits = { 8, 4, 26, 8 }, }, 201 { .regs = { REG_6, REG_5 }, .bits = { 7, 4 }, }, 202 { .regs = { REG_6, REG_5 }, .bits = { 6, 4 }, }, 203 { .regs = { REG_6, REG_5 }, .bits = { 5, 4 }, }, 204 { .regs = { REG_6, REG_5 }, .bits = { 4, 4 }, }, 205 { .regs = { REG_6, 0, REG_5 }, .bits = { 3, 0, 28 }, }, 206 { .regs = { REG_6, 0, REG_5 }, .bits = { 2, 0, 29 }, }, 207 { }, 208 { .regs = { 0, REG_6 }, .bits = { 0, 15 }, }, 209 }, 210 }, 211 // GPIODV Block 212 { 213 .mux = { 214 { }, 215 { }, 216 { }, 217 { }, 218 { }, 219 { }, 220 { }, 221 { }, 222 { }, 223 { }, 224 { }, 225 { }, 226 { }, 227 { }, 228 { }, 229 { }, 230 { }, 231 { }, 232 { }, 233 { }, 234 { }, 235 { }, 236 { }, 237 { }, 238 { .regs = { REG_0, REG_0, REG_5, 0, REG_2, REG_7 }, .bits = { 7, 12, 12, 0, 29, 26 }, }, 239 { .regs = { REG_0, REG_0, REG_5, 0, REG_2, REG_7 }, .bits = { 6, 11, 11, 0, 28, 27 }, }, 240 { .regs = { 0, REG_0, REG_5, 0, REG_2, REG_7 }, .bits = { 0, 10, 10, 0, 27, 24 }, }, 241 { .regs = { 0, REG_0, REG_5, REG_5, REG_2, REG_7 }, .bits = { 0, 9, 9, 8, 26, 25 }, }, 242 { .regs = { 0, 0, 0, 0, REG_3, REG_7 }, .bits = { 0, 0, 0, 0, 20, 22 }, }, 243 { .regs = { 0, 0, 0, REG_3, REG_3, REG_7 }, .bits = { 0, 0, 0, 22, 21, 23 }, }, 244 }, 245 }, 246 // GPIOH Block 247 { 248 .mux = { 249 { .regs = { REG_1 }, .bits = { 26 }, }, 250 { .regs = { REG_1 }, .bits = { 25 }, }, 251 { .regs = { REG_1 }, .bits = { 24 }, }, 252 {}, 253 }, 254 }, 255 // GPIOCLK Block 256 { 257 .mux = { 258 {}, 259 {}, 260 }, 261 }, 262 // GPIOBOOT Block 263 { 264 .mux = { 265 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 266 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 267 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 268 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 269 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 270 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 271 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 272 { .regs = { 0, REG_4 }, .bits = { 0, 30 }, }, 273 { .regs = { REG_4, REG_4 }, .bits = { 26, 18 }, }, 274 { .regs = { REG_4 }, .bits = { 27 }, }, 275 { .regs = { REG_4, REG_4 }, .bits = { 25, 19 }, }, 276 { .regs = { REG_4, 0, REG_5 }, .bits = { 24, 0, 1 }, }, 277 { .regs = { REG_4, 0, REG_5 }, .bits = { 23, 0, 3 }, }, 278 { .regs = { REG_4, 0, REG_5 }, .bits = { 22, 0, 2 }, }, 279 { .regs = { REG_4 }, .bits = { 21 }, }, 280 { .regs = { REG_4, 0, REG_5 }, .bits = { 20, 0, 3 }, }, 281 }, 282 }, 283 // GPIOCARD Block 284 { 285 .mux = { 286 { .regs = { REG_2 }, .bits = { 14 }, }, 287 { .regs = { REG_2 }, .bits = { 15 }, }, 288 { .regs = { REG_2 }, .bits = { 11 }, }, 289 { .regs = { REG_2 }, .bits = { 10 }, }, 290 { .regs = { REG_2, REG_8, REG_8 }, .bits = { 12, 10, 18 }, }, 291 { .regs = { REG_2, REG_8, REG_8 }, .bits = { 13, 17, 9 }, }, 292 }, 293 }, 294 // GPIOAO Block 295 { 296 .mux = { 297 { .regs = { AO_REG, AO_REG }, .bits = { 12, 26 }, }, 298 { .regs = { AO_REG, AO_REG }, .bits = { 11, 25 }, }, 299 { .regs = { AO_REG, AO_REG }, .bits = { 10, 8 }, }, 300 { .regs = { AO_REG, AO_REG, AO_REG }, .bits = { 9, 7, 22 }, }, 301 { .regs = { 0, AO_REG, AO_REG, AO_REG }, .bits = { 0, 24, 6, 2 }, }, 302 { .regs = { 0, AO_REG, AO_REG, AO_REG }, .bits = { 0, 25, 5, 1 }, }, 303 { .regs = { 0, AO_REG, AO_REG, AO_REG }, .bits = { 0, 0, 18, 16 }, }, 304 { .regs = { AO_REG, AO_REG }, .bits = { 0, 2 }, }, 305 { .regs = { 0, 0, 0, AO_REG }, .bits = { 0, 0, 0, 30 }, }, 306 { .regs = { 0, 0, 0, AO_REG }, .bits = { 0, 0, 0, 29 }, }, 307 { .regs = { 0, 0, 0, AO_REG }, .bits = { 0, 0, 0, 28 }, }, 308 { .regs = { 0, 0, 0, AO_REG }, .bits = { 0, 0, 0, 27 }, }, 309 { .regs = { AO_REG, AO_REG, AO_REG, AO_REG_2 }, .bits = { 15, 14, 17, 0 }, }, 310 { .regs = { AO_REG, AO_REG, AO_REG, AO_REG_2 }, .bits = { 31, 4, 3, 2 }, }, 311 }, 312 }, 313 }; 314 315 static_assert(countof(s905_gpio_blocks) == countof(s905_pinmux_blocks), ""); 316 317 #undef REG_0 318 #undef REG_1 319 #undef REG_2 320 #undef REG_3 321 #undef REG_4 322 #undef REG_5 323 #undef REG_6 324 #undef REG_7 325 #undef REG_8 326 #undef REG_9 327 #undef AO_REG 328 #undef AO_REG_2 329 330 } // namespace gpio 331