Sylvain Munaut | 2f9ea1b | 2007-09-16 20:53:27 +1000 | [diff] [blame] | 1 | /* |
| 2 | * Private header for the MPC52xx processor BestComm driver |
| 3 | * |
| 4 | * By private, we mean that driver should not use it directly. It's meant |
| 5 | * to be used by the BestComm engine driver itself and by the intermediate |
| 6 | * layer between the core and the drivers. |
| 7 | * |
| 8 | * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com> |
| 9 | * Copyright (C) 2005 Varma Electronics Oy, |
| 10 | * ( by Andrey Volkov <avolkov@varma-el.com> ) |
| 11 | * Copyright (C) 2003-2004 MontaVista, Software, Inc. |
| 12 | * ( by Dale Farnsworth <dfarnsworth@mvista.com> ) |
| 13 | * |
| 14 | * This file is licensed under the terms of the GNU General Public License |
| 15 | * version 2. This program is licensed "as is" without any warranty of any |
| 16 | * kind, whether express or implied. |
| 17 | */ |
| 18 | |
| 19 | #ifndef __BESTCOMM_PRIV_H__ |
| 20 | #define __BESTCOMM_PRIV_H__ |
| 21 | |
| 22 | #include <linux/spinlock.h> |
| 23 | #include <linux/of.h> |
| 24 | #include <asm/io.h> |
| 25 | #include <asm/mpc52xx.h> |
| 26 | |
| 27 | #include "sram.h" |
| 28 | |
| 29 | |
| 30 | /* ======================================================================== */ |
| 31 | /* Engine related stuff */ |
| 32 | /* ======================================================================== */ |
| 33 | |
| 34 | /* Zones sizes and needed alignments */ |
| 35 | #define BCOM_MAX_TASKS 16 |
| 36 | #define BCOM_MAX_VAR 24 |
| 37 | #define BCOM_MAX_INC 8 |
| 38 | #define BCOM_MAX_FDT 64 |
| 39 | #define BCOM_MAX_CTX 20 |
| 40 | #define BCOM_CTX_SIZE (BCOM_MAX_CTX * sizeof(u32)) |
| 41 | #define BCOM_CTX_ALIGN 0x100 |
| 42 | #define BCOM_VAR_SIZE (BCOM_MAX_VAR * sizeof(u32)) |
| 43 | #define BCOM_INC_SIZE (BCOM_MAX_INC * sizeof(u32)) |
| 44 | #define BCOM_VAR_ALIGN 0x80 |
| 45 | #define BCOM_FDT_SIZE (BCOM_MAX_FDT * sizeof(u32)) |
| 46 | #define BCOM_FDT_ALIGN 0x100 |
| 47 | |
| 48 | /** |
| 49 | * struct bcom_tdt - Task Descriptor Table Entry |
| 50 | * |
| 51 | */ |
| 52 | struct bcom_tdt { |
| 53 | u32 start; |
| 54 | u32 stop; |
| 55 | u32 var; |
| 56 | u32 fdt; |
| 57 | u32 exec_status; /* used internally by BestComm engine */ |
| 58 | u32 mvtp; /* used internally by BestComm engine */ |
| 59 | u32 context; |
| 60 | u32 litbase; |
| 61 | }; |
| 62 | |
| 63 | /** |
| 64 | * struct bcom_engine |
| 65 | * |
| 66 | * This holds all info needed globaly to handle the engine |
| 67 | */ |
| 68 | struct bcom_engine { |
| 69 | struct device_node *ofnode; |
| 70 | struct mpc52xx_sdma __iomem *regs; |
| 71 | phys_addr_t regs_base; |
| 72 | |
| 73 | struct bcom_tdt *tdt; |
| 74 | u32 *ctx; |
| 75 | u32 *var; |
| 76 | u32 *fdt; |
| 77 | |
| 78 | spinlock_t lock; |
| 79 | }; |
| 80 | |
| 81 | extern struct bcom_engine *bcom_eng; |
| 82 | |
| 83 | |
| 84 | /* ======================================================================== */ |
| 85 | /* Tasks related stuff */ |
| 86 | /* ======================================================================== */ |
| 87 | |
| 88 | /* Tasks image header */ |
| 89 | #define BCOM_TASK_MAGIC 0x4243544B /* 'BCTK' */ |
| 90 | |
| 91 | struct bcom_task_header { |
| 92 | u32 magic; |
| 93 | u8 desc_size; /* the size fields */ |
| 94 | u8 var_size; /* are given in number */ |
| 95 | u8 inc_size; /* of 32-bits words */ |
| 96 | u8 first_var; |
| 97 | u8 reserved[8]; |
| 98 | }; |
| 99 | |
Lucas De Marchi | 25985ed | 2011-03-30 22:57:33 -0300 | [diff] [blame] | 100 | /* Descriptors structure & co */ |
Sylvain Munaut | 2f9ea1b | 2007-09-16 20:53:27 +1000 | [diff] [blame] | 101 | #define BCOM_DESC_NOP 0x000001f8 |
| 102 | #define BCOM_LCD_MASK 0x80000000 |
| 103 | #define BCOM_DRD_EXTENDED 0x40000000 |
| 104 | #define BCOM_DRD_INITIATOR_SHIFT 21 |
| 105 | |
| 106 | /* Tasks pragma */ |
| 107 | #define BCOM_PRAGMA_BIT_RSV 7 /* reserved pragma bit */ |
| 108 | #define BCOM_PRAGMA_BIT_PRECISE_INC 6 /* increment 0=when possible, */ |
| 109 | /* 1=iter end */ |
| 110 | #define BCOM_PRAGMA_BIT_RST_ERROR_NO 5 /* don't reset errors on */ |
| 111 | /* task enable */ |
| 112 | #define BCOM_PRAGMA_BIT_PACK 4 /* pack data enable */ |
| 113 | #define BCOM_PRAGMA_BIT_INTEGER 3 /* data alignment */ |
| 114 | /* 0=frac(msb), 1=int(lsb) */ |
| 115 | #define BCOM_PRAGMA_BIT_SPECREAD 2 /* XLB speculative read */ |
| 116 | #define BCOM_PRAGMA_BIT_CW 1 /* write line buffer enable */ |
| 117 | #define BCOM_PRAGMA_BIT_RL 0 /* read line buffer enable */ |
| 118 | |
| 119 | /* Looks like XLB speculative read generates XLB errors when a buffer |
| 120 | * is at the end of the physical memory. i.e. when accessing the |
| 121 | * lasts words, the engine tries to prefetch the next but there is no |
| 122 | * next ... |
| 123 | */ |
| 124 | #define BCOM_STD_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \ |
| 125 | (0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \ |
| 126 | (0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \ |
| 127 | (0 << BCOM_PRAGMA_BIT_PACK) | \ |
| 128 | (0 << BCOM_PRAGMA_BIT_INTEGER) | \ |
| 129 | (0 << BCOM_PRAGMA_BIT_SPECREAD) | \ |
| 130 | (1 << BCOM_PRAGMA_BIT_CW) | \ |
| 131 | (1 << BCOM_PRAGMA_BIT_RL)) |
| 132 | |
| 133 | #define BCOM_PCI_PRAGMA ((0 << BCOM_PRAGMA_BIT_RSV) | \ |
| 134 | (0 << BCOM_PRAGMA_BIT_PRECISE_INC) | \ |
| 135 | (0 << BCOM_PRAGMA_BIT_RST_ERROR_NO) | \ |
| 136 | (0 << BCOM_PRAGMA_BIT_PACK) | \ |
| 137 | (1 << BCOM_PRAGMA_BIT_INTEGER) | \ |
| 138 | (0 << BCOM_PRAGMA_BIT_SPECREAD) | \ |
| 139 | (1 << BCOM_PRAGMA_BIT_CW) | \ |
| 140 | (1 << BCOM_PRAGMA_BIT_RL)) |
| 141 | |
| 142 | #define BCOM_ATA_PRAGMA BCOM_STD_PRAGMA |
| 143 | #define BCOM_CRC16_DP_0_PRAGMA BCOM_STD_PRAGMA |
| 144 | #define BCOM_CRC16_DP_1_PRAGMA BCOM_STD_PRAGMA |
| 145 | #define BCOM_FEC_RX_BD_PRAGMA BCOM_STD_PRAGMA |
| 146 | #define BCOM_FEC_TX_BD_PRAGMA BCOM_STD_PRAGMA |
| 147 | #define BCOM_GEN_DP_0_PRAGMA BCOM_STD_PRAGMA |
| 148 | #define BCOM_GEN_DP_1_PRAGMA BCOM_STD_PRAGMA |
| 149 | #define BCOM_GEN_DP_2_PRAGMA BCOM_STD_PRAGMA |
| 150 | #define BCOM_GEN_DP_3_PRAGMA BCOM_STD_PRAGMA |
| 151 | #define BCOM_GEN_DP_BD_0_PRAGMA BCOM_STD_PRAGMA |
| 152 | #define BCOM_GEN_DP_BD_1_PRAGMA BCOM_STD_PRAGMA |
| 153 | #define BCOM_GEN_RX_BD_PRAGMA BCOM_STD_PRAGMA |
| 154 | #define BCOM_GEN_TX_BD_PRAGMA BCOM_STD_PRAGMA |
| 155 | #define BCOM_GEN_LPC_PRAGMA BCOM_STD_PRAGMA |
| 156 | #define BCOM_PCI_RX_PRAGMA BCOM_PCI_PRAGMA |
| 157 | #define BCOM_PCI_TX_PRAGMA BCOM_PCI_PRAGMA |
| 158 | |
| 159 | /* Initiators number */ |
| 160 | #define BCOM_INITIATOR_ALWAYS 0 |
| 161 | #define BCOM_INITIATOR_SCTMR_0 1 |
| 162 | #define BCOM_INITIATOR_SCTMR_1 2 |
| 163 | #define BCOM_INITIATOR_FEC_RX 3 |
| 164 | #define BCOM_INITIATOR_FEC_TX 4 |
| 165 | #define BCOM_INITIATOR_ATA_RX 5 |
| 166 | #define BCOM_INITIATOR_ATA_TX 6 |
| 167 | #define BCOM_INITIATOR_SCPCI_RX 7 |
| 168 | #define BCOM_INITIATOR_SCPCI_TX 8 |
| 169 | #define BCOM_INITIATOR_PSC3_RX 9 |
| 170 | #define BCOM_INITIATOR_PSC3_TX 10 |
| 171 | #define BCOM_INITIATOR_PSC2_RX 11 |
| 172 | #define BCOM_INITIATOR_PSC2_TX 12 |
| 173 | #define BCOM_INITIATOR_PSC1_RX 13 |
| 174 | #define BCOM_INITIATOR_PSC1_TX 14 |
| 175 | #define BCOM_INITIATOR_SCTMR_2 15 |
| 176 | #define BCOM_INITIATOR_SCLPC 16 |
| 177 | #define BCOM_INITIATOR_PSC5_RX 17 |
| 178 | #define BCOM_INITIATOR_PSC5_TX 18 |
| 179 | #define BCOM_INITIATOR_PSC4_RX 19 |
| 180 | #define BCOM_INITIATOR_PSC4_TX 20 |
| 181 | #define BCOM_INITIATOR_I2C2_RX 21 |
| 182 | #define BCOM_INITIATOR_I2C2_TX 22 |
| 183 | #define BCOM_INITIATOR_I2C1_RX 23 |
| 184 | #define BCOM_INITIATOR_I2C1_TX 24 |
| 185 | #define BCOM_INITIATOR_PSC6_RX 25 |
| 186 | #define BCOM_INITIATOR_PSC6_TX 26 |
| 187 | #define BCOM_INITIATOR_IRDA_RX 25 |
| 188 | #define BCOM_INITIATOR_IRDA_TX 26 |
| 189 | #define BCOM_INITIATOR_SCTMR_3 27 |
| 190 | #define BCOM_INITIATOR_SCTMR_4 28 |
| 191 | #define BCOM_INITIATOR_SCTMR_5 29 |
| 192 | #define BCOM_INITIATOR_SCTMR_6 30 |
| 193 | #define BCOM_INITIATOR_SCTMR_7 31 |
| 194 | |
| 195 | /* Initiators priorities */ |
| 196 | #define BCOM_IPR_ALWAYS 7 |
| 197 | #define BCOM_IPR_SCTMR_0 2 |
| 198 | #define BCOM_IPR_SCTMR_1 2 |
| 199 | #define BCOM_IPR_FEC_RX 6 |
| 200 | #define BCOM_IPR_FEC_TX 5 |
Tim Yamin | e4efe3c | 2008-12-21 02:54:28 -0700 | [diff] [blame] | 201 | #define BCOM_IPR_ATA_RX 7 |
| 202 | #define BCOM_IPR_ATA_TX 7 |
Sylvain Munaut | 2f9ea1b | 2007-09-16 20:53:27 +1000 | [diff] [blame] | 203 | #define BCOM_IPR_SCPCI_RX 2 |
| 204 | #define BCOM_IPR_SCPCI_TX 2 |
| 205 | #define BCOM_IPR_PSC3_RX 2 |
| 206 | #define BCOM_IPR_PSC3_TX 2 |
| 207 | #define BCOM_IPR_PSC2_RX 2 |
| 208 | #define BCOM_IPR_PSC2_TX 2 |
| 209 | #define BCOM_IPR_PSC1_RX 2 |
| 210 | #define BCOM_IPR_PSC1_TX 2 |
| 211 | #define BCOM_IPR_SCTMR_2 2 |
| 212 | #define BCOM_IPR_SCLPC 2 |
| 213 | #define BCOM_IPR_PSC5_RX 2 |
| 214 | #define BCOM_IPR_PSC5_TX 2 |
| 215 | #define BCOM_IPR_PSC4_RX 2 |
| 216 | #define BCOM_IPR_PSC4_TX 2 |
| 217 | #define BCOM_IPR_I2C2_RX 2 |
| 218 | #define BCOM_IPR_I2C2_TX 2 |
| 219 | #define BCOM_IPR_I2C1_RX 2 |
| 220 | #define BCOM_IPR_I2C1_TX 2 |
| 221 | #define BCOM_IPR_PSC6_RX 2 |
| 222 | #define BCOM_IPR_PSC6_TX 2 |
| 223 | #define BCOM_IPR_IRDA_RX 2 |
| 224 | #define BCOM_IPR_IRDA_TX 2 |
| 225 | #define BCOM_IPR_SCTMR_3 2 |
| 226 | #define BCOM_IPR_SCTMR_4 2 |
| 227 | #define BCOM_IPR_SCTMR_5 2 |
| 228 | #define BCOM_IPR_SCTMR_6 2 |
| 229 | #define BCOM_IPR_SCTMR_7 2 |
| 230 | |
| 231 | |
| 232 | /* ======================================================================== */ |
| 233 | /* API */ |
| 234 | /* ======================================================================== */ |
| 235 | |
| 236 | extern struct bcom_task *bcom_task_alloc(int bd_count, int bd_size, int priv_size); |
| 237 | extern void bcom_task_free(struct bcom_task *tsk); |
| 238 | extern int bcom_load_image(int task, u32 *task_image); |
| 239 | extern void bcom_set_initiator(int task, int initiator); |
| 240 | |
| 241 | |
| 242 | #define TASK_ENABLE 0x8000 |
| 243 | |
Grant Likely | aaab5e8 | 2008-12-21 02:54:28 -0700 | [diff] [blame] | 244 | /** |
| 245 | * bcom_disable_prefetch - Hook to disable bus prefetching |
| 246 | * |
| 247 | * ATA DMA and the original MPC5200 need this due to silicon bugs. At the |
| 248 | * moment disabling prefetch is a one-way street. There is no mechanism |
| 249 | * in place to turn prefetch back on after it has been disabled. There is |
| 250 | * no reason it couldn't be done, it would just be more complex to implement. |
| 251 | */ |
| 252 | static inline void bcom_disable_prefetch(void) |
| 253 | { |
| 254 | u16 regval; |
| 255 | |
| 256 | regval = in_be16(&bcom_eng->regs->PtdCntrl); |
| 257 | out_be16(&bcom_eng->regs->PtdCntrl, regval | 1); |
| 258 | }; |
| 259 | |
Sylvain Munaut | 2f9ea1b | 2007-09-16 20:53:27 +1000 | [diff] [blame] | 260 | static inline void |
| 261 | bcom_enable_task(int task) |
| 262 | { |
| 263 | u16 reg; |
| 264 | reg = in_be16(&bcom_eng->regs->tcr[task]); |
| 265 | out_be16(&bcom_eng->regs->tcr[task], reg | TASK_ENABLE); |
| 266 | } |
| 267 | |
| 268 | static inline void |
| 269 | bcom_disable_task(int task) |
| 270 | { |
| 271 | u16 reg = in_be16(&bcom_eng->regs->tcr[task]); |
| 272 | out_be16(&bcom_eng->regs->tcr[task], reg & ~TASK_ENABLE); |
| 273 | } |
| 274 | |
| 275 | |
| 276 | static inline u32 * |
| 277 | bcom_task_desc(int task) |
| 278 | { |
| 279 | return bcom_sram_pa2va(bcom_eng->tdt[task].start); |
| 280 | } |
| 281 | |
| 282 | static inline int |
| 283 | bcom_task_num_descs(int task) |
| 284 | { |
| 285 | return (bcom_eng->tdt[task].stop - bcom_eng->tdt[task].start)/sizeof(u32) + 1; |
| 286 | } |
| 287 | |
| 288 | static inline u32 * |
| 289 | bcom_task_var(int task) |
| 290 | { |
| 291 | return bcom_sram_pa2va(bcom_eng->tdt[task].var); |
| 292 | } |
| 293 | |
| 294 | static inline u32 * |
| 295 | bcom_task_inc(int task) |
| 296 | { |
| 297 | return &bcom_task_var(task)[BCOM_MAX_VAR]; |
| 298 | } |
| 299 | |
| 300 | |
| 301 | static inline int |
| 302 | bcom_drd_is_extended(u32 desc) |
| 303 | { |
| 304 | return (desc) & BCOM_DRD_EXTENDED; |
| 305 | } |
| 306 | |
| 307 | static inline int |
| 308 | bcom_desc_is_drd(u32 desc) |
| 309 | { |
| 310 | return !(desc & BCOM_LCD_MASK) && desc != BCOM_DESC_NOP; |
| 311 | } |
| 312 | |
| 313 | static inline int |
| 314 | bcom_desc_initiator(u32 desc) |
| 315 | { |
| 316 | return (desc >> BCOM_DRD_INITIATOR_SHIFT) & 0x1f; |
| 317 | } |
| 318 | |
| 319 | static inline void |
| 320 | bcom_set_desc_initiator(u32 *desc, int initiator) |
| 321 | { |
| 322 | *desc = (*desc & ~(0x1f << BCOM_DRD_INITIATOR_SHIFT)) | |
| 323 | ((initiator & 0x1f) << BCOM_DRD_INITIATOR_SHIFT); |
| 324 | } |
| 325 | |
| 326 | |
| 327 | static inline void |
| 328 | bcom_set_task_pragma(int task, int pragma) |
| 329 | { |
| 330 | u32 *fdt = &bcom_eng->tdt[task].fdt; |
| 331 | *fdt = (*fdt & ~0xff) | pragma; |
| 332 | } |
| 333 | |
| 334 | static inline void |
| 335 | bcom_set_task_auto_start(int task, int next_task) |
| 336 | { |
| 337 | u16 __iomem *tcr = &bcom_eng->regs->tcr[task]; |
| 338 | out_be16(tcr, (in_be16(tcr) & ~0xff) | 0x00c0 | next_task); |
| 339 | } |
| 340 | |
| 341 | static inline void |
| 342 | bcom_set_tcr_initiator(int task, int initiator) |
| 343 | { |
| 344 | u16 __iomem *tcr = &bcom_eng->regs->tcr[task]; |
| 345 | out_be16(tcr, (in_be16(tcr) & ~0x1f00) | ((initiator & 0x1f) << 8)); |
| 346 | } |
| 347 | |
| 348 | |
| 349 | #endif /* __BESTCOMM_PRIV_H__ */ |
| 350 | |