1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> 4 */ 5 6 #include <linux/export.h> 7 #include <linux/jiffies.h> 8 #include <linux/regmap.h> 9 #include <linux/mfd/syscon.h> 10 #include <linux/soc/mediatek/infracfg.h> 11 #include <asm/processor.h> 12 13 #define MTK_POLL_DELAY_US 10 14 #define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ)) 15 16 /** 17 * mtk_infracfg_set_bus_protection - enable bus protection 18 * @infracfg: The infracfg regmap 19 * @mask: The mask containing the protection bits to be enabled. 20 * @reg_update: The boolean flag determines to set the protection bits 21 * by regmap_update_bits with enable register(PROTECTEN) or 22 * by regmap_write with set register(PROTECTEN_SET). 23 * 24 * This function enables the bus protection bits for disabled power 25 * domains so that the system does not hang when some unit accesses the 26 * bus while in power down. 27 */ 28 int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, 29 bool reg_update) 30 { 31 u32 val; 32 int ret; 33 34 if (reg_update) 35 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 36 mask); 37 else 38 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask); 39 40 ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, 41 val, (val & mask) == mask, 42 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 43 44 return ret; 45 } 46 47 /** 48 * mtk_infracfg_clear_bus_protection - disable bus protection 49 * @infracfg: The infracfg regmap 50 * @mask: The mask containing the protection bits to be disabled. 51 * @reg_update: The boolean flag determines to clear the protection bits 52 * by regmap_update_bits with enable register(PROTECTEN) or 53 * by regmap_write with clear register(PROTECTEN_CLR). 54 * 55 * This function disables the bus protection bits previously enabled with 56 * mtk_infracfg_set_bus_protection. 57 */ 58 59 int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, 60 bool reg_update) 61 { 62 int ret; 63 u32 val; 64 65 if (reg_update) 66 regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); 67 else 68 regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask); 69 70 ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, 71 val, !(val & mask), 72 MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 73 74 return ret; 75 } 76 77 static int __init mtk_infracfg_init(void) 78 { 79 struct regmap *infracfg; 80 81 /* 82 * MT8192 has an experimental path to route GPU traffic to the DSU's 83 * Accelerator Coherency Port, which is inadvertently enabled by 84 * default. It turns out not to work, so disable it to prevent spurious 85 * GPU faults. 86 */ 87 infracfg = syscon_regmap_lookup_by_compatible("mediatek,mt8192-infracfg"); 88 if (!IS_ERR(infracfg)) 89 regmap_set_bits(infracfg, MT8192_INFRA_CTRL, 90 MT8192_INFRA_CTRL_DISABLE_MFG2ACP); 91 return 0; 92 } 93 postcore_initcall(mtk_infracfg_init); 94