1 // SPDX-License-Identifier: GPL-2.0-or-later
3 * Copyright (C) 2021 Aspeed Technology Inc.
5 * PWM/TACH controller driver for Aspeed ast2600 SoCs.
6 * This drivers doesn't support earlier version of the IP.
8 * The hardware operates in time quantities of length
9 * Q := (DIV_L + 1) << DIV_H / input-clk
10 * The length of a PWM period is (DUTY_CYCLE_PERIOD + 1) * Q.
11 * The maximal value for DUTY_CYCLE_PERIOD is used here to provide
12 * a fine grained selection for the duty cycle.
14 * This driver uses DUTY_CYCLE_RISING_POINT = 0, so from the start of a
15 * period the output is active until DUTY_CYCLE_FALLING_POINT * Q. Note
16 * that if DUTY_CYCLE_RISING_POINT = DUTY_CYCLE_FALLING_POINT the output is
20 * PIN_ENABLE: When it is unset the pwm controller will emit inactive level to the external.
21 * Use to determine whether the PWM channel is enabled or disabled
22 * CLK_ENABLE: When it is unset the pwm controller will assert the duty counter reset and
23 * emit inactive level to the PIN_ENABLE mux after that the driver can still change the pwm period
24 * and duty and the value will apply when CLK_ENABLE be set again.
25 * Use to determine whether duty_cycle bigger than 0.
26 * PWM_ASPEED_CTRL_INVERSE: When it is toggled the output value will inverse immediately.
27 * PWM_ASPEED_DUTY_CYCLE_FALLING_POINT/PWM_ASPEED_DUTY_CYCLE_RISING_POINT: When these two
28 * values are equal it means the duty cycle = 100%.
30 * The glitch may generate at:
31 * - Enabled changing when the duty_cycle bigger than 0% and less than 100%.
32 * - Polarity changing when the duty_cycle bigger than 0% and less than 100%.
35 * - When changing both duty cycle and period, we cannot prevent in
36 * software that the output might produce a period with mixed
38 * - Disabling the PWM doesn't complete the current period.
41 * - When only changing one of duty cycle or period, our pwm controller will not
42 * generate the glitch, the configure will change at next cycle of pwm.
43 * This improvement can disable/enable through PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE.
46 #include <linux/bitfield.h>
47 #include <linux/clk.h>
48 #include <linux/delay.h>
49 #include <linux/errno.h>
50 #include <linux/hwmon.h>
52 #include <linux/kernel.h>
53 #include <linux/math64.h>
54 #include <linux/module.h>
55 #include <linux/of_device.h>
56 #include <linux/of_platform.h>
57 #include <linux/platform_device.h>
58 #include <linux/pwm.h>
59 #include <linux/reset.h>
60 #include <linux/sysfs.h>
62 /* The channel number of Aspeed pwm controller */
63 #define PWM_ASPEED_NR_PWMS 16
64 /* PWM Control Register */
65 #define PWM_ASPEED_CTRL(ch) ((ch) * 0x10 + 0x00)
66 #define PWM_ASPEED_CTRL_LOAD_SEL_RISING_AS_WDT BIT(19)
67 #define PWM_ASPEED_CTRL_DUTY_LOAD_AS_WDT_ENABLE BIT(18)
68 #define PWM_ASPEED_CTRL_DUTY_SYNC_DISABLE BIT(17)
69 #define PWM_ASPEED_CTRL_CLK_ENABLE BIT(16)
70 #define PWM_ASPEED_CTRL_LEVEL_OUTPUT BIT(15)
71 #define PWM_ASPEED_CTRL_INVERSE BIT(14)
72 #define PWM_ASPEED_CTRL_OPEN_DRAIN_ENABLE BIT(13)
73 #define PWM_ASPEED_CTRL_PIN_ENABLE BIT(12)
74 #define PWM_ASPEED_CTRL_CLK_DIV_H GENMASK(11, 8)
75 #define PWM_ASPEED_CTRL_CLK_DIV_L GENMASK(7, 0)
77 /* PWM Duty Cycle Register */
78 #define PWM_ASPEED_DUTY_CYCLE(ch) ((ch) * 0x10 + 0x04)
79 #define PWM_ASPEED_DUTY_CYCLE_PERIOD GENMASK(31, 24)
80 #define PWM_ASPEED_DUTY_CYCLE_POINT_AS_WDT GENMASK(23, 16)
81 #define PWM_ASPEED_DUTY_CYCLE_FALLING_POINT GENMASK(15, 8)
82 #define PWM_ASPEED_DUTY_CYCLE_RISING_POINT GENMASK(7, 0)
85 #define PWM_ASPEED_FIXED_PERIOD FIELD_MAX(PWM_ASPEED_DUTY_CYCLE_PERIOD)
87 /* The channel number of Aspeed tach controller */
88 #define TACH_ASPEED_NR_TACHS 16
89 /* TACH Control Register */
90 #define TACH_ASPEED_CTRL(ch) (((ch) * 0x10) + 0x08)
91 #define TACH_ASPEED_IER BIT(31)
92 #define TACH_ASPEED_INVERS_LIMIT BIT(30)
93 #define TACH_ASPEED_LOOPBACK BIT(29)
94 #define TACH_ASPEED_ENABLE BIT(28)
95 #define TACH_ASPEED_DEBOUNCE_MASK GENMASK(27, 26)
96 #define TACH_ASPEED_DEBOUNCE_BIT 26
97 #define TACH_ASPEED_IO_EDGE_MASK GENMASK(25, 24)
98 #define TACH_ASPEED_IO_EDGE_BIT 24
99 #define TACH_ASPEED_CLK_DIV_T_MASK GENMASK(23, 20)
100 #define TACH_ASPEED_CLK_DIV_BIT 20
101 #define TACH_ASPEED_THRESHOLD_MASK GENMASK(19, 0)
103 #define DEBOUNCE_3_CLK 0x00
104 #define DEBOUNCE_2_CLK 0x01
105 #define DEBOUNCE_1_CLK 0x02
106 #define DEBOUNCE_0_CLK 0x03
108 #define F2F_EDGES 0x00
109 #define R2R_EDGES 0x01
110 #define BOTH_EDGES 0x02
112 /* divisor = 4 to the nth power, n = register value */
113 #define DEFAULT_TACH_DIV 1024
114 #define DIV_TO_REG(divisor) (ilog2(divisor) >> 1)
116 /* TACH Status Register */
117 #define TACH_ASPEED_STS(ch) (((ch) * 0x10) + 0x0C)
120 #define TACH_ASPEED_ISR BIT(31)
121 #define TACH_ASPEED_PWM_OUT BIT(25)
122 #define TACH_ASPEED_PWM_OEN BIT(24)
123 #define TACH_ASPEED_DEB_INPUT BIT(23)
124 #define TACH_ASPEED_RAW_INPUT BIT(22)
125 #define TACH_ASPEED_VALUE_UPDATE BIT(21)
126 #define TACH_ASPEED_FULL_MEASUREMENT BIT(20)
127 #define TACH_ASPEED_VALUE_MASK GENMASK(19, 0)
128 /**********************************************************
130 *********************************************************/
131 #define DEFAULT_FAN_PULSE_PR 2
133 struct aspeed_pwm_tach_data
{
137 struct reset_control
*reset
;
138 unsigned long clk_rate
;
139 bool tach_present
[TACH_ASPEED_NR_TACHS
];
143 static inline struct aspeed_pwm_tach_data
*
144 aspeed_pwm_chip_to_data(struct pwm_chip
*chip
)
146 return pwmchip_get_drvdata(chip
);
149 static int aspeed_pwm_get_state(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
150 struct pwm_state
*state
)
152 struct aspeed_pwm_tach_data
*priv
= aspeed_pwm_chip_to_data(chip
);
153 u32 hwpwm
= pwm
->hwpwm
;
154 bool polarity
, pin_en
, clk_en
;
156 u64 div_h
, div_l
, duty_cycle_period
, dividend
;
158 val
= readl(priv
->base
+ PWM_ASPEED_CTRL(hwpwm
));
159 polarity
= FIELD_GET(PWM_ASPEED_CTRL_INVERSE
, val
);
160 pin_en
= FIELD_GET(PWM_ASPEED_CTRL_PIN_ENABLE
, val
);
161 clk_en
= FIELD_GET(PWM_ASPEED_CTRL_CLK_ENABLE
, val
);
162 div_h
= FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_H
, val
);
163 div_l
= FIELD_GET(PWM_ASPEED_CTRL_CLK_DIV_L
, val
);
164 val
= readl(priv
->base
+ PWM_ASPEED_DUTY_CYCLE(hwpwm
));
165 duty_pt
= FIELD_GET(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT
, val
);
166 duty_cycle_period
= FIELD_GET(PWM_ASPEED_DUTY_CYCLE_PERIOD
, val
);
168 * This multiplication doesn't overflow, the upper bound is
169 * 1000000000 * 256 * 256 << 15 = 0x1dcd650000000000
171 dividend
= (u64
)NSEC_PER_SEC
* (div_l
+ 1) * (duty_cycle_period
+ 1)
173 state
->period
= DIV_ROUND_UP_ULL(dividend
, priv
->clk_rate
);
175 if (clk_en
&& duty_pt
) {
176 dividend
= (u64
)NSEC_PER_SEC
* (div_l
+ 1) * duty_pt
178 state
->duty_cycle
= DIV_ROUND_UP_ULL(dividend
, priv
->clk_rate
);
180 state
->duty_cycle
= clk_en
? state
->period
: 0;
182 state
->polarity
= polarity
? PWM_POLARITY_INVERSED
: PWM_POLARITY_NORMAL
;
183 state
->enabled
= pin_en
;
187 static int aspeed_pwm_apply(struct pwm_chip
*chip
, struct pwm_device
*pwm
,
188 const struct pwm_state
*state
)
190 struct aspeed_pwm_tach_data
*priv
= aspeed_pwm_chip_to_data(chip
);
191 u32 hwpwm
= pwm
->hwpwm
, duty_pt
, val
;
192 u64 div_h
, div_l
, divisor
, expect_period
;
195 expect_period
= div64_u64(ULLONG_MAX
, (u64
)priv
->clk_rate
);
196 expect_period
= min(expect_period
, state
->period
);
197 dev_dbg(pwmchip_parent(chip
), "expect period: %lldns, duty_cycle: %lldns",
198 expect_period
, state
->duty_cycle
);
200 * Pick the smallest value for div_h so that div_l can be the biggest
201 * which results in a finer resolution near the target period value.
203 divisor
= (u64
)NSEC_PER_SEC
* (PWM_ASPEED_FIXED_PERIOD
+ 1) *
204 (FIELD_MAX(PWM_ASPEED_CTRL_CLK_DIV_L
) + 1);
205 div_h
= order_base_2(DIV64_U64_ROUND_UP(priv
->clk_rate
* expect_period
, divisor
));
209 divisor
= ((u64
)NSEC_PER_SEC
* (PWM_ASPEED_FIXED_PERIOD
+ 1)) << div_h
;
210 div_l
= div64_u64(priv
->clk_rate
* expect_period
, divisor
);
220 dev_dbg(pwmchip_parent(chip
), "clk source: %ld div_h %lld, div_l : %lld\n",
221 priv
->clk_rate
, div_h
, div_l
);
222 /* duty_pt = duty_cycle * (PERIOD + 1) / period */
223 duty_pt
= div64_u64(state
->duty_cycle
* priv
->clk_rate
,
224 (u64
)NSEC_PER_SEC
* (div_l
+ 1) << div_h
);
225 dev_dbg(pwmchip_parent(chip
), "duty_cycle = %lld, duty_pt = %d\n",
226 state
->duty_cycle
, duty_pt
);
229 * Fixed DUTY_CYCLE_PERIOD to its max value to get a
230 * fine-grained resolution for duty_cycle at the expense of a
231 * coarser period resolution.
233 val
= readl(priv
->base
+ PWM_ASPEED_DUTY_CYCLE(hwpwm
));
234 val
&= ~PWM_ASPEED_DUTY_CYCLE_PERIOD
;
235 val
|= FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_PERIOD
,
236 PWM_ASPEED_FIXED_PERIOD
);
237 writel(val
, priv
->base
+ PWM_ASPEED_DUTY_CYCLE(hwpwm
));
240 /* emit inactive level and assert the duty counter reset */
244 if (duty_pt
>= (PWM_ASPEED_FIXED_PERIOD
+ 1))
246 val
= readl(priv
->base
+ PWM_ASPEED_DUTY_CYCLE(hwpwm
));
247 val
&= ~(PWM_ASPEED_DUTY_CYCLE_RISING_POINT
|
248 PWM_ASPEED_DUTY_CYCLE_FALLING_POINT
);
249 val
|= FIELD_PREP(PWM_ASPEED_DUTY_CYCLE_FALLING_POINT
, duty_pt
);
250 writel(val
, priv
->base
+ PWM_ASPEED_DUTY_CYCLE(hwpwm
));
253 val
= readl(priv
->base
+ PWM_ASPEED_CTRL(hwpwm
));
254 val
&= ~(PWM_ASPEED_CTRL_CLK_DIV_H
| PWM_ASPEED_CTRL_CLK_DIV_L
|
255 PWM_ASPEED_CTRL_PIN_ENABLE
| PWM_ASPEED_CTRL_CLK_ENABLE
|
256 PWM_ASPEED_CTRL_INVERSE
);
257 val
|= FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_H
, div_h
) |
258 FIELD_PREP(PWM_ASPEED_CTRL_CLK_DIV_L
, div_l
) |
259 FIELD_PREP(PWM_ASPEED_CTRL_PIN_ENABLE
, state
->enabled
) |
260 FIELD_PREP(PWM_ASPEED_CTRL_CLK_ENABLE
, clk_en
) |
261 FIELD_PREP(PWM_ASPEED_CTRL_INVERSE
, state
->polarity
);
262 writel(val
, priv
->base
+ PWM_ASPEED_CTRL(hwpwm
));
267 static const struct pwm_ops aspeed_pwm_ops
= {
268 .apply
= aspeed_pwm_apply
,
269 .get_state
= aspeed_pwm_get_state
,
272 static void aspeed_tach_ch_enable(struct aspeed_pwm_tach_data
*priv
, u8 tach_ch
,
276 writel(readl(priv
->base
+ TACH_ASPEED_CTRL(tach_ch
)) |
278 priv
->base
+ TACH_ASPEED_CTRL(tach_ch
));
280 writel(readl(priv
->base
+ TACH_ASPEED_CTRL(tach_ch
)) &
282 priv
->base
+ TACH_ASPEED_CTRL(tach_ch
));
285 static int aspeed_tach_val_to_rpm(struct aspeed_pwm_tach_data
*priv
, u32 tach_val
)
290 tach_div
= tach_val
* priv
->tach_divisor
* DEFAULT_FAN_PULSE_PR
;
292 dev_dbg(priv
->dev
, "clk %ld, tach_val %d , tach_div %d\n",
293 priv
->clk_rate
, tach_val
, tach_div
);
295 rpm
= (u64
)priv
->clk_rate
* 60;
296 do_div(rpm
, tach_div
);
301 static int aspeed_get_fan_tach_ch_rpm(struct aspeed_pwm_tach_data
*priv
,
306 val
= readl(priv
->base
+ TACH_ASPEED_STS(fan_tach_ch
));
308 if (!(val
& TACH_ASPEED_FULL_MEASUREMENT
))
310 val
= FIELD_GET(TACH_ASPEED_VALUE_MASK
, val
);
311 return aspeed_tach_val_to_rpm(priv
, val
);
314 static int aspeed_tach_hwmon_read(struct device
*dev
,
315 enum hwmon_sensor_types type
, u32 attr
,
316 int channel
, long *val
)
318 struct aspeed_pwm_tach_data
*priv
= dev_get_drvdata(dev
);
322 case hwmon_fan_input
:
323 *val
= aspeed_get_fan_tach_ch_rpm(priv
, channel
);
326 reg_val
= readl(priv
->base
+ TACH_ASPEED_CTRL(channel
));
327 reg_val
= FIELD_GET(TACH_ASPEED_CLK_DIV_T_MASK
, reg_val
);
328 *val
= BIT(reg_val
<< 1);
336 static int aspeed_tach_hwmon_write(struct device
*dev
,
337 enum hwmon_sensor_types type
, u32 attr
,
338 int channel
, long val
)
340 struct aspeed_pwm_tach_data
*priv
= dev_get_drvdata(dev
);
345 if (!is_power_of_2(val
) || (ilog2(val
) % 2) ||
346 DIV_TO_REG(val
) > 0xb)
348 priv
->tach_divisor
= val
;
349 reg_val
= readl(priv
->base
+ TACH_ASPEED_CTRL(channel
));
350 reg_val
&= ~TACH_ASPEED_CLK_DIV_T_MASK
;
351 reg_val
|= FIELD_PREP(TACH_ASPEED_CLK_DIV_T_MASK
,
352 DIV_TO_REG(priv
->tach_divisor
));
353 writel(reg_val
, priv
->base
+ TACH_ASPEED_CTRL(channel
));
362 static umode_t
aspeed_tach_dev_is_visible(const void *drvdata
,
363 enum hwmon_sensor_types type
,
364 u32 attr
, int channel
)
366 const struct aspeed_pwm_tach_data
*priv
= drvdata
;
368 if (!priv
->tach_present
[channel
])
371 case hwmon_fan_input
:
379 static const struct hwmon_ops aspeed_tach_ops
= {
380 .is_visible
= aspeed_tach_dev_is_visible
,
381 .read
= aspeed_tach_hwmon_read
,
382 .write
= aspeed_tach_hwmon_write
,
385 static const struct hwmon_channel_info
*aspeed_tach_info
[] = {
386 HWMON_CHANNEL_INFO(fan
, HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
,
387 HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
,
388 HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
,
389 HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
,
390 HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
,
391 HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
,
392 HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
,
393 HWMON_F_INPUT
| HWMON_F_DIV
, HWMON_F_INPUT
| HWMON_F_DIV
),
397 static const struct hwmon_chip_info aspeed_tach_chip_info
= {
398 .ops
= &aspeed_tach_ops
,
399 .info
= aspeed_tach_info
,
402 static void aspeed_present_fan_tach(struct aspeed_pwm_tach_data
*priv
, u8
*tach_ch
, int count
)
407 for (index
= 0; index
< count
; index
++) {
409 priv
->tach_present
[ch
] = true;
410 priv
->tach_divisor
= DEFAULT_TACH_DIV
;
412 val
= readl(priv
->base
+ TACH_ASPEED_CTRL(ch
));
413 val
&= ~(TACH_ASPEED_INVERS_LIMIT
| TACH_ASPEED_DEBOUNCE_MASK
|
414 TACH_ASPEED_IO_EDGE_MASK
| TACH_ASPEED_CLK_DIV_T_MASK
|
415 TACH_ASPEED_THRESHOLD_MASK
);
416 val
|= (DEBOUNCE_3_CLK
<< TACH_ASPEED_DEBOUNCE_BIT
) |
418 FIELD_PREP(TACH_ASPEED_CLK_DIV_T_MASK
,
419 DIV_TO_REG(priv
->tach_divisor
));
420 writel(val
, priv
->base
+ TACH_ASPEED_CTRL(ch
));
422 aspeed_tach_ch_enable(priv
, ch
, true);
426 static int aspeed_create_fan_monitor(struct device
*dev
,
427 struct device_node
*child
,
428 struct aspeed_pwm_tach_data
*priv
)
433 count
= of_property_count_u8_elems(child
, "tach-ch");
436 tach_ch
= devm_kcalloc(dev
, count
, sizeof(*tach_ch
), GFP_KERNEL
);
439 ret
= of_property_read_u8_array(child
, "tach-ch", tach_ch
, count
);
443 aspeed_present_fan_tach(priv
, tach_ch
, count
);
448 static void aspeed_pwm_tach_reset_assert(void *data
)
450 struct reset_control
*rst
= data
;
452 reset_control_assert(rst
);
455 static int aspeed_pwm_tach_probe(struct platform_device
*pdev
)
457 struct device
*dev
= &pdev
->dev
, *hwmon
;
459 struct aspeed_pwm_tach_data
*priv
;
460 struct pwm_chip
*chip
;
462 priv
= devm_kzalloc(dev
, sizeof(*priv
), GFP_KERNEL
);
466 priv
->base
= devm_platform_ioremap_resource(pdev
, 0);
467 if (IS_ERR(priv
->base
))
468 return PTR_ERR(priv
->base
);
470 priv
->clk
= devm_clk_get_enabled(dev
, NULL
);
471 if (IS_ERR(priv
->clk
))
472 return dev_err_probe(dev
, PTR_ERR(priv
->clk
),
473 "Couldn't get clock\n");
474 priv
->clk_rate
= clk_get_rate(priv
->clk
);
475 priv
->reset
= devm_reset_control_get_exclusive(dev
, NULL
);
476 if (IS_ERR(priv
->reset
))
477 return dev_err_probe(dev
, PTR_ERR(priv
->reset
),
478 "Couldn't get reset control\n");
480 ret
= reset_control_deassert(priv
->reset
);
482 return dev_err_probe(dev
, ret
,
483 "Couldn't deassert reset control\n");
484 ret
= devm_add_action_or_reset(dev
, aspeed_pwm_tach_reset_assert
,
489 chip
= devm_pwmchip_alloc(dev
, PWM_ASPEED_NR_PWMS
, 0);
491 return PTR_ERR(chip
);
493 pwmchip_set_drvdata(chip
, priv
);
494 chip
->ops
= &aspeed_pwm_ops
;
496 ret
= devm_pwmchip_add(dev
, chip
);
498 return dev_err_probe(dev
, ret
, "Failed to add PWM chip\n");
500 for_each_child_of_node_scoped(dev
->of_node
, child
) {
501 ret
= aspeed_create_fan_monitor(dev
, child
, priv
);
503 dev_warn(dev
, "Failed to create fan %d", ret
);
508 hwmon
= devm_hwmon_device_register_with_info(dev
, "aspeed_tach", priv
,
509 &aspeed_tach_chip_info
, NULL
);
510 ret
= PTR_ERR_OR_ZERO(hwmon
);
512 return dev_err_probe(dev
, ret
,
513 "Failed to register hwmon device\n");
515 of_platform_populate(dev
->of_node
, NULL
, NULL
, dev
);
520 static void aspeed_pwm_tach_remove(struct platform_device
*pdev
)
522 struct aspeed_pwm_tach_data
*priv
= platform_get_drvdata(pdev
);
524 reset_control_assert(priv
->reset
);
527 static const struct of_device_id aspeed_pwm_tach_match
[] = {
529 .compatible
= "aspeed,ast2600-pwm-tach",
533 MODULE_DEVICE_TABLE(of
, aspeed_pwm_tach_match
);
535 static struct platform_driver aspeed_pwm_tach_driver
= {
536 .probe
= aspeed_pwm_tach_probe
,
537 .remove
= aspeed_pwm_tach_remove
,
539 .name
= "aspeed-g6-pwm-tach",
540 .of_match_table
= aspeed_pwm_tach_match
,
544 module_platform_driver(aspeed_pwm_tach_driver
);
546 MODULE_AUTHOR("Billy Tsai <billy_tsai@aspeedtech.com>");
547 MODULE_DESCRIPTION("Aspeed ast2600 PWM and Fan Tach device driver");
548 MODULE_LICENSE("GPL");