|
| 1 | +// SPDX-License-Identifier: GPL-2.0-only |
| 2 | +/* |
| 3 | + * |
| 4 | + * CIX System Reset Controller (SRC) driver |
| 5 | + * |
| 6 | + * Author: Jerry Zhu <jerry.zhu@cixtech.com> |
| 7 | + */ |
| 8 | + |
| 9 | +#include <linux/delay.h> |
| 10 | +#include <linux/mfd/syscon.h> |
| 11 | +#include <linux/module.h> |
| 12 | +#include <linux/of.h> |
| 13 | +#include <linux/platform_device.h> |
| 14 | +#include <linux/regmap.h> |
| 15 | +#include <linux/reset-controller.h> |
| 16 | + |
| 17 | +#include <dt-bindings/reset/cix,sky1-system-control.h> |
| 18 | +#include <dt-bindings/reset/cix,sky1-s5-system-control.h> |
| 19 | + |
| 20 | +#define SKY1_RESET_SLEEP_MIN_US 50 |
| 21 | +#define SKY1_RESET_SLEEP_MAX_US 100 |
| 22 | + |
| 23 | +struct sky1_src_signal { |
| 24 | + unsigned int offset; |
| 25 | + unsigned int bit; |
| 26 | +}; |
| 27 | + |
| 28 | +struct sky1_src_variant { |
| 29 | + const struct sky1_src_signal *signals; |
| 30 | + unsigned int signals_num; |
| 31 | +}; |
| 32 | + |
| 33 | +struct sky1_src { |
| 34 | + struct reset_controller_dev rcdev; |
| 35 | + const struct sky1_src_signal *signals; |
| 36 | + struct regmap *regmap; |
| 37 | +}; |
| 38 | + |
| 39 | +enum { |
| 40 | + CSU_PM_RESET = 0x304, |
| 41 | + SENSORFUSION_RESET = 0x308, |
| 42 | + SENSORFUSION_NOC_RESET = 0x30c, |
| 43 | + RESET_GROUP0_S0_DOMAIN_0 = 0x400, |
| 44 | + RESET_GROUP0_S0_DOMAIN_1 = 0x404, |
| 45 | + RESET_GROUP1_USB_PHYS = 0x408, |
| 46 | + RESET_GROUP1_USB_CONTROLLERS = 0x40c, |
| 47 | + RESET_GROUP0_RCSU = 0x800, |
| 48 | + RESET_GROUP1_RCSU = 0x804, |
| 49 | +}; |
| 50 | + |
| 51 | +static const struct sky1_src_signal sky1_src_signals[] = { |
| 52 | + /* reset group1 for s0 domain modules */ |
| 53 | + [SKY1_CSU_PM_RESET_N] = { CSU_PM_RESET, BIT(0) }, |
| 54 | + [SKY1_SENSORFUSION_RESET_N] = { SENSORFUSION_RESET, BIT(0) }, |
| 55 | + [SKY1_SENSORFUSION_NOC_RESET_N] = { SENSORFUSION_NOC_RESET, BIT(0) }, |
| 56 | + [SKY1_DDRC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(0) }, |
| 57 | + [SKY1_GIC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(1) }, |
| 58 | + [SKY1_CI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(2) }, |
| 59 | + [SKY1_SYS_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(3) }, |
| 60 | + [SKY1_MM_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(4) }, |
| 61 | + [SKY1_PCIE_NI700_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(5) }, |
| 62 | + [SKY1_GPU_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(6) }, |
| 63 | + [SKY1_NPUTOP_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(7) }, |
| 64 | + [SKY1_NPUCORE0_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(8) }, |
| 65 | + [SKY1_NPUCORE1_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(9) }, |
| 66 | + [SKY1_NPUCORE2_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(10) }, |
| 67 | + [SKY1_VPU_RESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(11) }, |
| 68 | + [SKY1_ISP_SRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(12) }, |
| 69 | + [SKY1_ISP_ARESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(13) }, |
| 70 | + [SKY1_ISP_HRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(14) }, |
| 71 | + [SKY1_ISP_GDCRESET_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(15) }, |
| 72 | + [SKY1_DPU_RESET0_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(16) }, |
| 73 | + [SKY1_DPU_RESET1_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(17) }, |
| 74 | + [SKY1_DPU_RESET2_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(18) }, |
| 75 | + [SKY1_DPU_RESET3_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(19) }, |
| 76 | + [SKY1_DPU_RESET4_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(20) }, |
| 77 | + [SKY1_DP_RESET0_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(21) }, |
| 78 | + [SKY1_DP_RESET1_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(22) }, |
| 79 | + [SKY1_DP_RESET2_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(23) }, |
| 80 | + [SKY1_DP_RESET3_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(24) }, |
| 81 | + [SKY1_DP_RESET4_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(25) }, |
| 82 | + [SKY1_DP_PHY_RST_N] = { RESET_GROUP0_S0_DOMAIN_0, BIT(26) }, |
| 83 | + |
| 84 | + /* reset group1 for s0 domain modules */ |
| 85 | + [SKY1_AUDIO_HIFI5_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(0) }, |
| 86 | + [SKY1_AUDIO_HIFI5_NOC_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(1) }, |
| 87 | + [SKY1_CSIDPHY_PRST0_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(2) }, |
| 88 | + [SKY1_CSIDPHY_CMNRST0_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(3) }, |
| 89 | + [SKY1_CSI0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(4) }, |
| 90 | + [SKY1_CSIDPHY_PRST1_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(5) }, |
| 91 | + [SKY1_CSIDPHY_CMNRST1_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(6) }, |
| 92 | + [SKY1_CSI1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(7) }, |
| 93 | + [SKY1_CSI2_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(8) }, |
| 94 | + [SKY1_CSI3_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(9) }, |
| 95 | + [SKY1_CSIBRDGE0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(10) }, |
| 96 | + [SKY1_CSIBRDGE1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(11) }, |
| 97 | + [SKY1_CSIBRDGE2_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(12) }, |
| 98 | + [SKY1_CSIBRDGE3_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(13) }, |
| 99 | + [SKY1_GMAC0_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(14) }, |
| 100 | + [SKY1_GMAC1_RST_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(15) }, |
| 101 | + [SKY1_PCIE0_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(16) }, |
| 102 | + [SKY1_PCIE1_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(17) }, |
| 103 | + [SKY1_PCIE2_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(18) }, |
| 104 | + [SKY1_PCIE3_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(19) }, |
| 105 | + [SKY1_PCIE4_RESET_N] = { RESET_GROUP0_S0_DOMAIN_1, BIT(20) }, |
| 106 | + |
| 107 | + /* reset group1 for usb phys */ |
| 108 | + [SKY1_USB_DP_PHY0_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(0) }, |
| 109 | + [SKY1_USB_DP_PHY1_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(1) }, |
| 110 | + [SKY1_USB_DP_PHY2_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(2) }, |
| 111 | + [SKY1_USB_DP_PHY3_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(3) }, |
| 112 | + [SKY1_USB_DP_PHY0_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(4) }, |
| 113 | + [SKY1_USB_DP_PHY1_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(5) }, |
| 114 | + [SKY1_USB_DP_PHY2_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(6) }, |
| 115 | + [SKY1_USB_DP_PHY3_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(7) }, |
| 116 | + [SKY1_USBPHY_SS_PST_N] = { RESET_GROUP1_USB_PHYS, BIT(8) }, |
| 117 | + [SKY1_USBPHY_SS_RST_N] = { RESET_GROUP1_USB_PHYS, BIT(9) }, |
| 118 | + [SKY1_USBPHY_HS0_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(10) }, |
| 119 | + [SKY1_USBPHY_HS1_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(11) }, |
| 120 | + [SKY1_USBPHY_HS2_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(12) }, |
| 121 | + [SKY1_USBPHY_HS3_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(13) }, |
| 122 | + [SKY1_USBPHY_HS4_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(14) }, |
| 123 | + [SKY1_USBPHY_HS5_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(15) }, |
| 124 | + [SKY1_USBPHY_HS6_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(16) }, |
| 125 | + [SKY1_USBPHY_HS7_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(17) }, |
| 126 | + [SKY1_USBPHY_HS8_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(18) }, |
| 127 | + [SKY1_USBPHY_HS9_PRST_N] = { RESET_GROUP1_USB_PHYS, BIT(19) }, |
| 128 | + |
| 129 | + /* reset group1 for usb controllers */ |
| 130 | + [SKY1_USBC_SS0_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(0) }, |
| 131 | + [SKY1_USBC_SS1_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(1) }, |
| 132 | + [SKY1_USBC_SS2_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(2) }, |
| 133 | + [SKY1_USBC_SS3_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(3) }, |
| 134 | + [SKY1_USBC_SS4_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(4) }, |
| 135 | + [SKY1_USBC_SS5_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(5) }, |
| 136 | + [SKY1_USBC_SS0_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(6) }, |
| 137 | + [SKY1_USBC_SS1_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(7) }, |
| 138 | + [SKY1_USBC_SS2_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(8) }, |
| 139 | + [SKY1_USBC_SS3_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(9) }, |
| 140 | + [SKY1_USBC_SS4_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(10) }, |
| 141 | + [SKY1_USBC_SS5_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(11) }, |
| 142 | + [SKY1_USBC_HS0_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(12) }, |
| 143 | + [SKY1_USBC_HS1_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(13) }, |
| 144 | + [SKY1_USBC_HS2_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(14) }, |
| 145 | + [SKY1_USBC_HS3_PRST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(15) }, |
| 146 | + [SKY1_USBC_HS0_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(16) }, |
| 147 | + [SKY1_USBC_HS1_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(17) }, |
| 148 | + [SKY1_USBC_HS2_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(18) }, |
| 149 | + [SKY1_USBC_HS3_RST_N] = { RESET_GROUP1_USB_CONTROLLERS, BIT(19) }, |
| 150 | + |
| 151 | + /* reset group0 for rcsu */ |
| 152 | + [SKY1_AUDIO_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(0) }, |
| 153 | + [SKY1_CI700_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(1) }, |
| 154 | + [SKY1_CSI_RCSU0_RESET_N] = { RESET_GROUP0_RCSU, BIT(2) }, |
| 155 | + [SKY1_CSI_RCSU1_RESET_N] = { RESET_GROUP0_RCSU, BIT(3) }, |
| 156 | + [SKY1_CSU_PM_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(4) }, |
| 157 | + [SKY1_DDR_BROADCAST_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(5) }, |
| 158 | + [SKY1_DDR_CTRL_RCSU_0_RESET_N] = { RESET_GROUP0_RCSU, BIT(6) }, |
| 159 | + [SKY1_DDR_CTRL_RCSU_1_RESET_N] = { RESET_GROUP0_RCSU, BIT(7) }, |
| 160 | + [SKY1_DDR_CTRL_RCSU_2_RESET_N] = { RESET_GROUP0_RCSU, BIT(8) }, |
| 161 | + [SKY1_DDR_CTRL_RCSU_3_RESET_N] = { RESET_GROUP0_RCSU, BIT(9) }, |
| 162 | + [SKY1_DDR_TZC400_RCSU_0_RESET_N] = { RESET_GROUP0_RCSU, BIT(10) }, |
| 163 | + [SKY1_DDR_TZC400_RCSU_1_RESET_N] = { RESET_GROUP0_RCSU, BIT(11) }, |
| 164 | + [SKY1_DDR_TZC400_RCSU_2_RESET_N] = { RESET_GROUP0_RCSU, BIT(12) }, |
| 165 | + [SKY1_DDR_TZC400_RCSU_3_RESET_N] = { RESET_GROUP0_RCSU, BIT(13) }, |
| 166 | + [SKY1_DP0_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(14) }, |
| 167 | + [SKY1_DP1_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(15) }, |
| 168 | + [SKY1_DP2_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(16) }, |
| 169 | + [SKY1_DP3_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(17) }, |
| 170 | + [SKY1_DP4_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(18) }, |
| 171 | + [SKY1_DPU0_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(19) }, |
| 172 | + [SKY1_DPU1_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(20) }, |
| 173 | + [SKY1_DPU2_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(21) }, |
| 174 | + [SKY1_DPU3_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(22) }, |
| 175 | + [SKY1_DPU4_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(23) }, |
| 176 | + [SKY1_DSU_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(24) }, |
| 177 | + [SKY1_FCH_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(25) }, |
| 178 | + [SKY1_GICD_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(26) }, |
| 179 | + [SKY1_GMAC_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(27) }, |
| 180 | + [SKY1_GPU_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(28) }, |
| 181 | + [SKY1_ISP_RCSU0_RESET_N] = { RESET_GROUP0_RCSU, BIT(29) }, |
| 182 | + [SKY1_ISP_RCSU1_RESET_N] = { RESET_GROUP0_RCSU, BIT(30) }, |
| 183 | + [SKY1_NI700_MMHUB_RCSU_RESET_N] = { RESET_GROUP0_RCSU, BIT(31) }, |
| 184 | + |
| 185 | + /* reset group1 for rcsu */ |
| 186 | + [SKY1_NPU_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(0) }, |
| 187 | + [SKY1_NI700_PCIE_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(1) }, |
| 188 | + [SKY1_PCIE_X421_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(2) }, |
| 189 | + [SKY1_PCIE_X8_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(3) }, |
| 190 | + [SKY1_SF_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(4) }, |
| 191 | + [SKY1_RCSU_SMMU_MMHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(5) }, |
| 192 | + [SKY1_RCSU_SMMU_PCIEHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(6) }, |
| 193 | + [SKY1_RCSU_SYSHUB_RESET_N] = { RESET_GROUP1_RCSU, BIT(7) }, |
| 194 | + [SKY1_NI700_SMN_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(8) }, |
| 195 | + [SKY1_NI700_SYSHUB_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(9) }, |
| 196 | + [SKY1_RCSU_USB2_HOST0_RESET_N] = { RESET_GROUP1_RCSU, BIT(10) }, |
| 197 | + [SKY1_RCSU_USB2_HOST1_RESET_N] = { RESET_GROUP1_RCSU, BIT(11) }, |
| 198 | + [SKY1_RCSU_USB2_HOST2_RESET_N] = { RESET_GROUP1_RCSU, BIT(12) }, |
| 199 | + [SKY1_RCSU_USB2_HOST3_RESET_N] = { RESET_GROUP1_RCSU, BIT(13) }, |
| 200 | + [SKY1_RCSU_USB3_TYPEA_DRD_RESET_N] = { RESET_GROUP1_RCSU, BIT(14) }, |
| 201 | + [SKY1_RCSU_USB3_TYPEC_DRD_RESET_N] = { RESET_GROUP1_RCSU, BIT(15) }, |
| 202 | + [SKY1_RCSU_USB3_TYPEC_HOST0_RESET_N] = { RESET_GROUP1_RCSU, BIT(16) }, |
| 203 | + [SKY1_RCSU_USB3_TYPEC_HOST1_RESET_N] = { RESET_GROUP1_RCSU, BIT(17) }, |
| 204 | + [SKY1_RCSU_USB3_TYPEC_HOST2_RESET_N] = { RESET_GROUP1_RCSU, BIT(18) }, |
| 205 | + [SKY1_VPU_RCSU_RESET_N] = { RESET_GROUP1_RCSU, BIT(19) }, |
| 206 | +}; |
| 207 | + |
| 208 | +static const struct sky1_src_variant variant_sky1 = { |
| 209 | + .signals = sky1_src_signals, |
| 210 | + .signals_num = ARRAY_SIZE(sky1_src_signals), |
| 211 | +}; |
| 212 | + |
| 213 | +enum { |
| 214 | + FCH_SW_RST_FUNC = 0x8, |
| 215 | + FCH_SW_RST_BUS = 0xc, |
| 216 | + FCH_SW_XSPI = 0x10, |
| 217 | +}; |
| 218 | + |
| 219 | +static const struct sky1_src_signal sky1_src_fch_signals[] = { |
| 220 | + /* resets for fch_sw_rst_func */ |
| 221 | + [SW_I3C0_RST_FUNC_G_N] = { FCH_SW_RST_FUNC, BIT(0) }, |
| 222 | + [SW_I3C0_RST_FUNC_I_N] = { FCH_SW_RST_FUNC, BIT(1) }, |
| 223 | + [SW_I3C1_RST_FUNC_G_N] = { FCH_SW_RST_FUNC, BIT(2) }, |
| 224 | + [SW_I3C1_RST_FUNC_I_N] = { FCH_SW_RST_FUNC, BIT(3) }, |
| 225 | + [SW_UART0_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(4) }, |
| 226 | + [SW_UART1_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(5) }, |
| 227 | + [SW_UART2_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(6) }, |
| 228 | + [SW_UART3_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(7) }, |
| 229 | + [SW_TIMER_RST_FUNC_N] = { FCH_SW_RST_FUNC, BIT(20) }, |
| 230 | + |
| 231 | + /* resets for fch_sw_rst_bus */ |
| 232 | + [SW_I3C0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(0) }, |
| 233 | + [SW_I3C1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(1) }, |
| 234 | + [SW_DMA_RST_AXI_N] = { FCH_SW_RST_BUS, BIT(2) }, |
| 235 | + [SW_UART0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(4) }, |
| 236 | + [SW_UART1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(5) }, |
| 237 | + [SW_UART2_RST_APB_N] = { FCH_SW_RST_BUS, BIT(6) }, |
| 238 | + [SW_UART3_RST_APB_N] = { FCH_SW_RST_BUS, BIT(7) }, |
| 239 | + [SW_SPI0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(8) }, |
| 240 | + [SW_SPI1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(9) }, |
| 241 | + [SW_I2C0_RST_APB_N] = { FCH_SW_RST_BUS, BIT(12) }, |
| 242 | + [SW_I2C1_RST_APB_N] = { FCH_SW_RST_BUS, BIT(13) }, |
| 243 | + [SW_I2C2_RST_APB_N] = { FCH_SW_RST_BUS, BIT(14) }, |
| 244 | + [SW_I2C3_RST_APB_N] = { FCH_SW_RST_BUS, BIT(15) }, |
| 245 | + [SW_I2C4_RST_APB_N] = { FCH_SW_RST_BUS, BIT(16) }, |
| 246 | + [SW_I2C5_RST_APB_N] = { FCH_SW_RST_BUS, BIT(17) }, |
| 247 | + [SW_I2C6_RST_APB_N] = { FCH_SW_RST_BUS, BIT(18) }, |
| 248 | + [SW_I2C7_RST_APB_N] = { FCH_SW_RST_BUS, BIT(19) }, |
| 249 | + [SW_GPIO_RST_APB_N] = { FCH_SW_RST_BUS, BIT(21) }, |
| 250 | + |
| 251 | + /* resets for fch_sw_xspi */ |
| 252 | + [SW_XSPI_REG_RST_N] = { FCH_SW_XSPI, BIT(0) }, |
| 253 | + [SW_XSPI_SYS_RST_N] = { FCH_SW_XSPI, BIT(1) }, |
| 254 | +}; |
| 255 | + |
| 256 | +static const struct sky1_src_variant variant_sky1_fch = { |
| 257 | + .signals = sky1_src_fch_signals, |
| 258 | + .signals_num = ARRAY_SIZE(sky1_src_fch_signals), |
| 259 | +}; |
| 260 | + |
| 261 | +static struct sky1_src *to_sky1_src(struct reset_controller_dev *rcdev) |
| 262 | +{ |
| 263 | + return container_of(rcdev, struct sky1_src, rcdev); |
| 264 | +} |
| 265 | + |
| 266 | +static int sky1_reset_set(struct reset_controller_dev *rcdev, |
| 267 | + unsigned long id, bool assert) |
| 268 | +{ |
| 269 | + struct sky1_src *sky1src = to_sky1_src(rcdev); |
| 270 | + const struct sky1_src_signal *signal = &sky1src->signals[id]; |
| 271 | + unsigned int value = assert ? 0 : signal->bit; |
| 272 | + |
| 273 | + return regmap_update_bits(sky1src->regmap, |
| 274 | + signal->offset, signal->bit, value); |
| 275 | +} |
| 276 | + |
| 277 | +static int sky1_reset_assert(struct reset_controller_dev *rcdev, |
| 278 | + unsigned long id) |
| 279 | +{ |
| 280 | + sky1_reset_set(rcdev, id, true); |
| 281 | + usleep_range(SKY1_RESET_SLEEP_MIN_US, |
| 282 | + SKY1_RESET_SLEEP_MAX_US); |
| 283 | + return 0; |
| 284 | +} |
| 285 | + |
| 286 | +static int sky1_reset_deassert(struct reset_controller_dev *rcdev, |
| 287 | + unsigned long id) |
| 288 | +{ |
| 289 | + sky1_reset_set(rcdev, id, false); |
| 290 | + usleep_range(SKY1_RESET_SLEEP_MIN_US, |
| 291 | + SKY1_RESET_SLEEP_MAX_US); |
| 292 | + return 0; |
| 293 | +} |
| 294 | + |
| 295 | +static int sky1_reset(struct reset_controller_dev *rcdev, |
| 296 | + unsigned long id) |
| 297 | +{ |
| 298 | + sky1_reset_assert(rcdev, id); |
| 299 | + sky1_reset_deassert(rcdev, id); |
| 300 | + return 0; |
| 301 | +} |
| 302 | + |
| 303 | +static int sky1_reset_status(struct reset_controller_dev *rcdev, |
| 304 | + unsigned long id) |
| 305 | +{ |
| 306 | + unsigned int value = 0; |
| 307 | + struct sky1_src *sky1src = to_sky1_src(rcdev); |
| 308 | + const struct sky1_src_signal *signal = &sky1src->signals[id]; |
| 309 | + |
| 310 | + regmap_read(sky1src->regmap, signal->offset, &value); |
| 311 | + return !(value & signal->bit); |
| 312 | +} |
| 313 | + |
| 314 | +static const struct reset_control_ops sky1_src_ops = { |
| 315 | + .reset = sky1_reset, |
| 316 | + .assert = sky1_reset_assert, |
| 317 | + .deassert = sky1_reset_deassert, |
| 318 | + .status = sky1_reset_status |
| 319 | +}; |
| 320 | + |
| 321 | +static int sky1_reset_probe(struct platform_device *pdev) |
| 322 | +{ |
| 323 | + struct sky1_src *sky1src; |
| 324 | + struct device *dev = &pdev->dev; |
| 325 | + const struct sky1_src_variant *variant; |
| 326 | + |
| 327 | + sky1src = devm_kzalloc(dev, sizeof(*sky1src), GFP_KERNEL); |
| 328 | + if (!sky1src) |
| 329 | + return -ENOMEM; |
| 330 | + |
| 331 | + variant = of_device_get_match_data(dev); |
| 332 | + |
| 333 | + sky1src->regmap = device_node_to_regmap(dev->of_node); |
| 334 | + if (IS_ERR(sky1src->regmap)) { |
| 335 | + return dev_err_probe(dev, PTR_ERR(sky1src->regmap), |
| 336 | + "Unable to get sky1-src regmap"); |
| 337 | + } |
| 338 | + |
| 339 | + sky1src->signals = variant->signals; |
| 340 | + sky1src->rcdev.owner = THIS_MODULE; |
| 341 | + sky1src->rcdev.nr_resets = variant->signals_num; |
| 342 | + sky1src->rcdev.ops = &sky1_src_ops; |
| 343 | + sky1src->rcdev.of_node = dev->of_node; |
| 344 | + sky1src->rcdev.dev = dev; |
| 345 | + |
| 346 | + return devm_reset_controller_register(dev, &sky1src->rcdev); |
| 347 | +} |
| 348 | + |
| 349 | +static const struct of_device_id sky1_sysreg_of_match[] = { |
| 350 | + { .compatible = "cix,sky1-system-control", .data = &variant_sky1_fch}, |
| 351 | + { .compatible = "cix,sky1-s5-system-control", .data = &variant_sky1}, |
| 352 | + {}, |
| 353 | +}; |
| 354 | +MODULE_DEVICE_TABLE(of, sky1_sysreg_of_match); |
| 355 | + |
| 356 | +static struct platform_driver sky1_reset_driver = { |
| 357 | + .probe = sky1_reset_probe, |
| 358 | + .driver = { |
| 359 | + .name = "cix,sky1-rst", |
| 360 | + .of_match_table = sky1_sysreg_of_match, |
| 361 | + }, |
| 362 | +}; |
| 363 | +module_platform_driver(sky1_reset_driver) |
| 364 | + |
| 365 | +MODULE_AUTHOR("Jerry Zhu <jerry.zhu@cixtech.com>"); |
| 366 | +MODULE_DESCRIPTION("Cix Sky1 reset driver"); |
| 367 | +MODULE_LICENSE("GPL"); |
0 commit comments