uboot/board/micronas/vct/scc.c
<<
>>
Prefs
   1/*
   2 * (C) Copyright 2009 Stefan Roese <sr@denx.de>, DENX Software Engineering
   3 *
   4 * Copyright (C) 2006 Micronas GmbH
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License as
   8 * published by the Free Software Foundation; either version 2 of
   9 * the License, or (at your option) any later version.
  10 *
  11 * This program is distributed in the hope that it will be useful,
  12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  14 * GNU General Public License for more details.
  15 *
  16 * You should have received a copy of the GNU General Public License
  17 * along with this program; if not, write to the Free Software
  18 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
  19 * MA 02111-1307 USA
  20 */
  21
  22#include <common.h>
  23#include <asm/errno.h>
  24
  25#include "vct.h"
  26
  27/*
  28 * List of statically defined buffers per SCC.
  29 * The first entry in the table is the number of fixed buffers
  30 * followed by the list of buffer IDs
  31 */
  32static u32 buffer_list_0[] = { 6, 120, 121, 122, 123, 139, 140 };
  33static u32 buffer_list_1[] = { 6, 120, 121, 122, 123, 139, 140 };
  34static u32 buffer_list_2[] = { 5, 124, 125, 126, 139, 140 };
  35static u32 buffer_list_3[] = { 5, 124, 125, 126, 139, 140 };
  36static u32 buffer_list_4[] = { 5, 124, 125, 126, 139, 140 };
  37static u32 buffer_list_5[] = { 3, 127, 139, 140 };
  38static u32 buffer_list_6[] = { 3, 127, 139, 140 };
  39static u32 buffer_list_7[] = { 6, 128, 129, 130, 131, 139, 140 };
  40static u32 buffer_list_8[] = { 6, 128, 129, 130, 131, 139, 140 };
  41static u32 buffer_list_9[] = { 5, 124, 125, 126, 139, 140 };
  42static u32 buffer_list_10[] = { 5, 124, 125, 126, 139, 140 };
  43static u32 buffer_list_11[] = { 5, 124, 125, 126, 139, 140 };
  44static u32 buffer_list_12[] = { 6, 132, 133, 134, 135, 139, 140 };
  45static u32 buffer_list_13[] = { 6, 132, 133, 134, 135, 139, 140 };
  46static u32 buffer_list_14[] = { 4, 137, 138, 139, 140 };
  47static u32 buffer_list_15[] = { 6, 136, 136, 137, 138, 139, 140 };
  48
  49/** Issue#7674 (new) - DP/DVP buffer assignment */
  50static u32 buffer_list_16[] = { 6, 106, 108, 109, 107, 139, 140 };
  51static u32 buffer_list_17[] = { 6, 106, 110, 107, 111, 139, 140 };
  52static u32 buffer_list_18[] = { 6, 106, 113, 107, 114, 139, 140 };
  53static u32 buffer_list_19[] = { 3, 112, 139, 140 };
  54static u32 buffer_list_20[] = { 35, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  55                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  56                                79, 80, 81, 82, 83, 84, 85, 86, 139, 140 };
  57static u32 buffer_list_21[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  58                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  59                                139, 140 };
  60static u32 buffer_list_22[] = { 81, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  61                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  62                                25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
  63                                37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
  64                                49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
  65                                61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
  66                                73, 74, 75, 76, 77, 78, 139, 140 };
  67static u32 buffer_list_23[] = { 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  68                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  69                                88, 89, 139, 140 };
  70static u32 buffer_list_24[] = { 6, 90, 91, 92, 93, 139, 140 };
  71static u32 buffer_list_25[] = { 18, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99,
  72                                100, 101, 102, 103, 104, 105, 139, 140 };
  73static u32 buffer_list_26[] = { 5, 94, 95, 96, 139, 140 };
  74static u32 buffer_list_27[] = { 5, 97, 98, 99, 139, 140 };
  75static u32 buffer_list_28[] = { 5, 100, 101, 102, 139, 140 };
  76static u32 buffer_list_29[] = { 5, 103, 104, 105, 139, 140 };
  77static u32 buffer_list_30[] = { 10, 108, 109, 110, 111, 113, 114, 116, 117,
  78                                139, 140 };
  79static u32 buffer_list_31[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114,
  80                                115, 116, 117, 139, 140 };
  81static u32 buffer_list_32[] = { 13, 106, 107, 108, 109, 110, 111, 113, 114,
  82                                115, 116, 117, 139, 140 };
  83static u32 buffer_list_33[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  84                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  85                                139, 140 };
  86static u32 buffer_list_34[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  87                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  88                                139, 140 };
  89static u32 buffer_list_35[] = { 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  90                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  91                                87, 139, 140 };
  92static u32 buffer_list_36[] = { 28, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  93                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  94                                87, 139, 140 };
  95static u32 buffer_list_37[] = { 27, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  96                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
  97                                139, 140 };
  98static u32 buffer_list_38[] = { 29, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
  99                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
 100                                118, 119, 139, 140 };
 101static u32 buffer_list_39[] = { 91, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,
 102                                13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24,
 103                                25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36,
 104                                37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48,
 105                                49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60,
 106                                61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72,
 107                                73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84,
 108                                85, 86, 118, 119, 139, 140 };
 109static u32 buffer_list_40[] = { 0 };
 110
 111/*
 112 * List of statically defined vcid.csize values.
 113 * The first entry in the table is the number of possible csize values
 114 * followed by the list of data path values in bits.
 115 */
 116static u32 csize_list_0[] = { 2, 0, 1 };
 117static u32 csize_list_1[] = { 2, 0, 1 };
 118static u32 csize_list_2[] = { 1, 1 };
 119static u32 csize_list_3[] = { 1, 1 };
 120static u32 csize_list_4[] = { 1, 1 };
 121static u32 csize_list_5[] = { 1, 0 };
 122static u32 csize_list_6[] = { 1, 0 };
 123static u32 csize_list_7[] = { 1, 1 };
 124static u32 csize_list_8[] = { 1, 1 };
 125static u32 csize_list_9[] = { 1, 1 };
 126static u32 csize_list_10[] = { 1, 1 };
 127static u32 csize_list_11[] = { 1, 1 };
 128static u32 csize_list_12[] = { 1, 1 };
 129static u32 csize_list_13[] = { 1, 1 };
 130static u32 csize_list_14[] = { 1, 2 };
 131static u32 csize_list_15[] = { 1, 4 };
 132static u32 csize_list_16[] = { 3, 0, 1, 2 };
 133static u32 csize_list_17[] = { 3, 0, 1, 2 };
 134static u32 csize_list_18[] = { 3, 0, 1, 2 };
 135static u32 csize_list_19[] = { 1, 2 };
 136static u32 csize_list_20[] = { 1, 0 };
 137static u32 csize_list_21[] = { 1, 0 };
 138static u32 csize_list_22[] = { 1, 2 };
 139static u32 csize_list_23[] = { 1, 3 };
 140static u32 csize_list_24[] = { 1, 3 };
 141static u32 csize_list_25[] = { 1, 3 };
 142static u32 csize_list_26[] = { 1, 0 };
 143static u32 csize_list_27[] = { 1, 0 };
 144static u32 csize_list_28[] = { 1, 0 };
 145static u32 csize_list_29[] = { 1, 0 };
 146static u32 csize_list_30[] = { 1, 2 };
 147static u32 csize_list_31[] = { 1, 2 };
 148static u32 csize_list_32[] = { 1, 2 };
 149static u32 csize_list_33[] = { 1, 2 };
 150static u32 csize_list_34[] = { 1, 2 };
 151static u32 csize_list_35[] = { 1, 2 };
 152static u32 csize_list_36[] = { 1, 2 };
 153static u32 csize_list_37[] = { 2, 0, 1 };
 154static u32 csize_list_38[] = { 1, 2 };
 155static u32 csize_list_39[] = { 1, 3 };
 156static u32 csize_list_40[] = { 1, 3 };
 157
 158/*
 159 * SCC_Configuration table
 160 */
 161static const struct scc_descriptor scc_descriptor_table[] = {
 162/* scn  scc_name  profile  SCC  scc_id  mci_id  rd  wr   m   p fh  si cfg sta */
 163        {"fe_", "fe_3dcomb_wr", STRM_P, SCC0_BASE, 0, 0, 0, 4, 1, 1, 0, 0, 0, 1,
 164         buffer_list_0, csize_list_0},
 165        {"fe_", "fe_3dcomb_rd", STRM_P, SCC1_BASE, 1, 18, 4, 0, 1, 1, 0, 1, 0,
 166         1, buffer_list_1, csize_list_1},
 167        {"di_", "di_tnr_wr", STRM_P, SCC2_BASE, 2, 1, 0, 3, 1, 1, 0, 2, 0, 1,
 168         buffer_list_2, csize_list_2},
 169        {"di_", "di_tnr_field_rd", STRM_P, SCC3_BASE, 3, 19, 3, 0, 1, 1, 0, 3,
 170         0, 1, buffer_list_3, csize_list_3},
 171        {"di_", "di_tnr_frame_rd", STRM_P, SCC4_BASE, 4, 20, 3, 0, 1, 1, 0, 4,
 172         0, 1, buffer_list_4, csize_list_4},
 173        {"di_", "di_mval_wr", STRM_P, SCC5_BASE, 5, 2, 0, 1, 1, 1, 0, 5, 0, 1,
 174         buffer_list_5, csize_list_5},
 175        {"di_", "di_mval_rd", STRM_P, SCC6_BASE, 6, 21, 1, 0, 1, 1, 0, 6, 0, 1,
 176         buffer_list_6, csize_list_6},
 177        {"rc_", "rc_frame_wr", STRM_P, SCC7_BASE, 7, 3, 0, 4, 1, 1, 0, 7, 0, 1,
 178         buffer_list_7, csize_list_7},
 179        {"rc_", "rc_frame0_rd", STRM_P, SCC8_BASE, 8, 22, 4, 0, 1, 1, 0, 8, 0,
 180         1, buffer_list_8, csize_list_8},
 181        {"opt", "opt_field0_rd", STRM_P, SCC9_BASE, 9, 23, 3, 0, 1, 1, 0, 9, 0,
 182         1, buffer_list_9, csize_list_9},
 183        {"opt", "opt_field1_rd", STRM_P, SCC10_BASE, 10, 24, 3, 0, 1, 1, 0, 10,
 184         0, 1, buffer_list_10, csize_list_10},
 185        {"opt", "opt_field2_rd", STRM_P, SCC11_BASE, 11, 25, 3, 0, 1, 1, 0, 11,
 186         0, 1, buffer_list_11, csize_list_11},
 187        {"pip", "pip_frame_wr", STRM_P, SCC12_BASE, 12, 4, 0, 4, 1, 1, 0, 12, 0,
 188         1, buffer_list_12, csize_list_12},
 189        {"pip", "pip_frame_rd", STRM_P, SCC13_BASE, 13, 26, 4, 0, 1, 1, 0, 13,
 190         0, 1, buffer_list_13, csize_list_13},
 191        {"dp_", "dp_agpu_rd", STRM_P, SCC14_BASE, 14, 27, 2, 0, 2, 1, 0, 14, 0,
 192         1, buffer_list_14, csize_list_14},
 193        {"ewa", "ewarp_rw", SRMD, SCC15_BASE, 15, 11, 1, 1, 0, 0, 0, -1, 0, 0,
 194         buffer_list_15, csize_list_15},
 195        {"dp_", "dp_osd_rd", STRM_P, SCC16_BASE, 16, 28, 3, 0, 2, 1, 0, 15, 0,
 196         1, buffer_list_16, csize_list_16},
 197        {"dp_", "dp_graphic_rd", STRM_P, SCC17_BASE, 17, 29, 3, 0, 2, 1, 0, 16,
 198         0, 1, buffer_list_17, csize_list_17},
 199        {"dvp", "dvp_osd_rd", STRM_P, SCC18_BASE, 18, 30, 2, 0, 2, 1, 0, 17, 0,
 200         1, buffer_list_18, csize_list_18},
 201        {"dvp", "dvp_vbi_rd", STRM_D, SCC19_BASE, 19, 31, 1, 0, 0, 1, 0, -1, 0,
 202         0, buffer_list_19, csize_list_19},
 203        {"tsi", "tsio_wr", STRM_P, SCC20_BASE, 20, 5, 0, 8, 2, 1, 1, -1, 0, 0,
 204         buffer_list_20, csize_list_20},
 205        {"tsi", "tsio_rd", STRM_P, SCC21_BASE, 21, 32, 4, 0, 2, 1, 1, -1, 0, 0,
 206         buffer_list_21, csize_list_21},
 207        {"tsd", "tsd_wr", SRMD, SCC22_BASE, 22, 6, 0, 64, 0, 0, 1, -1, 0, 0,
 208         buffer_list_22, csize_list_22},
 209        {"vd_", "vd_ud_st_rw", SRMD, SCC23_BASE, 23, 12, 2, 2, 0, 0, 1, -1, 0,
 210         0, buffer_list_23, csize_list_23},
 211        {"vd_", "vd_frr_rd", SRMD, SCC24_BASE, 24, 33, 4, 0, 0, 0, 0, -1, 0, 0,
 212         buffer_list_24, csize_list_24},
 213        {"vd_", "vd_frw_disp_wr", SRMD, SCC25_BASE, 25, 7, 0, 16, 0, 0, 0, -1,
 214         0, 0, buffer_list_25, csize_list_25},
 215        {"mr_", "mr_vd_m_y_rd", STRM_P, SCC26_BASE, 26, 34, 3, 0, 2, 1, 0, 18,
 216         0, 1, buffer_list_26, csize_list_26},
 217        {"mr_", "mr_vd_m_c_rd", STRM_P, SCC27_BASE, 27, 35, 3, 0, 2, 1, 0, 19,
 218         0, 1, buffer_list_27, csize_list_27},
 219        {"mr_", "mr_vd_s_y_rd", STRM_P, SCC28_BASE, 28, 36, 3, 0, 2, 1, 0, 20,
 220         0, 1, buffer_list_28, csize_list_28},
 221        {"mr_", "mr_vd_s_c_rd", STRM_P, SCC29_BASE, 29, 37, 3, 0, 2, 1, 0, 21,
 222         0, 1, buffer_list_29, csize_list_29},
 223        {"ga_", "ga_wr", STRM_P, SCC30_BASE, 30, 8, 0, 1, 1, 1, 0, -1, 1, 1,
 224         buffer_list_30, csize_list_30},
 225        {"ga_", "ga_src1_rd", STRM_P, SCC31_BASE, 31, 38, 1, 0, 1, 1, 0, -1, 1,
 226         1, buffer_list_31, csize_list_31},
 227        {"ga_", "ga_src2_rd", STRM_P, SCC32_BASE, 32, 39, 1, 0, 1, 1, 0, -1, 1,
 228         1, buffer_list_32, csize_list_32},
 229        {"ad_", "ad_rd", STRM_D, SCC33_BASE, 33, 40, 2, 0, 0, 1, 1, -1, 0, 0,
 230         buffer_list_33, csize_list_33},
 231        {"ad_", "ad_wr", STRM_D, SCC34_BASE, 34, 9, 0, 3, 0, 1, 1, -1, 0, 0,
 232         buffer_list_34, csize_list_34},
 233        {"abp", "abp_rd", STRM_D, SCC35_BASE, 35, 41, 5, 0, 0, 1, 1, -1, 0, 0,
 234         buffer_list_35, csize_list_35},
 235        {"abp", "abp_wr", STRM_D, SCC36_BASE, 36, 10, 0, 3, 0, 1, 1, -1, 0, 0,
 236         buffer_list_36, csize_list_36},
 237        {"ebi", "ebi_rw", STRM_P, SCC37_BASE, 37, 13, 4, 4, 2, 1, 1, -1, 0, 0,
 238         buffer_list_37, csize_list_37},
 239        {"usb", "usb_rw", SRMD, SCC38_BASE, 38, 14, 1, 1, 0, 0, 1, -1, 0, 0,
 240         buffer_list_38, csize_list_38},
 241        {"cpu", "cpu1_spdma_rw", SRMD, SCC39_BASE, 39, 15, 1, 1, 0, 0, 1, -1, 0,
 242         0, buffer_list_39, csize_list_39},
 243        {"cpu", "cpu1_bridge_rw", SRMD, SCC40_BASE, 40, 16, 0, 0, 0, 0, 0, -1,
 244         0, 0, buffer_list_40, csize_list_40},
 245};
 246
 247/* DMA state structures for read and write channels for each SCC */
 248
 249static struct scc_dma_state scc_state_rd_0[] = { {-1} };
 250static struct scc_dma_state scc_state_wr_0[] = { {0}, {0}, {0}, {0} };
 251static struct scc_dma_state scc_state_rd_1[] = { {0}, {0}, {0}, {0} };
 252static struct scc_dma_state scc_state_wr_1[] = { {-1} };
 253static struct scc_dma_state scc_state_rd_2[] = { {-1} };
 254static struct scc_dma_state scc_state_wr_2[] = { {0}, {0}, {0} };
 255static struct scc_dma_state scc_state_rd_3[] = { {0}, {0}, {0} };
 256static struct scc_dma_state scc_state_wr_3[] = { {-1} };
 257static struct scc_dma_state scc_state_rd_4[] = { {0}, {0}, {0} };
 258static struct scc_dma_state scc_state_wr_4[] = { {-1} };
 259static struct scc_dma_state scc_state_rd_5[] = { {-1} };
 260static struct scc_dma_state scc_state_wr_5[] = { {0} };
 261static struct scc_dma_state scc_state_rd_6[] = { {0} };
 262static struct scc_dma_state scc_state_wr_6[] = { {-1} };
 263static struct scc_dma_state scc_state_rd_7[] = { {-1} };
 264static struct scc_dma_state scc_state_wr_7[] = { {0}, {0}, {0}, {0} };
 265static struct scc_dma_state scc_state_rd_8[] = { {0}, {0}, {0}, {0} };
 266static struct scc_dma_state scc_state_wr_8[] = { {-1} };
 267static struct scc_dma_state scc_state_rd_9[] = { {0}, {0}, {0}, };
 268static struct scc_dma_state scc_state_wr_9[] = { {-1} };
 269static struct scc_dma_state scc_state_rd_10[] = { {0}, {0}, {0} };
 270static struct scc_dma_state scc_state_wr_10[] = { {-1} };
 271static struct scc_dma_state scc_state_rd_11[] = { {0}, {0}, {0} };
 272static struct scc_dma_state scc_state_wr_11[] = { {-1} };
 273static struct scc_dma_state scc_state_rd_12[] = { {-1} };
 274static struct scc_dma_state scc_state_wr_12[] = { {0}, {0}, {0}, {0} };
 275static struct scc_dma_state scc_state_rd_13[] = { {0}, {0}, {0}, {0} };
 276static struct scc_dma_state scc_state_wr_13[] = { {-1} };
 277static struct scc_dma_state scc_state_rd_14[] = { {0}, {0} };
 278static struct scc_dma_state scc_state_wr_14[] = { {-1} };
 279static struct scc_dma_state scc_state_rd_15[] = { {0} };
 280static struct scc_dma_state scc_state_wr_15[] = { {0} };
 281static struct scc_dma_state scc_state_rd_16[] = { {0}, {0}, {0} };
 282static struct scc_dma_state scc_state_wr_16[] = { {-1} };
 283static struct scc_dma_state scc_state_rd_17[] = { {0}, {0}, {0} };
 284static struct scc_dma_state scc_state_wr_17[] = { {-1} };
 285static struct scc_dma_state scc_state_rd_18[] = { {0}, {0} };
 286static struct scc_dma_state scc_state_wr_18[] = { {-1} };
 287static struct scc_dma_state scc_state_rd_19[] = { {0} };
 288static struct scc_dma_state scc_state_wr_19[] = { {-1} };
 289static struct scc_dma_state scc_state_rd_20[] = { {-1} };
 290static struct scc_dma_state scc_state_wr_20[] = {
 291        {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} };
 292static struct scc_dma_state scc_state_rd_21[] = { {0}, {0}, {0}, {0} };
 293static struct scc_dma_state scc_state_wr_21[] = { {-1} };
 294static struct scc_dma_state scc_state_rd_22[] = { {-1} };
 295static struct scc_dma_state scc_state_wr_22[] = {
 296        {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
 297        {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
 298        {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
 299        {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
 300        {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0} };
 301static struct scc_dma_state scc_state_rd_23[] = { {0}, {0} };
 302static struct scc_dma_state scc_state_wr_23[] = { {0}, {0} };
 303static struct scc_dma_state scc_state_rd_24[] = { {0}, {0}, {0}, {0} };
 304static struct scc_dma_state scc_state_wr_24[] = { {-1} };
 305static struct scc_dma_state scc_state_rd_25[] = { {-1} };
 306static struct scc_dma_state scc_state_wr_25[] = {
 307        {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0}, {0},
 308        {0}, {0} };
 309static struct scc_dma_state scc_state_rd_26[] = { {0}, {0}, {0} };
 310static struct scc_dma_state scc_state_wr_26[] = { {-1} };
 311static struct scc_dma_state scc_state_rd_27[] = { {0}, {0}, {0} };
 312static struct scc_dma_state scc_state_wr_27[] = { {-1} };
 313static struct scc_dma_state scc_state_rd_28[] = { {0}, {0}, {0} };
 314static struct scc_dma_state scc_state_wr_28[] = { {-1} };
 315static struct scc_dma_state scc_state_rd_29[] = { {0}, {0}, {0} };
 316static struct scc_dma_state scc_state_wr_29[] = { {-1} };
 317static struct scc_dma_state scc_state_rd_30[] = { {-1} };
 318static struct scc_dma_state scc_state_wr_30[] = { {0} };
 319static struct scc_dma_state scc_state_rd_31[] = { {0} };
 320static struct scc_dma_state scc_state_wr_31[] = { {-1} };
 321static struct scc_dma_state scc_state_rd_32[] = { {0} };
 322static struct scc_dma_state scc_state_wr_32[] = { {-1} };
 323static struct scc_dma_state scc_state_rd_33[] = { {0}, {0} };
 324static struct scc_dma_state scc_state_wr_33[] = { {-1} };
 325static struct scc_dma_state scc_state_rd_34[] = { {-1} };
 326static struct scc_dma_state scc_state_wr_34[] = { {0}, {0}, {0} };
 327static struct scc_dma_state scc_state_rd_35[] = { {0}, {0}, {0}, {0}, {0} };
 328static struct scc_dma_state scc_state_wr_35[] = { {-1} };
 329static struct scc_dma_state scc_state_rd_36[] = { {-1} };
 330static struct scc_dma_state scc_state_wr_36[] = { {0}, {0}, {0} };
 331static struct scc_dma_state scc_state_rd_37[] = { {0}, {0}, {0}, {0} };
 332static struct scc_dma_state scc_state_wr_37[] = { {0}, {0}, {0}, {0} };
 333static struct scc_dma_state scc_state_rd_38[] = { {0} };
 334static struct scc_dma_state scc_state_wr_38[] = { {0} };
 335static struct scc_dma_state scc_state_rd_39[] = { {0} };
 336static struct scc_dma_state scc_state_wr_39[] = { {0} };
 337static struct scc_dma_state scc_state_rd_40[] = { {-1} };
 338static struct scc_dma_state scc_state_wr_40[] = { {-1} };
 339
 340/* DMA state references to access from the driver */
 341static struct scc_dma_state *scc_state_rd[] = {
 342        scc_state_rd_0,
 343        scc_state_rd_1,
 344        scc_state_rd_2,
 345        scc_state_rd_3,
 346        scc_state_rd_4,
 347        scc_state_rd_5,
 348        scc_state_rd_6,
 349        scc_state_rd_7,
 350        scc_state_rd_8,
 351        scc_state_rd_9,
 352        scc_state_rd_10,
 353        scc_state_rd_11,
 354        scc_state_rd_12,
 355        scc_state_rd_13,
 356        scc_state_rd_14,
 357        scc_state_rd_15,
 358        scc_state_rd_16,
 359        scc_state_rd_17,
 360        scc_state_rd_18,
 361        scc_state_rd_19,
 362        scc_state_rd_20,
 363        scc_state_rd_21,
 364        scc_state_rd_22,
 365        scc_state_rd_23,
 366        scc_state_rd_24,
 367        scc_state_rd_25,
 368        scc_state_rd_26,
 369        scc_state_rd_27,
 370        scc_state_rd_28,
 371        scc_state_rd_29,
 372        scc_state_rd_30,
 373        scc_state_rd_31,
 374        scc_state_rd_32,
 375        scc_state_rd_33,
 376        scc_state_rd_34,
 377        scc_state_rd_35,
 378        scc_state_rd_36,
 379        scc_state_rd_37,
 380        scc_state_rd_38,
 381        scc_state_rd_39,
 382        scc_state_rd_40,
 383};
 384
 385static struct scc_dma_state *scc_state_wr[] = {
 386        scc_state_wr_0,
 387        scc_state_wr_1,
 388        scc_state_wr_2,
 389        scc_state_wr_3,
 390        scc_state_wr_4,
 391        scc_state_wr_5,
 392        scc_state_wr_6,
 393        scc_state_wr_7,
 394        scc_state_wr_8,
 395        scc_state_wr_9,
 396        scc_state_wr_10,
 397        scc_state_wr_11,
 398        scc_state_wr_12,
 399        scc_state_wr_13,
 400        scc_state_wr_14,
 401        scc_state_wr_15,
 402        scc_state_wr_16,
 403        scc_state_wr_17,
 404        scc_state_wr_18,
 405        scc_state_wr_19,
 406        scc_state_wr_20,
 407        scc_state_wr_21,
 408        scc_state_wr_22,
 409        scc_state_wr_23,
 410        scc_state_wr_24,
 411        scc_state_wr_25,
 412        scc_state_wr_26,
 413        scc_state_wr_27,
 414        scc_state_wr_28,
 415        scc_state_wr_29,
 416        scc_state_wr_30,
 417        scc_state_wr_31,
 418        scc_state_wr_32,
 419        scc_state_wr_33,
 420        scc_state_wr_34,
 421        scc_state_wr_35,
 422        scc_state_wr_36,
 423        scc_state_wr_37,
 424        scc_state_wr_38,
 425        scc_state_wr_39,
 426        scc_state_wr_40,
 427};
 428
 429static u32 scc_takeover_mode = SCC_TO_IMMEDIATE;
 430
 431/* Change mode of the SPDMA for given direction */
 432static u32 scc_agu_mode_sp = AGU_BYPASS;
 433
 434/* Change mode of the USB for given direction */
 435static u32 scc_agu_mode_usb = AGU_BYPASS;
 436
 437static union scc_softwareconfiguration scc_software_configuration[SCC_MAX];
 438
 439static u32 dma_fsm[4][4] = {
 440        /* DMA_CMD_RESET  DMA_CMD_SETUP    DMA_CMD_START    DMA_CMD_STOP */
 441        /* DMA_STATE_RESET */
 442        {DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_ERROR, DMA_STATE_ERROR},
 443        /* DMA_STATE_SETUP */
 444        {DMA_STATE_RESET, DMA_STATE_SETUP, DMA_STATE_START, DMA_STATE_SETUP},
 445        /* DMA_STATE_START */
 446        {DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_START, DMA_STATE_SETUP},
 447        /* DMA_STATE_ERROR */
 448        {DMA_STATE_RESET, DMA_STATE_ERROR, DMA_STATE_ERROR, DMA_STATE_ERROR},
 449};
 450
 451static void dma_state_process(struct scc_dma_state *dma_state, u32 cmd)
 452{
 453        dma_state->dma_status = dma_fsm[dma_state->dma_status][cmd];
 454        dma_state->dma_cmd = cmd;
 455}
 456
 457static void dma_state_process_dma_command(struct scc_dma_state *dma_state,
 458                                          u32 dma_cmd)
 459{
 460        dma_state->dma_cmd = dma_cmd;
 461        switch (dma_cmd) {
 462        case DMA_START:
 463        case DMA_START_FH_RESET:
 464                dma_state_process(dma_state, DMA_CMD_START);
 465                break;
 466        case DMA_STOP:
 467                dma_state_process(dma_state, DMA_CMD_STOP);
 468                break;
 469        default:
 470                break;
 471        }
 472}
 473
 474static void scc_takeover_dma(enum scc_id id, u32 dma_id, u32 drs)
 475{
 476        union scc_cmd dma_cmd;
 477
 478        dma_cmd.reg = 0;
 479
 480        /* Prepare the takeover for the DMA channel */
 481        dma_cmd.bits.action = DMA_TAKEOVER;
 482        dma_cmd.bits.id = dma_id;
 483        dma_cmd.bits.rid = TO_DMA_CFG;  /* this is DMA_CFG register takeover */
 484        if (drs == DMA_WRITE)
 485                dma_cmd.bits.drs = DMA_WRITE;
 486
 487        reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg);
 488}
 489
 490int scc_dma_cmd(enum scc_id id, u32 cmd, u32 dma_id, u32 drs)
 491{
 492        union scc_cmd dma_cmd;
 493        struct scc_dma_state *dma_state;
 494
 495        if ((id >= SCC_MAX) || (id < 0))
 496                return -EINVAL;
 497
 498        dma_cmd.reg = 0;
 499
 500        /* Prepare the takeover for the DMA channel */
 501        dma_cmd.bits.action = cmd;
 502        dma_cmd.bits.id = dma_id;
 503        if (drs == DMA_WRITE) {
 504                dma_cmd.bits.drs = DMA_WRITE;
 505                dma_state = &scc_state_wr[id][dma_id];
 506        } else {
 507                dma_state = &scc_state_rd[id][dma_id];
 508        }
 509
 510        dma_state->scc_id = id;
 511        dma_state->dma_id = dma_id;
 512        dma_state_process_dma_command(dma_state, cmd);
 513
 514        reg_write(SCC_CMD(scc_descriptor_table[id].base_address), dma_cmd.reg);
 515
 516        return 0;
 517}
 518
 519int scc_set_usb_address_generation_mode(u32 agu_mode)
 520{
 521        if (AGU_ACTIVE == agu_mode) {
 522                /* Ensure both DMAs are stopped */
 523                scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_WRITE);
 524                scc_dma_cmd(SCC_USB_RW, DMA_STOP, 0, DMA_READ);
 525        } else {
 526                agu_mode = AGU_BYPASS;
 527        }
 528
 529        scc_agu_mode_usb = agu_mode;
 530
 531        return 0;
 532}
 533
 534int scc_setup_dma(enum scc_id id, u32 buffer_tag,
 535                  u32 type, u32 fh_mode, u32 drs, u32 dma_id)
 536{
 537        struct scc_dma_state *dma_state;
 538        int return_value = 0;
 539        union scc_dma_cfg dma_cfg;
 540        u32 *buffer_tag_list = scc_descriptor_table[id].buffer_tag_list;
 541        u32 tag_count, t, t_valid;
 542
 543        if ((id >= SCC_MAX) || (id < 0))
 544                return -EINVAL;
 545
 546        /* if the register is only configured by hw, cannot write! */
 547        if (1 == scc_descriptor_table[id].hw_dma_cfg)
 548                return -EACCES;
 549
 550        if (DMA_WRITE == drs) {
 551                if (dma_id >= scc_descriptor_table[id].p_dma_channels_wr)
 552                        return -EINVAL;
 553                dma_state = &scc_state_wr[id][dma_id];
 554        } else {
 555                if (dma_id >= scc_descriptor_table[id].p_dma_channels_rd)
 556                        return -EINVAL;
 557                dma_state = &scc_state_rd[id][dma_id];
 558        }
 559
 560        /* Compose the DMA configuration register */
 561        tag_count = buffer_tag_list[0];
 562        t_valid = 0;
 563        for (t = 1; t <= tag_count; t++) {
 564                if (buffer_tag == buffer_tag_list[t]) {
 565                        /* Tag found - validate */
 566                        t_valid = 1;
 567                        break;
 568                }
 569        }
 570
 571        if (!t_valid)
 572                return -EACCES;
 573
 574        /*
 575         * Read the register first -- two functions write into the register
 576         * it does not make sense to read the DMA config back, because there
 577         * are two register configuration sets (drs)
 578         */
 579        dma_cfg.reg = 0;
 580        dma_cfg.bits.buffer_id = buffer_tag;
 581        dma_state_process(dma_state, DMA_CMD_SETUP);
 582
 583        /*
 584         * This is Packet CFG set select - usable for TSIO, EBI and those SCCs
 585         * which habe 2 packet configs
 586         */
 587        dma_cfg.bits.packet_cfg_id =
 588                scc_software_configuration[id].bits.packet_select;
 589
 590        if (type == DMA_CYCLIC)
 591                dma_cfg.bits.buffer_type = 1;
 592        else
 593                dma_cfg.bits.buffer_type = 0;
 594
 595        if (fh_mode == USE_FH)
 596                dma_cfg.bits.fh_mode = 1;
 597        else
 598                dma_cfg.bits.fh_mode = 0;
 599
 600        if (id == SCC_CPU1_SPDMA_RW)
 601                dma_cfg.bits.agu_mode = scc_agu_mode_sp;
 602
 603        if (id == SCC_USB_RW)
 604                dma_cfg.bits.agu_mode = scc_agu_mode_usb;
 605
 606        reg_write(SCC_DMA_CFG(scc_descriptor_table[id].base_address),
 607                  dma_cfg.reg);
 608
 609        /* The DMA_CFG needs a takeover! */
 610        if (SCC_TO_IMMEDIATE == scc_takeover_mode)
 611                scc_takeover_dma(id, dma_id, drs);
 612
 613        /* if (buffer_tag is not used) */
 614        dma_state->buffer_tag = buffer_tag;
 615
 616        dma_state->scc_id = id;
 617        dma_state->dma_id = dma_id;
 618
 619        return return_value;
 620}
 621
 622int scc_enable(enum scc_id id, u32 value)
 623{
 624        if ((id >= SCC_MAX) || (id < 0))
 625                return -EINVAL;
 626
 627        if (value == 0) {
 628                scc_software_configuration[id].bits.enable_status = 0;
 629        } else {
 630                value = 1;
 631                scc_software_configuration[id].bits.enable_status = 1;
 632        }
 633        reg_write(SCC_ENABLE(scc_descriptor_table[id].base_address), value);
 634
 635        return 0;
 636}
 637
 638static inline void ehb(void)
 639{
 640        __asm__ __volatile__(
 641                "       .set    mips32r2        \n"
 642                "       ehb                     \n"
 643                "       .set    mips0           \n");
 644}
 645
 646int scc_reset(enum scc_id id, u32 value)
 647{
 648        if ((id >= SCC_MAX) || (id < 0))
 649                return -EINVAL;
 650
 651        /* Invert value to the strait logic from the negative hardware logic */
 652        if (value == 0)
 653                value = 1;
 654        else
 655                value = 0;
 656
 657        /* Write the value to the register */
 658        reg_write(SCC_RESET(scc_descriptor_table[id].base_address), value);
 659
 660        /* sync flush */
 661        asm("sync");    /* request bus write queue flush */
 662        ehb();          /* wait until previous bus commit instr has finished */
 663        asm("nop");     /* wait for flush to occur */
 664        asm("nop");     /* wait for flush to occur */
 665
 666        udelay(100);
 667
 668        return 0;
 669}
 670