From: Russell King - ARM Linux <linux@arm.linux.org.uk>
To: Paul Walmsley <paul@pwsan.com>
Cc: linux-arm-kernel@lists.arm.linux.org.uk,
linux-omap@vger.kernel.org, Tony Lindgren <tony@atomide.com>
Subject: Re: [PATCH 04/10] ARM: OMAP2: Remove OMAP_PRM_REGADDR, OMAP_CM_REGADDR
Date: Mon, 6 Oct 2008 17:18:49 +0100 [thread overview]
Message-ID: <20081006161849.GC27466@flint.arm.linux.org.uk> (raw)
In-Reply-To: <20081002163751.15385.31321.stgit@localhost.localdomain>
On Thu, Oct 02, 2008 at 10:37:52AM -0600, Paul Walmsley wrote:
> From: Tony Lindgren <tony@atomide.com>
>
> Remove OMAP_PRM_REGADDR and OMAP_CM_REGADDR. Use
> prm_read/write_mod_reg() or cm_read/write_mod_reg() instead. For
> assembly, use OMAPXXXX_PRM_REGADDR or OMAPXXXX_CM_REGADDR macros.
I do have concerns about this patch as well - hating those casts
that are required to store an offset in 'enable_reg', which then
have to be un-casted to add the correct base address.
I've been trying to work out if there's a better way to do this
using the existing structures. How about:
struct clk {
...
void __iomem *base;
struct clk *other_clk; /* associated func/interface clock */
u16 enable_offset;
u16 idlest_offset;
u16 clksel_offset;
u8 enable_bit;
u8 idlest_bit;
...
int (*enable)(struct clk *);
void (*disable)(struct clk *);
...
};
(or use u8 if the offsets always fit.)
The setup of apll96_ck becomes:
static struct clk apll96_ck = {
.name = "apll96_ck",
.parent = &sys_ck,
.rate = 96000000,
.flags = CLOCK_IN_OMAP242X | CLOCK_IN_OMAP243X |
RATE_FIXED | RATE_PROPAGATES | ENABLE_ON_INIT,
.clkdm_name = "wkup_clkdm",
.enable_offset = CM_REG_OFFSET(PLL_MOD, CM_CLKEN),
.idlest_offset = CM_REG_OFFSET(PLL_MOD, CM_IDLEST),
.enable_bit = OFFSET_OF_BIT(EN_APLL_LOCKED << OMAP24XX_EN_96M_PLL_SHIFT),
.idlest_bit = OFFSET_OF_BIT(OMAP24XX_ST_96M_APLL),
.enable = clkll_enable32_and_wait,
.disable = clkll_disable32,
.recalc = &propagate_rate,
};
(replacing OFFSET_OF_BIT() with the appropriate real bit position number).
You register all such clocks thusly:
void clk_register_offset_clks(void __iomem *base, struct clk **clks, size_t num)
{
size_t i;
for (i = 0; i < num; i++) {
struct clk *clk = clks[i];
clk->base = base;
clk_register(clk);
}
}
static struct clk cm_clks[] = {
&apll96_ck,
};
clk_register_offset_clks(cm_base, cm_clks, ARRAY_SIZE(cm_clks);
and, eg, the accesses to the enable register become:
int clkll_enable32(struct clk *clk)
{
u32 val, mask = 1 << clk->enable_bit;
val = __raw_readl(clk->base + clk->enable_offset);
if (clk->flags & INVERT_ENABLE)
val &= ~mask;
else
val |= mask;
__raw_writel(val, clk->base + clk->enable_offset);
wmb();
return 0;
}
void clkll_disable32(struct clk *clk)
{
u32 val, mask = 1 << clk->enable_bit;
val = __raw_readl(clk->base + clk->enable_offset);
if (clk->flags & INVERT_ENABLE)
val |= mask;
else
val &= ~mask;
__raw_writel(val, clk->base + clk->enable_offset);
wmb();
}
int clkll_is_running32(struct clk *clk)
{
u32 val, mask = 1 << clk->enable_bit;
val = __raw_readl(clk->base + clk->enable_offset) & mask;
return clk->flags & INVERT_ENABLE ? !val : !!val;
}
int clkll_enable32_and_wait(struct clk *clk)
{
u32 mask, result, val;
unsigned int tries = 0;
if (!clkll_is_running32(clk))
clkll_enable32(clk);
/* check if other clock, if any, is running */
if (clk->other_clk && !clkll_is_running32(clk->other_clk))
return 0;
val = mask = 1 << clk->idlest_bit;
if (inverted_on_this_cpu)
val = 0;
for (tries = 0; tries < MAX_CLOCK_ENABLE_WAIT; tries++, udelay(1)) {
result = __raw_readl(clk->base + clk->idlest_offset) & mask;
if (result == val)
break;
}
if (result == val)
pr_debug("Clock %s stable after %uus\n", clk->name, tries);
else
pr_err("Clock %s failed to stablize after %uus\n",
clk->name, tries);
return result == val ? 0 : -ETIMEDOUT;
}
Then, you use clkll_enable32() if you don't need to wait for the clock
to stablize, or clkll_enable32_and_wait() if you do.
If you need 16-bit, which I think I've seen, obviously create the
corresponding versions.
next prev parent reply other threads:[~2008-10-06 16:19 UTC|newest]
Thread overview: 25+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-10-02 16:37 [PATCH 00/10] OMAP clock updates for post 2.6.27 Paul Walmsley
2008-10-02 16:37 ` [PATCH 01/10] ARM: OMAP2: Add non-CORE DPLL rate set code and M, N programming Paul Walmsley
2008-10-02 16:37 ` [PATCH 02/10] ARM: OMAP: Fix sparse, checkpatch warnings in OMAP2/3 PRCM/PM code Paul Walmsley
2008-10-04 13:19 ` Russell King - ARM Linux
2008-10-06 14:52 ` Paul Walmsley
2008-10-06 15:09 ` Russell King - ARM Linux
2008-10-06 15:13 ` Paul Walmsley
2008-10-02 16:37 ` [PATCH 03/10] ARM: OMAP: Clock tree updates for OMAP2/3 Paul Walmsley
2008-10-02 16:37 ` [PATCH 05/10] ARM: OMAP2: Implement CPUfreq frequency table based on PRCM table Paul Walmsley
2008-10-02 16:37 ` [PATCH 04/10] ARM: OMAP2: Remove OMAP_PRM_REGADDR, OMAP_CM_REGADDR Paul Walmsley
2008-10-06 16:18 ` Russell King - ARM Linux [this message]
2008-10-06 23:39 ` Russell King - ARM Linux
2008-10-07 14:12 ` Paul Walmsley
2008-10-27 20:59 ` Russell King - ARM Linux
2008-11-06 13:15 ` Paul Walmsley
2008-10-07 12:54 ` Paul Walmsley
2008-10-02 16:37 ` [PATCH 06/10] OMAP2/3 clock: combine clkdm, clkdm_name into union in struct clk Paul Walmsley
2008-10-02 16:37 ` [PATCH 07/10] OMAP2/3 clockdomains: combine pwrdm, pwrdm_name into union in struct clockdomain Paul Walmsley
2008-10-02 16:37 ` [PATCH 09/10] OMAP3 PRCM: add DPLL1-5 powerdomains, clockdomains; mark clocks Paul Walmsley
2008-10-02 16:37 ` [PATCH 08/10] OMAP2/3 clockdomains: add CM, PRM, virt_opp_clkdm clockdomains Paul Walmsley
2008-10-02 16:37 ` [PATCH 10/10] OMAP2/3 clock: add clockdomains to all remaining clocks; remove superfluous init Paul Walmsley
2008-10-02 20:17 ` [PATCH 00/10] OMAP clock updates for post 2.6.27 Russell King - ARM Linux
2008-10-03 6:38 ` Tony Lindgren
2008-10-06 14:48 ` Paul Walmsley
2008-10-06 15:12 ` Russell King - ARM Linux
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=20081006161849.GC27466@flint.arm.linux.org.uk \
--to=linux@arm.linux.org.uk \
--cc=linux-arm-kernel@lists.arm.linux.org.uk \
--cc=linux-omap@vger.kernel.org \
--cc=paul@pwsan.com \
--cc=tony@atomide.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox