14fadcaf0SPatrice Chotard /* 24fadcaf0SPatrice Chotard * (C) Copyright 2017 STMicroelectronics 34fadcaf0SPatrice Chotard * 44fadcaf0SPatrice Chotard * SPDX-License-Identifier: GPL-2.0+ 54fadcaf0SPatrice Chotard */ 64fadcaf0SPatrice Chotard 74fadcaf0SPatrice Chotard #include <common.h> 84fadcaf0SPatrice Chotard #include <clk.h> 94fadcaf0SPatrice Chotard #include <dm.h> 104fadcaf0SPatrice Chotard #include <i2c.h> 114fadcaf0SPatrice Chotard #include <reset.h> 124fadcaf0SPatrice Chotard 134fadcaf0SPatrice Chotard #include <dm/device.h> 144fadcaf0SPatrice Chotard #include <linux/io.h> 154fadcaf0SPatrice Chotard 164fadcaf0SPatrice Chotard /* STM32 I2C registers */ 174fadcaf0SPatrice Chotard struct stm32_i2c_regs { 184fadcaf0SPatrice Chotard u32 cr1; /* I2C control register 1 */ 194fadcaf0SPatrice Chotard u32 cr2; /* I2C control register 2 */ 204fadcaf0SPatrice Chotard u32 oar1; /* I2C own address 1 register */ 214fadcaf0SPatrice Chotard u32 oar2; /* I2C own address 2 register */ 224fadcaf0SPatrice Chotard u32 timingr; /* I2C timing register */ 234fadcaf0SPatrice Chotard u32 timeoutr; /* I2C timeout register */ 244fadcaf0SPatrice Chotard u32 isr; /* I2C interrupt and status register */ 254fadcaf0SPatrice Chotard u32 icr; /* I2C interrupt clear register */ 264fadcaf0SPatrice Chotard u32 pecr; /* I2C packet error checking register */ 274fadcaf0SPatrice Chotard u32 rxdr; /* I2C receive data register */ 284fadcaf0SPatrice Chotard u32 txdr; /* I2C transmit data register */ 294fadcaf0SPatrice Chotard }; 304fadcaf0SPatrice Chotard 314fadcaf0SPatrice Chotard #define STM32_I2C_CR1 0x00 324fadcaf0SPatrice Chotard #define STM32_I2C_CR2 0x04 334fadcaf0SPatrice Chotard #define STM32_I2C_TIMINGR 0x10 344fadcaf0SPatrice Chotard #define STM32_I2C_ISR 0x18 354fadcaf0SPatrice Chotard #define STM32_I2C_ICR 0x1C 364fadcaf0SPatrice Chotard #define STM32_I2C_RXDR 0x24 374fadcaf0SPatrice Chotard #define STM32_I2C_TXDR 0x28 384fadcaf0SPatrice Chotard 394fadcaf0SPatrice Chotard /* STM32 I2C control 1 */ 404fadcaf0SPatrice Chotard #define STM32_I2C_CR1_ANFOFF BIT(12) 414fadcaf0SPatrice Chotard #define STM32_I2C_CR1_ERRIE BIT(7) 424fadcaf0SPatrice Chotard #define STM32_I2C_CR1_TCIE BIT(6) 434fadcaf0SPatrice Chotard #define STM32_I2C_CR1_STOPIE BIT(5) 444fadcaf0SPatrice Chotard #define STM32_I2C_CR1_NACKIE BIT(4) 454fadcaf0SPatrice Chotard #define STM32_I2C_CR1_ADDRIE BIT(3) 464fadcaf0SPatrice Chotard #define STM32_I2C_CR1_RXIE BIT(2) 474fadcaf0SPatrice Chotard #define STM32_I2C_CR1_TXIE BIT(1) 484fadcaf0SPatrice Chotard #define STM32_I2C_CR1_PE BIT(0) 494fadcaf0SPatrice Chotard 504fadcaf0SPatrice Chotard /* STM32 I2C control 2 */ 514fadcaf0SPatrice Chotard #define STM32_I2C_CR2_AUTOEND BIT(25) 524fadcaf0SPatrice Chotard #define STM32_I2C_CR2_RELOAD BIT(24) 534fadcaf0SPatrice Chotard #define STM32_I2C_CR2_NBYTES_MASK GENMASK(23, 16) 544fadcaf0SPatrice Chotard #define STM32_I2C_CR2_NBYTES(n) ((n & 0xff) << 16) 554fadcaf0SPatrice Chotard #define STM32_I2C_CR2_NACK BIT(15) 564fadcaf0SPatrice Chotard #define STM32_I2C_CR2_STOP BIT(14) 574fadcaf0SPatrice Chotard #define STM32_I2C_CR2_START BIT(13) 584fadcaf0SPatrice Chotard #define STM32_I2C_CR2_HEAD10R BIT(12) 594fadcaf0SPatrice Chotard #define STM32_I2C_CR2_ADD10 BIT(11) 604fadcaf0SPatrice Chotard #define STM32_I2C_CR2_RD_WRN BIT(10) 614fadcaf0SPatrice Chotard #define STM32_I2C_CR2_SADD10_MASK GENMASK(9, 0) 624fadcaf0SPatrice Chotard #define STM32_I2C_CR2_SADD10(n) ((n & STM32_I2C_CR2_SADD10_MASK)) 634fadcaf0SPatrice Chotard #define STM32_I2C_CR2_SADD7_MASK GENMASK(7, 1) 644fadcaf0SPatrice Chotard #define STM32_I2C_CR2_SADD7(n) ((n & 0x7f) << 1) 654fadcaf0SPatrice Chotard #define STM32_I2C_CR2_RESET_MASK (STM32_I2C_CR2_HEAD10R \ 664fadcaf0SPatrice Chotard | STM32_I2C_CR2_NBYTES_MASK \ 674fadcaf0SPatrice Chotard | STM32_I2C_CR2_SADD7_MASK \ 684fadcaf0SPatrice Chotard | STM32_I2C_CR2_RELOAD \ 694fadcaf0SPatrice Chotard | STM32_I2C_CR2_RD_WRN) 704fadcaf0SPatrice Chotard 714fadcaf0SPatrice Chotard /* STM32 I2C Interrupt Status */ 724fadcaf0SPatrice Chotard #define STM32_I2C_ISR_BUSY BIT(15) 734fadcaf0SPatrice Chotard #define STM32_I2C_ISR_ARLO BIT(9) 744fadcaf0SPatrice Chotard #define STM32_I2C_ISR_BERR BIT(8) 754fadcaf0SPatrice Chotard #define STM32_I2C_ISR_TCR BIT(7) 764fadcaf0SPatrice Chotard #define STM32_I2C_ISR_TC BIT(6) 774fadcaf0SPatrice Chotard #define STM32_I2C_ISR_STOPF BIT(5) 784fadcaf0SPatrice Chotard #define STM32_I2C_ISR_NACKF BIT(4) 794fadcaf0SPatrice Chotard #define STM32_I2C_ISR_ADDR BIT(3) 804fadcaf0SPatrice Chotard #define STM32_I2C_ISR_RXNE BIT(2) 814fadcaf0SPatrice Chotard #define STM32_I2C_ISR_TXIS BIT(1) 824fadcaf0SPatrice Chotard #define STM32_I2C_ISR_TXE BIT(0) 834fadcaf0SPatrice Chotard #define STM32_I2C_ISR_ERRORS (STM32_I2C_ISR_BERR \ 844fadcaf0SPatrice Chotard | STM32_I2C_ISR_ARLO) 854fadcaf0SPatrice Chotard 864fadcaf0SPatrice Chotard /* STM32 I2C Interrupt Clear */ 874fadcaf0SPatrice Chotard #define STM32_I2C_ICR_ARLOCF BIT(9) 884fadcaf0SPatrice Chotard #define STM32_I2C_ICR_BERRCF BIT(8) 894fadcaf0SPatrice Chotard #define STM32_I2C_ICR_STOPCF BIT(5) 904fadcaf0SPatrice Chotard #define STM32_I2C_ICR_NACKCF BIT(4) 914fadcaf0SPatrice Chotard 924fadcaf0SPatrice Chotard /* STM32 I2C Timing */ 934fadcaf0SPatrice Chotard #define STM32_I2C_TIMINGR_PRESC(n) ((n & 0xf) << 28) 944fadcaf0SPatrice Chotard #define STM32_I2C_TIMINGR_SCLDEL(n) ((n & 0xf) << 20) 954fadcaf0SPatrice Chotard #define STM32_I2C_TIMINGR_SDADEL(n) ((n & 0xf) << 16) 964fadcaf0SPatrice Chotard #define STM32_I2C_TIMINGR_SCLH(n) ((n & 0xff) << 8) 974fadcaf0SPatrice Chotard #define STM32_I2C_TIMINGR_SCLL(n) (n & 0xff) 984fadcaf0SPatrice Chotard 994fadcaf0SPatrice Chotard #define STM32_I2C_MAX_LEN 0xff 1004fadcaf0SPatrice Chotard 1014fadcaf0SPatrice Chotard #define STM32_I2C_DNF_DEFAULT 0 1024fadcaf0SPatrice Chotard #define STM32_I2C_DNF_MAX 16 1034fadcaf0SPatrice Chotard 1044fadcaf0SPatrice Chotard #define STM32_I2C_ANALOG_FILTER_ENABLE 1 1054fadcaf0SPatrice Chotard #define STM32_I2C_ANALOG_FILTER_DELAY_MIN 50 /* ns */ 1064fadcaf0SPatrice Chotard #define STM32_I2C_ANALOG_FILTER_DELAY_MAX 260 /* ns */ 1074fadcaf0SPatrice Chotard 1084fadcaf0SPatrice Chotard #define STM32_I2C_RISE_TIME_DEFAULT 25 /* ns */ 1094fadcaf0SPatrice Chotard #define STM32_I2C_FALL_TIME_DEFAULT 10 /* ns */ 1104fadcaf0SPatrice Chotard 1114fadcaf0SPatrice Chotard #define STM32_PRESC_MAX BIT(4) 1124fadcaf0SPatrice Chotard #define STM32_SCLDEL_MAX BIT(4) 1134fadcaf0SPatrice Chotard #define STM32_SDADEL_MAX BIT(4) 1144fadcaf0SPatrice Chotard #define STM32_SCLH_MAX BIT(8) 1154fadcaf0SPatrice Chotard #define STM32_SCLL_MAX BIT(8) 1164fadcaf0SPatrice Chotard 1174fadcaf0SPatrice Chotard #define STM32_NSEC_PER_SEC 1000000000L 1184fadcaf0SPatrice Chotard 1194fadcaf0SPatrice Chotard #define STANDARD_RATE 100000 1204fadcaf0SPatrice Chotard #define FAST_RATE 400000 1214fadcaf0SPatrice Chotard #define FAST_PLUS_RATE 1000000 1224fadcaf0SPatrice Chotard 1234fadcaf0SPatrice Chotard enum stm32_i2c_speed { 1244fadcaf0SPatrice Chotard STM32_I2C_SPEED_STANDARD, /* 100 kHz */ 1254fadcaf0SPatrice Chotard STM32_I2C_SPEED_FAST, /* 400 kHz */ 1264fadcaf0SPatrice Chotard STM32_I2C_SPEED_FAST_PLUS, /* 1 MHz */ 1274fadcaf0SPatrice Chotard STM32_I2C_SPEED_END, 1284fadcaf0SPatrice Chotard }; 1294fadcaf0SPatrice Chotard 1304fadcaf0SPatrice Chotard /** 1314fadcaf0SPatrice Chotard * struct stm32_i2c_spec - private i2c specification timing 1324fadcaf0SPatrice Chotard * @rate: I2C bus speed (Hz) 1334fadcaf0SPatrice Chotard * @rate_min: 80% of I2C bus speed (Hz) 1344fadcaf0SPatrice Chotard * @rate_max: 120% of I2C bus speed (Hz) 1354fadcaf0SPatrice Chotard * @fall_max: Max fall time of both SDA and SCL signals (ns) 1364fadcaf0SPatrice Chotard * @rise_max: Max rise time of both SDA and SCL signals (ns) 1374fadcaf0SPatrice Chotard * @hddat_min: Min data hold time (ns) 1384fadcaf0SPatrice Chotard * @vddat_max: Max data valid time (ns) 1394fadcaf0SPatrice Chotard * @sudat_min: Min data setup time (ns) 1404fadcaf0SPatrice Chotard * @l_min: Min low period of the SCL clock (ns) 1414fadcaf0SPatrice Chotard * @h_min: Min high period of the SCL clock (ns) 1424fadcaf0SPatrice Chotard */ 1434fadcaf0SPatrice Chotard 1444fadcaf0SPatrice Chotard struct stm32_i2c_spec { 1454fadcaf0SPatrice Chotard u32 rate; 1464fadcaf0SPatrice Chotard u32 rate_min; 1474fadcaf0SPatrice Chotard u32 rate_max; 1484fadcaf0SPatrice Chotard u32 fall_max; 1494fadcaf0SPatrice Chotard u32 rise_max; 1504fadcaf0SPatrice Chotard u32 hddat_min; 1514fadcaf0SPatrice Chotard u32 vddat_max; 1524fadcaf0SPatrice Chotard u32 sudat_min; 1534fadcaf0SPatrice Chotard u32 l_min; 1544fadcaf0SPatrice Chotard u32 h_min; 1554fadcaf0SPatrice Chotard }; 1564fadcaf0SPatrice Chotard 1574fadcaf0SPatrice Chotard /** 1584fadcaf0SPatrice Chotard * struct stm32_i2c_setup - private I2C timing setup parameters 1594fadcaf0SPatrice Chotard * @speed: I2C speed mode (standard, Fast Plus) 1604fadcaf0SPatrice Chotard * @speed_freq: I2C speed frequency (Hz) 1614fadcaf0SPatrice Chotard * @clock_src: I2C clock source frequency (Hz) 1624fadcaf0SPatrice Chotard * @rise_time: Rise time (ns) 1634fadcaf0SPatrice Chotard * @fall_time: Fall time (ns) 1644fadcaf0SPatrice Chotard * @dnf: Digital filter coefficient (0-16) 1654fadcaf0SPatrice Chotard * @analog_filter: Analog filter delay (On/Off) 1664fadcaf0SPatrice Chotard */ 1674fadcaf0SPatrice Chotard struct stm32_i2c_setup { 1684fadcaf0SPatrice Chotard enum stm32_i2c_speed speed; 1694fadcaf0SPatrice Chotard u32 speed_freq; 1704fadcaf0SPatrice Chotard u32 clock_src; 1714fadcaf0SPatrice Chotard u32 rise_time; 1724fadcaf0SPatrice Chotard u32 fall_time; 1734fadcaf0SPatrice Chotard u8 dnf; 1744fadcaf0SPatrice Chotard bool analog_filter; 1754fadcaf0SPatrice Chotard }; 1764fadcaf0SPatrice Chotard 1774fadcaf0SPatrice Chotard /** 1784fadcaf0SPatrice Chotard * struct stm32_i2c_timings - private I2C output parameters 1794fadcaf0SPatrice Chotard * @prec: Prescaler value 1804fadcaf0SPatrice Chotard * @scldel: Data setup time 1814fadcaf0SPatrice Chotard * @sdadel: Data hold time 1824fadcaf0SPatrice Chotard * @sclh: SCL high period (master mode) 1834fadcaf0SPatrice Chotard * @sclh: SCL low period (master mode) 1844fadcaf0SPatrice Chotard */ 1854fadcaf0SPatrice Chotard struct stm32_i2c_timings { 1864fadcaf0SPatrice Chotard struct list_head node; 1874fadcaf0SPatrice Chotard u8 presc; 1884fadcaf0SPatrice Chotard u8 scldel; 1894fadcaf0SPatrice Chotard u8 sdadel; 1904fadcaf0SPatrice Chotard u8 sclh; 1914fadcaf0SPatrice Chotard u8 scll; 1924fadcaf0SPatrice Chotard }; 1934fadcaf0SPatrice Chotard 1944fadcaf0SPatrice Chotard struct stm32_i2c_priv { 1954fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs; 1964fadcaf0SPatrice Chotard struct clk clk; 1974fadcaf0SPatrice Chotard struct stm32_i2c_setup *setup; 1984fadcaf0SPatrice Chotard int speed; 1994fadcaf0SPatrice Chotard }; 2004fadcaf0SPatrice Chotard 2014fadcaf0SPatrice Chotard static struct stm32_i2c_spec i2c_specs[] = { 2024fadcaf0SPatrice Chotard [STM32_I2C_SPEED_STANDARD] = { 2034fadcaf0SPatrice Chotard .rate = STANDARD_RATE, 2044fadcaf0SPatrice Chotard .rate_min = 8000, 2054fadcaf0SPatrice Chotard .rate_max = 120000, 2064fadcaf0SPatrice Chotard .fall_max = 300, 2074fadcaf0SPatrice Chotard .rise_max = 1000, 2084fadcaf0SPatrice Chotard .hddat_min = 0, 2094fadcaf0SPatrice Chotard .vddat_max = 3450, 2104fadcaf0SPatrice Chotard .sudat_min = 250, 2114fadcaf0SPatrice Chotard .l_min = 4700, 2124fadcaf0SPatrice Chotard .h_min = 4000, 2134fadcaf0SPatrice Chotard }, 2144fadcaf0SPatrice Chotard [STM32_I2C_SPEED_FAST] = { 2154fadcaf0SPatrice Chotard .rate = FAST_RATE, 2164fadcaf0SPatrice Chotard .rate_min = 320000, 2174fadcaf0SPatrice Chotard .rate_max = 480000, 2184fadcaf0SPatrice Chotard .fall_max = 300, 2194fadcaf0SPatrice Chotard .rise_max = 300, 2204fadcaf0SPatrice Chotard .hddat_min = 0, 2214fadcaf0SPatrice Chotard .vddat_max = 900, 2224fadcaf0SPatrice Chotard .sudat_min = 100, 2234fadcaf0SPatrice Chotard .l_min = 1300, 2244fadcaf0SPatrice Chotard .h_min = 600, 2254fadcaf0SPatrice Chotard }, 2264fadcaf0SPatrice Chotard [STM32_I2C_SPEED_FAST_PLUS] = { 2274fadcaf0SPatrice Chotard .rate = FAST_PLUS_RATE, 2284fadcaf0SPatrice Chotard .rate_min = 800000, 2294fadcaf0SPatrice Chotard .rate_max = 1200000, 2304fadcaf0SPatrice Chotard .fall_max = 100, 2314fadcaf0SPatrice Chotard .rise_max = 120, 2324fadcaf0SPatrice Chotard .hddat_min = 0, 2334fadcaf0SPatrice Chotard .vddat_max = 450, 2344fadcaf0SPatrice Chotard .sudat_min = 50, 2354fadcaf0SPatrice Chotard .l_min = 500, 2364fadcaf0SPatrice Chotard .h_min = 260, 2374fadcaf0SPatrice Chotard }, 2384fadcaf0SPatrice Chotard }; 2394fadcaf0SPatrice Chotard 2404fadcaf0SPatrice Chotard static struct stm32_i2c_setup stm32f7_setup = { 2414fadcaf0SPatrice Chotard .rise_time = STM32_I2C_RISE_TIME_DEFAULT, 2424fadcaf0SPatrice Chotard .fall_time = STM32_I2C_FALL_TIME_DEFAULT, 2434fadcaf0SPatrice Chotard .dnf = STM32_I2C_DNF_DEFAULT, 2444fadcaf0SPatrice Chotard .analog_filter = STM32_I2C_ANALOG_FILTER_ENABLE, 2454fadcaf0SPatrice Chotard }; 2464fadcaf0SPatrice Chotard 2474fadcaf0SPatrice Chotard DECLARE_GLOBAL_DATA_PTR; 2484fadcaf0SPatrice Chotard 2494fadcaf0SPatrice Chotard static int stm32_i2c_check_device_busy(struct stm32_i2c_priv *i2c_priv) 2504fadcaf0SPatrice Chotard { 2514fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs = i2c_priv->regs; 2524fadcaf0SPatrice Chotard u32 status = readl(®s->isr); 2534fadcaf0SPatrice Chotard 2544fadcaf0SPatrice Chotard if (status & STM32_I2C_ISR_BUSY) 2554fadcaf0SPatrice Chotard return -EBUSY; 2564fadcaf0SPatrice Chotard 2574fadcaf0SPatrice Chotard return 0; 2584fadcaf0SPatrice Chotard } 2594fadcaf0SPatrice Chotard 2604fadcaf0SPatrice Chotard static void stm32_i2c_message_start(struct stm32_i2c_priv *i2c_priv, 2614fadcaf0SPatrice Chotard struct i2c_msg *msg, bool stop) 2624fadcaf0SPatrice Chotard { 2634fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs = i2c_priv->regs; 2644fadcaf0SPatrice Chotard u32 cr2 = readl(®s->cr2); 2654fadcaf0SPatrice Chotard 2664fadcaf0SPatrice Chotard /* Set transfer direction */ 2674fadcaf0SPatrice Chotard cr2 &= ~STM32_I2C_CR2_RD_WRN; 2684fadcaf0SPatrice Chotard if (msg->flags & I2C_M_RD) 2694fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_RD_WRN; 2704fadcaf0SPatrice Chotard 2714fadcaf0SPatrice Chotard /* Set slave address */ 2724fadcaf0SPatrice Chotard cr2 &= ~(STM32_I2C_CR2_HEAD10R | STM32_I2C_CR2_ADD10); 2734fadcaf0SPatrice Chotard if (msg->flags & I2C_M_TEN) { 2744fadcaf0SPatrice Chotard cr2 &= ~STM32_I2C_CR2_SADD10_MASK; 2754fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_SADD10(msg->addr); 2764fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_ADD10; 2774fadcaf0SPatrice Chotard } else { 2784fadcaf0SPatrice Chotard cr2 &= ~STM32_I2C_CR2_SADD7_MASK; 2794fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_SADD7(msg->addr); 2804fadcaf0SPatrice Chotard } 2814fadcaf0SPatrice Chotard 2824fadcaf0SPatrice Chotard /* Set nb bytes to transfer and reload or autoend bits */ 2834fadcaf0SPatrice Chotard cr2 &= ~(STM32_I2C_CR2_NBYTES_MASK | STM32_I2C_CR2_RELOAD | 2844fadcaf0SPatrice Chotard STM32_I2C_CR2_AUTOEND); 2854fadcaf0SPatrice Chotard if (msg->len > STM32_I2C_MAX_LEN) { 2864fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_NBYTES(STM32_I2C_MAX_LEN); 2874fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_RELOAD; 2884fadcaf0SPatrice Chotard } else { 2894fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_NBYTES(msg->len); 2904fadcaf0SPatrice Chotard } 2914fadcaf0SPatrice Chotard 2924fadcaf0SPatrice Chotard /* Write configurations register */ 2934fadcaf0SPatrice Chotard writel(cr2, ®s->cr2); 2944fadcaf0SPatrice Chotard 2954fadcaf0SPatrice Chotard /* START/ReSTART generation */ 2964fadcaf0SPatrice Chotard setbits_le32(®s->cr2, STM32_I2C_CR2_START); 2974fadcaf0SPatrice Chotard } 2984fadcaf0SPatrice Chotard 2994fadcaf0SPatrice Chotard /* 3004fadcaf0SPatrice Chotard * RELOAD mode must be selected if total number of data bytes to be 3014fadcaf0SPatrice Chotard * sent is greater than MAX_LEN 3024fadcaf0SPatrice Chotard */ 3034fadcaf0SPatrice Chotard 3044fadcaf0SPatrice Chotard static void stm32_i2c_handle_reload(struct stm32_i2c_priv *i2c_priv, 3054fadcaf0SPatrice Chotard struct i2c_msg *msg, bool stop) 3064fadcaf0SPatrice Chotard { 3074fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs = i2c_priv->regs; 3084fadcaf0SPatrice Chotard u32 cr2 = readl(®s->cr2); 3094fadcaf0SPatrice Chotard 3104fadcaf0SPatrice Chotard cr2 &= ~STM32_I2C_CR2_NBYTES_MASK; 3114fadcaf0SPatrice Chotard 3124fadcaf0SPatrice Chotard if (msg->len > STM32_I2C_MAX_LEN) { 3134fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_NBYTES(STM32_I2C_MAX_LEN); 3144fadcaf0SPatrice Chotard } else { 3154fadcaf0SPatrice Chotard cr2 &= ~STM32_I2C_CR2_RELOAD; 3164fadcaf0SPatrice Chotard cr2 |= STM32_I2C_CR2_NBYTES(msg->len); 3174fadcaf0SPatrice Chotard } 3184fadcaf0SPatrice Chotard 3194fadcaf0SPatrice Chotard writel(cr2, ®s->cr2); 3204fadcaf0SPatrice Chotard } 3214fadcaf0SPatrice Chotard 3224fadcaf0SPatrice Chotard static int stm32_i2c_wait_flags(struct stm32_i2c_priv *i2c_priv, 3234fadcaf0SPatrice Chotard u32 flags, u32 *status) 3244fadcaf0SPatrice Chotard { 3254fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs = i2c_priv->regs; 3264fadcaf0SPatrice Chotard u32 time_start = get_timer(0); 3274fadcaf0SPatrice Chotard 3284fadcaf0SPatrice Chotard *status = readl(®s->isr); 3294fadcaf0SPatrice Chotard while (!(*status & flags)) { 3304fadcaf0SPatrice Chotard if (get_timer(time_start) > CONFIG_SYS_HZ) { 3314fadcaf0SPatrice Chotard debug("%s: i2c timeout\n", __func__); 3324fadcaf0SPatrice Chotard return -ETIMEDOUT; 3334fadcaf0SPatrice Chotard } 3344fadcaf0SPatrice Chotard 3354fadcaf0SPatrice Chotard *status = readl(®s->isr); 3364fadcaf0SPatrice Chotard } 3374fadcaf0SPatrice Chotard 3384fadcaf0SPatrice Chotard return 0; 3394fadcaf0SPatrice Chotard } 3404fadcaf0SPatrice Chotard 3414fadcaf0SPatrice Chotard static int stm32_i2c_check_end_of_message(struct stm32_i2c_priv *i2c_priv) 3424fadcaf0SPatrice Chotard { 3434fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs = i2c_priv->regs; 3444fadcaf0SPatrice Chotard u32 mask = STM32_I2C_ISR_ERRORS | STM32_I2C_ISR_NACKF | 3454fadcaf0SPatrice Chotard STM32_I2C_ISR_STOPF; 3464fadcaf0SPatrice Chotard u32 status; 3474fadcaf0SPatrice Chotard int ret; 3484fadcaf0SPatrice Chotard 3494fadcaf0SPatrice Chotard ret = stm32_i2c_wait_flags(i2c_priv, mask, &status); 3504fadcaf0SPatrice Chotard if (ret) 3514fadcaf0SPatrice Chotard return ret; 3524fadcaf0SPatrice Chotard 3534fadcaf0SPatrice Chotard if (status & STM32_I2C_ISR_BERR) { 3544fadcaf0SPatrice Chotard debug("%s: Bus error\n", __func__); 3554fadcaf0SPatrice Chotard 3564fadcaf0SPatrice Chotard /* Clear BERR flag */ 3574fadcaf0SPatrice Chotard setbits_le32(®s->icr, STM32_I2C_ICR_BERRCF); 3584fadcaf0SPatrice Chotard 3594fadcaf0SPatrice Chotard return -EIO; 3604fadcaf0SPatrice Chotard } 3614fadcaf0SPatrice Chotard 3624fadcaf0SPatrice Chotard if (status & STM32_I2C_ISR_ARLO) { 3634fadcaf0SPatrice Chotard debug("%s: Arbitration lost\n", __func__); 3644fadcaf0SPatrice Chotard 3654fadcaf0SPatrice Chotard /* Clear ARLO flag */ 3664fadcaf0SPatrice Chotard setbits_le32(®s->icr, STM32_I2C_ICR_ARLOCF); 3674fadcaf0SPatrice Chotard 3684fadcaf0SPatrice Chotard return -EAGAIN; 3694fadcaf0SPatrice Chotard } 3704fadcaf0SPatrice Chotard 3714fadcaf0SPatrice Chotard if (status & STM32_I2C_ISR_NACKF) { 3724fadcaf0SPatrice Chotard debug("%s: Receive NACK\n", __func__); 3734fadcaf0SPatrice Chotard 3744fadcaf0SPatrice Chotard /* Clear NACK flag */ 3754fadcaf0SPatrice Chotard setbits_le32(®s->icr, STM32_I2C_ICR_NACKCF); 3764fadcaf0SPatrice Chotard 3774fadcaf0SPatrice Chotard /* Wait until STOPF flag is set */ 3784fadcaf0SPatrice Chotard mask = STM32_I2C_ISR_STOPF; 3794fadcaf0SPatrice Chotard ret = stm32_i2c_wait_flags(i2c_priv, mask, &status); 3804fadcaf0SPatrice Chotard if (ret) 3814fadcaf0SPatrice Chotard return ret; 3824fadcaf0SPatrice Chotard 3834fadcaf0SPatrice Chotard ret = -EIO; 3844fadcaf0SPatrice Chotard } 3854fadcaf0SPatrice Chotard 3864fadcaf0SPatrice Chotard if (status & STM32_I2C_ISR_STOPF) { 3874fadcaf0SPatrice Chotard /* Clear STOP flag */ 3884fadcaf0SPatrice Chotard setbits_le32(®s->icr, STM32_I2C_ICR_STOPCF); 3894fadcaf0SPatrice Chotard 3904fadcaf0SPatrice Chotard /* Clear control register 2 */ 3914fadcaf0SPatrice Chotard setbits_le32(®s->cr2, STM32_I2C_CR2_RESET_MASK); 3924fadcaf0SPatrice Chotard } 3934fadcaf0SPatrice Chotard 3944fadcaf0SPatrice Chotard return ret; 3954fadcaf0SPatrice Chotard } 3964fadcaf0SPatrice Chotard 3974fadcaf0SPatrice Chotard static int stm32_i2c_message_xfer(struct stm32_i2c_priv *i2c_priv, 3984fadcaf0SPatrice Chotard struct i2c_msg *msg, bool stop) 3994fadcaf0SPatrice Chotard { 4004fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs = i2c_priv->regs; 4014fadcaf0SPatrice Chotard u32 status; 4024fadcaf0SPatrice Chotard u32 mask = msg->flags & I2C_M_RD ? STM32_I2C_ISR_RXNE : 4034fadcaf0SPatrice Chotard STM32_I2C_ISR_TXIS | STM32_I2C_ISR_NACKF; 4044fadcaf0SPatrice Chotard int bytes_to_rw = msg->len > STM32_I2C_MAX_LEN ? 4054fadcaf0SPatrice Chotard STM32_I2C_MAX_LEN : msg->len; 4064fadcaf0SPatrice Chotard int ret = 0; 4074fadcaf0SPatrice Chotard 4084fadcaf0SPatrice Chotard /* Add errors */ 4094fadcaf0SPatrice Chotard mask |= STM32_I2C_ISR_ERRORS; 4104fadcaf0SPatrice Chotard 4114fadcaf0SPatrice Chotard stm32_i2c_message_start(i2c_priv, msg, stop); 4124fadcaf0SPatrice Chotard 4134fadcaf0SPatrice Chotard while (msg->len) { 4144fadcaf0SPatrice Chotard /* 4154fadcaf0SPatrice Chotard * Wait until TXIS/NACKF/BERR/ARLO flags or 4164fadcaf0SPatrice Chotard * RXNE/BERR/ARLO flags are set 4174fadcaf0SPatrice Chotard */ 4184fadcaf0SPatrice Chotard ret = stm32_i2c_wait_flags(i2c_priv, mask, &status); 4194fadcaf0SPatrice Chotard if (ret) 4204fadcaf0SPatrice Chotard break; 4214fadcaf0SPatrice Chotard 4224fadcaf0SPatrice Chotard if (status & (STM32_I2C_ISR_NACKF | STM32_I2C_ISR_ERRORS)) 4234fadcaf0SPatrice Chotard break; 4244fadcaf0SPatrice Chotard 4254fadcaf0SPatrice Chotard if (status & STM32_I2C_ISR_RXNE) { 4264fadcaf0SPatrice Chotard *msg->buf++ = readb(®s->rxdr); 4274fadcaf0SPatrice Chotard msg->len--; 4284fadcaf0SPatrice Chotard bytes_to_rw--; 4294fadcaf0SPatrice Chotard } 4304fadcaf0SPatrice Chotard 4314fadcaf0SPatrice Chotard if (status & STM32_I2C_ISR_TXIS) { 4324fadcaf0SPatrice Chotard writeb(*msg->buf++, ®s->txdr); 4334fadcaf0SPatrice Chotard msg->len--; 4344fadcaf0SPatrice Chotard bytes_to_rw--; 4354fadcaf0SPatrice Chotard } 4364fadcaf0SPatrice Chotard 4374fadcaf0SPatrice Chotard if (!bytes_to_rw && msg->len) { 4384fadcaf0SPatrice Chotard /* Wait until TCR flag is set */ 4394fadcaf0SPatrice Chotard mask = STM32_I2C_ISR_TCR; 4404fadcaf0SPatrice Chotard ret = stm32_i2c_wait_flags(i2c_priv, mask, &status); 4414fadcaf0SPatrice Chotard if (ret) 4424fadcaf0SPatrice Chotard break; 4434fadcaf0SPatrice Chotard 4444fadcaf0SPatrice Chotard bytes_to_rw = msg->len > STM32_I2C_MAX_LEN ? 4454fadcaf0SPatrice Chotard STM32_I2C_MAX_LEN : msg->len; 4464fadcaf0SPatrice Chotard mask = msg->flags & I2C_M_RD ? STM32_I2C_ISR_RXNE : 4474fadcaf0SPatrice Chotard STM32_I2C_ISR_TXIS | STM32_I2C_ISR_NACKF; 4484fadcaf0SPatrice Chotard 4494fadcaf0SPatrice Chotard stm32_i2c_handle_reload(i2c_priv, msg, stop); 4504fadcaf0SPatrice Chotard } else if (!bytes_to_rw) { 4514fadcaf0SPatrice Chotard /* Wait until TC flag is set */ 4524fadcaf0SPatrice Chotard mask = STM32_I2C_ISR_TC; 4534fadcaf0SPatrice Chotard ret = stm32_i2c_wait_flags(i2c_priv, mask, &status); 4544fadcaf0SPatrice Chotard if (ret) 4554fadcaf0SPatrice Chotard break; 4564fadcaf0SPatrice Chotard 4574fadcaf0SPatrice Chotard if (!stop) 4584fadcaf0SPatrice Chotard /* Message sent, new message has to be sent */ 4594fadcaf0SPatrice Chotard return 0; 4604fadcaf0SPatrice Chotard } 4614fadcaf0SPatrice Chotard } 4624fadcaf0SPatrice Chotard 4634fadcaf0SPatrice Chotard /* End of transfer, send stop condition */ 4644fadcaf0SPatrice Chotard mask = STM32_I2C_CR2_STOP; 4654fadcaf0SPatrice Chotard setbits_le32(®s->cr2, mask); 4664fadcaf0SPatrice Chotard 4674fadcaf0SPatrice Chotard return stm32_i2c_check_end_of_message(i2c_priv); 4684fadcaf0SPatrice Chotard } 4694fadcaf0SPatrice Chotard 4704fadcaf0SPatrice Chotard static int stm32_i2c_xfer(struct udevice *bus, struct i2c_msg *msg, 4714fadcaf0SPatrice Chotard int nmsgs) 4724fadcaf0SPatrice Chotard { 4734fadcaf0SPatrice Chotard struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); 4744fadcaf0SPatrice Chotard int ret; 4754fadcaf0SPatrice Chotard 4764fadcaf0SPatrice Chotard ret = stm32_i2c_check_device_busy(i2c_priv); 4774fadcaf0SPatrice Chotard if (ret) 4784fadcaf0SPatrice Chotard return ret; 4794fadcaf0SPatrice Chotard 4804fadcaf0SPatrice Chotard for (; nmsgs > 0; nmsgs--, msg++) { 4814fadcaf0SPatrice Chotard ret = stm32_i2c_message_xfer(i2c_priv, msg, nmsgs == 1); 4824fadcaf0SPatrice Chotard if (ret) 4834fadcaf0SPatrice Chotard return ret; 4844fadcaf0SPatrice Chotard } 4854fadcaf0SPatrice Chotard 4864fadcaf0SPatrice Chotard return 0; 4874fadcaf0SPatrice Chotard } 4884fadcaf0SPatrice Chotard 4894fadcaf0SPatrice Chotard static int stm32_i2c_compute_solutions(struct stm32_i2c_setup *setup, 4904fadcaf0SPatrice Chotard struct list_head *solutions) 4914fadcaf0SPatrice Chotard { 4924fadcaf0SPatrice Chotard struct stm32_i2c_timings *v; 4934fadcaf0SPatrice Chotard u32 p_prev = STM32_PRESC_MAX; 4944fadcaf0SPatrice Chotard u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, 4954fadcaf0SPatrice Chotard setup->clock_src); 4964fadcaf0SPatrice Chotard u32 af_delay_min, af_delay_max; 4974fadcaf0SPatrice Chotard u16 p, l, a; 4984fadcaf0SPatrice Chotard int sdadel_min, sdadel_max, scldel_min; 4994fadcaf0SPatrice Chotard int ret = 0; 5004fadcaf0SPatrice Chotard 5014fadcaf0SPatrice Chotard af_delay_min = setup->analog_filter ? 5024fadcaf0SPatrice Chotard STM32_I2C_ANALOG_FILTER_DELAY_MIN : 0; 5034fadcaf0SPatrice Chotard af_delay_max = setup->analog_filter ? 5044fadcaf0SPatrice Chotard STM32_I2C_ANALOG_FILTER_DELAY_MAX : 0; 5054fadcaf0SPatrice Chotard 5064fadcaf0SPatrice Chotard sdadel_min = setup->fall_time - i2c_specs[setup->speed].hddat_min - 5074fadcaf0SPatrice Chotard af_delay_min - (setup->dnf + 3) * i2cclk; 5084fadcaf0SPatrice Chotard 5094fadcaf0SPatrice Chotard sdadel_max = i2c_specs[setup->speed].vddat_max - setup->rise_time - 5104fadcaf0SPatrice Chotard af_delay_max - (setup->dnf + 4) * i2cclk; 5114fadcaf0SPatrice Chotard 5124fadcaf0SPatrice Chotard scldel_min = setup->rise_time + i2c_specs[setup->speed].sudat_min; 5134fadcaf0SPatrice Chotard 5144fadcaf0SPatrice Chotard if (sdadel_min < 0) 5154fadcaf0SPatrice Chotard sdadel_min = 0; 5164fadcaf0SPatrice Chotard if (sdadel_max < 0) 5174fadcaf0SPatrice Chotard sdadel_max = 0; 5184fadcaf0SPatrice Chotard 5194fadcaf0SPatrice Chotard debug("%s: SDADEL(min/max): %i/%i, SCLDEL(Min): %i\n", __func__, 5204fadcaf0SPatrice Chotard sdadel_min, sdadel_max, scldel_min); 5214fadcaf0SPatrice Chotard 5224fadcaf0SPatrice Chotard /* Compute possible values for PRESC, SCLDEL and SDADEL */ 5234fadcaf0SPatrice Chotard for (p = 0; p < STM32_PRESC_MAX; p++) { 5244fadcaf0SPatrice Chotard for (l = 0; l < STM32_SCLDEL_MAX; l++) { 5254fadcaf0SPatrice Chotard u32 scldel = (l + 1) * (p + 1) * i2cclk; 5264fadcaf0SPatrice Chotard 5274fadcaf0SPatrice Chotard if (scldel < scldel_min) 5284fadcaf0SPatrice Chotard continue; 5294fadcaf0SPatrice Chotard 5304fadcaf0SPatrice Chotard for (a = 0; a < STM32_SDADEL_MAX; a++) { 5314fadcaf0SPatrice Chotard u32 sdadel = (a * (p + 1) + 1) * i2cclk; 5324fadcaf0SPatrice Chotard 5334fadcaf0SPatrice Chotard if (((sdadel >= sdadel_min) && 5344fadcaf0SPatrice Chotard (sdadel <= sdadel_max)) && 5354fadcaf0SPatrice Chotard (p != p_prev)) { 5364fadcaf0SPatrice Chotard v = kmalloc(sizeof(*v), GFP_KERNEL); 5374fadcaf0SPatrice Chotard if (!v) 5384fadcaf0SPatrice Chotard return -ENOMEM; 5394fadcaf0SPatrice Chotard 5404fadcaf0SPatrice Chotard v->presc = p; 5414fadcaf0SPatrice Chotard v->scldel = l; 5424fadcaf0SPatrice Chotard v->sdadel = a; 5434fadcaf0SPatrice Chotard p_prev = p; 5444fadcaf0SPatrice Chotard 5454fadcaf0SPatrice Chotard list_add_tail(&v->node, solutions); 5464fadcaf0SPatrice Chotard } 5474fadcaf0SPatrice Chotard } 5484fadcaf0SPatrice Chotard } 5494fadcaf0SPatrice Chotard } 5504fadcaf0SPatrice Chotard 5514fadcaf0SPatrice Chotard if (list_empty(solutions)) { 5529b643e31SMasahiro Yamada pr_err("%s: no Prescaler solution\n", __func__); 5534fadcaf0SPatrice Chotard ret = -EPERM; 5544fadcaf0SPatrice Chotard } 5554fadcaf0SPatrice Chotard 5564fadcaf0SPatrice Chotard return ret; 5574fadcaf0SPatrice Chotard } 5584fadcaf0SPatrice Chotard 5594fadcaf0SPatrice Chotard static int stm32_i2c_choose_solution(struct stm32_i2c_setup *setup, 5604fadcaf0SPatrice Chotard struct list_head *solutions, 5614fadcaf0SPatrice Chotard struct stm32_i2c_timings *s) 5624fadcaf0SPatrice Chotard { 5634fadcaf0SPatrice Chotard struct stm32_i2c_timings *v; 5644fadcaf0SPatrice Chotard u32 i2cbus = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, 5654fadcaf0SPatrice Chotard setup->speed_freq); 5664fadcaf0SPatrice Chotard u32 clk_error_prev = i2cbus; 5674fadcaf0SPatrice Chotard u32 i2cclk = DIV_ROUND_CLOSEST(STM32_NSEC_PER_SEC, 5684fadcaf0SPatrice Chotard setup->clock_src); 5694fadcaf0SPatrice Chotard u32 clk_min, clk_max; 5704fadcaf0SPatrice Chotard u32 af_delay_min; 5714fadcaf0SPatrice Chotard u32 dnf_delay; 5724fadcaf0SPatrice Chotard u32 tsync; 5734fadcaf0SPatrice Chotard u16 l, h; 57481c48437SChristophe Kerello bool sol_found = false; 5754fadcaf0SPatrice Chotard int ret = 0; 5764fadcaf0SPatrice Chotard 5774fadcaf0SPatrice Chotard af_delay_min = setup->analog_filter ? 5784fadcaf0SPatrice Chotard STM32_I2C_ANALOG_FILTER_DELAY_MIN : 0; 5794fadcaf0SPatrice Chotard dnf_delay = setup->dnf * i2cclk; 5804fadcaf0SPatrice Chotard 5814fadcaf0SPatrice Chotard tsync = af_delay_min + dnf_delay + (2 * i2cclk); 5824fadcaf0SPatrice Chotard clk_max = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_min; 5834fadcaf0SPatrice Chotard clk_min = STM32_NSEC_PER_SEC / i2c_specs[setup->speed].rate_max; 5844fadcaf0SPatrice Chotard 5854fadcaf0SPatrice Chotard /* 5864fadcaf0SPatrice Chotard * Among Prescaler possibilities discovered above figures out SCL Low 5874fadcaf0SPatrice Chotard * and High Period. Provided: 5884fadcaf0SPatrice Chotard * - SCL Low Period has to be higher than Low Period of the SCL Clock 5894fadcaf0SPatrice Chotard * defined by I2C Specification. I2C Clock has to be lower than 5904fadcaf0SPatrice Chotard * (SCL Low Period - Analog/Digital filters) / 4. 5914fadcaf0SPatrice Chotard * - SCL High Period has to be lower than High Period of the SCL Clock 5924fadcaf0SPatrice Chotard * defined by I2C Specification 5934fadcaf0SPatrice Chotard * - I2C Clock has to be lower than SCL High Period 5944fadcaf0SPatrice Chotard */ 5954fadcaf0SPatrice Chotard list_for_each_entry(v, solutions, node) { 5964fadcaf0SPatrice Chotard u32 prescaler = (v->presc + 1) * i2cclk; 5974fadcaf0SPatrice Chotard 5984fadcaf0SPatrice Chotard for (l = 0; l < STM32_SCLL_MAX; l++) { 5994fadcaf0SPatrice Chotard u32 tscl_l = (l + 1) * prescaler + tsync; 6004fadcaf0SPatrice Chotard if ((tscl_l < i2c_specs[setup->speed].l_min) || 6014fadcaf0SPatrice Chotard (i2cclk >= 6024fadcaf0SPatrice Chotard ((tscl_l - af_delay_min - dnf_delay) / 4))) { 6034fadcaf0SPatrice Chotard continue; 6044fadcaf0SPatrice Chotard } 6054fadcaf0SPatrice Chotard 6064fadcaf0SPatrice Chotard for (h = 0; h < STM32_SCLH_MAX; h++) { 6074fadcaf0SPatrice Chotard u32 tscl_h = (h + 1) * prescaler + tsync; 6084fadcaf0SPatrice Chotard u32 tscl = tscl_l + tscl_h + 6094fadcaf0SPatrice Chotard setup->rise_time + setup->fall_time; 6104fadcaf0SPatrice Chotard 6114fadcaf0SPatrice Chotard if ((tscl >= clk_min) && (tscl <= clk_max) && 6124fadcaf0SPatrice Chotard (tscl_h >= i2c_specs[setup->speed].h_min) && 6134fadcaf0SPatrice Chotard (i2cclk < tscl_h)) { 6144fadcaf0SPatrice Chotard int clk_error = tscl - i2cbus; 6154fadcaf0SPatrice Chotard 6164fadcaf0SPatrice Chotard if (clk_error < 0) 6174fadcaf0SPatrice Chotard clk_error = -clk_error; 6184fadcaf0SPatrice Chotard 6194fadcaf0SPatrice Chotard if (clk_error < clk_error_prev) { 6204fadcaf0SPatrice Chotard clk_error_prev = clk_error; 6214fadcaf0SPatrice Chotard v->scll = l; 6224fadcaf0SPatrice Chotard v->sclh = h; 62381c48437SChristophe Kerello sol_found = true; 62481c48437SChristophe Kerello memcpy(s, v, sizeof(*s)); 6254fadcaf0SPatrice Chotard } 6264fadcaf0SPatrice Chotard } 6274fadcaf0SPatrice Chotard } 6284fadcaf0SPatrice Chotard } 6294fadcaf0SPatrice Chotard } 6304fadcaf0SPatrice Chotard 63181c48437SChristophe Kerello if (!sol_found) { 6329b643e31SMasahiro Yamada pr_err("%s: no solution at all\n", __func__); 6334fadcaf0SPatrice Chotard ret = -EPERM; 6344fadcaf0SPatrice Chotard } 6354fadcaf0SPatrice Chotard 6364fadcaf0SPatrice Chotard return ret; 6374fadcaf0SPatrice Chotard } 6384fadcaf0SPatrice Chotard 6394fadcaf0SPatrice Chotard static int stm32_i2c_compute_timing(struct stm32_i2c_priv *i2c_priv, 6404fadcaf0SPatrice Chotard struct stm32_i2c_setup *setup, 6414fadcaf0SPatrice Chotard struct stm32_i2c_timings *output) 6424fadcaf0SPatrice Chotard { 643*d10bd6cfSPatrice Chotard struct stm32_i2c_timings *v, *_v; 6444fadcaf0SPatrice Chotard struct list_head solutions; 6454fadcaf0SPatrice Chotard int ret; 6464fadcaf0SPatrice Chotard 6474fadcaf0SPatrice Chotard if (setup->speed >= STM32_I2C_SPEED_END) { 6489b643e31SMasahiro Yamada pr_err("%s: speed out of bound {%d/%d}\n", __func__, 6494fadcaf0SPatrice Chotard setup->speed, STM32_I2C_SPEED_END - 1); 6504fadcaf0SPatrice Chotard return -EINVAL; 6514fadcaf0SPatrice Chotard } 6524fadcaf0SPatrice Chotard 6534fadcaf0SPatrice Chotard if ((setup->rise_time > i2c_specs[setup->speed].rise_max) || 6544fadcaf0SPatrice Chotard (setup->fall_time > i2c_specs[setup->speed].fall_max)) { 6559b643e31SMasahiro Yamada pr_err("%s :timings out of bound Rise{%d>%d}/Fall{%d>%d}\n", 6564fadcaf0SPatrice Chotard __func__, 6574fadcaf0SPatrice Chotard setup->rise_time, i2c_specs[setup->speed].rise_max, 6584fadcaf0SPatrice Chotard setup->fall_time, i2c_specs[setup->speed].fall_max); 6594fadcaf0SPatrice Chotard return -EINVAL; 6604fadcaf0SPatrice Chotard } 6614fadcaf0SPatrice Chotard 6624fadcaf0SPatrice Chotard if (setup->dnf > STM32_I2C_DNF_MAX) { 6639b643e31SMasahiro Yamada pr_err("%s: DNF out of bound %d/%d\n", __func__, 6644fadcaf0SPatrice Chotard setup->dnf, STM32_I2C_DNF_MAX); 6654fadcaf0SPatrice Chotard return -EINVAL; 6664fadcaf0SPatrice Chotard } 6674fadcaf0SPatrice Chotard 6684fadcaf0SPatrice Chotard if (setup->speed_freq > i2c_specs[setup->speed].rate) { 6699b643e31SMasahiro Yamada pr_err("%s: Freq {%d/%d}\n", __func__, 6704fadcaf0SPatrice Chotard setup->speed_freq, i2c_specs[setup->speed].rate); 6714fadcaf0SPatrice Chotard return -EINVAL; 6724fadcaf0SPatrice Chotard } 6734fadcaf0SPatrice Chotard 6744fadcaf0SPatrice Chotard INIT_LIST_HEAD(&solutions); 6754fadcaf0SPatrice Chotard ret = stm32_i2c_compute_solutions(setup, &solutions); 6764fadcaf0SPatrice Chotard if (ret) 6774fadcaf0SPatrice Chotard goto exit; 6784fadcaf0SPatrice Chotard 679*d10bd6cfSPatrice Chotard ret = stm32_i2c_choose_solution(setup, &solutions, output); 6804fadcaf0SPatrice Chotard if (ret) 6814fadcaf0SPatrice Chotard goto exit; 6824fadcaf0SPatrice Chotard 6834fadcaf0SPatrice Chotard debug("%s: Presc: %i, scldel: %i, sdadel: %i, scll: %i, sclh: %i\n", 6844fadcaf0SPatrice Chotard __func__, output->presc, 6854fadcaf0SPatrice Chotard output->scldel, output->sdadel, 6864fadcaf0SPatrice Chotard output->scll, output->sclh); 6874fadcaf0SPatrice Chotard 6884fadcaf0SPatrice Chotard exit: 6894fadcaf0SPatrice Chotard /* Release list and memory */ 6904fadcaf0SPatrice Chotard list_for_each_entry_safe(v, _v, &solutions, node) { 6914fadcaf0SPatrice Chotard list_del(&v->node); 6924fadcaf0SPatrice Chotard kfree(v); 6934fadcaf0SPatrice Chotard } 6944fadcaf0SPatrice Chotard 6954fadcaf0SPatrice Chotard return ret; 6964fadcaf0SPatrice Chotard } 6974fadcaf0SPatrice Chotard 6984fadcaf0SPatrice Chotard static int stm32_i2c_setup_timing(struct stm32_i2c_priv *i2c_priv, 6994fadcaf0SPatrice Chotard struct stm32_i2c_timings *timing) 7004fadcaf0SPatrice Chotard { 7014fadcaf0SPatrice Chotard struct stm32_i2c_setup *setup = i2c_priv->setup; 7024fadcaf0SPatrice Chotard int ret = 0; 7034fadcaf0SPatrice Chotard 7044fadcaf0SPatrice Chotard setup->speed = i2c_priv->speed; 7054fadcaf0SPatrice Chotard setup->speed_freq = i2c_specs[setup->speed].rate; 7064fadcaf0SPatrice Chotard setup->clock_src = clk_get_rate(&i2c_priv->clk); 7074fadcaf0SPatrice Chotard 7084fadcaf0SPatrice Chotard if (!setup->clock_src) { 7099b643e31SMasahiro Yamada pr_err("%s: clock rate is 0\n", __func__); 7104fadcaf0SPatrice Chotard return -EINVAL; 7114fadcaf0SPatrice Chotard } 7124fadcaf0SPatrice Chotard 7134fadcaf0SPatrice Chotard do { 7144fadcaf0SPatrice Chotard ret = stm32_i2c_compute_timing(i2c_priv, setup, timing); 7154fadcaf0SPatrice Chotard if (ret) { 7164fadcaf0SPatrice Chotard debug("%s: failed to compute I2C timings.\n", 7174fadcaf0SPatrice Chotard __func__); 7184fadcaf0SPatrice Chotard if (i2c_priv->speed > STM32_I2C_SPEED_STANDARD) { 7194fadcaf0SPatrice Chotard i2c_priv->speed--; 7204fadcaf0SPatrice Chotard setup->speed = i2c_priv->speed; 7214fadcaf0SPatrice Chotard setup->speed_freq = 7224fadcaf0SPatrice Chotard i2c_specs[setup->speed].rate; 7234fadcaf0SPatrice Chotard debug("%s: downgrade I2C Speed Freq to (%i)\n", 7244fadcaf0SPatrice Chotard __func__, i2c_specs[setup->speed].rate); 7254fadcaf0SPatrice Chotard } else { 7264fadcaf0SPatrice Chotard break; 7274fadcaf0SPatrice Chotard } 7284fadcaf0SPatrice Chotard } 7294fadcaf0SPatrice Chotard } while (ret); 7304fadcaf0SPatrice Chotard 7314fadcaf0SPatrice Chotard if (ret) { 7329b643e31SMasahiro Yamada pr_err("%s: impossible to compute I2C timings.\n", __func__); 7334fadcaf0SPatrice Chotard return ret; 7344fadcaf0SPatrice Chotard } 7354fadcaf0SPatrice Chotard 7364fadcaf0SPatrice Chotard debug("%s: I2C Speed(%i), Freq(%i), Clk Source(%i)\n", __func__, 7374fadcaf0SPatrice Chotard setup->speed, setup->speed_freq, setup->clock_src); 7384fadcaf0SPatrice Chotard debug("%s: I2C Rise(%i) and Fall(%i) Time\n", __func__, 7394fadcaf0SPatrice Chotard setup->rise_time, setup->fall_time); 7404fadcaf0SPatrice Chotard debug("%s: I2C Analog Filter(%s), DNF(%i)\n", __func__, 7414fadcaf0SPatrice Chotard setup->analog_filter ? "On" : "Off", setup->dnf); 7424fadcaf0SPatrice Chotard 7434fadcaf0SPatrice Chotard return 0; 7444fadcaf0SPatrice Chotard } 7454fadcaf0SPatrice Chotard 7464fadcaf0SPatrice Chotard static int stm32_i2c_hw_config(struct stm32_i2c_priv *i2c_priv) 7474fadcaf0SPatrice Chotard { 7484fadcaf0SPatrice Chotard struct stm32_i2c_regs *regs = i2c_priv->regs; 7494fadcaf0SPatrice Chotard struct stm32_i2c_timings t; 7504fadcaf0SPatrice Chotard int ret; 7514fadcaf0SPatrice Chotard u32 timing = 0; 7524fadcaf0SPatrice Chotard 7534fadcaf0SPatrice Chotard ret = stm32_i2c_setup_timing(i2c_priv, &t); 7544fadcaf0SPatrice Chotard if (ret) 7554fadcaf0SPatrice Chotard return ret; 7564fadcaf0SPatrice Chotard 7574fadcaf0SPatrice Chotard /* Disable I2C */ 7584fadcaf0SPatrice Chotard clrbits_le32(®s->cr1, STM32_I2C_CR1_PE); 7594fadcaf0SPatrice Chotard 7604fadcaf0SPatrice Chotard /* Timing settings */ 7614fadcaf0SPatrice Chotard timing |= STM32_I2C_TIMINGR_PRESC(t.presc); 7624fadcaf0SPatrice Chotard timing |= STM32_I2C_TIMINGR_SCLDEL(t.scldel); 7634fadcaf0SPatrice Chotard timing |= STM32_I2C_TIMINGR_SDADEL(t.sdadel); 7644fadcaf0SPatrice Chotard timing |= STM32_I2C_TIMINGR_SCLH(t.sclh); 7654fadcaf0SPatrice Chotard timing |= STM32_I2C_TIMINGR_SCLL(t.scll); 7664fadcaf0SPatrice Chotard writel(timing, ®s->timingr); 7674fadcaf0SPatrice Chotard 7684fadcaf0SPatrice Chotard /* Enable I2C */ 7694fadcaf0SPatrice Chotard if (i2c_priv->setup->analog_filter) 7704fadcaf0SPatrice Chotard clrbits_le32(®s->cr1, STM32_I2C_CR1_ANFOFF); 7714fadcaf0SPatrice Chotard else 7724fadcaf0SPatrice Chotard setbits_le32(®s->cr1, STM32_I2C_CR1_ANFOFF); 7734fadcaf0SPatrice Chotard setbits_le32(®s->cr1, STM32_I2C_CR1_PE); 7744fadcaf0SPatrice Chotard 7754fadcaf0SPatrice Chotard return 0; 7764fadcaf0SPatrice Chotard } 7774fadcaf0SPatrice Chotard 7784fadcaf0SPatrice Chotard static int stm32_i2c_set_bus_speed(struct udevice *bus, unsigned int speed) 7794fadcaf0SPatrice Chotard { 7804fadcaf0SPatrice Chotard struct stm32_i2c_priv *i2c_priv = dev_get_priv(bus); 7814fadcaf0SPatrice Chotard 7824fadcaf0SPatrice Chotard switch (speed) { 7834fadcaf0SPatrice Chotard case STANDARD_RATE: 7844fadcaf0SPatrice Chotard i2c_priv->speed = STM32_I2C_SPEED_STANDARD; 7854fadcaf0SPatrice Chotard break; 7864fadcaf0SPatrice Chotard case FAST_RATE: 7874fadcaf0SPatrice Chotard i2c_priv->speed = STM32_I2C_SPEED_FAST; 7884fadcaf0SPatrice Chotard break; 7894fadcaf0SPatrice Chotard case FAST_PLUS_RATE: 7904fadcaf0SPatrice Chotard i2c_priv->speed = STM32_I2C_SPEED_FAST_PLUS; 7914fadcaf0SPatrice Chotard break; 7924fadcaf0SPatrice Chotard default: 7934fadcaf0SPatrice Chotard debug("%s: Speed %d not supported\n", __func__, speed); 7944fadcaf0SPatrice Chotard return -EINVAL; 7954fadcaf0SPatrice Chotard } 7964fadcaf0SPatrice Chotard 7974fadcaf0SPatrice Chotard return stm32_i2c_hw_config(i2c_priv); 7984fadcaf0SPatrice Chotard } 7994fadcaf0SPatrice Chotard 8004fadcaf0SPatrice Chotard static int stm32_i2c_probe(struct udevice *dev) 8014fadcaf0SPatrice Chotard { 8024fadcaf0SPatrice Chotard struct stm32_i2c_priv *i2c_priv = dev_get_priv(dev); 8034fadcaf0SPatrice Chotard struct reset_ctl reset_ctl; 8044fadcaf0SPatrice Chotard fdt_addr_t addr; 8054fadcaf0SPatrice Chotard int ret; 8064fadcaf0SPatrice Chotard 8074fadcaf0SPatrice Chotard addr = dev_read_addr(dev); 8084fadcaf0SPatrice Chotard if (addr == FDT_ADDR_T_NONE) 8094fadcaf0SPatrice Chotard return -EINVAL; 8104fadcaf0SPatrice Chotard 8114fadcaf0SPatrice Chotard i2c_priv->regs = (struct stm32_i2c_regs *)addr; 8124fadcaf0SPatrice Chotard 8134fadcaf0SPatrice Chotard ret = clk_get_by_index(dev, 0, &i2c_priv->clk); 8144fadcaf0SPatrice Chotard if (ret) 8154fadcaf0SPatrice Chotard return ret; 8164fadcaf0SPatrice Chotard 8174fadcaf0SPatrice Chotard ret = clk_enable(&i2c_priv->clk); 8184fadcaf0SPatrice Chotard if (ret) 8194fadcaf0SPatrice Chotard goto clk_free; 8204fadcaf0SPatrice Chotard 8214fadcaf0SPatrice Chotard ret = reset_get_by_index(dev, 0, &reset_ctl); 8224fadcaf0SPatrice Chotard if (ret) 8234fadcaf0SPatrice Chotard goto clk_disable; 8244fadcaf0SPatrice Chotard 8254fadcaf0SPatrice Chotard reset_assert(&reset_ctl); 8264fadcaf0SPatrice Chotard udelay(2); 8274fadcaf0SPatrice Chotard reset_deassert(&reset_ctl); 8284fadcaf0SPatrice Chotard 8294fadcaf0SPatrice Chotard return 0; 8304fadcaf0SPatrice Chotard 8314fadcaf0SPatrice Chotard clk_disable: 8324fadcaf0SPatrice Chotard clk_disable(&i2c_priv->clk); 8334fadcaf0SPatrice Chotard clk_free: 8344fadcaf0SPatrice Chotard clk_free(&i2c_priv->clk); 8354fadcaf0SPatrice Chotard 8364fadcaf0SPatrice Chotard return ret; 8374fadcaf0SPatrice Chotard } 8384fadcaf0SPatrice Chotard 8394fadcaf0SPatrice Chotard static int stm32_ofdata_to_platdata(struct udevice *dev) 8404fadcaf0SPatrice Chotard { 8414fadcaf0SPatrice Chotard struct stm32_i2c_priv *i2c_priv = dev_get_priv(dev); 8424fadcaf0SPatrice Chotard u32 rise_time, fall_time; 8434fadcaf0SPatrice Chotard 8444fadcaf0SPatrice Chotard i2c_priv->setup = (struct stm32_i2c_setup *)dev_get_driver_data(dev); 8454fadcaf0SPatrice Chotard if (!i2c_priv->setup) 8464fadcaf0SPatrice Chotard return -EINVAL; 8474fadcaf0SPatrice Chotard 8484fadcaf0SPatrice Chotard rise_time = dev_read_u32_default(dev, "i2c-scl-rising-time-ns", 0); 8494fadcaf0SPatrice Chotard if (rise_time) 8504fadcaf0SPatrice Chotard i2c_priv->setup->rise_time = rise_time; 8514fadcaf0SPatrice Chotard 8524fadcaf0SPatrice Chotard fall_time = dev_read_u32_default(dev, "i2c-scl-falling-time-ns", 0); 8534fadcaf0SPatrice Chotard if (fall_time) 8544fadcaf0SPatrice Chotard i2c_priv->setup->fall_time = fall_time; 8554fadcaf0SPatrice Chotard 8564fadcaf0SPatrice Chotard return 0; 8574fadcaf0SPatrice Chotard } 8584fadcaf0SPatrice Chotard 8594fadcaf0SPatrice Chotard static const struct dm_i2c_ops stm32_i2c_ops = { 8604fadcaf0SPatrice Chotard .xfer = stm32_i2c_xfer, 8614fadcaf0SPatrice Chotard .set_bus_speed = stm32_i2c_set_bus_speed, 8624fadcaf0SPatrice Chotard }; 8634fadcaf0SPatrice Chotard 8644fadcaf0SPatrice Chotard static const struct udevice_id stm32_i2c_of_match[] = { 8654fadcaf0SPatrice Chotard { .compatible = "st,stm32f7-i2c", .data = (ulong)&stm32f7_setup }, 8664fadcaf0SPatrice Chotard {} 8674fadcaf0SPatrice Chotard }; 8684fadcaf0SPatrice Chotard 8694fadcaf0SPatrice Chotard U_BOOT_DRIVER(stm32f7_i2c) = { 8704fadcaf0SPatrice Chotard .name = "stm32f7-i2c", 8714fadcaf0SPatrice Chotard .id = UCLASS_I2C, 8724fadcaf0SPatrice Chotard .of_match = stm32_i2c_of_match, 8734fadcaf0SPatrice Chotard .ofdata_to_platdata = stm32_ofdata_to_platdata, 8744fadcaf0SPatrice Chotard .probe = stm32_i2c_probe, 8754fadcaf0SPatrice Chotard .priv_auto_alloc_size = sizeof(struct stm32_i2c_priv), 8764fadcaf0SPatrice Chotard .ops = &stm32_i2c_ops, 8774fadcaf0SPatrice Chotard }; 878