1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2021 BAIKAL ELECTRONICS, JSC 4 * 5 * Authors: 6 * Serge Semin <Sergey.Semin@baikalelectronics.ru> 7 * 8 * Baikal-T1 CCU Resets interface driver 9 */ 10 11 #define pr_fmt(fmt) "bt1-ccu-rst: " fmt 12 13 #include <linux/bits.h> 14 #include <linux/delay.h> 15 #include <linux/kernel.h> 16 #include <linux/of.h> 17 #include <linux/printk.h> 18 #include <linux/regmap.h> 19 #include <linux/reset-controller.h> 20 #include <linux/slab.h> 21 22 #include <dt-bindings/reset/bt1-ccu.h> 23 24 #include "ccu-rst.h" 25 26 #define CCU_AXI_MAIN_BASE 0x030 27 #define CCU_AXI_DDR_BASE 0x034 28 #define CCU_AXI_SATA_BASE 0x038 29 #define CCU_AXI_GMAC0_BASE 0x03C 30 #define CCU_AXI_GMAC1_BASE 0x040 31 #define CCU_AXI_XGMAC_BASE 0x044 32 #define CCU_AXI_PCIE_M_BASE 0x048 33 #define CCU_AXI_PCIE_S_BASE 0x04C 34 #define CCU_AXI_USB_BASE 0x050 35 #define CCU_AXI_HWA_BASE 0x054 36 #define CCU_AXI_SRAM_BASE 0x058 37 38 #define CCU_SYS_DDR_BASE 0x02c 39 #define CCU_SYS_SATA_REF_BASE 0x060 40 #define CCU_SYS_APB_BASE 0x064 41 #define CCU_SYS_PCIE_BASE 0x144 42 43 #define CCU_RST_DELAY_US 1 44 45 #define CCU_RST_TRIG(_base, _ofs) \ 46 { \ 47 .type = CCU_RST_TRIG, \ 48 .base = _base, \ 49 .mask = BIT(_ofs), \ 50 } 51 52 #define CCU_RST_DIR(_base, _ofs) \ 53 { \ 54 .type = CCU_RST_DIR, \ 55 .base = _base, \ 56 .mask = BIT(_ofs), \ 57 } 58 59 struct ccu_rst_info { 60 enum ccu_rst_type type; 61 unsigned int base; 62 unsigned int mask; 63 }; 64 65 /* 66 * Each AXI-bus clock divider is equipped with the corresponding clock-consumer 67 * domain reset (it's self-deasserted reset control). 68 */ 69 static const struct ccu_rst_info axi_rst_info[] = { 70 [CCU_AXI_MAIN_RST] = CCU_RST_TRIG(CCU_AXI_MAIN_BASE, 1), 71 [CCU_AXI_DDR_RST] = CCU_RST_TRIG(CCU_AXI_DDR_BASE, 1), 72 [CCU_AXI_SATA_RST] = CCU_RST_TRIG(CCU_AXI_SATA_BASE, 1), 73 [CCU_AXI_GMAC0_RST] = CCU_RST_TRIG(CCU_AXI_GMAC0_BASE, 1), 74 [CCU_AXI_GMAC1_RST] = CCU_RST_TRIG(CCU_AXI_GMAC1_BASE, 1), 75 [CCU_AXI_XGMAC_RST] = CCU_RST_TRIG(CCU_AXI_XGMAC_BASE, 1), 76 [CCU_AXI_PCIE_M_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_M_BASE, 1), 77 [CCU_AXI_PCIE_S_RST] = CCU_RST_TRIG(CCU_AXI_PCIE_S_BASE, 1), 78 [CCU_AXI_USB_RST] = CCU_RST_TRIG(CCU_AXI_USB_BASE, 1), 79 [CCU_AXI_HWA_RST] = CCU_RST_TRIG(CCU_AXI_HWA_BASE, 1), 80 [CCU_AXI_SRAM_RST] = CCU_RST_TRIG(CCU_AXI_SRAM_BASE, 1), 81 }; 82 83 /* 84 * SATA reference clock domain and APB-bus domain are connected with the 85 * sefl-deasserted reset control, which can be activated via the corresponding 86 * clock divider register. DDR and PCIe sub-domains can be reset with directly 87 * controlled reset signals. Resetting the DDR controller though won't end up 88 * well while the Linux kernel is working. 89 */ 90 static const struct ccu_rst_info sys_rst_info[] = { 91 [CCU_SYS_SATA_REF_RST] = CCU_RST_TRIG(CCU_SYS_SATA_REF_BASE, 1), 92 [CCU_SYS_APB_RST] = CCU_RST_TRIG(CCU_SYS_APB_BASE, 1), 93 [CCU_SYS_DDR_FULL_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 1), 94 [CCU_SYS_DDR_INIT_RST] = CCU_RST_DIR(CCU_SYS_DDR_BASE, 2), 95 [CCU_SYS_PCIE_PCS_PHY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 0), 96 [CCU_SYS_PCIE_PIPE0_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 4), 97 [CCU_SYS_PCIE_CORE_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 8), 98 [CCU_SYS_PCIE_PWR_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 9), 99 [CCU_SYS_PCIE_STICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 10), 100 [CCU_SYS_PCIE_NSTICKY_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 11), 101 [CCU_SYS_PCIE_HOT_RST] = CCU_RST_DIR(CCU_SYS_PCIE_BASE, 12), 102 }; 103 104 static int ccu_rst_reset(struct reset_controller_dev *rcdev, unsigned long idx) 105 { 106 struct ccu_rst *rst = to_ccu_rst(rcdev); 107 const struct ccu_rst_info *info = &rst->rsts_info[idx]; 108 109 if (info->type != CCU_RST_TRIG) 110 return -EOPNOTSUPP; 111 112 regmap_update_bits(rst->sys_regs, info->base, info->mask, info->mask); 113 114 /* The next delay must be enough to cover all the resets. */ 115 udelay(CCU_RST_DELAY_US); 116 117 return 0; 118 } 119 120 static int ccu_rst_set(struct reset_controller_dev *rcdev, 121 unsigned long idx, bool high) 122 { 123 struct ccu_rst *rst = to_ccu_rst(rcdev); 124 const struct ccu_rst_info *info = &rst->rsts_info[idx]; 125 126 if (info->type != CCU_RST_DIR) 127 return high ? -EOPNOTSUPP : 0; 128 129 return regmap_update_bits(rst->sys_regs, info->base, 130 info->mask, high ? info->mask : 0); 131 } 132 133 static int ccu_rst_assert(struct reset_controller_dev *rcdev, 134 unsigned long idx) 135 { 136 return ccu_rst_set(rcdev, idx, true); 137 } 138 139 static int ccu_rst_deassert(struct reset_controller_dev *rcdev, 140 unsigned long idx) 141 { 142 return ccu_rst_set(rcdev, idx, false); 143 } 144 145 static int ccu_rst_status(struct reset_controller_dev *rcdev, 146 unsigned long idx) 147 { 148 struct ccu_rst *rst = to_ccu_rst(rcdev); 149 const struct ccu_rst_info *info = &rst->rsts_info[idx]; 150 u32 val; 151 152 if (info->type != CCU_RST_DIR) 153 return -EOPNOTSUPP; 154 155 regmap_read(rst->sys_regs, info->base, &val); 156 157 return !!(val & info->mask); 158 } 159 160 static const struct reset_control_ops ccu_rst_ops = { 161 .reset = ccu_rst_reset, 162 .assert = ccu_rst_assert, 163 .deassert = ccu_rst_deassert, 164 .status = ccu_rst_status, 165 }; 166 167 struct ccu_rst *ccu_rst_hw_register(const struct ccu_rst_init_data *rst_init) 168 { 169 struct ccu_rst *rst; 170 int ret; 171 172 if (!rst_init) 173 return ERR_PTR(-EINVAL); 174 175 rst = kzalloc(sizeof(*rst), GFP_KERNEL); 176 if (!rst) 177 return ERR_PTR(-ENOMEM); 178 179 rst->sys_regs = rst_init->sys_regs; 180 if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-axi")) { 181 rst->rcdev.nr_resets = ARRAY_SIZE(axi_rst_info); 182 rst->rsts_info = axi_rst_info; 183 } else if (of_device_is_compatible(rst_init->np, "baikal,bt1-ccu-sys")) { 184 rst->rcdev.nr_resets = ARRAY_SIZE(sys_rst_info); 185 rst->rsts_info = sys_rst_info; 186 } else { 187 pr_err("Incompatible DT node '%s' specified\n", 188 of_node_full_name(rst_init->np)); 189 ret = -EINVAL; 190 goto err_kfree_rst; 191 } 192 193 rst->rcdev.owner = THIS_MODULE; 194 rst->rcdev.ops = &ccu_rst_ops; 195 rst->rcdev.of_node = rst_init->np; 196 197 ret = reset_controller_register(&rst->rcdev); 198 if (ret) { 199 pr_err("Couldn't register '%s' reset controller\n", 200 of_node_full_name(rst_init->np)); 201 goto err_kfree_rst; 202 } 203 204 return rst; 205 206 err_kfree_rst: 207 kfree(rst); 208 209 return ERR_PTR(ret); 210 } 211 212 void ccu_rst_hw_unregister(struct ccu_rst *rst) 213 { 214 reset_controller_unregister(&rst->rcdev); 215 216 kfree(rst); 217 } 218