From 21349b4ba414df61a2b752e78e4982265ffe56c3 Mon Sep 17 00:00:00 2001 From: Tomas Thoresen Date: Fri, 12 Jul 2013 06:33:54 -0700 Subject: [PATCH] zynq: qspi: Changed hardcoded QSPI clk frequency to be calculated. Changed hardcoded QSPI clk frequency to be calculated based on CPU frequency and Quad Ref Clock Control(slcr) DIVISOR. Signed-off-by: Tomas Thoresen Signed-off-by: Michal Simek --- arch/arm/cpu/armv7/zynq/slcr.c | 6 ++++++ arch/arm/include/asm/arch-zynq/hardware.h | 4 +++- arch/arm/include/asm/arch-zynq/sys_proto.h | 1 + drivers/spi/zynq_qspi.c | 23 +++++++++++++++++++++- 4 files changed, 32 insertions(+), 2 deletions(-) diff --git a/arch/arm/cpu/armv7/zynq/slcr.c b/arch/arm/cpu/armv7/zynq/slcr.c index cfd66098620..06dd1bd9a85 100644 --- a/arch/arm/cpu/armv7/zynq/slcr.c +++ b/arch/arm/cpu/armv7/zynq/slcr.c @@ -171,6 +171,12 @@ out: zynq_slcr_lock(); } +u32 zynq_slcr_get_lqspi_clk_ctrl(void) +{ + /* Get the lqspi_clkk_ctrl register value */ + return readl(&slcr_base->lqspi_clk_ctrl); +} + void zynq_slcr_devcfg_disable(void) { zynq_slcr_unlock(); diff --git a/arch/arm/include/asm/arch-zynq/hardware.h b/arch/arm/include/asm/arch-zynq/hardware.h index 25b8c288bee..f6e25520de5 100644 --- a/arch/arm/include/asm/arch-zynq/hardware.h +++ b/arch/arm/include/asm/arch-zynq/hardware.h @@ -50,7 +50,9 @@ struct slcr_regs { u32 gem1_rclk_ctrl; /* 0x13c */ u32 gem0_clk_ctrl; /* 0x140 */ u32 gem1_clk_ctrl; /* 0x144 */ - u32 reserved1[46]; + u32 smc_clk_ctrl; /* 0x148 */ + u32 lqspi_clk_ctrl; /* 0x14c */ + u32 reserved1[44]; u32 pss_rst_ctrl; /* 0x200 */ u32 reserved2[15]; u32 fpga_rst_ctrl; /* 0x240 */ diff --git a/arch/arm/include/asm/arch-zynq/sys_proto.h b/arch/arm/include/asm/arch-zynq/sys_proto.h index 9445a1db475..839f15c9a83 100644 --- a/arch/arm/include/asm/arch-zynq/sys_proto.h +++ b/arch/arm/include/asm/arch-zynq/sys_proto.h @@ -31,6 +31,7 @@ extern void zynq_slcr_cpu_reset(void); extern void zynq_slcr_gem_clk_setup(u32 gem_id, u32 rclk, u32 clk); extern void zynq_slcr_devcfg_disable(void); extern void zynq_slcr_devcfg_enable(void); +extern u32 zynq_slcr_get_lqspi_clk_ctrl(void); extern u32 zynq_slcr_get_boot_mode(void); extern u32 zynq_slcr_get_idcode(void); extern int zynq_slcr_get_mio_pin_status(const char *periph); diff --git a/drivers/spi/zynq_qspi.c b/drivers/spi/zynq_qspi.c index 69ea1b2eb9e..0af50170f66 100644 --- a/drivers/spi/zynq_qspi.c +++ b/drivers/spi/zynq_qspi.c @@ -951,6 +951,8 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, unsigned int max_hz, unsigned int mode) { int is_dual; + unsigned long lqspi_clk_ctrl_reg; + unsigned long lqspi_frequency; struct zynq_qspi_slave *qspi; debug("%s: bus: %d cs: %d max_hz: %d mode: %d\n", @@ -975,8 +977,24 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, return NULL; } +/* + * Read the lqspi_clk_ctrl_reg register and calculate the frequency. If failure + * revert to 200Mhz + */ + + lqspi_clk_ctrl_reg = zynq_slcr_get_lqspi_clk_ctrl(); + + lqspi_frequency = (CONFIG_CPU_FREQ_HZ / ((lqspi_clk_ctrl_reg & 0x3F00)>> + 8)); + if (!lqspi_frequency) { + printf("Defaulting to 200000000 Hz qspi clk"); + qspi->qspi.master.input_clk_hz = 200000000; + } else { + qspi->qspi.master.input_clk_hz = lqspi_frequency; + printf("Qspi clk frequency set to %d Hz\n", lqspi_frequency); + } + qspi->slave.is_dual = is_dual; - qspi->qspi.master.input_clk_hz = 100000000; qspi->qspi.master.speed_hz = qspi->qspi.master.input_clk_hz / 2; qspi->qspi.max_speed_hz = qspi->qspi.master.speed_hz; qspi->qspi.master.is_dual = is_dual; @@ -985,6 +1003,9 @@ struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs, qspi->qspi.bits_per_word = 32; zynq_qspi_setup_transfer(&qspi->qspi, NULL); + debug("%s: lqspi_clk_ctrl_reg: %d CONFIG_CPU_FREQ_HZ %d\n", + __func__, lqspi_clk_ctrl_reg, CONFIG_CPU_FREQ_HZ); + spi_enable_quad_bit(&qspi->slave); return &qspi->slave; -- 2.47.3