linux/arch/arm/plat-omap/dma.c
<<
>>
Prefs
   1/*
   2 * linux/arch/arm/plat-omap/dma.c
   3 *
   4 * Copyright (C) 2003 Nokia Corporation
   5 * Author: Juha Yrjölä <juha.yrjola@nokia.com>
   6 * DMA channel linking for 1610 by Samuel Ortiz <samuel.ortiz@nokia.com>
   7 * Graphics DMA and LCD DMA graphics tranformations
   8 * by Imre Deak <imre.deak@nokia.com>
   9 * OMAP2/3 support Copyright (C) 2004-2007 Texas Instruments, Inc.
  10 * Merged to support both OMAP1 and OMAP2 by Tony Lindgren <tony@atomide.com>
  11 * Some functions based on earlier dma-omap.c Copyright (C) 2001 RidgeRun, Inc.
  12 *
  13 * Support functions for the OMAP internal DMA channels.
  14 *
  15 * This program is free software; you can redistribute it and/or modify
  16 * it under the terms of the GNU General Public License version 2 as
  17 * published by the Free Software Foundation.
  18 *
  19 */
  20
  21#include <linux/module.h>
  22#include <linux/init.h>
  23#include <linux/sched.h>
  24#include <linux/spinlock.h>
  25#include <linux/errno.h>
  26#include <linux/interrupt.h>
  27#include <linux/irq.h>
  28
  29#include <asm/system.h>
  30#include <asm/hardware.h>
  31#include <asm/dma.h>
  32#include <asm/io.h>
  33
  34#include <asm/arch/tc.h>
  35
  36#undef DEBUG
  37
  38#ifndef CONFIG_ARCH_OMAP1
  39enum { DMA_CH_ALLOC_DONE, DMA_CH_PARAMS_SET_DONE, DMA_CH_STARTED,
  40        DMA_CH_QUEUED, DMA_CH_NOTSTARTED, DMA_CH_PAUSED, DMA_CH_LINK_ENABLED
  41};
  42
  43enum { DMA_CHAIN_STARTED, DMA_CHAIN_NOTSTARTED };
  44#endif
  45
  46#define OMAP_DMA_ACTIVE         0x01
  47#define OMAP_DMA_CCR_EN         (1 << 7)
  48#define OMAP2_DMA_CSR_CLEAR_MASK        0xffe
  49
  50#define OMAP_FUNC_MUX_ARM_BASE  (0xfffe1000 + 0xec)
  51
  52static int enable_1510_mode = 0;
  53
  54struct omap_dma_lch {
  55        int next_lch;
  56        int dev_id;
  57        u16 saved_csr;
  58        u16 enabled_irqs;
  59        const char *dev_name;
  60        void (* callback)(int lch, u16 ch_status, void *data);
  61        void *data;
  62
  63#ifndef CONFIG_ARCH_OMAP1
  64        /* required for Dynamic chaining */
  65        int prev_linked_ch;
  66        int next_linked_ch;
  67        int state;
  68        int chain_id;
  69
  70        int status;
  71#endif
  72        long flags;
  73};
  74
  75#ifndef CONFIG_ARCH_OMAP1
  76struct dma_link_info {
  77        int *linked_dmach_q;
  78        int no_of_lchs_linked;
  79
  80        int q_count;
  81        int q_tail;
  82        int q_head;
  83
  84        int chain_state;
  85        int chain_mode;
  86
  87};
  88
  89static struct dma_link_info dma_linked_lch[OMAP_LOGICAL_DMA_CH_COUNT];
  90
  91/* Chain handling macros */
  92#define OMAP_DMA_CHAIN_QINIT(chain_id)                                  \
  93        do {                                                            \
  94                dma_linked_lch[chain_id].q_head =                       \
  95                dma_linked_lch[chain_id].q_tail =                       \
  96                dma_linked_lch[chain_id].q_count = 0;                   \
  97        } while (0)
  98#define OMAP_DMA_CHAIN_QFULL(chain_id)                                  \
  99                (dma_linked_lch[chain_id].no_of_lchs_linked ==          \
 100                dma_linked_lch[chain_id].q_count)
 101#define OMAP_DMA_CHAIN_QLAST(chain_id)                                  \
 102        do {                                                            \
 103                ((dma_linked_lch[chain_id].no_of_lchs_linked-1) ==      \
 104                dma_linked_lch[chain_id].q_count)                       \
 105        } while (0)
 106#define OMAP_DMA_CHAIN_QEMPTY(chain_id)                                 \
 107                (0 == dma_linked_lch[chain_id].q_count)
 108#define __OMAP_DMA_CHAIN_INCQ(end)                                      \
 109        ((end) = ((end)+1) % dma_linked_lch[chain_id].no_of_lchs_linked)
 110#define OMAP_DMA_CHAIN_INCQHEAD(chain_id)                               \
 111        do {                                                            \
 112                __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_head); \
 113                dma_linked_lch[chain_id].q_count--;                     \
 114        } while (0)
 115
 116#define OMAP_DMA_CHAIN_INCQTAIL(chain_id)                               \
 117        do {                                                            \
 118                __OMAP_DMA_CHAIN_INCQ(dma_linked_lch[chain_id].q_tail); \
 119                dma_linked_lch[chain_id].q_count++; \
 120        } while (0)
 121#endif
 122static int dma_chan_count;
 123
 124static spinlock_t dma_chan_lock;
 125static struct omap_dma_lch dma_chan[OMAP_LOGICAL_DMA_CH_COUNT];
 126
 127static const u8 omap1_dma_irq[OMAP_LOGICAL_DMA_CH_COUNT] = {
 128        INT_DMA_CH0_6, INT_DMA_CH1_7, INT_DMA_CH2_8, INT_DMA_CH3,
 129        INT_DMA_CH4, INT_DMA_CH5, INT_1610_DMA_CH6, INT_1610_DMA_CH7,
 130        INT_1610_DMA_CH8, INT_1610_DMA_CH9, INT_1610_DMA_CH10,
 131        INT_1610_DMA_CH11, INT_1610_DMA_CH12, INT_1610_DMA_CH13,
 132        INT_1610_DMA_CH14, INT_1610_DMA_CH15, INT_DMA_LCD
 133};
 134
 135static inline void disable_lnk(int lch);
 136static void omap_disable_channel_irq(int lch);
 137static inline void omap_enable_channel_irq(int lch);
 138
 139#define REVISIT_24XX()          printk(KERN_ERR "FIXME: no %s on 24xx\n", \
 140                                                __func__);
 141
 142#ifdef CONFIG_ARCH_OMAP15XX
 143/* Returns 1 if the DMA module is in OMAP1510-compatible mode, 0 otherwise */
 144int omap_dma_in_1510_mode(void)
 145{
 146        return enable_1510_mode;
 147}
 148#else
 149#define omap_dma_in_1510_mode()         0
 150#endif
 151
 152#ifdef CONFIG_ARCH_OMAP1
 153static inline int get_gdma_dev(int req)
 154{
 155        u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
 156        int shift = ((req - 1) % 5) * 6;
 157
 158        return ((omap_readl(reg) >> shift) & 0x3f) + 1;
 159}
 160
 161static inline void set_gdma_dev(int req, int dev)
 162{
 163        u32 reg = OMAP_FUNC_MUX_ARM_BASE + ((req - 1) / 5) * 4;
 164        int shift = ((req - 1) % 5) * 6;
 165        u32 l;
 166
 167        l = omap_readl(reg);
 168        l &= ~(0x3f << shift);
 169        l |= (dev - 1) << shift;
 170        omap_writel(l, reg);
 171}
 172#else
 173#define set_gdma_dev(req, dev)  do {} while (0)
 174#endif
 175
 176static void clear_lch_regs(int lch)
 177{
 178        int i;
 179        u32 lch_base = OMAP_DMA_BASE + lch * 0x40;
 180
 181        for (i = 0; i < 0x2c; i += 2)
 182                omap_writew(0, lch_base + i);
 183}
 184
 185void omap_set_dma_priority(int lch, int dst_port, int priority)
 186{
 187        unsigned long reg;
 188        u32 l;
 189
 190        if (cpu_class_is_omap1()) {
 191                switch (dst_port) {
 192                case OMAP_DMA_PORT_OCP_T1:      /* FFFECC00 */
 193                        reg = OMAP_TC_OCPT1_PRIOR;
 194                        break;
 195                case OMAP_DMA_PORT_OCP_T2:      /* FFFECCD0 */
 196                        reg = OMAP_TC_OCPT2_PRIOR;
 197                        break;
 198                case OMAP_DMA_PORT_EMIFF:       /* FFFECC08 */
 199                        reg = OMAP_TC_EMIFF_PRIOR;
 200                        break;
 201                case OMAP_DMA_PORT_EMIFS:       /* FFFECC04 */
 202                        reg = OMAP_TC_EMIFS_PRIOR;
 203                        break;
 204                default:
 205                        BUG();
 206                        return;
 207                }
 208                l = omap_readl(reg);
 209                l &= ~(0xf << 8);
 210                l |= (priority & 0xf) << 8;
 211                omap_writel(l, reg);
 212        }
 213
 214        if (cpu_class_is_omap2()) {
 215                if (priority)
 216                        OMAP_DMA_CCR_REG(lch) |= (1 << 6);
 217                else
 218                        OMAP_DMA_CCR_REG(lch) &= ~(1 << 6);
 219        }
 220}
 221
 222void omap_set_dma_transfer_params(int lch, int data_type, int elem_count,
 223                                  int frame_count, int sync_mode,
 224                                  int dma_trigger, int src_or_dst_synch)
 225{
 226        OMAP_DMA_CSDP_REG(lch) &= ~0x03;
 227        OMAP_DMA_CSDP_REG(lch) |= data_type;
 228
 229        if (cpu_class_is_omap1()) {
 230                OMAP_DMA_CCR_REG(lch) &= ~(1 << 5);
 231                if (sync_mode == OMAP_DMA_SYNC_FRAME)
 232                        OMAP_DMA_CCR_REG(lch) |= 1 << 5;
 233
 234                OMAP1_DMA_CCR2_REG(lch) &= ~(1 << 2);
 235                if (sync_mode == OMAP_DMA_SYNC_BLOCK)
 236                        OMAP1_DMA_CCR2_REG(lch) |= 1 << 2;
 237        }
 238
 239        if (cpu_class_is_omap2() && dma_trigger) {
 240                u32 val = OMAP_DMA_CCR_REG(lch);
 241
 242                val &= ~(3 << 19);
 243                if (dma_trigger > 63)
 244                        val |= 1 << 20;
 245                if (dma_trigger > 31)
 246                        val |= 1 << 19;
 247
 248                val &= ~(0x1f);
 249                val |= (dma_trigger & 0x1f);
 250
 251                if (sync_mode & OMAP_DMA_SYNC_FRAME)
 252                        val |= 1 << 5;
 253                else
 254                        val &= ~(1 << 5);
 255
 256                if (sync_mode & OMAP_DMA_SYNC_BLOCK)
 257                        val |= 1 << 18;
 258                else
 259                        val &= ~(1 << 18);
 260
 261                if (src_or_dst_synch)
 262                        val |= 1 << 24;         /* source synch */
 263                else
 264                        val &= ~(1 << 24);      /* dest synch */
 265
 266                OMAP_DMA_CCR_REG(lch) = val;
 267        }
 268
 269        OMAP_DMA_CEN_REG(lch) = elem_count;
 270        OMAP_DMA_CFN_REG(lch) = frame_count;
 271}
 272
 273void omap_set_dma_color_mode(int lch, enum omap_dma_color_mode mode, u32 color)
 274{
 275        u16 w;
 276
 277        BUG_ON(omap_dma_in_1510_mode());
 278
 279        if (cpu_class_is_omap2()) {
 280                REVISIT_24XX();
 281                return;
 282        }
 283
 284        w = OMAP1_DMA_CCR2_REG(lch) & ~0x03;
 285        switch (mode) {
 286        case OMAP_DMA_CONSTANT_FILL:
 287                w |= 0x01;
 288                break;
 289        case OMAP_DMA_TRANSPARENT_COPY:
 290                w |= 0x02;
 291                break;
 292        case OMAP_DMA_COLOR_DIS:
 293                break;
 294        default:
 295                BUG();
 296        }
 297        OMAP1_DMA_CCR2_REG(lch) = w;
 298
 299        w = OMAP1_DMA_LCH_CTRL_REG(lch) & ~0x0f;
 300        /* Default is channel type 2D */
 301        if (mode) {
 302                OMAP1_DMA_COLOR_L_REG(lch) = (u16)color;
 303                OMAP1_DMA_COLOR_U_REG(lch) = (u16)(color >> 16);
 304                w |= 1;         /* Channel type G */
 305        }
 306        OMAP1_DMA_LCH_CTRL_REG(lch) = w;
 307}
 308
 309void omap_set_dma_write_mode(int lch, enum omap_dma_write_mode mode)
 310{
 311        if (cpu_class_is_omap2()) {
 312                OMAP_DMA_CSDP_REG(lch) &= ~(0x3 << 16);
 313                OMAP_DMA_CSDP_REG(lch) |= (mode << 16);
 314        }
 315}
 316
 317/* Note that src_port is only for omap1 */
 318void omap_set_dma_src_params(int lch, int src_port, int src_amode,
 319                             unsigned long src_start,
 320                             int src_ei, int src_fi)
 321{
 322        if (cpu_class_is_omap1()) {
 323                OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 2);
 324                OMAP_DMA_CSDP_REG(lch) |= src_port << 2;
 325        }
 326
 327        OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 12);
 328        OMAP_DMA_CCR_REG(lch) |= src_amode << 12;
 329
 330        if (cpu_class_is_omap1()) {
 331                OMAP1_DMA_CSSA_U_REG(lch) = src_start >> 16;
 332                OMAP1_DMA_CSSA_L_REG(lch) = src_start;
 333        }
 334
 335        if (cpu_class_is_omap2())
 336                OMAP2_DMA_CSSA_REG(lch) = src_start;
 337
 338        OMAP_DMA_CSEI_REG(lch) = src_ei;
 339        OMAP_DMA_CSFI_REG(lch) = src_fi;
 340}
 341
 342void omap_set_dma_params(int lch, struct omap_dma_channel_params * params)
 343{
 344        omap_set_dma_transfer_params(lch, params->data_type,
 345                                     params->elem_count, params->frame_count,
 346                                     params->sync_mode, params->trigger,
 347                                     params->src_or_dst_synch);
 348        omap_set_dma_src_params(lch, params->src_port,
 349                                params->src_amode, params->src_start,
 350                                params->src_ei, params->src_fi);
 351
 352        omap_set_dma_dest_params(lch, params->dst_port,
 353                                 params->dst_amode, params->dst_start,
 354                                 params->dst_ei, params->dst_fi);
 355        if (params->read_prio || params->write_prio)
 356                omap_dma_set_prio_lch(lch, params->read_prio,
 357                                      params->write_prio);
 358}
 359
 360void omap_set_dma_src_index(int lch, int eidx, int fidx)
 361{
 362        if (cpu_class_is_omap2()) {
 363                REVISIT_24XX();
 364                return;
 365        }
 366        OMAP_DMA_CSEI_REG(lch) = eidx;
 367        OMAP_DMA_CSFI_REG(lch) = fidx;
 368}
 369
 370void omap_set_dma_src_data_pack(int lch, int enable)
 371{
 372        OMAP_DMA_CSDP_REG(lch) &= ~(1 << 6);
 373        if (enable)
 374                OMAP_DMA_CSDP_REG(lch) |= (1 << 6);
 375}
 376
 377void omap_set_dma_src_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 378{
 379        unsigned int burst = 0;
 380        OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 7);
 381
 382        switch (burst_mode) {
 383        case OMAP_DMA_DATA_BURST_DIS:
 384                break;
 385        case OMAP_DMA_DATA_BURST_4:
 386                if (cpu_class_is_omap2())
 387                        burst = 0x1;
 388                else
 389                        burst = 0x2;
 390                break;
 391        case OMAP_DMA_DATA_BURST_8:
 392                if (cpu_class_is_omap2()) {
 393                        burst = 0x2;
 394                        break;
 395                }
 396                /* not supported by current hardware on OMAP1
 397                 * w |= (0x03 << 7);
 398                 * fall through
 399                 */
 400        case OMAP_DMA_DATA_BURST_16:
 401                if (cpu_class_is_omap2()) {
 402                        burst = 0x3;
 403                        break;
 404                }
 405                /* OMAP1 don't support burst 16
 406                 * fall through
 407                 */
 408        default:
 409                BUG();
 410        }
 411        OMAP_DMA_CSDP_REG(lch) |= (burst << 7);
 412}
 413
 414/* Note that dest_port is only for OMAP1 */
 415void omap_set_dma_dest_params(int lch, int dest_port, int dest_amode,
 416                              unsigned long dest_start,
 417                              int dst_ei, int dst_fi)
 418{
 419        if (cpu_class_is_omap1()) {
 420                OMAP_DMA_CSDP_REG(lch) &= ~(0x1f << 9);
 421                OMAP_DMA_CSDP_REG(lch) |= dest_port << 9;
 422        }
 423
 424        OMAP_DMA_CCR_REG(lch) &= ~(0x03 << 14);
 425        OMAP_DMA_CCR_REG(lch) |= dest_amode << 14;
 426
 427        if (cpu_class_is_omap1()) {
 428                OMAP1_DMA_CDSA_U_REG(lch) = dest_start >> 16;
 429                OMAP1_DMA_CDSA_L_REG(lch) = dest_start;
 430        }
 431
 432        if (cpu_class_is_omap2())
 433                OMAP2_DMA_CDSA_REG(lch) = dest_start;
 434
 435        OMAP_DMA_CDEI_REG(lch) = dst_ei;
 436        OMAP_DMA_CDFI_REG(lch) = dst_fi;
 437}
 438
 439void omap_set_dma_dest_index(int lch, int eidx, int fidx)
 440{
 441        if (cpu_class_is_omap2()) {
 442                REVISIT_24XX();
 443                return;
 444        }
 445        OMAP_DMA_CDEI_REG(lch) = eidx;
 446        OMAP_DMA_CDFI_REG(lch) = fidx;
 447}
 448
 449void omap_set_dma_dest_data_pack(int lch, int enable)
 450{
 451        OMAP_DMA_CSDP_REG(lch) &= ~(1 << 13);
 452        if (enable)
 453                OMAP_DMA_CSDP_REG(lch) |= 1 << 13;
 454}
 455
 456void omap_set_dma_dest_burst_mode(int lch, enum omap_dma_burst_mode burst_mode)
 457{
 458        unsigned int burst = 0;
 459        OMAP_DMA_CSDP_REG(lch) &= ~(0x03 << 14);
 460
 461        switch (burst_mode) {
 462        case OMAP_DMA_DATA_BURST_DIS:
 463                break;
 464        case OMAP_DMA_DATA_BURST_4:
 465                if (cpu_class_is_omap2())
 466                        burst = 0x1;
 467                else
 468                        burst = 0x2;
 469                break;
 470        case OMAP_DMA_DATA_BURST_8:
 471                if (cpu_class_is_omap2())
 472                        burst = 0x2;
 473                else
 474                        burst = 0x3;
 475                break;
 476        case OMAP_DMA_DATA_BURST_16:
 477                if (cpu_class_is_omap2()) {
 478                        burst = 0x3;
 479                        break;
 480                }
 481                /* OMAP1 don't support burst 16
 482                 * fall through
 483                 */
 484        default:
 485                printk(KERN_ERR "Invalid DMA burst mode\n");
 486                BUG();
 487                return;
 488        }
 489        OMAP_DMA_CSDP_REG(lch) |= (burst << 14);
 490}
 491
 492static inline void omap_enable_channel_irq(int lch)
 493{
 494        u32 status;
 495
 496        /* Clear CSR */
 497        if (cpu_class_is_omap1())
 498                status = OMAP_DMA_CSR_REG(lch);
 499        else if (cpu_class_is_omap2())
 500                OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
 501
 502        /* Enable some nice interrupts. */
 503        OMAP_DMA_CICR_REG(lch) = dma_chan[lch].enabled_irqs;
 504}
 505
 506static void omap_disable_channel_irq(int lch)
 507{
 508        if (cpu_class_is_omap2())
 509                OMAP_DMA_CICR_REG(lch) = 0;
 510}
 511
 512void omap_enable_dma_irq(int lch, u16 bits)
 513{
 514        dma_chan[lch].enabled_irqs |= bits;
 515}
 516
 517void omap_disable_dma_irq(int lch, u16 bits)
 518{
 519        dma_chan[lch].enabled_irqs &= ~bits;
 520}
 521
 522static inline void enable_lnk(int lch)
 523{
 524        if (cpu_class_is_omap1())
 525                OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 14);
 526
 527        /* Set the ENABLE_LNK bits */
 528        if (dma_chan[lch].next_lch != -1)
 529                OMAP_DMA_CLNK_CTRL_REG(lch) =
 530                        dma_chan[lch].next_lch | (1 << 15);
 531
 532#ifndef CONFIG_ARCH_OMAP1
 533        if (dma_chan[lch].next_linked_ch != -1)
 534                OMAP_DMA_CLNK_CTRL_REG(lch) =
 535                        dma_chan[lch].next_linked_ch | (1 << 15);
 536#endif
 537}
 538
 539static inline void disable_lnk(int lch)
 540{
 541        /* Disable interrupts */
 542        if (cpu_class_is_omap1()) {
 543                OMAP_DMA_CICR_REG(lch) = 0;
 544                /* Set the STOP_LNK bit */
 545                OMAP_DMA_CLNK_CTRL_REG(lch) |= 1 << 14;
 546        }
 547
 548        if (cpu_class_is_omap2()) {
 549                omap_disable_channel_irq(lch);
 550                /* Clear the ENABLE_LNK bit */
 551                OMAP_DMA_CLNK_CTRL_REG(lch) &= ~(1 << 15);
 552        }
 553
 554        dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 555}
 556
 557static inline void omap2_enable_irq_lch(int lch)
 558{
 559        u32 val;
 560
 561        if (!cpu_class_is_omap2())
 562                return;
 563
 564        val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
 565        val |= 1 << lch;
 566        omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
 567}
 568
 569int omap_request_dma(int dev_id, const char *dev_name,
 570                     void (* callback)(int lch, u16 ch_status, void *data),
 571                     void *data, int *dma_ch_out)
 572{
 573        int ch, free_ch = -1;
 574        unsigned long flags;
 575        struct omap_dma_lch *chan;
 576
 577        spin_lock_irqsave(&dma_chan_lock, flags);
 578        for (ch = 0; ch < dma_chan_count; ch++) {
 579                if (free_ch == -1 && dma_chan[ch].dev_id == -1) {
 580                        free_ch = ch;
 581                        if (dev_id == 0)
 582                                break;
 583                }
 584        }
 585        if (free_ch == -1) {
 586                spin_unlock_irqrestore(&dma_chan_lock, flags);
 587                return -EBUSY;
 588        }
 589        chan = dma_chan + free_ch;
 590        chan->dev_id = dev_id;
 591
 592        if (cpu_class_is_omap1())
 593                clear_lch_regs(free_ch);
 594
 595        if (cpu_class_is_omap2())
 596                omap_clear_dma(free_ch);
 597
 598        spin_unlock_irqrestore(&dma_chan_lock, flags);
 599
 600        chan->dev_name = dev_name;
 601        chan->callback = callback;
 602        chan->data = data;
 603#ifndef CONFIG_ARCH_OMAP1
 604        chan->chain_id = -1;
 605        chan->next_linked_ch = -1;
 606#endif
 607        chan->enabled_irqs = OMAP_DMA_DROP_IRQ | OMAP_DMA_BLOCK_IRQ;
 608
 609        if (cpu_class_is_omap1())
 610                chan->enabled_irqs |= OMAP1_DMA_TOUT_IRQ;
 611        else if (cpu_class_is_omap2())
 612                chan->enabled_irqs |= OMAP2_DMA_MISALIGNED_ERR_IRQ |
 613                        OMAP2_DMA_TRANS_ERR_IRQ;
 614
 615        if (cpu_is_omap16xx()) {
 616                /* If the sync device is set, configure it dynamically. */
 617                if (dev_id != 0) {
 618                        set_gdma_dev(free_ch + 1, dev_id);
 619                        dev_id = free_ch + 1;
 620                }
 621                /* Disable the 1510 compatibility mode and set the sync device
 622                 * id. */
 623                OMAP_DMA_CCR_REG(free_ch) = dev_id | (1 << 10);
 624        } else if (cpu_is_omap730() || cpu_is_omap15xx()) {
 625                OMAP_DMA_CCR_REG(free_ch) = dev_id;
 626        }
 627
 628        if (cpu_class_is_omap2()) {
 629                omap2_enable_irq_lch(free_ch);
 630
 631                omap_enable_channel_irq(free_ch);
 632                /* Clear the CSR register and IRQ status register */
 633                OMAP_DMA_CSR_REG(free_ch) = OMAP2_DMA_CSR_CLEAR_MASK;
 634                omap_writel(1 << free_ch, OMAP_DMA4_IRQSTATUS_L0);
 635        }
 636
 637        *dma_ch_out = free_ch;
 638
 639        return 0;
 640}
 641
 642void omap_free_dma(int lch)
 643{
 644        unsigned long flags;
 645
 646        spin_lock_irqsave(&dma_chan_lock, flags);
 647        if (dma_chan[lch].dev_id == -1) {
 648                printk("omap_dma: trying to free nonallocated DMA channel %d\n",
 649                       lch);
 650                spin_unlock_irqrestore(&dma_chan_lock, flags);
 651                return;
 652        }
 653        dma_chan[lch].dev_id = -1;
 654        dma_chan[lch].next_lch = -1;
 655        dma_chan[lch].callback = NULL;
 656        spin_unlock_irqrestore(&dma_chan_lock, flags);
 657
 658        if (cpu_class_is_omap1()) {
 659                /* Disable all DMA interrupts for the channel. */
 660                OMAP_DMA_CICR_REG(lch) = 0;
 661                /* Make sure the DMA transfer is stopped. */
 662                OMAP_DMA_CCR_REG(lch) = 0;
 663        }
 664
 665        if (cpu_class_is_omap2()) {
 666                u32 val;
 667                /* Disable interrupts */
 668                val = omap_readl(OMAP_DMA4_IRQENABLE_L0);
 669                val &= ~(1 << lch);
 670                omap_writel(val, OMAP_DMA4_IRQENABLE_L0);
 671
 672                /* Clear the CSR register and IRQ status register */
 673                OMAP_DMA_CSR_REG(lch) = OMAP2_DMA_CSR_CLEAR_MASK;
 674                omap_writel(1 << lch, OMAP_DMA4_IRQSTATUS_L0);
 675
 676                /* Disable all DMA interrupts for the channel. */
 677                OMAP_DMA_CICR_REG(lch) = 0;
 678
 679                /* Make sure the DMA transfer is stopped. */
 680                OMAP_DMA_CCR_REG(lch) = 0;
 681                omap_clear_dma(lch);
 682        }
 683}
 684
 685/**
 686 * @brief omap_dma_set_global_params : Set global priority settings for dma
 687 *
 688 * @param arb_rate
 689 * @param max_fifo_depth
 690 * @param tparams - Number of thereads to reserve : DMA_THREAD_RESERVE_NORM
 691 *                                                  DMA_THREAD_RESERVE_ONET
 692 *                                                  DMA_THREAD_RESERVE_TWOT
 693 *                                                  DMA_THREAD_RESERVE_THREET
 694 */
 695void
 696omap_dma_set_global_params(int arb_rate, int max_fifo_depth, int tparams)
 697{
 698        u32 reg;
 699
 700        if (!cpu_class_is_omap2()) {
 701                printk(KERN_ERR "FIXME: no %s on 15xx/16xx\n", __func__);
 702                return;
 703        }
 704
 705        if (arb_rate == 0)
 706                arb_rate = 1;
 707
 708        reg = (arb_rate & 0xff) << 16;
 709        reg |= (0xff & max_fifo_depth);
 710
 711        omap_writel(reg, OMAP_DMA4_GCR_REG);
 712}
 713EXPORT_SYMBOL(omap_dma_set_global_params);
 714
 715/**
 716 * @brief omap_dma_set_prio_lch : Set channel wise priority settings
 717 *
 718 * @param lch
 719 * @param read_prio - Read priority
 720 * @param write_prio - Write priority
 721 * Both of the above can be set with one of the following values :
 722 *      DMA_CH_PRIO_HIGH/DMA_CH_PRIO_LOW
 723 */
 724int
 725omap_dma_set_prio_lch(int lch, unsigned char read_prio,
 726                      unsigned char write_prio)
 727{
 728        u32 w;
 729
 730        if (unlikely((lch < 0 || lch >= OMAP_LOGICAL_DMA_CH_COUNT))) {
 731                printk(KERN_ERR "Invalid channel id\n");
 732                return -EINVAL;
 733        }
 734        w = OMAP_DMA_CCR_REG(lch);
 735        w &= ~((1 << 6) | (1 << 26));
 736        if (cpu_is_omap2430() || cpu_is_omap34xx())
 737                w |= ((read_prio & 0x1) << 6) | ((write_prio & 0x1) << 26);
 738        else
 739                w |= ((read_prio & 0x1) << 6);
 740
 741        OMAP_DMA_CCR_REG(lch) = w;
 742        return 0;
 743}
 744EXPORT_SYMBOL(omap_dma_set_prio_lch);
 745
 746/*
 747 * Clears any DMA state so the DMA engine is ready to restart with new buffers
 748 * through omap_start_dma(). Any buffers in flight are discarded.
 749 */
 750void omap_clear_dma(int lch)
 751{
 752        unsigned long flags;
 753
 754        local_irq_save(flags);
 755
 756        if (cpu_class_is_omap1()) {
 757                int status;
 758                OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
 759
 760                /* Clear pending interrupts */
 761                status = OMAP_DMA_CSR_REG(lch);
 762        }
 763
 764        if (cpu_class_is_omap2()) {
 765                int i;
 766                u32 lch_base = OMAP_DMA4_BASE + lch * 0x60 + 0x80;
 767                for (i = 0; i < 0x44; i += 4)
 768                        omap_writel(0, lch_base + i);
 769        }
 770
 771        local_irq_restore(flags);
 772}
 773
 774void omap_start_dma(int lch)
 775{
 776        if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
 777                int next_lch, cur_lch;
 778                char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
 779
 780                dma_chan_link_map[lch] = 1;
 781                /* Set the link register of the first channel */
 782                enable_lnk(lch);
 783
 784                memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
 785                cur_lch = dma_chan[lch].next_lch;
 786                do {
 787                        next_lch = dma_chan[cur_lch].next_lch;
 788
 789                        /* The loop case: we've been here already */
 790                        if (dma_chan_link_map[cur_lch])
 791                                break;
 792                        /* Mark the current channel */
 793                        dma_chan_link_map[cur_lch] = 1;
 794
 795                        enable_lnk(cur_lch);
 796                        omap_enable_channel_irq(cur_lch);
 797
 798                        cur_lch = next_lch;
 799                } while (next_lch != -1);
 800        } else if (cpu_class_is_omap2()) {
 801                /* Errata: Need to write lch even if not using chaining */
 802                OMAP_DMA_CLNK_CTRL_REG(lch) = lch;
 803        }
 804
 805        omap_enable_channel_irq(lch);
 806
 807        /* Errata: On ES2.0 BUFFERING disable must be set.
 808         * This will always fail on ES1.0 */
 809        if (cpu_is_omap24xx()) {
 810                OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
 811        }
 812
 813        OMAP_DMA_CCR_REG(lch) |= OMAP_DMA_CCR_EN;
 814
 815        dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
 816}
 817
 818void omap_stop_dma(int lch)
 819{
 820        if (!omap_dma_in_1510_mode() && dma_chan[lch].next_lch != -1) {
 821                int next_lch, cur_lch = lch;
 822                char dma_chan_link_map[OMAP_LOGICAL_DMA_CH_COUNT];
 823
 824                memset(dma_chan_link_map, 0, sizeof(dma_chan_link_map));
 825                do {
 826                        /* The loop case: we've been here already */
 827                        if (dma_chan_link_map[cur_lch])
 828                                break;
 829                        /* Mark the current channel */
 830                        dma_chan_link_map[cur_lch] = 1;
 831
 832                        disable_lnk(cur_lch);
 833
 834                        next_lch = dma_chan[cur_lch].next_lch;
 835                        cur_lch = next_lch;
 836                } while (next_lch != -1);
 837
 838                return;
 839        }
 840
 841        /* Disable all interrupts on the channel */
 842        if (cpu_class_is_omap1())
 843                OMAP_DMA_CICR_REG(lch) = 0;
 844
 845        OMAP_DMA_CCR_REG(lch) &= ~OMAP_DMA_CCR_EN;
 846        dma_chan[lch].flags &= ~OMAP_DMA_ACTIVE;
 847}
 848
 849/*
 850 * Allows changing the DMA callback function or data. This may be needed if
 851 * the driver shares a single DMA channel for multiple dma triggers.
 852 */
 853int omap_set_dma_callback(int lch,
 854                          void (* callback)(int lch, u16 ch_status, void *data),
 855                          void *data)
 856{
 857        unsigned long flags;
 858
 859        if (lch < 0)
 860                return -ENODEV;
 861
 862        spin_lock_irqsave(&dma_chan_lock, flags);
 863        if (dma_chan[lch].dev_id == -1) {
 864                printk(KERN_ERR "DMA callback for not set for free channel\n");
 865                spin_unlock_irqrestore(&dma_chan_lock, flags);
 866                return -EINVAL;
 867        }
 868        dma_chan[lch].callback = callback;
 869        dma_chan[lch].data = data;
 870        spin_unlock_irqrestore(&dma_chan_lock, flags);
 871
 872        return 0;
 873}
 874
 875/*
 876 * Returns current physical source address for the given DMA channel.
 877 * If the channel is running the caller must disable interrupts prior calling
 878 * this function and process the returned value before re-enabling interrupt to
 879 * prevent races with the interrupt handler. Note that in continuous mode there
 880 * is a chance for CSSA_L register overflow inbetween the two reads resulting
 881 * in incorrect return value.
 882 */
 883dma_addr_t omap_get_dma_src_pos(int lch)
 884{
 885        dma_addr_t offset = 0;
 886
 887        if (cpu_class_is_omap1())
 888                offset = (dma_addr_t) (OMAP1_DMA_CSSA_L_REG(lch) |
 889                                       (OMAP1_DMA_CSSA_U_REG(lch) << 16));
 890
 891        if (cpu_class_is_omap2())
 892                offset = OMAP_DMA_CSAC_REG(lch);
 893
 894        return offset;
 895}
 896
 897/*
 898 * Returns current physical destination address for the given DMA channel.
 899 * If the channel is running the caller must disable interrupts prior calling
 900 * this function and process the returned value before re-enabling interrupt to
 901 * prevent races with the interrupt handler. Note that in continuous mode there
 902 * is a chance for CDSA_L register overflow inbetween the two reads resulting
 903 * in incorrect return value.
 904 */
 905dma_addr_t omap_get_dma_dst_pos(int lch)
 906{
 907        dma_addr_t offset = 0;
 908
 909        if (cpu_class_is_omap1())
 910                offset = (dma_addr_t) (OMAP1_DMA_CDSA_L_REG(lch) |
 911                                       (OMAP1_DMA_CDSA_U_REG(lch) << 16));
 912
 913        if (cpu_class_is_omap2())
 914                offset = OMAP_DMA_CDAC_REG(lch);
 915
 916        return offset;
 917}
 918
 919/*
 920 * Returns current source transfer counting for the given DMA channel.
 921 * Can be used to monitor the progress of a transfer inside a block.
 922 * It must be called with disabled interrupts.
 923 */
 924int omap_get_dma_src_addr_counter(int lch)
 925{
 926        return (dma_addr_t) OMAP_DMA_CSAC_REG(lch);
 927}
 928
 929int omap_dma_running(void)
 930{
 931        int lch;
 932
 933        /* Check if LCD DMA is running */
 934        if (cpu_is_omap16xx())
 935                if (omap_readw(OMAP1610_DMA_LCD_CCR) & OMAP_DMA_CCR_EN)
 936                        return 1;
 937
 938        for (lch = 0; lch < dma_chan_count; lch++)
 939                if (OMAP_DMA_CCR_REG(lch) & OMAP_DMA_CCR_EN)
 940                        return 1;
 941
 942        return 0;
 943}
 944
 945/*
 946 * lch_queue DMA will start right after lch_head one is finished.
 947 * For this DMA link to start, you still need to start (see omap_start_dma)
 948 * the first one. That will fire up the entire queue.
 949 */
 950void omap_dma_link_lch (int lch_head, int lch_queue)
 951{
 952        if (omap_dma_in_1510_mode()) {
 953                printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
 954                BUG();
 955                return;
 956        }
 957
 958        if ((dma_chan[lch_head].dev_id == -1) ||
 959            (dma_chan[lch_queue].dev_id == -1)) {
 960                printk(KERN_ERR "omap_dma: trying to link "
 961                       "non requested channels\n");
 962                dump_stack();
 963        }
 964
 965        dma_chan[lch_head].next_lch = lch_queue;
 966}
 967
 968/*
 969 * Once the DMA queue is stopped, we can destroy it.
 970 */
 971void omap_dma_unlink_lch (int lch_head, int lch_queue)
 972{
 973        if (omap_dma_in_1510_mode()) {
 974                printk(KERN_ERR "DMA linking is not supported in 1510 mode\n");
 975                BUG();
 976                return;
 977        }
 978
 979        if (dma_chan[lch_head].next_lch != lch_queue ||
 980            dma_chan[lch_head].next_lch == -1) {
 981                printk(KERN_ERR "omap_dma: trying to unlink "
 982                       "non linked channels\n");
 983                dump_stack();
 984        }
 985
 986
 987        if ((dma_chan[lch_head].flags & OMAP_DMA_ACTIVE) ||
 988            (dma_chan[lch_head].flags & OMAP_DMA_ACTIVE)) {
 989                printk(KERN_ERR "omap_dma: You need to stop the DMA channels "
 990                       "before unlinking\n");
 991                dump_stack();
 992        }
 993
 994        dma_chan[lch_head].next_lch = -1;
 995}
 996
 997#ifndef CONFIG_ARCH_OMAP1
 998/* Create chain of DMA channesls */
 999static void create_dma_lch_chain(int lch_head, int lch_queue)
1000{
1001        u32 w;
1002
1003        /* Check if this is the first link in chain */
1004        if (dma_chan[lch_head].next_linked_ch == -1) {
1005                dma_chan[lch_head].next_linked_ch = lch_queue;
1006                dma_chan[lch_head].prev_linked_ch = lch_queue;
1007                dma_chan[lch_queue].next_linked_ch = lch_head;
1008                dma_chan[lch_queue].prev_linked_ch = lch_head;
1009        }
1010
1011        /* a link exists, link the new channel in circular chain */
1012        else {
1013                dma_chan[lch_queue].next_linked_ch =
1014                                        dma_chan[lch_head].next_linked_ch;
1015                dma_chan[lch_queue].prev_linked_ch = lch_head;
1016                dma_chan[lch_head].next_linked_ch = lch_queue;
1017                dma_chan[dma_chan[lch_queue].next_linked_ch].prev_linked_ch =
1018                                        lch_queue;
1019        }
1020
1021        w = OMAP_DMA_CLNK_CTRL_REG(lch_head);
1022        w &= ~(0x1f);
1023        w |= lch_queue;
1024        OMAP_DMA_CLNK_CTRL_REG(lch_head) = w;
1025
1026        w = OMAP_DMA_CLNK_CTRL_REG(lch_queue);
1027        w &= ~(0x1f);
1028        w |= (dma_chan[lch_queue].next_linked_ch);
1029        OMAP_DMA_CLNK_CTRL_REG(lch_queue) = w;
1030}
1031
1032/**
1033 * @brief omap_request_dma_chain : Request a chain of DMA channels
1034 *
1035 * @param dev_id - Device id using the dma channel
1036 * @param dev_name - Device name
1037 * @param callback - Call back function
1038 * @chain_id -
1039 * @no_of_chans - Number of channels requested
1040 * @chain_mode - Dynamic or static chaining : OMAP_DMA_STATIC_CHAIN
1041 *                                            OMAP_DMA_DYNAMIC_CHAIN
1042 * @params - Channel parameters
1043 *
1044 * @return - Succes : 0
1045 *           Failure: -EINVAL/-ENOMEM
1046 */
1047int omap_request_dma_chain(int dev_id, const char *dev_name,
1048                           void (*callback) (int chain_id, u16 ch_status,
1049                                             void *data),
1050                           int *chain_id, int no_of_chans, int chain_mode,
1051                           struct omap_dma_channel_params params)
1052{
1053        int *channels;
1054        int i, err;
1055
1056        /* Is the chain mode valid ? */
1057        if (chain_mode != OMAP_DMA_STATIC_CHAIN
1058                        && chain_mode != OMAP_DMA_DYNAMIC_CHAIN) {
1059                printk(KERN_ERR "Invalid chain mode requested\n");
1060                return -EINVAL;
1061        }
1062
1063        if (unlikely((no_of_chans < 1
1064                        || no_of_chans > OMAP_LOGICAL_DMA_CH_COUNT))) {
1065                printk(KERN_ERR "Invalid Number of channels requested\n");
1066                return -EINVAL;
1067        }
1068
1069        /* Allocate a queue to maintain the status of the channels
1070         * in the chain */
1071        channels = kmalloc(sizeof(*channels) * no_of_chans, GFP_KERNEL);
1072        if (channels == NULL) {
1073                printk(KERN_ERR "omap_dma: No memory for channel queue\n");
1074                return -ENOMEM;
1075        }
1076
1077        /* request and reserve DMA channels for the chain */
1078        for (i = 0; i < no_of_chans; i++) {
1079                err = omap_request_dma(dev_id, dev_name,
1080                                        callback, 0, &channels[i]);
1081                if (err < 0) {
1082                        int j;
1083                        for (j = 0; j < i; j++)
1084                                omap_free_dma(channels[j]);
1085                        kfree(channels);
1086                        printk(KERN_ERR "omap_dma: Request failed %d\n", err);
1087                        return err;
1088                }
1089                dma_chan[channels[i]].prev_linked_ch = -1;
1090                dma_chan[channels[i]].state = DMA_CH_NOTSTARTED;
1091
1092                /*
1093                 * Allowing client drivers to set common parameters now,
1094                 * so that later only relevant (src_start, dest_start
1095                 * and element count) can be set
1096                 */
1097                omap_set_dma_params(channels[i], &params);
1098        }
1099
1100        *chain_id = channels[0];
1101        dma_linked_lch[*chain_id].linked_dmach_q = channels;
1102        dma_linked_lch[*chain_id].chain_mode = chain_mode;
1103        dma_linked_lch[*chain_id].chain_state = DMA_CHAIN_NOTSTARTED;
1104        dma_linked_lch[*chain_id].no_of_lchs_linked = no_of_chans;
1105
1106        for (i = 0; i < no_of_chans; i++)
1107                dma_chan[channels[i]].chain_id = *chain_id;
1108
1109        /* Reset the Queue pointers */
1110        OMAP_DMA_CHAIN_QINIT(*chain_id);
1111
1112        /* Set up the chain */
1113        if (no_of_chans == 1)
1114                create_dma_lch_chain(channels[0], channels[0]);
1115        else {
1116                for (i = 0; i < (no_of_chans - 1); i++)
1117                        create_dma_lch_chain(channels[i], channels[i + 1]);
1118        }
1119        return 0;
1120}
1121EXPORT_SYMBOL(omap_request_dma_chain);
1122
1123/**
1124 * @brief omap_modify_dma_chain_param : Modify the chain's params - Modify the
1125 * params after setting it. Dont do this while dma is running!!
1126 *
1127 * @param chain_id - Chained logical channel id.
1128 * @param params
1129 *
1130 * @return - Success : 0
1131 *           Failure : -EINVAL
1132 */
1133int omap_modify_dma_chain_params(int chain_id,
1134                                struct omap_dma_channel_params params)
1135{
1136        int *channels;
1137        u32 i;
1138
1139        /* Check for input params */
1140        if (unlikely((chain_id < 0
1141                        || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1142                printk(KERN_ERR "Invalid chain id\n");
1143                return -EINVAL;
1144        }
1145
1146        /* Check if the chain exists */
1147        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1148                printk(KERN_ERR "Chain doesn't exists\n");
1149                return -EINVAL;
1150        }
1151        channels = dma_linked_lch[chain_id].linked_dmach_q;
1152
1153        for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
1154                /*
1155                 * Allowing client drivers to set common parameters now,
1156                 * so that later only relevant (src_start, dest_start
1157                 * and element count) can be set
1158                 */
1159                omap_set_dma_params(channels[i], &params);
1160        }
1161        return 0;
1162}
1163EXPORT_SYMBOL(omap_modify_dma_chain_params);
1164
1165/**
1166 * @brief omap_free_dma_chain - Free all the logical channels in a chain.
1167 *
1168 * @param chain_id
1169 *
1170 * @return - Success : 0
1171 *           Failure : -EINVAL
1172 */
1173int omap_free_dma_chain(int chain_id)
1174{
1175        int *channels;
1176        u32 i;
1177
1178        /* Check for input params */
1179        if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1180                printk(KERN_ERR "Invalid chain id\n");
1181                return -EINVAL;
1182        }
1183
1184        /* Check if the chain exists */
1185        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1186                printk(KERN_ERR "Chain doesn't exists\n");
1187                return -EINVAL;
1188        }
1189
1190        channels = dma_linked_lch[chain_id].linked_dmach_q;
1191        for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
1192                dma_chan[channels[i]].next_linked_ch = -1;
1193                dma_chan[channels[i]].prev_linked_ch = -1;
1194                dma_chan[channels[i]].chain_id = -1;
1195                dma_chan[channels[i]].state = DMA_CH_NOTSTARTED;
1196                omap_free_dma(channels[i]);
1197        }
1198
1199        kfree(channels);
1200
1201        dma_linked_lch[chain_id].linked_dmach_q = NULL;
1202        dma_linked_lch[chain_id].chain_mode = -1;
1203        dma_linked_lch[chain_id].chain_state = -1;
1204        return (0);
1205}
1206EXPORT_SYMBOL(omap_free_dma_chain);
1207
1208/**
1209 * @brief omap_dma_chain_status - Check if the chain is in
1210 * active / inactive state.
1211 * @param chain_id
1212 *
1213 * @return - Success : OMAP_DMA_CHAIN_ACTIVE/OMAP_DMA_CHAIN_INACTIVE
1214 *           Failure : -EINVAL
1215 */
1216int omap_dma_chain_status(int chain_id)
1217{
1218        /* Check for input params */
1219        if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1220                printk(KERN_ERR "Invalid chain id\n");
1221                return -EINVAL;
1222        }
1223
1224        /* Check if the chain exists */
1225        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1226                printk(KERN_ERR "Chain doesn't exists\n");
1227                return -EINVAL;
1228        }
1229        pr_debug("CHAINID=%d, qcnt=%d\n", chain_id,
1230                        dma_linked_lch[chain_id].q_count);
1231
1232        if (OMAP_DMA_CHAIN_QEMPTY(chain_id))
1233                return OMAP_DMA_CHAIN_INACTIVE;
1234        return OMAP_DMA_CHAIN_ACTIVE;
1235}
1236EXPORT_SYMBOL(omap_dma_chain_status);
1237
1238/**
1239 * @brief omap_dma_chain_a_transfer - Get a free channel from a chain,
1240 * set the params and start the transfer.
1241 *
1242 * @param chain_id
1243 * @param src_start - buffer start address
1244 * @param dest_start - Dest address
1245 * @param elem_count
1246 * @param frame_count
1247 * @param callbk_data - channel callback parameter data.
1248 *
1249 * @return  - Success : 0
1250 *            Failure: -EINVAL/-EBUSY
1251 */
1252int omap_dma_chain_a_transfer(int chain_id, int src_start, int dest_start,
1253                        int elem_count, int frame_count, void *callbk_data)
1254{
1255        int *channels;
1256        u32 w, lch;
1257        int start_dma = 0;
1258
1259        /* if buffer size is less than 1 then there is
1260         * no use of starting the chain */
1261        if (elem_count < 1) {
1262                printk(KERN_ERR "Invalid buffer size\n");
1263                return -EINVAL;
1264        }
1265
1266        /* Check for input params */
1267        if (unlikely((chain_id < 0
1268                        || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1269                printk(KERN_ERR "Invalid chain id\n");
1270                return -EINVAL;
1271        }
1272
1273        /* Check if the chain exists */
1274        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1275                printk(KERN_ERR "Chain doesn't exist\n");
1276                return -EINVAL;
1277        }
1278
1279        /* Check if all the channels in chain are in use */
1280        if (OMAP_DMA_CHAIN_QFULL(chain_id))
1281                return -EBUSY;
1282
1283        /* Frame count may be negative in case of indexed transfers */
1284        channels = dma_linked_lch[chain_id].linked_dmach_q;
1285
1286        /* Get a free channel */
1287        lch = channels[dma_linked_lch[chain_id].q_tail];
1288
1289        /* Store the callback data */
1290        dma_chan[lch].data = callbk_data;
1291
1292        /* Increment the q_tail */
1293        OMAP_DMA_CHAIN_INCQTAIL(chain_id);
1294
1295        /* Set the params to the free channel */
1296        if (src_start != 0)
1297                OMAP2_DMA_CSSA_REG(lch) = src_start;
1298        if (dest_start != 0)
1299                OMAP2_DMA_CDSA_REG(lch) = dest_start;
1300
1301        /* Write the buffer size */
1302        OMAP_DMA_CEN_REG(lch) = elem_count;
1303        OMAP_DMA_CFN_REG(lch) = frame_count;
1304
1305        /* If the chain is dynamically linked,
1306         * then we may have to start the chain if its not active */
1307        if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_DYNAMIC_CHAIN) {
1308
1309                /* In Dynamic chain, if the chain is not started,
1310                 * queue the channel */
1311                if (dma_linked_lch[chain_id].chain_state ==
1312                                                DMA_CHAIN_NOTSTARTED) {
1313                        /* Enable the link in previous channel */
1314                        if (dma_chan[dma_chan[lch].prev_linked_ch].state ==
1315                                                                DMA_CH_QUEUED)
1316                                enable_lnk(dma_chan[lch].prev_linked_ch);
1317                        dma_chan[lch].state = DMA_CH_QUEUED;
1318                }
1319
1320                /* Chain is already started, make sure its active,
1321                 * if not then start the chain */
1322                else {
1323                        start_dma = 1;
1324
1325                        if (dma_chan[dma_chan[lch].prev_linked_ch].state ==
1326                                                        DMA_CH_STARTED) {
1327                                enable_lnk(dma_chan[lch].prev_linked_ch);
1328                                dma_chan[lch].state = DMA_CH_QUEUED;
1329                                start_dma = 0;
1330                                if (0 == ((1 << 7) & (OMAP_DMA_CCR_REG
1331                                        (dma_chan[lch].prev_linked_ch)))) {
1332                                        disable_lnk(dma_chan[lch].
1333                                                    prev_linked_ch);
1334                                        pr_debug("\n prev ch is stopped\n");
1335                                        start_dma = 1;
1336                                }
1337                        }
1338
1339                        else if (dma_chan[dma_chan[lch].prev_linked_ch].state
1340                                                        == DMA_CH_QUEUED) {
1341                                enable_lnk(dma_chan[lch].prev_linked_ch);
1342                                dma_chan[lch].state = DMA_CH_QUEUED;
1343                                start_dma = 0;
1344                        }
1345                        omap_enable_channel_irq(lch);
1346
1347                        w = OMAP_DMA_CCR_REG(lch);
1348
1349                        if ((0 == (w & (1 << 24))))
1350                                w &= ~(1 << 25);
1351                        else
1352                                w |= (1 << 25);
1353                        if (start_dma == 1) {
1354                                if (0 == (w & (1 << 7))) {
1355                                        w |= (1 << 7);
1356                                        dma_chan[lch].state = DMA_CH_STARTED;
1357                                        pr_debug("starting %d\n", lch);
1358                                        OMAP_DMA_CCR_REG(lch) = w;
1359                                } else
1360                                        start_dma = 0;
1361                        } else {
1362                                if (0 == (w & (1 << 7)))
1363                                        OMAP_DMA_CCR_REG(lch) = w;
1364                        }
1365                        dma_chan[lch].flags |= OMAP_DMA_ACTIVE;
1366                }
1367        }
1368        return 0;
1369}
1370EXPORT_SYMBOL(omap_dma_chain_a_transfer);
1371
1372/**
1373 * @brief omap_start_dma_chain_transfers - Start the chain
1374 *
1375 * @param chain_id
1376 *
1377 * @return - Success : 0
1378 *           Failure : -EINVAL/-EBUSY
1379 */
1380int omap_start_dma_chain_transfers(int chain_id)
1381{
1382        int *channels;
1383        u32 w, i;
1384
1385        if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1386                printk(KERN_ERR "Invalid chain id\n");
1387                return -EINVAL;
1388        }
1389
1390        channels = dma_linked_lch[chain_id].linked_dmach_q;
1391
1392        if (dma_linked_lch[channels[0]].chain_state == DMA_CHAIN_STARTED) {
1393                printk(KERN_ERR "Chain is already started\n");
1394                return -EBUSY;
1395        }
1396
1397        if (dma_linked_lch[chain_id].chain_mode == OMAP_DMA_STATIC_CHAIN) {
1398                for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked;
1399                                                                        i++) {
1400                        enable_lnk(channels[i]);
1401                        omap_enable_channel_irq(channels[i]);
1402                }
1403        } else {
1404                omap_enable_channel_irq(channels[0]);
1405        }
1406
1407        w = OMAP_DMA_CCR_REG(channels[0]);
1408        w |= (1 << 7);
1409        dma_linked_lch[chain_id].chain_state = DMA_CHAIN_STARTED;
1410        dma_chan[channels[0]].state = DMA_CH_STARTED;
1411
1412        if ((0 == (w & (1 << 24))))
1413                w &= ~(1 << 25);
1414        else
1415                w |= (1 << 25);
1416        OMAP_DMA_CCR_REG(channels[0]) = w;
1417
1418        dma_chan[channels[0]].flags |= OMAP_DMA_ACTIVE;
1419        return 0;
1420}
1421EXPORT_SYMBOL(omap_start_dma_chain_transfers);
1422
1423/**
1424 * @brief omap_stop_dma_chain_transfers - Stop the dma transfer of a chain.
1425 *
1426 * @param chain_id
1427 *
1428 * @return - Success : 0
1429 *           Failure : EINVAL
1430 */
1431int omap_stop_dma_chain_transfers(int chain_id)
1432{
1433        int *channels;
1434        u32 w, i;
1435        u32 sys_cf;
1436
1437        /* Check for input params */
1438        if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1439                printk(KERN_ERR "Invalid chain id\n");
1440                return -EINVAL;
1441        }
1442
1443        /* Check if the chain exists */
1444        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1445                printk(KERN_ERR "Chain doesn't exists\n");
1446                return -EINVAL;
1447        }
1448        channels = dma_linked_lch[chain_id].linked_dmach_q;
1449
1450        /* DMA Errata:
1451         * Special programming model needed to disable DMA before end of block
1452         */
1453        sys_cf = omap_readl(OMAP_DMA4_OCP_SYSCONFIG);
1454        w = sys_cf;
1455        /* Middle mode reg set no Standby */
1456        w &= ~((1 << 12)|(1 << 13));
1457        omap_writel(w, OMAP_DMA4_OCP_SYSCONFIG);
1458
1459        for (i = 0; i < dma_linked_lch[chain_id].no_of_lchs_linked; i++) {
1460
1461                /* Stop the Channel transmission */
1462                w = OMAP_DMA_CCR_REG(channels[i]);
1463                w &= ~(1 << 7);
1464                OMAP_DMA_CCR_REG(channels[i]) = w;
1465
1466                /* Disable the link in all the channels */
1467                disable_lnk(channels[i]);
1468                dma_chan[channels[i]].state = DMA_CH_NOTSTARTED;
1469
1470        }
1471        dma_linked_lch[chain_id].chain_state = DMA_CHAIN_NOTSTARTED;
1472
1473        /* Reset the Queue pointers */
1474        OMAP_DMA_CHAIN_QINIT(chain_id);
1475
1476        /* Errata - put in the old value */
1477        omap_writel(sys_cf, OMAP_DMA4_OCP_SYSCONFIG);
1478        return 0;
1479}
1480EXPORT_SYMBOL(omap_stop_dma_chain_transfers);
1481
1482/* Get the index of the ongoing DMA in chain */
1483/**
1484 * @brief omap_get_dma_chain_index - Get the element and frame index
1485 * of the ongoing DMA in chain
1486 *
1487 * @param chain_id
1488 * @param ei - Element index
1489 * @param fi - Frame index
1490 *
1491 * @return - Success : 0
1492 *           Failure : -EINVAL
1493 */
1494int omap_get_dma_chain_index(int chain_id, int *ei, int *fi)
1495{
1496        int lch;
1497        int *channels;
1498
1499        /* Check for input params */
1500        if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1501                printk(KERN_ERR "Invalid chain id\n");
1502                return -EINVAL;
1503        }
1504
1505        /* Check if the chain exists */
1506        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1507                printk(KERN_ERR "Chain doesn't exists\n");
1508                return -EINVAL;
1509        }
1510        if ((!ei) || (!fi))
1511                return -EINVAL;
1512
1513        channels = dma_linked_lch[chain_id].linked_dmach_q;
1514
1515        /* Get the current channel */
1516        lch = channels[dma_linked_lch[chain_id].q_head];
1517
1518        *ei = OMAP2_DMA_CCEN_REG(lch);
1519        *fi = OMAP2_DMA_CCFN_REG(lch);
1520
1521        return 0;
1522}
1523EXPORT_SYMBOL(omap_get_dma_chain_index);
1524
1525/**
1526 * @brief omap_get_dma_chain_dst_pos - Get the destination position of the
1527 * ongoing DMA in chain
1528 *
1529 * @param chain_id
1530 *
1531 * @return - Success : Destination position
1532 *           Failure : -EINVAL
1533 */
1534int omap_get_dma_chain_dst_pos(int chain_id)
1535{
1536        int lch;
1537        int *channels;
1538
1539        /* Check for input params */
1540        if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1541                printk(KERN_ERR "Invalid chain id\n");
1542                return -EINVAL;
1543        }
1544
1545        /* Check if the chain exists */
1546        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1547                printk(KERN_ERR "Chain doesn't exists\n");
1548                return -EINVAL;
1549        }
1550
1551        channels = dma_linked_lch[chain_id].linked_dmach_q;
1552
1553        /* Get the current channel */
1554        lch = channels[dma_linked_lch[chain_id].q_head];
1555
1556        return (OMAP_DMA_CDAC_REG(lch));
1557}
1558EXPORT_SYMBOL(omap_get_dma_chain_dst_pos);
1559
1560/**
1561 * @brief omap_get_dma_chain_src_pos - Get the source position
1562 * of the ongoing DMA in chain
1563 * @param chain_id
1564 *
1565 * @return - Success : Destination position
1566 *           Failure : -EINVAL
1567 */
1568int omap_get_dma_chain_src_pos(int chain_id)
1569{
1570        int lch;
1571        int *channels;
1572
1573        /* Check for input params */
1574        if (unlikely((chain_id < 0 || chain_id >= OMAP_LOGICAL_DMA_CH_COUNT))) {
1575                printk(KERN_ERR "Invalid chain id\n");
1576                return -EINVAL;
1577        }
1578
1579        /* Check if the chain exists */
1580        if (dma_linked_lch[chain_id].linked_dmach_q == NULL) {
1581                printk(KERN_ERR "Chain doesn't exists\n");
1582                return -EINVAL;
1583        }
1584
1585        channels = dma_linked_lch[chain_id].linked_dmach_q;
1586
1587        /* Get the current channel */
1588        lch = channels[dma_linked_lch[chain_id].q_head];
1589
1590        return (OMAP_DMA_CSAC_REG(lch));
1591}
1592EXPORT_SYMBOL(omap_get_dma_chain_src_pos);
1593#endif
1594
1595/*----------------------------------------------------------------------------*/
1596
1597#ifdef CONFIG_ARCH_OMAP1
1598
1599static int omap1_dma_handle_ch(int ch)
1600{
1601        u16 csr;
1602
1603        if (enable_1510_mode && ch >= 6) {
1604                csr = dma_chan[ch].saved_csr;
1605                dma_chan[ch].saved_csr = 0;
1606        } else
1607                csr = OMAP_DMA_CSR_REG(ch);
1608        if (enable_1510_mode && ch <= 2 && (csr >> 7) != 0) {
1609                dma_chan[ch + 6].saved_csr = csr >> 7;
1610                csr &= 0x7f;
1611        }
1612        if ((csr & 0x3f) == 0)
1613                return 0;
1614        if (unlikely(dma_chan[ch].dev_id == -1)) {
1615                printk(KERN_WARNING "Spurious interrupt from DMA channel "
1616                       "%d (CSR %04x)\n", ch, csr);
1617                return 0;
1618        }
1619        if (unlikely(csr & OMAP1_DMA_TOUT_IRQ))
1620                printk(KERN_WARNING "DMA timeout with device %d\n",
1621                       dma_chan[ch].dev_id);
1622        if (unlikely(csr & OMAP_DMA_DROP_IRQ))
1623                printk(KERN_WARNING "DMA synchronization event drop occurred "
1624                       "with device %d\n", dma_chan[ch].dev_id);
1625        if (likely(csr & OMAP_DMA_BLOCK_IRQ))
1626                dma_chan[ch].flags &= ~OMAP_DMA_ACTIVE;
1627        if (likely(dma_chan[ch].callback != NULL))
1628                dma_chan[ch].callback(ch, csr, dma_chan[ch].data);
1629        return 1;
1630}
1631
1632static irqreturn_t omap1_dma_irq_handler(int irq, void *dev_id)
1633{
1634        int ch = ((int) dev_id) - 1;
1635        int handled = 0;
1636
1637        for (;;) {
1638                int handled_now = 0;
1639
1640                handled_now += omap1_dma_handle_ch(ch);
1641                if (enable_1510_mode && dma_chan[ch + 6].saved_csr)
1642                        handled_now += omap1_dma_handle_ch(ch + 6);
1643                if (!handled_now)
1644                        break;
1645                handled += handled_now;
1646        }
1647
1648        return handled ? IRQ_HANDLED : IRQ_NONE;
1649}
1650
1651#else
1652#define omap1_dma_irq_handler   NULL
1653#endif
1654
1655#if defined(CONFIG_ARCH_OMAP2) || defined(CONFIG_ARCH_OMAP3)
1656
1657static int omap2_dma_handle_ch(int ch)
1658{
1659        u32 status = OMAP_DMA_CSR_REG(ch);
1660
1661        if (!status) {
1662                if (printk_ratelimit())
1663                        printk(KERN_WARNING "Spurious DMA IRQ for lch %d\n", ch);
1664                omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0);
1665                return 0;
1666        }
1667        if (unlikely(dma_chan[ch].dev_id == -1)) {
1668                if (printk_ratelimit())
1669                        printk(KERN_WARNING "IRQ %04x for non-allocated DMA"
1670                                        "channel %d\n", status, ch);
1671                return 0;
1672        }
1673        if (unlikely(status & OMAP_DMA_DROP_IRQ))
1674                printk(KERN_INFO
1675                       "DMA synchronization event drop occurred with device "
1676                       "%d\n", dma_chan[ch].dev_id);
1677        if (unlikely(status & OMAP2_DMA_TRANS_ERR_IRQ))
1678                printk(KERN_INFO "DMA transaction error with device %d\n",
1679                       dma_chan[ch].dev_id);
1680        if (unlikely(status & OMAP2_DMA_SECURE_ERR_IRQ))
1681                printk(KERN_INFO "DMA secure error with device %d\n",
1682                       dma_chan[ch].dev_id);
1683        if (unlikely(status & OMAP2_DMA_MISALIGNED_ERR_IRQ))
1684                printk(KERN_INFO "DMA misaligned error with device %d\n",
1685                       dma_chan[ch].dev_id);
1686
1687        OMAP_DMA_CSR_REG(ch) = OMAP2_DMA_CSR_CLEAR_MASK;
1688        omap_writel(1 << ch, OMAP_DMA4_IRQSTATUS_L0);
1689
1690        /* If the ch is not chained then chain_id will be -1 */
1691        if (dma_chan[ch].chain_id != -1) {
1692                int chain_id = dma_chan[ch].chain_id;
1693                dma_chan[ch].state = DMA_CH_NOTSTARTED;
1694                if (OMAP_DMA_CLNK_CTRL_REG(ch) & (1 << 15))
1695                        dma_chan[dma_chan[ch].next_linked_ch].state =
1696                                                        DMA_CH_STARTED;
1697                if (dma_linked_lch[chain_id].chain_mode ==
1698                                                OMAP_DMA_DYNAMIC_CHAIN)
1699                        disable_lnk(ch);
1700
1701                if (!OMAP_DMA_CHAIN_QEMPTY(chain_id))
1702                        OMAP_DMA_CHAIN_INCQHEAD(chain_id);
1703
1704                status = OMAP_DMA_CSR_REG(ch);
1705        }
1706
1707        if (likely(dma_chan[ch].callback != NULL))
1708                dma_chan[ch].callback(ch, status, dma_chan[ch].data);
1709
1710        OMAP_DMA_CSR_REG(ch) = status;
1711
1712        return 0;
1713}
1714
1715/* STATUS register count is from 1-32 while our is 0-31 */
1716static irqreturn_t omap2_dma_irq_handler(int irq, void *dev_id)
1717{
1718        u32 val;
1719        int i;
1720
1721        val = omap_readl(OMAP_DMA4_IRQSTATUS_L0);
1722        if (val == 0) {
1723                if (printk_ratelimit())
1724                        printk(KERN_WARNING "Spurious DMA IRQ\n");
1725                return IRQ_HANDLED;
1726        }
1727        for (i = 0; i < OMAP_LOGICAL_DMA_CH_COUNT && val != 0; i++) {
1728                if (val & 1)
1729                        omap2_dma_handle_ch(i);
1730                val >>= 1;
1731        }
1732
1733        return IRQ_HANDLED;
1734}
1735
1736static struct irqaction omap24xx_dma_irq = {
1737        .name = "DMA",
1738        .handler = omap2_dma_irq_handler,
1739        .flags = IRQF_DISABLED
1740};
1741
1742#else
1743static struct irqaction omap24xx_dma_irq;
1744#endif
1745
1746/*----------------------------------------------------------------------------*/
1747
1748static struct lcd_dma_info {
1749        spinlock_t lock;
1750        int reserved;
1751        void (* callback)(u16 status, void *data);
1752        void *cb_data;
1753
1754        int active;
1755        unsigned long addr, size;
1756        int rotate, data_type, xres, yres;
1757        int vxres;
1758        int mirror;
1759        int xscale, yscale;
1760        int ext_ctrl;
1761        int src_port;
1762        int single_transfer;
1763} lcd_dma;
1764
1765void omap_set_lcd_dma_b1(unsigned long addr, u16 fb_xres, u16 fb_yres,
1766                         int data_type)
1767{
1768        lcd_dma.addr = addr;
1769        lcd_dma.data_type = data_type;
1770        lcd_dma.xres = fb_xres;
1771        lcd_dma.yres = fb_yres;
1772}
1773
1774void omap_set_lcd_dma_src_port(int port)
1775{
1776        lcd_dma.src_port = port;
1777}
1778
1779void omap_set_lcd_dma_ext_controller(int external)
1780{
1781        lcd_dma.ext_ctrl = external;
1782}
1783
1784void omap_set_lcd_dma_single_transfer(int single)
1785{
1786        lcd_dma.single_transfer = single;
1787}
1788
1789
1790void omap_set_lcd_dma_b1_rotation(int rotate)
1791{
1792        if (omap_dma_in_1510_mode()) {
1793                printk(KERN_ERR "DMA rotation is not supported in 1510 mode\n");
1794                BUG();
1795                return;
1796        }
1797        lcd_dma.rotate = rotate;
1798}
1799
1800void omap_set_lcd_dma_b1_mirror(int mirror)
1801{
1802        if (omap_dma_in_1510_mode()) {
1803                printk(KERN_ERR "DMA mirror is not supported in 1510 mode\n");
1804                BUG();
1805        }
1806        lcd_dma.mirror = mirror;
1807}
1808
1809void omap_set_lcd_dma_b1_vxres(unsigned long vxres)
1810{
1811        if (omap_dma_in_1510_mode()) {
1812                printk(KERN_ERR "DMA virtual resulotion is not supported "
1813                                "in 1510 mode\n");
1814                BUG();
1815        }
1816        lcd_dma.vxres = vxres;
1817}
1818
1819void omap_set_lcd_dma_b1_scale(unsigned int xscale, unsigned int yscale)
1820{
1821        if (omap_dma_in_1510_mode()) {
1822                printk(KERN_ERR "DMA scale is not supported in 1510 mode\n");
1823                BUG();
1824        }
1825        lcd_dma.xscale = xscale;
1826        lcd_dma.yscale = yscale;
1827}
1828
1829static void set_b1_regs(void)
1830{
1831        unsigned long top, bottom;
1832        int es;
1833        u16 w;
1834        unsigned long en, fn;
1835        long ei, fi;
1836        unsigned long vxres;
1837        unsigned int xscale, yscale;
1838
1839        switch (lcd_dma.data_type) {
1840        case OMAP_DMA_DATA_TYPE_S8:
1841                es = 1;
1842                break;
1843        case OMAP_DMA_DATA_TYPE_S16:
1844                es = 2;
1845                break;
1846        case OMAP_DMA_DATA_TYPE_S32:
1847                es = 4;
1848                break;
1849        default:
1850                BUG();
1851                return;
1852        }
1853
1854        vxres = lcd_dma.vxres ? lcd_dma.vxres : lcd_dma.xres;
1855        xscale = lcd_dma.xscale ? lcd_dma.xscale : 1;
1856        yscale = lcd_dma.yscale ? lcd_dma.yscale : 1;
1857        BUG_ON(vxres < lcd_dma.xres);
1858#define PIXADDR(x,y) (lcd_dma.addr + ((y) * vxres * yscale + (x) * xscale) * es)
1859#define PIXSTEP(sx, sy, dx, dy) (PIXADDR(dx, dy) - PIXADDR(sx, sy) - es + 1)
1860        switch (lcd_dma.rotate) {
1861        case 0:
1862                if (!lcd_dma.mirror) {
1863                        top = PIXADDR(0, 0);
1864                        bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
1865                        /* 1510 DMA requires the bottom address to be 2 more
1866                         * than the actual last memory access location. */
1867                        if (omap_dma_in_1510_mode() &&
1868                            lcd_dma.data_type == OMAP_DMA_DATA_TYPE_S32)
1869                                bottom += 2;
1870                        ei = PIXSTEP(0, 0, 1, 0);
1871                        fi = PIXSTEP(lcd_dma.xres - 1, 0, 0, 1);
1872                } else {
1873                        top = PIXADDR(lcd_dma.xres - 1, 0);
1874                        bottom = PIXADDR(0, lcd_dma.yres - 1);
1875                        ei = PIXSTEP(1, 0, 0, 0);
1876                        fi = PIXSTEP(0, 0, lcd_dma.xres - 1, 1);
1877                }
1878                en = lcd_dma.xres;
1879                fn = lcd_dma.yres;
1880                break;
1881        case 90:
1882                if (!lcd_dma.mirror) {
1883                        top = PIXADDR(0, lcd_dma.yres - 1);
1884                        bottom = PIXADDR(lcd_dma.xres - 1, 0);
1885                        ei = PIXSTEP(0, 1, 0, 0);
1886                        fi = PIXSTEP(0, 0, 1, lcd_dma.yres - 1);
1887                } else {
1888                        top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
1889                        bottom = PIXADDR(0, 0);
1890                        ei = PIXSTEP(0, 1, 0, 0);
1891                        fi = PIXSTEP(1, 0, 0, lcd_dma.yres - 1);
1892                }
1893                en = lcd_dma.yres;
1894                fn = lcd_dma.xres;
1895                break;
1896        case 180:
1897                if (!lcd_dma.mirror) {
1898                        top = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
1899                        bottom = PIXADDR(0, 0);
1900                        ei = PIXSTEP(1, 0, 0, 0);
1901                        fi = PIXSTEP(0, 1, lcd_dma.xres - 1, 0);
1902                } else {
1903                        top = PIXADDR(0, lcd_dma.yres - 1);
1904                        bottom = PIXADDR(lcd_dma.xres - 1, 0);
1905                        ei = PIXSTEP(0, 0, 1, 0);
1906                        fi = PIXSTEP(lcd_dma.xres - 1, 1, 0, 0);
1907                }
1908                en = lcd_dma.xres;
1909                fn = lcd_dma.yres;
1910                break;
1911        case 270:
1912                if (!lcd_dma.mirror) {
1913                        top = PIXADDR(lcd_dma.xres - 1, 0);
1914                        bottom = PIXADDR(0, lcd_dma.yres - 1);
1915                        ei = PIXSTEP(0, 0, 0, 1);
1916                        fi = PIXSTEP(1, lcd_dma.yres - 1, 0, 0);
1917                } else {
1918                        top = PIXADDR(0, 0);
1919                        bottom = PIXADDR(lcd_dma.xres - 1, lcd_dma.yres - 1);
1920                        ei = PIXSTEP(0, 0, 0, 1);
1921                        fi = PIXSTEP(0, lcd_dma.yres - 1, 1, 0);
1922                }
1923                en = lcd_dma.yres;
1924                fn = lcd_dma.xres;
1925                break;
1926        default:
1927                BUG();
1928                return; /* Suppress warning about uninitialized vars */
1929        }
1930
1931        if (omap_dma_in_1510_mode()) {
1932                omap_writew(top >> 16, OMAP1510_DMA_LCD_TOP_F1_U);
1933                omap_writew(top, OMAP1510_DMA_LCD_TOP_F1_L);
1934                omap_writew(bottom >> 16, OMAP1510_DMA_LCD_BOT_F1_U);
1935                omap_writew(bottom, OMAP1510_DMA_LCD_BOT_F1_L);
1936
1937                return;
1938        }
1939
1940        /* 1610 regs */
1941        omap_writew(top >> 16, OMAP1610_DMA_LCD_TOP_B1_U);
1942        omap_writew(top, OMAP1610_DMA_LCD_TOP_B1_L);
1943        omap_writew(bottom >> 16, OMAP1610_DMA_LCD_BOT_B1_U);
1944        omap_writew(bottom, OMAP1610_DMA_LCD_BOT_B1_L);
1945
1946        omap_writew(en, OMAP1610_DMA_LCD_SRC_EN_B1);
1947        omap_writew(fn, OMAP1610_DMA_LCD_SRC_FN_B1);
1948
1949        w = omap_readw(OMAP1610_DMA_LCD_CSDP);
1950        w &= ~0x03;
1951        w |= lcd_dma.data_type;
1952        omap_writew(w, OMAP1610_DMA_LCD_CSDP);
1953
1954        w = omap_readw(OMAP1610_DMA_LCD_CTRL);
1955        /* Always set the source port as SDRAM for now*/
1956        w &= ~(0x03 << 6);
1957        if (lcd_dma.callback != NULL)
1958                w |= 1 << 1;            /* Block interrupt enable */
1959        else
1960                w &= ~(1 << 1);
1961        omap_writew(w, OMAP1610_DMA_LCD_CTRL);
1962
1963        if (!(lcd_dma.rotate || lcd_dma.mirror ||
1964              lcd_dma.vxres || lcd_dma.xscale || lcd_dma.yscale))
1965                return;
1966
1967        w = omap_readw(OMAP1610_DMA_LCD_CCR);
1968        /* Set the double-indexed addressing mode */
1969        w |= (0x03 << 12);
1970        omap_writew(w, OMAP1610_DMA_LCD_CCR);
1971
1972        omap_writew(ei, OMAP1610_DMA_LCD_SRC_EI_B1);
1973        omap_writew(fi >> 16, OMAP1610_DMA_LCD_SRC_FI_B1_U);
1974        omap_writew(fi, OMAP1610_DMA_LCD_SRC_FI_B1_L);
1975}
1976
1977static irqreturn_t lcd_dma_irq_handler(int irq, void *dev_id)
1978{
1979        u16 w;
1980
1981        w = omap_readw(OMAP1610_DMA_LCD_CTRL);
1982        if (unlikely(!(w & (1 << 3)))) {
1983                printk(KERN_WARNING "Spurious LCD DMA IRQ\n");
1984                return IRQ_NONE;
1985        }
1986        /* Ack the IRQ */
1987        w |= (1 << 3);
1988        omap_writew(w, OMAP1610_DMA_LCD_CTRL);
1989        lcd_dma.active = 0;
1990        if (lcd_dma.callback != NULL)
1991                lcd_dma.callback(w, lcd_dma.cb_data);
1992
1993        return IRQ_HANDLED;
1994}
1995
1996int omap_request_lcd_dma(void (* callback)(u16 status, void *data),
1997                         void *data)
1998{
1999        spin_lock_irq(&lcd_dma.lock);
2000        if (lcd_dma.reserved) {
2001                spin_unlock_irq(&lcd_dma.lock);
2002                printk(KERN_ERR "LCD DMA channel already reserved\n");
2003                BUG();
2004                return -EBUSY;
2005        }
2006        lcd_dma.reserved = 1;
2007        spin_unlock_irq(&lcd_dma.lock);
2008        lcd_dma.callback = callback;
2009        lcd_dma.cb_data = data;
2010        lcd_dma.active = 0;
2011        lcd_dma.single_transfer = 0;
2012        lcd_dma.rotate = 0;
2013        lcd_dma.vxres = 0;
2014        lcd_dma.mirror = 0;
2015        lcd_dma.xscale = 0;
2016        lcd_dma.yscale = 0;
2017        lcd_dma.ext_ctrl = 0;
2018        lcd_dma.src_port = 0;
2019
2020        return 0;
2021}
2022
2023void omap_free_lcd_dma(void)
2024{
2025        spin_lock(&lcd_dma.lock);
2026        if (!lcd_dma.reserved) {
2027                spin_unlock(&lcd_dma.lock);
2028                printk(KERN_ERR "LCD DMA is not reserved\n");
2029                BUG();
2030                return;
2031        }
2032        if (!enable_1510_mode)
2033                omap_writew(omap_readw(OMAP1610_DMA_LCD_CCR) & ~1,
2034                            OMAP1610_DMA_LCD_CCR);
2035        lcd_dma.reserved = 0;
2036        spin_unlock(&lcd_dma.lock);
2037}
2038
2039void omap_enable_lcd_dma(void)
2040{
2041        u16 w;
2042
2043        /* Set the Enable bit only if an external controller is
2044         * connected. Otherwise the OMAP internal controller will
2045         * start the transfer when it gets enabled.
2046         */
2047        if (enable_1510_mode || !lcd_dma.ext_ctrl)
2048                return;
2049
2050        w = omap_readw(OMAP1610_DMA_LCD_CTRL);
2051        w |= 1 << 8;
2052        omap_writew(w, OMAP1610_DMA_LCD_CTRL);
2053
2054        lcd_dma.active = 1;
2055
2056        w = omap_readw(OMAP1610_DMA_LCD_CCR);
2057        w |= 1 << 7;
2058        omap_writew(w, OMAP1610_DMA_LCD_CCR);
2059}
2060
2061void omap_setup_lcd_dma(void)
2062{
2063        BUG_ON(lcd_dma.active);
2064        if (!enable_1510_mode) {
2065                /* Set some reasonable defaults */
2066                omap_writew(0x5440, OMAP1610_DMA_LCD_CCR);
2067                omap_writew(0x9102, OMAP1610_DMA_LCD_CSDP);
2068                omap_writew(0x0004, OMAP1610_DMA_LCD_LCH_CTRL);
2069        }
2070        set_b1_regs();
2071        if (!enable_1510_mode) {
2072                u16 w;
2073
2074                w = omap_readw(OMAP1610_DMA_LCD_CCR);
2075                /* If DMA was already active set the end_prog bit to have
2076                 * the programmed register set loaded into the active
2077                 * register set.
2078                 */
2079                w |= 1 << 11;           /* End_prog */
2080                if (!lcd_dma.single_transfer)
2081                        w |= (3 << 8);  /* Auto_init, repeat */
2082                omap_writew(w, OMAP1610_DMA_LCD_CCR);
2083        }
2084}
2085
2086void omap_stop_lcd_dma(void)
2087{
2088        u16 w;
2089
2090        lcd_dma.active = 0;
2091        if (enable_1510_mode || !lcd_dma.ext_ctrl)
2092                return;
2093
2094        w = omap_readw(OMAP1610_DMA_LCD_CCR);
2095        w &= ~(1 << 7);
2096        omap_writew(w, OMAP1610_DMA_LCD_CCR);
2097
2098        w = omap_readw(OMAP1610_DMA_LCD_CTRL);
2099        w &= ~(1 << 8);
2100        omap_writew(w, OMAP1610_DMA_LCD_CTRL);
2101}
2102
2103/*----------------------------------------------------------------------------*/
2104
2105static int __init omap_init_dma(void)
2106{
2107        int ch, r;
2108
2109        if (cpu_is_omap15xx()) {
2110                printk(KERN_INFO "DMA support for OMAP15xx initialized\n");
2111                dma_chan_count = 9;
2112                enable_1510_mode = 1;
2113        } else if (cpu_is_omap16xx() || cpu_is_omap730()) {
2114                printk(KERN_INFO "OMAP DMA hardware version %d\n",
2115                       omap_readw(OMAP_DMA_HW_ID));
2116                printk(KERN_INFO "DMA capabilities: %08x:%08x:%04x:%04x:%04x\n",
2117                       (omap_readw(OMAP_DMA_CAPS_0_U) << 16) |
2118                       omap_readw(OMAP_DMA_CAPS_0_L),
2119                       (omap_readw(OMAP_DMA_CAPS_1_U) << 16) |
2120                       omap_readw(OMAP_DMA_CAPS_1_L),
2121                       omap_readw(OMAP_DMA_CAPS_2), omap_readw(OMAP_DMA_CAPS_3),
2122                       omap_readw(OMAP_DMA_CAPS_4));
2123                if (!enable_1510_mode) {
2124                        u16 w;
2125
2126                        /* Disable OMAP 3.0/3.1 compatibility mode. */
2127                        w = omap_readw(OMAP_DMA_GSCR);
2128                        w |= 1 << 3;
2129                        omap_writew(w, OMAP_DMA_GSCR);
2130                        dma_chan_count = 16;
2131                } else
2132                        dma_chan_count = 9;
2133                if (cpu_is_omap16xx()) {
2134                        u16 w;
2135
2136                        /* this would prevent OMAP sleep */
2137                        w = omap_readw(OMAP1610_DMA_LCD_CTRL);
2138                        w &= ~(1 << 8);
2139                        omap_writew(w, OMAP1610_DMA_LCD_CTRL);
2140                }
2141        } else if (cpu_class_is_omap2()) {
2142                u8 revision = omap_readb(OMAP_DMA4_REVISION);
2143                printk(KERN_INFO "OMAP DMA hardware revision %d.%d\n",
2144                       revision >> 4, revision & 0xf);
2145                dma_chan_count = OMAP_LOGICAL_DMA_CH_COUNT;
2146        } else {
2147                dma_chan_count = 0;
2148                return 0;
2149        }
2150
2151        memset(&lcd_dma, 0, sizeof(lcd_dma));
2152        spin_lock_init(&lcd_dma.lock);
2153        spin_lock_init(&dma_chan_lock);
2154        memset(&dma_chan, 0, sizeof(dma_chan));
2155
2156        for (ch = 0; ch < dma_chan_count; ch++) {
2157                omap_clear_dma(ch);
2158                dma_chan[ch].dev_id = -1;
2159                dma_chan[ch].next_lch = -1;
2160
2161                if (ch >= 6 && enable_1510_mode)
2162                        continue;
2163
2164                if (cpu_class_is_omap1()) {
2165                        /* request_irq() doesn't like dev_id (ie. ch) being
2166                         * zero, so we have to kludge around this. */
2167                        r = request_irq(omap1_dma_irq[ch],
2168                                        omap1_dma_irq_handler, 0, "DMA",
2169                                        (void *) (ch + 1));
2170                        if (r != 0) {
2171                                int i;
2172
2173                                printk(KERN_ERR "unable to request IRQ %d "
2174                                       "for DMA (error %d)\n",
2175                                       omap1_dma_irq[ch], r);
2176                                for (i = 0; i < ch; i++)
2177                                        free_irq(omap1_dma_irq[i],
2178                                                 (void *) (i + 1));
2179                                return r;
2180                        }
2181                }
2182        }
2183
2184        if (cpu_is_omap2430() || cpu_is_omap34xx())
2185                omap_dma_set_global_params(DMA_DEFAULT_ARB_RATE,
2186                                DMA_DEFAULT_FIFO_DEPTH, 0);
2187
2188        if (cpu_class_is_omap2())
2189                setup_irq(INT_24XX_SDMA_IRQ0, &omap24xx_dma_irq);
2190
2191        /* FIXME: Update LCD DMA to work on 24xx */
2192        if (cpu_class_is_omap1()) {
2193                r = request_irq(INT_DMA_LCD, lcd_dma_irq_handler, 0,
2194                                "LCD DMA", NULL);
2195                if (r != 0) {
2196                        int i;
2197
2198                        printk(KERN_ERR "unable to request IRQ for LCD DMA "
2199                               "(error %d)\n", r);
2200                        for (i = 0; i < dma_chan_count; i++)
2201                                free_irq(omap1_dma_irq[i], (void *) (i + 1));
2202                        return r;
2203                }
2204        }
2205
2206        return 0;
2207}
2208
2209arch_initcall(omap_init_dma);
2210
2211EXPORT_SYMBOL(omap_get_dma_src_pos);
2212EXPORT_SYMBOL(omap_get_dma_dst_pos);
2213EXPORT_SYMBOL(omap_get_dma_src_addr_counter);
2214EXPORT_SYMBOL(omap_clear_dma);
2215EXPORT_SYMBOL(omap_set_dma_priority);
2216EXPORT_SYMBOL(omap_request_dma);
2217EXPORT_SYMBOL(omap_free_dma);
2218EXPORT_SYMBOL(omap_start_dma);
2219EXPORT_SYMBOL(omap_stop_dma);
2220EXPORT_SYMBOL(omap_set_dma_callback);
2221EXPORT_SYMBOL(omap_enable_dma_irq);
2222EXPORT_SYMBOL(omap_disable_dma_irq);
2223
2224EXPORT_SYMBOL(omap_set_dma_transfer_params);
2225EXPORT_SYMBOL(omap_set_dma_color_mode);
2226EXPORT_SYMBOL(omap_set_dma_write_mode);
2227
2228EXPORT_SYMBOL(omap_set_dma_src_params);
2229EXPORT_SYMBOL(omap_set_dma_src_index);
2230EXPORT_SYMBOL(omap_set_dma_src_data_pack);
2231EXPORT_SYMBOL(omap_set_dma_src_burst_mode);
2232
2233EXPORT_SYMBOL(omap_set_dma_dest_params);
2234EXPORT_SYMBOL(omap_set_dma_dest_index);
2235EXPORT_SYMBOL(omap_set_dma_dest_data_pack);
2236EXPORT_SYMBOL(omap_set_dma_dest_burst_mode);
2237
2238EXPORT_SYMBOL(omap_set_dma_params);
2239
2240EXPORT_SYMBOL(omap_dma_link_lch);
2241EXPORT_SYMBOL(omap_dma_unlink_lch);
2242
2243EXPORT_SYMBOL(omap_request_lcd_dma);
2244EXPORT_SYMBOL(omap_free_lcd_dma);
2245EXPORT_SYMBOL(omap_enable_lcd_dma);
2246EXPORT_SYMBOL(omap_setup_lcd_dma);
2247EXPORT_SYMBOL(omap_stop_lcd_dma);
2248EXPORT_SYMBOL(omap_set_lcd_dma_b1);
2249EXPORT_SYMBOL(omap_set_lcd_dma_single_transfer);
2250EXPORT_SYMBOL(omap_set_lcd_dma_ext_controller);
2251EXPORT_SYMBOL(omap_set_lcd_dma_b1_rotation);
2252EXPORT_SYMBOL(omap_set_lcd_dma_b1_vxres);
2253EXPORT_SYMBOL(omap_set_lcd_dma_b1_scale);
2254EXPORT_SYMBOL(omap_set_lcd_dma_b1_mirror);
2255
2256
lxr.linux.no kindly hosted by Redpill Linpro AS, provider of Linux consulting and operations services since 1995.