From 1900fe4437df322338b019f1165b0ac405aa0332 Mon Sep 17 00:00:00 2001 From: Julius Werner Date: Tue, 24 Mar 2015 16:12:08 -0700 Subject: [PATCH] rk3288: Fix SPI clock divisor calculation The code to calculate the RK3288 SPI controller's internal clock divisor is wrong: it assumes that the divisor register was an "n-1" divisor when it actually isn't (due to some misleading kernel code that was copied in here). This means that all SPI clocks are currently running lower than expected. This patch fixes the calculation and changes all callers such that the effective speeds stay the same. BRANCH=veyron BUG=chrome-os-partner:38352 TEST=Booted Jerry with and without the patch, dumping the divisor for flash and EC clocks. Made sure it stays the same. Change-Id: I094d57a5933c8b849f5c66194e6cc2952ab68b90 Signed-off-by: Julius Werner Reviewed-on: https://chromium-review.googlesource.com/262269 Reviewed-by: David Hendricks (cherry picked from commit 1fd5b990f937019a9bee7bd693c91d6e2fca1adb) jwerner: Added Gus, Jaq and Minnie, removed Danger and Rialto. Replaced write32() with writel(). Signed-off-by: Julius Werner Reviewed-on: https://chromium-review.googlesource.com/262805 --- src/mainboard/google/veyron_brain/bootblock.c | 2 +- src/mainboard/google/veyron_gus/bootblock.c | 4 ++-- src/mainboard/google/veyron_jaq/bootblock.c | 4 ++-- src/mainboard/google/veyron_jerry/bootblock.c | 4 ++-- src/mainboard/google/veyron_mighty/bootblock.c | 4 ++-- src/mainboard/google/veyron_minnie/bootblock.c | 4 ++-- src/mainboard/google/veyron_pinky/bootblock.c | 4 ++-- src/mainboard/google/veyron_speedy/bootblock.c | 4 ++-- src/soc/rockchip/rk3288/spi.c | 8 ++------ 9 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/mainboard/google/veyron_brain/bootblock.c b/src/mainboard/google/veyron_brain/bootblock.c index 8650e0eea2..ffa4bdecf8 100644 --- a/src/mainboard/google/veyron_brain/bootblock.c +++ b/src/mainboard/google/veyron_brain/bootblock.c @@ -70,7 +70,7 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); setup_chromeos_gpios(); } diff --git a/src/mainboard/google/veyron_gus/bootblock.c b/src/mainboard/google/veyron_gus/bootblock.c index 2f012ec80e..cbb55ea4d2 100644 --- a/src/mainboard/google/veyron_gus/bootblock.c +++ b/src/mainboard/google/veyron_gus/bootblock.c @@ -68,11 +68,11 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); /* spi0 for chrome ec */ writel(IOMUX_SPI0, &rk3288_grf->iomux_spi0); - rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 9*MHz); + rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 8250*KHz); setup_chromeos_gpios(); } diff --git a/src/mainboard/google/veyron_jaq/bootblock.c b/src/mainboard/google/veyron_jaq/bootblock.c index 2f012ec80e..cbb55ea4d2 100644 --- a/src/mainboard/google/veyron_jaq/bootblock.c +++ b/src/mainboard/google/veyron_jaq/bootblock.c @@ -68,11 +68,11 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); /* spi0 for chrome ec */ writel(IOMUX_SPI0, &rk3288_grf->iomux_spi0); - rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 9*MHz); + rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 8250*KHz); setup_chromeos_gpios(); } diff --git a/src/mainboard/google/veyron_jerry/bootblock.c b/src/mainboard/google/veyron_jerry/bootblock.c index 2f012ec80e..cbb55ea4d2 100644 --- a/src/mainboard/google/veyron_jerry/bootblock.c +++ b/src/mainboard/google/veyron_jerry/bootblock.c @@ -68,11 +68,11 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); /* spi0 for chrome ec */ writel(IOMUX_SPI0, &rk3288_grf->iomux_spi0); - rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 9*MHz); + rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 8250*KHz); setup_chromeos_gpios(); } diff --git a/src/mainboard/google/veyron_mighty/bootblock.c b/src/mainboard/google/veyron_mighty/bootblock.c index 2f012ec80e..cbb55ea4d2 100644 --- a/src/mainboard/google/veyron_mighty/bootblock.c +++ b/src/mainboard/google/veyron_mighty/bootblock.c @@ -68,11 +68,11 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); /* spi0 for chrome ec */ writel(IOMUX_SPI0, &rk3288_grf->iomux_spi0); - rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 9*MHz); + rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 8250*KHz); setup_chromeos_gpios(); } diff --git a/src/mainboard/google/veyron_minnie/bootblock.c b/src/mainboard/google/veyron_minnie/bootblock.c index 2f012ec80e..cbb55ea4d2 100644 --- a/src/mainboard/google/veyron_minnie/bootblock.c +++ b/src/mainboard/google/veyron_minnie/bootblock.c @@ -68,11 +68,11 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); /* spi0 for chrome ec */ writel(IOMUX_SPI0, &rk3288_grf->iomux_spi0); - rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 9*MHz); + rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 8250*KHz); setup_chromeos_gpios(); } diff --git a/src/mainboard/google/veyron_pinky/bootblock.c b/src/mainboard/google/veyron_pinky/bootblock.c index 2f012ec80e..cbb55ea4d2 100644 --- a/src/mainboard/google/veyron_pinky/bootblock.c +++ b/src/mainboard/google/veyron_pinky/bootblock.c @@ -68,11 +68,11 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); /* spi0 for chrome ec */ writel(IOMUX_SPI0, &rk3288_grf->iomux_spi0); - rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 9*MHz); + rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 8250*KHz); setup_chromeos_gpios(); } diff --git a/src/mainboard/google/veyron_speedy/bootblock.c b/src/mainboard/google/veyron_speedy/bootblock.c index 2f012ec80e..cbb55ea4d2 100644 --- a/src/mainboard/google/veyron_speedy/bootblock.c +++ b/src/mainboard/google/veyron_speedy/bootblock.c @@ -68,11 +68,11 @@ void bootblock_mainboard_init(void) /* spi2 for firmware ROM */ writel(IOMUX_SPI2_CSCLK, &rk3288_grf->iomux_spi2csclk); writel(IOMUX_SPI2_TXRX, &rk3288_grf->iomux_spi2txrx); - rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 11*MHz); + rockchip_spi_init(CONFIG_BOOT_MEDIA_SPI_BUS, 9900*KHz); /* spi0 for chrome ec */ writel(IOMUX_SPI0, &rk3288_grf->iomux_spi0); - rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 9*MHz); + rockchip_spi_init(CONFIG_EC_GOOGLE_CHROMEEC_SPI_BUS, 8250*KHz); setup_chromeos_gpios(); } diff --git a/src/soc/rockchip/rk3288/spi.c b/src/soc/rockchip/rk3288/spi.c index f3a12cc6b7..91b17cc1f8 100644 --- a/src/soc/rockchip/rk3288/spi.c +++ b/src/soc/rockchip/rk3288/spi.c @@ -94,12 +94,8 @@ static void rockchip_spi_enable_chip(struct rockchip_spi *regs, int enable) static void rockchip_spi_set_clk(struct rockchip_spi *regs, unsigned int hz) { - unsigned short clk_div = 0; - - /* Calculate clock divisor. */ - clk_div = SPI_SRCCLK_HZ / hz; - clk_div = (clk_div + 1) & 0xfffe; - assert((clk_div - 1) * hz == SPI_SRCCLK_HZ); + unsigned short clk_div = SPI_SRCCLK_HZ / hz; + assert(clk_div * hz == SPI_SRCCLK_HZ && !(clk_div & 1)); writel(clk_div, ®s->baudr); }