LinuxPPC-Dev Archive on lore.kernel.org
 help / color / mirror / Atom feed
* Re: [PATCH 0/3] cpu: idle state framework for offline CPUs.
From: Rafael J. Wysocki @ 2009-08-09 13:22 UTC (permalink / raw)
  To: Pavel Machek
  Cc: Brown, Len, Peter Zijlstra, Gautham R Shenoy,
	linux-kernel@vger.kernel.org, Pallipadi, Venkatesh, Shaohua Li,
	Ingo Molnar, linuxppc-dev@lists.ozlabs.org, Darrick J. Wong
In-Reply-To: <20090809120818.GA1338@ucw.cz>

On Sunday 09 August 2009, Pavel Machek wrote:
> Hi!
> 
> > > Also, approaches such as [1] can make use of this
> > > extended infrastructure instead of putting the CPU to an arbitrary C-state
> > > when it is offlined, thereby providing the system administrator a rope to hang
> > > himself with should he feel the need to do so.
> > I didn't see the reason why administrator needs to know which state offline cpu
> > should stay. Don't know about powerpc side, but in x86 side, it appears deepest
> > C-state is already preferred.
> > 
> 
> Agreed, deepest c-state is always best, there's no need to make it configurable.

Unless it doesn't work.

Rafael

^ permalink raw reply

* Re: [PATCH 0/3] cpu: idle state framework for offline CPUs.
From: Pavel Machek @ 2009-08-09 12:08 UTC (permalink / raw)
  To: Shaohua Li
  Cc: Brown, Len, Peter Zijlstra, Gautham R Shenoy,
	linux-kernel@vger.kernel.org, Pallipadi, Venkatesh, Ingo Molnar,
	linuxppc-dev@lists.ozlabs.org, Darrick J. Wong
In-Reply-To: <20090806015855.GA20596@sli10-desk.sh.intel.com>

Hi!

> > Also, approaches such as [1] can make use of this
> > extended infrastructure instead of putting the CPU to an arbitrary C-state
> > when it is offlined, thereby providing the system administrator a rope to hang
> > himself with should he feel the need to do so.
> I didn't see the reason why administrator needs to know which state offline cpu
> should stay. Don't know about powerpc side, but in x86 side, it appears deepest
> C-state is already preferred.
> 

Agreed, deepest c-state is always best, there's no need to make it configurable.

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: [PATCH 0/3] cpu: idle state framework for offline CPUs.
From: Pavel Machek @ 2009-08-09 12:08 UTC (permalink / raw)
  To: Vaidyanathan Srinivasan
  Cc: Brown, Len, Peter Zijlstra, Gautham R Shenoy,
	linux-kernel@vger.kernel.org, Pallipadi, Venkatesh, Shaohua Li,
	Ingo Molnar, linuxppc-dev@lists.ozlabs.org, Darrick J. Wong
In-Reply-To: <20090806043351.GC14333@dirshya.in.ibm.com>

Hi!

> > > Also, approaches such as [1] can make use of this
> > > extended infrastructure instead of putting the CPU to an arbitrary C-state
> > > when it is offlined, thereby providing the system administrator a rope to hang
> > > himself with should he feel the need to do so.
> > I didn't see the reason why administrator needs to know which state offline cpu
> > should stay. Don't know about powerpc side, but in x86 side, it appears deepest
> > C-state is already preferred.
> 
> Yes that is what we would expect, but the deepest sleep state may be
> restricted by BIOS or other system level parameters.  This was the
> main objection to Venki's deepest sleep state for offline cpus
> patch.

'May be restricted'? Kernel already needs to know about that
restriction, just do the right thing...

-- 
(english) http://www.livejournal.com/~pavelmachek
(cesky, pictures) http://atrey.karlin.mff.cuni.cz/~pavel/picture/horses/blog.html

^ permalink raw reply

* Re: [PATCH] mtd/maps: add mtd-ram support to physmap_of
From: Artem Bityutskiy @ 2009-08-09  5:17 UTC (permalink / raw)
  To: Grant Likely
  Cc: devicetree-discuss, Vitaly Wool, Albrecht Dreß, linuxppc-dev,
	linux-mtd, Ken MacLeod, David Woodhouse
In-Reply-To: <fa686aa40908072243x56d2160fk688149f4b7b912ae@mail.gmail.com>

On Fri, 2009-08-07 at 23:43 -0600, Grant Likely wrote:
> On Fri, Jul 17, 2009 at 6:39 AM, Wolfram Sang<w.sang@pengutronix.de> wrote:
> > Use physmap_of to access RAMs as mtd and add documenation for it. This approach
> > is a lot less intrusive as adding an of-wrapper around plat-ram.c. As most
> > extensions of plat-ram.c (e.g. custom map-functions) can't be mapped to the
> > device tree anyhow, extending physmap_of seems to be the cleanest approach.
> >
> > Tested with a phyCORE-MPC5121e.
> >
> > Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>
> 
> Looks good to me.
> 
> Acked-by: Grant Likely <grant.likely@secretlab.ca>

This patch is sitting in my l2-mtd-2.6.git tree.

-- 
Best Regards,
Artem Bityutskiy (Артём Битюцкий)

^ permalink raw reply

* Re: [PATCH V2] Use clock freqency from the device tree to calculate correct MPC5200 PSC clock.
From: Wolfram Sang @ 2009-08-08 10:26 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Linuxppc-dev
In-Reply-To: <20090807191936.17939.69607.stgit@terra>

[-- Attachment #1: Type: text/plain, Size: 6628 bytes --]

On Fri, Aug 07, 2009 at 03:19:36PM -0400, Jon Smirl wrote:
> Use clock freqency from the device tree to calculate correct MPC5200 PSC clock.
> Previous code had errors or used a constant. This versions computes
> the right clock based on the xtal and register settings.
> 
> Signed-off-by: Jon Smirl <jonsmirl@gmail.com>

Acked-by: Wolfram Sang <w.sang@pengutronix.de>

> ---
>  arch/powerpc/include/asm/mpc52xx.h           |    2 +-
>  arch/powerpc/platforms/52xx/mpc52xx_common.c |   26 ++++++++++++++++++++++++--
>  drivers/spi/mpc52xx_psc_spi.c                |    8 +-------
>  sound/soc/fsl/mpc5200_psc_i2s.c              |   11 +----------
>  4 files changed, 27 insertions(+), 20 deletions(-)
> 
> diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
> index cadd398..1ca8a0e 100644
> --- a/arch/powerpc/include/asm/mpc52xx.h
> +++ b/arch/powerpc/include/asm/mpc52xx.h
> @@ -285,7 +285,7 @@ struct mpc52xx_rtc {
>  extern void mpc5200_setup_xlb_arbiter(void);
>  extern void mpc52xx_declare_of_platform_devices(void);
>  extern void mpc52xx_map_common_devices(void);
> -extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
> +extern int mpc52xx_set_psc_clkdiv(int psc_id, int freq);
>  extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
>  extern void mpc52xx_restart(char *cmd);
>  
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> index a46bad0..8a19156 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> @@ -110,6 +110,8 @@ static struct of_device_id mpc52xx_cdm_ids[] __initdata = {
>  	{}
>  };
>  
> +static u32 mpc52xx_fsystem; /* fsystem clock on mpc5200 */
> +
>  /**
>   * mpc52xx_map_common_devices: iomap devices required by common code
>   */
> @@ -117,6 +119,7 @@ void __init
>  mpc52xx_map_common_devices(void)
>  {
>  	struct device_node *np;
> +	u32 val;
>  
>  	/* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
>  	 * possibly from a interrupt context. wdt is only implement
> @@ -133,8 +136,16 @@ mpc52xx_map_common_devices(void)
>  
>  	/* Clock Distribution Module, used by PSC clock setting function */
>  	np = of_find_matching_node(NULL, mpc52xx_cdm_ids);
> +	mpc52xx_fsystem = mpc5xxx_get_bus_frequency(np);
>  	mpc52xx_cdm = of_iomap(np, 0);
>  	of_node_put(np);
> +
> +	/* compute fsystem, it is either 4 or 8 times the bus freq */
> +	val = in_be32(&mpc52xx_cdm->rstcfg);
> +	if (val & (1 << 5))
> +		mpc52xx_fsystem *= 8;
> +	else
> +		mpc52xx_fsystem *= 4;
>  }
>  
>  /**
> @@ -143,17 +154,28 @@ mpc52xx_map_common_devices(void)
>   * @psc_id: id of psc port; must be 1,2,3 or 6
>   * @clkdiv: clock divider value to put into CDM PSC register.
>   */
> -int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
> +int mpc52xx_set_psc_clkdiv(int psc_id, int freq)
>  {
>  	unsigned long flags;
>  	u16 __iomem *reg;
>  	u32 val;
> -	u32 mask;
> +	u32 mask, clkdiv, err;
>  	u32 mclken_div;
>  
>  	if (!mpc52xx_cdm)
>  		return -ENODEV;
>  
> +	/* figure out the closest frequency the hardware can make */
> +	clkdiv = mpc52xx_fsystem / freq;
> +	err = mpc52xx_fsystem % freq;
> +	if (err > freq / 2)
> +		clkdiv++;
> +	/* hardware is not very flexible, there will be significant error */
> +	/* frequency error = fsystem / clkdiv - freq; */
> +
> +	/* hardware adds one to the divisor */
> +	clkdiv -= 1;
> +
>  	mclken_div = 0x8000 | (clkdiv & 0x1FF);
>  	switch (psc_id) {
>  	case 1: reg = &mpc52xx_cdm->mclken_div_psc1; mask = 0x20; break;
> diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
> index d2a04d6..5c8e621 100644
> --- a/drivers/spi/mpc52xx_psc_spi.c
> +++ b/drivers/spi/mpc52xx_psc_spi.c
> @@ -33,7 +33,6 @@
>  struct mpc52xx_psc_spi {
>  	/* fsl_spi_platform data */
>  	void (*cs_control)(struct spi_device *spi, bool on);
> -	u32 sysclk;
>  
>  	/* driver internal data */
>  	struct mpc52xx_psc __iomem *psc;
> @@ -313,12 +312,9 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
>  {
>  	struct mpc52xx_psc __iomem *psc = mps->psc;
>  	struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
> -	u32 mclken_div;
>  	int ret = 0;
>  
> -	/* default sysclk is 512MHz */
> -	mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
> -	mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
> +	mpc52xx_set_psc_clkdiv(psc_id, MCLK);
>  
>  	/* Reset the PSC into a known state */
>  	out_8(&psc->command, MPC52xx_PSC_RST_RX);
> @@ -383,12 +379,10 @@ static int __init mpc52xx_psc_spi_do_probe(struct of_device *op, u32 regaddr,
>  		dev_warn(&op->dev, "probe called without platform data, no "
>  				"cs_control function will be called\n");
>  		mps->cs_control = NULL;
> -		mps->sysclk = 0;
>  		master->bus_num = bus_num;
>  		master->num_chipselect = 255;
>  	} else {
>  		mps->cs_control = pdata->cs_control;
> -		mps->sysclk = pdata->sysclk;
>  		master->bus_num = pdata->bus_num;
>  		master->num_chipselect = pdata->max_chipselect;
>  	}
> diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
> index c58fcde..8de4719 100644
> --- a/sound/soc/fsl/mpc5200_psc_i2s.c
> +++ b/sound/soc/fsl/mpc5200_psc_i2s.c
> @@ -115,7 +115,6 @@ static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
>  			      int clk_id, unsigned int freq, int dir)
>  {
>  	struct psc_dma *psc_dma = cpu_dai->private_data;
> -	int clkdiv, err;
>  
>  	dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, freq=%u, dir=%i)\n",
>  				cpu_dai, freq, dir);
> @@ -128,15 +127,7 @@ static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
>  			psc_dma->sicr &= ~MPC52xx_PSC_SICR_CELLSLAVE;
>  			psc_dma->sicr |= MPC52xx_PSC_SICR_GENCLK;
>  
> -			clkdiv = ppc_proc_freq / freq;
> -			err = ppc_proc_freq % freq;
> -			if (err > freq / 2)
> -				clkdiv++;
> -
> -			dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(clkdiv %d freq error=%ldHz)\n",
> -					clkdiv, (ppc_proc_freq / clkdiv - freq));
> -
> -			return mpc52xx_set_psc_clkdiv(psc_dma->id + 1, clkdiv);
> +			return mpc52xx_set_psc_clkdiv(psc_dma->id + 1, freq);
>  		}
>  	}
>  	return 0;
> 
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev

-- 
Pengutronix e.K.                           | Wolfram Sang                |
Industrial Linux Solutions                 | http://www.pengutronix.de/  |

[-- Attachment #2: Digital signature --]
[-- Type: application/pgp-signature, Size: 197 bytes --]

^ permalink raw reply

* Re: sequoia: The final kernel image would overwrite the device tree
From: Wolfgang Denk @ 2009-08-08  7:38 UTC (permalink / raw)
  To: Benjamin Herrenschmidt
  Cc: Geert Uytterhoeven, Linux/PPC Development, Stefan Roese
In-Reply-To: <1249678991.10143.1.camel@pasglop>

Dear Ben,

In message <1249678991.10143.1.camel@pasglop> you wrote:
> 
> My experience, however, with a Canyonlands board, is that uBoot has
> a bug that makes it always allocate the device-tree below 8M and clash
> with the kernel when it gets too big.
> 
> I think Stefan fixed that recently, you may need to rebuild your uboot,
> I'll let him tell you the details about the fix.

Right. These are the relevant commits; they went into mainline some
time ago:

commit 27dd5f8e1062684f1ba685760409d9b2ab6691bf
Author: Stefan Roese <sr@denx.de>
Date:   Tue Jul 28 10:56:03 2009 +0200

    ppc4xx: amcc: Move "kernel_addr_r" etc to higher locations (> 16MB)
    
    This patch moves the load addresses for kernel, fdt and ramdisk to higher
    addresses (>= 16MB). This enables booting of bigger kernel images (e.g.
    lockdep enabled).
    
    Signed-off-by: Stefan Roese <sr@denx.de>

commit 6942efc2be1b90054fa4afa5cda7023469fe08b9
Author: Stefan Roese <sr@denx.de>
Date:   Tue Jul 28 10:50:32 2009 +0200

    ppc4xx: amcc: Set CONFIG_SYS_BOOTMAPSZ to 16MB for big kernels
    
    This patch changes CONFIG_SYS_BOOTMAPSZ from 8MB to 16MB which is the
    initial TLB on 40x PPC's in the Linux kernel. With this change even bigger
    Linux kernels (> 8MB) can be booted.
    
    This patch also sets CONFIG_SYS_BOOTM_LEN to 16MB (default 8MB) to enable
    decompression of bigger images.
    
    Signed-off-by: Stefan Roese <sr@denx.de>


Best regards,

Wolfgang Denk

-- 
DENX Software Engineering GmbH,     MD: Wolfgang Denk & Detlev Zundel
HRB 165235 Munich, Office: Kirchenstr.5, D-82194 Groebenzell, Germany
Phone: (+49)-8142-66989-10 Fax: (+49)-8142-66989-80 Email: wd@denx.de
Every solution breeds new problems.

^ permalink raw reply

* Re: [5200] ATA and (BAD) interrupts question
From: Grant Likely @ 2009-08-08  5:48 UTC (permalink / raw)
  To: Albrecht Dreß; +Cc: linuxppc-dev
In-Reply-To: <24979490.1248785451446.JavaMail.ngmail@webmail10.arcor-online.net>

On Tue, Jul 28, 2009 at 6:50 AM, Albrecht Dre=DF<albrecht.dress@arcor.de> w=
rote:
> Hi all,
>
> I run linux 2.6.29.1 from kernel.org on a custom Freescale MPC5200B based=
 board, which has a CF card attached to the 5200's ATA. =A0The CF seems to =
run nicely, but I am somewhat confused by the interrupts reproted by the ke=
rnel.
>
> Immediately after the boot, /proc/interrupts reports (inter alia)
>
> 135: =A0 =A0 =A0 =A0 =A08 =A0MPC52xx Peripherals Edge =A0 =A0 =A0mpc52xx_=
ata
> 194: =A0 =A0 =A0 =A0 =A00 =A0MPC52xx SDMA Edge =A0 =A0 =A0ATA task
> BAD: =A0 =A0 =A0 =A0 44
>
> Then I say 'mount -t vfat -o noatime /dev/sda1 /mnt/cf0', and I get
>
> 135: =A0 =A0 =A0 =A0 41 =A0MPC52xx Peripherals Edge =A0 =A0 =A0mpc52xx_at=
a
> 194: =A0 =A0 =A0 =A0 =A00 =A0MPC52xx SDMA Edge =A0 =A0 =A0ATA task
> BAD: =A0 =A0 =A0 =A0 44
>
> Then, I recursively copy a folder to the CF card:
>
> 135: =A0 =A0 125111 =A0MPC52xx Peripherals Edge =A0 =A0 =A0mpc52xx_ata
> 194: =A0 =A0 =A0 =A0 =A00 =A0MPC52xx SDMA Edge =A0 =A0 =A0ATA task
> BAD: =A0 =A0 121863
>
> Is it correct that the "ATA task" interrupts are still 0, and that I get =
such a high number of BAD ones? =A0Is there a way to detect which source ac=
tually triggered the BAD interrupts?

No, not really, but I'd spend some time looking at the DMA portion of
the IRQ handler.  Either edge IRQs are not getting acked correctly, or
the interrupt controller driver is not reading the pending IRQs
correctly.

g.

--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: [PATCH] mtd/maps: add mtd-ram support to physmap_of
From: Grant Likely @ 2009-08-08  5:43 UTC (permalink / raw)
  To: Wolfram Sang
  Cc: devicetree-discuss, Vitaly Wool, Artem Bityutskiy,
	Albrecht Dreß, linuxppc-dev, linux-mtd, Ken MacLeod,
	David Woodhouse
In-Reply-To: <1247834363-28198-1-git-send-email-w.sang@pengutronix.de>

On Fri, Jul 17, 2009 at 6:39 AM, Wolfram Sang<w.sang@pengutronix.de> wrote:
> Use physmap_of to access RAMs as mtd and add documenation for it. This ap=
proach
> is a lot less intrusive as adding an of-wrapper around plat-ram.c. As mos=
t
> extensions of plat-ram.c (e.g. custom map-functions) can't be mapped to t=
he
> device tree anyhow, extending physmap_of seems to be the cleanest approac=
h.
>
> Tested with a phyCORE-MPC5121e.
>
> Signed-off-by: Wolfram Sang <w.sang@pengutronix.de>

Looks good to me.

Acked-by: Grant Likely <grant.likely@secretlab.ca>

> Cc: Vitaly Wool <vwool@ru.mvista.com>
> Cc: Artem Bityutskiy <dedekind@infradead.org>
> Cc: David Woodhouse <dwmw2@infradead.org>
> Cc: Ken MacLeod <ken@bitsko.slc.ut.us>
> Cc: Albrecht Dre=DF <albrecht.dress@arcor.de>
> ---
> =A0Documentation/powerpc/dts-bindings/mtd-physmap.txt | =A0 42 ++++++++++=
++-------
> =A0drivers/mtd/maps/physmap_of.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =
=A0| =A0 =A04 ++
> =A02 files changed, 30 insertions(+), 16 deletions(-)
>
> diff --git a/Documentation/powerpc/dts-bindings/mtd-physmap.txt b/Documen=
tation/powerpc/dts-bindings/mtd-physmap.txt
> index 667c9bd..80152cb 100644
> --- a/Documentation/powerpc/dts-bindings/mtd-physmap.txt
> +++ b/Documentation/powerpc/dts-bindings/mtd-physmap.txt
> @@ -1,18 +1,19 @@
> -CFI or JEDEC memory-mapped NOR flash
> +CFI or JEDEC memory-mapped NOR flash, MTD-RAM (NVRAM...)
>
> =A0Flash chips (Memory Technology Devices) are often used for solid state
> =A0file systems on embedded devices.
>
> - - compatible : should contain the specific model of flash chip(s)
> - =A0 used, if known, followed by either "cfi-flash" or "jedec-flash"
> - - reg : Address range(s) of the flash chip(s)
> + - compatible : should contain the specific model of mtd chip(s)
> + =A0 used, if known, followed by either "cfi-flash", "jedec-flash"
> + =A0 or "mtd-ram".
> + - reg : Address range(s) of the mtd chip(s)
> =A0 =A0It's possible to (optionally) define multiple "reg" tuples so that
> - =A0 non-identical NOR chips can be described in one flash node.
> - - bank-width : Width (in bytes) of the flash bank. =A0Equal to the
> + =A0 non-identical chips can be described in one node.
> + - bank-width : Width (in bytes) of the bank. =A0Equal to the
> =A0 =A0device width times the number of interleaved chips.
> - - device-width : (optional) Width of a single flash chip. =A0If
> + - device-width : (optional) Width of a single mtd chip. =A0If
> =A0 =A0omitted, assumed to be equal to 'bank-width'.
> - - #address-cells, #size-cells : Must be present if the flash has
> + - #address-cells, #size-cells : Must be present if the device has
> =A0 =A0sub-nodes representing partitions (see below). =A0In this case
> =A0 =A0both #address-cells and #size-cells must be equal to 1.
>
> @@ -22,24 +23,24 @@ are defined:
> =A0- vendor-id : Contains the flash chip's vendor id (1 byte).
> =A0- device-id : Contains the flash chip's device id (1 byte).
>
> -In addition to the information on the flash bank itself, the
> +In addition to the information on the mtd bank itself, the
> =A0device tree may optionally contain additional information
> -describing partitions of the flash address space. =A0This can be
> +describing partitions of the address space. =A0This can be
> =A0used on platforms which have strong conventions about which
> -portions of the flash are used for what purposes, but which don't
> +portions of a flash are used for what purposes, but which don't
> =A0use an on-flash partition table such as RedBoot.
>
> -Each partition is represented as a sub-node of the flash device.
> +Each partition is represented as a sub-node of the mtd device.
> =A0Each node's name represents the name of the corresponding
> -partition of the flash device.
> +partition of the mtd device.
>
> =A0Flash partitions
> - - reg : The partition's offset and size within the flash bank.
> - - label : (optional) The label / name for this flash partition.
> + - reg : The partition's offset and size within the mtd bank.
> + - label : (optional) The label / name for this partition.
> =A0 =A0If omitted, the label is taken from the node name (excluding
> =A0 =A0the unit address).
> =A0- read-only : (optional) This parameter, if present, is a hint to
> - =A0 Linux that this flash partition should only be mounted
> + =A0 Linux that this partition should only be mounted
> =A0 =A0read-only. =A0This is usually used for flash partitions
> =A0 =A0containing early-boot firmware images or data which should not
> =A0 =A0be clobbered.
> @@ -78,3 +79,12 @@ Here an example with multiple "reg" tuples:
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0reg =3D <0 0x04000000>;
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0};
> =A0 =A0 =A0 =A0};
> +
> +An example using SRAM:
> +
> + =A0 =A0 =A0 sram@2,0 {
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 compatible =3D "samsung,k6f1616u6a", "mtd-r=
am";
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 reg =3D <2 0 0x00200000>;
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 bank-width =3D <2>;
> + =A0 =A0 =A0 };
> +
> diff --git a/drivers/mtd/maps/physmap_of.c b/drivers/mtd/maps/physmap_of.=
c
> index 39d357b..45eee20 100644
> --- a/drivers/mtd/maps/physmap_of.c
> +++ b/drivers/mtd/maps/physmap_of.c
> @@ -360,6 +360,10 @@ static struct of_device_id of_flash_match[] =3D {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0.data =A0 =A0 =A0 =A0 =A0 =3D (void *)"jed=
ec_probe",
> =A0 =A0 =A0 =A0},
> =A0 =A0 =A0 =A0{
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .compatible =A0 =A0 =3D "mtd-ram",
> + =A0 =A0 =A0 =A0 =A0 =A0 =A0 .data =A0 =A0 =A0 =A0 =A0 =3D (void *)"map_=
ram",
> + =A0 =A0 =A0 },
> + =A0 =A0 =A0 {
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0.type =A0 =A0 =A0 =A0 =A0 =3D "rom",
> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0.compatible =A0 =A0 =3D "direct-mapped"
> =A0 =A0 =A0 =A0},
> --
> 1.6.3.1
>
> _______________________________________________
> Linuxppc-dev mailing list
> Linuxppc-dev@lists.ozlabs.org
> https://lists.ozlabs.org/listinfo/linuxppc-dev



--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* [PATCH 3/3] crypto: talitos - add support for 36 bit addressing
From: Kim Phillips @ 2009-08-07 23:40 UTC (permalink / raw)
  To: linux-crypto; +Cc: linuxppc-dev

Enabling extended addressing in the h/w requires we always assign the
extended address component (eptr) of the talitos h/w pointer.  This is
for e500 based platforms with large memories.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---
 drivers/crypto/talitos.c |   69 ++++++++++++++++++++++++++-------------------
 drivers/crypto/talitos.h |    1 +
 2 files changed, 41 insertions(+), 29 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index 5013a2d..c47ffe8 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -146,6 +146,12 @@ struct talitos_private {
 #define TALITOS_FTR_SRC_LINK_TBL_LEN_INCLUDES_EXTENT 0x00000001
 #define TALITOS_FTR_HW_AUTH_CHECK 0x00000002
 
+static void to_talitos_ptr(struct talitos_ptr *talitos_ptr, dma_addr_t dma_addr)
+{
+	talitos_ptr->ptr = cpu_to_be32(lower_32_bits(dma_addr));
+	talitos_ptr->eptr = cpu_to_be32(upper_32_bits(dma_addr));
+}
+
 /*
  * map virtual single (contiguous) pointer to h/w descriptor pointer
  */
@@ -155,8 +161,10 @@ static void map_single_talitos_ptr(struct device *dev,
 				   unsigned char extent,
 				   enum dma_data_direction dir)
 {
+	dma_addr_t dma_addr = dma_map_single(dev, data, len, dir);
+
 	talitos_ptr->len = cpu_to_be16(len);
-	talitos_ptr->ptr = cpu_to_be32(dma_map_single(dev, data, len, dir));
+	to_talitos_ptr(talitos_ptr, dma_addr);
 	talitos_ptr->j_extent = extent;
 }
 
@@ -187,9 +195,9 @@ static int reset_channel(struct device *dev, int ch)
 		return -EIO;
 	}
 
-	/* set done writeback and IRQ */
-	setbits32(priv->reg + TALITOS_CCCR_LO(ch), TALITOS_CCCR_LO_CDWE |
-		  TALITOS_CCCR_LO_CDIE);
+	/* set 36-bit addressing, done writeback enable and done IRQ enable */
+	setbits32(priv->reg + TALITOS_CCCR_LO(ch), TALITOS_CCCR_LO_EAE |
+		  TALITOS_CCCR_LO_CDWE | TALITOS_CCCR_LO_CDIE);
 
 	/* and ICCR writeback, if available */
 	if (priv->features & TALITOS_FTR_HW_AUTH_CHECK)
@@ -312,7 +320,10 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc,
 
 	/* GO! */
 	wmb();
-	out_be32(priv->reg + TALITOS_FF_LO(ch), request->dma_desc);
+	out_be32(priv->reg + TALITOS_FF(ch),
+		 cpu_to_be32(upper_32_bits(request->dma_desc)));
+	out_be32(priv->reg + TALITOS_FF_LO(ch),
+		 cpu_to_be32(lower_32_bits(request->dma_desc)));
 
 	spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
 
@@ -934,7 +945,7 @@ static int sg_to_link_tbl(struct scatterlist *sg, int sg_count,
 	int n_sg = sg_count;
 
 	while (n_sg--) {
-		link_tbl_ptr->ptr = cpu_to_be32(sg_dma_address(sg));
+		to_talitos_ptr(link_tbl_ptr, sg_dma_address(sg));
 		link_tbl_ptr->len = cpu_to_be16(sg_dma_len(sg));
 		link_tbl_ptr->j_extent = 0;
 		link_tbl_ptr++;
@@ -1009,7 +1020,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
 				  edesc->src_is_chained);
 
 	if (sg_count == 1) {
-		desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->src));
+		to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->src));
 	} else {
 		sg_link_tbl_len = cryptlen;
 
@@ -1020,14 +1031,14 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
 					  &edesc->link_tbl[0]);
 		if (sg_count > 1) {
 			desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
-			desc->ptr[4].ptr = cpu_to_be32(edesc->dma_link_tbl);
+			to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl);
 			dma_sync_single_for_device(dev, edesc->dma_link_tbl,
 						   edesc->dma_len,
 						   DMA_BIDIRECTIONAL);
 		} else {
 			/* Only one segment now, so no link tbl needed */
-			desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->
-								      src));
+			to_talitos_ptr(&desc->ptr[4],
+				       sg_dma_address(areq->src));
 		}
 	}
 
@@ -1042,14 +1053,14 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
 					  edesc->dst_is_chained);
 
 	if (sg_count == 1) {
-		desc->ptr[5].ptr = cpu_to_be32(sg_dma_address(areq->dst));
+		to_talitos_ptr(&desc->ptr[5], sg_dma_address(areq->dst));
 	} else {
 		struct talitos_ptr *link_tbl_ptr =
 			&edesc->link_tbl[edesc->src_nents + 1];
 
-		desc->ptr[5].ptr = cpu_to_be32((struct talitos_ptr *)
-					       edesc->dma_link_tbl +
-					       edesc->src_nents + 1);
+		to_talitos_ptr(&desc->ptr[5], edesc->dma_link_tbl +
+			       (edesc->src_nents + 1) *
+			       sizeof(struct talitos_ptr));
 		sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
 					  link_tbl_ptr);
 
@@ -1062,11 +1073,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
 		link_tbl_ptr->len = cpu_to_be16(authsize);
 
 		/* icv data follows link tables */
-		link_tbl_ptr->ptr = cpu_to_be32((struct talitos_ptr *)
-						edesc->dma_link_tbl +
-					        edesc->src_nents +
-						edesc->dst_nents + 2);
-
+		to_talitos_ptr(link_tbl_ptr, edesc->dma_link_tbl +
+			       (edesc->src_nents + edesc->dst_nents + 2) *
+			       sizeof(struct talitos_ptr));
 		desc->ptr[5].j_extent |= DESC_PTR_LNKTBL_JUMP;
 		dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
 					   edesc->dma_len, DMA_BIDIRECTIONAL);
@@ -1341,7 +1350,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 
 	/* first DWORD empty */
 	desc->ptr[0].len = 0;
-	desc->ptr[0].ptr = 0;
+	to_talitos_ptr(&desc->ptr[0], 0);
 	desc->ptr[0].j_extent = 0;
 
 	/* cipher iv */
@@ -1365,20 +1374,20 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 				  edesc->src_is_chained);
 
 	if (sg_count == 1) {
-		desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->src));
+		to_talitos_ptr(&desc->ptr[3], sg_dma_address(areq->src));
 	} else {
 		sg_count = sg_to_link_tbl(areq->src, sg_count, cryptlen,
 					  &edesc->link_tbl[0]);
 		if (sg_count > 1) {
+			to_talitos_ptr(&desc->ptr[3], edesc->dma_link_tbl);
 			desc->ptr[3].j_extent |= DESC_PTR_LNKTBL_JUMP;
-			desc->ptr[3].ptr = cpu_to_be32(edesc->dma_link_tbl);
 			dma_sync_single_for_device(dev, edesc->dma_link_tbl,
 						   edesc->dma_len,
 						   DMA_BIDIRECTIONAL);
 		} else {
 			/* Only one segment now, so no link tbl needed */
-			desc->ptr[3].ptr = cpu_to_be32(sg_dma_address(areq->
-								      src));
+			to_talitos_ptr(&desc->ptr[3],
+				       sg_dma_address(areq->src));
 		}
 	}
 
@@ -1393,15 +1402,15 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 					  edesc->dst_is_chained);
 
 	if (sg_count == 1) {
-		desc->ptr[4].ptr = cpu_to_be32(sg_dma_address(areq->dst));
+		to_talitos_ptr(&desc->ptr[4], sg_dma_address(areq->dst));
 	} else {
 		struct talitos_ptr *link_tbl_ptr =
 			&edesc->link_tbl[edesc->src_nents + 1];
 
+		to_talitos_ptr(&desc->ptr[4], edesc->dma_link_tbl +
+					      (edesc->src_nents + 1) *
+					      sizeof(struct talitos_ptr));
 		desc->ptr[4].j_extent |= DESC_PTR_LNKTBL_JUMP;
-		desc->ptr[4].ptr = cpu_to_be32((struct talitos_ptr *)
-					       edesc->dma_link_tbl +
-					       edesc->src_nents + 1);
 		sg_count = sg_to_link_tbl(areq->dst, sg_count, cryptlen,
 					  link_tbl_ptr);
 		dma_sync_single_for_device(ctx->dev, edesc->dma_link_tbl,
@@ -1414,7 +1423,7 @@ static int common_nonsnoop(struct talitos_edesc *edesc,
 
 	/* last DWORD empty */
 	desc->ptr[6].len = 0;
-	desc->ptr[6].ptr = 0;
+	to_talitos_ptr(&desc->ptr[6], 0);
 	desc->ptr[6].j_extent = 0;
 
 	ret = talitos_submit(dev, desc, callback, areq);
@@ -1898,6 +1907,8 @@ static int talitos_probe(struct of_device *ofdev,
 		atomic_set(&priv->chan[i].submit_count,
 			   -(priv->chfifo_len - 1));
 
+	dma_set_mask(dev, DMA_BIT_MASK(36));
+
 	/* reset and initialize the h/w */
 	err = init_device(dev);
 	if (err) {
diff --git a/drivers/crypto/talitos.h b/drivers/crypto/talitos.h
index 575981f..ff5a145 100644
--- a/drivers/crypto/talitos.h
+++ b/drivers/crypto/talitos.h
@@ -57,6 +57,7 @@
 #define   TALITOS_CCCR_RESET		0x1    /* channel reset */
 #define TALITOS_CCCR_LO(ch)		(ch * TALITOS_CH_STRIDE + 0x110c)
 #define   TALITOS_CCCR_LO_IWSE		0x80   /* chan. ICCR writeback enab. */
+#define   TALITOS_CCCR_LO_EAE		0x20   /* extended address enable */
 #define   TALITOS_CCCR_LO_CDWE		0x10   /* chan. done writeback enab. */
 #define   TALITOS_CCCR_LO_NT		0x4    /* notification type */
 #define   TALITOS_CCCR_LO_CDIE		0x2    /* channel done IRQ enable */
-- 
1.6.3

^ permalink raw reply related

* [PATCH 2/3] crypto: talitos - align locks on cache lines
From: Kim Phillips @ 2009-08-07 23:40 UTC (permalink / raw)
  To: linux-crypto; +Cc: linuxppc-dev

align channel access locks onto separate cache lines (for performance
reasons).  This is done by placing per-channel variables into their own
private struct, and using the cacheline_aligned attribute within that
struct.

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---
 drivers/crypto/talitos.c |  141 +++++++++++++++++++---------------------------
 1 files changed, 58 insertions(+), 83 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index b1a651c..5013a2d 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -86,6 +86,25 @@ struct talitos_request {
 	void *context;
 };
 
+/* per-channel fifo management */
+struct talitos_channel {
+	/* request fifo */
+	struct talitos_request *fifo;
+
+	/* number of requests pending in channel h/w fifo */
+	atomic_t submit_count ____cacheline_aligned;
+
+	/* request submission (head) lock */
+	spinlock_t head_lock ____cacheline_aligned;
+	/* index to next free descriptor request */
+	int head;
+
+	/* request release (tail) lock */
+	spinlock_t tail_lock ____cacheline_aligned;
+	/* index to next in-progress/done descriptor request */
+	int tail;
+};
+
 struct talitos_private {
 	struct device *dev;
 	struct of_device *ofdev;
@@ -101,15 +120,6 @@ struct talitos_private {
 	/* SEC Compatibility info */
 	unsigned long features;
 
-	/* next channel to be assigned next incoming descriptor */
-	atomic_t last_chan;
-
-	/* per-channel number of requests pending in channel h/w fifo */
-	atomic_t *submit_count;
-
-	/* per-channel request fifo */
-	struct talitos_request **fifo;
-
 	/*
 	 * length of the request fifo
 	 * fifo_len is chfifo_len rounded up to next power of 2
@@ -117,15 +127,10 @@ struct talitos_private {
 	 */
 	unsigned int fifo_len;
 
-	/* per-channel index to next free descriptor request */
-	int *head;
-
-	/* per-channel index to next in-progress/done descriptor request */
-	int *tail;
+	struct talitos_channel *chan;
 
-	/* per-channel request submission (head) and release (tail) locks */
-	spinlock_t *head_lock;
-	spinlock_t *tail_lock;
+	/* next channel to be assigned next incoming descriptor */
+	atomic_t last_chan ____cacheline_aligned;
 
 	/* request callback tasklet */
 	struct tasklet_struct done_task;
@@ -282,16 +287,16 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc,
 	/* emulate SEC's round-robin channel fifo polling scheme */
 	ch = atomic_inc_return(&priv->last_chan) & (priv->num_channels - 1);
 
-	spin_lock_irqsave(&priv->head_lock[ch], flags);
+	spin_lock_irqsave(&priv->chan[ch].head_lock, flags);
 
-	if (!atomic_inc_not_zero(&priv->submit_count[ch])) {
+	if (!atomic_inc_not_zero(&priv->chan[ch].submit_count)) {
 		/* h/w fifo is full */
-		spin_unlock_irqrestore(&priv->head_lock[ch], flags);
+		spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
 		return -EAGAIN;
 	}
 
-	head = priv->head[ch];
-	request = &priv->fifo[ch][head];
+	head = priv->chan[ch].head;
+	request = &priv->chan[ch].fifo[head];
 
 	/* map descriptor and save caller data */
 	request->dma_desc = dma_map_single(dev, desc, sizeof(*desc),
@@ -300,7 +305,7 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc,
 	request->context = context;
 
 	/* increment fifo head */
-	priv->head[ch] = (priv->head[ch] + 1) & (priv->fifo_len - 1);
+	priv->chan[ch].head = (priv->chan[ch].head + 1) & (priv->fifo_len - 1);
 
 	smp_wmb();
 	request->desc = desc;
@@ -309,7 +314,7 @@ static int talitos_submit(struct device *dev, struct talitos_desc *desc,
 	wmb();
 	out_be32(priv->reg + TALITOS_FF_LO(ch), request->dma_desc);
 
-	spin_unlock_irqrestore(&priv->head_lock[ch], flags);
+	spin_unlock_irqrestore(&priv->chan[ch].head_lock, flags);
 
 	return -EINPROGRESS;
 }
@@ -324,11 +329,11 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
 	unsigned long flags;
 	int tail, status;
 
-	spin_lock_irqsave(&priv->tail_lock[ch], flags);
+	spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
 
-	tail = priv->tail[ch];
-	while (priv->fifo[ch][tail].desc) {
-		request = &priv->fifo[ch][tail];
+	tail = priv->chan[ch].tail;
+	while (priv->chan[ch].fifo[tail].desc) {
+		request = &priv->chan[ch].fifo[tail];
 
 		/* descriptors with their done bits set don't get the error */
 		rmb();
@@ -354,22 +359,22 @@ static void flush_channel(struct device *dev, int ch, int error, int reset_ch)
 		request->desc = NULL;
 
 		/* increment fifo tail */
-		priv->tail[ch] = (tail + 1) & (priv->fifo_len - 1);
+		priv->chan[ch].tail = (tail + 1) & (priv->fifo_len - 1);
 
-		spin_unlock_irqrestore(&priv->tail_lock[ch], flags);
+		spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
 
-		atomic_dec(&priv->submit_count[ch]);
+		atomic_dec(&priv->chan[ch].submit_count);
 
 		saved_req.callback(dev, saved_req.desc, saved_req.context,
 				   status);
 		/* channel may resume processing in single desc error case */
 		if (error && !reset_ch && status == error)
 			return;
-		spin_lock_irqsave(&priv->tail_lock[ch], flags);
-		tail = priv->tail[ch];
+		spin_lock_irqsave(&priv->chan[ch].tail_lock, flags);
+		tail = priv->chan[ch].tail;
 	}
 
-	spin_unlock_irqrestore(&priv->tail_lock[ch], flags);
+	spin_unlock_irqrestore(&priv->chan[ch].tail_lock, flags);
 }
 
 /*
@@ -397,20 +402,20 @@ static void talitos_done(unsigned long data)
 static struct talitos_desc *current_desc(struct device *dev, int ch)
 {
 	struct talitos_private *priv = dev_get_drvdata(dev);
-	int tail = priv->tail[ch];
+	int tail = priv->chan[ch].tail;
 	dma_addr_t cur_desc;
 
 	cur_desc = in_be32(priv->reg + TALITOS_CDPR_LO(ch));
 
-	while (priv->fifo[ch][tail].dma_desc != cur_desc) {
+	while (priv->chan[ch].fifo[tail].dma_desc != cur_desc) {
 		tail = (tail + 1) & (priv->fifo_len - 1);
-		if (tail == priv->tail[ch]) {
+		if (tail == priv->chan[ch].tail) {
 			dev_err(dev, "couldn't locate current descriptor\n");
 			return NULL;
 		}
 	}
 
-	return priv->fifo[ch][tail].desc;
+	return priv->chan[ch].fifo[tail].desc;
 }
 
 /*
@@ -1740,17 +1745,11 @@ static int talitos_remove(struct of_device *ofdev)
 	if (hw_supports(dev, DESC_HDR_SEL0_RNG))
 		talitos_unregister_rng(dev);
 
-	kfree(priv->submit_count);
-	kfree(priv->tail);
-	kfree(priv->head);
-
-	if (priv->fifo)
-		for (i = 0; i < priv->num_channels; i++)
-			kfree(priv->fifo[i]);
+	for (i = 0; i < priv->num_channels; i++)
+		if (priv->chan[i].fifo)
+			kfree(priv->chan[i].fifo);
 
-	kfree(priv->fifo);
-	kfree(priv->head_lock);
-	kfree(priv->tail_lock);
+	kfree(priv->chan);
 
 	if (priv->irq != NO_IRQ) {
 		free_irq(priv->irq, dev);
@@ -1870,58 +1869,34 @@ static int talitos_probe(struct of_device *ofdev,
 	if (of_device_is_compatible(np, "fsl,sec2.1"))
 		priv->features |= TALITOS_FTR_HW_AUTH_CHECK;
 
-	priv->head_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels,
-				  GFP_KERNEL);
-	priv->tail_lock = kmalloc(sizeof(spinlock_t) * priv->num_channels,
-				  GFP_KERNEL);
-	if (!priv->head_lock || !priv->tail_lock) {
-		dev_err(dev, "failed to allocate fifo locks\n");
+	priv->chan = kzalloc(sizeof(struct talitos_channel) *
+			     priv->num_channels, GFP_KERNEL);
+	if (!priv->chan) {
+		dev_err(dev, "failed to allocate channel management space\n");
 		err = -ENOMEM;
 		goto err_out;
 	}
 
 	for (i = 0; i < priv->num_channels; i++) {
-		spin_lock_init(&priv->head_lock[i]);
-		spin_lock_init(&priv->tail_lock[i]);
-	}
-
-	priv->fifo = kmalloc(sizeof(struct talitos_request *) *
-			     priv->num_channels, GFP_KERNEL);
-	if (!priv->fifo) {
-		dev_err(dev, "failed to allocate request fifo\n");
-		err = -ENOMEM;
-		goto err_out;
+		spin_lock_init(&priv->chan[i].head_lock);
+		spin_lock_init(&priv->chan[i].tail_lock);
 	}
 
 	priv->fifo_len = roundup_pow_of_two(priv->chfifo_len);
 
 	for (i = 0; i < priv->num_channels; i++) {
-		priv->fifo[i] = kzalloc(sizeof(struct talitos_request) *
-					priv->fifo_len, GFP_KERNEL);
-		if (!priv->fifo[i]) {
+		priv->chan[i].fifo = kzalloc(sizeof(struct talitos_request) *
+					     priv->fifo_len, GFP_KERNEL);
+		if (!priv->chan[i].fifo) {
 			dev_err(dev, "failed to allocate request fifo %d\n", i);
 			err = -ENOMEM;
 			goto err_out;
 		}
 	}
 
-	priv->submit_count = kmalloc(sizeof(atomic_t) * priv->num_channels,
-				     GFP_KERNEL);
-	if (!priv->submit_count) {
-		dev_err(dev, "failed to allocate fifo submit count space\n");
-		err = -ENOMEM;
-		goto err_out;
-	}
 	for (i = 0; i < priv->num_channels; i++)
-		atomic_set(&priv->submit_count[i], -(priv->chfifo_len - 1));
-
-	priv->head = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL);
-	priv->tail = kzalloc(sizeof(int) * priv->num_channels, GFP_KERNEL);
-	if (!priv->head || !priv->tail) {
-		dev_err(dev, "failed to allocate request index space\n");
-		err = -ENOMEM;
-		goto err_out;
-	}
+		atomic_set(&priv->chan[i].submit_count,
+			   -(priv->chfifo_len - 1));
 
 	/* reset and initialize the h/w */
 	err = init_device(dev);
-- 
1.6.3

^ permalink raw reply related

* [PATCH 1/3] crypto: talitos - simplify hmac data size calculation
From: Kim Phillips @ 2009-08-07 23:39 UTC (permalink / raw)
  To: linux-crypto; +Cc: linuxppc-dev

don't do request->src vs. assoc pointer math - it's the same as adding
assoclen and ivsize (just with more effort).

Signed-off-by: Kim Phillips <kim.phillips@freescale.com>
---
 drivers/crypto/talitos.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/crypto/talitos.c b/drivers/crypto/talitos.c
index c70775f..b1a651c 100644
--- a/drivers/crypto/talitos.c
+++ b/drivers/crypto/talitos.c
@@ -970,7 +970,7 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
 	struct talitos_desc *desc = &edesc->desc;
 	unsigned int cryptlen = areq->cryptlen;
 	unsigned int authsize = ctx->authsize;
-	unsigned int ivsize;
+	unsigned int ivsize = crypto_aead_ivsize(aead);
 	int sg_count, ret;
 	int sg_link_tbl_len;
 
@@ -978,11 +978,9 @@ static int ipsec_esp(struct talitos_edesc *edesc, struct aead_request *areq,
 	map_single_talitos_ptr(dev, &desc->ptr[0], ctx->authkeylen, &ctx->key,
 			       0, DMA_TO_DEVICE);
 	/* hmac data */
-	map_single_talitos_ptr(dev, &desc->ptr[1], sg_virt(areq->src) -
-			       sg_virt(areq->assoc), sg_virt(areq->assoc), 0,
-			       DMA_TO_DEVICE);
+	map_single_talitos_ptr(dev, &desc->ptr[1], areq->assoclen + ivsize,
+			       sg_virt(areq->assoc), 0, DMA_TO_DEVICE);
 	/* cipher iv */
-	ivsize = crypto_aead_ivsize(aead);
 	map_single_talitos_ptr(dev, &desc->ptr[2], ivsize, giv ?: areq->iv, 0,
 			       DMA_TO_DEVICE);
 
-- 
1.6.3

^ permalink raw reply related

* Re: sequoia: The final kernel image would overwrite the device tree
From: Benjamin Herrenschmidt @ 2009-08-07 21:03 UTC (permalink / raw)
  To: Geert Uytterhoeven; +Cc: Linux/PPC Development, Stefan Roese
In-Reply-To: <alpine.LRH.2.00.0908071740410.22357@vixen.sonytel.be>

On Fri, 2009-08-07 at 17:48 +0200, Geert Uytterhoeven wrote:
> | Allocating 0x85e784 bytes for kernel ...
> | platform_ops.vmlinux_alloc = 0x00000000
> | _end = 0x792000
> | The final kernel image would overwrite the device tree?
> 
> and it reboots.
> 
> However, nm says _end = c085f000.
> 
> So in both cases _end is not correct in
> arch/powerpc/boot/main.c:prep_kernel()?
> But depending on CONFIG_PROVE_LOCKING, the test for
> ((unsigned long)_end < ei.memsize) gives different results, and the
> kernel
> boots or doesn't boot?
> 
Well, "Allocating 0x85e784" looks right...

My experience, however, with a Canyonlands board, is that uBoot has
a bug that makes it always allocate the device-tree below 8M and clash
with the kernel when it gets too big.

I think Stefan fixed that recently, you may need to rebuild your uboot,
I'll let him tell you the details about the fix.

Cheers,
Ben.

^ permalink raw reply

* [PATCH 7/7] powerpc/85xx: Add eSDHC support for MPC8536DS boards
From: Anton Vorontsov @ 2009-08-07 19:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel
In-Reply-To: <20090807195724.GA24020@oksana.dev.rtsoft.ru>

This patch simply adds sdhci node to the device tree.

We specify clock-frequency manually, so that eSDHC will work without
upgrading U-Boot. Though, that'll only work for default setup (1500
MHz) on new board revisions. For non-default setups, it's recommended
to upgrade U-Boot, since it will fixup clock-frequency automatically.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 arch/powerpc/boot/dts/mpc8536ds.dts |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/arch/powerpc/boot/dts/mpc8536ds.dts b/arch/powerpc/boot/dts/mpc8536ds.dts
index 22caf69..815cebb 100644
--- a/arch/powerpc/boot/dts/mpc8536ds.dts
+++ b/arch/powerpc/boot/dts/mpc8536ds.dts
@@ -250,6 +250,14 @@
 			phy_type = "ulpi";
 		};
 
+		sdhci@2e000 {
+			compatible = "fsl,mpc8536-esdhc", "fsl,esdhc";
+			reg = <0x2e000 0x1000>;
+			interrupts = <72 0x2>;
+			interrupt-parent = <&mpic>;
+			clock-frequency = <250000000>;
+		};
+
 		serial0: serial@4500 {
 			cell-index = <0>;
 			device_type = "serial";
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 6/7] sdhci-of: Cleanup eSDHC's set_clock() a little bit
From: Anton Vorontsov @ 2009-08-07 19:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel
In-Reply-To: <20090807195724.GA24020@oksana.dev.rtsoft.ru>

- Get rid of incomprehensible "if { for { if } }" construction for the
  exponential divisor calculation. The first if statement isn't correct
  at all, since it should check for "host->max_clk / pre_div / 16 >
  clock". The error doesn't cause any bugs because the check in the for
  loop does the right thing, and so the outer check becomes useless;

- For the linear divisor do the same: a single while statement is more
  readable than for + if construction;

- Add dev_dbg() that prints desired and actual clock frequency.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/mmc/host/sdhci-of.c |   19 ++++++++-----------
 1 files changed, 8 insertions(+), 11 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
index 87aaf4b..048bc01 100644
--- a/drivers/mmc/host/sdhci-of.c
+++ b/drivers/mmc/host/sdhci-of.c
@@ -121,8 +121,8 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
 
 static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
 {
-	int div;
 	int pre_div = 2;
+	int div = 1;
 
 	clrbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
 		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN | ESDHC_CLOCK_MASK);
@@ -130,17 +130,14 @@ static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
 	if (clock == 0)
 		goto out;
 
-	if (host->max_clk / 16 > clock) {
-		for (; pre_div < 256; pre_div *= 2) {
-			if (host->max_clk / pre_div < clock * 16)
-				break;
-		}
-	}
+	while (host->max_clk / pre_div / 16 > clock && pre_div < 256)
+		pre_div *= 2;
 
-	for (div = 1; div <= 16; div++) {
-		if (host->max_clk / (div * pre_div) <= clock)
-			break;
-	}
+	while (host->max_clk / pre_div / div > clock && div < 16)
+		div++;
+
+	dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
+		clock, host->max_clk / pre_div / div);
 
 	pre_div >>= 1;
 	div--;
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 5/7] sdhci-of: Don't hard-code inverted write-protect quirk
From: Anton Vorontsov @ 2009-08-07 19:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel
In-Reply-To: <20090807195724.GA24020@oksana.dev.rtsoft.ru>

MPC85xx SOCs have normal write-protect state reporting, so we shouldn't
hard-code the quirk.

Instead, look for "sdhci,wp-inverted" property, plus check for
mpc837x_{rdb,mds} machines since older device trees don't specify the
new property.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/mmc/host/sdhci-of.c |   14 +++++++++++++-
 1 files changed, 13 insertions(+), 1 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
index 004f24d..87aaf4b 100644
--- a/drivers/mmc/host/sdhci-of.c
+++ b/drivers/mmc/host/sdhci-of.c
@@ -21,6 +21,7 @@
 #include <linux/of.h>
 #include <linux/of_platform.h>
 #include <linux/mmc/host.h>
+#include <asm/machdep.h>
 #include "sdhci.h"
 
 struct sdhci_of_data {
@@ -175,7 +176,6 @@ static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
 static struct sdhci_of_data sdhci_esdhc = {
 	.quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
 		  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
-		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
 		  SDHCI_QUIRK_NO_BUSY_IRQ |
 		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
 		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
@@ -219,6 +219,15 @@ static int sdhci_of_resume(struct of_device *ofdev)
 
 #endif
 
+static bool __devinit sdhci_of_wp_inverted(struct device_node *np)
+{
+	if (of_get_property(np, "sdhci,wp-inverted", NULL))
+		return true;
+
+	/* Old device trees don't have the wp-inverted property. */
+	return machine_is(mpc837x_rdb) || machine_is(mpc837x_mds);
+}
+
 static int __devinit sdhci_of_probe(struct of_device *ofdev,
 				 const struct of_device_id *match)
 {
@@ -261,6 +270,9 @@ static int __devinit sdhci_of_probe(struct of_device *ofdev,
 	if (of_get_property(np, "sdhci,1-bit-only", NULL))
 		host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
 
+	if (sdhci_of_wp_inverted(np))
+		host->quirks |= SDHCI_QUIRK_INVERTED_WRITE_PROTECT;
+
 	clk = of_get_property(np, "clock-frequency", &size);
 	if (clk && size == sizeof(*clk) && *clk)
 		of_host->clock = *clk;
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 4/7] powerpc: Introduce and document sdhci,wp-inverted property for eSDHC
From: Anton Vorontsov @ 2009-08-07 19:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel
In-Reply-To: <20090807195724.GA24020@oksana.dev.rtsoft.ru>

eSDHC block in MPC837x SOCs reports inverted write-protect state,
soon sdhci-of driver will look for sdhci,wp-inverted properties to
decide whether apply a specific quirk.

So, document the property and add it to device tree source files.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 Documentation/powerpc/dts-bindings/fsl/esdhc.txt |    2 ++
 arch/powerpc/boot/dts/mpc8377_mds.dts            |    1 +
 arch/powerpc/boot/dts/mpc8377_rdb.dts            |    1 +
 arch/powerpc/boot/dts/mpc8377_wlan.dts           |    1 +
 arch/powerpc/boot/dts/mpc8378_mds.dts            |    1 +
 arch/powerpc/boot/dts/mpc8378_rdb.dts            |    1 +
 arch/powerpc/boot/dts/mpc8379_mds.dts            |    1 +
 arch/powerpc/boot/dts/mpc8379_rdb.dts            |    1 +
 8 files changed, 9 insertions(+), 0 deletions(-)

diff --git a/Documentation/powerpc/dts-bindings/fsl/esdhc.txt b/Documentation/powerpc/dts-bindings/fsl/esdhc.txt
index 3ed3797..8a00407 100644
--- a/Documentation/powerpc/dts-bindings/fsl/esdhc.txt
+++ b/Documentation/powerpc/dts-bindings/fsl/esdhc.txt
@@ -10,6 +10,8 @@ Required properties:
   - interrupts : should contain eSDHC interrupt.
   - interrupt-parent : interrupt source phandle.
   - clock-frequency : specifies eSDHC base clock frequency.
+  - sdhci,wp-inverted : (optional) specifies that eSDHC controller
+    reports inverted write-protect state;
   - sdhci,1-bit-only : (optional) specifies that a controller can
     only handle 1-bit data transfers.
 
diff --git a/arch/powerpc/boot/dts/mpc8377_mds.dts b/arch/powerpc/boot/dts/mpc8377_mds.dts
index f32c281..855782c 100644
--- a/arch/powerpc/boot/dts/mpc8377_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8377_mds.dts
@@ -159,6 +159,7 @@
 				reg = <0x2e000 0x1000>;
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
+				sdhci,wp-inverted;
 				/* Filled in by U-Boot */
 				clock-frequency = <0>;
 			};
diff --git a/arch/powerpc/boot/dts/mpc8377_rdb.dts b/arch/powerpc/boot/dts/mpc8377_rdb.dts
index 28e022a..9e2264b 100644
--- a/arch/powerpc/boot/dts/mpc8377_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8377_rdb.dts
@@ -173,6 +173,7 @@
 				reg = <0x2e000 0x1000>;
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
+				sdhci,wp-inverted;
 				/* Filled in by U-Boot */
 				clock-frequency = <111111111>;
 			};
diff --git a/arch/powerpc/boot/dts/mpc8377_wlan.dts b/arch/powerpc/boot/dts/mpc8377_wlan.dts
index 3febc4e..9a60369 100644
--- a/arch/powerpc/boot/dts/mpc8377_wlan.dts
+++ b/arch/powerpc/boot/dts/mpc8377_wlan.dts
@@ -150,6 +150,7 @@
 				reg = <0x2e000 0x1000>;
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
+				sdhci,wp-inverted;
 				clock-frequency = <133333333>;
 			};
 		};
diff --git a/arch/powerpc/boot/dts/mpc8378_mds.dts b/arch/powerpc/boot/dts/mpc8378_mds.dts
index f720ab9..f70cf60 100644
--- a/arch/powerpc/boot/dts/mpc8378_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8378_mds.dts
@@ -159,6 +159,7 @@
 				reg = <0x2e000 0x1000>;
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
+				sdhci,wp-inverted;
 				/* Filled in by U-Boot */
 				clock-frequency = <0>;
 			};
diff --git a/arch/powerpc/boot/dts/mpc8378_rdb.dts b/arch/powerpc/boot/dts/mpc8378_rdb.dts
index a11ead8..4e6a1a4 100644
--- a/arch/powerpc/boot/dts/mpc8378_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8378_rdb.dts
@@ -173,6 +173,7 @@
 				reg = <0x2e000 0x1000>;
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
+				sdhci,wp-inverted;
 				/* Filled in by U-Boot */
 				clock-frequency = <111111111>;
 			};
diff --git a/arch/powerpc/boot/dts/mpc8379_mds.dts b/arch/powerpc/boot/dts/mpc8379_mds.dts
index 4fa221f..645ec51 100644
--- a/arch/powerpc/boot/dts/mpc8379_mds.dts
+++ b/arch/powerpc/boot/dts/mpc8379_mds.dts
@@ -157,6 +157,7 @@
 				reg = <0x2e000 0x1000>;
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
+				sdhci,wp-inverted;
 				/* Filled in by U-Boot */
 				clock-frequency = <0>;
 			};
diff --git a/arch/powerpc/boot/dts/mpc8379_rdb.dts b/arch/powerpc/boot/dts/mpc8379_rdb.dts
index e35dfba..72336d5 100644
--- a/arch/powerpc/boot/dts/mpc8379_rdb.dts
+++ b/arch/powerpc/boot/dts/mpc8379_rdb.dts
@@ -171,6 +171,7 @@
 				reg = <0x2e000 0x1000>;
 				interrupts = <42 0x8>;
 				interrupt-parent = <&ipic>;
+				sdhci,wp-inverted;
 				/* Filled in by U-Boot */
 				clock-frequency = <111111111>;
 			};
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 3/7] sdhci-of: Fix high-speed cards recognition
From: Anton Vorontsov @ 2009-08-07 19:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel
In-Reply-To: <20090807195724.GA24020@oksana.dev.rtsoft.ru>

eSDHC fails to recognize some SDHS cards, throwing timeout errors:

  mmc0: error -110 whilst initialising SD card

That's because we calculate timeout value in a wrong way: on eSDHC
hosts the timeout clock is derivied from the SD clock, which is set
dynamically.

As David Vrabel suggested, deriving timeout clock from SD clock is
a common scheme, so let's implement DATA_TIMEOUT_USES_SDCLK quirk
and use it for eSDHC hosts.

Also, from now on we don't need esdhc_get_timeout_clock() callback,
so remove it.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/mmc/host/sdhci-of.c |    9 +--------
 drivers/mmc/host/sdhci.c    |    9 +++++++--
 drivers/mmc/host/sdhci.h    |    2 ++
 3 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
index 8440fd9..004f24d 100644
--- a/drivers/mmc/host/sdhci-of.c
+++ b/drivers/mmc/host/sdhci-of.c
@@ -172,19 +172,13 @@ static unsigned int esdhc_get_min_clock(struct sdhci_host *host)
 	return of_host->clock / 256 / 16;
 }
 
-static unsigned int esdhc_get_timeout_clock(struct sdhci_host *host)
-{
-	struct sdhci_of_host *of_host = sdhci_priv(host);
-
-	return of_host->clock / 1000;
-}
-
 static struct sdhci_of_data sdhci_esdhc = {
 	.quirks = SDHCI_QUIRK_FORCE_BLK_SZ_2048 |
 		  SDHCI_QUIRK_BROKEN_CARD_DETECTION |
 		  SDHCI_QUIRK_INVERTED_WRITE_PROTECT |
 		  SDHCI_QUIRK_NO_BUSY_IRQ |
 		  SDHCI_QUIRK_NONSTANDARD_CLOCK |
+		  SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK |
 		  SDHCI_QUIRK_PIO_NEEDS_DELAY |
 		  SDHCI_QUIRK_RESTORE_IRQS_AFTER_RESET |
 		  SDHCI_QUIRK_NO_CARD_NO_RESET,
@@ -199,7 +193,6 @@ static struct sdhci_of_data sdhci_esdhc = {
 		.enable_dma = esdhc_enable_dma,
 		.get_max_clock = esdhc_get_max_clock,
 		.get_min_clock = esdhc_get_min_clock,
-		.get_timeout_clock = esdhc_get_timeout_clock,
 	},
 };
 
diff --git a/drivers/mmc/host/sdhci.c b/drivers/mmc/host/sdhci.c
index fc96f8c..288e40b 100644
--- a/drivers/mmc/host/sdhci.c
+++ b/drivers/mmc/host/sdhci.c
@@ -591,6 +591,9 @@ static u8 sdhci_calc_timeout(struct sdhci_host *host, struct mmc_data *data)
 	target_timeout = data->timeout_ns / 1000 +
 		data->timeout_clks / host->clock;
 
+	if (host->quirks & SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)
+		host->timeout_clk = host->clock / 1000;
+
 	/*
 	 * Figure out needed cycles.
 	 * We do this in steps in order to fit inside a 32 bit int.
@@ -1757,13 +1760,15 @@ int sdhci_add_host(struct sdhci_host *host)
 	host->timeout_clk =
 		(caps & SDHCI_TIMEOUT_CLK_MASK) >> SDHCI_TIMEOUT_CLK_SHIFT;
 	if (host->timeout_clk == 0) {
-		if (!host->ops->get_timeout_clock) {
+		if (host->ops->get_timeout_clock) {
+			host->timeout_clk = host->ops->get_timeout_clock(host);
+		} else if (!(host->quirks &
+				SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK)) {
 			printk(KERN_ERR
 			       "%s: Hardware doesn't specify timeout clock "
 			       "frequency.\n", mmc_hostname(mmc));
 			return -ENODEV;
 		}
-		host->timeout_clk = host->ops->get_timeout_clock(host);
 	}
 	if (caps & SDHCI_TIMEOUT_CLK_UNIT)
 		host->timeout_clk *= 1000;
diff --git a/drivers/mmc/host/sdhci.h b/drivers/mmc/host/sdhci.h
index c77e9ff..afda7f1 100644
--- a/drivers/mmc/host/sdhci.h
+++ b/drivers/mmc/host/sdhci.h
@@ -232,6 +232,8 @@ struct sdhci_host {
 #define SDHCI_QUIRK_FORCE_1_BIT_DATA			(1<<22)
 /* Controller needs 10ms delay between applying power and clock */
 #define SDHCI_QUIRK_DELAY_AFTER_POWER			(1<<23)
+/* Controller uses SDCLK instead of TMCLK for data timeouts */
+#define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK		(1<<24)
 
 	int			irq;		/* Device IRQ */
 	void __iomem *		ioaddr;		/* Mapped address */
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 2/7] sdhci-of: Avoid writing reserved bits into host control register
From: Anton Vorontsov @ 2009-08-07 19:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel
In-Reply-To: <20090807195724.GA24020@oksana.dev.rtsoft.ru>

SDHCI core tries to write HISPD bit into the host control register,
but the eSDHC controllers don't have that bit, and that causes
all sorts of misbehaviour when using 4-bit mode capable SD cards.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/mmc/host/sdhci-of.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
index 92b5667..8440fd9 100644
--- a/drivers/mmc/host/sdhci-of.c
+++ b/drivers/mmc/host/sdhci-of.c
@@ -48,6 +48,8 @@ struct sdhci_of_host {
 #define ESDHC_CLOCK_HCKEN	0x00000002
 #define ESDHC_CLOCK_IPGEN	0x00000001
 
+#define ESDHC_HOST_CONTROL_RES	0x05
+
 static u32 esdhc_readl(struct sdhci_host *host, int reg)
 {
 	return in_be32(host->ioaddr + reg);
@@ -109,6 +111,10 @@ static void esdhc_writeb(struct sdhci_host *host, u8 val, int reg)
 	int base = reg & ~0x3;
 	int shift = (reg & 0x3) * 8;
 
+	/* Prevent SDHCI core from writing reserved bits (e.g. HISPD). */
+	if (reg == SDHCI_HOST_CONTROL)
+		val &= ~ESDHC_HOST_CONTROL_RES;
+
 	clrsetbits_be32(host->ioaddr + base , 0xff << shift, val << shift);
 }
 
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH 1/7] sdhci-of: Fix SD clock calculation
From: Anton Vorontsov @ 2009-08-07 19:58 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel
In-Reply-To: <20090807195724.GA24020@oksana.dev.rtsoft.ru>

Linear divisor's values in a register start at 0 (zero means
"divide by 1"). Before this patch the code didn't account that
fact, so SD cards were running underclocked.

Signed-off-by: Anton Vorontsov <avorontsov@ru.mvista.com>
---
 drivers/mmc/host/sdhci-of.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

diff --git a/drivers/mmc/host/sdhci-of.c b/drivers/mmc/host/sdhci-of.c
index 9088443..92b5667 100644
--- a/drivers/mmc/host/sdhci-of.c
+++ b/drivers/mmc/host/sdhci-of.c
@@ -136,6 +136,7 @@ static void esdhc_set_clock(struct sdhci_host *host, unsigned int clock)
 	}
 
 	pre_div >>= 1;
+	div--;
 
 	setbits32(host->ioaddr + ESDHC_SYSTEM_CONTROL, ESDHC_CLOCK_IPGEN |
 		  ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN |
-- 
1.6.3.3

^ permalink raw reply related

* [PATCH v2 0/7] sdhci-of: Some fixes for high-speed and 4-bit SD cards
From: Anton Vorontsov @ 2009-08-07 19:57 UTC (permalink / raw)
  To: Andrew Morton
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Pierre Ossman,
	David Vrabel

In v2:

- Addressed David Vrabel's comments;
- New patches added:
  powerpc: Introduce and document sdhci,wp-inverted property for eSDHC
  sdhci-of: Don't hard-code inverted write-protect quirk
  powerpc/85xx: Add eSDHC support for MPC8536DS boards

^ permalink raw reply

* Re: 5121 cache handling.
From: Scott Wood @ 2009-08-07 19:56 UTC (permalink / raw)
  To: Kenneth Johansson; +Cc: linuxppc-dev
In-Reply-To: <1249649632.4940.38.camel@localhost>

On Fri, Aug 07, 2009 at 02:53:52PM +0200, Kenneth Johansson wrote:
> on 5121 there is a e300 core that unfortunately is connected to the rest
> of the SOC with a bus that do not support coherency.
> 
> solution for many driver has been to use uncached memory. But for the
> framebuffer that is not going to work as the performance impact of doing
> graphics operations on uncached memory is to large.
> 
> currently the "solution" is to flush the cache in the interrupt
> handler. 
> 
> #if defined(CONFIG_NOT_COHERENT_CACHE)
>                         int i;
>                         unsigned int *ptr;
>                         ptr  = coherence_data;
>                         for (i = 0; i < 1024*8; i++)
>                                 *ptr++ = 0;
> #endif
> 
> Now this apparently is not enough on a e300 core that has a PLRU cache
> replacement algorithm. but what is the optimal solution? 

Which driver (in which kernel) are you looking at?

drivers/video/fsl-diu-fb.c in current mainline has properly sized
coherence data.  It also does a dcbz (on unused data) instead of loads,
as it's apparently faster (though I'd think you'd get more traffic
flushing those zeroes out later on, compared to a clean line that can
just be discarded).

> should not the framebuffer be marked as cache write through. that is the
> W bit should be set in the tlb mapping. Why is this not done ? is that
> feature also not working on 5121 ??

It probably would have been too slow.

> problem with doing it over just the framebuffer is that a 1024x768
> buffer is 98304 cache lines it's going to take a considerable time to
> do. 

That's why we flush the whole cache instead.

> how many cycles does it take per cache line if we never get a hit ??
> 3cycles at 400MHz gives 4.5milisec/sec or 4-5% overhead
> 
> 1024*768*4/32*3*(1/400000000)*60
> .04423680000000000000
> 
> 52kB on the other hand is only 1664 lines but is obviously going to have
> to do a lot of actual memory writes also for any modified cache line and
> later a lot of reads to read back what was evicted. 

During periods of framebuffer activity, a lot of those cache lines likely
are for the framebuffer, so you'll still have those same issues.

If current performance is inadequate, you may want to consider using the
MMU and timers to figure out when the framebuffer is active, and stop the
sync when it's not.

-Scott

^ permalink raw reply

* Re: Question about powerpc branch instructions
From: Scott Wood @ 2009-08-07 19:37 UTC (permalink / raw)
  To: HongWoo Lee; +Cc: linuxppc-dev
In-Reply-To: <4A7BEA04.7030006@gmail.com>

On Fri, Aug 07, 2009 at 05:47:00PM +0900, HongWoo Lee wrote:
> #2: Is b similar to the jmp in x86 ? 

Yes, specifically a relative near jmp.

> and bl is similar to the call in x86 ?

Sort of (and again, specifically a relative near call).  Call on x86
pushes the return address on the stack, while bl on powerpc puts the
return address in a special register (lr) that the called function has to
save on the stack itself if it wants to call another function.

-Scott

^ permalink raw reply

* [PATCH V2] Use clock freqency from the device tree to calculate correct MPC5200 PSC clock.
From: Jon Smirl @ 2009-08-07 19:19 UTC (permalink / raw)
  To: grant.likely, Linuxppc-dev

Use clock freqency from the device tree to calculate correct MPC5200 PSC clock.
Previous code had errors or used a constant. This versions computes
the right clock based on the xtal and register settings.

Signed-off-by: Jon Smirl <jonsmirl@gmail.com>
---
 arch/powerpc/include/asm/mpc52xx.h           |    2 +-
 arch/powerpc/platforms/52xx/mpc52xx_common.c |   26 ++++++++++++++++++++++++--
 drivers/spi/mpc52xx_psc_spi.c                |    8 +-------
 sound/soc/fsl/mpc5200_psc_i2s.c              |   11 +----------
 4 files changed, 27 insertions(+), 20 deletions(-)

diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/asm/mpc52xx.h
index cadd398..1ca8a0e 100644
--- a/arch/powerpc/include/asm/mpc52xx.h
+++ b/arch/powerpc/include/asm/mpc52xx.h
@@ -285,7 +285,7 @@ struct mpc52xx_rtc {
 extern void mpc5200_setup_xlb_arbiter(void);
 extern void mpc52xx_declare_of_platform_devices(void);
 extern void mpc52xx_map_common_devices(void);
-extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
+extern int mpc52xx_set_psc_clkdiv(int psc_id, int freq);
 extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
 extern void mpc52xx_restart(char *cmd);
 
diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/platforms/52xx/mpc52xx_common.c
index a46bad0..8a19156 100644
--- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
+++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
@@ -110,6 +110,8 @@ static struct of_device_id mpc52xx_cdm_ids[] __initdata = {
 	{}
 };
 
+static u32 mpc52xx_fsystem; /* fsystem clock on mpc5200 */
+
 /**
  * mpc52xx_map_common_devices: iomap devices required by common code
  */
@@ -117,6 +119,7 @@ void __init
 mpc52xx_map_common_devices(void)
 {
 	struct device_node *np;
+	u32 val;
 
 	/* mpc52xx_wdt is mapped here and used in mpc52xx_restart,
 	 * possibly from a interrupt context. wdt is only implement
@@ -133,8 +136,16 @@ mpc52xx_map_common_devices(void)
 
 	/* Clock Distribution Module, used by PSC clock setting function */
 	np = of_find_matching_node(NULL, mpc52xx_cdm_ids);
+	mpc52xx_fsystem = mpc5xxx_get_bus_frequency(np);
 	mpc52xx_cdm = of_iomap(np, 0);
 	of_node_put(np);
+
+	/* compute fsystem, it is either 4 or 8 times the bus freq */
+	val = in_be32(&mpc52xx_cdm->rstcfg);
+	if (val & (1 << 5))
+		mpc52xx_fsystem *= 8;
+	else
+		mpc52xx_fsystem *= 4;
 }
 
 /**
@@ -143,17 +154,28 @@ mpc52xx_map_common_devices(void)
  * @psc_id: id of psc port; must be 1,2,3 or 6
  * @clkdiv: clock divider value to put into CDM PSC register.
  */
-int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv)
+int mpc52xx_set_psc_clkdiv(int psc_id, int freq)
 {
 	unsigned long flags;
 	u16 __iomem *reg;
 	u32 val;
-	u32 mask;
+	u32 mask, clkdiv, err;
 	u32 mclken_div;
 
 	if (!mpc52xx_cdm)
 		return -ENODEV;
 
+	/* figure out the closest frequency the hardware can make */
+	clkdiv = mpc52xx_fsystem / freq;
+	err = mpc52xx_fsystem % freq;
+	if (err > freq / 2)
+		clkdiv++;
+	/* hardware is not very flexible, there will be significant error */
+	/* frequency error = fsystem / clkdiv - freq; */
+
+	/* hardware adds one to the divisor */
+	clkdiv -= 1;
+
 	mclken_div = 0x8000 | (clkdiv & 0x1FF);
 	switch (psc_id) {
 	case 1: reg = &mpc52xx_cdm->mclken_div_psc1; mask = 0x20; break;
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index d2a04d6..5c8e621 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -33,7 +33,6 @@
 struct mpc52xx_psc_spi {
 	/* fsl_spi_platform data */
 	void (*cs_control)(struct spi_device *spi, bool on);
-	u32 sysclk;
 
 	/* driver internal data */
 	struct mpc52xx_psc __iomem *psc;
@@ -313,12 +312,9 @@ static int mpc52xx_psc_spi_port_config(int psc_id, struct mpc52xx_psc_spi *mps)
 {
 	struct mpc52xx_psc __iomem *psc = mps->psc;
 	struct mpc52xx_psc_fifo __iomem *fifo = mps->fifo;
-	u32 mclken_div;
 	int ret = 0;
 
-	/* default sysclk is 512MHz */
-	mclken_div = (mps->sysclk ? mps->sysclk : 512000000) / MCLK;
-	mpc52xx_set_psc_clkdiv(psc_id, mclken_div);
+	mpc52xx_set_psc_clkdiv(psc_id, MCLK);
 
 	/* Reset the PSC into a known state */
 	out_8(&psc->command, MPC52xx_PSC_RST_RX);
@@ -383,12 +379,10 @@ static int __init mpc52xx_psc_spi_do_probe(struct of_device *op, u32 regaddr,
 		dev_warn(&op->dev, "probe called without platform data, no "
 				"cs_control function will be called\n");
 		mps->cs_control = NULL;
-		mps->sysclk = 0;
 		master->bus_num = bus_num;
 		master->num_chipselect = 255;
 	} else {
 		mps->cs_control = pdata->cs_control;
-		mps->sysclk = pdata->sysclk;
 		master->bus_num = pdata->bus_num;
 		master->num_chipselect = pdata->max_chipselect;
 	}
diff --git a/sound/soc/fsl/mpc5200_psc_i2s.c b/sound/soc/fsl/mpc5200_psc_i2s.c
index c58fcde..8de4719 100644
--- a/sound/soc/fsl/mpc5200_psc_i2s.c
+++ b/sound/soc/fsl/mpc5200_psc_i2s.c
@@ -115,7 +115,6 @@ static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
 			      int clk_id, unsigned int freq, int dir)
 {
 	struct psc_dma *psc_dma = cpu_dai->private_data;
-	int clkdiv, err;
 
 	dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(cpu_dai=%p, freq=%u, dir=%i)\n",
 				cpu_dai, freq, dir);
@@ -128,15 +127,7 @@ static int psc_i2s_set_sysclk(struct snd_soc_dai *cpu_dai,
 			psc_dma->sicr &= ~MPC52xx_PSC_SICR_CELLSLAVE;
 			psc_dma->sicr |= MPC52xx_PSC_SICR_GENCLK;
 
-			clkdiv = ppc_proc_freq / freq;
-			err = ppc_proc_freq % freq;
-			if (err > freq / 2)
-				clkdiv++;
-
-			dev_dbg(psc_dma->dev, "psc_i2s_set_sysclk(clkdiv %d freq error=%ldHz)\n",
-					clkdiv, (ppc_proc_freq / clkdiv - freq));
-
-			return mpc52xx_set_psc_clkdiv(psc_dma->id + 1, clkdiv);
+			return mpc52xx_set_psc_clkdiv(psc_dma->id + 1, freq);
 		}
 	}
 	return 0;

^ permalink raw reply related

* Re: [PATCH] Use clock freqency from the device tree to calculate correct MPC5200 PSC clock.
From: Grant Likely @ 2009-08-07 18:49 UTC (permalink / raw)
  To: Jon Smirl; +Cc: Linuxppc-dev
In-Reply-To: <20090807184147.4932.18130.stgit@terra>

On Fri, Aug 7, 2009 at 12:41 PM, Jon Smirl<jonsmirl@gmail.com> wrote:
> Use clock freqency from the device tree to calculate correct MPC5200 PSC =
clock.
> Previous code had errors or used a constant. This versions computes
> the right clock based on the xtal and register settings.

Looks good to me; one comment below:

> ---
> =A0arch/powerpc/include/asm/mpc52xx.h =A0 =A0 =A0 =A0 =A0 | =A0 =A02 +-
> =A0arch/powerpc/platforms/52xx/mpc52xx_common.c | =A0 26 ++++++++++++++++=
++++++++--
> =A0drivers/spi/mpc52xx_psc_spi.c =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 =A0=
8 +-------
> =A0sound/soc/fsl/mpc5200_psc_i2s.c =A0 =A0 =A0 =A0 =A0 =A0 =A0| =A0 11 +-=
---------
> =A04 files changed, 27 insertions(+), 20 deletions(-)
>
> diff --git a/arch/powerpc/include/asm/mpc52xx.h b/arch/powerpc/include/as=
m/mpc52xx.h
> index cadd398..1ca8a0e 100644
> --- a/arch/powerpc/include/asm/mpc52xx.h
> +++ b/arch/powerpc/include/asm/mpc52xx.h
> @@ -285,7 +285,7 @@ struct mpc52xx_rtc {
> =A0extern void mpc5200_setup_xlb_arbiter(void);
> =A0extern void mpc52xx_declare_of_platform_devices(void);
> =A0extern void mpc52xx_map_common_devices(void);
> -extern int mpc52xx_set_psc_clkdiv(int psc_id, int clkdiv);
> +extern int mpc52xx_set_psc_clkdiv(int psc_id, int freq);
> =A0extern unsigned int mpc52xx_get_xtal_freq(struct device_node *node);
> =A0extern void mpc52xx_restart(char *cmd);
>
> diff --git a/arch/powerpc/platforms/52xx/mpc52xx_common.c b/arch/powerpc/=
platforms/52xx/mpc52xx_common.c
> index a46bad0..f81fb03 100644
> --- a/arch/powerpc/platforms/52xx/mpc52xx_common.c
> +++ b/arch/powerpc/platforms/52xx/mpc52xx_common.c
> @@ -110,6 +110,8 @@ static struct of_device_id mpc52xx_cdm_ids[] __initda=
ta =3D {
> =A0 =A0 =A0 =A0{}
> =A0};
>
> +static u32 fsystem; /* fsystem clock on mpc5200 */
> +

To protect against collisions with the global namespace, please name
this mpc5200_fsystem.

g.

--=20
Grant Likely, B.Sc., P.Eng.
Secret Lab Technologies Ltd.

^ permalink raw reply

* Re: [PATCH 3/4] sdhci-of: Fix high-speed cards recognition
From: Anton Vorontsov @ 2009-08-07 18:43 UTC (permalink / raw)
  To: David Vrabel
  Cc: Ben Dooks, sdhci-devel, linux-kernel, linuxppc-dev, Andrew Morton,
	Pierre Ossman
In-Reply-To: <4A7C5FAB.2020304@csr.com>

On Fri, Aug 07, 2009 at 06:08:59PM +0100, David Vrabel wrote:
> Anton Vorontsov wrote:
> > eSDHC fails to recognize some SDHS cards, throwing timeout errors:
> > 
> >   mmc0: error -110 whilst initialising SD card
> > 
> > That's because we calculate timeout value in a wrong way: on eSDHC
> > hosts the timeout clock is derivied from the SD clock, which is set
> > dynamically.
> 
> I've seen an reference design for an SDHC controller do this also.

Thanks for the information!

> > +/* Controller has dynamic timeout clock management */
> > +#define SDHCI_QUIRK_DYNAMIC_TIMEOUT_CLOCK		(1<<24)
> 
> This comment and define would be better if it matched terms used in the
> spec.  Suggest:
> 
> /* Controller uses SDCLK instead of TMCLK for data timeouts. */
> #define SDHCI_QUIRK_DATA_TIMEOUT_USES_SDCLK  (1 << 24)

Yeah, if it's somewhat common scheme, then it makes sense to name the
quirk that way.

Thanks,

-- 
Anton Vorontsov
email: cbouatmailru@gmail.com
irc://irc.freenode.net/bd2

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox