1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright ASPEED Technology Inc. 4 */ 5#include <common.h> 6#include <clk.h> 7#include <dm.h> 8#include <errno.h> 9#include <fdtdec.h> 10#include <i2c.h> 11#include <log.h> 12#include <regmap.h> 13#include <reset.h> 14#include <asm/io.h> 15#include <linux/iopoll.h> 16#include "ast2600_i2c.h" 17 18/* Device private data */ 19struct ast2600_i2c_priv { 20 struct clk clk; 21 struct ast2600_i2c_regs *regs; 22 void __iomem *global; 23}; 24 25static int ast2600_i2c_read_data(struct ast2600_i2c_priv *priv, u8 chip_addr, 26 u8 *buffer, size_t len, bool send_stop) 27{ 28 int rx_cnt, ret = 0; 29 u32 cmd, isr; 30 31 for (rx_cnt = 0; rx_cnt < len; rx_cnt++, buffer++) { 32 cmd = I2CM_PKT_EN | I2CM_PKT_ADDR(chip_addr) | 33 I2CM_RX_CMD; 34 if (!rx_cnt) 35 cmd |= I2CM_START_CMD; 36 37 if ((len - 1) == rx_cnt) 38 cmd |= I2CM_RX_CMD_LAST; 39 40 if (send_stop && ((len - 1) == rx_cnt)) 41 cmd |= I2CM_STOP_CMD; 42 43 writel(cmd, &priv->regs->cmd_sts); 44 45 ret = readl_poll_timeout(&priv->regs->isr, isr, 46 isr & I2CM_PKT_DONE, 47 I2C_TIMEOUT_US); 48 if (ret) 49 return -ETIMEDOUT; 50 51 *buffer = 52 I2CC_GET_RX_BUFF(readl(&priv->regs->trx_buff)); 53 54 writel(I2CM_PKT_DONE, &priv->regs->isr); 55 56 if (isr & I2CM_TX_NAK) 57 return -EREMOTEIO; 58 } 59 60 return 0; 61} 62 63static int ast2600_i2c_write_data(struct ast2600_i2c_priv *priv, u8 chip_addr, 64 u8 *buffer, size_t len, bool send_stop) 65{ 66 int tx_cnt, ret = 0; 67 u32 cmd, isr; 68 69 if (!len) { 70 cmd = I2CM_PKT_EN | I2CM_PKT_ADDR(chip_addr) | 71 I2CM_START_CMD; 72 writel(cmd, &priv->regs->cmd_sts); 73 ret = readl_poll_timeout(&priv->regs->isr, isr, 74 isr & I2CM_PKT_DONE, 75 I2C_TIMEOUT_US); 76 if (ret) 77 return -ETIMEDOUT; 78 79 writel(I2CM_PKT_DONE, &priv->regs->isr); 80 81 if (isr & I2CM_TX_NAK) 82 return -EREMOTEIO; 83 } 84 85 for (tx_cnt = 0; tx_cnt < len; tx_cnt++, buffer++) { 86 cmd = I2CM_PKT_EN | I2CM_PKT_ADDR(chip_addr); 87 cmd |= I2CM_TX_CMD; 88 89 if (!tx_cnt) 90 cmd |= I2CM_START_CMD; 91 92 if (send_stop && ((len - 1) == tx_cnt)) 93 cmd |= I2CM_STOP_CMD; 94 95 writel(*buffer, &priv->regs->trx_buff); 96 writel(cmd, &priv->regs->cmd_sts); 97 ret = readl_poll_timeout(&priv->regs->isr, isr, 98 isr & I2CM_PKT_DONE, 99 I2C_TIMEOUT_US); 100 if (ret) 101 return -ETIMEDOUT; 102 103 writel(I2CM_PKT_DONE, &priv->regs->isr); 104 105 if (isr & I2CM_TX_NAK) 106 return -EREMOTEIO; 107 } 108 109 return 0; 110} 111 112static int ast2600_i2c_deblock(struct udevice *dev) 113{ 114 struct ast2600_i2c_priv *priv = dev_get_priv(dev); 115 u32 csr = readl(&priv->regs->cmd_sts); 116 u32 isr; 117 int ret; 118 119 /* reinit */ 120 writel(0, &priv->regs->fun_ctrl); 121 /* Enable Master Mode. Assuming single-master */ 122 writel(I2CC_BUS_AUTO_RELEASE | I2CC_MASTER_EN | 123 I2CC_MULTI_MASTER_DIS, 124 &priv->regs->fun_ctrl); 125 126 csr = readl(&priv->regs->cmd_sts); 127 128 if (!(csr & I2CC_SDA_LINE_STS) && 129 (csr & I2CC_SCL_LINE_STS)) { 130 debug("Bus stuck (%x), attempting recovery\n", csr); 131 writel(I2CM_RECOVER_CMD_EN, &priv->regs->cmd_sts); 132 ret = readl_poll_timeout(&priv->regs->isr, isr, 133 isr & (I2CM_BUS_RECOVER_FAIL | 134 I2CM_BUS_RECOVER), 135 I2C_TIMEOUT_US); 136 writel(~0, &priv->regs->isr); 137 if (ret) 138 return -EREMOTEIO; 139 } 140 141 return 0; 142} 143 144static int ast2600_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) 145{ 146 struct ast2600_i2c_priv *priv = dev_get_priv(dev); 147 int ret; 148 149 if (readl(&priv->regs->trx_buff) & I2CC_BUS_BUSY_STS) 150 return -EREMOTEIO; 151 152 for (; nmsgs > 0; nmsgs--, msg++) { 153 if (msg->flags & I2C_M_RD) { 154 debug("i2c_read: chip=0x%x, len=0x%x, flags=0x%x\n", 155 msg->addr, msg->len, msg->flags); 156 ret = ast2600_i2c_read_data(priv, msg->addr, msg->buf, 157 msg->len, (nmsgs == 1)); 158 } else { 159 debug("i2c_write: chip=0x%x, len=0x%x, flags=0x%x\n", 160 msg->addr, msg->len, msg->flags); 161 ret = ast2600_i2c_write_data(priv, msg->addr, msg->buf, 162 msg->len, (nmsgs == 1)); 163 } 164 if (ret) { 165 debug("%s: error (%d)\n", __func__, ret); 166 return -EREMOTEIO; 167 } 168 } 169 170 return 0; 171} 172 173static int ast2600_i2c_set_speed(struct udevice *dev, unsigned int speed) 174{ 175 struct ast2600_i2c_priv *priv = dev_get_priv(dev); 176 unsigned long base_clk1, base_clk2, base_clk3, base_clk4; 177 int multiply = 10; 178 int baseclk_idx; 179 u32 clk_div_reg; 180 u32 apb_clk; 181 u32 scl_low; 182 u32 scl_high; 183 int divisor; 184 int inc = 0; 185 u32 data; 186 187 debug("Setting speed for I2C%d to <%u>\n", dev->seq_, speed); 188 if (!speed) { 189 debug("No valid speed specified\n"); 190 return -EINVAL; 191 } 192 193 apb_clk = clk_get_rate(&priv->clk); 194 195 clk_div_reg = readl(priv->global + I2CG_CLK_DIV_CTRL); 196 197 base_clk1 = (apb_clk * multiply) / (((GET_CLK1_DIV(clk_div_reg) + 2) * multiply) / 2); 198 base_clk2 = (apb_clk * multiply) / (((GET_CLK2_DIV(clk_div_reg) + 2) * multiply) / 2); 199 base_clk3 = (apb_clk * multiply) / (((GET_CLK3_DIV(clk_div_reg) + 2) * multiply) / 2); 200 base_clk4 = (apb_clk * multiply) / (((GET_CLK4_DIV(clk_div_reg) + 2) * multiply) / 2); 201 202 if ((apb_clk / speed) <= 32) { 203 baseclk_idx = 0; 204 divisor = DIV_ROUND_UP(apb_clk, speed); 205 } else if ((base_clk1 / speed) <= 32) { 206 baseclk_idx = 1; 207 divisor = DIV_ROUND_UP(base_clk1, speed); 208 } else if ((base_clk2 / speed) <= 32) { 209 baseclk_idx = 2; 210 divisor = DIV_ROUND_UP(base_clk2, speed); 211 } else if ((base_clk3 / speed) <= 32) { 212 baseclk_idx = 3; 213 divisor = DIV_ROUND_UP(base_clk3, speed); 214 } else { 215 baseclk_idx = 4; 216 divisor = DIV_ROUND_UP(base_clk4, speed); 217 inc = 0; 218 while ((divisor + inc) > 32) { 219 inc |= divisor & 0x1; 220 divisor >>= 1; 221 baseclk_idx++; 222 } 223 divisor += inc; 224 } 225 divisor = min_t(int, divisor, 32); 226 baseclk_idx &= 0xf; 227 scl_low = ((divisor * 9) / 16) - 1; 228 scl_low = min_t(u32, scl_low, 0xf); 229 scl_high = (divisor - scl_low - 2) & 0xf; 230 /* Divisor : Base Clock : tCKHighMin : tCK High : tCK Low */ 231 data = ((scl_high - 1) << 20) | (scl_high << 16) | (scl_low << 12) | 232 baseclk_idx; 233 /* Set AC Timing */ 234 writel(data, &priv->regs->ac_timing); 235 236 return 0; 237} 238 239static int ast2600_i2c_probe(struct udevice *dev) 240{ 241 struct ast2600_i2c_priv *priv = dev_get_priv(dev); 242 ofnode i2c_global_node; 243 244 /* find global base address */ 245 i2c_global_node = ofnode_get_parent(dev_ofnode(dev)); 246 priv->global = (void *)ofnode_get_addr(i2c_global_node); 247 if (IS_ERR(priv->global)) { 248 debug("%s(): can't get global\n", __func__); 249 return PTR_ERR(priv->global); 250 } 251 252 /* Reset device */ 253 writel(0, &priv->regs->fun_ctrl); 254 /* Enable Master Mode. Assuming single-master */ 255 writel(I2CC_BUS_AUTO_RELEASE | I2CC_MASTER_EN | 256 I2CC_MULTI_MASTER_DIS, 257 &priv->regs->fun_ctrl); 258 259 writel(0, &priv->regs->ier); 260 /* Clear Interrupt */ 261 writel(~0, &priv->regs->isr); 262 263 return 0; 264} 265 266static int ast2600_i2c_of_to_plat(struct udevice *dev) 267{ 268 struct ast2600_i2c_priv *priv = dev_get_priv(dev); 269 int ret; 270 271 priv->regs = dev_read_addr_ptr(dev); 272 if (!priv->regs) 273 return -EINVAL; 274 275 ret = clk_get_by_index(dev, 0, &priv->clk); 276 if (ret < 0) { 277 debug("%s: Can't get clock for %s: %d\n", __func__, dev->name, 278 ret); 279 return ret; 280 } 281 282 return 0; 283} 284 285static const struct dm_i2c_ops ast2600_i2c_ops = { 286 .xfer = ast2600_i2c_xfer, 287 .deblock = ast2600_i2c_deblock, 288 .set_bus_speed = ast2600_i2c_set_speed, 289}; 290 291static const struct udevice_id ast2600_i2c_ids[] = { 292 { .compatible = "aspeed,ast2600-i2c" }, 293 {}, 294}; 295 296U_BOOT_DRIVER(ast2600_i2c) = { 297 .name = "ast2600_i2c", 298 .id = UCLASS_I2C, 299 .of_match = ast2600_i2c_ids, 300 .probe = ast2600_i2c_probe, 301 .of_to_plat = ast2600_i2c_of_to_plat, 302 .priv_auto = sizeof(struct ast2600_i2c_priv), 303 .ops = &ast2600_i2c_ops, 304}; 305 306struct ast2600_i2c_global_priv { 307 void __iomem *regs; 308 struct reset_ctl reset; 309}; 310 311/* 312 * APB clk : 100Mhz 313 * div : scl : baseclk [APB/((div/2) + 1)] : tBuf [1/bclk * 16] 314 * I2CG10[31:24] base clk4 for i2c auto recovery timeout counter (0xC6) 315 * I2CG10[23:16] base clk3 for Standard-mode (100Khz) min tBuf 4.7us 316 * 0x3c : 100.8Khz : 3.225Mhz : 4.96us 317 * 0x3d : 99.2Khz : 3.174Mhz : 5.04us 318 * 0x3e : 97.65Khz : 3.125Mhz : 5.12us 319 * 0x40 : 97.75Khz : 3.03Mhz : 5.28us 320 * 0x41 : 99.5Khz : 2.98Mhz : 5.36us (default) 321 * I2CG10[15:8] base clk2 for Fast-mode (400Khz) min tBuf 1.3us 322 * 0x12 : 400Khz : 10Mhz : 1.6us 323 * I2CG10[7:0] base clk1 for Fast-mode Plus (1Mhz) min tBuf 0.5us 324 * 0x08 : 1Mhz : 20Mhz : 0.8us 325 */ 326 327static int aspeed_i2c_global_probe(struct udevice *dev) 328{ 329 struct ast2600_i2c_global_priv *i2c_global = dev_get_priv(dev); 330 void __iomem *regs; 331 int ret = 0; 332 333 i2c_global->regs = dev_read_addr_ptr(dev); 334 if (!i2c_global->regs) 335 return -EINVAL; 336 337 debug("%s(dev=%p)\n", __func__, dev); 338 339 regs = i2c_global->regs; 340 341 ret = reset_get_by_index(dev, 0, &i2c_global->reset); 342 if (ret) { 343 printf("%s(): Failed to get reset signal\n", __func__); 344 return ret; 345 } 346 347 reset_deassert(&i2c_global->reset); 348 349 writel(GLOBAL_INIT, regs + I2CG_CTRL); 350 writel(I2CCG_DIV_CTRL, regs + I2CG_CLK_DIV_CTRL); 351 352 return 0; 353} 354 355static const struct udevice_id aspeed_i2c_global_ids[] = { 356 { .compatible = "aspeed,ast2600-i2c-global", }, 357 { } 358}; 359 360U_BOOT_DRIVER(aspeed_i2c_global) = { 361 .name = "aspeed_i2c_global", 362 .id = UCLASS_MISC, 363 .of_match = aspeed_i2c_global_ids, 364 .probe = aspeed_i2c_global_probe, 365 .priv_auto = sizeof(struct ast2600_i2c_global_priv), 366}; 367