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