// SPDX-License-Identifier: BSD-2-Clause /* * Copyright 2021 NXP * * I2C driver for I2C Controller * */ #include #include #include #include #include #include #include #include #include static const char * const i2c_controller_map[] = { "/soc/i2c@2000000", "/soc/i2c@2010000", "/soc/i2c@2020000", "/soc/i2c@2030000", "/soc/i2c@2040000", "/soc/i2c@2050000", "/soc/i2c@2060000", "/soc/i2c@2070000" }; /* * I2C divisor and ibfd register values when glitch filter is enabled * In case of duplicate SCL divisor value, the ibfd value with high MUL value * has been selected. A higher MUL value results in a lower sampling rate of * the I2C signals. This gives the I2C module greater immunity against glitches * in the I2C signals. */ static const struct i2c_clock_divisor_pair clk_div_glitch_enabled[] = { { 34, 0x0 }, { 36, 0x1 }, { 38, 0x2 }, { 40, 0x3 }, { 42, 0x4 }, { 44, 0x8 }, { 48, 0x9 }, { 52, 0xA }, { 54, 0x7 }, { 56, 0xB }, { 60, 0xC }, { 64, 0x10 }, { 68, 0x40 }, { 72, 0x41 }, { 76, 0x42 }, { 80, 0x43 }, { 84, 0x44 }, { 88, 0x48 }, { 96, 0x49 }, { 104, 0x4A }, { 108, 0x47 }, { 112, 0x4B }, { 120, 0x4C }, { 128, 0x50 }, { 136, 0x80 }, { 144, 0x81 }, { 152, 0x82 }, { 160, 0x83 }, { 168, 0x84 }, { 176, 0x88 }, { 192, 0x89 }, { 208, 0x8A }, { 216, 0x87 }, { 224, 0x8B }, { 240, 0x8C }, { 256, 0x90 }, { 288, 0x91 }, { 320, 0x92 }, { 336, 0x8F }, { 352, 0x93 }, { 384, 0x98 }, { 416, 0x95 }, { 448, 0x99 }, { 480, 0x96 }, { 512, 0x9A }, { 576, 0x9B }, { 640, 0xA0 }, { 704, 0x9D }, { 768, 0xA1 }, { 832, 0x9E }, { 896, 0xA2 }, { 960, 0x67 }, { 1024, 0xA3 }, { 1152, 0xA4 }, { 1280, 0xA8 }, { 1536, 0xA9 }, { 1792, 0xAA }, { 1920, 0xA7 }, { 2048, 0xAB }, { 2304, 0xAC }, { 2560, 0xB0 }, { 3072, 0xB1 }, { 3584, 0xB2 }, { 3840, 0xAF }, { 4096, 0xB3 }, { 4608, 0xB4 }, { 5120, 0xB8 }, { 6144, 0xB9 }, { 7168, 0xBA }, { 7680, 0xB7 }, { 8192, 0xBB }, { 9216, 0xBC }, { 10240, 0xBD }, { 12288, 0xBE }, { 15360, 0xBF } }; /* * I2C divisor and ibfd register values when glitch filter is disabled. * In case of duplicate SCL divisor value, the ibfd value with high MUL value * has been selected. A higher MUL value results in a lower sampling rate of * the I2C signals. This gives the I2C module greater immunity against glitches * in the I2C signals. */ static const struct i2c_clock_divisor_pair clk_div_glitch_disabled[] = { { 20, 0x0 }, { 22, 0x1 }, { 24, 0x2 }, { 26, 0x3 }, { 28, 0x8 }, { 30, 0x5 }, { 32, 0x9 }, { 34, 0x6 }, { 36, 0x0A }, { 40, 0x40 }, { 44, 0x41 }, { 48, 0x42 }, { 52, 0x43 }, { 56, 0x48 }, { 60, 0x45 }, { 64, 0x49 }, { 68, 0x46 }, { 72, 0x4A }, { 80, 0x80 }, { 88, 0x81 }, { 96, 0x82 }, { 104, 0x83 }, { 112, 0x88 }, { 120, 0x85 }, { 128, 0x89 }, { 136, 0x86 }, { 144, 0x8A }, { 160, 0x8B }, { 176, 0x8C }, { 192, 0x90 }, { 208, 0x56 }, { 224, 0x91 }, { 240, 0x1F }, { 256, 0x92 }, { 272, 0x8F }, { 288, 0x93 }, { 320, 0x98 }, { 352, 0x95 }, { 384, 0x99 }, { 416, 0x96 }, { 448, 0x9A }, { 480, 0x5F }, { 512, 0x9B }, { 576, 0x9C }, { 640, 0xA0 }, { 768, 0xA1 }, { 896, 0xA2 }, { 960, 0x9F }, { 1024, 0xA3 }, { 1152, 0xA4 }, { 1280, 0xA8 }, { 1536, 0xA9 }, { 1792, 0xAA }, { 1920, 0xA7 }, { 2048, 0xAB }, { 2304, 0xAC }, { 2560, 0xAD }, { 3072, 0xB1 }, { 3584, 0xB2 }, { 3840, 0xAF }, { 4096, 0xB3 }, { 4608, 0xB4 }, { 5120, 0xB8 }, { 6144, 0xB9 }, { 7168, 0xBA }, { 7680, 0xB7 }, { 8192, 0xBB }, { 9216, 0xBC }, { 10240, 0xBD }, { 12288, 0xBE }, { 15360, 0xBF } }; void i2c_reset(vaddr_t base) { struct i2c_regs *regs = (struct i2c_regs *)base; io_setbits8((vaddr_t)®s->ibcr, I2C_IBCR_MDIS); io_setbits8((vaddr_t)®s->ibsr, I2C_IBSR_IBAL | I2C_IBSR_IBIF); io_clrbits8((vaddr_t)®s->ibcr, I2C_IBCR_IBIE | I2C_IBCR_DMAEN); io_clrbits8((vaddr_t)®s->ibic, I2C_IBIC_BIIE); } /* * Get I2c Bus Frequency Divider Register value based on clock_divisor * and if the glitch is enabled or not in I2c controller. * base Base address of I2C controller * clock_divisor Clock Divisor */ static uint8_t i2c_get_ibfd(vaddr_t base, uint16_t clock_divisor) { struct i2c_regs *regs = (struct i2c_regs *)base; const struct i2c_clock_divisor_pair *dpair = NULL; size_t dpair_sz = 0; unsigned int n = 0; if (io_read8((vaddr_t)®s->ibdbg) & I2C_IBDBG_GLFLT_EN) { dpair = clk_div_glitch_enabled; dpair_sz = ARRAY_SIZE(clk_div_glitch_enabled); } else { dpair = clk_div_glitch_disabled; dpair_sz = ARRAY_SIZE(clk_div_glitch_disabled); } for (n = 0; n < dpair_sz - 1; n++) if (clock_divisor < dpair[n].divisor) break; return dpair[n].ibfd; } TEE_Result i2c_init(struct ls_i2c_data *i2c_data) { struct i2c_regs *regs = NULL; uint16_t clock_divisor = 0; uint8_t ibfd = 0; /* I2c Bus Frequency Divider Register */ size_t size = 0; int node = 0; vaddr_t ctrl_base = 0; void *fdt = NULL; /* * First get the I2C Controller base address from the DTB * if DTB present and if the I2C Controller defined in it. */ fdt = get_embedded_dt(); if (!fdt) { EMSG("Unable to get the Embedded DTB, I2C init failed\n"); return TEE_ERROR_GENERIC; } node = fdt_path_offset(fdt, i2c_controller_map[i2c_data->i2c_controller]); if (node > 0) { if (dt_map_dev(fdt, node, &ctrl_base, &size, DT_MAP_AUTO) < 0) { EMSG("Unable to get virtual address"); return TEE_ERROR_GENERIC; } } else { EMSG("Unable to get I2C offset node"); return TEE_ERROR_ITEM_NOT_FOUND; } i2c_data->base = ctrl_base; regs = (struct i2c_regs *)ctrl_base; clock_divisor = (i2c_data->i2c_bus_clock + i2c_data->speed - 1) / i2c_data->speed; ibfd = i2c_get_ibfd(ctrl_base, clock_divisor); io_write8((vaddr_t)®s->ibfd, ibfd); i2c_reset(ctrl_base); return TEE_SUCCESS; } /* * Check if I2C bus is busy with previous transaction or not. * regs pointer to I2c controller registers * test_busy this flag tells if we need to check the busy bit in IBSR reg */ static TEE_Result i2c_bus_test_bus_busy(struct i2c_regs *regs, bool test_busy) { unsigned int n = 0; uint8_t reg = 0; for (n = 0; n < I2C_NUM_RETRIES; n++) { reg = io_read8((vaddr_t)®s->ibsr); if (reg & I2C_IBSR_IBAL) { io_write8((vaddr_t)®s->ibsr, reg); return TEE_ERROR_BUSY; } if (test_busy && (reg & I2C_IBSR_IBB)) break; if (!test_busy && !(reg & I2C_IBSR_IBB)) break; mdelay(1); } if (n == I2C_NUM_RETRIES) return TEE_ERROR_BUSY; return TEE_SUCCESS; } /* * Check if data transfer to/from i2c controller is complete. * regs pointer to I2c controller registers * test_rx_ack this flag tells if we need to check RXAK bit in IBSR reg */ static TEE_Result i2c_transfer_complete(struct i2c_regs *regs, bool test_rx_ack) { unsigned int n = 0; uint8_t reg = 0; for (n = 0; n < I2C_NUM_RETRIES; n++) { reg = io_read8((vaddr_t)®s->ibsr); if (reg & I2C_IBSR_IBIF) { /* Write 1 to clear the IBIF field */ io_write8((vaddr_t)®s->ibsr, reg); break; } mdelay(1); } if (n == I2C_NUM_RETRIES) return TEE_ERROR_BUSY; if (test_rx_ack && (reg & I2C_IBSR_RXAK)) return TEE_ERROR_NO_DATA; if (reg & I2C_IBSR_TCF) return TEE_SUCCESS; return TEE_ERROR_GENERIC; } /* * Read data from I2c controller. * regs pointer to I2c controller registers * slave_address slave address from which to read * operation pointer to i2c_operation struct * is_last_operation if current operation is last operation */ static TEE_Result i2c_read(struct i2c_regs *regs, unsigned int slave_address, struct i2c_operation *operation, bool is_last_operation) { TEE_Result res = TEE_ERROR_GENERIC; unsigned int n = 0; /* Write Slave Address */ io_write8((vaddr_t)®s->ibdr, (slave_address << 0x1) | BIT(0)); res = i2c_transfer_complete(regs, I2C_BUS_TEST_RX_ACK); if (res) return res; /* select Receive mode. */ io_clrbits8((vaddr_t)®s->ibcr, I2C_IBCR_TXRX); if (operation->length_in_bytes > 1) { /* Set No ACK = 0 */ io_clrbits8((vaddr_t)®s->ibcr, I2C_IBCR_NOACK); } /* Perform a dummy read to initiate the receive operation. */ io_read8((vaddr_t)®s->ibdr); for (n = 0; n < operation->length_in_bytes; n++) { res = i2c_transfer_complete(regs, I2C_BUS_NO_TEST_RX_ACK); if (res) return res; if (n == (operation->length_in_bytes - 2)) { /* Set No ACK = 1 */ io_setbits8((vaddr_t)®s->ibcr, I2C_IBCR_NOACK); } else if (n == (operation->length_in_bytes - 1)) { if (!is_last_operation) { /* select Transmit mode (for repeat start) */ io_setbits8((vaddr_t)®s->ibcr, I2C_IBCR_TXRX); } else { /* Generate Stop Signal */ io_clrbits8((vaddr_t)®s->ibcr, (I2C_IBCR_MSSL | I2C_IBCR_TXRX)); res = i2c_bus_test_bus_busy(regs, I2C_BUS_TEST_IDLE); if (res) return res; } } operation->buffer[n] = io_read8((vaddr_t)®s->ibdr); } return TEE_SUCCESS; } /* * Write data to I2c controller * regs pointer to I2c controller registers * slave_address slave address from which to read * operation pointer to i2c_operation struct */ static TEE_Result i2c_write(struct i2c_regs *regs, unsigned int slave_address, struct i2c_operation *operation) { TEE_Result res = TEE_ERROR_GENERIC; unsigned int n = 0; /* Write Slave Address */ io_write8((vaddr_t)®s->ibdr, (slave_address << 0x1) & ~(BIT(0))); res = i2c_transfer_complete(regs, I2C_BUS_TEST_RX_ACK); if (res) return res; /* Write Data */ for (n = 0; n < operation->length_in_bytes; n++) { io_write8((vaddr_t)®s->ibdr, operation->buffer[n]); res = i2c_transfer_complete(regs, I2C_BUS_TEST_RX_ACK); if (res) return res; } return TEE_SUCCESS; } /* * Generate Stop Signal and disable I2C controller. * regs pointer to I2c controller registers */ static TEE_Result i2c_stop(struct i2c_regs *regs) { TEE_Result res = TEE_SUCCESS; uint8_t reg = 0; reg = io_read8((vaddr_t)®s->ibsr); if (reg & I2C_IBSR_IBB) { /* Generate Stop Signal */ io_clrbits8((vaddr_t)®s->ibcr, I2C_IBCR_MSSL | I2C_IBCR_TXRX); res = i2c_bus_test_bus_busy(regs, I2C_BUS_TEST_IDLE); if (res) return res; } /* Disable I2c Controller */ io_setbits8((vaddr_t)®s->ibcr, I2C_IBCR_MDIS); return TEE_SUCCESS; } /* * Generate Start Signal and set I2C controller in transmit mode. * regs pointer to I2c controller registers */ static TEE_Result i2c_start(struct i2c_regs *regs) { TEE_Result res = TEE_ERROR_GENERIC; io_setbits8((vaddr_t)®s->ibsr, I2C_IBSR_IBAL | I2C_IBSR_IBIF); io_clrbits8((vaddr_t)®s->ibcr, I2C_IBCR_MDIS); /* Wait controller to be stable */ mdelay(1); /* Generate Start Signal */ io_setbits8((vaddr_t)®s->ibcr, I2C_IBCR_MSSL); res = i2c_bus_test_bus_busy(regs, I2C_BUS_TEST_BUSY); if (res) return res; /* Select Transmit Mode. set No ACK = 1 */ io_setbits8((vaddr_t)®s->ibcr, I2C_IBCR_TXRX | I2C_IBCR_NOACK); return TEE_SUCCESS; } TEE_Result i2c_bus_xfer(vaddr_t base, unsigned int slave_address, struct i2c_operation *i2c_operation, unsigned int operation_count) { unsigned int n = 0; struct i2c_regs *regs = (struct i2c_regs *)base; struct i2c_operation *operation = NULL; TEE_Result res = TEE_ERROR_GENERIC; bool is_last_operation = false; res = i2c_bus_test_bus_busy(regs, I2C_BUS_TEST_IDLE); if (res) goto out; res = i2c_start(regs); if (res) goto out; for (n = 0, operation = i2c_operation; n < operation_count; n++, operation++) { if (n == (operation_count - 1)) is_last_operation = true; /* Send repeat start after first transmit/receive */ if (n) { io_setbits8((vaddr_t)®s->ibcr, I2C_IBCR_RSTA); res = i2c_bus_test_bus_busy(regs, I2C_BUS_TEST_BUSY); if (res) goto out; } /* Read/write data */ if (operation->flags & I2C_FLAG_READ) res = i2c_read(regs, slave_address, operation, is_last_operation); else res = i2c_write(regs, slave_address, operation); if (res) goto out; } out: i2c_stop(regs); return res; }