Add u-boot Hibernation code for porter board.
[AGL/meta-agl.git] / meta-agl-bsp / meta-renesas / recipes-bsp / u-boot / u-boot / hibernation / 0001-Add-rcar-sdhi-DMA-support.patch
1 From 0aae8f3fefc67bc07b7e4e42f885ef661f0921ab Mon Sep 17 00:00:00 2001
2 From: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
3 Date: Fri, 19 May 2017 14:25:38 +0900
4 Subject: [PATCH 1/4] Add rcar-sdhi DMA support
5
6 Signed-off-by: Yuichi Kusakabe <yuichi.kusakabe@jp.fujitsu.com>
7 ---
8  drivers/dma/Makefile  |   1 +
9  drivers/dma/sh_dma.c  | 306 ++++++++++++++++++++++++++++++++++++++++++++++++++
10  drivers/mmc/sh_sdhi.c | 158 +++++++++++++++++++++++++-
11  drivers/mmc/sh_sdhi.h |   5 +
12  include/sh_dma.h      |  58 ++++++++++
13  5 files changed, 524 insertions(+), 4 deletions(-)
14  create mode 100644 drivers/dma/sh_dma.c
15  create mode 100644 include/sh_dma.h
16
17 diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
18 index 5d864b5..1129fc3 100644
19 --- a/drivers/dma/Makefile
20 +++ b/drivers/dma/Makefile
21 @@ -29,6 +29,7 @@ COBJS-$(CONFIG_FSLDMAFEC) += MCD_tasksInit.o MCD_dmaApi.o MCD_tasks.o
22  COBJS-$(CONFIG_APBH_DMA) += apbh_dma.o
23  COBJS-$(CONFIG_FSL_DMA) += fsl_dma.o
24  COBJS-$(CONFIG_OMAP3_DMA) += omap3_dma.o
25 +COBJS-$(CONFIG_SH_DMA) += sh_dma.o
26  
27  COBJS  := $(COBJS-y)
28  SRCS   := $(COBJS:.o=.c)
29 diff --git a/drivers/dma/sh_dma.c b/drivers/dma/sh_dma.c
30 new file mode 100644
31 index 0000000..0af2480
32 --- /dev/null
33 +++ b/drivers/dma/sh_dma.c
34 @@ -0,0 +1,306 @@
35 +/*
36 + * SH SYS-DMA driver
37 + *
38 + * Copyright (C) 2014  Cogent Embedded, Inc.
39 + *
40 + * This program is free software; you can redistribute it and/or
41 + * modify it under the terms of the GNU General Public License as
42 + * published by the Free Software Foundation; either version 2 of
43 + * the License, or (at your option) any later version.
44 + *
45 + * This program is distributed in the hope that it will be useful,
46 + * but WITHOUT ANY WARRANTY; without even the implied warranty of
47 + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
48 + * GNU General Public License for more details.
49 + */
50 +
51 +#include <common.h>
52 +#include <malloc.h>
53 +#include <asm/io.h>
54 +#include <linux/list.h>
55 +#include <sh_dma.h>
56 +
57 +struct sh_dma {
58 +       u32 base;
59 +       u32 mask;
60 +       u32 nch;
61 +       struct list_head list;
62 +};
63 +
64 +struct sh_dma_chan {
65 +       struct sh_dma *dma;
66 +       u32 base;
67 +       u32 num;
68 +       u32 ts;
69 +       u32 bs;
70 +       u32 rounds;
71 +};
72 +
73 +#define SH_DMA_MAX_TC                  0x1000000
74 +#define SH_DMA_MAX_CHAN                        32
75 +#define SH_DMA_CHAN_OFFSET             0x8000
76 +#define SH_DMA_CHAN_SIZE               0x80
77 +
78 +/* Global registers */
79 +#define SH_DMAISTA                     0x20
80 +#define SH_DMASEC                      0x30
81 +#define SH_DMAOR                       0x60
82 +#define SH_DMACHCL                     0x80
83 +#define SH_DMADPSEC                    0xA0
84 +
85 +/* DMA operation register bits */
86 +#define SH_DMAOR_DME                   (0x1 << 0)
87 +
88 +/* Channel registers */
89 +#define SH_DMASAR                      0x00
90 +#define SH_DMADAR                      0x04
91 +#define SH_DMATCR                      0x08
92 +#define SH_DMACHCR                     0x0C
93 +#define SH_DMATSR                      0x28
94 +#define SH_DMATCRB                     0x18
95 +#define SH_DMATSRB                     0x38
96 +#define SH_DMACHCRB                    0x1C
97 +#define SH_DMARS                       0x40
98 +#define SH_DMABUFCR                    0x48
99 +#define SH_DMADPBASE                   0x50
100 +#define SH_DMADPCR                     0x54
101 +#define SH_DMAFIXSAR                   0x10
102 +#define SH_DMAFIXDAR                   0x14
103 +#define SH_DMAFIXDPBASE                        0x60
104 +
105 +/* Channel control register bits */
106 +#define SH_DMACHCR_SM(v)               (((v) & 0x3) << 12)
107 +#define SH_DMACHCR_SM_MASK             (0x3 << 12)
108 +#define SH_DMACHCR_DM(v)               (((v) & 0x3) << 14)
109 +#define SH_DMACHCR_DM_MASK             (0x3 << 14)
110 +#define SH_DMACHCR_TS_1                        (0x0 << 3 | 0x0 << 20)
111 +#define SH_DMACHCR_TS_2                        (0x1 << 3 | 0x0 << 20)
112 +#define SH_DMACHCR_TS_4                        (0x2 << 3 | 0x0 << 20)
113 +#define SH_DMACHCR_TS_8                        (0x3 << 3 | 0x1 << 20)
114 +#define SH_DMACHCR_TS_16               (0x3 << 3 | 0x0 << 20)
115 +#define SH_DMACHCR_TS_32               (0x0 << 3 | 0x1 << 20)
116 +#define SH_DMACHCR_TS_64               (0x1 << 3 | 0x1 << 20)
117 +#define SH_DMACHCR_TS_MASK             (0x3 << 3 | 0x3 << 20)
118 +#define SH_DMACHCR_RS_AUTO             (0x4 << 8)
119 +#define SH_DMACHCR_RS_SEL              (0x8 << 8)
120 +#define SH_DMACHCR_RS_MASK             (0xf << 8)
121 +#define SH_DMACHCR_CAE                 (0x1 << 31)
122 +#define SH_DMACHCR_TE                  (0x1 << 1)
123 +#define SH_DMACHCR_DE                  (0x1 << 0)
124 +
125 +#define sh_dma_writel(d, r, v)         writel((v), (d)->base + (r))
126 +#define sh_dma_readl(d, r)             readl((d)->base + (r))
127 +#define sh_dma_writew(d, r, v)         writew((v), (d)->base + (r))
128 +#define sh_dma_readw(d, r)             readw((d)->base + (r))
129 +
130 +static LIST_HEAD(sh_dma_list);
131 +
132 +struct sh_dma *sh_dma_add(u32 base, u32 nch)
133 +{
134 +       struct list_head *entry;
135 +       struct sh_dma *dma;
136 +       u32 mask;
137 +
138 +       if (nch > SH_DMA_MAX_CHAN)
139 +               return NULL;
140 +
141 +       mask = (1 << nch) - 1;
142 +       list_for_each(entry, &sh_dma_list) {
143 +               dma = list_entry(entry, struct sh_dma, list);
144 +               if (dma->base == base) {
145 +                       if (nch > dma->nch) {
146 +                               mask &= ~((1 << dma->nch) - 1);
147 +                               sh_dma_writel(dma, SH_DMACHCL, mask);
148 +                               dma->nch = nch;
149 +                       }
150 +                       return dma;
151 +               }
152 +       }
153 +
154 +       dma = malloc(sizeof(*dma));
155 +       if (!dma)
156 +               return NULL;
157 +
158 +       dma->base = base;
159 +       dma->mask = 0;
160 +       dma->nch = nch;
161 +       sh_dma_writel(dma, SH_DMACHCL, mask);
162 +       sh_dma_writew(dma, SH_DMAOR, SH_DMAOR_DME);
163 +       list_add(&dma->list, &sh_dma_list);
164 +       return dma;
165 +}
166 +
167 +void sh_dma_chan_src(struct sh_dma_chan *chan, u32 src)
168 +{
169 +       sh_dma_writel(chan, SH_DMASAR, src);
170 +}
171 +
172 +void sh_dma_chan_dst(struct sh_dma_chan *chan, u32 dst)
173 +{
174 +       sh_dma_writel(chan, SH_DMADAR, dst);
175 +}
176 +
177 +void sh_dma_chan_cfg(struct sh_dma_chan *chan, u8 midrid, u8 sm, u8 dm)
178 +{
179 +       u32 val;
180 +
181 +       sh_dma_writew(chan, SH_DMARS, midrid);
182 +       val = sh_dma_readl(chan, SH_DMACHCR);
183 +       val &= ~(SH_DMACHCR_RS_MASK |
184 +                SH_DMACHCR_SM_MASK | SH_DMACHCR_DM_MASK);
185 +       val |= midrid ? SH_DMACHCR_RS_SEL : SH_DMACHCR_RS_AUTO;
186 +       val |= SH_DMACHCR_SM(sm) | SH_DMACHCR_DM(dm);
187 +       sh_dma_writel(chan, SH_DMACHCR, val);
188 +}
189 +
190 +void sh_dma_chan_start(struct sh_dma_chan *chan, u32 ts, u8 bs)
191 +{
192 +       u32 val;
193 +
194 +       if (!ts)
195 +               return;
196 +
197 +       val = (ts + (1 << bs) - 1) >> bs;
198 +       val = val < SH_DMA_MAX_TC ? val : 0x0;
199 +       sh_dma_writel(chan, SH_DMATCR, val);
200 +
201 +       chan->ts = ts;
202 +       chan->bs = bs;
203 +       chan->rounds = val;
204 +
205 +       val = sh_dma_readl(chan, SH_DMACHCR);
206 +
207 +       val &= ~(SH_DMACHCR_TE | SH_DMACHCR_TS_MASK);
208 +       val |= SH_DMACHCR_DE;
209 +       switch (bs) {
210 +       default:
211 +       case 0:
212 +               val |= SH_DMACHCR_TS_1;
213 +               break;
214 +       case 1:
215 +               val |= SH_DMACHCR_TS_2;
216 +               break;
217 +       case 2:
218 +               val |= SH_DMACHCR_TS_4;
219 +               break;
220 +       case 3:
221 +               val |= SH_DMACHCR_TS_8;
222 +               break;
223 +       case 4:
224 +               val |= SH_DMACHCR_TS_16;
225 +               break;
226 +       case 5:
227 +               val |= SH_DMACHCR_TS_32;
228 +               break;
229 +       case 6:
230 +               val |= SH_DMACHCR_TS_64;
231 +               break;
232 +       }
233 +
234 +       sh_dma_writel(chan, SH_DMACHCR, val);
235 +}
236 +
237 +void sh_dma_chan_stop(struct sh_dma_chan *chan)
238 +{
239 +       u32 val;
240 +
241 +       chan->ts = 0;
242 +       chan->bs = 0;
243 +       chan->rounds = 0;
244 +
245 +       val = sh_dma_readl(chan, SH_DMACHCR);
246 +       val &= ~(SH_DMACHCR_CAE | SH_DMACHCR_TE | SH_DMACHCR_DE);
247 +       sh_dma_writel(chan, SH_DMACHCR, val);
248 +       do {
249 +               val = sh_dma_readl(chan, SH_DMACHCR);
250 +       } while (val & SH_DMACHCR_DE);
251 +}
252 +
253 +int sh_dma_chan_wait(struct sh_dma_chan *chan)
254 +{
255 +       u32 val;
256 +       u32 timeout = 10000000;
257 +       int retval = 0;
258 +
259 +       do {
260 +               val = sh_dma_readl(chan, SH_DMACHCR);
261 +               val &= SH_DMACHCR_CAE | SH_DMACHCR_TE | SH_DMACHCR_DE;
262 +               if (val == (SH_DMACHCR_TE | SH_DMACHCR_DE))
263 +                       break;
264 +
265 +               if (!timeout)
266 +                       return -ETIMEDOUT;
267 +
268 +               timeout--;
269 +               udelay(1);
270 +       } while (1);
271 +
272 +       if (!(val & SH_DMACHCR_DE))
273 +               return chan->ts ? -EINTR : 0;
274 +
275 +       if (val & SH_DMACHCR_CAE) {
276 +               retval = -EFAULT;
277 +               goto out;
278 +       }
279 +
280 +       val = chan->rounds < SH_DMA_MAX_TC ? chan->rounds : SH_DMA_MAX_TC;
281 +       val = chan->rounds - val;
282 +       if (val) {
283 +               puts("abnormal end\n");
284 +               sh_dma_chan_start(chan, val << chan->bs, 0);
285 +               return -EAGAIN;
286 +       }
287 +
288 +out:
289 +       sh_dma_chan_stop(chan);
290 +       return retval;
291 +}
292 +
293 +void sh_dma_chan_clr(struct sh_dma_chan *chan)
294 +{
295 +       chan->ts = 0;
296 +       chan->bs = 0;
297 +       chan->rounds = 0;
298 +
299 +       sh_dma_writel(chan->dma, SH_DMACHCL, 1 << chan->num);
300 +}
301 +
302 +struct sh_dma_chan *sh_dma_chan_init(struct sh_dma *dma, int ch)
303 +{
304 +       struct sh_dma_chan *chan;
305 +       u32 mask;
306 +
307 +       if (ch < 0) {
308 +               if (!~dma->mask)
309 +                       return NULL;
310 +
311 +               ch = ffz(dma->mask);
312 +       }
313 +
314 +       if (!dma || ch > dma->nch)
315 +               return NULL;
316 +
317 +       mask = 1 << ch;
318 +       if (dma->mask & mask)
319 +               return NULL;
320 +
321 +       chan = malloc(sizeof(*chan));
322 +       if (!chan)
323 +               return NULL;
324 +
325 +       dma->mask |= mask;
326 +       chan->dma = dma;
327 +       chan->base = dma->base + SH_DMA_CHAN_OFFSET + ch * SH_DMA_CHAN_SIZE;
328 +       chan->num = ch;
329 +       sh_dma_chan_clr(chan);
330 +
331 +       return chan;
332 +}
333 +
334 +void sh_dma_chan_release(struct sh_dma_chan *chan)
335 +{
336 +       struct sh_dma *dma = chan->dma;
337 +
338 +       dma->mask &= ~(1 << chan->num);
339 +       free(chan);
340 +}
341 diff --git a/drivers/mmc/sh_sdhi.c b/drivers/mmc/sh_sdhi.c
342 index ddad43a..80dc7a8 100644
343 --- a/drivers/mmc/sh_sdhi.c
344 +++ b/drivers/mmc/sh_sdhi.c
345 @@ -17,7 +17,6 @@
346  #include <command.h>
347  #include <mmc.h>
348  #include <malloc.h>
349 -#include <mmc.h>
350  #include <asm/errno.h>
351  #include <asm/io.h>
352  
353 @@ -33,6 +32,111 @@
354  
355  #define DRIVER_NAME "sh-sdhi"
356  
357 +#ifdef CONFIG_SH_DMA
358 +
359 +#ifdef CONFIG_SYS_DCACHE_OFF
360 +static inline void sh_sdhi_invalidate_dcache(u32 addr, int len) { }
361 +#else  /* CONFIG_SYS_DCACHE_OFF */
362 +#define DCACHE_LINE_MASK       (ARCH_DMA_MINALIGN - 1)
363 +
364 +static void sh_sdhi_invalidate_dcache(u32 addr, int len)
365 +{
366 +       u32 start, end;
367 +
368 +       start = addr & ~DCACHE_LINE_MASK;
369 +       if (start != addr) {
370 +               end = start + ARCH_DMA_MINALIGN;
371 +               flush_dcache_range(start, end);
372 +
373 +               len -= end - addr;
374 +               start = end;
375 +       }
376 +
377 +       if (len >= ARCH_DMA_MINALIGN) {
378 +               end = (start + len) & ~DCACHE_LINE_MASK;
379 +               invalidate_dcache_range(start, end);
380 +
381 +               len &= DCACHE_LINE_MASK;
382 +               start = end;
383 +       }
384 +
385 +       if (len > 0) {
386 +               end = start + ARCH_DMA_MINALIGN;
387 +               flush_dcache_range(start, end);
388 +       }
389 +}
390 +#endif /* CONFIG_SYS_DCACHE_OFF */
391 +
392 +static void sh_sdhi_dma_init(struct sdhi_host *host)
393 +{
394 +       struct sh_dma *dma;
395 +
396 +       dma = sh_dma_add(CONFIG_SH_SYS_DMAL_BASE, CONFIG_SH_SYS_DMAL_NCH);
397 +       if (!dma)
398 +               return;
399 +
400 +       host->dma_rx = sh_dma_chan_init(dma, 1);
401 +       if (!host->dma_rx)
402 +               return;
403 +
404 +       sh_dma_chan_cfg(host->dma_rx, SH_DMA_SDHI0_RX,
405 +                       SH_DMA_AM_FIX, SH_DMA_AM_INC);
406 +       sh_dma_chan_src(host->dma_rx,
407 +                       host->addr + (SDHI_BUF0 << host->bus_shift) +
408 +                       0x2000);
409 +}
410 +
411 +static void sh_sdhi_dma_release(struct sdhi_host *host)
412 +{
413 +       if (host->dma_rx) {
414 +               sh_dma_chan_release(host->dma_rx);
415 +               host->dma_rx = NULL;
416 +       }
417 +}
418 +
419 +static void sh_sdhi_start_dma_rx(struct sdhi_host *host,
420 +                                       struct mmc_data *data)
421 +{
422 +       int ret;
423 +       u32 blocksize = data->blocksize;
424 +       sh_sdhi_dma_init(host);
425 +       sdhi_writew(host, SDHI_SD_DMACR, 0xa0);
426 +       sdhi_writew(host, SDHI_CC_EXT_MODE, (1 << 1));
427 +
428 +       sh_sdhi_invalidate_dcache((u32)data->dest, blocksize);
429 +
430 +       sh_dma_chan_dst(host->dma_rx, (u32)data->dest);
431 +
432 +       /* sh_sdhi_bitset(BUF_ACC_DMAREN, &host->regs->ce_buf_acc); */
433 +
434 +       /* MMCIF is capable to transfer only 4 bytes at a time,
435 +        * provide size order as a param */
436 +       blocksize = sdhi_readw(host, SDHI_SIZE);
437 +       sh_dma_chan_start(host->dma_rx, blocksize, 1);
438 +
439 +       do {
440 +               ret = sh_dma_chan_wait(host->dma_rx);
441 +       } while (ret == -EAGAIN);
442 +       sdhi_writew(host, SDHI_CC_EXT_MODE, 0x0);
443 +       sh_dma_chan_clr(host->dma_rx);
444 +       sh_sdhi_dma_release(host);
445 +}
446 +
447 +static void sdhi_dma_transfer(struct sdhi_host *host,
448 +                       struct mmc_data *data)
449 +{
450 +       sh_sdhi_start_dma_rx(host, data);
451 +}
452 +
453 +
454 +#else  /* CONFIG_SH_DMA */
455 +static inline void sh_sdhi_dma_init(struct sdhi_host *host) { }
456 +static inline void sh_sdhi_dma_release(struct sdhi_host *host) { }
457 +static inline void sh_sdhi_start_dma_rx(struct sdhi_host *host,
458 +                                               struct mmc_data *data) { }
459 +
460 +#endif /* CONFIG_SH_DMA */
461 +
462  static void *mmc_priv(struct mmc *mmc)
463  {
464         return (void *)mmc->priv;
465 @@ -253,7 +357,9 @@ static int sdhi_single_read(struct sdhi_host *host, struct mmc_data *data)
466  {
467         int ch = host->ch;
468         long time;
469 +#ifndef CONFIG_SH_DMA
470         unsigned short blocksize, i;
471 +#endif
472         unsigned short *p = (unsigned short *)data->dest;
473  
474         if ((unsigned long)p & 0x00000001) {
475 @@ -272,10 +378,14 @@ static int sdhi_single_read(struct sdhi_host *host, struct mmc_data *data)
476                 return sdhi_error_manage(host);
477  
478         g_wait_int[ch] = 0;
479 +#ifdef CONFIG_SH_DMA
480 +       sdhi_dma_transfer(host, data);
481 +#else
482         blocksize = sdhi_readw(host, SDHI_SIZE);
483         for (i = 0; i < blocksize / 2; i++)
484                 *p++ = sdhi_readw(host, SDHI_BUF0);
485  
486 +#endif
487         time = sdhi_wait_interrupt_flag(host);
488         if (time == 0 || g_sd_error[ch] != 0)
489                 return sdhi_error_manage(host);
490 @@ -537,7 +647,6 @@ static int sdhi_start_cmd(struct sdhi_host *host,
491                 ;
492  
493         sdhi_writew(host, SDHI_CMD, (unsigned short)(opc & CMD_MASK));
494 -
495         g_wait_int[host->ch] = 0;
496         sdhi_writew(host, SDHI_INFO1_MASK,
497                         ~INFO1M_RESP_END & sdhi_readw(host, SDHI_INFO1_MASK));
498 @@ -546,7 +655,6 @@ static int sdhi_start_cmd(struct sdhi_host *host,
499                           INFO2M_END_ERROR | INFO2M_TIMEOUT   |
500                           INFO2M_RESP_TIMEOUT | INFO2M_ILA)   &
501                           sdhi_readw(host, SDHI_INFO2_MASK));
502 -
503         time = sdhi_wait_interrupt_flag(host);
504         if (time == 0)
505                 return sdhi_error_manage(host);
506 @@ -578,7 +686,6 @@ static int sdhi_start_cmd(struct sdhi_host *host,
507         }
508         if (host->data)
509                 ret = sdhi_data_trans(host, data, opc);
510 -
511         pr_debug("ret = %d, resp = %08x, %08x, %08x, %08x\n",
512                  ret, cmd->response[0], cmd->response[1],
513                  cmd->response[2], cmd->response[3]);
514 @@ -697,3 +804,46 @@ int sdhi_mmc_init(unsigned long addr, int ch)
515         return ret;
516  }
517  
518 +
519 +int sdhi_warmup_sdio(struct mmc *mmc)
520 +{
521 +       struct mmc_cmd cmd;
522 +       int err;
523 +       int32_t ocr;
524 +
525 +       udelay(10);
526 +
527 +       mmc->bus_width = 1;
528 +       mmc->clock = mmc->f_min;
529 +       sdhi_set_ios(mmc);
530 +       udelay(10);
531 +
532 +       cmd.cmdidx = MMC_CMD_GO_IDLE_STATE;
533 +       cmd.resp_type = MMC_RSP_NONE;
534 +       cmd.cmdarg = 0;
535 +       err = sdhi_request(mmc, &cmd, NULL);
536 +       if (err)
537 +               goto err_out;
538 +       cmd.cmdidx = 0x5;
539 +       cmd.resp_type = MMC_RSP_R4;
540 +       cmd.cmdarg = 0;
541 +       err = sdhi_request(mmc, &cmd, NULL);
542 +       if (err)
543 +               goto err_out;
544 +       ocr = cmd.response[0];
545 +       ocr |= (1 << 24);
546 +       cmd.cmdidx = 0x05;
547 +       cmd.resp_type = MMC_RSP_R4;
548 +       cmd.cmdarg = ocr;
549 +       err = sdhi_request(mmc, &cmd, NULL);
550 +       if (err)
551 +               goto err_out;
552 +       printf("SDIO OCR:%08x\n", cmd.response[0]);
553 +       return 0;
554 +err_out:
555 +       printf("cmd: CMD%02d err = %d, resp = %08x, %08x, %08x, %08x\n",
556 +                err, cmd.cmdidx, cmd.response[0], cmd.response[1],
557 +                cmd.response[2], cmd.response[3]);
558 +       return err;
559 +}
560 +
561 diff --git a/drivers/mmc/sh_sdhi.h b/drivers/mmc/sh_sdhi.h
562 index 4deded2..7b5d421 100644
563 --- a/drivers/mmc/sh_sdhi.h
564 +++ b/drivers/mmc/sh_sdhi.h
565 @@ -15,6 +15,8 @@
566  #ifndef _SH_SDHI_H_
567  #define _SH_SDHI_H_
568  
569 +#include <sh_dma.h>
570 +
571  #define SDHI_CMD                       (0x0000 >> 1)
572  #define SDHI_PORTSEL                   (0x0004 >> 1)
573  #define SDHI_ARG0                      (0x0008 >> 1)
574 @@ -181,6 +183,9 @@ struct sdhi_host {
575         unsigned int    power_mode;
576         int             ch;
577         int             bus_shift;
578 +#ifdef CONFIG_SH_DMA
579 +       struct sh_dma_chan      *dma_rx;
580 +#endif
581  };
582  
583  static unsigned short g_wait_int[CONFIG_MMC_SH_SDHI_NR_CHANNEL];
584 diff --git a/include/sh_dma.h b/include/sh_dma.h
585 new file mode 100644
586 index 0000000..3f35c3a
587 --- /dev/null
588 +++ b/include/sh_dma.h
589 @@ -0,0 +1,58 @@
590 +#ifndef __SH_DMA_H__
591 +#define __SH_DMA_H__
592 +
593 +#include <asm/types.h>
594 +#include <errno.h>
595 +
596 +#define SH_DMA_MMCIF0_RX       0xD2
597 +#define SH_DMA_SDHI0_RX        0xCE
598 +
599 +/* Address mode */
600 +#define SH_DMA_AM_FIX          0
601 +#define SH_DMA_AM_INC          1
602 +#define SH_DMA_AM_DEC          2
603 +
604 +struct sh_dma;
605 +struct sh_dma_chan;
606 +
607 +#ifdef CONFIG_SH_DMA
608 +struct sh_dma *sh_dma_add(u32 base, u32 nch);
609 +struct sh_dma_chan *sh_dma_chan_init(struct sh_dma *dma, int ch);
610 +void sh_dma_chan_release(struct sh_dma_chan *chan);
611 +
612 +void sh_dma_chan_src(struct sh_dma_chan *chan, u32 src);
613 +void sh_dma_chan_dst(struct sh_dma_chan *chan, u32 dst);
614 +void sh_dma_chan_cfg(struct sh_dma_chan *chan, u8 midrid, u8 sm, u8 dm);
615 +void sh_dma_chan_start(struct sh_dma_chan *chan, u32 ts, u8 bs);
616 +void sh_dma_chan_stop(struct sh_dma_chan *chan);
617 +int sh_dma_chan_wait(struct sh_dma_chan *chan);
618 +void sh_dma_chan_clr(struct sh_dma_chan *chan);
619 +#else
620 +static inline struct sh_dma *sh_dma_add(u32 base, u32 nch)
621 +{
622 +       return NULL;
623 +}
624 +
625 +static inline struct sh_dma_chan *sh_dma_chan_init(struct sh_dma *dma,
626 +                                                      int ch)
627 +{
628 +       return NULL;
629 +}
630 +
631 +static inline void sh_dma_chan_release(struct sh_dma_chan *chan) { }
632 +static inline void sh_dma_chan_src(struct sh_dma_chan *chan, u32 src) { }
633 +static inline void sh_dma_chan_dst(struct sh_dma_chan *chan, u32 dst) { }
634 +static inline void sh_dma_chan_cfg(struct sh_dma_chan *chan,
635 +                                    u8 midrid, u8 sm, u8 dm) { }
636 +static inline void sh_dma_chan_start(struct sh_dma_chan *chan,
637 +                                    u32 ts, u8 bs) { }
638 +static inline void sh_dma_chan_stop(struct sh_dma_chan *chan) { }
639 +static inline int sh_dma_chan_wait(struct sh_dma_chan *chan)
640 +{
641 +       return -ENOSYS;
642 +}
643 +
644 +static inline void sh_dma_chan_clr(struct sh_dma_chan *chan) { }
645 +#endif
646 +
647 +#endif /* __SH_DMA_H__ */
648 -- 
649 1.8.3.1
650