diff options
author | Manish Narani <manish.narani@xilinx.com> | 2018-07-23 20:32:01 +0530 |
---|---|---|
committer | Jonathan Cameron <Jonathan.Cameron@huawei.com> | 2018-07-29 12:49:48 +0100 |
commit | 81f5471838c279c97f0b46f18e766c2ac0de8806 (patch) | |
tree | 5982fe6b985ffa762e49f9a9a4efb9d2c9e82983 /drivers/iio | |
parent | 0a8460966fc28c3c25160c34da055e9a8a0c90a1 (diff) | |
download | linux-81f5471838c279c97f0b46f18e766c2ac0de8806.tar.bz2 |
iio: adc: xilinx: limit pcap clock frequency value
This patch limits the xadc pcap clock frequency value to be less than
200MHz. This fixes the issue when zynq is booted at higher frequency
values, pcap crosses the maximum limit of 200MHz(Fmax) as it is derived
from IOPLL.
If this limit is crossed it is required to alter the WEDGE and REDGE
bits of XADC_CFG register to make timings better in the interface. So to
avoid alteration of these bits every time, the pcap value should not
cross the Fmax limit.
Signed-off-by: Manish Narani <manish.narani@xilinx.com>
Signed-off-by: Jonathan Cameron <Jonathan.Cameron@huawei.com>
Diffstat (limited to 'drivers/iio')
-rw-r--r-- | drivers/iio/adc/xilinx-xadc-core.c | 15 |
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/iio/adc/xilinx-xadc-core.c b/drivers/iio/adc/xilinx-xadc-core.c index 23395fc5b267..0dd306d2c7f1 100644 --- a/drivers/iio/adc/xilinx-xadc-core.c +++ b/drivers/iio/adc/xilinx-xadc-core.c @@ -322,6 +322,7 @@ static irqreturn_t xadc_zynq_interrupt_handler(int irq, void *devid) #define XADC_ZYNQ_TCK_RATE_MAX 50000000 #define XADC_ZYNQ_IGAP_DEFAULT 20 +#define XADC_ZYNQ_PCAP_RATE_MAX 200000000 static int xadc_zynq_setup(struct platform_device *pdev, struct iio_dev *indio_dev, int irq) @@ -332,6 +333,7 @@ static int xadc_zynq_setup(struct platform_device *pdev, unsigned int div; unsigned int igap; unsigned int tck_rate; + int ret; /* TODO: Figure out how to make igap and tck_rate configurable */ igap = XADC_ZYNQ_IGAP_DEFAULT; @@ -343,6 +345,13 @@ static int xadc_zynq_setup(struct platform_device *pdev, if (!pcap_rate) return -EINVAL; + if (pcap_rate > XADC_ZYNQ_PCAP_RATE_MAX) { + ret = clk_set_rate(xadc->clk, + (unsigned long)XADC_ZYNQ_PCAP_RATE_MAX); + if (ret) + return ret; + } + if (tck_rate > pcap_rate / 2) { div = 2; } else { @@ -368,6 +377,12 @@ static int xadc_zynq_setup(struct platform_device *pdev, XADC_ZYNQ_CFG_REDGE | XADC_ZYNQ_CFG_WEDGE | tck_div | XADC_ZYNQ_CFG_IGAP(igap)); + if (pcap_rate > XADC_ZYNQ_PCAP_RATE_MAX) { + ret = clk_set_rate(xadc->clk, pcap_rate); + if (ret) + return ret; + } + return 0; } |