18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Copyright (c) 2015 Pengutronix, Sascha Hauer <kernel@pengutronix.de> 48c2ecf20Sopenharmony_ci */ 58c2ecf20Sopenharmony_ci 68c2ecf20Sopenharmony_ci#include <linux/export.h> 78c2ecf20Sopenharmony_ci#include <linux/jiffies.h> 88c2ecf20Sopenharmony_ci#include <linux/regmap.h> 98c2ecf20Sopenharmony_ci#include <linux/soc/mediatek/infracfg.h> 108c2ecf20Sopenharmony_ci#include <asm/processor.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#define MTK_POLL_DELAY_US 10 138c2ecf20Sopenharmony_ci#define MTK_POLL_TIMEOUT (jiffies_to_usecs(HZ)) 148c2ecf20Sopenharmony_ci 158c2ecf20Sopenharmony_ci#define INFRA_TOPAXI_PROTECTEN 0x0220 168c2ecf20Sopenharmony_ci#define INFRA_TOPAXI_PROTECTSTA1 0x0228 178c2ecf20Sopenharmony_ci#define INFRA_TOPAXI_PROTECTEN_SET 0x0260 188c2ecf20Sopenharmony_ci#define INFRA_TOPAXI_PROTECTEN_CLR 0x0264 198c2ecf20Sopenharmony_ci 208c2ecf20Sopenharmony_ci/** 218c2ecf20Sopenharmony_ci * mtk_infracfg_set_bus_protection - enable bus protection 228c2ecf20Sopenharmony_ci * @infracfg: The infracfg regmap 238c2ecf20Sopenharmony_ci * @mask: The mask containing the protection bits to be enabled. 248c2ecf20Sopenharmony_ci * @reg_update: The boolean flag determines to set the protection bits 258c2ecf20Sopenharmony_ci * by regmap_update_bits with enable register(PROTECTEN) or 268c2ecf20Sopenharmony_ci * by regmap_write with set register(PROTECTEN_SET). 278c2ecf20Sopenharmony_ci * 288c2ecf20Sopenharmony_ci * This function enables the bus protection bits for disabled power 298c2ecf20Sopenharmony_ci * domains so that the system does not hang when some unit accesses the 308c2ecf20Sopenharmony_ci * bus while in power down. 318c2ecf20Sopenharmony_ci */ 328c2ecf20Sopenharmony_ciint mtk_infracfg_set_bus_protection(struct regmap *infracfg, u32 mask, 338c2ecf20Sopenharmony_ci bool reg_update) 348c2ecf20Sopenharmony_ci{ 358c2ecf20Sopenharmony_ci u32 val; 368c2ecf20Sopenharmony_ci int ret; 378c2ecf20Sopenharmony_ci 388c2ecf20Sopenharmony_ci if (reg_update) 398c2ecf20Sopenharmony_ci regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 408c2ecf20Sopenharmony_ci mask); 418c2ecf20Sopenharmony_ci else 428c2ecf20Sopenharmony_ci regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_SET, mask); 438c2ecf20Sopenharmony_ci 448c2ecf20Sopenharmony_ci ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, 458c2ecf20Sopenharmony_ci val, (val & mask) == mask, 468c2ecf20Sopenharmony_ci MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 478c2ecf20Sopenharmony_ci 488c2ecf20Sopenharmony_ci return ret; 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ci 518c2ecf20Sopenharmony_ci/** 528c2ecf20Sopenharmony_ci * mtk_infracfg_clear_bus_protection - disable bus protection 538c2ecf20Sopenharmony_ci * @infracfg: The infracfg regmap 548c2ecf20Sopenharmony_ci * @mask: The mask containing the protection bits to be disabled. 558c2ecf20Sopenharmony_ci * @reg_update: The boolean flag determines to clear the protection bits 568c2ecf20Sopenharmony_ci * by regmap_update_bits with enable register(PROTECTEN) or 578c2ecf20Sopenharmony_ci * by regmap_write with clear register(PROTECTEN_CLR). 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * This function disables the bus protection bits previously enabled with 608c2ecf20Sopenharmony_ci * mtk_infracfg_set_bus_protection. 618c2ecf20Sopenharmony_ci */ 628c2ecf20Sopenharmony_ci 638c2ecf20Sopenharmony_ciint mtk_infracfg_clear_bus_protection(struct regmap *infracfg, u32 mask, 648c2ecf20Sopenharmony_ci bool reg_update) 658c2ecf20Sopenharmony_ci{ 668c2ecf20Sopenharmony_ci int ret; 678c2ecf20Sopenharmony_ci u32 val; 688c2ecf20Sopenharmony_ci 698c2ecf20Sopenharmony_ci if (reg_update) 708c2ecf20Sopenharmony_ci regmap_update_bits(infracfg, INFRA_TOPAXI_PROTECTEN, mask, 0); 718c2ecf20Sopenharmony_ci else 728c2ecf20Sopenharmony_ci regmap_write(infracfg, INFRA_TOPAXI_PROTECTEN_CLR, mask); 738c2ecf20Sopenharmony_ci 748c2ecf20Sopenharmony_ci ret = regmap_read_poll_timeout(infracfg, INFRA_TOPAXI_PROTECTSTA1, 758c2ecf20Sopenharmony_ci val, !(val & mask), 768c2ecf20Sopenharmony_ci MTK_POLL_DELAY_US, MTK_POLL_TIMEOUT); 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci return ret; 798c2ecf20Sopenharmony_ci} 80