From: bpringlemeir@nbsps•com (Bill Pringlemeir)
To: linux-arm-kernel@lists•infradead.org
Subject: [RFC] pwm: Add Freescale FTM PWM driver support
Date: Thu, 19 Dec 2013 16:06:17 -0500 [thread overview]
Message-ID: <87eh58zh2u.fsf@nbsps.com> (raw)
In-Reply-To: 1385979309-10505-1-git-send-email-Li.Xiubo@freescale.com
On 2 Dec 2013, Li.Xiubo at freescale.com wrote:
> The FTM PWM device can be found on Vybrid VF610 Tower and
> Layerscape LS-1 SoCs.
[snip]
> In Vybird VF610 Tower, all the IP blocks expect LE data. In the LS-1, some of
> the IP blocks expect LE data, while others expect BE data. And the CPU always
> operates in LE mode in these two platforms.
[snip]
> +static inline u32 fsl_pwm_readl(struct fsl_pwm_chip *fpc, void __iomem *reg)
> +{
> + u32 val;
> +
> + val = __raw_readl(reg);
> +
> + if (fpc->endianess == FTM_BIG)
> + return be32_to_cpu(val);
> + else
> + return le32_to_cpu(val);
> +}
> +
> +static inline void fsl_pwm_writel(struct fsl_pwm_chip *fpc, u32 val,
> + void __iomem *reg)
> +{
> + if (fpc->endianess == FTM_BIG)
> + val = cpu_to_be32(val);
> + else
> + val = cpu_to_le32(val);
> +
> + __raw_writel(val, reg);
> +}
Remove above and alter as below,
static int fsl_pwm_set_polarity(struct pwm_chip *chip, struct pwm_device *pwm,
enum pwm_polarity polarity)
{
u32 val;
struct fsl_pwm_chip *fpc = to_fsl_chip(chip);
val = readl(fpc, fpc->base + FTM_POL);
if (polarity == PWM_POLARITY_INVERSED)
- val |= BIT(pwm->hwpwm);
+ val |= BIT(fpc->chn_bit);
else
- val &= ~BIT(pwm->hwpwm);
+ val &= ~BIT(fpc->chn_bit);
writel(fpc, val, fpc->base + FTM_POL);
return 0;
}
static int fsl_counter_clock_enable(struct fsl_pwm_chip *fpc)
{
int ret;
u32 val;
if (fpc->counter_clk_enable++)
return 0;
ret = clk_prepare_enable(fpc->counter_clk);
if (ret) {
fpc->counter_clk_enable--;
return ret;
}
val = readl(fpc, fpc->base + FTM_SC);
+ val |= val >> 24; /* get value on big-endian. */
val &= ~((FTM_SC_CLK_MASK << FTM_SC_CLK_SHIFT) |
(FTM_SC_PS_MASK << FTM_SC_PS_SHIFT));
/* select counter clock source */
switch (fpc->counter_clk_select) {
case VF610_CLK_FTM0:
val |= FTM_SC_CLK_SYS;
break;
case VF610_CLK_FTM0_FIX_SEL:
val |= FTM_SC_CLK_FIX;
break;
case VF610_CLK_FTM0_EXT_SEL:
val |= FTM_SC_CLK_EXT;
break;
default:
fpc->counter_clk_enable--;
return -EINVAL;
}
val |= fpc->clk_ps;
+ val |= val << 24; /* modify to high byte for big-endian. */
writel(fpc, val, fpc->base + FTM_SC);
return 0;
}
That is instead of modifying the low level accessor, you can alter the
driver masks based on the OF selected endian. Many of the registers are
already accessed as run-time fields because each channel is in a
different bit position. There are only two registers with fields that
cross a byte boundary; COUNT and MOD. These two must be swapped. The
others are either a byte or are accessed base on a channel number.
For example in fsl_pwm_set_polarity(), we would read the memory, swap
the value, calculate a bit to set, clear or set the bit and then write
back the swapped value all on the 'big_endian' condition. This way, you
just read a bit shift which is conditional on the endian at probe time
and don't double swap.
In the fsl_counter_clock_enable(), the example is using 'write ignored
bits' and duplicating the value in both big/little bytes. An
alternative is to parameterize all the mask/values in 'const struct' and
have a different pointer for big/little and store this in-place (or via
a pointer) in fsl_pwm_chip.
Fwiw,
Bill Pringlemeir.
next prev parent reply other threads:[~2013-12-19 21:06 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2013-12-02 10:15 [RFC] pwm: Add Freescale FTM PWM driver support Xiubo Li
2013-12-02 12:34 ` Mark Rutland
2013-12-03 4:02 ` Li Xiubo
2013-12-03 10:36 ` Mark Rutland
2013-12-04 3:12 ` Li Xiubo
2013-12-19 21:06 ` Bill Pringlemeir [this message]
2013-12-26 9:11 ` Li.Xiubo at freescale.com
2014-01-03 6:13 ` Li.Xiubo at freescale.com
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=87eh58zh2u.fsf@nbsps.com \
--to=bpringlemeir@nbsps$(echo .)com \
--cc=linux-arm-kernel@lists$(echo .)infradead.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox