• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0-only OR MIT */
2 
3 #include <assert.h>
4 #include <console/console.h>
5 #include <device/mmio.h>
6 #include <device/i2c_simple.h>
7 #include <gpio.h>
8 #include <soc/i2c.h>
9 
10 struct mtk_i2c mtk_i2c_bus_controller[] = {
11 	[0] = {
12 		.i2c_regs = (void *)(I2C_BASE),
13 		.i2c_dma_regs = (void *)(I2C_DMA_BASE),
14 		.mt_i2c_flag = I2C_APDMA_ASYNC,
15 	},
16 	[1] = {
17 		.i2c_regs = (void *)(I2C_BASE + 0x1000),
18 		.i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x180),
19 		.mt_i2c_flag = I2C_APDMA_ASYNC,
20 	},
21 	[2] = {
22 		.i2c_regs = (void *)(I2C_BASE + 0x2000),
23 		.i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x300),
24 		.mt_i2c_flag = I2C_APDMA_ASYNC,
25 	},
26 	[3] = {
27 		.i2c_regs = (void *)(I2C_BASE + 0x3000),
28 		.i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x400),
29 		.mt_i2c_flag = I2C_APDMA_ASYNC,
30 	},
31 	[4] = {
32 		.i2c_regs = (void *)(I2C_BASE + 0x4000),
33 		.i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x480),
34 		.mt_i2c_flag = I2C_APDMA_ASYNC,
35 	},
36 	[5] = {
37 		.i2c_regs = (void *)(I2C_BASE - 0x100000),
38 		.i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x500),
39 		.mt_i2c_flag = I2C_APDMA_ASYNC,
40 	},
41 	[6] = {
42 		.i2c_regs = (void *)(I2C_BASE - 0xFF000),
43 		.i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x580),
44 		.mt_i2c_flag = I2C_APDMA_ASYNC,
45 	},
46 	[7] = {
47 		.i2c_regs = (void *)(I2C_BASE - 0xFE000),
48 		.i2c_dma_regs = (void *)(I2C_DMA_BASE + 0x600),
49 		.mt_i2c_flag = I2C_APDMA_ASYNC,
50 	},
51 };
52 
53 _Static_assert(ARRAY_SIZE(mtk_i2c_bus_controller) == I2C_BUS_NUMBER,
54 	       "Wrong size of mtk_i2c_bus_controller");
55 
56 struct pad_func {
57 	gpio_t gpio;
58 	u8 func;
59 };
60 
61 #define PAD_FUNC(name, func) {GPIO(name), PAD_##name##_FUNC_##func}
62 
63 static const struct pad_func i2c_funcs[I2C_BUS_NUMBER][2] = {
64 	[0] = {
65 		PAD_FUNC(SDA0, SDA0),
66 		PAD_FUNC(SCL0, SCL0),
67 	},
68 	[1] = {
69 		PAD_FUNC(SDA1, SDA1),
70 		PAD_FUNC(SCL1, SCL1),
71 	},
72 	[2] = {
73 		PAD_FUNC(SDA2, SDA2),
74 		PAD_FUNC(SCL2, SCL2),
75 	},
76 	[3] = {
77 		PAD_FUNC(SDA3, SDA3),
78 		PAD_FUNC(SCL3, SCL3),
79 	},
80 	[4] = {
81 		PAD_FUNC(SDA4, SDA4),
82 		PAD_FUNC(SCL4, SCL4),
83 	},
84 	[5] = {
85 		PAD_FUNC(HDMIRX_SCL, SCL5),
86 		PAD_FUNC(HDMIRX_SDA, SDA5),
87 	},
88 	[6] = {
89 		PAD_FUNC(HDMITX_SCL, SCL6),
90 		PAD_FUNC(HDMITX_SDA, SDA6),
91 	},
92 	[7] = {
93 		PAD_FUNC(HDMIRX_HTPLG, SCL7),
94 		PAD_FUNC(HDMIRX_PWR5V, SDA7),
95 	},
96 
97 };
98 
mtk_i2c_set_gpio_pinmux(uint8_t bus)99 static void mtk_i2c_set_gpio_pinmux(uint8_t bus)
100 {
101 	assert(bus < I2C_BUS_NUMBER);
102 
103 	const struct pad_func *ptr = i2c_funcs[bus];
104 	for (size_t i = 0; i < 2; i++) {
105 		gpio_set_mode(ptr[i].gpio, ptr[i].func);
106 		if (bus <= I2C4)
107 			gpio_set_pull(ptr[i].gpio, GPIO_PULL_ENABLE, GPIO_PULL_UP);
108 	}
109 }
110 
mtk_i2c_bus_init(uint8_t bus,uint32_t speed)111 void mtk_i2c_bus_init(uint8_t bus, uint32_t speed)
112 {
113 	mtk_i2c_speed_init(bus, speed);
114 	mtk_i2c_set_gpio_pinmux(bus);
115 }
116 
mtk_i2c_dump_more_info(struct mt_i2c_regs * regs)117 void mtk_i2c_dump_more_info(struct mt_i2c_regs *regs)
118 {
119 	printk(BIOS_DEBUG, "LTIMING %x\nCLK_DIV %x\n",
120 	       read32(&regs->ltiming),
121 	       read32(&regs->clock_div));
122 }
123 
mtk_i2c_config_timing(struct mt_i2c_regs * regs,struct mtk_i2c * bus_ctrl)124 void mtk_i2c_config_timing(struct mt_i2c_regs *regs, struct mtk_i2c *bus_ctrl)
125 {
126 	write32(&regs->clock_div, bus_ctrl->ac_timing.inter_clk_div);
127 	write32(&regs->timing, bus_ctrl->ac_timing.htiming);
128 	write32(&regs->ltiming, bus_ctrl->ac_timing.ltiming);
129 	write32(&regs->hs, bus_ctrl->ac_timing.hs);
130 	write32(&regs->ext_conf, bus_ctrl->ac_timing.ext);
131 }
132