1 /* 2 * (C) Copyright 2011 3 * Yuri Tikhonov, Emcraft Systems, yur@emcraft.com 4 * 5 * (C) Copyright 2015 6 * Kamil Lulko, <rev13@wp.pl> 7 * 8 * Copyright 2015 ATS Advanced Telematics Systems GmbH 9 * Copyright 2015 Konsulko Group, Matt Porter <mporter@konsulko.com> 10 * 11 * SPDX-License-Identifier: GPL-2.0+ 12 */ 13 14 #include <common.h> 15 #include <asm/io.h> 16 #include <asm/errno.h> 17 #include <asm/arch/stm32.h> 18 #include <asm/arch/gpio.h> 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #if defined(CONFIG_STM32F4) 23 #define STM32_GPIOA_BASE (STM32_AHB1PERIPH_BASE + 0x0000) 24 #define STM32_GPIOB_BASE (STM32_AHB1PERIPH_BASE + 0x0400) 25 #define STM32_GPIOC_BASE (STM32_AHB1PERIPH_BASE + 0x0800) 26 #define STM32_GPIOD_BASE (STM32_AHB1PERIPH_BASE + 0x0C00) 27 #define STM32_GPIOE_BASE (STM32_AHB1PERIPH_BASE + 0x1000) 28 #define STM32_GPIOF_BASE (STM32_AHB1PERIPH_BASE + 0x1400) 29 #define STM32_GPIOG_BASE (STM32_AHB1PERIPH_BASE + 0x1800) 30 #define STM32_GPIOH_BASE (STM32_AHB1PERIPH_BASE + 0x1C00) 31 #define STM32_GPIOI_BASE (STM32_AHB1PERIPH_BASE + 0x2000) 32 33 static const unsigned long io_base[] = { 34 STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE, 35 STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE, 36 STM32_GPIOG_BASE, STM32_GPIOH_BASE, STM32_GPIOI_BASE 37 }; 38 39 struct stm32_gpio_regs { 40 u32 moder; /* GPIO port mode */ 41 u32 otyper; /* GPIO port output type */ 42 u32 ospeedr; /* GPIO port output speed */ 43 u32 pupdr; /* GPIO port pull-up/pull-down */ 44 u32 idr; /* GPIO port input data */ 45 u32 odr; /* GPIO port output data */ 46 u32 bsrr; /* GPIO port bit set/reset */ 47 u32 lckr; /* GPIO port configuration lock */ 48 u32 afr[2]; /* GPIO alternate function */ 49 }; 50 51 #define CHECK_DSC(x) (!x || x->port > 8 || x->pin > 15) 52 #define CHECK_CTL(x) (!x || x->af > 15 || x->mode > 3 || x->otype > 1 || \ 53 x->pupd > 2 || x->speed > 3) 54 55 int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, 56 const struct stm32_gpio_ctl *ctl) 57 { 58 struct stm32_gpio_regs *gpio_regs; 59 u32 i; 60 int rv; 61 62 if (CHECK_DSC(dsc)) { 63 rv = -EINVAL; 64 goto out; 65 } 66 if (CHECK_CTL(ctl)) { 67 rv = -EINVAL; 68 goto out; 69 } 70 71 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 72 73 setbits_le32(&STM32_RCC->ahb1enr, 1 << dsc->port); 74 75 i = (dsc->pin & 0x07) * 4; 76 clrsetbits_le32(&gpio_regs->afr[dsc->pin >> 3], 0xF << i, ctl->af << i); 77 78 i = dsc->pin * 2; 79 80 clrsetbits_le32(&gpio_regs->moder, 0x3 << i, ctl->mode << i); 81 clrsetbits_le32(&gpio_regs->otyper, 0x3 << i, ctl->otype << i); 82 clrsetbits_le32(&gpio_regs->ospeedr, 0x3 << i, ctl->speed << i); 83 clrsetbits_le32(&gpio_regs->pupdr, 0x3 << i, ctl->pupd << i); 84 85 rv = 0; 86 out: 87 return rv; 88 } 89 #elif defined(CONFIG_STM32F1) 90 #define STM32_GPIOA_BASE (STM32_APB2PERIPH_BASE + 0x0800) 91 #define STM32_GPIOB_BASE (STM32_APB2PERIPH_BASE + 0x0C00) 92 #define STM32_GPIOC_BASE (STM32_APB2PERIPH_BASE + 0x1000) 93 #define STM32_GPIOD_BASE (STM32_APB2PERIPH_BASE + 0x1400) 94 #define STM32_GPIOE_BASE (STM32_APB2PERIPH_BASE + 0x1800) 95 #define STM32_GPIOF_BASE (STM32_APB2PERIPH_BASE + 0x1C00) 96 #define STM32_GPIOG_BASE (STM32_APB2PERIPH_BASE + 0x2000) 97 98 static const unsigned long io_base[] = { 99 STM32_GPIOA_BASE, STM32_GPIOB_BASE, STM32_GPIOC_BASE, 100 STM32_GPIOD_BASE, STM32_GPIOE_BASE, STM32_GPIOF_BASE, 101 STM32_GPIOG_BASE 102 }; 103 104 #define STM32_GPIO_CR_MODE_MASK 0x3 105 #define STM32_GPIO_CR_MODE_SHIFT(p) (p * 4) 106 #define STM32_GPIO_CR_CNF_MASK 0x3 107 #define STM32_GPIO_CR_CNF_SHIFT(p) (p * 4 + 2) 108 109 struct stm32_gpio_regs { 110 u32 crl; /* GPIO port configuration low */ 111 u32 crh; /* GPIO port configuration high */ 112 u32 idr; /* GPIO port input data */ 113 u32 odr; /* GPIO port output data */ 114 u32 bsrr; /* GPIO port bit set/reset */ 115 u32 brr; /* GPIO port bit reset */ 116 u32 lckr; /* GPIO port configuration lock */ 117 }; 118 119 #define CHECK_DSC(x) (!x || x->port > 6 || x->pin > 15) 120 #define CHECK_CTL(x) (!x || x->mode > 3 || x->icnf > 3 || x->ocnf > 3 || \ 121 x->pupd > 1) 122 123 int stm32_gpio_config(const struct stm32_gpio_dsc *dsc, 124 const struct stm32_gpio_ctl *ctl) 125 { 126 struct stm32_gpio_regs *gpio_regs; 127 u32 *cr; 128 int p, crp; 129 int rv; 130 131 if (CHECK_DSC(dsc)) { 132 rv = -EINVAL; 133 goto out; 134 } 135 if (CHECK_CTL(ctl)) { 136 rv = -EINVAL; 137 goto out; 138 } 139 140 p = dsc->pin; 141 142 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 143 144 /* Enable clock for GPIO port */ 145 setbits_le32(&STM32_RCC->apb2enr, 0x04 << dsc->port); 146 147 if (p < 8) { 148 cr = &gpio_regs->crl; 149 crp = p; 150 } else { 151 cr = &gpio_regs->crh; 152 crp = p - 8; 153 } 154 155 clrbits_le32(cr, 0x3 << STM32_GPIO_CR_MODE_SHIFT(crp)); 156 setbits_le32(cr, ctl->mode << STM32_GPIO_CR_MODE_SHIFT(crp)); 157 158 clrbits_le32(cr, 0x3 << STM32_GPIO_CR_CNF_SHIFT(crp)); 159 /* Inputs set the optional pull up / pull down */ 160 if (ctl->mode == STM32_GPIO_MODE_IN) { 161 setbits_le32(cr, ctl->icnf << STM32_GPIO_CR_CNF_SHIFT(crp)); 162 clrbits_le32(&gpio_regs->odr, 0x1 << p); 163 setbits_le32(&gpio_regs->odr, ctl->pupd << p); 164 } else { 165 setbits_le32(cr, ctl->ocnf << STM32_GPIO_CR_CNF_SHIFT(crp)); 166 } 167 168 rv = 0; 169 out: 170 return rv; 171 } 172 #else 173 #error STM32 family not supported 174 #endif 175 176 int stm32_gpout_set(const struct stm32_gpio_dsc *dsc, int state) 177 { 178 struct stm32_gpio_regs *gpio_regs; 179 int rv; 180 181 if (CHECK_DSC(dsc)) { 182 rv = -EINVAL; 183 goto out; 184 } 185 186 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 187 188 if (state) 189 writel(1 << dsc->pin, &gpio_regs->bsrr); 190 else 191 writel(1 << (dsc->pin + 16), &gpio_regs->bsrr); 192 193 rv = 0; 194 out: 195 return rv; 196 } 197 198 int stm32_gpin_get(const struct stm32_gpio_dsc *dsc) 199 { 200 struct stm32_gpio_regs *gpio_regs; 201 int rv; 202 203 if (CHECK_DSC(dsc)) { 204 rv = -EINVAL; 205 goto out; 206 } 207 208 gpio_regs = (struct stm32_gpio_regs *)io_base[dsc->port]; 209 rv = readl(&gpio_regs->idr) & (1 << dsc->pin); 210 out: 211 return rv; 212 } 213 214 /* Common GPIO API */ 215 216 int gpio_request(unsigned gpio, const char *label) 217 { 218 return 0; 219 } 220 221 int gpio_free(unsigned gpio) 222 { 223 return 0; 224 } 225 226 int gpio_direction_input(unsigned gpio) 227 { 228 struct stm32_gpio_dsc dsc; 229 struct stm32_gpio_ctl ctl; 230 231 dsc.port = stm32_gpio_to_port(gpio); 232 dsc.pin = stm32_gpio_to_pin(gpio); 233 #if defined(CONFIG_STM32F4) 234 ctl.af = STM32_GPIO_AF0; 235 ctl.mode = STM32_GPIO_MODE_IN; 236 ctl.otype = STM32_GPIO_OTYPE_PP; 237 ctl.pupd = STM32_GPIO_PUPD_NO; 238 ctl.speed = STM32_GPIO_SPEED_50M; 239 #elif defined(CONFIG_STM32F1) 240 ctl.mode = STM32_GPIO_MODE_IN; 241 ctl.icnf = STM32_GPIO_ICNF_IN_FLT; 242 ctl.ocnf = STM32_GPIO_OCNF_GP_PP; /* ignored for input */ 243 ctl.pupd = STM32_GPIO_PUPD_UP; /* ignored for floating */ 244 #else 245 #error STM32 family not supported 246 #endif 247 248 return stm32_gpio_config(&dsc, &ctl); 249 } 250 251 int gpio_direction_output(unsigned gpio, int value) 252 { 253 struct stm32_gpio_dsc dsc; 254 struct stm32_gpio_ctl ctl; 255 int res; 256 257 dsc.port = stm32_gpio_to_port(gpio); 258 dsc.pin = stm32_gpio_to_pin(gpio); 259 #if defined(CONFIG_STM32F4) 260 ctl.af = STM32_GPIO_AF0; 261 ctl.mode = STM32_GPIO_MODE_OUT; 262 ctl.pupd = STM32_GPIO_PUPD_NO; 263 ctl.speed = STM32_GPIO_SPEED_50M; 264 #elif defined(CONFIG_STM32F1) 265 ctl.mode = STM32_GPIO_MODE_OUT_50M; 266 ctl.ocnf = STM32_GPIO_OCNF_GP_PP; 267 ctl.icnf = STM32_GPIO_ICNF_IN_FLT; /* ignored for output */ 268 ctl.pupd = STM32_GPIO_PUPD_UP; /* ignored for output */ 269 #else 270 #error STM32 family not supported 271 #endif 272 273 res = stm32_gpio_config(&dsc, &ctl); 274 if (res < 0) 275 goto out; 276 res = stm32_gpout_set(&dsc, value); 277 out: 278 return res; 279 } 280 281 int gpio_get_value(unsigned gpio) 282 { 283 struct stm32_gpio_dsc dsc; 284 285 dsc.port = stm32_gpio_to_port(gpio); 286 dsc.pin = stm32_gpio_to_pin(gpio); 287 288 return stm32_gpin_get(&dsc); 289 } 290 291 int gpio_set_value(unsigned gpio, int value) 292 { 293 struct stm32_gpio_dsc dsc; 294 295 dsc.port = stm32_gpio_to_port(gpio); 296 dsc.pin = stm32_gpio_to_pin(gpio); 297 298 return stm32_gpout_set(&dsc, value); 299 } 300