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

取消
显示结果 
显示  仅  | 搜索替代 
您的意思是: 
已解决

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

跳至解决方案
1,337 次查看
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.

标签 (1)
0 项奖励
回复
1 解答
848 次查看
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 项奖励
回复
2 回复数
848 次查看
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;


849 次查看
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 项奖励
回复