changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1323-GTA01-use-slow-SD-clock-when-gps-on.patch.patch
1 From d944934bbddc281938fb1905a69e35c0581937c2 Mon Sep 17 00:00:00 2001
2 From: Mike Westerhof <mwester@dls.net>
3 Date: Thu, 13 Nov 2008 20:39:36 +0000
4 Subject: [PATCH] GTA01-use-slow-SD-clock-when-gps-on.patch
5
6 This patch implements Andy Green's SD clock slow-down code
7 for the GTA01 device.
8
9 Signed-off-by: Mike Westerhof <mwester@dls.net>
10 ---
11  arch/arm/mach-s3c2410/mach-gta01.c |    8 ++++++
12  drivers/mmc/host/s3cmci.c          |   43 ++++++++++++++++++++++++++++++++++-
13  drivers/mmc/host/s3cmci.h          |    1 +
14  include/asm-arm/arch-s3c2410/mci.h |    1 +
15  4 files changed, 51 insertions(+), 2 deletions(-)
16
17 diff --git a/arch/arm/mach-s3c2410/mach-gta01.c b/arch/arm/mach-s3c2410/mach-gta01.c
18 index a364b76..c0817dc 100644
19 --- a/arch/arm/mach-s3c2410/mach-gta01.c
20 +++ b/arch/arm/mach-s3c2410/mach-gta01.c
21 @@ -75,6 +75,8 @@
22  #include <asm/plat-s3c24xx/neo1973.h>
23  #include <asm/arch-s3c2410/neo1973-pm-gsm.h>
24  
25 +#include "../plat-s3c24xx/neo1973_pm_gps.h"
26 +
27  #include <linux/jbt6k74.h>
28  
29  static struct map_desc gta01_iodesc[] __initdata = {
30 @@ -432,9 +434,15 @@ static void gta01_mmc_set_power(unsigned char power_mode, unsigned short vdd)
31         }
32  }
33  
34 +static int gta01_mmc_use_slow(void)
35 +{
36 +       return neo1973_pm_gps_is_on();
37 +}
38 +
39  static struct s3c24xx_mci_pdata gta01_mmc_cfg = {
40         .gpio_detect    = GTA01_GPIO_nSD_DETECT,
41         .set_power      = &gta01_mmc_set_power,
42 +       .use_slow       = &gta01_mmc_use_slow,
43         .ocr_avail      = MMC_VDD_165_195|MMC_VDD_20_21|
44                           MMC_VDD_21_22|MMC_VDD_22_23|MMC_VDD_23_24|
45                           MMC_VDD_24_25|MMC_VDD_25_26|MMC_VDD_26_27|
46 diff --git a/drivers/mmc/host/s3cmci.c b/drivers/mmc/host/s3cmci.c
47 index 8f88721..87d24b2 100644
48 --- a/drivers/mmc/host/s3cmci.c
49 +++ b/drivers/mmc/host/s3cmci.c
50 @@ -59,6 +59,23 @@ module_param(sd_max_clk, int, 0644);
51  static int sd_idleclk;  /* disallow idle clock by default */
52  module_param(sd_idleclk, int, 0644);
53  
54 +/*
55 + * Slow SD clock rate
56 + *
57 + * you can override this on kernel commandline using
58 + *
59 + *  s3cmci.sd_slow_ratio=8
60 + *
61 + * for example.
62 + *
63 + * A platform callback is used to decide effective clock rate.  If not
64 + * defined, then the max is used, if defined and the callback returns
65 + * nonzero, the rate is divided by this factor.
66 + */
67 +
68 +static int sd_slow_ratio = 8;
69 +module_param(sd_slow_ratio, int, 0644);
70 +
71  /* used to stash real idleclk state in suspend: we force it to run in there */
72  static int suspend_sd_idleclk;
73  
74 @@ -252,7 +269,7 @@ static inline void do_pio_read(struct s3cmci_host *host)
75         void __iomem *from_ptr;
76  
77         /* write real prescaler to host, it might be set slow to fix */
78 -       writel(host->prescaler, host->base + S3C2410_SDIPRE);
79 +       writel(host->sdipre, host->base + S3C2410_SDIPRE);
80  
81         from_ptr = host->base + host->sdidata;
82  
83 @@ -755,7 +772,7 @@ static void finalize_request(struct s3cmci_host *host)
84         cmd->resp[3] = readl(host->base + S3C2410_SDIRSP3);
85  
86         /* reset clock speed, as it could still be set low for */
87 -       writel(host->prescaler, host->base + S3C2410_SDIPRE);
88 +       writel(host->sdipre, host->base + S3C2410_SDIPRE);
89  
90         if (cmd->error)
91                 debug_as_failure = 1;
92 @@ -1032,6 +1049,7 @@ static void s3cmci_send_request(struct mmc_host *mmc)
93         struct s3cmci_host *host = mmc_priv(mmc);
94         struct mmc_request *mrq = host->mrq;
95         struct mmc_command *cmd = host->cmd_is_stop?mrq->stop:mrq->cmd;
96 +       int pre;
97  
98         host->ccnt++;
99  #ifdef CONFIG_MMC_DEBUG
100 @@ -1073,6 +1091,26 @@ static void s3cmci_send_request(struct mmc_host *mmc)
101  
102         }
103  
104 +       /* establish the correct prescaler depending on the sd_slow_ratio */
105 +
106 +       if ((sd_slow_ratio > 1) &&
107 +           host->pdata->use_slow && (host->pdata->use_slow)()) {
108 +               /* compute the slower speed */
109 +               pre = host->prescaler * sd_slow_ratio;
110 +               if (pre > 255)
111 +                       pre = 255;
112 +       } else {
113 +               /* use the normal speed */
114 +               pre = host->prescaler;
115 +       }
116 +
117 +       if (host->sdipre != pre) {
118 +               dbg(host, dbg_conf, "prescaler changed: %d -> %d\n",
119 +                   (int)host->sdipre, pre);
120 +               host->sdipre = pre;
121 +               writel(host->sdipre, host->base + S3C2410_SDIPRE);
122 +       }
123 +
124         __s3cmci_enable_clock(host);
125         s3cmci_send_command(host, cmd);
126         enable_irq(host->irq);
127 @@ -1138,6 +1176,7 @@ static void s3cmci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
128         if (mci_psc > 255)
129                 mci_psc = 255;
130         host->prescaler = mci_psc;
131 +       host->sdipre = mci_psc;
132  
133         writel(host->prescaler, host->base + S3C2410_SDIPRE);
134  
135 diff --git a/drivers/mmc/host/s3cmci.h b/drivers/mmc/host/s3cmci.h
136 index 9644b45..11974ff 100644
137 --- a/drivers/mmc/host/s3cmci.h
138 +++ b/drivers/mmc/host/s3cmci.h
139 @@ -32,6 +32,7 @@ struct s3cmci_host {
140         unsigned long           clk_div;
141         unsigned long           real_rate;
142         u8                      prescaler;
143 +       u8                      sdipre;
144  
145         int                     is2440;
146         unsigned                sdiimsk;
147 diff --git a/include/asm-arm/arch-s3c2410/mci.h b/include/asm-arm/arch-s3c2410/mci.h
148 index 24e6cd1..f087229 100644
149 --- a/include/asm-arm/arch-s3c2410/mci.h
150 +++ b/include/asm-arm/arch-s3c2410/mci.h
151 @@ -8,6 +8,7 @@ struct s3c24xx_mci_pdata {
152         unsigned int    do_dma;
153         void            (*set_power)(unsigned char power_mode,
154                                      unsigned short vdd);
155 +       int             (*use_slow)(void);
156  };
157  
158  #endif /* _ARCH_NCI_H */
159 -- 
160 1.5.6.5
161