33
33
enum hi6220_reset_ctrl_type {
34
34
PERIPHERAL ,
35
35
MEDIA ,
36
+ AO ,
36
37
};
37
38
38
39
struct hi6220_reset_data {
@@ -92,6 +93,65 @@ static const struct reset_control_ops hi6220_media_reset_ops = {
92
93
.deassert = hi6220_media_deassert ,
93
94
};
94
95
96
+ #define AO_SCTRL_SC_PW_CLKEN0 0x800
97
+ #define AO_SCTRL_SC_PW_CLKDIS0 0x804
98
+
99
+ #define AO_SCTRL_SC_PW_RSTEN0 0x810
100
+ #define AO_SCTRL_SC_PW_RSTDIS0 0x814
101
+
102
+ #define AO_SCTRL_SC_PW_ISOEN0 0x820
103
+ #define AO_SCTRL_SC_PW_ISODIS0 0x824
104
+ #define AO_MAX_INDEX 12
105
+
106
+ static int hi6220_ao_assert (struct reset_controller_dev * rc_dev ,
107
+ unsigned long idx )
108
+ {
109
+ struct hi6220_reset_data * data = to_reset_data (rc_dev );
110
+ struct regmap * regmap = data -> regmap ;
111
+ int ret ;
112
+
113
+ ret = regmap_write (regmap , AO_SCTRL_SC_PW_RSTEN0 , BIT (idx ));
114
+ if (ret )
115
+ return ret ;
116
+
117
+ ret = regmap_write (regmap , AO_SCTRL_SC_PW_ISOEN0 , BIT (idx ));
118
+ if (ret )
119
+ return ret ;
120
+
121
+ ret = regmap_write (regmap , AO_SCTRL_SC_PW_CLKDIS0 , BIT (idx ));
122
+ return ret ;
123
+ }
124
+
125
+ static int hi6220_ao_deassert (struct reset_controller_dev * rc_dev ,
126
+ unsigned long idx )
127
+ {
128
+ struct hi6220_reset_data * data = to_reset_data (rc_dev );
129
+ struct regmap * regmap = data -> regmap ;
130
+ int ret ;
131
+
132
+ /*
133
+ * It was suggested to disable isolation before enabling
134
+ * the clocks and deasserting reset, to avoid glitches.
135
+ * But this order is preserved to keep it matching the
136
+ * vendor code.
137
+ */
138
+ ret = regmap_write (regmap , AO_SCTRL_SC_PW_RSTDIS0 , BIT (idx ));
139
+ if (ret )
140
+ return ret ;
141
+
142
+ ret = regmap_write (regmap , AO_SCTRL_SC_PW_ISODIS0 , BIT (idx ));
143
+ if (ret )
144
+ return ret ;
145
+
146
+ ret = regmap_write (regmap , AO_SCTRL_SC_PW_CLKEN0 , BIT (idx ));
147
+ return ret ;
148
+ }
149
+
150
+ static const struct reset_control_ops hi6220_ao_reset_ops = {
151
+ .assert = hi6220_ao_assert ,
152
+ .deassert = hi6220_ao_deassert ,
153
+ };
154
+
95
155
static int hi6220_reset_probe (struct platform_device * pdev )
96
156
{
97
157
struct device_node * np = pdev -> dev .of_node ;
@@ -117,9 +177,12 @@ static int hi6220_reset_probe(struct platform_device *pdev)
117
177
if (type == MEDIA ) {
118
178
data -> rc_dev .ops = & hi6220_media_reset_ops ;
119
179
data -> rc_dev .nr_resets = MEDIA_MAX_INDEX ;
120
- } else {
180
+ } else if ( type == PERIPHERAL ) {
121
181
data -> rc_dev .ops = & hi6220_peripheral_reset_ops ;
122
182
data -> rc_dev .nr_resets = PERIPH_MAX_INDEX ;
183
+ } else {
184
+ data -> rc_dev .ops = & hi6220_ao_reset_ops ;
185
+ data -> rc_dev .nr_resets = AO_MAX_INDEX ;
123
186
}
124
187
125
188
return reset_controller_register (& data -> rc_dev );
@@ -134,6 +197,10 @@ static const struct of_device_id hi6220_reset_match[] = {
134
197
.compatible = "hisilicon,hi6220-mediactrl" ,
135
198
.data = (void * )MEDIA ,
136
199
},
200
+ {
201
+ .compatible = "hisilicon,hi6220-aoctrl" ,
202
+ .data = (void * )AO ,
203
+ },
137
204
{ /* sentinel */ },
138
205
};
139
206
MODULE_DEVICE_TABLE (of , hi6220_reset_match );
0 commit comments