blob: 1aaa236dd51a72063a0c557966c233c18eb60f08 [file] [log] [blame]
Angel Ponse67ab182020-04-04 18:51:11 +02001/* SPDX-License-Identifier: GPL-2.0-only */
Qii Wang66532b02019-01-18 09:29:09 +08002
3#include <assert.h>
Elyes HAOUAS879d04b2022-01-12 17:45:29 +01004#include <console/console.h>
Qii Wang66532b02019-01-18 09:29:09 +08005#include <device/mmio.h>
Qii Wang66532b02019-01-18 09:29:09 +08006#include <soc/i2c.h>
7#include <soc/gpio.h>
8
Qii Wang66532b02019-01-18 09:29:09 +08009struct mtk_i2c mtk_i2c_bus_controller[] = {
10 /* i2c0 setting */
11 {
12 .i2c_regs = (void *)(I2C_BASE + 0x2000),
13 .i2c_dma_regs = (void *)(I2C_DMA_BASE),
14 },
15
16 /* i2c1 setting */
17 {
18 .i2c_regs = (void *)(I2C_BASE + 0xc000),
19 .i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x400),
20 },
21
22 /* i2c2 setting */
23 {
24 .i2c_regs = (void *)(I2C_BASE + 0x4000),
25 .i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x200),
26 },
27
28 /* i2c3 setting */
29 {
30 .i2c_regs = (void *)(I2C_BASE + 0xa000),
31 .i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x380),
32 },
33
34 /* i2c4 setting */
35 {
36 .i2c_regs = (void *)(I2C_BASE + 0x3000),
37 .i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x80),
38 },
39
40 /* i2c5 setting */
41 {
42 .i2c_regs = (void *)(I2C_BASE + 0x11000),
43 .i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x480),
44 },
45
46 /* i2c6 setting */
47 {
48 .i2c_regs = (void *)(I2C_BASE),
49 .i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x580),
50 },
51};
52
Rex-BC Chen9d321582021-11-03 11:28:23 +080053_Static_assert(ARRAY_SIZE(mtk_i2c_bus_controller) == I2C_BUS_NUMBER,
54 "Wrong size of mtk_i2c_bus_controller");
Qii Wang66532b02019-01-18 09:29:09 +080055
56struct pad_func {
57 gpio_t gpio;
58 u8 func;
59};
60
61#define PAD_FUNC(name, func) {GPIO(name), PAD_##name##_FUNC_##func}
62
63static const struct pad_func i2c_funcs[I2C_BUS_NUMBER][2] = {
64 {
65 PAD_FUNC(SDA0, SDA0),
66 PAD_FUNC(SCL0, SCL0),
67 },
68 {
69 PAD_FUNC(SDA1, SDA1),
70 PAD_FUNC(SCL1, SCL1),
71 },
72 {
73 PAD_FUNC(SDA2, SDA2),
74 PAD_FUNC(SCL2, SCL2),
75 },
76 {
77 PAD_FUNC(SDA3, SDA3),
78 PAD_FUNC(SCL3, SCL3),
79 },
80 {
81 PAD_FUNC(SDA4, SDA4),
82 PAD_FUNC(SCL4, SCL4),
83 },
84 {
85 PAD_FUNC(SDA5, SDA5),
86 PAD_FUNC(SCL5, SCL5),
87 },
88 {
89 PAD_FUNC(SDA6, SDA6),
90 PAD_FUNC(SCL6, SCL6),
91 },
92};
93
94static void mtk_i2c_set_gpio_pinmux(uint8_t bus)
95{
96 assert(bus < I2C_BUS_NUMBER);
97
98 const struct pad_func *ptr = i2c_funcs[bus];
99 for (size_t i = 0; i < 2; i++) {
100 gpio_set_mode(ptr[i].gpio, ptr[i].func);
101 gpio_set_pull(ptr[i].gpio, GPIO_PULL_ENABLE, GPIO_PULL_UP);
102 }
103}
104
Rex-BC Chen9d321582021-11-03 11:28:23 +0800105static void mtk_i2c_speed_init_soc(uint8_t bus)
Qii Wang66532b02019-01-18 09:29:09 +0800106{
107 uint8_t step_div;
108 const uint8_t clock_div = 5;
109 const uint8_t sample_div = 1;
110 uint32_t i2c_freq;
111
112 assert(bus < ARRAY_SIZE(mtk_i2c_bus_controller));
113
114 /* Calculate i2c frequency */
115 step_div = DIV_ROUND_UP(I2C_CLK_HZ,
116 (400 * KHz * sample_div * 2) * clock_div);
117 i2c_freq = I2C_CLK_HZ / (step_div * sample_div * 2 * clock_div);
118 assert(sample_div < 8 && step_div < 64 && i2c_freq <= 400 * KHz &&
119 i2c_freq >= 380 * KHz);
120
121 /* Init i2c bus Timing register */
122 write32(&mtk_i2c_bus_controller[bus].i2c_regs->timing,
123 (sample_div - 1) << 8 | (step_div - 1));
124 write32(&mtk_i2c_bus_controller[bus].i2c_regs->ltiming,
125 (sample_div - 1) << 6 | (step_div - 1));
126
127 /* Init i2c bus clock_div register */
128 write32(&mtk_i2c_bus_controller[bus].i2c_regs->clock_div,
129 clock_div - 1);
130}
131
132void mtk_i2c_bus_init(uint8_t bus)
133{
Rex-BC Chen9d321582021-11-03 11:28:23 +0800134 mtk_i2c_speed_init_soc(bus);
Qii Wang66532b02019-01-18 09:29:09 +0800135 mtk_i2c_set_gpio_pinmux(bus);
136}
Rex-BC Chenf4d6e902021-10-01 14:39:39 +0800137
138void mtk_i2c_dump_more_info(struct mt_i2c_regs *regs)
139{
140 printk(BIOS_DEBUG, "LTIMING %x\nCLK_DIV %x\n",
141 read32(&regs->ltiming),
142 read32(&regs->clock_div));
143}