* [PATCH v3] pwm:lpss: update pwm setting for Broxton
@ 2015-11-16 11:07 Qipeng Zha
0 siblings, 0 replies; 2+ messages in thread
From: Qipeng Zha @ 2015-11-16 11:07 UTC (permalink / raw)
To: linux-pwm; +Cc: thierry.reding, mika.westerberg, qipeng.zha
For Broxton PWM controller, base unit is defined as 8bit integer
and 14bit fraction, so need to update base unit setting to output
wave with right frequency.
Signed-off-by: Qipeng Zha <qipeng.zha@intel.com>
---
change in v3
use BIT macro to calculate base_unit_range;
mask base_unit with "base_unit_range - 1".
---
drivers/pwm/pwm-lpss.c | 30 ++++++++++++++++--------------
drivers/pwm/pwm-lpss.h | 1 +
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index 2504410..4530c48 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -14,6 +14,7 @@
*/
#include <linux/io.h>
+#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
@@ -24,11 +25,8 @@
#define PWM_ENABLE BIT(31)
#define PWM_SW_UPDATE BIT(30)
#define PWM_BASE_UNIT_SHIFT 8
-#define PWM_BASE_UNIT_MASK 0x00ffff00
#define PWM_ON_TIME_DIV_MASK 0x000000ff
#define PWM_DIVISION_CORRECTION 0x2
-#define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION)
-#define NSECS_PER_SEC 1000000000UL
/* Size of each PWM register space if multiple */
#define PWM_SIZE 0x400
@@ -36,13 +34,14 @@
struct pwm_lpss_chip {
struct pwm_chip chip;
void __iomem *regs;
- unsigned long clk_rate;
+ const struct pwm_lpss_boardinfo *info;
};
/* BayTrail */
const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
.clk_rate = 25000000,
.npwm = 1,
+ .base_unit_bits = 16,
};
EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
@@ -50,6 +49,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
.clk_rate = 19200000,
.npwm = 1,
+ .base_unit_bits = 16,
};
EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
@@ -57,6 +57,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.clk_rate = 19200000,
.npwm = 4,
+ .base_unit_bits = 22,
};
EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info);
@@ -84,23 +85,22 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
{
struct pwm_lpss_chip *lpwm = to_lpwm(chip);
u8 on_time_div;
- unsigned long c;
- unsigned long long base_unit, freq = NSECS_PER_SEC;
+ unsigned long c, base_unit_range;
+ unsigned long long base_unit, freq = NSEC_PER_SEC;
u32 ctrl;
do_div(freq, period_ns);
- /* The equation is: base_unit = ((freq / c) * 65536) + correction */
- base_unit = freq * 65536;
+ /* The equation is: base_unit = ((freq / c) * base_unit_range) + correction */
+ base_unit_range = BIT(lpwm->info->base_unit_bits);
+ base_unit = freq * base_unit_range;
- c = lpwm->clk_rate;
+ c = lpwm->info->clk_rate;
if (!c)
return -EINVAL;
do_div(base_unit, c);
base_unit += PWM_DIVISION_CORRECTION;
- if (base_unit > PWM_LIMIT)
- return -EINVAL;
if (duty_ns <= 0)
duty_ns = 1;
@@ -109,8 +109,10 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
pm_runtime_get_sync(chip->dev);
ctrl = pwm_lpss_read(pwm);
- ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
- ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
+ ctrl &= ~PWM_ON_TIME_DIV_MASK;
+ ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT);
+ base_unit &= (base_unit_range - 1);
+ ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
ctrl |= on_time_div;
/* request PWM to update on next cycle */
ctrl |= PWM_SW_UPDATE;
@@ -156,7 +158,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
if (IS_ERR(lpwm->regs))
return ERR_CAST(lpwm->regs);
- lpwm->clk_rate = info->clk_rate;
+ lpwm->info = info;
lpwm->chip.dev = dev;
lpwm->chip.ops = &pwm_lpss_ops;
lpwm->chip.base = -1;
diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
index e8cf337..04766e0 100644
--- a/drivers/pwm/pwm-lpss.h
+++ b/drivers/pwm/pwm-lpss.h
@@ -21,6 +21,7 @@ struct pwm_lpss_chip;
struct pwm_lpss_boardinfo {
unsigned long clk_rate;
unsigned int npwm;
+ unsigned long base_unit_bits;
};
extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 2+ messages in thread* [PATCH v3] pwm:lpss: update pwm setting for Broxton
@ 2015-11-16 11:06 Qipeng Zha
0 siblings, 0 replies; 2+ messages in thread
From: Qipeng Zha @ 2015-11-16 11:06 UTC (permalink / raw)
To: linux-pwm; +Cc: thierry.reding, mika.westerberg, qipeng.zha
For Broxton PWM controller, base unit is defined as 8bit integer
and 14bit fraction, so need to update base unit setting to output
wave with right frequency.
---
change in v3
use BIT macro to calculate base_unit_range;
mask base_unit with "base_unit_range - 1".
Signed-off-by: Qipeng Zha <qipeng.zha@intel.com>
---
drivers/pwm/pwm-lpss.c | 30 ++++++++++++++++--------------
drivers/pwm/pwm-lpss.h | 1 +
2 files changed, 17 insertions(+), 14 deletions(-)
diff --git a/drivers/pwm/pwm-lpss.c b/drivers/pwm/pwm-lpss.c
index 2504410..4530c48 100644
--- a/drivers/pwm/pwm-lpss.c
+++ b/drivers/pwm/pwm-lpss.c
@@ -14,6 +14,7 @@
*/
#include <linux/io.h>
+#include <linux/time.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
@@ -24,11 +25,8 @@
#define PWM_ENABLE BIT(31)
#define PWM_SW_UPDATE BIT(30)
#define PWM_BASE_UNIT_SHIFT 8
-#define PWM_BASE_UNIT_MASK 0x00ffff00
#define PWM_ON_TIME_DIV_MASK 0x000000ff
#define PWM_DIVISION_CORRECTION 0x2
-#define PWM_LIMIT (0x8000 + PWM_DIVISION_CORRECTION)
-#define NSECS_PER_SEC 1000000000UL
/* Size of each PWM register space if multiple */
#define PWM_SIZE 0x400
@@ -36,13 +34,14 @@
struct pwm_lpss_chip {
struct pwm_chip chip;
void __iomem *regs;
- unsigned long clk_rate;
+ const struct pwm_lpss_boardinfo *info;
};
/* BayTrail */
const struct pwm_lpss_boardinfo pwm_lpss_byt_info = {
.clk_rate = 25000000,
.npwm = 1,
+ .base_unit_bits = 16,
};
EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
@@ -50,6 +49,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_byt_info);
const struct pwm_lpss_boardinfo pwm_lpss_bsw_info = {
.clk_rate = 19200000,
.npwm = 1,
+ .base_unit_bits = 16,
};
EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
@@ -57,6 +57,7 @@ EXPORT_SYMBOL_GPL(pwm_lpss_bsw_info);
const struct pwm_lpss_boardinfo pwm_lpss_bxt_info = {
.clk_rate = 19200000,
.npwm = 4,
+ .base_unit_bits = 22,
};
EXPORT_SYMBOL_GPL(pwm_lpss_bxt_info);
@@ -84,23 +85,22 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
{
struct pwm_lpss_chip *lpwm = to_lpwm(chip);
u8 on_time_div;
- unsigned long c;
- unsigned long long base_unit, freq = NSECS_PER_SEC;
+ unsigned long c, base_unit_range;
+ unsigned long long base_unit, freq = NSEC_PER_SEC;
u32 ctrl;
do_div(freq, period_ns);
- /* The equation is: base_unit = ((freq / c) * 65536) + correction */
- base_unit = freq * 65536;
+ /* The equation is: base_unit = ((freq / c) * base_unit_range) + correction */
+ base_unit_range = BIT(lpwm->info->base_unit_bits);
+ base_unit = freq * base_unit_range;
- c = lpwm->clk_rate;
+ c = lpwm->info->clk_rate;
if (!c)
return -EINVAL;
do_div(base_unit, c);
base_unit += PWM_DIVISION_CORRECTION;
- if (base_unit > PWM_LIMIT)
- return -EINVAL;
if (duty_ns <= 0)
duty_ns = 1;
@@ -109,8 +109,10 @@ static int pwm_lpss_config(struct pwm_chip *chip, struct pwm_device *pwm,
pm_runtime_get_sync(chip->dev);
ctrl = pwm_lpss_read(pwm);
- ctrl &= ~(PWM_BASE_UNIT_MASK | PWM_ON_TIME_DIV_MASK);
- ctrl |= (u16) base_unit << PWM_BASE_UNIT_SHIFT;
+ ctrl &= ~PWM_ON_TIME_DIV_MASK;
+ ctrl &= ~((base_unit_range - 1) << PWM_BASE_UNIT_SHIFT);
+ base_unit &= (base_unit_range - 1);
+ ctrl |= (u32) base_unit << PWM_BASE_UNIT_SHIFT;
ctrl |= on_time_div;
/* request PWM to update on next cycle */
ctrl |= PWM_SW_UPDATE;
@@ -156,7 +158,7 @@ struct pwm_lpss_chip *pwm_lpss_probe(struct device *dev, struct resource *r,
if (IS_ERR(lpwm->regs))
return ERR_CAST(lpwm->regs);
- lpwm->clk_rate = info->clk_rate;
+ lpwm->info = info;
lpwm->chip.dev = dev;
lpwm->chip.ops = &pwm_lpss_ops;
lpwm->chip.base = -1;
diff --git a/drivers/pwm/pwm-lpss.h b/drivers/pwm/pwm-lpss.h
index e8cf337..04766e0 100644
--- a/drivers/pwm/pwm-lpss.h
+++ b/drivers/pwm/pwm-lpss.h
@@ -21,6 +21,7 @@ struct pwm_lpss_chip;
struct pwm_lpss_boardinfo {
unsigned long clk_rate;
unsigned int npwm;
+ unsigned long base_unit_bits;
};
extern const struct pwm_lpss_boardinfo pwm_lpss_byt_info;
--
1.8.3.2
^ permalink raw reply related [flat|nested] 2+ messages in thread
end of thread, other threads:[~2015-11-16 3:03 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2015-11-16 11:07 [PATCH v3] pwm:lpss: update pwm setting for Broxton Qipeng Zha
-- strict thread matches above, loose matches on Subject: below --
2015-11-16 11:06 Qipeng Zha
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).