All of lore.kernel.org
 help / color / mirror / Atom feed
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.

  parent reply	other threads:[~2013-12-19 21:06 UTC|newest]

Thread overview: 14+ 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 10:15 ` Xiubo Li
2013-12-02 10:15 ` Xiubo Li
2013-12-02 12:34 ` Mark Rutland
2013-12-02 12:34   ` Mark Rutland
2013-12-03  4:02   ` Li Xiubo
2013-12-03  4:02     ` Li Xiubo
2013-12-03 10:36     ` Mark Rutland
2013-12-03 10:36       ` Mark Rutland
2013-12-04  3:12       ` Li Xiubo
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.com \
    --cc=linux-arm-kernel@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.