[meta-ti] [PATCH] linux 3.0: Fix sprz319 erratum 2.1

Denys Dmytriyenko denis at denix.org
Mon Mar 19 11:35:35 PDT 2012


On Mon, Mar 19, 2012 at 07:16:08PM +0100, Koen Kooi wrote:
> Signed-off-by: Koen Kooi <koen at dominion.thruhere.net>

This is a good one, thanks! Pushed to master.

> ---
>  recipes-kernel/linux/linux-3.0/patch.sh            |    2 +-
>  .../usb/0001-Fix-sprz319-erratum-2.1.patch         |  210 ++++++++++++++++++++
>  recipes-kernel/linux/linux_3.0.bb                  |    4 +-
>  3 files changed, 214 insertions(+), 2 deletions(-)
>  create mode 100644 recipes-kernel/linux/linux-3.0/usb/0001-Fix-sprz319-erratum-2.1.patch
> 
> diff --git a/recipes-kernel/linux/linux-3.0/patch.sh b/recipes-kernel/linux/linux-3.0/patch.sh
> index dc19a9e..31bdfe1 100755
> --- a/recipes-kernel/linux/linux-3.0/patch.sh
> +++ b/recipes-kernel/linux/linux-3.0/patch.sh
> @@ -13,7 +13,7 @@ git reset --hard ${TAG}
>  rm export -rf
>  
>  previous=${TAG}
> -PATCHSET="pm-wip/voltdm pm-wip/cpufreq beagle madc sakoman sgx ulcd omap4 misc"
> +PATCHSET="pm-wip/voltdm pm-wip/cpufreq beagle madc sakoman sgx ulcd omap4 misc usb"
>  
>  # apply patches
>  for patchset in ${PATCHSET} ; do
> diff --git a/recipes-kernel/linux/linux-3.0/usb/0001-Fix-sprz319-erratum-2.1.patch b/recipes-kernel/linux/linux-3.0/usb/0001-Fix-sprz319-erratum-2.1.patch
> new file mode 100644
> index 0000000..8d65b5f
> --- /dev/null
> +++ b/recipes-kernel/linux/linux-3.0/usb/0001-Fix-sprz319-erratum-2.1.patch
> @@ -0,0 +1,210 @@
> +From cf5db5477d8d43f02f4511f3835ab4bec0dcc27c Mon Sep 17 00:00:00 2001
> +From: Richard Watts <rrw at kynesim.co.uk>
> +Date: Mon, 20 Feb 2012 17:58:26 +0000
> +Subject: [PATCH] Fix sprz319 erratum 2.1
> +
> +There is an erratum in DM3730 which results in the
> +EHCI USB PLL (DPLL5) not updating sufficiently frequently; this
> +leads to USB PHY clock drift and once the clock has drifted far
> +enough, the PHY's ULPI interface stops responding and USB
> +drops out. This is manifested on a Beagle xM by having the attached
> +SMSC9514 report 'Cannot enable port 2. Maybe the USB cable is bad?'
> +or similar.
> +
> +The fix is to carefully adjust your DPLL5 settings so as to
> +keep the PHY clock as close as possible to 120MHz over the long
> +term; TI SPRZ319e gives a table of such settings and this patch
> +applies that table to systems with a 13MHz or a 26MHz clock,
> +thus fixing the issue (inasfar as it can be fixed) on Beagle xM
> +and Overo Firestorm.
> +
> +Signed-off-by: Richard Watts <rrw at kynesim.co.uk>
> +---
> + arch/arm/mach-omap2/clkt_clksel.c    |   15 ++++++++
> + arch/arm/mach-omap2/clock.h          |    7 ++++
> + arch/arm/mach-omap2/clock3xxx.c      |   65 +++++++++++++++++++++++++++++----
> + arch/arm/mach-omap2/clock3xxx.h      |    1 +
> + arch/arm/mach-omap2/clock3xxx_data.c |    2 +-
> + arch/arm/mach-omap2/dpll3xxx.c       |    2 +-
> + 6 files changed, 82 insertions(+), 10 deletions(-)
> +
> +diff --git a/arch/arm/mach-omap2/clkt_clksel.c b/arch/arm/mach-omap2/clkt_clksel.c
> +index e25364d..e378fe7 100644
> +--- a/arch/arm/mach-omap2/clkt_clksel.c
> ++++ b/arch/arm/mach-omap2/clkt_clksel.c
> +@@ -460,6 +460,21 @@ int omap2_clksel_set_rate(struct clk *clk, unsigned long rate)
> + 	return 0;
> + }
> + 
> ++int omap2_clksel_force_divisor(struct clk *clk, int new_div)
> ++{
> ++	u32 field_val;
> ++
> ++	field_val = _divisor_to_clksel(clk, new_div);
> ++	if (field_val == ~0)
> ++		return -EINVAL;
> ++
> ++	_write_clksel_reg(clk, field_val);
> ++
> ++	clk->rate = clk->parent->rate / new_div;
> ++
> ++	return 0;
> ++}
> ++
> + /*
> +  * Clksel parent setting function - not passed in struct clk function
> +  * pointer - instead, the OMAP clock code currently assumes that any
> +diff --git a/arch/arm/mach-omap2/clock.h b/arch/arm/mach-omap2/clock.h
> +index 8bad1c6..ac3d367 100644
> +--- a/arch/arm/mach-omap2/clock.h
> ++++ b/arch/arm/mach-omap2/clock.h
> +@@ -61,6 +61,12 @@ void omap3_dpll_allow_idle(struct clk *clk);
> + void omap3_dpll_deny_idle(struct clk *clk);
> + u32 omap3_dpll_autoidle_read(struct clk *clk);
> + int omap3_noncore_dpll_set_rate(struct clk *clk, unsigned long rate);
> ++#if CONFIG_ARCH_OMAP3
> ++int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel);
> ++/* If you are using this function and not on OMAP3, you are
> ++ * Doing It Wrong(tm), so there is no stub.
> ++ */
> ++#endif
> + int omap3_noncore_dpll_enable(struct clk *clk);
> + void omap3_noncore_dpll_disable(struct clk *clk);
> + int omap4_dpllmx_gatectrl_read(struct clk *clk);
> +@@ -84,6 +90,7 @@ unsigned long omap2_clksel_recalc(struct clk *clk);
> + long omap2_clksel_round_rate(struct clk *clk, unsigned long target_rate);
> + int omap2_clksel_set_rate(struct clk *clk, unsigned long rate);
> + int omap2_clksel_set_parent(struct clk *clk, struct clk *new_parent);
> ++int omap2_clksel_force_divisor(struct clk *clk, int new_div);
> + 
> + /* clkt_iclk.c public functions */
> + extern void omap2_clkt_iclk_allow_idle(struct clk *clk);
> +diff --git a/arch/arm/mach-omap2/clock3xxx.c b/arch/arm/mach-omap2/clock3xxx.c
> +index 952c3e0..d5be086 100644
> +--- a/arch/arm/mach-omap2/clock3xxx.c
> ++++ b/arch/arm/mach-omap2/clock3xxx.c
> +@@ -40,6 +40,60 @@
> + /* needed by omap3_core_dpll_m2_set_rate() */
> + struct clk *sdrc_ick_p, *arm_fck_p;
> + 
> ++struct dpll_settings {
> ++	int rate, m, n, f;
> ++};
> ++
> ++
> ++static int omap3_dpll5_apply_erratum21(struct clk *clk, struct clk *dpll5_m2)
> ++{
> ++	struct clk *sys_clk;
> ++	int i, rv;
> ++	static const struct dpll_settings precomputed[] = {
> ++		/* From DM3730 errata (sprz319e), table 36
> ++		* +1 is because the values in the table are register values;
> ++		* dpll_program() will subtract one from what we give it,
> ++		* so ...
> ++		*/
> ++		{ 13000000, 443+1, 5+1, 8 },
> ++		{ 26000000, 443+1, 11+1, 8 }
> ++	};
> ++
> ++	sys_clk = clk_get(NULL, "sys_ck");
> ++
> ++	for (i = 0 ; i < (sizeof(precomputed)/sizeof(struct dpll_settings)) ;
> ++		++i) {
> ++		const struct dpll_settings *d = &precomputed[i];
> ++		if (sys_clk->rate == d->rate) {
> ++			rv =  omap3_noncore_dpll_program(clk, d->m , d->n, 0);
> ++			if (rv)
> ++				return 1;
> ++			rv =  omap2_clksel_force_divisor(dpll5_m2 , d->f);
> ++			return 1;
> ++		}
> ++	}
> ++	return 0;
> ++}
> ++
> ++int omap3_dpll5_set_rate(struct clk *clk, unsigned long rate)
> ++{
> ++	struct clk *dpll5_m2;
> ++	int rv;
> ++	dpll5_m2 = clk_get(NULL, "dpll5_m2_ck");
> ++
> ++	if (cpu_is_omap3630() && rate == DPLL5_FREQ_FOR_USBHOST &&
> ++		omap3_dpll5_apply_erratum21(clk, dpll5_m2)) {
> ++		return 1;
> ++	}
> ++	rv = omap3_noncore_dpll_set_rate(clk, rate);
> ++	if (rv)
> ++		goto out;
> ++	rv = clk_set_rate(dpll5_m2, rate);
> ++
> ++out:
> ++	return rv;
> ++}
> ++
> + int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
> + {
> + 	/*
> +@@ -59,19 +113,14 @@ int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate)
> + void __init omap3_clk_lock_dpll5(void)
> + {
> + 	struct clk *dpll5_clk;
> +-	struct clk *dpll5_m2_clk;
> + 
> + 	dpll5_clk = clk_get(NULL, "dpll5_ck");
> + 	clk_set_rate(dpll5_clk, DPLL5_FREQ_FOR_USBHOST);
> +-	clk_enable(dpll5_clk);
> + 
> +-	/* Program dpll5_m2_clk divider for no division */
> +-	dpll5_m2_clk = clk_get(NULL, "dpll5_m2_ck");
> +-	clk_enable(dpll5_m2_clk);
> +-	clk_set_rate(dpll5_m2_clk, DPLL5_FREQ_FOR_USBHOST);
> ++	/* dpll5_m2_ck is now (grottily!) handled by dpll5_clk's set routine,
> ++	 * to cope with an erratum on DM3730
> ++	 */
> + 
> +-	clk_disable(dpll5_m2_clk);
> +-	clk_disable(dpll5_clk);
> + 	return;
> + }
> + 
> +diff --git a/arch/arm/mach-omap2/clock3xxx.h b/arch/arm/mach-omap2/clock3xxx.h
> +index 8bbeeaf..0ede513 100644
> +--- a/arch/arm/mach-omap2/clock3xxx.h
> ++++ b/arch/arm/mach-omap2/clock3xxx.h
> +@@ -10,6 +10,7 @@
> + 
> + int omap3xxx_clk_init(void);
> + int omap3_dpll4_set_rate(struct clk *clk, unsigned long rate);
> ++int omap3_dpll5_set_rate(struct clk *clk, unsigned long rate);
> + int omap3_core_dpll_m2_set_rate(struct clk *clk, unsigned long rate);
> + void omap3_clk_lock_dpll5(void);
> + 
> +diff --git a/arch/arm/mach-omap2/clock3xxx_data.c b/arch/arm/mach-omap2/clock3xxx_data.c
> +index ffd55b1..dcd7bdc 100644
> +--- a/arch/arm/mach-omap2/clock3xxx_data.c
> ++++ b/arch/arm/mach-omap2/clock3xxx_data.c
> +@@ -942,7 +942,7 @@ static struct clk dpll5_ck = {
> + 	.parent		= &sys_ck,
> + 	.dpll_data	= &dpll5_dd,
> + 	.round_rate	= &omap2_dpll_round_rate,
> +-	.set_rate	= &omap3_noncore_dpll_set_rate,
> ++	.set_rate	= &omap3_dpll5_set_rate,
> + 	.clkdm_name	= "dpll5_clkdm",
> + 	.recalc		= &omap3_dpll_recalc,
> + };
> +diff --git a/arch/arm/mach-omap2/dpll3xxx.c b/arch/arm/mach-omap2/dpll3xxx.c
> +index f77022b..1909cd0 100644
> +--- a/arch/arm/mach-omap2/dpll3xxx.c
> ++++ b/arch/arm/mach-omap2/dpll3xxx.c
> +@@ -291,7 +291,7 @@ static void _lookup_sddiv(struct clk *clk, u8 *sd_div, u16 m, u8 n)
> +  * Program the DPLL with the supplied M, N values, and wait for the DPLL to
> +  * lock..  Returns -EINVAL upon error, or 0 upon success.
> +  */
> +-static int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
> ++int omap3_noncore_dpll_program(struct clk *clk, u16 m, u8 n, u16 freqsel)
> + {
> + 	struct dpll_data *dd = clk->dpll_data;
> + 	u8 dco, sd_div;
> +-- 
> +1.7.2.5
> +
> diff --git a/recipes-kernel/linux/linux_3.0.bb b/recipes-kernel/linux/linux_3.0.bb
> index 32ef963..c95542e 100644
> --- a/recipes-kernel/linux/linux_3.0.bb
> +++ b/recipes-kernel/linux/linux_3.0.bb
> @@ -10,7 +10,7 @@ PV = "3.0.23"
>  SRCREV_pn-${PN} = "bf6a68d2a214e07f7c0d6538e00e17b826714160"
>  
>  # The main PR is now using MACHINE_KERNEL_PR, for omap3 see conf/machine/include/omap3.inc
> -MACHINE_KERNEL_PR_append = "a"
> +MACHINE_KERNEL_PR_append = "b"
>  
>  FILESPATH =. "${FILE_DIRNAME}/linux-3.0:${FILE_DIRNAME}/linux-3.0/${MACHINE}:"
>  
> @@ -224,6 +224,8 @@ SRC_URI += "git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable.gi
>              \
>              file://misc/0001-compiler.h-Undef-before-redefining-__attribute_const.patch \
>              \
> +            file://usb/0001-Fix-sprz319-erratum-2.1.patch \
> +            \
>              file://defconfig"
>  
>  SRC_URI_append_beagleboard = " file://logo_linux_clut224.ppm \
> -- 
> 1.7.2.5
> 
> _______________________________________________
> meta-ti mailing list
> meta-ti at yoctoproject.org
> https://lists.yoctoproject.org/listinfo/meta-ti
> 



More information about the meta-ti mailing list