diff options
Diffstat (limited to 'drivers/spi')
-rw-r--r-- | drivers/spi/spi-pl022.c | 102 |
1 files changed, 51 insertions, 51 deletions
diff --git a/drivers/spi/spi-pl022.c b/drivers/spi/spi-pl022.c index 248674c8a8c2..4e1a1e3b2a8c 100644 --- a/drivers/spi/spi-pl022.c +++ b/drivers/spi/spi-pl022.c | |||
@@ -1790,67 +1790,67 @@ static int pl022_transfer(struct spi_device *spi, struct spi_message *msg) | |||
1790 | return 0; | 1790 | return 0; |
1791 | } | 1791 | } |
1792 | 1792 | ||
1793 | static int calculate_effective_freq(struct pl022 *pl022, | 1793 | static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr) |
1794 | int freq, | 1794 | { |
1795 | struct ssp_clock_params *clk_freq) | 1795 | return rate / (cpsdvsr * (1 + scr)); |
1796 | } | ||
1797 | |||
1798 | static int calculate_effective_freq(struct pl022 *pl022, int freq, struct | ||
1799 | ssp_clock_params * clk_freq) | ||
1796 | { | 1800 | { |
1797 | /* Lets calculate the frequency parameters */ | 1801 | /* Lets calculate the frequency parameters */ |
1798 | u16 cpsdvsr = 2; | 1802 | u16 cpsdvsr = CPSDVR_MIN, scr = SCR_MIN; |
1799 | u16 scr = 0; | 1803 | u32 rate, max_tclk, min_tclk, best_freq = 0, best_cpsdvsr = 0, |
1800 | bool freq_found = false; | 1804 | best_scr = 0, tmp, found = 0; |
1801 | u32 rate; | ||
1802 | u32 max_tclk; | ||
1803 | u32 min_tclk; | ||
1804 | 1805 | ||
1805 | rate = clk_get_rate(pl022->clk); | 1806 | rate = clk_get_rate(pl022->clk); |
1806 | /* cpsdvscr = 2 & scr 0 */ | 1807 | /* cpsdvscr = 2 & scr 0 */ |
1807 | max_tclk = (rate / (CPSDVR_MIN * (1 + SCR_MIN))); | 1808 | max_tclk = spi_rate(rate, CPSDVR_MIN, SCR_MIN); |
1808 | /* cpsdvsr = 254 & scr = 255 */ | 1809 | /* cpsdvsr = 254 & scr = 255 */ |
1809 | min_tclk = (rate / (CPSDVR_MAX * (1 + SCR_MAX))); | 1810 | min_tclk = spi_rate(rate, CPSDVR_MAX, SCR_MAX); |
1810 | 1811 | ||
1811 | if ((freq <= max_tclk) && (freq >= min_tclk)) { | 1812 | if (!((freq <= max_tclk) && (freq >= min_tclk))) { |
1812 | while (cpsdvsr <= CPSDVR_MAX && !freq_found) { | ||
1813 | while (scr <= SCR_MAX && !freq_found) { | ||
1814 | if ((rate / | ||
1815 | (cpsdvsr * (1 + scr))) > freq) | ||
1816 | scr += 1; | ||
1817 | else { | ||
1818 | /* | ||
1819 | * This bool is made true when | ||
1820 | * effective frequency >= | ||
1821 | * target frequency is found | ||
1822 | */ | ||
1823 | freq_found = true; | ||
1824 | if ((rate / | ||
1825 | (cpsdvsr * (1 + scr))) != freq) { | ||
1826 | if (scr == SCR_MIN) { | ||
1827 | cpsdvsr -= 2; | ||
1828 | scr = SCR_MAX; | ||
1829 | } else | ||
1830 | scr -= 1; | ||
1831 | } | ||
1832 | } | ||
1833 | } | ||
1834 | if (!freq_found) { | ||
1835 | cpsdvsr += 2; | ||
1836 | scr = SCR_MIN; | ||
1837 | } | ||
1838 | } | ||
1839 | if (cpsdvsr != 0) { | ||
1840 | dev_dbg(&pl022->adev->dev, | ||
1841 | "SSP Effective Frequency is %u\n", | ||
1842 | (rate / (cpsdvsr * (1 + scr)))); | ||
1843 | clk_freq->cpsdvsr = (u8) (cpsdvsr & 0xFF); | ||
1844 | clk_freq->scr = (u8) (scr & 0xFF); | ||
1845 | dev_dbg(&pl022->adev->dev, | ||
1846 | "SSP cpsdvsr = %d, scr = %d\n", | ||
1847 | clk_freq->cpsdvsr, clk_freq->scr); | ||
1848 | } | ||
1849 | } else { | ||
1850 | dev_err(&pl022->adev->dev, | 1813 | dev_err(&pl022->adev->dev, |
1851 | "controller data is incorrect: out of range frequency"); | 1814 | "controller data is incorrect: out of range frequency"); |
1852 | return -EINVAL; | 1815 | return -EINVAL; |
1853 | } | 1816 | } |
1817 | |||
1818 | /* | ||
1819 | * best_freq will give closest possible available rate (<= requested | ||
1820 | * freq) for all values of scr & cpsdvsr. | ||
1821 | */ | ||
1822 | while ((cpsdvsr <= CPSDVR_MAX) && !found) { | ||
1823 | while (scr <= SCR_MAX) { | ||
1824 | tmp = spi_rate(rate, cpsdvsr, scr); | ||
1825 | |||
1826 | if (tmp > freq) | ||
1827 | scr++; | ||
1828 | /* | ||
1829 | * If found exact value, update and break. | ||
1830 | * If found more closer value, update and continue. | ||
1831 | */ | ||
1832 | else if ((tmp == freq) || (tmp > best_freq)) { | ||
1833 | best_freq = tmp; | ||
1834 | best_cpsdvsr = cpsdvsr; | ||
1835 | best_scr = scr; | ||
1836 | |||
1837 | if (tmp == freq) | ||
1838 | break; | ||
1839 | } | ||
1840 | scr++; | ||
1841 | } | ||
1842 | cpsdvsr += 2; | ||
1843 | scr = SCR_MIN; | ||
1844 | } | ||
1845 | |||
1846 | clk_freq->cpsdvsr = (u8) (best_cpsdvsr & 0xFF); | ||
1847 | clk_freq->scr = (u8) (best_scr & 0xFF); | ||
1848 | dev_dbg(&pl022->adev->dev, | ||
1849 | "SSP Target Frequency is: %u, Effective Frequency is %u\n", | ||
1850 | freq, best_freq); | ||
1851 | dev_dbg(&pl022->adev->dev, "SSP cpsdvsr = %d, scr = %d\n", | ||
1852 | clk_freq->cpsdvsr, clk_freq->scr); | ||
1853 | |||
1854 | return 0; | 1854 | return 0; |
1855 | } | 1855 | } |
1856 | 1856 | ||