aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/spi/spi-pxa2xx.c176
1 files changed, 114 insertions, 62 deletions
diff --git a/drivers/spi/spi-pxa2xx.c b/drivers/spi/spi-pxa2xx.c
index 6d6473427432..60526a591742 100644
--- a/drivers/spi/spi-pxa2xx.c
+++ b/drivers/spi/spi-pxa2xx.c
@@ -20,6 +20,7 @@
20#include <linux/errno.h> 20#include <linux/errno.h>
21#include <linux/err.h> 21#include <linux/err.h>
22#include <linux/interrupt.h> 22#include <linux/interrupt.h>
23#include <linux/kernel.h>
23#include <linux/platform_device.h> 24#include <linux/platform_device.h>
24#include <linux/spi/pxa2xx_spi.h> 25#include <linux/spi/pxa2xx_spi.h>
25#include <linux/spi/spi.h> 26#include <linux/spi/spi.h>
@@ -63,54 +64,6 @@ MODULE_ALIAS("platform:pxa2xx-spi");
63#define LPSS_TX_LOTHRESH_DFLT 160 64#define LPSS_TX_LOTHRESH_DFLT 160
64#define LPSS_TX_HITHRESH_DFLT 224 65#define LPSS_TX_HITHRESH_DFLT 224
65 66
66struct quark_spi_rate {
67 u32 bitrate;
68 u32 dds_clk_rate;
69 u32 clk_div;
70};
71
72/*
73 * 'rate', 'dds', 'clk_div' lookup table, which is defined in
74 * the Quark SPI datasheet.
75 */
76static const struct quark_spi_rate quark_spi_rate_table[] = {
77/* bitrate, dds_clk_rate, clk_div */
78 {50000000, 0x800000, 0},
79 {40000000, 0x666666, 0},
80 {25000000, 0x400000, 0},
81 {20000000, 0x666666, 1},
82 {16667000, 0x800000, 2},
83 {13333000, 0x666666, 2},
84 {12500000, 0x200000, 0},
85 {10000000, 0x800000, 4},
86 {8000000, 0x666666, 4},
87 {6250000, 0x400000, 3},
88 {5000000, 0x400000, 4},
89 {4000000, 0x666666, 9},
90 {3125000, 0x80000, 0},
91 {2500000, 0x400000, 9},
92 {2000000, 0x666666, 19},
93 {1563000, 0x40000, 0},
94 {1250000, 0x200000, 9},
95 {1000000, 0x400000, 24},
96 {800000, 0x666666, 49},
97 {781250, 0x20000, 0},
98 {625000, 0x200000, 19},
99 {500000, 0x400000, 49},
100 {400000, 0x666666, 99},
101 {390625, 0x10000, 0},
102 {250000, 0x400000, 99},
103 {200000, 0x666666, 199},
104 {195313, 0x8000, 0},
105 {125000, 0x100000, 49},
106 {100000, 0x200000, 124},
107 {50000, 0x100000, 124},
108 {25000, 0x80000, 124},
109 {10016, 0x20000, 77},
110 {5040, 0x20000, 154},
111 {1002, 0x8000, 194},
112};
113
114/* Offset from drv_data->lpss_base */ 67/* Offset from drv_data->lpss_base */
115#define GENERAL_REG 0x08 68#define GENERAL_REG 0x08
116#define GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24) 69#define GENERAL_REG_RXTO_HOLDOFF_DISABLE BIT(24)
@@ -697,25 +650,124 @@ static irqreturn_t ssp_int(int irq, void *dev_id)
697} 650}
698 651
699/* 652/*
700 * The Quark SPI data sheet gives a table, and for the given 'rate', 653 * The Quark SPI has an additional 24 bit register (DDS_CLK_RATE) to multiply
701 * the 'dds' and 'clk_div' can be found in the table. 654 * input frequency by fractions of 2^24. It also has a divider by 5.
655 *
656 * There are formulas to get baud rate value for given input frequency and
657 * divider parameters, such as DDS_CLK_RATE and SCR:
658 *
659 * Fsys = 200MHz
660 *
661 * Fssp = Fsys * DDS_CLK_RATE / 2^24 (1)
662 * Baud rate = Fsclk = Fssp / (2 * (SCR + 1)) (2)
663 *
664 * DDS_CLK_RATE either 2^n or 2^n / 5.
665 * SCR is in range 0 .. 255
666 *
667 * Divisor = 5^i * 2^j * 2 * k
668 * i = [0, 1] i = 1 iff j = 0 or j > 3
669 * j = [0, 23] j = 0 iff i = 1
670 * k = [1, 256]
671 * Special case: j = 0, i = 1: Divisor = 2 / 5
672 *
673 * Accordingly to the specification the recommended values for DDS_CLK_RATE
674 * are:
675 * Case 1: 2^n, n = [0, 23]
676 * Case 2: 2^24 * 2 / 5 (0x666666)
677 * Case 3: less than or equal to 2^24 / 5 / 16 (0x33333)
678 *
679 * In all cases the lowest possible value is better.
680 *
681 * The function calculates parameters for all cases and chooses the one closest
682 * to the asked baud rate.
702 */ 683 */
703static u32 quark_x1000_set_clk_regvals(u32 rate, u32 *dds, u32 *clk_div) 684static unsigned int quark_x1000_get_clk_div(int rate, u32 *dds)
704{ 685{
705 unsigned int i; 686 unsigned long xtal = 200000000;
706 687 unsigned long fref = xtal / 2; /* mandatory division by 2,
707 for (i = 0; i < ARRAY_SIZE(quark_spi_rate_table); i++) { 688 see (2) */
708 if (rate >= quark_spi_rate_table[i].bitrate) { 689 /* case 3 */
709 *dds = quark_spi_rate_table[i].dds_clk_rate; 690 unsigned long fref1 = fref / 2; /* case 1 */
710 *clk_div = quark_spi_rate_table[i].clk_div; 691 unsigned long fref2 = fref * 2 / 5; /* case 2 */
711 return quark_spi_rate_table[i].bitrate; 692 unsigned long scale;
693 unsigned long q, q1, q2;
694 long r, r1, r2;
695 u32 mul;
696
697 /* Case 1 */
698
699 /* Set initial value for DDS_CLK_RATE */
700 mul = (1 << 24) >> 1;
701
702 /* Calculate initial quot */
703 q1 = DIV_ROUND_CLOSEST(fref1, rate);
704
705 /* Scale q1 if it's too big */
706 if (q1 > 256) {
707 /* Scale q1 to range [1, 512] */
708 scale = fls_long(q1 - 1);
709 if (scale > 9) {
710 q1 >>= scale - 9;
711 mul >>= scale - 9;
712 } 712 }
713
714 /* Round the result if we have a remainder */
715 q1 += q1 & 1;
713 } 716 }
714 717
715 *dds = quark_spi_rate_table[i-1].dds_clk_rate; 718 /* Decrease DDS_CLK_RATE as much as we can without loss in precision */
716 *clk_div = quark_spi_rate_table[i-1].clk_div; 719 scale = __ffs(q1);
720 q1 >>= scale;
721 mul >>= scale;
722
723 /* Get the remainder */
724 r1 = abs(fref1 / (1 << (24 - fls_long(mul))) / q1 - rate);
725
726 /* Case 2 */
727
728 q2 = DIV_ROUND_CLOSEST(fref2, rate);
729 r2 = abs(fref2 / q2 - rate);
730
731 /*
732 * Choose the best between two: less remainder we have the better. We
733 * can't go case 2 if q2 is greater than 256 since SCR register can
734 * hold only values 0 .. 255.
735 */
736 if (r2 >= r1 || q2 > 256) {
737 /* case 1 is better */
738 r = r1;
739 q = q1;
740 } else {
741 /* case 2 is better */
742 r = r2;
743 q = q2;
744 mul = (1 << 24) * 2 / 5;
745 }
746
747 /* Check case 3 only If the divisor is big enough */
748 if (fref / rate >= 80) {
749 u64 fssp;
750 u32 m;
751
752 /* Calculate initial quot */
753 q1 = DIV_ROUND_CLOSEST(fref, rate);
754 m = (1 << 24) / q1;
755
756 /* Get the remainder */
757 fssp = (u64)fref * m;
758 do_div(fssp, 1 << 24);
759 r1 = abs(fssp - rate);
760
761 /* Choose this one if it suits better */
762 if (r1 < r) {
763 /* case 3 is better */
764 q = 1;
765 mul = m;
766 }
767 }
717 768
718 return quark_spi_rate_table[i-1].bitrate; 769 *dds = mul;
770 return q - 1;
719} 771}
720 772
721static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate) 773static unsigned int ssp_get_clk_div(struct driver_data *drv_data, int rate)
@@ -738,7 +790,7 @@ static unsigned int pxa2xx_ssp_get_clk_div(struct driver_data *drv_data,
738 790
739 switch (drv_data->ssp_type) { 791 switch (drv_data->ssp_type) {
740 case QUARK_X1000_SSP: 792 case QUARK_X1000_SSP:
741 quark_x1000_set_clk_regvals(rate, &chip->dds_rate, &clk_div); 793 clk_div = quark_x1000_get_clk_div(rate, &chip->dds_rate);
742 default: 794 default:
743 clk_div = ssp_get_clk_div(drv_data, rate); 795 clk_div = ssp_get_clk_div(drv_data, rate);
744 } 796 }