cleanup kernel config and make use of previously applied soundcore patch
[oweals/openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1292-fix-glamo-mci-slow-clock-until-first-bulk.patch.patch
1 From 9e7ba57b104e9293f746342b7450b10d5fa0c4cd Mon Sep 17 00:00:00 2001
2 From: Andy Green <andy@openmoko.com>
3 Date: Mon, 22 Sep 2008 22:38:03 +0100
4 Subject: [PATCH] fix-glamo-mci-slow-clock-until-first-bulk.patch
5
6 This patch adds another module parameter to glamo-mci which sets the
7 SD Card clock rate used inbetween powering the card and the completion of
8 the first bulk transfer.  You can set it from kernel commandline like this.
9
10 glamo_mci.sd_post_power_clock=1000000
11
12 The period between changing the power state and the first bulk transfer
13 completion is critical because larger SDHC cards take longer to initialize
14 before they can service the bulk transfer, and the Glamo MMC unit has a
15 fixed timeout length of a maximum of 4095 x 16 x SD Card clocks.  Large
16 cards like 8GB Sandisk SDHC are not ready before this timeout is used up
17 at default 16MHz.
18
19 Subsequently, the card can handle 16MHz SD Clock and timeout durations
20 okay.
21
22 By default this patch operates the SD Clock at only 1MHz until the first
23 bulk transfer is completed after each powerup action from the MCI stack.  It
24 also keeps the SD Clock running during this time, and disables the SD Clock
25 if the card is not present and the MCI stack removes power.
26
27 Signed-off-by: Andy Green <andy@openmoko.com>
28 ---
29  drivers/mfd/glamo/glamo-mci.c |  108 +++++++++++++++++++++++++----------------
30  drivers/mfd/glamo/glamo-mci.h |    2 +
31  2 files changed, 68 insertions(+), 42 deletions(-)
32
33 diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
34 index 3eece08..cff43db 100644
35 --- a/drivers/mfd/glamo/glamo-mci.c
36 +++ b/drivers/mfd/glamo/glamo-mci.c
37 @@ -74,6 +74,23 @@ static int sd_slow_ratio = 8;
38  module_param(sd_slow_ratio, int, 0644);
39  
40  /*
41 + * Post-power SD clock rate
42 + *
43 + * you can override this on kernel commandline using
44 + *
45 + *   glamo_mci.sd_post_power_clock=1000000
46 + *
47 + * for example
48 + *
49 + * After changing power to card, clock is held at this rate until first bulk
50 + * transfer completes
51 + */
52 +
53 +static int sd_post_power_clock = 1000000;
54 +module_param(sd_post_power_clock, int, 0644);
55 +
56 +
57 +/*
58   * SD Signal drive strength
59   *
60   * you can override this on kernel commandline using
61 @@ -240,21 +257,35 @@ static void __glamo_mci_fix_card_div(struct glamo_mci_host *host, int div)
62                 writew(readw(glamo_mci_def_pdata.pglamo->base +
63                      GLAMO_REG_CLOCK_GEN5_1) & (~GLAMO_CLOCK_GEN51_EN_DIV_TCLK),
64                      glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1);
65 -       } else {
66 -               /* set the nearest prescaler factor
67 -               *
68 -               * register shared with SCLK divisor -- no chance of race because
69 -               * we don't use sensor interface
70 -               */
71 -               writew_dly((readw(glamo_mci_def_pdata.pglamo->base +
72 -                               GLAMO_REG_CLOCK_GEN8) & 0xff00) | div,
73 -                      glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8);
74 -               /* enable clock to divider input */
75 -               writew_dly(readw(glamo_mci_def_pdata.pglamo->base +
76 -                       GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK,
77 -                    glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1);
78 +
79 +               goto done;
80         }
81  
82 +       if (host->force_slow_during_powerup)
83 +               div = host->clk_rate / sd_post_power_clock;
84 +       else
85 +               if (host->pdata->glamo_mci_use_slow)
86 +                       if ((host->pdata->glamo_mci_use_slow)())
87 +                               div = div * sd_slow_ratio;
88 +
89 +       if (div > 255)
90 +               div = 255;
91 +
92 +       /*
93 +        * set the nearest prescaler factor
94 +        *
95 +        * register shared with SCLK divisor -- no chance of race because
96 +        * we don't use sensor interface
97 +        */
98 +       writew_dly((readw(glamo_mci_def_pdata.pglamo->base +
99 +                       GLAMO_REG_CLOCK_GEN8) & 0xff00) | div,
100 +               glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8);
101 +       /* enable clock to divider input */
102 +       writew_dly(readw(glamo_mci_def_pdata.pglamo->base +
103 +               GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK,
104 +               glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1);
105 +
106 +done:
107         spin_unlock_irqrestore(&clock_lock, flags);
108  }
109  
110 @@ -284,7 +315,7 @@ static int __glamo_mci_set_card_clock(struct glamo_mci_host *host, int freq,
111                 if (division)
112                         *division = 0xff;
113  
114 -               if (!sd_idleclk)
115 +               if (!sd_idleclk && !host->force_slow_during_powerup)
116                         /* clock off */
117                         __glamo_mci_fix_card_div(host, -1);
118         }
119 @@ -327,6 +358,10 @@ static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
120                 goto done;
121         }
122  
123 +       /* disable the initial slow start after first bulk transfer */
124 +       if (host->force_slow_during_powerup)
125 +               host->force_slow_during_powerup--;
126 +
127         if (host->pio_active == XFER_READ)
128                 do_pio_read(host);
129  
130 @@ -341,7 +376,7 @@ static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
131                 host->cmd_is_stop = 0;
132         }
133  
134 -       if (!sd_idleclk)
135 +       if (!sd_idleclk && !host->force_slow_during_powerup)
136                 /* clock off */
137                 __glamo_mci_fix_card_div(host, -1);
138  
139 @@ -357,7 +392,6 @@ static int glamo_mci_send_command(struct glamo_mci_host *host,
140  {
141         u8 u8a[6];
142         u16 fire = 0;
143 -       u16 timeout = 0xfff; /* max glamo MMC timeout, in units of 16 clocks */
144  
145         /* if we can't do it, reject as busy */
146         if (!readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1) &
147 @@ -467,15 +501,9 @@ static int glamo_mci_send_command(struct glamo_mci_host *host,
148                 fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */
149                 break;
150         }
151 -       /* enforce timeout, clipping at default 65520 clocks if larger */
152 -       if (cmd->data)
153 -               /* so long as there is one... */
154 -               if (cmd->data->timeout_clks &&
155 -                   /* ... and it is not longer than we can handle */
156 -                   (cmd->data->timeout_clks <= 0xffff))
157 -                       timeout = cmd->data->timeout_clks >> 4; /* / 16 clks */
158  
159 -       writew(timeout, host->base + GLAMO_REG_MMC_TIMEOUT);
160 +       /* always largest timeout */
161 +       writew(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
162  
163         /* Generate interrupt on txfer */
164         writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) & 0x3e) |
165 @@ -576,14 +604,7 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
166         /* resume requested clock rate
167          * scale it down by sd_slow_ratio if platform requests it
168          */
169 -       if (host->pdata->glamo_mci_use_slow)
170 -               if ((host->pdata->glamo_mci_use_slow)())
171 -                       __glamo_mci_fix_card_div(host, host->clk_div *
172 -                                                                sd_slow_ratio);
173 -               else
174 -                       __glamo_mci_fix_card_div(host, host->clk_div);
175 -       else
176 -               __glamo_mci_fix_card_div(host, host->clk_div);
177 +       __glamo_mci_fix_card_div(host, host->clk_div);
178  
179         if (glamo_mci_send_command(host, cmd))
180                 goto bail;
181 @@ -633,6 +654,7 @@ static void glamo_mci_send_request(struct mmc_host *mmc)
182                 goto done;
183         if (!(cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)))
184                 goto done;
185 +
186         /*
187          * Otherwise can can use the interrupt as async completion --
188          * if there is read data coming, or we wait for write data to complete,
189 @@ -676,7 +698,7 @@ done:
190         host->mrq = NULL;
191         mmc_request_done(host->mmc, cmd->mrq);
192  bail:
193 -       if (!sd_idleclk)
194 +       if (!sd_idleclk && !host->force_slow_during_powerup)
195                 /* stop the clock to card */
196                 __glamo_mci_fix_card_div(host, -1);
197  }
198 @@ -718,6 +740,12 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
199         switch(ios->power_mode) {
200         case MMC_POWER_ON:
201         case MMC_POWER_UP:
202 +               /*
203 +                * we should use very slow clock until first bulk
204 +                * transfer completes OK
205 +                */
206 +               host->force_slow_during_powerup = 1;
207 +
208                 if (host->vdd_current != ios->vdd) {
209                         host->pdata->glamo_set_mci_power(ios->power_mode,
210                                                          ios->vdd);
211 @@ -734,6 +762,9 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
212         default:
213                 if (host->power_mode_current == MMC_POWER_OFF)
214                         break;
215 +               /* never want clocking with dead card */
216 +               __glamo_mci_fix_card_div(host, -1);
217 +
218                 glamo_engine_disable(glamo_mci_def_pdata.pglamo,
219                                      GLAMO_ENGINE_MMC);
220                 host->pdata->glamo_set_mci_power(MMC_POWER_OFF, 0);
221 @@ -751,7 +782,7 @@ static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
222         if (powering)
223                 msleep(1);
224  
225 -       if (!sd_idleclk)
226 +       if (!sd_idleclk && !host->force_slow_during_powerup)
227                 /* stop the clock to card, because we are idle until transfer */
228                 __glamo_mci_fix_card_div(host, -1);
229  
230 @@ -954,14 +985,7 @@ static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
231          * make sure the clock was running during suspend and consequently
232          * resume
233          */
234 -       if (host->pdata->glamo_mci_use_slow)
235 -               if ((host->pdata->glamo_mci_use_slow)())
236 -                       __glamo_mci_fix_card_div(host, host->clk_div *
237 -                                                                sd_slow_ratio);
238 -               else
239 -                       __glamo_mci_fix_card_div(host, host->clk_div);
240 -       else
241 -               __glamo_mci_fix_card_div(host, host->clk_div);
242 +       __glamo_mci_fix_card_div(host, host->clk_div);
243  
244         /* we are going to do more commands to override this in
245          * mmc_suspend_host(), so we need to change sd_idleclk for the
246 diff --git a/drivers/mfd/glamo/glamo-mci.h b/drivers/mfd/glamo/glamo-mci.h
247 index f3f170e..38f6376 100644
248 --- a/drivers/mfd/glamo/glamo-mci.h
249 +++ b/drivers/mfd/glamo/glamo-mci.h
250 @@ -44,6 +44,8 @@ struct glamo_mci_host {
251         unsigned long           real_rate;
252         u8                      prescaler;
253  
254 +       int                     force_slow_during_powerup;
255 +
256         unsigned                sdiimsk;
257         int                     dodma;
258  
259 -- 
260 1.5.6.5
261