1 // SPDX-License-Identifier: BSD-2-Clause 2 /* 3 * (c) 2020 Jorge Ramirez <jorge@foundries.io>, Foundries Ltd. 4 */ 5 #include <arm.h> 6 #include <drivers/imx_i2c.h> 7 #include <initcall.h> 8 #include <io.h> 9 #include <kernel/delay.h> 10 #include <mm/core_memprot.h> 11 #include <mm/core_mmu.h> 12 #include <platform_config.h> 13 #include <stdlib.h> 14 #include <trace.h> 15 #include <util.h> 16 17 #define I2C_CLK_RATE 24000000 /* Bits per second */ 18 19 static struct io_pa_va i2c_bus[] = { 20 { .pa = I2C1_BASE, }, 21 { .pa = I2C2_BASE, }, 22 { .pa = I2C3_BASE, }, 23 }; 24 25 static struct imx_i2c_clk { 26 struct io_pa_va base; 27 uint32_t i2c[ARRAY_SIZE(i2c_bus)]; 28 } i2c_clk = { 29 .base.pa = CCM_BASE, 30 .i2c = { I2C_CLK_CGR(1), I2C_CLK_CGR(2), I2C_CLK_CGR(3), }, 31 }; 32 33 static struct imx_i2c_mux { 34 struct io_pa_va base; 35 struct imx_i2c_mux_regs { 36 uint32_t scl_mux; 37 uint32_t scl_cfg; 38 uint32_t sda_mux; 39 uint32_t sda_cfg; 40 } i2c[ARRAY_SIZE(i2c_bus)]; 41 } i2c_mux = { 42 .base.pa = IOMUXC_BASE, 43 .i2c = {{ .scl_mux = I2C_MUX_SCL(1), .scl_cfg = I2C_CFG_SCL(1), 44 .sda_mux = I2C_MUX_SDA(1), .sda_cfg = I2C_CFG_SDA(1), }, 45 { .scl_mux = I2C_MUX_SCL(2), .scl_cfg = I2C_CFG_SCL(2), 46 .sda_mux = I2C_MUX_SDA(2), .sda_cfg = I2C_CFG_SDA(2), }, 47 { .scl_mux = I2C_MUX_SCL(3), .scl_cfg = I2C_CFG_SCL(3), 48 .sda_mux = I2C_MUX_SDA(3), .sda_cfg = I2C_CFG_SDA(3), },}, 49 }; 50 51 #define I2DR 0x10 52 #define I2SR 0x0C 53 #define I2CR 0x08 54 #define IFDR 0x04 55 56 #define I2CR_IEN BIT(7) 57 #define I2CR_IIEN BIT(6) 58 #define I2CR_MSTA BIT(5) 59 #define I2CR_MTX BIT(4) 60 #define I2CR_TX_NO_AK BIT(3) 61 #define I2CR_RSTA BIT(2) 62 63 #define I2SR_ICF BIT(7) 64 #define I2SR_IBB BIT(5) 65 #define I2SR_IAL BIT(4) 66 #define I2SR_IIF BIT(1) 67 #define I2SR_RX_NO_AK BIT(0) 68 69 static uint8_t i2c_io_read8(uint8_t bid, uint32_t address) 70 { 71 return io_read8(i2c_bus[bid].va + address); 72 } 73 74 static void i2c_io_write8(uint8_t bid, uint32_t address, uint8_t data) 75 { 76 return io_write8(i2c_bus[bid].va + address, data); 77 } 78 79 static bool bus_is_idle(uint32_t sr) 80 { 81 return (sr & I2SR_IBB) == 0; 82 } 83 84 static bool bus_is_busy(uint32_t sr) 85 { 86 return !bus_is_idle(sr); 87 } 88 89 static bool isr_active(uint32_t sr) 90 { 91 return (sr & I2SR_IIF) == I2SR_IIF; 92 } 93 94 static struct ifdr_pair { 95 uint32_t divider; 96 uint8_t prescaler; 97 } ifdr_table[] = { 98 { 22, 0x20 }, { 24, 0x21 }, { 26, 0x22 }, { 28, 0x23 }, 99 { 30, 0x00 }, { 32, 0x24 }, { 36, 0x25 }, { 40, 0x26 }, 100 { 42, 0x03 }, { 44, 0x27 }, { 48, 0x28 }, { 52, 0x05 }, 101 { 56, 0x29 }, { 60, 0x06 }, { 64, 0x2A }, { 72, 0x2B }, 102 { 80, 0x2C }, { 88, 0x09 }, { 96, 0x2D }, { 104, 0x0A }, 103 { 112, 0x2E }, { 128, 0x2F }, { 144, 0x0C }, { 160, 0x30 }, 104 { 192, 0x31 }, { 224, 0x32 }, { 240, 0x0F }, { 256, 0x33 }, 105 { 288, 0x10 }, { 320, 0x34 }, { 384, 0x35 }, { 448, 0x36 }, 106 { 480, 0x13 }, { 512, 0x37 }, { 576, 0x14 }, { 640, 0x38 }, 107 { 768, 0x39 }, { 896, 0x3A }, { 960, 0x17 }, { 1024, 0x3B }, 108 { 1152, 0x18 }, { 1280, 0x3C }, { 1536, 0x3D }, { 1792, 0x3E }, 109 { 1920, 0x1B }, { 2048, 0x3F }, { 2304, 0x1C }, { 2560, 0x1D }, 110 { 3072, 0x1E }, { 3840, 0x1F } 111 }; 112 113 static void i2c_set_prescaler(uint8_t bid, uint32_t bps) 114 { 115 struct ifdr_pair *p = ifdr_table; 116 struct ifdr_pair *q = p + ARRAY_SIZE(ifdr_table) - 1; 117 uint32_t div = (I2C_CLK_RATE + bps - 1) / bps; 118 119 if (div < p->divider) 120 q = p; 121 else if (div > q->divider) 122 p = q; 123 124 while (p != q) { 125 if (div <= p->divider) 126 break; 127 p++; 128 } 129 130 i2c_io_write8(bid, IFDR, p->prescaler); 131 } 132 133 static void i2c_set_bus_speed(uint8_t bid, int bps) 134 { 135 /* Enable the clock */ 136 io_write32(i2c_clk.base.va + CCM_CCGRx_SET(i2c_clk.i2c[bid]), 137 CCM_CCGRx_ALWAYS_ON(0)); 138 139 i2c_set_prescaler(bid, bps); 140 } 141 142 static TEE_Result i2c_sync_bus(uint8_t bid, bool (*match)(uint32_t), 143 uint32_t *status) 144 { 145 uint64_t tref = timeout_init_us(100000); 146 uint32_t sr = 0; 147 148 while (!timeout_elapsed(tref)) { 149 sr = i2c_io_read8(bid, I2SR); 150 if (sr & I2SR_IAL) { 151 EMSG("bus arbitration lost"); 152 i2c_io_write8(bid, I2SR, sr & ~I2SR_IAL); 153 return TEE_ERROR_COMMUNICATION; 154 } 155 if ((*match)(sr)) { 156 if (status) 157 *status = sr; 158 return TEE_SUCCESS; 159 } 160 } 161 162 return TEE_ERROR_BUSY; 163 } 164 165 static TEE_Result i2c_idle_bus(uint8_t bid) 166 { 167 uint8_t tmp = i2c_io_read8(bid, I2CR) & ~I2CR_MSTA; 168 TEE_Result ret = TEE_SUCCESS; 169 170 i2c_io_write8(bid, I2CR, tmp); 171 ret = i2c_sync_bus(bid, &bus_is_idle, NULL); 172 i2c_io_write8(bid, I2SR, 0); 173 174 return ret; 175 } 176 177 static TEE_Result i2c_write_byte(uint8_t bid, uint8_t byte) 178 { 179 TEE_Result ret = TEE_SUCCESS; 180 uint32_t status = 0; 181 182 i2c_io_write8(bid, I2DR, byte); 183 ret = i2c_sync_bus(bid, &isr_active, &status); 184 i2c_io_write8(bid, I2SR, 0); 185 186 if (!ret && (status & I2SR_RX_NO_AK)) 187 return TEE_ERROR_BAD_STATE; 188 189 return ret; 190 } 191 192 static TEE_Result i2c_read_byte(uint8_t bid, uint8_t *p) 193 { 194 TEE_Result ret = TEE_SUCCESS; 195 196 *p = i2c_io_read8(bid, I2DR); 197 ret = i2c_sync_bus(bid, &isr_active, NULL); 198 i2c_io_write8(bid, I2SR, 0); 199 200 return ret; 201 } 202 203 static TEE_Result i2c_write_data(uint8_t bid, const uint8_t *buf, int len) 204 { 205 TEE_Result ret = TEE_SUCCESS; 206 uint32_t tmp = 0; 207 208 if (!len) 209 return TEE_SUCCESS; 210 211 tmp = i2c_io_read8(bid, I2CR) | I2CR_MTX | I2CR_TX_NO_AK; 212 i2c_io_write8(bid, I2CR, tmp); 213 214 while (len--) { 215 ret = i2c_write_byte(bid, *buf++); 216 if (ret) 217 return ret; 218 } 219 220 return ret; 221 } 222 223 static TEE_Result i2c_read_data(uint8_t bid, uint8_t *buf, int len) 224 { 225 TEE_Result ret = TEE_SUCCESS; 226 uint8_t dummy = 0; 227 uint32_t tmp = 0; 228 229 if (!len) 230 return TEE_SUCCESS; 231 232 tmp = i2c_io_read8(bid, I2CR) & ~I2CR_MTX; 233 tmp = (len == 1) ? tmp | I2CR_TX_NO_AK : tmp & ~I2CR_TX_NO_AK; 234 i2c_io_write8(bid, I2CR, tmp); 235 i2c_io_read8(bid, I2DR); 236 237 ret = i2c_read_byte(bid, &dummy); 238 if (ret) 239 return ret; 240 241 /* 242 * A data transfer ends when the master signals a stop; for a master 243 * receiver to terminate a transfer it must inform the slave transmiter 244 * by not acknowledging the last data byte. This is done by setting the 245 * transmit acknowledge bit before reading the next-to-last byte. 246 */ 247 do { 248 if (len == 2) { 249 tmp = i2c_io_read8(bid, I2CR) | I2CR_TX_NO_AK; 250 i2c_io_write8(bid, I2CR, tmp); 251 } 252 253 ret = i2c_read_byte(bid, buf++); 254 if (ret) 255 return ret; 256 } while (len--); 257 258 return ret; 259 } 260 261 static TEE_Result i2c_init_transfer(uint8_t bid, uint8_t chip) 262 { 263 TEE_Result ret = TEE_SUCCESS; 264 uint32_t tmp = 0; 265 266 ret = i2c_idle_bus(bid); 267 if (ret) 268 return ret; 269 270 /* Enable the interface */ 271 i2c_io_write8(bid, I2CR, I2CR_IEN); 272 273 tmp = i2c_io_read8(bid, I2CR) | I2CR_MSTA; 274 i2c_io_write8(bid, I2CR, tmp); 275 276 /* Wait until the bus is active */ 277 ret = i2c_sync_bus(bid, &bus_is_busy, NULL); 278 if (ret) 279 return ret; 280 281 /* Slave address on the bus */ 282 return i2c_write_data(bid, &chip, 1); 283 } 284 285 TEE_Result imx_i2c_read(uint8_t bid, uint8_t chip, uint8_t *buf, int len) 286 { 287 TEE_Result ret = TEE_SUCCESS; 288 289 if (bid >= ARRAY_SIZE(i2c_bus)) 290 return TEE_ERROR_BAD_PARAMETERS; 291 292 if ((len && !buf) || chip > 0x7F) 293 return TEE_ERROR_BAD_PARAMETERS; 294 295 ret = i2c_init_transfer(bid, chip << 1 | BIT(0)); 296 if (!ret) 297 ret = i2c_read_data(bid, buf, len); 298 299 if (i2c_idle_bus(bid)) 300 IMSG("bus not idle"); 301 302 return ret; 303 } 304 305 TEE_Result imx_i2c_write(uint8_t bid, uint8_t chip, const uint8_t *buf, int len) 306 { 307 TEE_Result ret = TEE_SUCCESS; 308 309 if (bid >= ARRAY_SIZE(i2c_bus)) 310 return TEE_ERROR_BAD_PARAMETERS; 311 312 if ((len && !buf) || chip > 0x7F) 313 return TEE_ERROR_BAD_PARAMETERS; 314 315 ret = i2c_init_transfer(bid, chip << 1); 316 if (!ret) 317 ret = i2c_write_data(bid, buf, len); 318 319 if (i2c_idle_bus(bid)) 320 IMSG("bus not idle"); 321 322 return ret; 323 } 324 325 TEE_Result imx_i2c_probe(uint8_t bid, uint8_t chip) 326 { 327 if (bid >= ARRAY_SIZE(i2c_bus)) 328 return TEE_ERROR_BAD_PARAMETERS; 329 330 if (chip > 0x7F) 331 return TEE_ERROR_BAD_PARAMETERS; 332 333 return imx_i2c_write(bid, chip, NULL, 0); 334 } 335 336 /* 337 * I2C bus initialization: configure the IOMUX and enable the clock. 338 * @bid: Bus ID: (0=I2C1), (1=I2C2), (2=I2C3). 339 * @bps: Bus baud rate, in bits per second. 340 */ 341 TEE_Result imx_i2c_init(uint8_t bid, int bps) 342 { 343 struct imx_i2c_mux *mux = &i2c_mux; 344 345 if (bid >= ARRAY_SIZE(i2c_bus)) 346 return TEE_ERROR_BAD_PARAMETERS; 347 348 if (!bps) 349 return TEE_ERROR_BAD_PARAMETERS; 350 351 io_write32(mux->base.va + mux->i2c[bid].scl_mux, I2C_MUX_VAL(bid)); 352 io_write32(mux->base.va + mux->i2c[bid].scl_cfg, I2C_CFG_VAL(bid)); 353 io_write32(mux->base.va + mux->i2c[bid].sda_mux, I2C_MUX_VAL(bid)); 354 io_write32(mux->base.va + mux->i2c[bid].sda_cfg, I2C_CFG_VAL(bid)); 355 356 /* Baud rate in bits per second */ 357 i2c_set_bus_speed(bid, bps); 358 359 return TEE_SUCCESS; 360 } 361 362 static TEE_Result get_va(paddr_t pa, vaddr_t *va) 363 { 364 if (!core_mmu_add_mapping(MEM_AREA_IO_SEC, pa, 0x10000)) 365 return TEE_ERROR_GENERIC; 366 367 *va = (vaddr_t)phys_to_virt(pa, MEM_AREA_IO_SEC); 368 if (*va) 369 return TEE_SUCCESS; 370 371 return TEE_ERROR_GENERIC; 372 } 373 374 static TEE_Result i2c_init(void) 375 { 376 size_t n = 0; 377 378 if (get_va(i2c_clk.base.pa, &i2c_clk.base.va)) 379 return TEE_ERROR_GENERIC; 380 381 if (get_va(i2c_mux.base.pa, &i2c_mux.base.va)) 382 return TEE_ERROR_GENERIC; 383 384 for (n = 0; n < ARRAY_SIZE(i2c_bus); n++) { 385 if (get_va(i2c_bus[n].pa, &i2c_bus[n].va)) 386 return TEE_ERROR_GENERIC; 387 } 388 389 return TEE_SUCCESS; 390 } 391 392 early_init(i2c_init); 393