@@ -22,6 +22,7 @@ enum scmi_clk_feats {
22
22
SCMI_CLK_STATE_CTRL_SUPPORTED ,
23
23
SCMI_CLK_RATE_CTRL_SUPPORTED ,
24
24
SCMI_CLK_PARENT_CTRL_SUPPORTED ,
25
+ SCMI_CLK_DUTY_CYCLE_SUPPORTED ,
25
26
SCMI_CLK_FEATS_COUNT
26
27
};
27
28
@@ -169,6 +170,45 @@ static int scmi_clk_atomic_is_enabled(struct clk_hw *hw)
169
170
return !!enabled ;
170
171
}
171
172
173
+ static int scmi_clk_get_duty_cycle (struct clk_hw * hw , struct clk_duty * duty )
174
+ {
175
+ int ret ;
176
+ u32 val ;
177
+ struct scmi_clk * clk = to_scmi_clk (hw );
178
+
179
+ ret = scmi_proto_clk_ops -> config_oem_get (clk -> ph , clk -> id ,
180
+ SCMI_CLOCK_CFG_DUTY_CYCLE ,
181
+ & val , NULL , false);
182
+ if (!ret ) {
183
+ duty -> num = val ;
184
+ duty -> den = 100 ;
185
+ } else {
186
+ dev_warn (clk -> dev ,
187
+ "Failed to get duty cycle for clock ID %d\n" , clk -> id );
188
+ }
189
+
190
+ return ret ;
191
+ }
192
+
193
+ static int scmi_clk_set_duty_cycle (struct clk_hw * hw , struct clk_duty * duty )
194
+ {
195
+ int ret ;
196
+ u32 val ;
197
+ struct scmi_clk * clk = to_scmi_clk (hw );
198
+
199
+ /* SCMI OEM Duty Cycle is expressed as a percentage */
200
+ val = (duty -> num * 100 ) / duty -> den ;
201
+ ret = scmi_proto_clk_ops -> config_oem_set (clk -> ph , clk -> id ,
202
+ SCMI_CLOCK_CFG_DUTY_CYCLE ,
203
+ val , false);
204
+ if (ret )
205
+ dev_warn (clk -> dev ,
206
+ "Failed to set duty cycle(%u/%u) for clock ID %d\n" ,
207
+ duty -> num , duty -> den , clk -> id );
208
+
209
+ return ret ;
210
+ }
211
+
172
212
static int scmi_clk_ops_init (struct device * dev , struct scmi_clk * sclk ,
173
213
const struct clk_ops * scmi_ops )
174
214
{
@@ -258,6 +298,12 @@ scmi_clk_ops_alloc(struct device *dev, unsigned long feats_key)
258
298
if (feats_key & BIT (SCMI_CLK_PARENT_CTRL_SUPPORTED ))
259
299
ops -> set_parent = scmi_clk_set_parent ;
260
300
301
+ /* Duty cycle */
302
+ if (feats_key & BIT (SCMI_CLK_DUTY_CYCLE_SUPPORTED )) {
303
+ ops -> get_duty_cycle = scmi_clk_get_duty_cycle ;
304
+ ops -> set_duty_cycle = scmi_clk_set_duty_cycle ;
305
+ }
306
+
261
307
return ops ;
262
308
}
263
309
@@ -312,6 +358,9 @@ scmi_clk_ops_select(struct scmi_clk *sclk, bool atomic_capable,
312
358
if (!ci -> parent_ctrl_forbidden )
313
359
feats_key |= BIT (SCMI_CLK_PARENT_CTRL_SUPPORTED );
314
360
361
+ if (ci -> extended_config )
362
+ feats_key |= BIT (SCMI_CLK_DUTY_CYCLE_SUPPORTED );
363
+
315
364
if (WARN_ON (feats_key >= db_size ))
316
365
return NULL ;
317
366
0 commit comments