1 // SPDX-License-Identifier: GPL-2.0+ 2 /* 3 * Atmel I2C driver. 4 * 5 * (C) Copyright 2016 Songjun Wu <songjun.wu (at) atmel.com> 6 */ 7 8 #include <asm/io.h> 9 #include <common.h> 10 #include <clk.h> 11 #include <dm.h> 12 #include <errno.h> 13 #include <fdtdec.h> 14 #include <i2c.h> 15 #include <linux/bitops.h> 16 #include <mach/clk.h> 17 18 #include "at91_i2c.h" 19 20 DECLARE_GLOBAL_DATA_PTR; 21 22 #define I2C_TIMEOUT_MS 100 23 24 static int at91_wait_for_xfer(struct at91_i2c_bus *bus, u32 status) 25 { 26 struct at91_i2c_regs *reg = bus->regs; 27 ulong start_time = get_timer(0); 28 u32 sr; 29 30 bus->status = 0; 31 32 do { 33 sr = readl(®->sr); 34 bus->status |= sr; 35 36 if (sr & TWI_SR_NACK) 37 return -EREMOTEIO; 38 else if (sr & status) 39 return 0; 40 } while (get_timer(start_time) < I2C_TIMEOUT_MS); 41 42 return -ETIMEDOUT; 43 } 44 45 static int at91_i2c_xfer_msg(struct at91_i2c_bus *bus, struct i2c_msg *msg) 46 { 47 struct at91_i2c_regs *reg = bus->regs; 48 bool is_read = msg->flags & I2C_M_RD; 49 u32 i; 50 int ret = 0; 51 52 readl(®->sr); 53 if (is_read) { 54 writel(TWI_CR_START, ®->cr); 55 56 for (i = 0; !ret && i < (msg->len - 1); i++) { 57 ret = at91_wait_for_xfer(bus, TWI_SR_RXRDY); 58 msg->buf[i] = readl(®->rhr); 59 } 60 61 if (ret) 62 goto error; 63 64 writel(TWI_CR_STOP, ®->cr); 65 66 ret = at91_wait_for_xfer(bus, TWI_SR_RXRDY); 67 if (ret) 68 goto error; 69 70 msg->buf[i] = readl(®->rhr); 71 72 } else { 73 writel(msg->buf[0], ®->thr); 74 ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY); 75 76 for (i = 1; !ret && (i < msg->len); i++) { 77 writel(msg->buf[i], ®->thr); 78 ret = at91_wait_for_xfer(bus, TWI_SR_TXRDY); 79 } 80 81 if (ret) 82 goto error; 83 84 writel(TWI_CR_STOP, ®->cr); 85 } 86 87 if (!ret) 88 ret = at91_wait_for_xfer(bus, TWI_SR_TXCOMP); 89 90 if (ret) 91 goto error; 92 93 if (bus->status & (TWI_SR_OVRE | TWI_SR_UNRE | TWI_SR_LOCK)) { 94 ret = -EIO; 95 goto error; 96 } 97 98 return 0; 99 100 error: 101 if (bus->status & TWI_SR_LOCK) 102 writel(TWI_CR_LOCKCLR, ®->cr); 103 104 return ret; 105 } 106 107 static int at91_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) 108 { 109 struct at91_i2c_bus *bus = dev_get_priv(dev); 110 struct at91_i2c_regs *reg = bus->regs; 111 struct i2c_msg *m_start = msg; 112 bool is_read; 113 u32 int_addr_flag = 0; 114 int ret = 0; 115 116 if (nmsgs == 2) { 117 int internal_address = 0; 118 int i; 119 120 /* 1st msg is put into the internal address, start with 2nd */ 121 m_start = &msg[1]; 122 123 /* the max length of internal address is 3 bytes */ 124 if (msg->len > 3) 125 return -EFAULT; 126 127 for (i = 0; i < msg->len; ++i) { 128 const unsigned addr = msg->buf[msg->len - 1 - i]; 129 130 internal_address |= addr << (8 * i); 131 int_addr_flag += TWI_MMR_IADRSZ_1; 132 } 133 134 writel(internal_address, ®->iadr); 135 } 136 137 is_read = m_start->flags & I2C_M_RD; 138 139 writel((m_start->addr << 16) | int_addr_flag | 140 (is_read ? TWI_MMR_MREAD : 0), ®->mmr); 141 142 ret = at91_i2c_xfer_msg(bus, m_start); 143 144 return ret; 145 } 146 147 /* 148 * Calculate symmetric clock as stated in datasheet: 149 * twi_clk = F_MAIN / (2 * (cdiv * (1 << ckdiv) + offset)) 150 */ 151 static void at91_calc_i2c_clock(struct udevice *dev, int i2c_clk) 152 { 153 struct at91_i2c_bus *bus = dev_get_priv(dev); 154 const struct at91_i2c_pdata *pdata = bus->pdata; 155 int offset = pdata->clk_offset; 156 int max_ckdiv = pdata->clk_max_div; 157 int ckdiv, cdiv, div; 158 unsigned long src_rate; 159 160 src_rate = bus->bus_clk_rate; 161 162 div = max(0, (int)DIV_ROUND_UP(src_rate, 2 * i2c_clk) - offset); 163 ckdiv = fls(div >> 8); 164 cdiv = div >> ckdiv; 165 166 if (ckdiv > max_ckdiv) { 167 ckdiv = max_ckdiv; 168 cdiv = 255; 169 } 170 171 bus->speed = DIV_ROUND_UP(src_rate, 172 (cdiv * (1 << ckdiv) + offset) * 2); 173 174 bus->cwgr_val = (ckdiv << 16) | (cdiv << 8) | cdiv; 175 } 176 177 static int at91_i2c_enable_clk(struct udevice *dev) 178 { 179 struct at91_i2c_bus *bus = dev_get_priv(dev); 180 struct clk clk; 181 ulong clk_rate; 182 int ret; 183 184 ret = clk_get_by_index(dev, 0, &clk); 185 if (ret) 186 return -EINVAL; 187 188 ret = clk_enable(&clk); 189 if (ret) 190 return ret; 191 192 clk_rate = clk_get_rate(&clk); 193 if (!clk_rate) 194 return -EINVAL; 195 196 bus->bus_clk_rate = clk_rate; 197 198 clk_free(&clk); 199 200 return 0; 201 } 202 203 static int at91_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) 204 { 205 struct at91_i2c_bus *bus = dev_get_priv(dev); 206 207 at91_calc_i2c_clock(dev, speed); 208 209 writel(bus->cwgr_val, &bus->regs->cwgr); 210 211 return 0; 212 } 213 214 int at91_i2c_get_bus_speed(struct udevice *dev) 215 { 216 struct at91_i2c_bus *bus = dev_get_priv(dev); 217 218 return bus->speed; 219 } 220 221 static int at91_i2c_ofdata_to_platdata(struct udevice *dev) 222 { 223 const void *blob = gd->fdt_blob; 224 struct at91_i2c_bus *bus = dev_get_priv(dev); 225 int node = dev_of_offset(dev); 226 227 bus->regs = (struct at91_i2c_regs *)devfdt_get_addr(dev); 228 bus->pdata = (struct at91_i2c_pdata *)dev_get_driver_data(dev); 229 bus->clock_frequency = fdtdec_get_int(blob, node, 230 "clock-frequency", 100000); 231 232 return 0; 233 } 234 235 static const struct dm_i2c_ops at91_i2c_ops = { 236 .xfer = at91_i2c_xfer, 237 .set_bus_speed = at91_i2c_set_bus_speed, 238 .get_bus_speed = at91_i2c_get_bus_speed, 239 }; 240 241 static int at91_i2c_probe(struct udevice *dev) 242 { 243 struct at91_i2c_bus *bus = dev_get_priv(dev); 244 struct at91_i2c_regs *reg = bus->regs; 245 int ret; 246 247 ret = at91_i2c_enable_clk(dev); 248 if (ret) 249 return ret; 250 251 writel(TWI_CR_SWRST, ®->cr); 252 253 at91_calc_i2c_clock(dev, bus->clock_frequency); 254 255 writel(bus->cwgr_val, ®->cwgr); 256 writel(TWI_CR_MSEN, ®->cr); 257 writel(TWI_CR_SVDIS, ®->cr); 258 259 return 0; 260 } 261 262 static const struct at91_i2c_pdata at91rm9200_config = { 263 .clk_max_div = 5, 264 .clk_offset = 3, 265 }; 266 267 static const struct at91_i2c_pdata at91sam9261_config = { 268 .clk_max_div = 5, 269 .clk_offset = 4, 270 }; 271 272 static const struct at91_i2c_pdata at91sam9260_config = { 273 .clk_max_div = 7, 274 .clk_offset = 4, 275 }; 276 277 static const struct at91_i2c_pdata at91sam9g20_config = { 278 .clk_max_div = 7, 279 .clk_offset = 4, 280 }; 281 282 static const struct at91_i2c_pdata at91sam9g10_config = { 283 .clk_max_div = 7, 284 .clk_offset = 4, 285 }; 286 287 static const struct at91_i2c_pdata at91sam9x5_config = { 288 .clk_max_div = 7, 289 .clk_offset = 4, 290 }; 291 292 static const struct at91_i2c_pdata sama5d4_config = { 293 .clk_max_div = 7, 294 .clk_offset = 4, 295 }; 296 297 static const struct at91_i2c_pdata sama5d2_config = { 298 .clk_max_div = 7, 299 .clk_offset = 3, 300 }; 301 302 static const struct udevice_id at91_i2c_ids[] = { 303 { .compatible = "atmel,at91rm9200-i2c", .data = (long)&at91rm9200_config }, 304 { .compatible = "atmel,at91sam9260-i2c", .data = (long)&at91sam9260_config }, 305 { .compatible = "atmel,at91sam9261-i2c", .data = (long)&at91sam9261_config }, 306 { .compatible = "atmel,at91sam9g20-i2c", .data = (long)&at91sam9g20_config }, 307 { .compatible = "atmel,at91sam9g10-i2c", .data = (long)&at91sam9g10_config }, 308 { .compatible = "atmel,at91sam9x5-i2c", .data = (long)&at91sam9x5_config }, 309 { .compatible = "atmel,sama5d4-i2c", .data = (long)&sama5d4_config }, 310 { .compatible = "atmel,sama5d2-i2c", .data = (long)&sama5d2_config }, 311 { } 312 }; 313 314 U_BOOT_DRIVER(i2c_at91) = { 315 .name = "i2c_at91", 316 .id = UCLASS_I2C, 317 .of_match = at91_i2c_ids, 318 .probe = at91_i2c_probe, 319 .ofdata_to_platdata = at91_i2c_ofdata_to_platdata, 320 .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), 321 .priv_auto_alloc_size = sizeof(struct at91_i2c_bus), 322 .ops = &at91_i2c_ops, 323 }; 324