Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

[POWERPC] bestcomm: ATA task support

This is the microcode for the ATA task and the associated
support code.

The microcode itself comes directly from the offical
API (v2.2)

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Signed-off-by: Grant Likely <grant.likely@secretlab.ca>

authored by

Sylvain Munaut and committed by
Grant Likely
9ea68df5 2f9ea1bd

+267
+7
arch/powerpc/sysdev/bestcomm/Kconfig
··· 16 16 If you want to use drivers that require DMA operations, 17 17 answer Y or M. Otherwise say N. 18 18 19 + config PPC_BESTCOMM_ATA 20 + tristate "Bestcomm ATA task support" 21 + depends on PPC_BESTCOMM 22 + default n 23 + help 24 + This option enables the support for the ATA task. 25 +
+2
arch/powerpc/sysdev/bestcomm/Makefile
··· 3 3 # 4 4 5 5 bestcomm-core-objs := bestcomm.o sram.o 6 + bestcomm-ata-objs := ata.o bcom_ata_task.o 6 7 7 8 obj-$(CONFIG_PPC_BESTCOMM) += bestcomm-core.o 9 + obj-$(CONFIG_PPC_BESTCOMM_ATA) += bestcomm-ata.o 8 10
+154
arch/powerpc/sysdev/bestcomm/ata.c
··· 1 + /* 2 + * Bestcomm ATA task driver 3 + * 4 + * 5 + * Patterned after bestcomm/fec.c by Dale Farnsworth <dfarnsworth@mvista.com> 6 + * 2003-2004 (c) MontaVista, Software, Inc. 7 + * 8 + * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com> 9 + * Copyright (C) 2006 Freescale - John Rigby 10 + * 11 + * This file is licensed under the terms of the GNU General Public License 12 + * version 2. This program is licensed "as is" without any warranty of any 13 + * kind, whether express or implied. 14 + */ 15 + 16 + #include <linux/kernel.h> 17 + #include <linux/module.h> 18 + #include <linux/types.h> 19 + #include <asm/io.h> 20 + 21 + #include "bestcomm.h" 22 + #include "bestcomm_priv.h" 23 + #include "ata.h" 24 + 25 + 26 + /* ======================================================================== */ 27 + /* Task image/var/inc */ 28 + /* ======================================================================== */ 29 + 30 + /* ata task image */ 31 + extern u32 bcom_ata_task[]; 32 + 33 + /* ata task vars that need to be set before enabling the task */ 34 + struct bcom_ata_var { 35 + u32 enable; /* (u16*) address of task's control register */ 36 + u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */ 37 + u32 bd_last; /* (struct bcom_bd*) end of ring buffer */ 38 + u32 bd_start; /* (struct bcom_bd*) current bd */ 39 + u32 buffer_size; /* size of receive buffer */ 40 + }; 41 + 42 + /* ata task incs that need to be set before enabling the task */ 43 + struct bcom_ata_inc { 44 + u16 pad0; 45 + s16 incr_bytes; 46 + u16 pad1; 47 + s16 incr_dst; 48 + u16 pad2; 49 + s16 incr_src; 50 + }; 51 + 52 + 53 + /* ======================================================================== */ 54 + /* Task support code */ 55 + /* ======================================================================== */ 56 + 57 + struct bcom_task * 58 + bcom_ata_init(int queue_len, int maxbufsize) 59 + { 60 + struct bcom_task *tsk; 61 + struct bcom_ata_var *var; 62 + struct bcom_ata_inc *inc; 63 + 64 + tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0); 65 + if (!tsk) 66 + return NULL; 67 + 68 + tsk->flags = BCOM_FLAGS_NONE; 69 + 70 + bcom_ata_reset_bd(tsk); 71 + 72 + var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum); 73 + inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 74 + 75 + if (bcom_load_image(tsk->tasknum, bcom_ata_task)) { 76 + bcom_task_free(tsk); 77 + return NULL; 78 + } 79 + 80 + var->enable = bcom_eng->regs_base + 81 + offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]); 82 + var->bd_base = tsk->bd_pa; 83 + var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size); 84 + var->bd_start = tsk->bd_pa; 85 + var->buffer_size = maxbufsize; 86 + 87 + /* Configure some stuff */ 88 + bcom_set_task_pragma(tsk->tasknum, BCOM_ATA_PRAGMA); 89 + bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum); 90 + 91 + out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_RX], BCOM_IPR_ATA_RX); 92 + out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_TX], BCOM_IPR_ATA_TX); 93 + 94 + out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */ 95 + 96 + return tsk; 97 + } 98 + EXPORT_SYMBOL_GPL(bcom_ata_init); 99 + 100 + void bcom_ata_rx_prepare(struct bcom_task *tsk) 101 + { 102 + struct bcom_ata_inc *inc; 103 + 104 + inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 105 + 106 + inc->incr_bytes = -(s16)sizeof(u32); 107 + inc->incr_src = 0; 108 + inc->incr_dst = sizeof(u32); 109 + 110 + bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_RX); 111 + } 112 + EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare); 113 + 114 + void bcom_ata_tx_prepare(struct bcom_task *tsk) 115 + { 116 + struct bcom_ata_inc *inc; 117 + 118 + inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 119 + 120 + inc->incr_bytes = -(s16)sizeof(u32); 121 + inc->incr_src = sizeof(u32); 122 + inc->incr_dst = 0; 123 + 124 + bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_TX); 125 + } 126 + EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare); 127 + 128 + void bcom_ata_reset_bd(struct bcom_task *tsk) 129 + { 130 + struct bcom_ata_var *var; 131 + 132 + /* Reset all BD */ 133 + memset(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); 134 + 135 + tsk->index = 0; 136 + tsk->outdex = 0; 137 + 138 + var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum); 139 + var->bd_start = var->bd_base; 140 + } 141 + EXPORT_SYMBOL_GPL(bcom_ata_reset_bd); 142 + 143 + void bcom_ata_release(struct bcom_task *tsk) 144 + { 145 + /* Nothing special for the ATA tasks */ 146 + bcom_task_free(tsk); 147 + } 148 + EXPORT_SYMBOL_GPL(bcom_ata_release); 149 + 150 + 151 + MODULE_DESCRIPTION("BestComm ATA task driver"); 152 + MODULE_AUTHOR("John Rigby"); 153 + MODULE_LICENSE("GPL v2"); 154 +
+37
arch/powerpc/sysdev/bestcomm/ata.h
··· 1 + /* 2 + * Header for Bestcomm ATA task driver 3 + * 4 + * 5 + * Copyright (C) 2006 Freescale - John Rigby 6 + * Copyright (C) 2006 Sylvain Munaut <tnt@246tNt.com> 7 + * 8 + * This file is licensed under the terms of the GNU General Public License 9 + * version 2. This program is licensed "as is" without any warranty of any 10 + * kind, whether express or implied. 11 + */ 12 + 13 + #ifndef __BESTCOMM_ATA_H__ 14 + #define __BESTCOMM_ATA_H__ 15 + 16 + 17 + struct bcom_ata_bd { 18 + u32 status; 19 + u32 dst_pa; 20 + u32 src_pa; 21 + }; 22 + 23 + extern struct bcom_task * 24 + bcom_ata_init(int queue_len, int maxbufsize); 25 + 26 + extern void 27 + bcom_ata_rx_prepare(struct bcom_task *tsk); 28 + 29 + extern void 30 + bcom_ata_tx_prepare(struct bcom_task *tsk); 31 + 32 + extern void 33 + bcom_ata_reset_bd(struct bcom_task *tsk); 34 + 35 + 36 + #endif /* __BESTCOMM_ATA_H__ */ 37 +
+67
arch/powerpc/sysdev/bestcomm/bcom_ata_task.c
··· 1 + /* 2 + * Bestcomm ATA task microcode 3 + * 4 + * Copyright (c) 2004 Freescale Semiconductor, Inc. 5 + * 6 + * This program is free software; you can redistribute it and/or modify it 7 + * under the terms of the GNU General Public License version 2 as published 8 + * by the Free Software Foundation. 9 + * 10 + * Created based on bestcom/code_dma/image_rtos1/dma_image.hex 11 + */ 12 + 13 + #include <asm/types.h> 14 + 15 + /* 16 + * The header consists of the following fields: 17 + * u32 magic; 18 + * u8 desc_size; 19 + * u8 var_size; 20 + * u8 inc_size; 21 + * u8 first_var; 22 + * u8 reserved[8]; 23 + * 24 + * The size fields contain the number of 32-bit words. 25 + */ 26 + 27 + u32 bcom_ata_task[] = { 28 + /* header */ 29 + 0x4243544b, 30 + 0x0e060709, 31 + 0x00000000, 32 + 0x00000000, 33 + 34 + /* Task descriptors */ 35 + 0x8198009b, /* LCD: idx0 = var3; idx0 <= var2; idx0 += inc3 */ 36 + 0x13e00c08, /* DRD1A: var3 = var1; FN=0 MORE init=31 WS=0 RS=0 */ 37 + 0xb8000264, /* LCD: idx1 = *idx0, idx2 = var0; idx1 < var9; idx1 += inc4, idx2 += inc4 */ 38 + 0x10000f00, /* DRD1A: var3 = idx0; FN=0 MORE init=0 WS=0 RS=0 */ 39 + 0x60140002, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=2 EXT init=0 WS=2 RS=2 */ 40 + 0x0c8cfc8a, /* DRD2B1: *idx2 = EU3(); EU3(*idx2,var10) */ 41 + 0xd8988240, /* LCDEXT: idx1 = idx1; idx1 > var9; idx1 += inc0 */ 42 + 0xf845e011, /* LCDEXT: idx2 = *(idx0 + var00000015); ; idx2 += inc2 */ 43 + 0xb845e00a, /* LCD: idx3 = *(idx0 + var00000019); ; idx3 += inc1 */ 44 + 0x0bfecf90, /* DRD1A: *idx3 = *idx2; FN=0 TFD init=31 WS=3 RS=3 */ 45 + 0x9898802d, /* LCD: idx1 = idx1; idx1 once var0; idx1 += inc5 */ 46 + 0x64000005, /* DRD2A: EU0=0 EU1=0 EU2=0 EU3=5 INT EXT init=0 WS=0 RS=0 */ 47 + 0x0c0cf849, /* DRD2B1: *idx0 = EU3(); EU3(idx1,var9) */ 48 + 0x000001f8, /* NOP */ 49 + 50 + /* VAR[9]-VAR[14] */ 51 + 0x40000000, 52 + 0x7fff7fff, 53 + 0x00000000, 54 + 0x00000000, 55 + 0x00000000, 56 + 0x00000000, 57 + 58 + /* INC[0]-INC[6] */ 59 + 0x40000000, 60 + 0xe0000000, 61 + 0xe0000000, 62 + 0xa000000c, 63 + 0x20000000, 64 + 0x00000000, 65 + 0x00000000, 66 + }; 67 +