^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0-only
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) #include <linux/export.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) #include <linux/jiffies.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) #include <linux/regmap.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) #include <linux/soc/mediatek/infracfg.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) #include <asm/processor.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) #define MTK_POLL_DELAY_US 10
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) #define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #define INFRA_TOPAXI_PROTECTEN 0x0220
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #define INFRA_TOPAXI_PROTECTSTA1 0x0228
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #define INFRA_TOPAXI_PROTECTEN_SET 0x0260
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #define INFRA_TOPAXI_PROTECTEN_CLR 0x0264
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) * mtk_infracfg_set_bus_protection - enable bus protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) * @infracfg: The infracfg regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23) * @mask: The mask containing the protection bits to be enabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) * @reg_update: The boolean flag determines to set the protection bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) * by regmap_update_bits with enable register(PROTECTEN) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) * by regmap_write with set register(PROTECTEN_SET).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) * This function enables the bus protection bits for disabled power
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) * domains so that the system does not hang when some unit accesses the
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) * bus while in power down.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) bool reg_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) if (reg_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) val, (val & mask) == mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) /**
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) * mtk_infracfg_clear_bus_protection - disable bus protection
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) * @infracfg: The infracfg regmap
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) * @mask: The mask containing the protection bits to be disabled.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) * @reg_update: The boolean flag determines to clear the protection bits
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) * by regmap_update_bits with enable register(PROTECTEN) or
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) * by regmap_write with clear register(PROTECTEN_CLR).
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) * This function disables the bus protection bits previously enabled with
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) * mtk_infracfg_set_bus_protection.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) bool reg_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) int ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) u32 val;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) if (reg_update)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) val, !(val & mask),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) return ret;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) }