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 100 /* Descriptors structure & co */ 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 201 #define BCOM_IPR_ATA_RX 7 202 #define BCOM_IPR_ATA_TX 7 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 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 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 351