Re: [patch] OMAPDSS: pll: NULL dereference in error handling
On 17/12/14 01:54, Dan Carpenter wrote: > The regulator_disable() doesn't accept NULL pointers. > > Signed-off-by: Dan Carpenter > > diff --git a/drivers/video/fbdev/omap2/dss/pll.c > b/drivers/video/fbdev/omap2/dss/pll.c > index 50bc62c5..335ffac 100644 > --- a/drivers/video/fbdev/omap2/dss/pll.c > +++ b/drivers/video/fbdev/omap2/dss/pll.c > @@ -97,7 +97,8 @@ int dss_pll_enable(struct dss_pll *pll) > return 0; > > err_enable: > - regulator_disable(pll->regulator); > + if (pll->regulator) > + regulator_disable(pll->regulator); > err_reg: > clk_disable_unprepare(pll->clkin); > return r; > Thanks! Queuing for 3.19 fbdev fixes. Tomi signature.asc Description: OpenPGP digital signature
Re: Fwd: next boot: 101 boots: 89 pass, 12 fail (next-20141216)
On 17 December 2014 at 02:33, Nishanth Menon wrote: > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-omap5-uevm.html > [2.071996] [ cut here ] > [2.076831] kernel BUG at ../drivers/cpufreq/cpufreq.c:1258! > [2.082753] Internal error: Oops - BUG: 0 [#1] SMP ARM This is what we have hit: if ((cpufreq_driver->flags & CPUFREQ_NEED_INITIAL_FREQ_CHECK) && has_target()) { /* Are we running at unknown frequency ? */ ret = cpufreq_frequency_table_get_index(policy, policy->cur); if (ret == -EINVAL) { /* Warn user and fix it */ pr_warn("%s: CPU%d: Running at unlisted freq: %u KHz\n", __func__, policy->cpu, policy->cur); ret = __cpufreq_driver_target(policy, policy->cur - 1, CPUFREQ_RELATION_L); /* * Reaching here after boot in a few seconds may not * mean that system will remain stable at "unknown" * frequency for longer duration. Hence, a BUG_ON(). */ BUG_ON(ret);/* We have hit this one ***/ pr_warn("%s: CPU%d: Unlisted initial frequency changed to: %u KHz\n", __func__, policy->cpu, policy->cur); } } So the SoC was running on unlisted frequency and when we tried to change to some other valid (listed) frequency, we failed. The comment over it describes why it is a BUG.. Its some SoC issue and need to be resolved by somebody with a board. So, in short __cpufreq_driver_target() failed to change freq.. -- viresh -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[patch] OMAPDSS: pll: NULL dereference in error handling
The regulator_disable() doesn't accept NULL pointers. Signed-off-by: Dan Carpenter diff --git a/drivers/video/fbdev/omap2/dss/pll.c b/drivers/video/fbdev/omap2/dss/pll.c index 50bc62c5..335ffac 100644 --- a/drivers/video/fbdev/omap2/dss/pll.c +++ b/drivers/video/fbdev/omap2/dss/pll.c @@ -97,7 +97,8 @@ int dss_pll_enable(struct dss_pll *pll) return 0; err_enable: - regulator_disable(pll->regulator); + if (pll->regulator) + regulator_disable(pll->regulator); err_reg: clk_disable_unprepare(pll->clkin); return r; -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: regression: Clock changes in next-20141205 break at least omap4
+ p...@pwsan.com (I prefer not having to deal with MS Exchange when possible :-) ) On Tue, 16 Dec 2014, Russell King - ARM Linux wrote: > On Tue, Dec 16, 2014 at 08:45:25PM +, Paul Walmsley wrote: > > On Tue, 16 Dec 2014, Russell King - ARM Linux wrote: > > > > > On Tue, Dec 16, 2014 at 01:01:17PM -0700, Paul Walmsley wrote: > > > > So the reference clock and functional clock are (usually) required by > > > > the > > > > PLL to operate, and should therefore be required by the PLL clock driver > > > > code in the kernel; but one could claim that they aren't technically > > > > parent > > > > clocks of the PLL in a clock tree sense, since the downstream output > > > > clock > > > > isn't directly derived from either of those clocks. > > > > > > The reference clock is the parent clock for a PLL, and the output clock > > > is a derivative of the reference clock. The PLL maths show that very > > > clearly. > > > > The PLL's internal oscillator is the electrical source of the PLL's output > > clock. The reference clock is just used to discipline that internal > > oscillator. Even that's not necessary - the reference clock can be > > optional on some clock source implementations, which can run the internal > > oscillator in open-loop mode. > > I would argue that running a PLL in open-loop mode is an exceptional > circumstance: in such scenarios, many PLLs will head towards a certain > frequency (depending on their design) and some may be rather unstable > in open loop mode. Only those which have been explicitly designed to > be stable in open loop mode should be run that way. > > And arguably, a PLL without a reference clock is not a phase *locked* > loop at all - the clue is in the name. A PLL without a reference clock > is merely an oscillator. There is no "phase lock" what so ever. ... > This really is a question about how you view a PLL, and it's one which > can be debated for a very long time, and everyone will have perfectly > valid but conflicting ideas on it. Yep, I agree with most of what you wrote. I was mostly thinking about our Linux data structures and software abstraction for clocks that have multiple input clocks that all need to be simultaneously active for the IP block to work. PLLs and PLL-like clock sources which take multiple input clocks just happened to be the examples of this phenomenon that came to mind. Those multiple input clocks could all be considered "parents" from a use-counting point of view, and we could expect the core clock code to deal with them. Or one could take the electrical point of view and consider only one of the input clocks to be the "parent" -- whatever's directly driving the output clock -- and fix up the gating and constraint details in the driver code for that clock source. I don't think this pot is boiling over at the moment; but, just something for us to reflect on. - Paul -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 2/2] ARM: dra7xx: Fix counter frequency drift for AM572x errata i856.
Errata i856 for the AM572x (DRA7xx) points out that the 32.768KHz external crystal is not enabled at power up. Instead the CPU falls back to using an emulation for the 32KHz clock which is SYSCLK1/610. SYSCLK1 is usually 20MHz on boards so far (which gives an emulated frequency of 32.786KHz), but can also be 19.2 or 27MHz which result in much larger drift. Since this is used to drive the master counter at 32.768KHz * 375 / 2 = 6.144MHz, the emulated speed for 20MHz is of by 570ppm, or about 43 seconds per day, and more than the 500ppm NTP is able to tolerate. Checking the CTRL_CORE_BOOTSTRAP register can determine if the CPU is using the real 32.768KHz crystal or the emulated SYSCLK1/610, and by known that the real counter frequency can be determined and used. The real speed is then SYSCLK1 / 610 * 375 / 2 or SYSCLK1 * 75 / 244. Signed-off-by: Len Sorensen --- arch/arm/mach-omap2/control.h |4 arch/arm/mach-omap2/timer.c | 36 ++-- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a3c0133..a80ac2d 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -286,6 +286,10 @@ #define OMAP5XXX_CONTROL_STATUS0x134 #define OMAP5_DEVICETYPE_MASK (0x7 << 6) +/* DRA7XX CONTROL CORE BOOTSTRAP */ +#define DRA7_CTRL_CORE_BOOTSTRAP 0x6c4 +#define DRA7_SPEEDSELECT_MASK (0x3 << 8) + /* * REVISIT: This list of registers is not comprehensive - there are more * that should be added. diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index fb0cb2b..7d45c84 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -54,6 +54,7 @@ #include "soc.h" #include "common.h" +#include "control.h" #include "powerdomain.h" #include "omap-secure.h" @@ -496,7 +497,8 @@ static void __init realtime_counter_init(void) void __iomem *base; static struct clk *sys_clk; unsigned long rate; - unsigned int reg, num, den; + unsigned int reg; + unsigned long long num, den; base = ioremap(REALTIME_COUNTER_BASE, SZ_32); if (!base) { @@ -511,6 +513,35 @@ static void __init realtime_counter_init(void) } rate = clk_get_rate(sys_clk); + + if (soc_is_dra7xx()) { + /* +* Errata i856 says the 32.768KHz crystal does not start at +* power on, so the CPU falls back to an emulated 32KHz clock +* based on sysclk / 610 instead. This causes the master counter +* frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2 +* (OR sysclk * 75 / 244) +* +* This affects at least the DRA7/AM572x 1.0, 1.1 revisions. +* Of course any board built without a populated 32.768KHz +* crystal would also need this fix even if the CPU is fixed +* later. +* +* Either case can be detected by using the two speedselect bits +* If they are not 0, then the 32.768KHz clock driving the +* coarse counter that corrects the fine counter every time it +* ticks is actually rate/610 rather than 32.768KHz and we +* should compensate to avoid the 570ppm (at 20MHz, much worse +* at other rates) too fast system time. +*/ + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); + if (reg & DRA7_SPEEDSELECT_MASK) { + num = 75; + den = 244; + goto sysclk1_based; + } + } + /* Numerator/denumerator values refer TRM Realtime Counter section */ switch (rate) { case 1200: @@ -545,6 +576,7 @@ static void __init realtime_counter_init(void) break; } +sysclk1_based: /* Program numerator and denumerator registers */ reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & NUMERATOR_DENUMERATOR_MASK; @@ -556,7 +588,7 @@ static void __init realtime_counter_init(void) reg |= den; writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); - arch_timer_freq = (rate / den) * num; + arch_timer_freq = DIV_ROUND_UP_ULL(rate * num, den); set_cntfreq(); iounmap(base); -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 1/2] ARM: omap5/dra7xx: Fix frequency typos.
The switch statement of the possible list of SYSCLK1 frequencies is missing a 0 in 4 out of the 7 frequencies. Fixes: fa6d79d27614 ("ARM: OMAP: Add initialisation for the real-time counter") Signed-off-by: Len Sorensen Reviewed-by: Lokesh Vutla Acked-by: Nishanth Menon --- arch/arm/mach-omap2/timer.c |8 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 4f61148..fb0cb2b 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -513,11 +513,11 @@ static void __init realtime_counter_init(void) rate = clk_get_rate(sys_clk); /* Numerator/denumerator values refer TRM Realtime Counter section */ switch (rate) { - case 120: + case 1200: num = 64; den = 125; break; - case 130: + case 1300: num = 768; den = 1625; break; @@ -529,11 +529,11 @@ static void __init realtime_counter_init(void) num = 192; den = 625; break; - case 260: + case 2600: num = 384; den = 1625; break; - case 270: + case 2700: num = 256; den = 1125; break; -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH V2 0/2] ARM: omap5/dra7xx counter frequency fixes
While trying to deal with errata i856 on the dra7xx I encountered some obvious typos in the frequencies checked in timer.c, so those are being fixed in case anyone ever tries to use one of them. Also implement a fix for errata i856. Without the fix the time on the system will get ahead by 43 seconds per day if SYSCLK1 is 20MHz, which it is on the EVM boards as well as the other boards I am currently aware of. ntp declares that the system time drifts by over 500ppm (the maximum ntp will tolerate). To fix it, check the status register to determine if the 32.768KHz clock source is real (driven by an external crystal) or emulated (SYSCLK1 / 610), and if it is emulated use the appropriate numerator and divisor to make the fine master counter match the coarse master counter (which is driven directly from the 32KHz clock (real or emulated) with a fixed multiplier of 375 / 2). Making the fine counter run at a frequency different from the coarse counter is not an option, as the value in the fine counter is updated to match the coarse counter if they ever get out of sync. With 19.2MHz installed on the board, the clock runs almost 5% slow. With the change in place, ntp runs with a drift of around 3ppm on all boards I have tried which is well within the spec of the crystals used for SYSCLK1. Even if the errata is fixed in future revisions of the chip, there is still the option of someone purposely not connecting a 32.768KHz crystal to save cost or board space, and relying on the emulated clock instead, in which case this correction will still be necessary. Len Sorensen (2): ARM: omap5/dra7xx: Fix frequency typos. ARM: dra7xx: Fix counter frequency drift for AM572x errata i856. arch/arm/mach-omap2/control.h |4 arch/arm/mach-omap2/timer.c | 44 +++-- 2 files changed, 42 insertions(+), 6 deletions(-) -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: Fwd: next boot: 101 boots: 89 pass, 12 fail (next-20141216)
+Viresh and linux-pm On 12/16/2014 10:59 AM, Kevin Hilman wrote: > FYI... New boot failures in today's linux-next for omap4-panda-es and > omap5-uevm: > >http://status.armcloud.us/boot/?lab-khilman&fail&omap http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-omap5-uevm.html [2.071996] [ cut here ] [2.076831] kernel BUG at ../drivers/cpufreq/cpufreq.c:1258! [2.082753] Internal error: Oops - BUG: 0 [#1] SMP ARM http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-omap4-panda-es.html [2.109588] [ cut here ] [2.114410] kernel BUG at ../drivers/cpufreq/cpufreq.c:1258! [2.120330] Internal error: Oops - BUG: 0 [#1] SMP ARM > > The omap3-beagle-xm one has been fixed by Tero, but the fix hasn't hit > -next yet. I haven't had a chance to bisect these yet. > > Kevin > > > -- Forwarded message -- > From: Kevin's boot bot > Date: Mon, Dec 15, 2014 at 10:28 PM > Subject: next boot: 101 boots: 89 pass, 12 fail (next-20141216) > To: kernel-build-repo...@lists.linaro.org > > > Full Build report: http://status.armcloud.us/build/next/kernel/next-20141216/ > Full Boot report: > http://status.armcloud.us/boot/all/job/next/kernel/next-20141216/ > > Tree/Branch: next > Git describe: next-20141216 > > Failed boot tests > = > emev2-kzm9d: FAIL:arm-shmobile_defconfig >u-boot: ERROR: timeout getting > DHCP address. > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-shmobile_defconfig/lab-khilman/boot-emev2-kzm9d.html > exynos5420-arndale-octa: FAIL: > arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y > kernel: ERROR: failed to boot: > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y/lab-khilman/boot-exynos5420-arndale-octa.html > exynos5800-peach-pi: FAIL: > arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y >kernel: ERROR: failed to boot: > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y/lab-khilman/boot-exynos5800-peach-pi.html > omap5-uevm: FAIL: > arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y > kernel: Unable to handle kernel > paging request at virtual address ffec > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y/lab-khilman/boot-omap5-uevm.html > exynos5800-peach-pi: FAIL:arm-multi_v7_defconfig >kernel: ERROR: failed to boot: > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-exynos5800-peach-pi.html > exynos5420-arndale-octa: FAIL:arm-multi_v7_defconfig >kernel: ERROR: failed to boot: > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-exynos5420-arndale-octa.html > omap5-uevm: FAIL:arm-multi_v7_defconfig >kernel: Unable to handle kernel > paging request at virtual address ffec > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-omap5-uevm.html > omap4-panda-es: FAIL:arm-multi_v7_defconfig >kernel: ERROR: failed to boot: > Kernel panic > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-omap4-panda-es.html > exynos5420-arndale-octa: FAIL:arm-exynos_defconfig >kernel: ERROR: failed to boot: > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-exynos_defconfig/lab-khilman/boot-exynos5420-arndale-octa.html > exynos5800-peach-pi: FAIL:arm-exynos_defconfig >kernel: ERROR: failed to boot: > > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-exynos_defconfig/lab-khilman/boot-exynos5800-peach-pi.html > exynos5410-odroid-xu: FAIL:arm-exynos_defconfig >ERROR: Timeout waiting for > command: if test -n ${preboot}; then run preboot; fi. > > http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-exynos_defconfig/lab-khilman/boot-exynos5410-odroid-xu.html > omap3-beagle-xm,l
Re: regression: Clock changes in next-20141205 break at least omap4
On Tue, Dec 16, 2014 at 08:45:25PM +, Paul Walmsley wrote: > On Tue, 16 Dec 2014, Russell King - ARM Linux wrote: > > > On Tue, Dec 16, 2014 at 01:01:17PM -0700, Paul Walmsley wrote: > > > So the reference clock and functional clock are (usually) required by the > > > PLL to operate, and should therefore be required by the PLL clock driver > > > code in the kernel; but one could claim that they aren't technically > > > parent > > > clocks of the PLL in a clock tree sense, since the downstream output clock > > > isn't directly derived from either of those clocks. > > > > The reference clock is the parent clock for a PLL, and the output clock > > is a derivative of the reference clock. The PLL maths show that very > > clearly. > > The PLL's internal oscillator is the electrical source of the PLL's output > clock. The reference clock is just used to discipline that internal > oscillator. Even that's not necessary - the reference clock can be > optional on some clock source implementations, which can run the internal > oscillator in open-loop mode. I would argue that running a PLL in open-loop mode is an exceptional circumstance: in such scenarios, many PLLs will head towards a certain frequency (depending on their design) and some may be rather unstable in open loop mode. Only those which have been explicitly designed to be stable in open loop mode should be run that way. And arguably, a PLL without a reference clock is not a phase *locked* loop at all - the clue is in the name. A PLL without a reference clock is merely an oscillator. There is no "phase lock" what so ever. > The question of what the appropriate "parent" clock(s) should be is really > a question of how the software chooses to model it, and has more to do > with use-counts, constraints, etc. I don't believe we have documented a > precise definition for what a "parent clock" is, in the Linux clock > framework context. If a PLL is designed to be operated in open loop mode, then the parent clock should be optional, otherwise the parent clock is rather fundamental to the PLLs operation, in the same way that the parent clock is fundamental to a divider's operation. You can argue that taking away the "reference" clock to a divider gives a known output (which happens to be 0Hz) but a steady state can still be a perfectly valid clock signal too if it changes state at some point. :) In much the same way, some PLLs are designed to disable their output when they are not in lock. Much like that divider above with no reference input. This really is a question about how you view a PLL, and it's one which can be debated for a very long time, and everyone will have perfectly valid but conflicting ideas on it. -- FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up according to speedtest.net. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: regression: Clock changes in next-20141205 break at least omap4
On Tue, 16 Dec 2014, Russell King - ARM Linux wrote: > On Tue, Dec 16, 2014 at 01:01:17PM -0700, Paul Walmsley wrote: > > So the reference clock and functional clock are (usually) required by the > > PLL to operate, and should therefore be required by the PLL clock driver > > code in the kernel; but one could claim that they aren't technically parent > > clocks of the PLL in a clock tree sense, since the downstream output clock > > isn't directly derived from either of those clocks. > > The reference clock is the parent clock for a PLL, and the output clock > is a derivative of the reference clock. The PLL maths show that very > clearly. The PLL's internal oscillator is the electrical source of the PLL's output clock. The reference clock is just used to discipline that internal oscillator. Even that's not necessary - the reference clock can be optional on some clock source implementations, which can run the internal oscillator in open-loop mode. The question of what the appropriate "parent" clock(s) should be is really a question of how the software chooses to model it, and has more to do with use-counts, constraints, etc. I don't believe we have documented a precise definition for what a "parent clock" is, in the Linux clock framework context. - Paul -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: regression: Clock changes in next-20141205 break at least omap4
On Tue, Dec 16, 2014 at 01:01:17PM -0700, Paul Walmsley wrote: > So the reference clock and functional clock are (usually) required by the > PLL to operate, and should therefore be required by the PLL clock driver > code in the kernel; but one could claim that they aren't technically parent > clocks of the PLL in a clock tree sense, since the downstream output clock > isn't directly derived from either of those clocks. The reference clock is the parent clock for a PLL, and the output clock is a derivative of the reference clock. The PLL maths show that very clearly. -- FTTC broadband for 0.8mile line: currently at 9.5Mbps down 400kbps up according to speedtest.net. -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: regression: Clock changes in next-20141205 break at least omap4
+ Tero On 12/16/2014 12:01 PM, Stephen Boyd wrote: On 12/15/2014 05:31 PM, Paul Walmsley wrote: I just took a quick glance at Tero's second patch, and it looks like a hack to me. Better to fix the problem in the core CCF code if possible. I don't think there's any reason why a PLL couldn't have just one parent clock. But I'm fine with merging it as a short-term fix if fixing the core code is difficult or risky. Can you describe what's wrong? Took a closer look at it, at your prompting. The first observation is that the issue seems to be limited to TI-specific clock code in drivers/clk/ti. So nothing to worry about in terms of the CCF core, it looks. The second observation is that this appears to only be a problem due to the current DT data in arch/arm/boot/dts/omap3xxx-clocks.dtsi: dpll3_ck: dpll3_ck { #clock-cells = <0>; compatible = "ti,omap3-dpll-core-clock"; clocks = <&sys_ck>, <&sys_ck>; reg = <0x0d00>, <0x0d20>, <0x0d40>, <0x0d30>; }; It lists two entries for the "clocks" node for some reason. of_ti_dpll_setup() only seems to require one. So unless there's some good reason to list two of them in the DTS file, the right fix would probably have been to fix the DT data. Does the PLL have a mux with two inputs that map to the same clock? I don't think so. ... Generally speaking, I suspect the way we model PLLs isn't quite right (although it's been a while since I've looked at that particular code). This was probably my fault, in the final analysis, for taking a shortcut here a long time ago. Unless one wishes to implement support for multiple clock parents, it's probably not quite right to state that a PLL's reference clock is a "parent" in a clock tree sense. When a PLL is active, the output clock originates from a VCO of some kind that is internal to the PLL. The reference clock is just used by the PLL internal logic to close the control loop. Some PLL-like clock sources use a third clock that is used to clock some of the PLL's internal logic (let's call this a "functional clock.") So the reference clock and functional clock are (usually) required by the PLL to operate, and should therefore be required by the PLL clock driver code in the kernel; but one could claim that they aren't technically parent clocks of the PLL in a clock tree sense, since the downstream output clock isn't directly derived from either of those clocks. Otherwise if we want to represent those clocks accurately in the Linux clock tree, we probably need to state that clocks can have multiple "parents" that often need to be active simultaneously, and we should propagate usecount changes accordingly up all of the parent paths. ... Anyway, thanks for following up on this, - Paul -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
On Tue, Dec 16, 2014 at 01:56:16PM -0600, Nishanth Menon wrote: > *AM*57xx is not *OMAP*57xx -> there is no OMAP57xx. Oh OK. Thanks for clearing that up. > AM57xx and DRA7xx are in the same generation of processors and is > derivative technology (not the same) as OMAP5432/OMAP5430. > > We have been using DRA7 as a generic terminology to indicate > AM57xx/DRA7 family of processors. I will drop omap5 from the subject for the next version then since it seems clear that the omap5 does not have this problem. -- Len Sorensen -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
On 12/16/2014 10:16 AM, Lennart Sorensen wrote: > On Tue, Dec 16, 2014 at 05:05:08PM +0530, Lokesh Vutla wrote: >> Is this applicable for OMAP5 also? >> If not can you drop omap5 from $subject? > > DRA7xx = OMAP57xx, which to me is an omap5. Isn't it? *AM*57xx is not *OMAP*57xx -> there is no OMAP57xx. AM57xx and DRA7xx are in the same generation of processors and is derivative technology (not the same) as OMAP5432/OMAP5430. We have been using DRA7 as a generic terminology to indicate AM57xx/DRA7 family of processors. -- Regards, Nishanth Menon -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
On 12/16/2014 01:27 PM, Lennart Sorensen wrote: >> I see why arch_timer_freq might skip the rounding error of 39, 15 and >> 55 Vs existing logic which is possibly at a truncation error risk >> (without errata for sysclk 13, 26 and 27MHz). >> >> all you'd probably need to do is cast rate, num and den to unsigned >> long and have a common computation logic. > > If that is acceptable, then sure I can do that. I liked avoiding casts > in general though. > >> if you'd really want to handle truncation error, it must be a separate >> patch of it's own - I would not mix it with the errata fix. > > Well there is no error in the existing code because the rate / den > is always a clean integer division. The problem is introduced by the key is "there is no error in existing code for existing value" :) -> the same code for new values will fail. and introducing (rate * num) / den without cast will fail for old values. > SYSCLK1 / 610 used by the emulated clock which is not a clean division. > > So for the existing logic, the calculation was perfect. It is only for > the errata case that it is a problem. > > So I think leaving the existing calculation but moved up works well, > and then having the alternate order calculation only in the errata case > seemed cleaner and avoids casts and 64bit math which I thought was > overall desirable. In general using DIV_ROUND_UP and family of macros(in kernel.h) is the right way of doing division in similar cases in Linux kernel. And for the same functionality, we want a common equation - if it does not fit well for all values (even if we introduce new values), then we must come to a better equation that will work for all values. What we do not do is to have two equations meant for doing the same thing. -- Regards, Nishanth Menon -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
> I see why arch_timer_freq might skip the rounding error of 39, 15 and > 55 Vs existing logic which is possibly at a truncation error risk > (without errata for sysclk 13, 26 and 27MHz). > > all you'd probably need to do is cast rate, num and den to unsigned > long and have a common computation logic. If that is acceptable, then sure I can do that. I liked avoiding casts in general though. > if you'd really want to handle truncation error, it must be a separate > patch of it's own - I would not mix it with the errata fix. Well there is no error in the existing code because the rate / den is always a clean integer division. The problem is introduced by the SYSCLK1 / 610 used by the emulated clock which is not a clean division. So for the existing logic, the calculation was perfect. It is only for the errata case that it is a problem. So I think leaving the existing calculation but moved up works well, and then having the alternate order calculation only in the errata case seemed cleaner and avoids casts and 64bit math which I thought was overall desirable. -- Len Sorensen -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: regression: Clock changes in next-20141205 break at least omap4
On 12/15/2014 05:31 PM, Paul Walmsley wrote: > > I just took a quick glance at Tero's second patch, and it looks like a > hack to me. Better to fix the problem in the core CCF code if > possible. I don't think there's any reason why a PLL couldn't have > just one parent clock. But I'm fine with merging it as a short-term > fix if fixing the core code is difficult or risky. Can you describe what's wrong? Does the PLL have a mux with two inputs that map to the same clock? -- Qualcomm Innovation Center, Inc. is a member of Code Aurora Forum, a Linux Foundation Collaborative Project -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
On 12/16/2014 10:36 AM, Lennart Sorensen wrote: [...] >> B) Since rate switch is no longer needed, how about something like the >> following: >> diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h >> index a3c0133..315d6d1 100644 >> --- a/arch/arm/mach-omap2/control.h >> +++ b/arch/arm/mach-omap2/control.h >> @@ -286,6 +286,11 @@ >> #define OMAP5XXX_CONTROL_STATUS0x134 >> #define OMAP5_DEVICETYPE_MASK (0x7 << 6) >> >> + >> +/* DRA7XX CONTROL CORE BOOTSTRAP */ >> +#define DRA7_CTRL_CORE_BOOTSTRAP0x6c4 >> +#define DRA7_SPEEDSELECT_MASK (0x3 << 8) >> + >> /* >> * REVISIT: This list of registers is not comprehensive - there are more >> * that should be added. > > I like that as a place for those. > >> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c >> index 4f61148..783d3c3 100644 >> --- a/arch/arm/mach-omap2/timer.c >> +++ b/arch/arm/mach-omap2/timer.c >> @@ -54,6 +54,7 @@ >> >> #include "soc.h" >> #include "common.h" >> +#include "control.h" >> #include "powerdomain.h" >> #include "omap-secure.h" >> > > How about this version for the rest of the file. It handles that for > the errata case we would like to do rate * num / den, which given how > small the num is will fit in 32bit and gives the best accuracy for the > calculation, while the non errata case the existing calculation works > well and fits in 32 bit for all other cases. It just has to be moved > up so that the goto can skip it. I changed sysclk to sysclk1 since on > the dra7xx there is in fact a sysclk1 and a sysclk2 and it is probably > worth keeping it clear which one this is referring to. > > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c > index fb0cb2b..be254bf 100644 > --- a/arch/arm/mach-omap2/timer.c > +++ b/arch/arm/mach-omap2/timer.c > @@ -511,6 +511,36 @@ static void __init realtime_counter_init(void) > } > > rate = clk_get_rate(sys_clk); > + > + if (soc_is_dra7xx()) { > + /* > + * Errata i856 says the 32.768KHz crystal does not start at > + * power on, so the CPU falls back to an emulated 32KHz clock > + * based on sysclk1 / 610 instead. This causes the master > counter > + * frequency to not be 6.144MHz but at sysclk1 / 610 * 375 / 2 > + * (OR sysclk1 * 75 / 244) > + * > + * This affects at least the DRA7/AM572x 1.0, 1.1 revisions. > + * Of course any board built without a populated 32.768KHz > + * crystal would also need this fix even if the CPU is fixed > + * later. > + * > + * Either case can be detected by using the two speedselect bits > + * If they are not 0, then the 32.768KHz clock driving the > + * coarse counter that corrects the fine counter every time it > + * ticks is actually rate/610 rather than 32.768KHz and we > + * should compensate to avoid the 570ppm (at 20MHz, much worse > + * at other rates) too fast system time. > + */ > + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); > + if (reg & DRA7_SPEEDSELECT_MASK) { > + num = 75; > + den = 244; > + arch_timer_freq = (rate * num) / den; > + goto sysclk1_based; > + } > + } > + > /* Numerator/denumerator values refer TRM Realtime Counter section */ > switch (rate) { > case 1200: > @@ -544,7 +574,9 @@ static void __init realtime_counter_init(void) > den = 25; > break; > } > + arch_timer_freq = (rate / den) * num; > > +sysclk1_based: > /* Program numerator and denumerator registers */ > reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & > NUMERATOR_DENUMERATOR_MASK; > @@ -556,7 +588,6 @@ static void __init realtime_counter_init(void) > reg |= den; > writel_relaxed(reg, base + INCREMENTER_DENUMERATOR_RELOAD_OFFSET); > > - arch_timer_freq = (rate / den) * num; I see why arch_timer_freq might skip the rounding error of 39, 15 and 55 Vs existing logic which is possibly at a truncation error risk (without errata for sysclk 13, 26 and 27MHz). all you'd probably need to do is cast rate, num and den to unsigned long and have a common computation logic. if you'd really want to handle truncation error, it must be a separate patch of it's own - I would not mix it with the errata fix. -- Regards, Nishanth Menon -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Fwd: next boot: 101 boots: 89 pass, 12 fail (next-20141216)
FYI... New boot failures in today's linux-next for omap4-panda-es and omap5-uevm: http://status.armcloud.us/boot/?lab-khilman&fail&omap The omap3-beagle-xm one has been fixed by Tero, but the fix hasn't hit -next yet. I haven't had a chance to bisect these yet. Kevin -- Forwarded message -- From: Kevin's boot bot Date: Mon, Dec 15, 2014 at 10:28 PM Subject: next boot: 101 boots: 89 pass, 12 fail (next-20141216) To: kernel-build-repo...@lists.linaro.org Full Build report: http://status.armcloud.us/build/next/kernel/next-20141216/ Full Boot report: http://status.armcloud.us/boot/all/job/next/kernel/next-20141216/ Tree/Branch: next Git describe: next-20141216 Failed boot tests = emev2-kzm9d: FAIL:arm-shmobile_defconfig u-boot: ERROR: timeout getting DHCP address. http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-shmobile_defconfig/lab-khilman/boot-emev2-kzm9d.html exynos5420-arndale-octa: FAIL: arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y kernel: ERROR: failed to boot: http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y/lab-khilman/boot-exynos5420-arndale-octa.html exynos5800-peach-pi: FAIL: arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y kernel: ERROR: failed to boot: http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y/lab-khilman/boot-exynos5800-peach-pi.html omap5-uevm: FAIL: arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y kernel: Unable to handle kernel paging request at virtual address ffec http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y/lab-khilman/boot-omap5-uevm.html exynos5800-peach-pi: FAIL:arm-multi_v7_defconfig kernel: ERROR: failed to boot: http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-exynos5800-peach-pi.html exynos5420-arndale-octa: FAIL:arm-multi_v7_defconfig kernel: ERROR: failed to boot: http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-exynos5420-arndale-octa.html omap5-uevm: FAIL:arm-multi_v7_defconfig kernel: Unable to handle kernel paging request at virtual address ffec http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-omap5-uevm.html omap4-panda-es: FAIL:arm-multi_v7_defconfig kernel: ERROR: failed to boot: Kernel panic http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-multi_v7_defconfig/lab-khilman/boot-omap4-panda-es.html exynos5420-arndale-octa: FAIL:arm-exynos_defconfig kernel: ERROR: failed to boot: http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-exynos_defconfig/lab-khilman/boot-exynos5420-arndale-octa.html exynos5800-peach-pi: FAIL:arm-exynos_defconfig kernel: ERROR: failed to boot: http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-exynos_defconfig/lab-khilman/boot-exynos5800-peach-pi.html exynos5410-odroid-xu: FAIL:arm-exynos_defconfig ERROR: Timeout waiting for command: if test -n ${preboot}; then run preboot; fi. http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-exynos_defconfig/lab-khilman/boot-exynos5410-odroid-xu.html omap3-beagle-xm,legacy: FAIL:arm-omap2plus_defconfig kernel: ERROR: did not start booting. http://storage.armcloud.us/kernel-ci/next/next-20141216/arm-omap2plus_defconfig/lab-khilman/boot-omap3-beagle-xm,legacy.html Full Report === arm-shmobile_defconfig -- emev2-kzm9d: FAIL - u-boot: ERROR: timeout getting DHCP address. arm-davinci_all_defconfig - dm365evm,legacy: PASS da850-evm: PASS arm-tegra_defconfig --- tegra124-jetson-tk1: PASS tegra30-beaver: PASS arm-bcm2835_defconfig - bcm2835-rpi: PASS arm-multi_v7_defconfig+CONFIG_CPU_BIG_ENDIAN=y -- armada-xp-openblocks-ax3-4: PASS armada-370-mirabox: PASS arm-multi_v7_defconfig+CONFIG_ARM_LPAE=y tegra124-jetson-tk1: PASS ex
Re: [PATCH 1/2] ARM: omap5/dra7xx: Fix frequency typos.
On Tue, Dec 16, 2014 at 08:06:34AM -0600, Nishanth Menon wrote: > On 12/12/2014 04:08 PM, Lennart Sorensen wrote: > > The switch statement of the possible list of SYSCLK1 frequencies is > > missing a 0 in 4 out of the 7 frequencies. > > > > Signed-off-by: Len Sorensen > > --- > > arch/arm/mach-omap2/timer.c |8 > > 1 file changed, 4 insertions(+), 4 deletions(-) > > > > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c > > index 4f61148..fb0cb2b 100644 > > --- a/arch/arm/mach-omap2/timer.c > > +++ b/arch/arm/mach-omap2/timer.c > > @@ -513,11 +513,11 @@ static void __init realtime_counter_init(void) > > rate = clk_get_rate(sys_clk); > > /* Numerator/denumerator values refer TRM Realtime Counter section */ > > switch (rate) { > > - case 120: > > + case 1200: > > num = 64; > > den = 125; > > break; > > - case 130: > > + case 1300: > > num = 768; > > den = 1625; > > break; > > @@ -529,11 +529,11 @@ static void __init realtime_counter_init(void) > > num = 192; > > den = 625; > > break; > > - case 260: > > + case 2600: > > num = 384; > > den = 1625; > > break; > > - case 270: > > + case 2700: > > num = 256; > > den = 1125; > > break; > > > > > Also please add: > Fixes: fa6d79d27614 ("ARM: OMAP: Add initialisation for the real-time > counter") > > With that, > > Acked-by: Nishanth Menon Should I send a new version with that added, or will someone else handle doing that bit? -- Len Sorensen -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
On Tue, Dec 16, 2014 at 08:58:56AM -0600, Nishanth Menon wrote: > On 17:05-20141216, Lokesh Vutla wrote: > [...] > > > > @@ -545,6 +546,16 @@ static void __init realtime_counter_init(void) > > break; > > } > > > > + if (soc_is_dra7xx()) { > > + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); > > + reg = reg & DRA7_SPEEDSELECT_MASK; > > + > > + if (reg) { > > + num = 75; > > + den = 244; > > + } > > + } > > + > > /* Program numerator and denumerator registers */ > > reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & > > NUMERATOR_DENUMERATOR_MASK; > > A) So, it does look like the 32k node is actually wrong then -> Tero: > any comments? should'nt this now be modeled based on > CTRL_CORE_BOOTSTRAP::SPEEDSELECT considering that clock nodes do have > clk mux options based on the 32k.. > sys_32k_ck: sys_32k_ck { > #clock-cells = <0>; > compatible = "fixed-clock"; > clock-frequency = <32768>; > }; Hmm, I hadn't considered other things that might care. Certainly if you were to use a SYSCLK1 other than 20MHz, it certainly won't be 32KHz anymore. > B) Since rate switch is no longer needed, how about something like the > following: > diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h > index a3c0133..315d6d1 100644 > --- a/arch/arm/mach-omap2/control.h > +++ b/arch/arm/mach-omap2/control.h > @@ -286,6 +286,11 @@ > #define OMAP5XXX_CONTROL_STATUS0x134 > #define OMAP5_DEVICETYPE_MASK (0x7 << 6) > > + > +/* DRA7XX CONTROL CORE BOOTSTRAP */ > +#define DRA7_CTRL_CORE_BOOTSTRAP 0x6c4 > +#define DRA7_SPEEDSELECT_MASK(0x3 << 8) > + > /* > * REVISIT: This list of registers is not comprehensive - there are more > * that should be added. I like that as a place for those. > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c > index 4f61148..783d3c3 100644 > --- a/arch/arm/mach-omap2/timer.c > +++ b/arch/arm/mach-omap2/timer.c > @@ -54,6 +54,7 @@ > > #include "soc.h" > #include "common.h" > +#include "control.h" > #include "powerdomain.h" > #include "omap-secure.h" > How about this version for the rest of the file. It handles that for the errata case we would like to do rate * num / den, which given how small the num is will fit in 32bit and gives the best accuracy for the calculation, while the non errata case the existing calculation works well and fits in 32 bit for all other cases. It just has to be moved up so that the goto can skip it. I changed sysclk to sysclk1 since on the dra7xx there is in fact a sysclk1 and a sysclk2 and it is probably worth keeping it clear which one this is referring to. diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index fb0cb2b..be254bf 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -511,6 +511,36 @@ static void __init realtime_counter_init(void) } rate = clk_get_rate(sys_clk); + + if (soc_is_dra7xx()) { + /* +* Errata i856 says the 32.768KHz crystal does not start at +* power on, so the CPU falls back to an emulated 32KHz clock +* based on sysclk1 / 610 instead. This causes the master counter +* frequency to not be 6.144MHz but at sysclk1 / 610 * 375 / 2 +* (OR sysclk1 * 75 / 244) +* +* This affects at least the DRA7/AM572x 1.0, 1.1 revisions. +* Of course any board built without a populated 32.768KHz +* crystal would also need this fix even if the CPU is fixed +* later. +* +* Either case can be detected by using the two speedselect bits +* If they are not 0, then the 32.768KHz clock driving the +* coarse counter that corrects the fine counter every time it +* ticks is actually rate/610 rather than 32.768KHz and we +* should compensate to avoid the 570ppm (at 20MHz, much worse +* at other rates) too fast system time. +*/ + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); + if (reg & DRA7_SPEEDSELECT_MASK) { + num = 75; + den = 244; + arch_timer_freq = (rate * num) / den; + goto sysclk1_based; + } + } + /* Numerator/denumerator values refer TRM Realtim
[PATCH 07/11] clk: ti: composite: add support for legacy composite clock init
Legacy clock data is initialized slightly differently compared to DT clocks, thus add support for this. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk.c |3 +++ drivers/clk/ti/clock.h |1 + drivers/clk/ti/composite.c | 46 3 files changed, 46 insertions(+), 4 deletions(-) diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index f41a757..546dae4 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -217,6 +217,9 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup) case TI_CLK_DIVIDER: clk = ti_clk_register_divider(setup); break; + case TI_CLK_COMPOSITE: + clk = ti_clk_register_composite(setup); + break; case TI_CLK_FIXED_FACTOR: fixed_factor = setup->data; diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index f4e8eb2..8d9c603 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -157,6 +157,7 @@ struct clk *ti_clk_register_gate(struct ti_clk *setup); struct clk *ti_clk_register_interface(struct ti_clk *setup); struct clk *ti_clk_register_mux(struct ti_clk *setup); struct clk *ti_clk_register_divider(struct ti_clk *setup); +struct clk *ti_clk_register_composite(struct ti_clk *setup); struct clk *ti_clk_register_dpll(struct ti_clk *setup); struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup); diff --git a/drivers/clk/ti/composite.c b/drivers/clk/ti/composite.c index 19d8980..3a9665f 100644 --- a/drivers/clk/ti/composite.c +++ b/drivers/clk/ti/composite.c @@ -23,6 +23,8 @@ #include #include +#include "clock.h" + #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -116,8 +118,44 @@ static inline struct clk_hw *_get_hw(struct clk_hw_omap_comp *clk, int idx) #define to_clk_hw_comp(_hw) container_of(_hw, struct clk_hw_omap_comp, hw) -static void __init ti_clk_register_composite(struct clk_hw *hw, -struct device_node *node) +struct clk *ti_clk_register_composite(struct ti_clk *setup) +{ + struct ti_clk_composite *comp; + struct clk_hw *gate; + struct clk_hw *mux; + struct clk_hw *div; + int num_parents = 1; + const char **parent_names = NULL; + struct clk *clk; + + comp = setup->data; + + div = ti_clk_build_component_div(comp->divider); + gate = ti_clk_build_component_gate(comp->gate); + mux = ti_clk_build_component_mux(comp->mux); + + if (div) + parent_names = &comp->divider->parent; + + if (gate) + parent_names = &comp->gate->parent; + + if (mux) { + num_parents = comp->mux->num_parents; + parent_names = comp->mux->parents; + } + + clk = clk_register_composite(NULL, setup->name, +parent_names, num_parents, mux, +&ti_clk_mux_ops, div, +&ti_composite_divider_ops, gate, +&ti_composite_gate_ops, 0); + + return clk; +} + +static void __init _register_composite(struct clk_hw *hw, + struct device_node *node) { struct clk *clk; struct clk_hw_omap_comp *cclk = to_clk_hw_comp(hw); @@ -136,7 +174,7 @@ static void __init ti_clk_register_composite(struct clk_hw *hw, pr_debug("component %s not ready for %s, retry\n", cclk->comp_nodes[i]->name, node->name); if (!ti_clk_retry_init(node, hw, - ti_clk_register_composite)) + _register_composite)) return; goto cleanup; @@ -216,7 +254,7 @@ static void __init of_ti_composite_clk_setup(struct device_node *node) for (i = 0; i < num_clks; i++) cclk->comp_nodes[i] = _get_component_node(node, i); - ti_clk_register_composite(&cclk->hw, node); + _register_composite(&cclk->hw, node); } CLK_OF_DECLARE(ti_composite_clock, "ti,composite-clock", of_ti_composite_clk_setup); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 05/11] clk: ti: divider: add support for legacy divider init
Legacy clock data is initialized slightly differently compared to DT clocks, thus add support for this. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk.c |3 ++ drivers/clk/ti/clock.h |2 + drivers/clk/ti/divider.c | 132 +- 3 files changed, 136 insertions(+), 1 deletion(-) diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 676dbf1..a0475e2 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -214,6 +214,9 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup) case TI_CLK_MUX: clk = ti_clk_register_mux(setup); break; + case TI_CLK_DIVIDER: + clk = ti_clk_register_divider(setup); + break; case TI_CLK_FIXED_FACTOR: fixed_factor = setup->data; diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index 9430dc6..fe70941 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -156,7 +156,9 @@ struct ti_clk_dpll { struct clk *ti_clk_register_gate(struct ti_clk *setup); struct clk *ti_clk_register_interface(struct ti_clk *setup); struct clk *ti_clk_register_mux(struct ti_clk *setup); +struct clk *ti_clk_register_divider(struct ti_clk *setup); +struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup); struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup); struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); diff --git a/drivers/clk/ti/divider.c b/drivers/clk/ti/divider.c index bff2b5b..6211893 100644 --- a/drivers/clk/ti/divider.c +++ b/drivers/clk/ti/divider.c @@ -21,6 +21,7 @@ #include #include #include +#include "clock.h" #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -301,6 +302,134 @@ static struct clk *_register_divider(struct device *dev, const char *name, } static struct clk_div_table * +_get_div_table_from_setup(struct ti_clk_divider *setup, u8 *width) +{ + int valid_div = 0; + struct clk_div_table *table; + int i; + int div; + u32 val; + u8 flags; + + if (!setup->num_dividers) { + /* Clk divider table not provided, determine min/max divs */ + flags = setup->flags; + + if (flags & CLKF_INDEX_STARTS_AT_ONE) + val = 1; + else + val = 0; + + div = 1; + + while (div < setup->max_div) { + if (flags & CLKF_INDEX_POWER_OF_TWO) + div <<= 1; + else + div++; + val++; + } + + *width = fls(val); + + return NULL; + } + + for (i = 0; i < setup->num_dividers; i++) + if (setup->dividers[i]) + valid_div++; + + table = kzalloc(sizeof(*table) * (valid_div + 1), GFP_KERNEL); + if (!table) + return ERR_PTR(-ENOMEM); + + valid_div = 0; + *width = 0; + + for (i = 0; i < setup->num_dividers; i++) + if (setup->dividers[i]) { + table[valid_div].div = setup->dividers[i]; + table[valid_div].val = i; + valid_div++; + *width = i; + } + + *width = fls(*width); + + return table; +} + +struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup) +{ + struct clk_divider *div; + struct clk_omap_reg *reg; + + if (!setup) + return NULL; + + div = kzalloc(sizeof(*div), GFP_KERNEL); + if (!div) + return ERR_PTR(-ENOMEM); + + reg = (struct clk_omap_reg *)&div->reg; + reg->index = setup->module; + reg->offset = setup->reg; + + if (setup->flags & CLKF_INDEX_STARTS_AT_ONE) + div->flags |= CLK_DIVIDER_ONE_BASED; + + if (setup->flags & CLKF_INDEX_POWER_OF_TWO) + div->flags |= CLK_DIVIDER_POWER_OF_TWO; + + div->table = _get_div_table_from_setup(setup, &div->width); + + div->shift = setup->bit_shift; + + return &div->hw; +} + +struct clk *ti_clk_register_divider(struct ti_clk *setup) +{ + struct ti_clk_divider *div; + struct clk_omap_reg *reg_setup; + u32 reg; + u8 width; + u32 flags = 0; + u8 div_flags = 0; + struct clk_div_table *table; + struct clk *clk; + + div = setup->data; + + reg_setup = (struct clk_omap_reg *)® + + reg_setup->index = div->module; + reg_setup->offset = div->reg; + + if (div->flags & CLKF_INDEX_STARTS_AT_ONE) + div_flags |= CLK_DIVIDER_ONE_BASED; + + if (div->flags & CLKF_INDEX_POWER_OF_TWO) + div_flags |= CLK_DIVIDER_POWER_OF_TWO; + + if (div->flags & CLKF_SET_RATE_PARENT) + flags |= CLK_SET_RATE_PARENT; + + t
[PATCH 09/11] ARM: OMAP3: PRM: add support for legacy iomapping init
As the legacy clock data is being moved under clock driver, the clock data will be using the same low level infrastructure for register accesses. This requires the clk_memmaps to be initialized properly. This patch adds a support hook to the PRM driver to initialize the mappings. Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/prm.h|1 + arch/arm/mach-omap2/prm_common.c | 11 +++ 2 files changed, 12 insertions(+) diff --git a/arch/arm/mach-omap2/prm.h b/arch/arm/mach-omap2/prm.h index 48480d5..a33303c 100644 --- a/arch/arm/mach-omap2/prm.h +++ b/arch/arm/mach-omap2/prm.h @@ -20,6 +20,7 @@ extern void __iomem *prm_base; extern u16 prm_features; extern void omap2_set_globals_prm(void __iomem *prm); int of_prcm_init(void); +void omap3_prcm_legacy_iomaps_init(void); # endif /* diff --git a/arch/arm/mach-omap2/prm_common.c b/arch/arm/mach-omap2/prm_common.c index ee2b522..18f8bac 100644 --- a/arch/arm/mach-omap2/prm_common.c +++ b/arch/arm/mach-omap2/prm_common.c @@ -35,6 +35,8 @@ #include "prm44xx.h" #include "common.h" #include "clock.h" +#include "cm.h" +#include "control.h" /* * OMAP_PRCM_MAX_NR_PENDING_REG: maximum number of PRM_IRQ*_MPU regs @@ -528,6 +530,15 @@ int __init of_prcm_init(void) return 0; } +void __init omap3_prcm_legacy_iomaps_init(void) +{ + ti_clk_ll_ops = &omap_clk_ll_ops; + + clk_memmaps[TI_CLKM_CM] = cm_base + OMAP3430_IVA2_MOD; + clk_memmaps[TI_CLKM_PRM] = prm_base + OMAP3430_IVA2_MOD; + clk_memmaps[TI_CLKM_SCRM] = omap_ctrl_base_get(); +} + static int __init prm_late_init(void) { if (prm_ll_data->late_init) -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 06/11] clk: ti: dpll: add support for legacy DPLL init
Legacy clock data is initialized slightly differently compared to DT clocks, thus add support for this. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk.c |3 ++ drivers/clk/ti/clock.h |1 + drivers/clk/ti/dpll.c | 118 +++- 3 files changed, 111 insertions(+), 11 deletions(-) diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index a0475e2..f41a757 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -228,6 +228,9 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup) case TI_CLK_GATE: clk = ti_clk_register_gate(setup); break; + case TI_CLK_DPLL: + clk = ti_clk_register_dpll(setup); + break; default: pr_err("bad type for %s!\n", setup->name); clk = ERR_PTR(-EINVAL); diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index fe70941..f4e8eb2 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -157,6 +157,7 @@ struct clk *ti_clk_register_gate(struct ti_clk *setup); struct clk *ti_clk_register_interface(struct ti_clk *setup); struct clk *ti_clk_register_mux(struct ti_clk *setup); struct clk *ti_clk_register_divider(struct ti_clk *setup); +struct clk *ti_clk_register_dpll(struct ti_clk *setup); struct clk_hw *ti_clk_build_component_div(struct ti_clk_divider *setup); struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup); diff --git a/drivers/clk/ti/dpll.c b/drivers/clk/ti/dpll.c index 79791e1..0693b8b 100644 --- a/drivers/clk/ti/dpll.c +++ b/drivers/clk/ti/dpll.c @@ -21,6 +21,7 @@ #include #include #include +#include "clock.h" #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -115,7 +116,7 @@ static const struct clk_ops dpll_x2_ck_ops = { }; /** - * ti_clk_register_dpll - low level registration of a DPLL clock + * _register_dpll - low level registration of a DPLL clock * @hw: hardware clock definition for the clock * @node: device node for the clock * @@ -123,8 +124,8 @@ static const struct clk_ops dpll_x2_ck_ops = { * clk-bypass is missing), the clock is added to retry list and * the initialization is retried on later stage. */ -static void __init ti_clk_register_dpll(struct clk_hw *hw, - struct device_node *node) +static void __init _register_dpll(struct clk_hw *hw, + struct device_node *node) { struct clk_hw_omap *clk_hw = to_clk_hw_omap(hw); struct dpll_data *dd = clk_hw->dpll_data; @@ -136,7 +137,7 @@ static void __init ti_clk_register_dpll(struct clk_hw *hw, if (IS_ERR(dd->clk_ref) || IS_ERR(dd->clk_bypass)) { pr_debug("clk-ref or clk-bypass missing for %s, retry later\n", node->name); - if (!ti_clk_retry_init(node, hw, ti_clk_register_dpll)) + if (!ti_clk_retry_init(node, hw, _register_dpll)) return; goto cleanup; @@ -160,20 +161,115 @@ cleanup: kfree(clk_hw); } +void __iomem *_get_reg(u8 module, u16 offset) +{ + u32 reg; + struct clk_omap_reg *reg_setup; + + reg_setup = (struct clk_omap_reg *)® + + reg_setup->index = module; + reg_setup->offset = offset; + + return (void __iomem *)reg; +} + +struct clk *ti_clk_register_dpll(struct ti_clk *setup) +{ + struct clk_hw_omap *clk_hw; + struct clk_init_data init = { NULL }; + struct dpll_data *dd; + struct clk *clk; + struct ti_clk_dpll *dpll; + const struct clk_ops *ops = &omap3_dpll_ck_ops; + struct clk *clk_ref; + struct clk *clk_bypass; + + dpll = setup->data; + + if (dpll->num_parents < 2) + return ERR_PTR(-EINVAL); + + clk_ref = clk_get_sys(NULL, dpll->parents[0]); + clk_bypass = clk_get_sys(NULL, dpll->parents[1]); + + if (IS_ERR_OR_NULL(clk_ref) || IS_ERR_OR_NULL(clk_bypass)) + return ERR_PTR(-EAGAIN); + + dd = kzalloc(sizeof(*dd), GFP_KERNEL); + clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); + if (!dd || !clk_hw) { + clk = ERR_PTR(-ENOMEM); + goto cleanup; + } + + clk_hw->dpll_data = dd; + clk_hw->ops = &clkhwops_omap3_dpll; + clk_hw->hw.init = &init; + clk_hw->flags = MEMMAP_ADDRESSING; + + init.name = setup->name; + init.ops = ops; + + init.num_parents = dpll->num_parents; + init.parent_names = dpll->parents; + + dd->control_reg = _get_reg(dpll->module, dpll->control_reg); + dd->idlest_reg = _get_reg(dpll->module, dpll->idlest_reg); + dd->mult_div1_reg = _get_reg(dpll->module, dpll->mult_div1_reg); + dd->autoidle_reg = _get_reg(dpll->module, dpll->autoidle_reg); + + dd->modes = dpll->modes; + dd->div1_mask = dpll->div1_mask; + dd->idlest_mask = dpll->idlest_mask; + dd->mult_m
[PATCH 10/11] ARM: OMAP3: use clock data from TI clock driver for legacy boot
As the clock data is now available for the legacy boot also from the clock driver, use this rather than the data under the mach folder. This allows us to get rid of the old clock data completely. Signed-off-by: Tero Kristo --- arch/arm/mach-omap2/io.c | 28 +++- 1 file changed, 19 insertions(+), 9 deletions(-) diff --git a/arch/arm/mach-omap2/io.c b/arch/arm/mach-omap2/io.c index 03cbb16..7295943 100644 --- a/arch/arm/mach-omap2/io.c +++ b/arch/arm/mach-omap2/io.c @@ -459,7 +459,17 @@ void __init omap3_init_early(void) omap3xxx_clockdomains_init(); omap3xxx_hwmod_init(); omap_hwmod_init_postsetup(); - omap_clk_soc_init = omap3xxx_clk_init; + if (!of_have_populated_dt()) { + omap3_prcm_legacy_iomaps_init(); + if (soc_is_am35xx()) + omap_clk_soc_init = am35xx_clk_legacy_init; + else if (cpu_is_omap3630()) + omap_clk_soc_init = omap36xx_clk_legacy_init; + else if (omap_rev() == OMAP3430_REV_ES1_0) + omap_clk_soc_init = omap3430es1_clk_legacy_init; + else + omap_clk_soc_init = omap3430_clk_legacy_init; + } } void __init omap3430_init_early(void) @@ -507,8 +517,6 @@ void __init ti81xx_init_early(void) omap_hwmod_init_postsetup(); if (of_have_populated_dt()) omap_clk_soc_init = ti81xx_dt_clk_init; - else - omap_clk_soc_init = omap3xxx_clk_init; } void __init omap3_init_late(void) @@ -722,15 +730,17 @@ int __init omap_clk_init(void) ti_clk_init_features(); - ret = of_prcm_init(); - if (ret) - return ret; + if (of_have_populated_dt()) { + ret = of_prcm_init(); + if (ret) + return ret; - of_clk_init(NULL); + of_clk_init(NULL); - ti_dt_clk_init_retry_clks(); + ti_dt_clk_init_retry_clks(); - ti_dt_clockdomains_setup(); + ti_dt_clockdomains_setup(); + } ret = omap_clk_soc_init(); -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 03/11] clk: ti: gate: add support for legacy gate init
Legacy clock data is initialialized slightly differently compared to DT clocks, thus add support for this. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk.c |3 + drivers/clk/ti/clock.h |2 + drivers/clk/ti/gate.c | 158 +++- 3 files changed, 133 insertions(+), 30 deletions(-) diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 215f681..676dbf1 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -222,6 +222,9 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup) 0, fixed_factor->mult, fixed_factor->div); break; + case TI_CLK_GATE: + clk = ti_clk_register_gate(setup); + break; default: pr_err("bad type for %s!\n", setup->name); clk = ERR_PTR(-EINVAL); diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index c06bbf4..d0715bc 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -153,8 +153,10 @@ struct ti_clk_dpll { u8 recal_st_bit; }; +struct clk *ti_clk_register_gate(struct ti_clk *setup); struct clk *ti_clk_register_mux(struct ti_clk *setup); +struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup); struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); void ti_clk_patch_legacy_clks(struct ti_clk **patch); diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index b326d27..ff3380e 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -22,6 +22,8 @@ #include #include +#include "clock.h" + #define to_clk_divider(_hw) container_of(_hw, struct clk_divider, hw) #undef pr_fmt @@ -90,63 +92,159 @@ static int omap36xx_gate_clk_enable_with_hsdiv_restore(struct clk_hw *clk) return ret; } -static void __init _of_ti_gate_clk_setup(struct device_node *node, -const struct clk_ops *ops, -const struct clk_hw_omap_ops *hw_ops) +static struct clk *_register_gate(struct device *dev, const char *name, + const char *parent_name, unsigned long flags, + void __iomem *reg, u8 bit_idx, + u8 clk_gate_flags, const struct clk_ops *ops, + const struct clk_hw_omap_ops *hw_ops) { - struct clk *clk; struct clk_init_data init = { NULL }; struct clk_hw_omap *clk_hw; - const char *clk_name = node->name; - const char *parent_name; - u32 val; + struct clk *clk; clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); if (!clk_hw) - return; + return ERR_PTR(-ENOMEM); clk_hw->hw.init = &init; - init.name = clk_name; + init.name = name; init.ops = ops; - if (ops != &omap_gate_clkdm_clk_ops) { - clk_hw->enable_reg = ti_clk_get_reg_addr(node, 0); - if (!clk_hw->enable_reg) - goto cleanup; + clk_hw->enable_reg = reg; + clk_hw->enable_bit = bit_idx; + clk_hw->ops = hw_ops; - if (!of_property_read_u32(node, "ti,bit-shift", &val)) - clk_hw->enable_bit = val; + clk_hw->flags = MEMMAP_ADDRESSING | clk_gate_flags; + + init.parent_names = &parent_name; + init.num_parents = 1; + + init.flags = flags; + + clk = clk_register(NULL, &clk_hw->hw); + + if (IS_ERR(clk)) + kfree(clk_hw); + + return clk; +} + +struct clk *ti_clk_register_gate(struct ti_clk *setup) +{ + const struct clk_ops *ops = &omap_gate_clk_ops; + const struct clk_hw_omap_ops *hw_ops = NULL; + u32 reg; + struct clk_omap_reg *reg_setup; + u32 flags = 0; + u8 clk_gate_flags = 0; + struct ti_clk_gate *gate; + + gate = setup->data; + + reg_setup = (struct clk_omap_reg *)® + + if (gate->flags & CLKF_SET_RATE_PARENT) + flags |= CLK_SET_RATE_PARENT; + + if (gate->flags & CLKF_SET_BIT_TO_DISABLE) + clk_gate_flags |= INVERT_ENABLE; + + if (gate->flags & CLKF_HSDIV) { + ops = &omap_gate_clk_hsdiv_restore_ops; + hw_ops = &clkhwops_wait; } - clk_hw->ops = hw_ops; + if (gate->flags & CLKF_DSS) + hw_ops = &clkhwops_omap3430es2_dss_usbhost_wait; + + if (gate->flags & CLKF_WAIT) + hw_ops = &clkhwops_wait; + + if (gate->flags & CLKF_CLKDM) + ops = &omap_gate_clkdm_clk_ops; + + if (gate->flags & CLKF_AM35XX) + hw_ops = &clkhwops_am35xx_ipss_module_wait; - clk_hw->flags = MEMMAP_ADDRESSING; + reg_setup->index = gate->module; + reg_setup->offset = gate->reg; + + return _register_gate(NULL, setup->name
[PATCH 00/11] ARM: OMAP3: legacy clock data move under clk driver
Hi, These patches move the legacy clock data for omap3 under drivers/clk/ti. After these patches are applied, it should be possible to get rid of clk-private.h (long pending project for Mike.) Testing done (on top of 3.18-rc1): omap3-beagle: boot / suspend-resume (ret/off) / cpuidle (ret/off) omap3-beagle-xm: boot upto fs mount (see note below) sdp3430: boot n900: boot Note: beagle-xm failed with FS mount on the board I have access to, but this happens with clean 3.18-rc1 and linux-next also at the moment. The board has probably corrupted filesystem image but I am unable to fix this atm (remote board.) Test branch: tree: https://github.com/t-kristo/linux-pm.git branch: 3.18-rc1-omap3-clk-rework -Tero -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 02/11] clk: ti: mux: add support for legacy mux init
Legacy clock data is initialized slightly differently compared to DT clocks, thus add support for this. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk.c |3 +++ drivers/clk/ti/clock.h |4 +++ drivers/clk/ti/mux.c | 70 ++-- 3 files changed, 75 insertions(+), 2 deletions(-) diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index a8958f1..215f681 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -211,6 +211,9 @@ struct clk __init *ti_clk_register_clk(struct ti_clk *setup) clk = clk_register_fixed_rate(NULL, setup->name, NULL, CLK_IS_ROOT, fixed->frequency); break; + case TI_CLK_MUX: + clk = ti_clk_register_mux(setup); + break; case TI_CLK_FIXED_FACTOR: fixed_factor = setup->data; diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index 6ee6c6e..c06bbf4 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -153,6 +153,10 @@ struct ti_clk_dpll { u8 recal_st_bit; }; +struct clk *ti_clk_register_mux(struct ti_clk *setup); + +struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup); + void ti_clk_patch_legacy_clks(struct ti_clk **patch); struct clk *ti_clk_register_clk(struct ti_clk *setup); int ti_clk_register_legacy_clks(struct ti_clk_alias *clks); diff --git a/drivers/clk/ti/mux.c b/drivers/clk/ti/mux.c index e9d650e..728e253 100644 --- a/drivers/clk/ti/mux.c +++ b/drivers/clk/ti/mux.c @@ -21,6 +21,7 @@ #include #include #include +#include "clock.h" #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -144,6 +145,39 @@ static struct clk *_register_mux(struct device *dev, const char *name, return clk; } +struct clk *ti_clk_register_mux(struct ti_clk *setup) +{ + struct ti_clk_mux *mux; + u32 flags; + u8 mux_flags = 0; + struct clk_omap_reg *reg_setup; + u32 reg; + u32 mask; + + reg_setup = (struct clk_omap_reg *)® + + mux = setup->data; + flags = CLK_SET_RATE_NO_REPARENT; + + mask = mux->num_parents; + if (!(mux->flags & CLKF_INDEX_STARTS_AT_ONE)) + mask--; + + mask = (1 << fls(mask)) - 1; + reg_setup->index = mux->module; + reg_setup->offset = mux->reg; + + if (mux->flags & CLKF_INDEX_STARTS_AT_ONE) + mux_flags |= CLK_MUX_INDEX_ONE; + + if (mux->flags & CLKF_SET_RATE_PARENT) + flags |= CLK_SET_RATE_PARENT; + + return _register_mux(NULL, setup->name, mux->parents, mux->num_parents, +flags, (void __iomem *)reg, mux->bit_shift, mask, +mux_flags, NULL, NULL); +} + /** * of_mux_clk_setup - Setup function for simple mux rate clock * @node: DT node for the clock @@ -194,8 +228,9 @@ static void of_mux_clk_setup(struct device_node *node) mask = (1 << fls(mask)) - 1; - clk = _register_mux(NULL, node->name, parent_names, num_parents, flags, - reg, shift, mask, clk_mux_flags, NULL, NULL); + clk = _register_mux(NULL, node->name, parent_names, num_parents, + flags, reg, shift, mask, clk_mux_flags, NULL, + NULL); if (!IS_ERR(clk)) of_clk_add_provider(node, of_clk_src_simple_get, clk); @@ -205,6 +240,37 @@ cleanup: } CLK_OF_DECLARE(mux_clk, "ti,mux-clock", of_mux_clk_setup); +struct clk_hw *ti_clk_build_component_mux(struct ti_clk_mux *setup) +{ + struct clk_mux *mux; + struct clk_omap_reg *reg; + int num_parents; + + if (!setup) + return NULL; + + mux = kzalloc(sizeof(*mux), GFP_KERNEL); + if (!mux) + return ERR_PTR(-ENOMEM); + + reg = (struct clk_omap_reg *)&mux->reg; + + mux->shift = setup->bit_shift; + + reg->index = setup->module; + reg->offset = setup->reg; + + if (setup->flags & CLKF_INDEX_STARTS_AT_ONE) + mux->flags |= CLK_MUX_INDEX_ONE; + + num_parents = setup->num_parents; + + mux->mask = num_parents - 1; + mux->mask = (1 << fls(mux->mask)) - 1; + + return &mux->hw; +} + static void __init of_ti_composite_mux_clk_setup(struct device_node *node) { struct clk_mux *mux; -- 1.7.9.5 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 04/11] clk: ti: interface: add support for legacy interface clock init
Legacy clock data is initialized slightly differently compared to DT clocks, thus add support for this. The interface clock descriptor itself is overloading the gate clock descriptor, thus it needs to be called from the gate setup. Signed-off-by: Tero Kristo --- drivers/clk/ti/clock.h |1 + drivers/clk/ti/gate.c |3 ++ drivers/clk/ti/interface.c | 96 +--- 3 files changed, 76 insertions(+), 24 deletions(-) diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h index d0715bc..9430dc6 100644 --- a/drivers/clk/ti/clock.h +++ b/drivers/clk/ti/clock.h @@ -154,6 +154,7 @@ struct ti_clk_dpll { }; struct clk *ti_clk_register_gate(struct ti_clk *setup); +struct clk *ti_clk_register_interface(struct ti_clk *setup); struct clk *ti_clk_register_mux(struct ti_clk *setup); struct clk_hw *ti_clk_build_component_gate(struct ti_clk_gate *setup); diff --git a/drivers/clk/ti/gate.c b/drivers/clk/ti/gate.c index ff3380e..d4f6cb2 100644 --- a/drivers/clk/ti/gate.c +++ b/drivers/clk/ti/gate.c @@ -142,6 +142,9 @@ struct clk *ti_clk_register_gate(struct ti_clk *setup) gate = setup->data; + if (gate->flags & CLKF_INTERFACE) + return ti_clk_register_interface(setup); + reg_setup = (struct clk_omap_reg *)® if (gate->flags & CLKF_SET_RATE_PARENT) diff --git a/drivers/clk/ti/interface.c b/drivers/clk/ti/interface.c index 9c3e8c4..d71cd9b 100644 --- a/drivers/clk/ti/interface.c +++ b/drivers/clk/ti/interface.c @@ -20,6 +20,7 @@ #include #include #include +#include "clock.h" #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -31,53 +32,100 @@ static const struct clk_ops ti_interface_clk_ops = { .is_enabled = &omap2_dflt_clk_is_enabled, }; -static void __init _of_ti_interface_clk_setup(struct device_node *node, - const struct clk_hw_omap_ops *ops) +static struct clk *_register_interface(struct device *dev, const char *name, + const char *parent_name, + void __iomem *reg, u8 bit_idx, + const struct clk_hw_omap_ops *ops) { - struct clk *clk; struct clk_init_data init = { NULL }; struct clk_hw_omap *clk_hw; - const char *parent_name; - u32 val; + struct clk *clk; clk_hw = kzalloc(sizeof(*clk_hw), GFP_KERNEL); if (!clk_hw) - return; + return ERR_PTR(-ENOMEM); clk_hw->hw.init = &init; clk_hw->ops = ops; clk_hw->flags = MEMMAP_ADDRESSING; + clk_hw->enable_reg = reg; + clk_hw->enable_bit = bit_idx; - clk_hw->enable_reg = ti_clk_get_reg_addr(node, 0); - if (!clk_hw->enable_reg) - goto cleanup; - - if (!of_property_read_u32(node, "ti,bit-shift", &val)) - clk_hw->enable_bit = val; - - init.name = node->name; + init.name = name; init.ops = &ti_interface_clk_ops; init.flags = 0; - parent_name = of_clk_get_parent_name(node, 0); - if (!parent_name) { - pr_err("%s must have a parent\n", node->name); - goto cleanup; - } - init.num_parents = 1; init.parent_names = &parent_name; clk = clk_register(NULL, &clk_hw->hw); - if (!IS_ERR(clk)) { - of_clk_add_provider(node, of_clk_src_simple_get, clk); + if (IS_ERR(clk)) + kfree(clk_hw); + else omap2_init_clk_hw_omap_clocks(clk); + + return clk; +} + +struct clk *ti_clk_register_interface(struct ti_clk *setup) +{ + const struct clk_hw_omap_ops *ops = &clkhwops_iclk_wait; + u32 reg; + struct clk_omap_reg *reg_setup; + struct ti_clk_gate *gate; + + gate = setup->data; + reg_setup = (struct clk_omap_reg *)® + reg_setup->index = gate->module; + reg_setup->offset = gate->reg; + + if (gate->flags & CLKF_NO_WAIT) + ops = &clkhwops_iclk; + + if (gate->flags & CLKF_HSOTGUSB) + ops = &clkhwops_omap3430es2_iclk_hsotgusb_wait; + + if (gate->flags & CLKF_DSS) + ops = &clkhwops_omap3430es2_iclk_dss_usbhost_wait; + + if (gate->flags & CLKF_SSI) + ops = &clkhwops_omap3430es2_iclk_ssi_wait; + + if (gate->flags & CLKF_AM35XX) + ops = &clkhwops_am35xx_ipss_wait; + + return _register_interface(NULL, setup->name, gate->parent, + (void __iomem *)reg, gate->bit_shift, ops); +} + +static void __init _of_ti_interface_clk_setup(struct device_node *node, + const struct clk_hw_omap_ops *ops) +{ + struct clk *clk; + const char *parent_name; + void __iomem *reg; + u8 enable_bit = 0; + u32 val; + + reg = ti_clk_get_reg_addr(node, 0); +
[PATCH 01/11] clk: ti: add core support for initializing legacy clocks
Legacy clock data for OMAP3 is being moved under clock driver, thus base support for this is needed. This patch adds basic definitions for clock init descriptors and core infrastructure for initialization, which will be called from the OMAP3 clock init. Signed-off-by: Tero Kristo --- drivers/clk/ti/clk.c | 110 + drivers/clk/ti/clock.h | 160 2 files changed, 270 insertions(+) create mode 100644 drivers/clk/ti/clock.h diff --git a/drivers/clk/ti/clk.c b/drivers/clk/ti/clk.c index 337abe5..a8958f1 100644 --- a/drivers/clk/ti/clk.c +++ b/drivers/clk/ti/clk.c @@ -22,6 +22,8 @@ #include #include +#include "clock.h" + #undef pr_fmt #define pr_fmt(fmt) "%s: " fmt, __func__ @@ -183,3 +185,111 @@ void ti_dt_clk_init_retry_clks(void) retries--; } } + +void __init ti_clk_patch_legacy_clks(struct ti_clk **patch) +{ + while (*patch) { + memcpy((*patch)->patch, *patch, sizeof(**patch)); + patch++; + } +} + +struct clk __init *ti_clk_register_clk(struct ti_clk *setup) +{ + struct clk *clk; + struct ti_clk_fixed *fixed; + struct ti_clk_fixed_factor *fixed_factor; + struct clk_hw *clk_hw; + + if (setup->clk) + return setup->clk; + + switch (setup->type) { + case TI_CLK_FIXED: + fixed = setup->data; + + clk = clk_register_fixed_rate(NULL, setup->name, NULL, + CLK_IS_ROOT, fixed->frequency); + break; + case TI_CLK_FIXED_FACTOR: + fixed_factor = setup->data; + + clk = clk_register_fixed_factor(NULL, setup->name, + fixed_factor->parent, + 0, fixed_factor->mult, + fixed_factor->div); + break; + default: + pr_err("bad type for %s!\n", setup->name); + clk = ERR_PTR(-EINVAL); + } + + if (!IS_ERR(clk)) { + setup->clk = clk; + if (setup->clkdm_name) { + if (__clk_get_flags(clk) & CLK_IS_BASIC) { + pr_warn("can't setup clkdm for basic clk %s\n", + setup->name); + } else { + clk_hw = __clk_get_hw(clk); + to_clk_hw_omap(clk_hw)->clkdm_name = + setup->clkdm_name; + omap2_init_clk_clkdm(clk_hw); + } + } + } + + return clk; +} + +int __init ti_clk_register_legacy_clks(struct ti_clk_alias *clks) +{ + struct clk *clk; + bool retry; + struct ti_clk_alias *retry_clk; + struct ti_clk_alias *tmp; + + while (clks->clk) { + clk = ti_clk_register_clk(clks->clk); + if (IS_ERR(clk)) { + if (PTR_ERR(clk) == -EAGAIN) { + list_add(&clks->link, &retry_list); + } else { + pr_err("register for %s failed: %ld\n", + clks->clk->name, PTR_ERR(clk)); + return PTR_ERR(clk); + } + } else { + clks->lk.clk = clk; + clkdev_add(&clks->lk); + } + clks++; + } + + retry = true; + + while (!list_empty(&retry_list) && retry) { + retry = false; + list_for_each_entry_safe(retry_clk, tmp, &retry_list, link) { + pr_debug("retry-init: %s\n", retry_clk->clk->name); + clk = ti_clk_register_clk(retry_clk->clk); + if (IS_ERR(clk)) { + if (PTR_ERR(clk) == -EAGAIN) { + continue; + } else { + pr_err("register for %s failed: %ld\n", + retry_clk->clk->name, + PTR_ERR(clk)); + return PTR_ERR(clk); + } + } else { + retry = true; + retry_clk->lk.clk = clk; + clkdev_add(&retry_clk->lk); + list_del(&retry_clk->link); + } + } + } + + return 0; +} diff --git a/drivers/clk/ti/clock.h b/drivers/clk/ti/clock.h new file mode 100644 index 000..6ee6c6e --- /dev/null +++ b/drivers/clk/ti/clock.h @@ -0,0 +1,160 @@ +/* + * TI Clock driver int
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
On Tue, Dec 16, 2014 at 05:05:08PM +0530, Lokesh Vutla wrote: > Is this applicable for OMAP5 also? > If not can you drop omap5 from $subject? DRA7xx = OMAP57xx, which to me is an omap5. Isn't it? And I haven't been able to get a manual for the omap54xx to confirm it, although it seems it does not apply to the omap54xx from what I have been able to gather indirectly. arch_timer_freq = (rate / den) * num; If I do this with the workaround I get: 2000 / 75 * 244 = 6147525 where as 2000 * 244 / 75 = 6147540 best value would be 6147541 with proper rounding. In the normal case the worst case is: 2600 * 384 = 998400 That is too big for 32 bits. Now what could be done is prescale by 4 to make the worst case still fit in 32 bits while doing the multiplication before the division, so like this: arch_timer_freq = ((rate / 4) * num / den ) * 4; That gives the same result in all cases including the errata case for the dra7xx at 20MHz and 27MHz. It is off by 3 in the 19.2MHz case though which isn't so nice. Would that be more acceptable? I think having the arch_timer_freq calculated for the errata case seperately from the normal case is cleaner looking compared to that mess and gives a better result for the 19.2MHz case. -- Len Sorensen -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/6] Touchscreen performance related fixes
On Tue, Dec 16, 2014 at 10:31:47AM +0200, Catalin Crenguta wrote: > > It seems that because the ribbon cable has both the analog and digital > signals, the analog signals are affected by the digital ones (hence > the touchscreen was working OK when the display was disabled). Putting > decoupling capacitors on X+, X-, Y+, Y- reduces the noise and the > false events disappear. IOW, the root cause is a design flaw in the BB-View 4.3 Cape? Thanks, Richard -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
On 17:05-20141216, Lokesh Vutla wrote: [...] > > @@ -545,6 +546,16 @@ static void __init realtime_counter_init(void) > break; > } > > + if (soc_is_dra7xx()) { > + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); > + reg = reg & DRA7_SPEEDSELECT_MASK; > + > + if (reg) { > + num = 75; > + den = 244; > + } > + } > + > /* Program numerator and denumerator registers */ > reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & > NUMERATOR_DENUMERATOR_MASK; A) So, it does look like the 32k node is actually wrong then -> Tero: any comments? should'nt this now be modeled based on CTRL_CORE_BOOTSTRAP::SPEEDSELECT considering that clock nodes do have clk mux options based on the 32k.. sys_32k_ck: sys_32k_ck { #clock-cells = <0>; compatible = "fixed-clock"; clock-frequency = <32768>; }; B) Since rate switch is no longer needed, how about something like the following: diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a3c0133..315d6d1 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -286,6 +286,11 @@ #define OMAP5XXX_CONTROL_STATUS0x134 #define OMAP5_DEVICETYPE_MASK (0x7 << 6) + +/* DRA7XX CONTROL CORE BOOTSTRAP */ +#define DRA7_CTRL_CORE_BOOTSTRAP 0x6c4 +#define DRA7_SPEEDSELECT_MASK (0x3 << 8) + /* * REVISIT: This list of registers is not comprehensive - there are more * that should be added. diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index 4f61148..783d3c3 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -54,6 +54,7 @@ #include "soc.h" #include "common.h" +#include "control.h" #include "powerdomain.h" #include "omap-secure.h" @@ -511,6 +512,35 @@ static void __init realtime_counter_init(void) } rate = clk_get_rate(sys_clk); + + if (soc_is_dra7xx()) { + /* +* Errata i856 says the 32.768KHz crystal does not start at +* power on, so the CPU falls back in an emulated 32KHz clock +* based on sysclk / 610 instead. This causes the master counter +* frequency to not be 6.144MHz but at sysclk / 610 * 375 / 2 +* (OR sysclk * 75 / 244) +* +* This affects at least the DRA7/AM572x 1.0, 1.1 revisions. +* Of course any board built without a populated 32.768KHz +* crystal would also need this fix even if the CPU is fixed +* later. +* +* Either case can be detected by using the two speedselect bits +* If they are not 0, then the 32.768KHz clock driving the +* course counter that corrects the fine counter every time it +* ticks is actually rate/610 rather than 32.768KHz and we +* should compensate to avoid the 570ppm (At 20MHz, much worse +* at other rates) too fast system time. +*/ + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); + if (reg & DRA7_SPEEDSELECT_MASK) { + num = 75; + den = 244; + goto sysclk_based; + } + } + /* Numerator/denumerator values refer TRM Realtime Counter section */ switch (rate) { case 120: @@ -545,6 +575,7 @@ static void __init realtime_counter_init(void) break; } +sysclk_based: /* Program numerator and denumerator registers */ reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & NUMERATOR_DENUMERATOR_MASK; -- Regards, Nishanth Menon -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ARM: omap5/dra7xx: Fix frequency typos.
On 12/12/2014 04:08 PM, Lennart Sorensen wrote: > The switch statement of the possible list of SYSCLK1 frequencies is > missing a 0 in 4 out of the 7 frequencies. > > Signed-off-by: Len Sorensen > --- > arch/arm/mach-omap2/timer.c |8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c > index 4f61148..fb0cb2b 100644 > --- a/arch/arm/mach-omap2/timer.c > +++ b/arch/arm/mach-omap2/timer.c > @@ -513,11 +513,11 @@ static void __init realtime_counter_init(void) > rate = clk_get_rate(sys_clk); > /* Numerator/denumerator values refer TRM Realtime Counter section */ > switch (rate) { > - case 120: > + case 1200: > num = 64; > den = 125; > break; > - case 130: > + case 1300: > num = 768; > den = 1625; > break; > @@ -529,11 +529,11 @@ static void __init realtime_counter_init(void) > num = 192; > den = 625; > break; > - case 260: > + case 2600: > num = 384; > den = 1625; > break; > - case 270: > + case 2700: > num = 256; > den = 1125; > break; > Also please add: Fixes: fa6d79d27614 ("ARM: OMAP: Add initialisation for the real-time counter") With that, Acked-by: Nishanth Menon -- Regards, Nishanth Menon -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] ARM: omap5/dra7xx: Fix frequency typos.
Hi Len, On Saturday 13 December 2014 03:38 AM, Lennart Sorensen wrote: > The switch statement of the possible list of SYSCLK1 frequencies is > missing a 0 in 4 out of the 7 frequencies. Indeed a good catch !! Reviewed-by: Lokesh Vutla Thanks and regards, Lokesh > > Signed-off-by: Len Sorensen > --- > arch/arm/mach-omap2/timer.c |8 > 1 file changed, 4 insertions(+), 4 deletions(-) > > diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c > index 4f61148..fb0cb2b 100644 > --- a/arch/arm/mach-omap2/timer.c > +++ b/arch/arm/mach-omap2/timer.c > @@ -513,11 +513,11 @@ static void __init realtime_counter_init(void) > rate = clk_get_rate(sys_clk); > /* Numerator/denumerator values refer TRM Realtime Counter section */ > switch (rate) { > - case 120: > + case 1200: > num = 64; > den = 125; > break; > - case 130: > + case 1300: > num = 768; > den = 1625; > break; > @@ -529,11 +529,11 @@ static void __init realtime_counter_init(void) > num = 192; > den = 625; > break; > - case 260: > + case 2600: > num = 384; > den = 1625; > break; > - case 270: > + case 2700: > num = 256; > den = 1125; > break; > -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/2] ARM: omap5/dra7xx: Fix counter frequency drift for AM572x errata i856.
Hi Lennart, On Sunday 14 December 2014 10:15 AM, Lennart Sorensen wrote: > On Fri, Dec 12, 2014 at 05:08:56PM -0500, Lennart Sorensen wrote: >> Errata i856 for the AM572x (DRA7xx) points out that the 32.768KHz external >> crystal is not enabled at power up. Instead the CPU falls back to using >> an emulation for the 32KHz clock which is SYSCLK1/610. SYSCLK1 is usually >> 20MHz on boards so far (which gives an emulated frequency of 32.786KHz), >> but can also be 19.2 or 27MHz which result in much larger drift. >> >> Since this is used to drive the master counter at 32.768KHz * 375 / >> 2 = 6.144MHz, the emulated speed for 20MHz is of by 570ppm, or about 43 >> seconds per day, and more than the 500ppm NTP is able to tolerate. >> >> Checking the CTRL_CORE_BOOTSTRAP register can determine if the CPU >> is using the real 32.768KHz crystal or the emulated SYSCLK1/610, and >> by known that the real counter frequency can be determined and used. > s/known/knowing/ > and a comma after that. >> The real speed is then SYSCLK1 / 610 * 375 / 2 or SYSCLK1 * 75 / 244. Is this applicable for OMAP5 also? If not can you drop omap5 from $subject? In order to make the code more simpler, can you use the following logic: and add documentation accordingly. diff --git a/arch/arm/mach-omap2/control.h b/arch/arm/mach-omap2/control.h index a3c0133..a80ac2d 100644 --- a/arch/arm/mach-omap2/control.h +++ b/arch/arm/mach-omap2/control.h @@ -286,6 +286,10 @@ #define OMAP5XXX_CONTROL_STATUS0x134 #define OMAP5_DEVICETYPE_MASK (0x7 << 6) +/* DRA7XX CONTROL CORE BOOTSTRAP */ +#define DRA7_CTRL_CORE_BOOTSTRAP 0x6c4 +#define DRA7_SPEEDSELECT_MASK (0x3 << 8) + /* * REVISIT: This list of registers is not comprehensive - there are more * that should be added. diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c index fb0cb2b..84aadae 100644 --- a/arch/arm/mach-omap2/timer.c +++ b/arch/arm/mach-omap2/timer.c @@ -54,6 +54,7 @@ #include "soc.h" #include "common.h" +#include "control.h" #include "powerdomain.h" #include "omap-secure.h" @@ -545,6 +546,16 @@ static void __init realtime_counter_init(void) break; } + if (soc_is_dra7xx()) { + reg = omap_ctrl_readl(DRA7_CTRL_CORE_BOOTSTRAP); + reg = reg & DRA7_SPEEDSELECT_MASK; + + if (reg) { + num = 75; + den = 244; + } + } + /* Program numerator and denumerator registers */ reg = readl_relaxed(base + INCREMENTER_NUMERATOR_OFFSET) & NUMERATOR_DENUMERATOR_MASK; -- 1.9.1 Thanks and regards, Lokesh >> >> Signed-off-by: Len Sorensen >> --- >> arch/arm/mach-omap2/timer.c | 120 >> +++ >> 1 file changed, 87 insertions(+), 33 deletions(-) >> >> diff --git a/arch/arm/mach-omap2/timer.c b/arch/arm/mach-omap2/timer.c >> index fb0cb2b..f00e4b4 100644 >> --- a/arch/arm/mach-omap2/timer.c >> +++ b/arch/arm/mach-omap2/timer.c >> @@ -497,6 +497,7 @@ static void __init realtime_counter_init(void) >> static struct clk *sys_clk; >> unsigned long rate; >> unsigned int reg, num, den; >> +bool errata_i856_workaround = false; >> >> base = ioremap(REALTIME_COUNTER_BASE, SZ_32); >> if (!base) { >> @@ -510,39 +511,93 @@ static void __init realtime_counter_init(void) >> return; >> } >> >> +if (soc_is_dra7xx()) { >> +#define CTRL_CORE_BOOTSTRAP 0x4A0026C4 >> +#define SPEEDSELECT_MASK 0x0300 >> +void __iomem *corebase; >> +corebase = ioremap(CTRL_CORE_BOOTSTRAP, SZ_4); >> +if (!corebase) >> +pr_err("%s: ioremap failed\n", __func__); >> +else { >> +reg = readl_relaxed(corebase) & SPEEDSELECT_MASK; >> +iounmap(corebase); >> +/* >> + * Errata i856 says the 32.768KHz crystal does >> + * not start at power on, so the CPU falls back in >> + * an emulated 32KHz clock instead. This causes >> + * the master counter frequency to not be 6.144MHz >> + * This affects at least the AM572x 1.0 and >> + * 1.1 revisions. >> + * >> + * Of course any board built without a populated >> + * 32.768KHz crystal would also need this fix >> + * even if the CPU is fixed later. >> + * >> + * If the two speedselect bits are not 0, then the >> + * 32.768KHz clock driving the course counter that > s/course/coarse/ >> + * corrects the fine counter every time it ticks is >> + * actually rate/610 rather than 32.768KHz and we >> + * should compensa
[PATCH 0/2] PCIe related fixes for DRA7xx
This patch fix inconsistent enumeration of PCIe gen2 cards on DRA7xx boards. Tested this patch series, after applying some out of the tree patches for resetting PCIe. Vignesh R (2): phy: phy-ti-pipe3: fix inconsistent enumeration of PCIe gen2 cards ARM: dts: DRA7X: drop id property in pcie_phy arch/arm/boot/dts/dra7.dtsi | 2 -- drivers/phy/phy-omap-control.c | 7 +++ drivers/phy/phy-ti-pipe3.c | 10 ++ include/linux/phy/omap_control_phy.h | 6 +++--- 4 files changed, 12 insertions(+), 13 deletions(-) -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] phy: phy-ti-pipe3: fix inconsistent enumeration of PCIe gen2 cards
Prior to DRA74x silicon rev 1.1, pcie_pcs register bits 8-15 and bits 16-23 were used to configure RC delay count for phy1 and phy2 respectively. phyid was used as index to distinguish the phys and to configure the delay values appropriately. As of DRA74x silicon rev 1.1, pcie_pcs register definition has changed. Bits 16-23 are used to configure delay values for *both* phy1 and phy2. Hence phyid is no longer required. So, drop id field from ti_pipe3 structure and its subsequent references for configuring pcie_pcs register. Also, pcie_pcs register now needs to be configured with delay value of 0x96 at bit positions 16-23. See register description of CTRL_CORE_PCIE_PCS in ARM572x TRM, SPRUHZ6, October 2014, section 18.5.2.2, table 18-1804. This is needed to ensure Gen2 cards are enumerated consistently. DRA72x silicon behaves same way as DRA74x rev 1.1 as far as this functionality is considered. Test results on DRA74x and DRA72x EVMs: Before patch DRA74x ES 1.0: Gen1 cards work, Gen2 cards do not work (expected result due to silicon errata) DRA74x ES 1.1: Gen1 cards work, Gen2 cards do not work sometimes due to incorrect programming of register DRA72x: Gen1 cards work, Gen2 cards do not work sometimes due to incorrect programming of register After patch --- DRA74x ES 1.0: Gen1 cards work, Gen2 cards do not work (expected result due to silicon errata) DRA74x ES 1.1: Gen1 cards work, Gen2 cards work consistently. DRA72x: Gen1 and Gen2 cards enumerate consistently. Signed-off-by: Vignesh R --- drivers/phy/phy-omap-control.c | 7 +++ drivers/phy/phy-ti-pipe3.c | 10 ++ include/linux/phy/omap_control_phy.h | 6 +++--- 3 files changed, 12 insertions(+), 11 deletions(-) diff --git a/drivers/phy/phy-omap-control.c b/drivers/phy/phy-omap-control.c index c96e8183a8ff..efe724f97e02 100644 --- a/drivers/phy/phy-omap-control.c +++ b/drivers/phy/phy-omap-control.c @@ -29,10 +29,9 @@ /** * omap_control_pcie_pcs - set the PCS delay count * @dev: the control module device - * @id: index of the pcie PHY (should be 1 or 2) * @delay: 8 bit delay value */ -void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) +void omap_control_pcie_pcs(struct device *dev, u8 delay) { u32 val; struct omap_control_phy *control_phy; @@ -55,8 +54,8 @@ void omap_control_pcie_pcs(struct device *dev, u8 id, u8 delay) val = readl(control_phy->pcie_pcs); val &= ~(OMAP_CTRL_PCIE_PCS_MASK << - (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT)); - val |= delay << (id * OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); + OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); + val |= (delay << OMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT); writel(val, control_phy->pcie_pcs); } EXPORT_SYMBOL_GPL(omap_control_pcie_pcs); diff --git a/drivers/phy/phy-ti-pipe3.c b/drivers/phy/phy-ti-pipe3.c index c297b7a10d30..4f31f2be4b5e 100644 --- a/drivers/phy/phy-ti-pipe3.c +++ b/drivers/phy/phy-ti-pipe3.c @@ -82,7 +82,6 @@ struct ti_pipe3 { struct clk *refclk; struct clk *div_clk; struct pipe3_dpll_map *dpll_map; - u8 id; }; static struct pipe3_dpll_map dpll_map_usb[] = { @@ -217,8 +216,13 @@ static int ti_pipe3_init(struct phy *x) u32 val; int ret = 0; + /* +* Set pcie_pcs register to 0x96 for proper functioning of phy +* as recommended in AM572x TRM SPRUHZ6, section 18.5.2.2, table +* 18-1804. +*/ if (of_device_is_compatible(phy->dev->of_node, "ti,phy-pipe3-pcie")) { - omap_control_pcie_pcs(phy->control_dev, phy->id, 0xF1); + omap_control_pcie_pcs(phy->control_dev, 0x96); return 0; } @@ -347,8 +351,6 @@ static int ti_pipe3_probe(struct platform_device *pdev) } if (of_device_is_compatible(node, "ti,phy-pipe3-pcie")) { - if (of_property_read_u8(node, "id", &phy->id) < 0) - phy->id = 1; clk = devm_clk_get(phy->dev, "dpll_ref"); if (IS_ERR(clk)) { diff --git a/include/linux/phy/omap_control_phy.h b/include/linux/phy/omap_control_phy.h index e9e6cfbfbb58..eb7d4a135a9e 100644 --- a/include/linux/phy/omap_control_phy.h +++ b/include/linux/phy/omap_control_phy.h @@ -66,7 +66,7 @@ enum omap_control_usb_mode { #defineOMAP_CTRL_PIPE3_PHY_TX_RX_POWEROFF 0x0 #defineOMAP_CTRL_PCIE_PCS_MASK 0xff -#defineOMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT0x8 +#defineOMAP_CTRL_PCIE_PCS_DELAY_COUNT_SHIFT16 #define OMAP_CTRL_USB2_PHY_PD BIT(28) @@ -79,7 +79,7 @@ enum omap_control_usb_mode { void omap_control_phy_power(struct device *dev, int on); void omap_control_usb_set_mode(struct device *dev, enum omap_control_usb_mode mode); -void omap_control_pcie_pcs(struct device *dev, u8 id
[PATCH 2/2] ARM: dts: DRA7X: drop id property in pcie_phy
Since phyid is no longer used by pcie driver, this field can be dropped from the DT. Signed-off-by: Vignesh R --- arch/arm/boot/dts/dra7.dtsi | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/arm/boot/dts/dra7.dtsi b/arch/arm/boot/dts/dra7.dtsi index 63bf99be1762..889e3023e68f 100644 --- a/arch/arm/boot/dts/dra7.dtsi +++ b/arch/arm/boot/dts/dra7.dtsi @@ -,7 +,6 @@ "wkupclk", "refclk", "div-clk", "phy-div"; #phy-cells = <0>; - id = <1>; ti,hwmods = "pcie1-phy"; }; @@ -1132,7 +1131,6 @@ "div-clk", "phy-div"; #phy-cells = <0>; ti,hwmods = "pcie2-phy"; - id = <2>; status = "disabled"; }; }; -- 1.9.1 -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] usb: host: f_usb20ho: add support for Fujitsu ehci/ohci USB 2.0 host controller
On Tuesday 16 December 2014 10:10:26 Sneeker Yeh wrote: > This patch adds support for EHCI compliant Host controller found > on Fujitsu Socs. > > Signed-off-by: Sneeker Yeh > --- > .../devicetree/bindings/usb/fujitsu-ehci.txt | 22 ++ > drivers/usb/host/Kconfig | 11 + > drivers/usb/host/Makefile |1 + > drivers/usb/host/f_usb20ho_hcd.c | 306 > > drivers/usb/host/f_usb20ho_hcd.h | 35 +++ > 5 files changed, 375 insertions(+) > create mode 100644 Documentation/devicetree/bindings/usb/fujitsu-ehci.txt > create mode 100644 drivers/usb/host/f_usb20ho_hcd.c > create mode 100644 drivers/usb/host/f_usb20ho_hcd.h > > diff --git a/Documentation/devicetree/bindings/usb/fujitsu-ehci.txt > b/Documentation/devicetree/bindings/usb/fujitsu-ehci.txt > new file mode 100644 > index 000..e180860 > --- /dev/null > +++ b/Documentation/devicetree/bindings/usb/fujitsu-ehci.txt > @@ -0,0 +1,22 @@ > +FUJITSU GLUE COMPONENTS > + > +MB86S7x EHCI GLUE > + - compatible : Should be "fujitsu,f_usb20ho_hcd" Please try to use the binding from Documentation/devicetree/bindings/usb/usb-ehci.txt and the respective ohci binding first, and use two separate devic enodes. > + - reg : Address and length of the register set for the device. > + - interrupts : The irq number of this device that is used to interrupt the > + CPU > + - clocks: from common clock binding, handle to usb clock. > + - clock-names: from common clock binding. You should always document the specific strings for a named property. > + - #stream-id-cells : handle to use "arm,mmu-400" ARM IOMMU driver Don't use that binding, we are trying to kill that off. Instead, use an 'iommus' property. > + hci_res[0].start = ohci ? resource->start + F_OHCI_OFFSET : > + resource->start + F_EHCI_OFFSET; > + hci_res[0].end = ohci ? > + resource->start + F_OHCI_OFFSET + F_OHCI_SIZE - 1 : > + resource->start + F_EHCI_OFFSET + F_EHCI_SIZE - 1; > + hci_res[0].flags = IORESOURCE_MEM; > + > + hci_res[1].start = irq; > + hci_res[1].flags = IORESOURCE_IRQ; > + > + hci_dev = platform_device_alloc(ohci ? "ohci-platform" : > + "ehci-platform", 0); > + if (!hci_dev) { > + dev_err(&pdev->dev, "platform_device_alloc() failed\n"); > + ret = -ENODEV; > + goto err_res; > + } No need for playing games with child devices, just see how the other drivers do it. > + ret = platform_device_add(hci_dev); > + if (ret) { > + dev_err(&pdev->dev, "platform_device_add() failed\n"); > + goto err_alloc; > + } > + > + return hci_dev; > + > +err_alloc: > + platform_device_put(hci_dev); > +err_res: > + return ERR_PTR(ret); > +} > + > +static u64 f_usb20ho_dma_mask = DMA_BIT_MASK(32); The dma mask should come from the dma-ranges property of the parent bus, as of_platform_populate now does. Arnd -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/6] Touchscreen performance related fixes
On Fri, Dec 12, 2014 at 4:16 PM, Griffis, Brad wrote: > How are you configuring ti,charge-delay in your dts? I've seen this behavior > on some custom boards where we were using a smaller charge delay (0x400) to > begin with, and by upping it to 0xb000 we resolved the issue. These patches > however already specified ti,charge-delay = 0xb000 by default so this would > surprise me that it's still seeing that issue. Was the touchscreen working > as expected before these new patches, or does it have issues both ways? It seems that because the ribbon cable has both the analog and digital signals, the analog signals are affected by the digital ones (hence the touchscreen was working OK when the display was disabled). Putting decoupling capacitors on X+, X-, Y+, Y- reduces the noise and the false events disappear. I'm sorry for all the noise I have generated. Best regards, -- To unsubscribe from this list: send the line "unsubscribe linux-omap" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html