1*16a624a9SSascha Hauer /* 2*16a624a9SSascha Hauer * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> 3*16a624a9SSascha Hauer * 4*16a624a9SSascha Hauer * This program is free software; you can redistribute it and/or modify 5*16a624a9SSascha Hauer * it under the terms of the GNU General Public License version 2 as 6*16a624a9SSascha Hauer * published by the Free Software Foundation. 7*16a624a9SSascha Hauer * 8*16a624a9SSascha Hauer * This program is distributed in the hope that it will be useful, 9*16a624a9SSascha Hauer * but WITHOUT ANY WARRANTY; without even the implied warranty of 10*16a624a9SSascha Hauer * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11*16a624a9SSascha Hauer * GNU General Public License for more details. 12*16a624a9SSascha Hauer */ 13*16a624a9SSascha Hauer 14*16a624a9SSascha Hauer #include <linux/export.h> 15*16a624a9SSascha Hauer #include <linux/jiffies.h> 16*16a624a9SSascha Hauer #include <linux/regmap.h> 17*16a624a9SSascha Hauer #include <linux/soc/mediatek/infracfg.h> 18*16a624a9SSascha Hauer #include <asm/processor.h> 19*16a624a9SSascha Hauer 20*16a624a9SSascha Hauer #define INFRA_TOPAXI_PROTECTEN 0x0220 21*16a624a9SSascha Hauer #define INFRA_TOPAXI_PROTECTSTA1 0x0228 22*16a624a9SSascha Hauer 23*16a624a9SSascha Hauer /** 24*16a624a9SSascha Hauer * mtk_infracfg_set_bus_protection - enable bus protection 25*16a624a9SSascha Hauer * @regmap: The infracfg regmap 26*16a624a9SSascha Hauer * @mask: The mask containing the protection bits to be enabled. 27*16a624a9SSascha Hauer * 28*16a624a9SSascha Hauer * This function enables the bus protection bits for disabled power 29*16a624a9SSascha Hauer * domains so that the system does not hang when some unit accesses the 30*16a624a9SSascha Hauer * bus while in power down. 31*16a624a9SSascha Hauer */ 32*16a624a9SSascha Hauer int mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask) 33*16a624a9SSascha Hauer { 34*16a624a9SSascha Hauer unsigned long expired; 35*16a624a9SSascha Hauer u32 val; 36*16a624a9SSascha Hauer int ret; 37*16a624a9SSascha Hauer 38*16a624a9SSascha Hauer regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, mask); 39*16a624a9SSascha Hauer 40*16a624a9SSascha Hauer expired = jiffies + HZ; 41*16a624a9SSascha Hauer 42*16a624a9SSascha Hauer while (1) { 43*16a624a9SSascha Hauer ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); 44*16a624a9SSascha Hauer if (ret) 45*16a624a9SSascha Hauer return ret; 46*16a624a9SSascha Hauer 47*16a624a9SSascha Hauer if ((val & mask) == mask) 48*16a624a9SSascha Hauer break; 49*16a624a9SSascha Hauer 50*16a624a9SSascha Hauer cpu_relax(); 51*16a624a9SSascha Hauer if (time_after(jiffies, expired)) 52*16a624a9SSascha Hauer return -EIO; 53*16a624a9SSascha Hauer } 54*16a624a9SSascha Hauer 55*16a624a9SSascha Hauer return 0; 56*16a624a9SSascha Hauer } 57*16a624a9SSascha Hauer 58*16a624a9SSascha Hauer /** 59*16a624a9SSascha Hauer * mtk_infracfg_clear_bus_protection - disable bus protection 60*16a624a9SSascha Hauer * @regmap: The infracfg regmap 61*16a624a9SSascha Hauer * @mask: The mask containing the protection bits to be disabled. 62*16a624a9SSascha Hauer * 63*16a624a9SSascha Hauer * This function disables the bus protection bits previously enabled with 64*16a624a9SSascha Hauer * mtk_infracfg_set_bus_protection. 65*16a624a9SSascha Hauer */ 66*16a624a9SSascha Hauer int mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask) 67*16a624a9SSascha Hauer { 68*16a624a9SSascha Hauer unsigned long expired; 69*16a624a9SSascha Hauer int ret; 70*16a624a9SSascha Hauer 71*16a624a9SSascha Hauer regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); 72*16a624a9SSascha Hauer 73*16a624a9SSascha Hauer expired = jiffies + HZ; 74*16a624a9SSascha Hauer 75*16a624a9SSascha Hauer while (1) { 76*16a624a9SSascha Hauer u32 val; 77*16a624a9SSascha Hauer 78*16a624a9SSascha Hauer ret = regmap_read(infracfg, INFRA_TOPAXI_PROTECTSTA1, &val); 79*16a624a9SSascha Hauer if (ret) 80*16a624a9SSascha Hauer return ret; 81*16a624a9SSascha Hauer 82*16a624a9SSascha Hauer if (!(val & mask)) 83*16a624a9SSascha Hauer break; 84*16a624a9SSascha Hauer 85*16a624a9SSascha Hauer cpu_relax(); 86*16a624a9SSascha Hauer if (time_after(jiffies, expired)) 87*16a624a9SSascha Hauer return -EIO; 88*16a624a9SSascha Hauer } 89*16a624a9SSascha Hauer 90*16a624a9SSascha Hauer return 0; 91*16a624a9SSascha Hauer } 92