i.MX28 SPI gpio-bitbang running 10x slower in 3.8.4

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

i.MX28 SPI gpio-bitbang running 10x slower in 3.8.4

Jump to solution
1,178 Views
spearson
Contributor III

A gpio-bitbang test app , which was running at approx 800kHz in 2.6.35.3 is now only running at 80kHz (on the same hardware). My SPI configuration in the .dtb file is similar to the 2.6.35 setup and the max-frequency is set at 50MHz so should not be throttling the throughput.

Anyone else experience the same degradation in performance?  Any suggestions what else in the system might be causing this slow-down?

Regards.

Labels (1)
0 Kudos
1 Solution
689 Views
spearson
Contributor III

The gpio-mxs.c file is selecting the generic gpio driver which has more overhead in the set function; gpio-generic.c: bgpio_set_set().  By assigning a set and clear register, the faster bgpio_set_with_clear() function is selected, which contains essentially the same code that was used in 2.6.35.3.

@@ -292,7 +292,8 @@ static int mxs_gpio_probe(struct platfor

     err = bgpio_init(&port->bgc, &pdev->dev, 4,

              port->base + PINCTRL_DIN(port),

-             port->base + PINCTRL_DOUT(port), NULL,

+             port->base + PINCTRL_DOUT(port) + MXS_SET,

+             port->base + PINCTRL_DOUT(port) + MXS_CLR,

              port->base + PINCTRL_DOE(port), NULL, 0);

     if (err)

         goto out_irqdesc_free;


View solution in original post

0 Kudos
2 Replies
689 Views
fabio_estevam
NXP Employee
NXP Employee

Your fix is correct and it has already been fixed in mainline:

kernel/git/torvalds/linux.git - Linux kernel source tree

commit 90dae4ebf03063a70d992aad00d5f5a607c31db8

Author: Maxime Ripard <maxime.ripard@free-electrons.com>

Date:   Mon Apr 29 16:07:18 2013 +0200

    gpio: mxs: Use set and clear capabilities of the gpio controller

   

    The current driver doesn't use the set and clear registers found on the

    mxs gpio controller.

   

    This leads the generic gpio controller to be using some internal value

    to avoid looking up the value stored in the registers, making it behave

    pretty much like a cache.

   

    This raises some coherency problem when a gpio is not modified by the

    gpio controller, while it can easily be fixed by using the set and clear

    registers.

   

    Signed-off-by: Maxime Ripard <maxime.ripard@free-electrons.com>

    Acked-by: Shawn Guo <shawn.guo@linaro.org>

    Signed-off-by: Linus Walleij <linus.walleij@linaro.org>

diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c

index 25000b0..f8e6af2 100644

--- a/drivers/gpio/gpio-mxs.c

+++ b/drivers/gpio/gpio-mxs.c

@@ -326,7 +326,8 @@ static int mxs_gpio_probe(struct platform_device *pdev)

        err = bgpio_init(&port->bgc, &pdev->dev, 4,

                         port->base + PINCTRL_DIN(port),

-                        port->base + PINCTRL_DOUT(port), NULL,

+                        port->base + PINCTRL_DOUT(port) + MXS_SET,

+                        port->base + PINCTRL_DOUT(port) + MXS_CLR,

                         port->base + PINCTRL_DOE(port), NULL, 0);

        if (err)

                goto out_irqdesc_free;


690 Views
spearson
Contributor III

The gpio-mxs.c file is selecting the generic gpio driver which has more overhead in the set function; gpio-generic.c: bgpio_set_set().  By assigning a set and clear register, the faster bgpio_set_with_clear() function is selected, which contains essentially the same code that was used in 2.6.35.3.

@@ -292,7 +292,8 @@ static int mxs_gpio_probe(struct platfor

     err = bgpio_init(&port->bgc, &pdev->dev, 4,

              port->base + PINCTRL_DIN(port),

-             port->base + PINCTRL_DOUT(port), NULL,

+             port->base + PINCTRL_DOUT(port) + MXS_SET,

+             port->base + PINCTRL_DOUT(port) + MXS_CLR,

              port->base + PINCTRL_DOE(port), NULL, 0);

     if (err)

         goto out_irqdesc_free;


0 Kudos