spi-pl022.c (b181565ee6a0f894bd6a134b9e5bed2966bdf9b3) | spi-pl022.c (0379b2a33a8a03d4ad1036ef646419dbdf1ac15a) |
---|---|
1/* 2 * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. 3 * 4 * Copyright (C) 2008-2009 ST-Ericsson AB 5 * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. 6 * 7 * Author: Linus Walleij <linus.walleij@stericsson.com> 8 * --- 1776 unchanged lines hidden (view full) --- 1785 list_add_tail(&msg->queue, &pl022->queue); 1786 if (pl022->running && !pl022->busy) 1787 queue_work(pl022->workqueue, &pl022->pump_messages); 1788 1789 spin_unlock_irqrestore(&pl022->queue_lock, flags); 1790 return 0; 1791} 1792 | 1/* 2 * A driver for the ARM PL022 PrimeCell SSP/SPI bus master. 3 * 4 * Copyright (C) 2008-2009 ST-Ericsson AB 5 * Copyright (C) 2006 STMicroelectronics Pvt. Ltd. 6 * 7 * Author: Linus Walleij <linus.walleij@stericsson.com> 8 * --- 1776 unchanged lines hidden (view full) --- 1785 list_add_tail(&msg->queue, &pl022->queue); 1786 if (pl022->running && !pl022->busy) 1787 queue_work(pl022->workqueue, &pl022->pump_messages); 1788 1789 spin_unlock_irqrestore(&pl022->queue_lock, flags); 1790 return 0; 1791} 1792 |
1793static int calculate_effective_freq(struct pl022 *pl022, 1794 int freq, 1795 struct ssp_clock_params *clk_freq) | 1793static inline u32 spi_rate(u32 rate, u16 cpsdvsr, u16 scr) |
1796{ | 1794{ |
1795 return rate / (cpsdvsr * (1 + scr)); 1796} 1797 1798static int calculate_effective_freq(struct pl022 *pl022, int freq, struct 1799 ssp_clock_params * clk_freq) 1800{ |
|
1797 /* Lets calculate the frequency parameters */ | 1801 /* Lets calculate the frequency parameters */ |
1798 u16 cpsdvsr = 2; 1799 u16 scr = 0; 1800 bool freq_found = false; 1801 u32 rate; 1802 u32 max_tclk; 1803 u32 min_tclk; | 1802 u16 cpsdvsr = CPSDVR_MIN, scr = SCR_MIN; 1803 u32 rate, max_tclk, min_tclk, best_freq = 0, best_cpsdvsr = 0, 1804 best_scr = 0, tmp, found = 0; |
1804 1805 rate = clk_get_rate(pl022->clk); 1806 /* cpsdvscr = 2 & scr 0 */ | 1805 1806 rate = clk_get_rate(pl022->clk); 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 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 { | 1812 if (!((freq <= max_tclk) && (freq >= min_tclk))) { |
1850 dev_err(&pl022->adev->dev, 1851 "controller data is incorrect: out of range frequency"); 1852 return -EINVAL; 1853 } | 1813 dev_err(&pl022->adev->dev, 1814 "controller data is incorrect: out of range frequency"); 1815 return -EINVAL; 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; 1855} 1856 1857/* 1858 * A piece of default chip info unless the platform 1859 * supplies it. 1860 */ 1861static const struct pl022_config_chip pl022_default_chip_info = { --- 560 unchanged lines hidden --- | 1854 return 0; 1855} 1856 1857/* 1858 * A piece of default chip info unless the platform 1859 * supplies it. 1860 */ 1861static const struct pl022_config_chip pl022_default_chip_info = { --- 560 unchanged lines hidden --- |