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