Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 883e4d07 authored by qipeng.zha's avatar qipeng.zha Committed by Thierry Reding
Browse files

pwm: lpss: Update PWM setting for Broxton



For Broxton PWM controller, base unit is defined as 8-bit integer
and 14-bit fraction, so need to update base unit setting to output
wave with right frequency.

Signed-off-by: default avatarQipeng Zha <qipeng.zha@intel.com>
Acked-by: default avatarMika Westerberg <mika.westerberg@linux.intel.com>
Signed-off-by: default avatarThierry Reding <thierry.reding@gmail.com>
parent 6ef7d1c4
Loading
Loading
Loading
Loading
+19 −14
Original line number Diff line number Diff line
@@ -17,6 +17,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/pm_runtime.h>
#include <linux/time.h>

#include "pwm-lpss.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,25 @@ 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 +112,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;
@@ -155,7 +160,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;
+1 −0
Original line number Diff line number Diff line
@@ -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;