002-0017-i2c-add-support-for-MediaTek-I2C-interface.patch 23 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870
  1. From de6f2293ab087f405dbcf7b8df45d1f9b03fc091 Mon Sep 17 00:00:00 2001
  2. From: Weijie Gao <[email protected]>
  3. Date: Wed, 27 Jul 2022 17:16:38 +0800
  4. Subject: [PATCH 17/31] i2c: add support for MediaTek I2C interface
  5. This patch adds support for MediaTek I2C interface
  6. Reviewed-by: Heiko Schocher <[email protected]>
  7. Reviewed-by: Simon Glass <[email protected]>
  8. Signed-off-by: Weijie Gao <[email protected]>
  9. ---
  10. drivers/i2c/Kconfig | 9 +
  11. drivers/i2c/Makefile | 1 +
  12. drivers/i2c/mtk_i2c.c | 822 ++++++++++++++++++++++++++++++++++++++++++
  13. 3 files changed, 832 insertions(+)
  14. create mode 100644 drivers/i2c/mtk_i2c.c
  15. --- a/drivers/i2c/Kconfig
  16. +++ b/drivers/i2c/Kconfig
  17. @@ -261,6 +261,15 @@ config SYS_I2C_MESON
  18. internal buffer holding up to 8 bytes for transfers and supports
  19. both 7-bit and 10-bit addresses.
  20. +config SYS_I2C_MTK
  21. + bool "MediaTek I2C driver"
  22. + help
  23. + This selects the MediaTek Integrated Inter Circuit bus driver.
  24. + The I2C bus adapter is the base for some other I2C client,
  25. + eg: touch, sensors.
  26. + If you want to use MediaTek I2C interface, say Y here.
  27. + If unsure, say N.
  28. +
  29. config SYS_I2C_MICROCHIP
  30. bool "Microchip I2C driver"
  31. help
  32. --- a/drivers/i2c/Makefile
  33. +++ b/drivers/i2c/Makefile
  34. @@ -32,6 +32,7 @@ obj-$(CONFIG_SYS_I2C_MICROCHIP) += i2c-m
  35. obj-$(CONFIG_SYS_I2C_MV) += mv_i2c.o
  36. obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
  37. obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
  38. +obj-$(CONFIG_SYS_I2C_MTK) += mtk_i2c.o
  39. obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
  40. obj-$(CONFIG_SYS_I2C_OCORES) += ocores_i2c.o
  41. obj-$(CONFIG_SYS_I2C_OCTEON) += octeon_i2c.o
  42. --- /dev/null
  43. +++ b/drivers/i2c/mtk_i2c.c
  44. @@ -0,0 +1,822 @@
  45. +// SPDX-License-Identifier: GPL-2.0+
  46. +/*
  47. + * Copyright (C) 2022 MediaTek Inc. All Rights Reserved.
  48. + *
  49. + * Author: Mingming Lee <[email protected]>
  50. + *
  51. + * MediaTek I2C Interface driver
  52. + */
  53. +
  54. +#include <clk.h>
  55. +#include <cpu_func.h>
  56. +#include <dm.h>
  57. +#include <i2c.h>
  58. +#include <log.h>
  59. +#include <asm/cache.h>
  60. +#include <asm/io.h>
  61. +#include <linux/delay.h>
  62. +#include <linux/errno.h>
  63. +
  64. +#define I2C_RS_TRANSFER BIT(4)
  65. +#define I2C_HS_NACKERR BIT(2)
  66. +#define I2C_ACKERR BIT(1)
  67. +#define I2C_TRANSAC_COMP BIT(0)
  68. +#define I2C_TRANSAC_START BIT(0)
  69. +#define I2C_RS_MUL_CNFG BIT(15)
  70. +#define I2C_RS_MUL_TRIG BIT(14)
  71. +#define I2C_DCM_DISABLE 0x0000
  72. +#define I2C_IO_CONFIG_OPEN_DRAIN 0x0003
  73. +#define I2C_IO_CONFIG_PUSH_PULL 0x0000
  74. +#define I2C_SOFT_RST 0x0001
  75. +#define I2C_FIFO_ADDR_CLR 0x0001
  76. +#define I2C_DELAY_LEN 0x0002
  77. +#define I2C_ST_START_CON 0x8001
  78. +#define I2C_FS_START_CON 0x1800
  79. +#define I2C_TIME_CLR_VALUE 0x0000
  80. +#define I2C_TIME_DEFAULT_VALUE 0x0003
  81. +#define I2C_WRRD_TRANAC_VALUE 0x0002
  82. +#define I2C_RD_TRANAC_VALUE 0x0001
  83. +
  84. +#define I2C_DMA_CON_TX 0x0000
  85. +#define I2C_DMA_CON_RX 0x0001
  86. +#define I2C_DMA_START_EN 0x0001
  87. +#define I2C_DMA_INT_FLAG_NONE 0x0000
  88. +#define I2C_DMA_CLR_FLAG 0x0000
  89. +#define I2C_DMA_TX_RX 0x0000
  90. +#define I2C_DMA_HARD_RST 0x0002
  91. +
  92. +#define MAX_ST_MODE_SPEED 100000
  93. +#define MAX_FS_MODE_SPEED 400000
  94. +#define MAX_HS_MODE_SPEED 3400000
  95. +#define MAX_SAMPLE_CNT_DIV 8
  96. +#define MAX_STEP_CNT_DIV 64
  97. +#define MAX_HS_STEP_CNT_DIV 8
  98. +#define I2C_DEFAULT_CLK_DIV 4
  99. +
  100. +#define MAX_I2C_ADDR 0x7f
  101. +#define MAX_I2C_LEN 0xff
  102. +#define TRANS_ADDR_ONLY BIT(8)
  103. +#define TRANSFER_TIMEOUT 50000 /* us */
  104. +#define I2C_FIFO_STAT1_MASK 0x001f
  105. +#define TIMING_SAMPLE_OFFSET 8
  106. +#define HS_SAMPLE_OFFSET 12
  107. +#define HS_STEP_OFFSET 8
  108. +
  109. +#define I2C_CONTROL_WRAPPER BIT(0)
  110. +#define I2C_CONTROL_RS BIT(1)
  111. +#define I2C_CONTROL_DMA_EN BIT(2)
  112. +#define I2C_CONTROL_CLK_EXT_EN BIT(3)
  113. +#define I2C_CONTROL_DIR_CHANGE BIT(4)
  114. +#define I2C_CONTROL_ACKERR_DET_EN BIT(5)
  115. +#define I2C_CONTROL_TRANSFER_LEN_CHANGE BIT(6)
  116. +#define I2C_CONTROL_DMAACK BIT(8)
  117. +#define I2C_CONTROL_ASYNC BIT(9)
  118. +
  119. +#define I2C_MASTER_WR BIT(0)
  120. +#define I2C_MASTER_RD BIT(1)
  121. +#define I2C_MASTER_WRRD (I2C_MASTER_WR | I2C_MASTER_RD)
  122. +
  123. +enum I2C_REGS_OFFSET {
  124. + REG_PORT,
  125. + REG_SLAVE_ADDR,
  126. + REG_INTR_MASK,
  127. + REG_INTR_STAT,
  128. + REG_CONTROL,
  129. + REG_TRANSFER_LEN,
  130. + REG_TRANSAC_LEN,
  131. + REG_DELAY_LEN,
  132. + REG_TIMING,
  133. + REG_START,
  134. + REG_EXT_CONF,
  135. + REG_FIFO_STAT1,
  136. + REG_LTIMING,
  137. + REG_FIFO_STAT,
  138. + REG_FIFO_THRESH,
  139. + REG_FIFO_ADDR_CLR,
  140. + REG_IO_CONFIG,
  141. + REG_RSV_DEBUG,
  142. + REG_HS,
  143. + REG_SOFTRESET,
  144. + REG_DCM_EN,
  145. + REG_PATH_DIR,
  146. + REG_DEBUGSTAT,
  147. + REG_DEBUGCTRL,
  148. + REG_TRANSFER_LEN_AUX,
  149. + REG_CLOCK_DIV,
  150. + REG_SCL_HL_RATIO,
  151. + REG_SCL_HS_HL_RATIO,
  152. + REG_SCL_MIS_COMP_POINT,
  153. + REG_STA_STOP_AC_TIME,
  154. + REG_HS_STA_STOP_AC_TIME,
  155. + REG_DATA_TIME,
  156. +};
  157. +
  158. +enum DMA_REGS_OFFSET {
  159. + REG_INT_FLAG = 0x0,
  160. + REG_INT_EN = 0x04,
  161. + REG_EN = 0x08,
  162. + REG_RST = 0x0c,
  163. + REG_CON = 0x18,
  164. + REG_TX_MEM_ADDR = 0x1c,
  165. + REG_RX_MEM_ADDR = 0x20,
  166. + REG_TX_LEN = 0x24,
  167. + REG_RX_LEN = 0x28,
  168. +};
  169. +
  170. +static const uint mt_i2c_regs_v1[] = {
  171. + [REG_PORT] = 0x0,
  172. + [REG_SLAVE_ADDR] = 0x4,
  173. + [REG_INTR_MASK] = 0x8,
  174. + [REG_INTR_STAT] = 0xc,
  175. + [REG_CONTROL] = 0x10,
  176. + [REG_TRANSFER_LEN] = 0x14,
  177. + [REG_TRANSAC_LEN] = 0x18,
  178. + [REG_DELAY_LEN] = 0x1c,
  179. + [REG_TIMING] = 0x20,
  180. + [REG_START] = 0x24,
  181. + [REG_EXT_CONF] = 0x28,
  182. + [REG_FIFO_STAT1] = 0x2c,
  183. + [REG_FIFO_STAT] = 0x30,
  184. + [REG_FIFO_THRESH] = 0x34,
  185. + [REG_FIFO_ADDR_CLR] = 0x38,
  186. + [REG_IO_CONFIG] = 0x40,
  187. + [REG_RSV_DEBUG] = 0x44,
  188. + [REG_HS] = 0x48,
  189. + [REG_SOFTRESET] = 0x50,
  190. + [REG_SOFTRESET] = 0x50,
  191. + [REG_DCM_EN] = 0x54,
  192. + [REG_DEBUGSTAT] = 0x64,
  193. + [REG_DEBUGCTRL] = 0x68,
  194. + [REG_TRANSFER_LEN_AUX] = 0x6c,
  195. + [REG_CLOCK_DIV] = 0x70,
  196. + [REG_SCL_HL_RATIO] = 0x74,
  197. + [REG_SCL_HS_HL_RATIO] = 0x78,
  198. + [REG_SCL_MIS_COMP_POINT] = 0x7c,
  199. + [REG_STA_STOP_AC_TIME] = 0x80,
  200. + [REG_HS_STA_STOP_AC_TIME] = 0x84,
  201. + [REG_DATA_TIME] = 0x88,
  202. +};
  203. +
  204. +static const uint mt_i2c_regs_v2[] = {
  205. + [REG_PORT] = 0x0,
  206. + [REG_SLAVE_ADDR] = 0x4,
  207. + [REG_INTR_MASK] = 0x8,
  208. + [REG_INTR_STAT] = 0xc,
  209. + [REG_CONTROL] = 0x10,
  210. + [REG_TRANSFER_LEN] = 0x14,
  211. + [REG_TRANSAC_LEN] = 0x18,
  212. + [REG_DELAY_LEN] = 0x1c,
  213. + [REG_TIMING] = 0x20,
  214. + [REG_START] = 0x24,
  215. + [REG_EXT_CONF] = 0x28,
  216. + [REG_LTIMING] = 0x2c,
  217. + [REG_HS] = 0x30,
  218. + [REG_IO_CONFIG] = 0x34,
  219. + [REG_FIFO_ADDR_CLR] = 0x38,
  220. + [REG_TRANSFER_LEN_AUX] = 0x44,
  221. + [REG_CLOCK_DIV] = 0x48,
  222. + [REG_SOFTRESET] = 0x50,
  223. + [REG_DEBUGSTAT] = 0xe0,
  224. + [REG_DEBUGCTRL] = 0xe8,
  225. + [REG_FIFO_STAT] = 0xf4,
  226. + [REG_FIFO_THRESH] = 0xf8,
  227. + [REG_DCM_EN] = 0xf88,
  228. +};
  229. +
  230. +struct mtk_i2c_soc_data {
  231. + const uint *regs;
  232. + uint dma_sync: 1;
  233. +};
  234. +
  235. +struct mtk_i2c_priv {
  236. + /* set in i2c probe */
  237. + void __iomem *base; /* i2c base addr */
  238. + void __iomem *pdmabase; /* dma base address*/
  239. + struct clk clk_main; /* main clock for i2c bus */
  240. + struct clk clk_dma; /* DMA clock for i2c via DMA */
  241. + const struct mtk_i2c_soc_data *soc_data; /* Compatible data for different IC */
  242. + int op; /* operation mode */
  243. + bool zero_len; /* Only transfer slave address, no data */
  244. + bool pushpull; /* push pull mode or open drain mode */
  245. + bool filter_msg; /* filter msg error log */
  246. + bool auto_restart; /* restart mode */
  247. + bool ignore_restart_irq; /* ignore restart IRQ */
  248. + uint speed; /* i2c speed, unit: hz */
  249. +};
  250. +
  251. +static inline void i2c_writel(struct mtk_i2c_priv *priv, uint reg, uint value)
  252. +{
  253. + u32 offset = priv->soc_data->regs[reg];
  254. +
  255. + writel(value, priv->base + offset);
  256. +}
  257. +
  258. +static inline uint i2c_readl(struct mtk_i2c_priv *priv, uint offset)
  259. +{
  260. + return readl(priv->base + priv->soc_data->regs[offset]);
  261. +}
  262. +
  263. +static int mtk_i2c_clk_enable(struct mtk_i2c_priv *priv)
  264. +{
  265. + int ret;
  266. +
  267. + ret = clk_enable(&priv->clk_main);
  268. + if (ret)
  269. + return log_msg_ret("enable clk_main", ret);
  270. +
  271. + ret = clk_enable(&priv->clk_dma);
  272. + if (ret)
  273. + return log_msg_ret("enable clk_dma", ret);
  274. +
  275. + return 0;
  276. +}
  277. +
  278. +static int mtk_i2c_clk_disable(struct mtk_i2c_priv *priv)
  279. +{
  280. + int ret;
  281. +
  282. + ret = clk_disable(&priv->clk_dma);
  283. + if (ret)
  284. + return log_msg_ret("disable clk_dma", ret);
  285. +
  286. + ret = clk_disable(&priv->clk_main);
  287. + if (ret)
  288. + return log_msg_ret("disable clk_main", ret);
  289. +
  290. + return 0;
  291. +}
  292. +
  293. +static void mtk_i2c_init_hw(struct mtk_i2c_priv *priv)
  294. +{
  295. + uint control_reg;
  296. +
  297. + writel(I2C_DMA_HARD_RST, priv->pdmabase + REG_RST);
  298. + writel(I2C_DMA_CLR_FLAG, priv->pdmabase + REG_RST);
  299. + i2c_writel(priv, REG_SOFTRESET, I2C_SOFT_RST);
  300. + /* set ioconfig */
  301. + if (priv->pushpull)
  302. + i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_PUSH_PULL);
  303. + else
  304. + i2c_writel(priv, REG_IO_CONFIG, I2C_IO_CONFIG_OPEN_DRAIN);
  305. +
  306. + i2c_writel(priv, REG_DCM_EN, I2C_DCM_DISABLE);
  307. + control_reg = I2C_CONTROL_ACKERR_DET_EN | I2C_CONTROL_CLK_EXT_EN;
  308. + if (priv->soc_data->dma_sync)
  309. + control_reg |= I2C_CONTROL_DMAACK | I2C_CONTROL_ASYNC;
  310. + i2c_writel(priv, REG_CONTROL, control_reg);
  311. + i2c_writel(priv, REG_DELAY_LEN, I2C_DELAY_LEN);
  312. +}
  313. +
  314. +/*
  315. + * Calculate i2c port speed
  316. + *
  317. + * Hardware design:
  318. + * i2c_bus_freq = parent_clk / (clock_div * 2 * sample_cnt * step_cnt)
  319. + * clock_div: fixed in hardware, but may be various in different SoCs
  320. + *
  321. + * The calculation want to pick the highest bus frequency that is still
  322. + * less than or equal to target_speed. The calculation try to get
  323. + * sample_cnt and step_cn
  324. + * @param[in]
  325. + * clk_src: i2c clock source
  326. + * @param[out]
  327. + * timing_step_cnt: step cnt calculate result
  328. + * @param[out]
  329. + * timing_sample_cnt: sample cnt calculate result
  330. + * @return
  331. + * 0, set speed successfully.
  332. + * -EINVAL, Unsupported speed.
  333. + */
  334. +static int mtk_i2c_calculate_speed(uint clk_src,
  335. + uint target_speed,
  336. + uint *timing_step_cnt,
  337. + uint *timing_sample_cnt)
  338. +{
  339. + uint base_sample_cnt = MAX_SAMPLE_CNT_DIV;
  340. + uint base_step_cnt;
  341. + uint max_step_cnt;
  342. + uint sample_cnt;
  343. + uint step_cnt;
  344. + uint opt_div;
  345. + uint best_mul;
  346. + uint cnt_mul;
  347. +
  348. + if (target_speed > MAX_HS_MODE_SPEED)
  349. + target_speed = MAX_HS_MODE_SPEED;
  350. +
  351. + if (target_speed > MAX_FS_MODE_SPEED)
  352. + max_step_cnt = MAX_HS_STEP_CNT_DIV;
  353. + else
  354. + max_step_cnt = MAX_STEP_CNT_DIV;
  355. +
  356. + base_step_cnt = max_step_cnt;
  357. + /* Find the best combination */
  358. + opt_div = DIV_ROUND_UP(clk_src >> 1, target_speed);
  359. + best_mul = MAX_SAMPLE_CNT_DIV * max_step_cnt;
  360. +
  361. + /*
  362. + * Search for the best pair (sample_cnt, step_cnt) with
  363. + * 0 < sample_cnt < MAX_SAMPLE_CNT_DIV
  364. + * 0 < step_cnt < max_step_cnt
  365. + * sample_cnt * step_cnt >= opt_div
  366. + * optimizing for sample_cnt * step_cnt being minimal
  367. + */
  368. + for (sample_cnt = 1; sample_cnt <= MAX_SAMPLE_CNT_DIV; sample_cnt++) {
  369. + step_cnt = DIV_ROUND_UP(opt_div, sample_cnt);
  370. + cnt_mul = step_cnt * sample_cnt;
  371. + if (step_cnt > max_step_cnt)
  372. + continue;
  373. +
  374. + if (cnt_mul < best_mul) {
  375. + best_mul = cnt_mul;
  376. + base_sample_cnt = sample_cnt;
  377. + base_step_cnt = step_cnt;
  378. + if (best_mul == opt_div)
  379. + break;
  380. + }
  381. + }
  382. +
  383. + sample_cnt = base_sample_cnt;
  384. + step_cnt = base_step_cnt;
  385. +
  386. + if ((clk_src / (2 * sample_cnt * step_cnt)) > target_speed) {
  387. + /*
  388. + * In this case, hardware can't support such
  389. + * low i2c_bus_freq
  390. + */
  391. + debug("Unsupported speed(%uhz)\n", target_speed);
  392. + return log_msg_ret("calculate speed", -EINVAL);
  393. + }
  394. +
  395. + *timing_step_cnt = step_cnt - 1;
  396. + *timing_sample_cnt = sample_cnt - 1;
  397. +
  398. + return 0;
  399. +}
  400. +
  401. +/*
  402. + * mtk_i2c_set_speed
  403. + *
  404. + * @par Description
  405. + * Calculate i2c speed and write sample_cnt, step_cnt to TIMING register.
  406. + * @param[in]
  407. + * dev: udevice pointer, struct udevice contains i2c source clock,
  408. + * clock divide and speed.
  409. + * @return
  410. + * 0, set speed successfully.\n
  411. + * error code from mtk_i2c_calculate_speed().
  412. + */
  413. +static int mtk_i2c_set_speed(struct udevice *dev, uint speed)
  414. +{
  415. + struct mtk_i2c_priv *priv = dev_get_priv(dev);
  416. + uint high_speed_reg;
  417. + uint sample_cnt;
  418. + uint timing_reg;
  419. + uint step_cnt;
  420. + uint clk_src;
  421. + int ret = 0;
  422. +
  423. + priv->speed = speed;
  424. + if (mtk_i2c_clk_enable(priv))
  425. + return log_msg_ret("set_speed enable clk", -1);
  426. +
  427. + clk_src = clk_get_rate(&priv->clk_main) / I2C_DEFAULT_CLK_DIV;
  428. + i2c_writel(priv, REG_CLOCK_DIV, (I2C_DEFAULT_CLK_DIV - 1));
  429. + if (priv->speed > MAX_FS_MODE_SPEED) {
  430. + /* Set master code speed register */
  431. + ret = mtk_i2c_calculate_speed(clk_src, MAX_FS_MODE_SPEED,
  432. + &step_cnt, &sample_cnt);
  433. + if (ret < 0)
  434. + goto exit;
  435. +
  436. + timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
  437. + i2c_writel(priv, REG_TIMING, timing_reg);
  438. + /* Set the high speed mode register */
  439. + ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
  440. + &step_cnt, &sample_cnt);
  441. + if (ret < 0)
  442. + goto exit;
  443. +
  444. + high_speed_reg = I2C_TIME_DEFAULT_VALUE |
  445. + (sample_cnt << HS_SAMPLE_OFFSET) |
  446. + (step_cnt << HS_STEP_OFFSET);
  447. + i2c_writel(priv, REG_HS, high_speed_reg);
  448. + } else {
  449. + ret = mtk_i2c_calculate_speed(clk_src, priv->speed,
  450. + &step_cnt, &sample_cnt);
  451. + if (ret < 0)
  452. + goto exit;
  453. +
  454. + timing_reg = (sample_cnt << TIMING_SAMPLE_OFFSET) | step_cnt;
  455. + /* Disable the high speed transaction */
  456. + high_speed_reg = I2C_TIME_CLR_VALUE;
  457. + i2c_writel(priv, REG_TIMING, timing_reg);
  458. + i2c_writel(priv, REG_HS, high_speed_reg);
  459. + }
  460. +exit:
  461. + if (mtk_i2c_clk_disable(priv))
  462. + return log_msg_ret("set_speed disable clk", -1);
  463. +
  464. + return ret;
  465. +}
  466. +
  467. +/*
  468. + * mtk_i2c_do_transfer
  469. + *
  470. + * @par Description
  471. + * Configure i2c register and trigger transfer.
  472. + * @param[in]
  473. + * priv: mtk_i2cmtk_i2c_priv pointer, struct mtk_i2c_priv contains register base\n
  474. + * address, operation mode, interrupt status and i2c driver data.
  475. + * @param[in]
  476. + * msgs: i2c_msg pointer, struct i2c_msg contains slave\n
  477. + * address, operation mode, msg length and data buffer.
  478. + * @param[in]
  479. + * num: i2c_msg number.
  480. + * @param[in]
  481. + * left_num: left i2c_msg number.
  482. + * @return
  483. + * 0, i2c transfer successfully.\n
  484. + * -ETIMEDOUT, i2c transfer timeout.\n
  485. + * -EREMOTEIO, i2c transfer ack error.
  486. + */
  487. +static int mtk_i2c_do_transfer(struct mtk_i2c_priv *priv,
  488. + struct i2c_msg *msgs,
  489. + int num, int left_num)
  490. +{
  491. + struct i2c_msg *msg_rx = NULL;
  492. + uint restart_flag = 0;
  493. + uint trans_error = 0;
  494. + uint irq_stat = 0;
  495. + uint tmo_poll = 0;
  496. + uint control_reg;
  497. + bool tmo = false;
  498. + uint start_reg;
  499. + uint addr_reg;
  500. + int ret = 0;
  501. +
  502. + if (priv->auto_restart)
  503. + restart_flag = I2C_RS_TRANSFER;
  504. +
  505. + control_reg = i2c_readl(priv, REG_CONTROL) &
  506. + ~(I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS);
  507. +
  508. + if (priv->speed > MAX_FS_MODE_SPEED || num > 1)
  509. + control_reg |= I2C_CONTROL_RS;
  510. +
  511. + if (priv->op == I2C_MASTER_WRRD)
  512. + control_reg |= I2C_CONTROL_DIR_CHANGE | I2C_CONTROL_RS;
  513. +
  514. + control_reg |= I2C_CONTROL_DMA_EN;
  515. + i2c_writel(priv, REG_CONTROL, control_reg);
  516. +
  517. + /* set start condition */
  518. + if (priv->speed <= MAX_ST_MODE_SPEED)
  519. + i2c_writel(priv, REG_EXT_CONF, I2C_ST_START_CON);
  520. + else
  521. + i2c_writel(priv, REG_EXT_CONF, I2C_FS_START_CON);
  522. +
  523. + addr_reg = msgs->addr << 1;
  524. + if (priv->op == I2C_MASTER_RD)
  525. + addr_reg |= I2C_M_RD;
  526. + if (priv->zero_len)
  527. + i2c_writel(priv, REG_SLAVE_ADDR, addr_reg | TRANS_ADDR_ONLY);
  528. + else
  529. + i2c_writel(priv, REG_SLAVE_ADDR, addr_reg);
  530. +
  531. + /* clear interrupt status */
  532. + i2c_writel(priv, REG_INTR_STAT, restart_flag | I2C_HS_NACKERR |
  533. + I2C_ACKERR | I2C_TRANSAC_COMP);
  534. + i2c_writel(priv, REG_FIFO_ADDR_CLR, I2C_FIFO_ADDR_CLR);
  535. +
  536. + /* enable interrupt */
  537. + i2c_writel(priv, REG_INTR_MASK, restart_flag | I2C_HS_NACKERR |
  538. + I2C_ACKERR | I2C_TRANSAC_COMP);
  539. +
  540. + /* set transfer and transaction len */
  541. + if (priv->op == I2C_MASTER_WRRD) {
  542. + i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
  543. + i2c_writel(priv, REG_TRANSFER_LEN_AUX, (msgs + 1)->len);
  544. + i2c_writel(priv, REG_TRANSAC_LEN, I2C_WRRD_TRANAC_VALUE);
  545. + } else {
  546. + i2c_writel(priv, REG_TRANSFER_LEN, msgs->len);
  547. + i2c_writel(priv, REG_TRANSAC_LEN, num);
  548. + }
  549. +
  550. + /* Clear DMA interrupt flag */
  551. + writel(I2C_DMA_INT_FLAG_NONE, priv->pdmabase + REG_INT_FLAG);
  552. +
  553. + /* Flush cache for first msg */
  554. + flush_cache((ulong)msgs->buf, msgs->len);
  555. +
  556. + /*
  557. + * prepare buffer data to start transfer
  558. + * three cases here: read, write, write then read
  559. + */
  560. + if (priv->op & I2C_MASTER_WR) {
  561. + /* Set DMA direction TX (w/ or w/o RX) */
  562. + writel(I2C_DMA_CON_TX, priv->pdmabase + REG_CON);
  563. +
  564. + /* Write the tx buffer address to dma register */
  565. + writel((ulong)msgs->buf, priv->pdmabase + REG_TX_MEM_ADDR);
  566. + /* Write the tx length to dma register */
  567. + writel(msgs->len, priv->pdmabase + REG_TX_LEN);
  568. +
  569. + if (priv->op & I2C_MASTER_RD) {
  570. + /* write then read */
  571. + msg_rx = msgs + 1;
  572. +
  573. + /* Flush cache for second msg */
  574. + flush_cache((ulong)msg_rx->buf, msg_rx->len);
  575. + }
  576. + }
  577. +
  578. + if (priv->op & I2C_MASTER_RD) {
  579. + if (!msg_rx) {
  580. + /* Set DMA direction RX */
  581. + writel(I2C_DMA_CON_RX, priv->pdmabase + REG_CON);
  582. +
  583. + msg_rx = msgs;
  584. + }
  585. +
  586. + /* Write the rx buffer address to dma register */
  587. + writel((ulong)msg_rx->buf, priv->pdmabase + REG_RX_MEM_ADDR);
  588. + /* Write the rx length to dma register */
  589. + writel(msg_rx->len, priv->pdmabase + REG_RX_LEN);
  590. + }
  591. +
  592. + writel(I2C_DMA_START_EN, priv->pdmabase + REG_EN);
  593. +
  594. + if (!priv->auto_restart) {
  595. + start_reg = I2C_TRANSAC_START;
  596. + } else {
  597. + start_reg = I2C_TRANSAC_START | I2C_RS_MUL_TRIG;
  598. + if (left_num >= 1)
  599. + start_reg |= I2C_RS_MUL_CNFG;
  600. + }
  601. + i2c_writel(priv, REG_START, start_reg);
  602. +
  603. + for (;;) {
  604. + irq_stat = i2c_readl(priv, REG_INTR_STAT);
  605. +
  606. + /* ignore the first restart irq after the master code */
  607. + if (priv->ignore_restart_irq && (irq_stat & restart_flag)) {
  608. + priv->ignore_restart_irq = false;
  609. + irq_stat = 0;
  610. + i2c_writel(priv, REG_START, I2C_RS_MUL_CNFG |
  611. + I2C_RS_MUL_TRIG | I2C_TRANSAC_START);
  612. + }
  613. +
  614. + if (irq_stat & (I2C_TRANSAC_COMP | restart_flag)) {
  615. + tmo = false;
  616. + if (irq_stat & (I2C_HS_NACKERR | I2C_ACKERR))
  617. + trans_error = 1;
  618. +
  619. + break;
  620. + }
  621. + udelay(1);
  622. + if (tmo_poll++ >= TRANSFER_TIMEOUT) {
  623. + tmo = true;
  624. + break;
  625. + }
  626. + }
  627. +
  628. + /* clear interrupt mask */
  629. + i2c_writel(priv, REG_INTR_MASK, ~(restart_flag | I2C_HS_NACKERR |
  630. + I2C_ACKERR | I2C_TRANSAC_COMP));
  631. +
  632. + if (!tmo && trans_error != 0) {
  633. + if (tmo) {
  634. + ret = -ETIMEDOUT;
  635. + if (!priv->filter_msg)
  636. + debug("I2C timeout! addr: 0x%x,\n", msgs->addr);
  637. + } else {
  638. + ret = -EREMOTEIO;
  639. + if (!priv->filter_msg)
  640. + debug("I2C ACKERR! addr: 0x%x,IRQ:0x%x\n",
  641. + msgs->addr, irq_stat);
  642. + }
  643. + mtk_i2c_init_hw(priv);
  644. + }
  645. +
  646. + return ret;
  647. +}
  648. +
  649. +/*
  650. + * mtk_i2c_transfer
  651. + *
  652. + * @par Description
  653. + * Common i2c transfer API. Set i2c transfer mode according to i2c_msg\n
  654. + * information, then call mtk_i2c_do_transfer() to configure i2c register\n
  655. + * and trigger transfer.
  656. + * @param[in]
  657. + * dev: udevice pointer, struct udevice contains struct mtk_i2c_priv, \n
  658. + * struct mtk_i2c_priv contains register base\n
  659. + * address, operation mode, interrupt status and i2c driver data.
  660. + * @param[in]
  661. + * msgs: i2c_msg pointer, struct i2c_msg contains slave\n
  662. + * address, operation mode, msg length and data buffer.
  663. + * @param[in]
  664. + * num: i2c_msg number.
  665. + * @return
  666. + * i2c_msg number, i2c transfer successfully.\n
  667. + * -EINVAL, msg length is more than 16\n
  668. + * use DMA MODE or slave address more than 0x7f.\n
  669. + * error code from mtk_i2c_init_base().\n
  670. + * error code from mtk_i2c_set_speed().\n
  671. + * error code from mtk_i2c_do_transfer().
  672. + */
  673. +static int mtk_i2c_transfer(struct udevice *dev, struct i2c_msg *msg,
  674. + int nmsgs)
  675. +{
  676. + struct mtk_i2c_priv *priv = dev_get_priv(dev);
  677. + int left_num;
  678. + uint num_cnt;
  679. + int ret;
  680. +
  681. + priv->auto_restart = true;
  682. + left_num = nmsgs;
  683. + if (mtk_i2c_clk_enable(priv))
  684. + return log_msg_ret("transfer enable clk", -1);
  685. +
  686. + for (num_cnt = 0; num_cnt < nmsgs; num_cnt++) {
  687. + if (((msg + num_cnt)->addr) > MAX_I2C_ADDR) {
  688. + ret = -EINVAL;
  689. + goto err_exit;
  690. + }
  691. + if ((msg + num_cnt)->len > MAX_I2C_LEN) {
  692. + ret = -EINVAL;
  693. + goto err_exit;
  694. + }
  695. + }
  696. +
  697. + /* check if we can skip restart and optimize using WRRD mode */
  698. + if (priv->auto_restart && nmsgs == 2) {
  699. + if (!(msg[0].flags & I2C_M_RD) && (msg[1].flags & I2C_M_RD) &&
  700. + msg[0].addr == msg[1].addr) {
  701. + priv->auto_restart = false;
  702. + }
  703. + }
  704. +
  705. + if (priv->auto_restart && nmsgs >= 2 && priv->speed > MAX_FS_MODE_SPEED)
  706. + /* ignore the first restart irq after the master code,
  707. + * otherwise the first transfer will be discarded.
  708. + */
  709. + priv->ignore_restart_irq = true;
  710. + else
  711. + priv->ignore_restart_irq = false;
  712. +
  713. + while (left_num--) {
  714. + /* transfer slave address only to support devices detect */
  715. + if (!msg->buf)
  716. + priv->zero_len = true;
  717. + else
  718. + priv->zero_len = false;
  719. +
  720. + if (msg->flags & I2C_M_RD)
  721. + priv->op = I2C_MASTER_RD;
  722. + else
  723. + priv->op = I2C_MASTER_WR;
  724. +
  725. + if (!priv->auto_restart) {
  726. + if (nmsgs > 1) {
  727. + /* combined two messages into one transaction */
  728. + priv->op = I2C_MASTER_WRRD;
  729. + left_num--;
  730. + }
  731. + }
  732. + ret = mtk_i2c_do_transfer(priv, msg, nmsgs, left_num);
  733. + if (ret < 0)
  734. + goto err_exit;
  735. + msg++;
  736. + }
  737. + ret = 0;
  738. +
  739. +err_exit:
  740. + if (mtk_i2c_clk_disable(priv))
  741. + return log_msg_ret("transfer disable clk", -1);
  742. +
  743. + return ret;
  744. +}
  745. +
  746. +static int mtk_i2c_of_to_plat(struct udevice *dev)
  747. +{
  748. + struct mtk_i2c_priv *priv = dev_get_priv(dev);
  749. + int ret;
  750. +
  751. + priv->base = dev_remap_addr_index(dev, 0);
  752. + priv->pdmabase = dev_remap_addr_index(dev, 1);
  753. + ret = clk_get_by_index(dev, 0, &priv->clk_main);
  754. + if (ret)
  755. + return log_msg_ret("clk_get_by_index 0", ret);
  756. +
  757. + ret = clk_get_by_index(dev, 1, &priv->clk_dma);
  758. +
  759. + return ret;
  760. +}
  761. +
  762. +static int mtk_i2c_probe(struct udevice *dev)
  763. +{
  764. + struct mtk_i2c_priv *priv = dev_get_priv(dev);
  765. +
  766. + priv->soc_data = (struct mtk_i2c_soc_data *)dev_get_driver_data(dev);
  767. +
  768. + if (mtk_i2c_clk_enable(priv))
  769. + return log_msg_ret("probe enable clk", -1);
  770. +
  771. + mtk_i2c_init_hw(priv);
  772. +
  773. + if (mtk_i2c_clk_disable(priv))
  774. + return log_msg_ret("probe disable clk", -1);
  775. +
  776. + return 0;
  777. +}
  778. +
  779. +static int mtk_i2c_deblock(struct udevice *dev)
  780. +{
  781. + struct mtk_i2c_priv *priv = dev_get_priv(dev);
  782. +
  783. + if (mtk_i2c_clk_enable(priv))
  784. + return log_msg_ret("deblock enable clk", -1);
  785. +
  786. + mtk_i2c_init_hw(priv);
  787. +
  788. + if (mtk_i2c_clk_disable(priv))
  789. + return log_msg_ret("deblock disable clk", -1);
  790. +
  791. + return 0;
  792. +}
  793. +
  794. +static const struct mtk_i2c_soc_data mt76xx_soc_data = {
  795. + .regs = mt_i2c_regs_v1,
  796. + .dma_sync = 0,
  797. +};
  798. +
  799. +static const struct mtk_i2c_soc_data mt7981_soc_data = {
  800. + .regs = mt_i2c_regs_v1,
  801. + .dma_sync = 1,
  802. +};
  803. +
  804. +static const struct mtk_i2c_soc_data mt7986_soc_data = {
  805. + .regs = mt_i2c_regs_v1,
  806. + .dma_sync = 1,
  807. +};
  808. +
  809. +static const struct mtk_i2c_soc_data mt8183_soc_data = {
  810. + .regs = mt_i2c_regs_v2,
  811. + .dma_sync = 1,
  812. +};
  813. +
  814. +static const struct mtk_i2c_soc_data mt8518_soc_data = {
  815. + .regs = mt_i2c_regs_v1,
  816. + .dma_sync = 0,
  817. +};
  818. +
  819. +static const struct mtk_i2c_soc_data mt8512_soc_data = {
  820. + .regs = mt_i2c_regs_v1,
  821. + .dma_sync = 1,
  822. +};
  823. +
  824. +static const struct dm_i2c_ops mtk_i2c_ops = {
  825. + .xfer = mtk_i2c_transfer,
  826. + .set_bus_speed = mtk_i2c_set_speed,
  827. + .deblock = mtk_i2c_deblock,
  828. +};
  829. +
  830. +static const struct udevice_id mtk_i2c_ids[] = {
  831. + {
  832. + .compatible = "mediatek,mt7622-i2c",
  833. + .data = (ulong)&mt76xx_soc_data,
  834. + }, {
  835. + .compatible = "mediatek,mt7623-i2c",
  836. + .data = (ulong)&mt76xx_soc_data,
  837. + }, {
  838. + .compatible = "mediatek,mt7629-i2c",
  839. + .data = (ulong)&mt76xx_soc_data,
  840. + }, {
  841. + .compatible = "mediatek,mt7981-i2c",
  842. + .data = (ulong)&mt7981_soc_data,
  843. + }, {
  844. + .compatible = "mediatek,mt7986-i2c",
  845. + .data = (ulong)&mt7986_soc_data,
  846. + }, {
  847. + .compatible = "mediatek,mt8183-i2c",
  848. + .data = (ulong)&mt8183_soc_data,
  849. + }, {
  850. + .compatible = "mediatek,mt8512-i2c",
  851. + .data = (ulong)&mt8512_soc_data,
  852. + }, {
  853. + .compatible = "mediatek,mt8518-i2c",
  854. + .data = (ulong)&mt8518_soc_data,
  855. + }
  856. +};
  857. +
  858. +U_BOOT_DRIVER(mtk_i2c) = {
  859. + .name = "mtk_i2c",
  860. + .id = UCLASS_I2C,
  861. + .of_match = mtk_i2c_ids,
  862. + .of_to_plat = mtk_i2c_of_to_plat,
  863. + .probe = mtk_i2c_probe,
  864. + .priv_auto = sizeof(struct mtk_i2c_priv),
  865. + .ops = &mtk_i2c_ops,
  866. +};