// SPDX-License-Identifier: GPL-2.0-or-later /* * Copyright (C) 2022-2024 Canaan Bright Sight Co., Ltd * Copyright (C) 2024-2025 Junhui Liu <junhui.liu@pigmoral.tech> * * The reset management module in the K230 SoC provides reset time control * registers. For RST_TYPE_CPU0, RST_TYPE_CPU1 and RST_TYPE_SW_DONE, the period * during which reset is applied or removed while the clock is stopped can be * set up to 15 * 0.25 = 3.75 µs. For RST_TYPE_HW_DONE, that period can be set * up to 255 * 0.25 = 63.75 µs. For RST_TYPE_FLUSH, the reset bit is * automatically cleared by hardware when flush completes. * * Although this driver does not configure the reset time registers, delays have * been added to the assert, deassert, and reset operations to cover the maximum * reset time. Some reset types include done bits whose toggle does not * unambiguously signal whether hardware reset removal or clock-stop period * expiration occurred first. Delays are therefore retained for types with done * bits to ensure safe timing. * * Reference: K230 Technical Reference Manual V0.3.1 * https://kendryte-download.canaan-creative.com/developer/k230/HDK/K230%E7%A1%AC%E4%BB%B6%E6%96%87%E6%A1%A3/K230_Technical_Reference_Manual_V0.3.1_20241118.pdf
*/
/** * enum k230_rst_type - K230 reset types * @RST_TYPE_CPU0: Reset type for CPU0 * Automatically clears, has write enable and done bit, active high * @RST_TYPE_CPU1: Reset type for CPU1 * Manually clears, has write enable and done bit, active high * @RST_TYPE_FLUSH: Reset type for CPU L2 cache flush * Automatically clears, has write enable, no done bit, active high * @RST_TYPE_HW_DONE: Reset type for hardware auto clear * Automatically clears, no write enable, has done bit, active high * @RST_TYPE_SW_DONE: Reset type for software manual clear * Manually clears, no write enable and done bit, * active high if ID is RST_SPI2AXI, otherwise active low
*/ enum k230_rst_type {
RST_TYPE_CPU0,
RST_TYPE_CPU1,
RST_TYPE_FLUSH,
RST_TYPE_HW_DONE,
RST_TYPE_SW_DONE,
};
switch (k230_resets[id].type) { case RST_TYPE_CPU1:
k230_rst_update(rstc, id, true, true, false); break; case RST_TYPE_SW_DONE:
k230_rst_update(rstc, id, true, false,
id == RST_SPI2AXI ? false : true); break; case RST_TYPE_CPU0: case RST_TYPE_FLUSH: case RST_TYPE_HW_DONE: return -EOPNOTSUPP;
}
/* * The time period when reset is applied but the clock is stopped for * RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay * 10us to ensure proper reset timing.
*/
udelay(10);
return0;
}
staticint k230_rst_deassert(struct reset_controller_dev *rcdev, unsignedlong id)
{ struct k230_rst *rstc = to_k230_rst(rcdev); int ret = 0;
switch (k230_resets[id].type) { case RST_TYPE_CPU1:
k230_rst_update(rstc, id, false, true, false);
ret = k230_rst_wait_and_clear_done(rstc, id, true); break; case RST_TYPE_SW_DONE:
k230_rst_update(rstc, id, false, false,
id == RST_SPI2AXI ? false : true); break; case RST_TYPE_CPU0: case RST_TYPE_FLUSH: case RST_TYPE_HW_DONE: return -EOPNOTSUPP;
}
/* * The time period when reset is removed but the clock is stopped for * RST_TYPE_CPU1 and RST_TYPE_SW_DONE can be set up to 3.75us. Delay * 10us to ensure proper reset timing.
*/
udelay(10);
switch (rmap->type) { case RST_TYPE_CPU0:
k230_rst_clear_done(rstc, id, true);
k230_rst_update(rstc, id, true, true, false);
ret = k230_rst_wait_and_clear_done(rstc, id, true);
/* * The time period when reset is applied and removed but the * clock is stopped for RST_TYPE_CPU0 can be set up to 7.5us. * Delay 10us to ensure proper reset timing.
*/
udelay(10);
break; case RST_TYPE_FLUSH:
k230_rst_update(rstc, id, true, true, false);
/* Wait flush request bit auto cleared by hardware */
ret = readl_poll_timeout(rstc->base + rmap->offset, reg,
!(reg & rmap->reset), 10, 1000); if (ret)
dev_err(rcdev->dev, "Wait for flush done timeout\n");
break; case RST_TYPE_HW_DONE:
k230_rst_clear_done(rstc, id, false);
k230_rst_update(rstc, id, true, false, false);
ret = k230_rst_wait_and_clear_done(rstc, id, false);
/* * The time period when reset is applied and removed but the * clock is stopped for RST_TYPE_HW_DONE can be set up to * 127.5us. Delay 200us to ensure proper reset timing.
*/
fsleep(200);
break; case RST_TYPE_CPU1: case RST_TYPE_SW_DONE:
k230_rst_assert(rcdev, id);
ret = k230_rst_deassert(rcdev, id); break;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.