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