mb/system76/cml-u/dt: Make use of chipset devicetree
[coreboot.git] / src / soc / mediatek / common / lastbus_v2.c
blob2893c5a72a5aed554fc2dbe4a6034c0f7662e3c7
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <console/console.h>
4 #include <device/mmio.h>
5 #include <soc/addressmap.h>
6 #include <soc/lastbus_v2.h>
7 #include <timer.h>
9 #define SYS_TIMER_0_OFFSET 0x400
10 #define SYS_TIMER_1_OFFSET 0x404
11 #define DEBUG_RESULT_OFFSET 0x408
13 static bool lastbus_is_timeout(const struct lastbus_monitor *m)
15 return read32p(m->base) & LASTBUS_TIMEOUT;
18 static uint64_t gray_code_to_binary(uint64_t gray_code)
20 uint64_t value = 0;
21 while (gray_code) {
22 value ^= gray_code;
23 gray_code >>= 1;
25 return value;
28 static void lastbus_dump_monitor(const struct lastbus_monitor *m)
30 int i;
31 uint64_t gray_code, bin_code;
33 printk(BIOS_INFO, "--- %s %#lx %ld ---\n", m->name, m->base, m->num_ports);
35 for (i = 0; i < m->num_ports; i++)
36 printk(BIOS_INFO, "%08x\n",
37 read32p(m->base + DEBUG_RESULT_OFFSET + (i * 4)));
39 gray_code = (uint64_t)read32p(m->base + SYS_TIMER_1_OFFSET) << 32 |
40 read32p(m->base + SYS_TIMER_0_OFFSET);
41 bin_code = gray_code_to_binary(gray_code);
42 printk(BIOS_INFO, "\ntimestamp: %#llx\n", bin_code);
45 static void lastbus_dump(void)
47 const struct lastbus_monitor *m;
48 bool found = false;
49 int i;
51 for (i = 0; i < lastbus_cfg.num_used_monitors; i++) {
52 m = &lastbus_cfg.monitors[i];
53 if (!lastbus_is_timeout(m))
54 continue;
56 if (!found)
57 printk(BIOS_INFO,
58 "\n******************* %s lastbus ******************\n",
59 lastbus_cfg.latch_platform);
60 found = true;
61 lastbus_dump_monitor(m);
65 static u16 calculate_timeout_thres(u16 bus_freq_mhz, u32 timeout_ms)
67 u64 value;
68 value = ((u64)timeout_ms * USECS_PER_MSEC * bus_freq_mhz) >> 10;
69 if (value >= UINT16_MAX)
70 return UINT16_MAX - 1;
71 return value >= 1 ? value - 1 : 0;
74 static void lastbus_init_monitor(const struct lastbus_monitor *m,
75 u32 timeout_ms, u32 timeout_type)
77 u16 timeout_thres;
78 int i;
80 for (i = 0; i < m->num_idle_mask; i++)
81 write32p(m->base + m->idle_masks[i].reg_offset,
82 m->idle_masks[i].reg_value);
84 /* clear timeout status with DBG_CKEN */
85 write32p(m->base, LASTBUS_TIMEOUT_CLR | LASTBUS_DEBUG_CKEN);
86 /* de-assert clear bit */
87 clrbits32p(m->base, LASTBUS_TIMEOUT_CLR);
89 if (timeout_ms == UINT32_MAX)
90 timeout_thres = 0xFFFF;
91 else
92 timeout_thres = calculate_timeout_thres(m->bus_freq_mhz, timeout_ms);
94 setbits32p(m->base, (timeout_thres << TIMEOUT_THRES_SHIFT) |
95 (timeout_type << TIMEOUT_TYPE_SHIFT));
96 setbits32p(m->base, LASTBUS_DEBUG_EN);
99 static void lastbus_setup(void)
101 int i;
103 for (i = 0; i < lastbus_cfg.num_used_monitors; i++)
104 lastbus_init_monitor(&lastbus_cfg.monitors[i], lastbus_cfg.timeout_ms,
105 lastbus_cfg.timeout_type);
108 void lastbus_init(void)
110 lastbus_dump();
111 lastbus_setup();