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>
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
)
28 static void lastbus_dump_monitor(const struct lastbus_monitor
*m
)
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
;
51 for (i
= 0; i
< lastbus_cfg
.num_used_monitors
; i
++) {
52 m
= &lastbus_cfg
.monitors
[i
];
53 if (!lastbus_is_timeout(m
))
58 "\n******************* %s lastbus ******************\n",
59 lastbus_cfg
.latch_platform
);
61 lastbus_dump_monitor(m
);
65 static u16
calculate_timeout_thres(u16 bus_freq_mhz
, u32 timeout_ms
)
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
)
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;
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)
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)