1// SPDX-License-Identifier: GPL-2.0+ 2/* 3 * Copyright (C) 2019 Stephan Gerhold 4 * 5 * Adapted from old U-Boot and Linux kernel implementation: 6 * Copyright (C) STMicroelectronics 2009 7 * Copyright (C) ST-Ericsson SA 2010 8 */ 9 10#include <common.h> 11#include <dm.h> 12#include <regmap.h> 13#include <syscon.h> 14#include <linux/bitops.h> 15#include <linux/err.h> 16#include <power/ab8500.h> 17#include <power/pmic.h> 18 19/* CPU mailbox registers */ 20#define PRCM_MBOX_CPU_VAL 0x0fc 21#define PRCM_MBOX_CPU_SET 0x100 22#define PRCM_MBOX_CPU_CLR 0x104 23 24#define PRCM_ARM_IT1_CLR 0x48C 25#define PRCM_ARM_IT1_VAL 0x494 26 27#define PRCM_TCDM_RANGE 2 28#define PRCM_REQ_MB5 0xE44 29#define PRCM_ACK_MB5 0xDF4 30#define _PRCM_MBOX_HEADER 0xFE8 31#define PRCM_MBOX_HEADER_REQ_MB5 (_PRCM_MBOX_HEADER + 0x5) 32#define PRCMU_I2C_MBOX_BIT BIT(5) 33 34/* Mailbox 5 Requests */ 35#define PRCM_REQ_MB5_I2C_SLAVE_OP (PRCM_REQ_MB5 + 0x0) 36#define PRCM_REQ_MB5_I2C_HW_BITS (PRCM_REQ_MB5 + 0x1) 37#define PRCM_REQ_MB5_I2C_REG (PRCM_REQ_MB5 + 0x2) 38#define PRCM_REQ_MB5_I2C_VAL (PRCM_REQ_MB5 + 0x3) 39#define PRCMU_I2C(bank) (((bank) << 1) | BIT(6)) 40#define PRCMU_I2C_WRITE 0 41#define PRCMU_I2C_READ 1 42#define PRCMU_I2C_STOP_EN BIT(3) 43 44/* Mailbox 5 ACKs */ 45#define PRCM_ACK_MB5_I2C_STATUS (PRCM_ACK_MB5 + 0x1) 46#define PRCM_ACK_MB5_I2C_VAL (PRCM_ACK_MB5 + 0x3) 47#define PRCMU_I2C_WR_OK 0x1 48#define PRCMU_I2C_RD_OK 0x2 49 50/* AB8500 version registers */ 51#define AB8500_MISC_REV_REG AB8500_MISC(0x80) 52#define AB8500_MISC_IC_NAME_REG AB8500_MISC(0x82) 53 54struct ab8500_priv { 55 struct ab8500 ab8500; 56 struct regmap *regmap; 57}; 58 59static inline int prcmu_tcdm_readb(struct regmap *map, uint offset, u8 *valp) 60{ 61 return regmap_raw_read_range(map, PRCM_TCDM_RANGE, offset, 62 valp, sizeof(*valp)); 63} 64 65static inline int prcmu_tcdm_writeb(struct regmap *map, uint offset, u8 val) 66{ 67 return regmap_raw_write_range(map, PRCM_TCDM_RANGE, offset, 68 &val, sizeof(val)); 69} 70 71static int prcmu_wait_i2c_mbx_ready(struct ab8500_priv *priv) 72{ 73 uint val; 74 int ret; 75 76 ret = regmap_read(priv->regmap, PRCM_ARM_IT1_VAL, &val); 77 if (ret) 78 return ret; 79 80 if (val & PRCMU_I2C_MBOX_BIT) { 81 printf("ab8500: warning: PRCMU i2c mailbox was not acked\n"); 82 /* clear mailbox 5 ack irq */ 83 ret = regmap_write(priv->regmap, PRCM_ARM_IT1_CLR, 84 PRCMU_I2C_MBOX_BIT); 85 if (ret) 86 return ret; 87 } 88 89 /* wait for on-going transaction, use 1s timeout */ 90 return regmap_read_poll_timeout(priv->regmap, PRCM_MBOX_CPU_VAL, val, 91 !(val & PRCMU_I2C_MBOX_BIT), 0, 1000); 92} 93 94static int prcmu_wait_i2c_mbx_done(struct ab8500_priv *priv) 95{ 96 uint val; 97 int ret; 98 99 /* set interrupt to XP70 */ 100 ret = regmap_write(priv->regmap, PRCM_MBOX_CPU_SET, PRCMU_I2C_MBOX_BIT); 101 if (ret) 102 return ret; 103 104 /* wait for mailbox 5 (i2c) ack, use 1s timeout */ 105 return regmap_read_poll_timeout(priv->regmap, PRCM_ARM_IT1_VAL, val, 106 (val & PRCMU_I2C_MBOX_BIT), 0, 1000); 107} 108 109static int ab8500_transfer(struct udevice *dev, uint bank_reg, u8 *val, 110 u8 op, u8 expected_status) 111{ 112 struct ab8500_priv *priv = dev_get_priv(dev); 113 u8 reg = bank_reg & 0xff; 114 u8 bank = bank_reg >> 8; 115 u8 status; 116 int ret; 117 118 ret = prcmu_wait_i2c_mbx_ready(priv); 119 if (ret) 120 return ret; 121 122 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_MBOX_HEADER_REQ_MB5, 0); 123 if (ret) 124 return ret; 125 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_SLAVE_OP, 126 PRCMU_I2C(bank) | op); 127 if (ret) 128 return ret; 129 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_HW_BITS, 130 PRCMU_I2C_STOP_EN); 131 if (ret) 132 return ret; 133 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_REG, reg); 134 if (ret) 135 return ret; 136 ret = prcmu_tcdm_writeb(priv->regmap, PRCM_REQ_MB5_I2C_VAL, *val); 137 if (ret) 138 return ret; 139 140 ret = prcmu_wait_i2c_mbx_done(priv); 141 if (ret) { 142 printf("%s: mailbox request timed out\n", __func__); 143 return ret; 144 } 145 146 /* read transfer result */ 147 ret = prcmu_tcdm_readb(priv->regmap, PRCM_ACK_MB5_I2C_STATUS, &status); 148 if (ret) 149 return ret; 150 ret = prcmu_tcdm_readb(priv->regmap, PRCM_ACK_MB5_I2C_VAL, val); 151 if (ret) 152 return ret; 153 154 /* 155 * Clear mailbox 5 ack irq. Note that the transfer is already complete 156 * here so checking for errors does not make sense. Clearing the irq 157 * will be retried in prcmu_wait_i2c_mbx_ready() on the next transfer. 158 */ 159 regmap_write(priv->regmap, PRCM_ARM_IT1_CLR, PRCMU_I2C_MBOX_BIT); 160 161 if (status != expected_status) { 162 /* 163 * AB8500 does not have the AB8500_MISC_IC_NAME_REG register, 164 * but we need to try reading it to detect AB8505. 165 * In case of an error, assume that we have AB8500. 166 */ 167 if (op == PRCMU_I2C_READ && bank_reg == AB8500_MISC_IC_NAME_REG) { 168 *val = AB8500_VERSION_AB8500; 169 return 0; 170 } 171 172 printf("%s: return status %d\n", __func__, status); 173 return -EIO; 174 } 175 176 return 0; 177} 178 179static int ab8500_reg_count(struct udevice *dev) 180{ 181 return AB8500_NUM_REGISTERS; 182} 183 184static int ab8500_read(struct udevice *dev, uint reg, uint8_t *buf, int len) 185{ 186 int ret; 187 188 if (len != 1) 189 return -EINVAL; 190 191 *buf = 0; 192 ret = ab8500_transfer(dev, reg, buf, PRCMU_I2C_READ, PRCMU_I2C_RD_OK); 193 if (ret) { 194 printf("%s failed: %d\n", __func__, ret); 195 return ret; 196 } 197 198 return 0; 199} 200 201static int ab8500_write(struct udevice *dev, uint reg, const uint8_t *buf, int len) 202{ 203 int ret; 204 u8 val; 205 206 if (len != 1) 207 return -EINVAL; 208 209 val = *buf; 210 ret = ab8500_transfer(dev, reg, &val, PRCMU_I2C_WRITE, PRCMU_I2C_WR_OK); 211 if (ret) { 212 printf("%s failed: %d\n", __func__, ret); 213 return ret; 214 } 215 216 return 0; 217} 218 219static struct dm_pmic_ops ab8500_ops = { 220 .reg_count = ab8500_reg_count, 221 .read = ab8500_read, 222 .write = ab8500_write, 223}; 224 225static int ab8500_probe(struct udevice *dev) 226{ 227 struct ab8500_priv *priv = dev_get_priv(dev); 228 int ret; 229 230 /* get regmap from the PRCMU parent device (syscon in U-Boot) */ 231 priv->regmap = syscon_get_regmap(dev->parent); 232 if (IS_ERR(priv->regmap)) 233 return PTR_ERR(priv->regmap); 234 235 ret = pmic_reg_read(dev, AB8500_MISC_IC_NAME_REG); 236 if (ret < 0) { 237 printf("ab8500: failed to read chip version: %d\n", ret); 238 return ret; 239 } 240 priv->ab8500.version = ret; 241 242 ret = pmic_reg_read(dev, AB8500_MISC_REV_REG); 243 if (ret < 0) { 244 printf("ab8500: failed to read chip id: %d\n", ret); 245 return ret; 246 } 247 priv->ab8500.chip_id = ret; 248 249 debug("ab8500: version: %#x, chip id: %#x\n", 250 priv->ab8500.version, priv->ab8500.chip_id); 251 252 return 0; 253} 254 255static const struct udevice_id ab8500_ids[] = { 256 { .compatible = "stericsson,ab8500" }, 257 { } 258}; 259 260U_BOOT_DRIVER(pmic_ab8500) = { 261 .name = "pmic_ab8500", 262 .id = UCLASS_PMIC, 263 .of_match = ab8500_ids, 264 .bind = dm_scan_fdt_dev, 265 .probe = ab8500_probe, 266 .ops = &ab8500_ops, 267 .priv_auto = sizeof(struct ab8500_priv), 268}; 269