In my use-case, before uboot jumps to booting linux, it should start watchdog on SCU. After kernel boots and everything is fine, the application on linux side would stop the watchdog.
Since we don't have a driver in uboot, I am initializing watchdog in uboot like this:
#define IMX_SIP_TIMER 0xC2000002
#define IMX_SIP_TIMER_START_WDOG 0x01
#define IMX_SIP_TIMER_STOP_WDOG 0x02
#define IMX_SIP_TIMER_SET_WDOG_ACT 0x03
#define IMX_SIP_TIMER_PING_WDOG 0x04
#define IMX_SIP_TIMER_SET_TIMEOUT_WDOG 0x05
#define IMX_SIP_TIMER_GET_WDOG_STAT 0x06
#define IMX_SIP_TIMER_SET_PRETIME_WDOG 0x07
#define SC_TIMER_WDOG_ACTION_PARTITION 0
void startWatchdogInUboot()
{
struct arm_smccc_res res;
u32 timeout=60000;
arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_TIMEOUT_WDOG,
timeout, 0, 0, 0, 0, 0, &res);
arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_START_WDOG,
0, 0, 0, 0, 0, 0, &res);
arm_smccc_smc(IMX_SIP_TIMER, IMX_SIP_TIMER_SET_WDOG_ACT,
SC_TIMER_WDOG_ACTION_PARTITION,
0, 0, 0, 0, 0, &res);
}
this code activates the watchdog.
If we don't do anything on linux side, it reboots after 60 secs.
On Linux side, there is already a driver for the watchdog in IMX8qxp (imx_sc_wdt.c).
On linux side also everything works fine, if I don't start the watchdog in uboot: I can start/stop the watchdog.
But when I activate the watchdog on uboot, I have no access to scu and watchdog from linux.
echo V > /dev/watchdog0
or
echo L > /dev/watchdog0
ends with "Permission denied"
a deeper look shows in driver, that the checks after
arm_smccc_smc( ... )
the checks like
if (res.a0)
return -EACCES;
fail. The actuak value of res.a0 is 10, which.
Any ideas, what I am missing?
Thanks in advance
I've struggled with the same thing in my design. Here's how I implemented this feature in my design.
The watchdog is enabled from the board_system_config() function in the board.c (SCFW)
More information:
The only way I managed to disable the watchdog from the Linux user-space was to write a custom device driver that calls the board_ioctl() function in the board.c (SCFW). From the board_ioctl() I can then disable the watchdog by simply calling timer_stop_wdog().
To create RPC in the custom device driver which calls the board_ioctl() function you need to
1. Include <linux/firmware/imx/ipc.h>
2. Get handle to the ipc (imx_scu_get_handle())
3. Create a proper message
- ver = IMX_SC_RPC_VERSION
- svc = IMX_SC_RPC_SVC_MISC
- func = 34 "sc_misc_board_ioctl()"
- size = 4
- Those 3 parameters you can define as you wish depending on how you wish to parse the stop watchdog message in board_ioctl() function
4. Call imx_scu_call_rpc() function with proper handle and message
Hope this helps. I've spent a lot of time googling for an answer to this, but the replies mainly point at looking the SCFW porting guide, which itself is not that helpful. I'm not sure if this is the best way to do it, but this was the only way I could make it work for now.
I know this is already a quite old post, but I decided to write one possible solution as I couldn't find any on this forum after spending some hours of googling.