1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Bestcomm ATA task driver 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 12 #include <linux/kernel.h> 13 #include <linux/module.h> 14 #include <linux/types.h> 15 #include <asm/io.h> 16 17 #include <linux/fsl/bestcomm/bestcomm.h> 18 #include <linux/fsl/bestcomm/bestcomm_priv.h> 19 #include <linux/fsl/bestcomm/ata.h> 20 21 22 /* ======================================================================== */ 23 /* Task image/var/inc */ 24 /* ======================================================================== */ 25 26 /* ata task image */ 27 extern u32 bcom_ata_task[]; 28 29 /* ata task vars that need to be set before enabling the task */ 30 struct bcom_ata_var { 31 u32 enable; /* (u16*) address of task's control register */ 32 u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */ 33 u32 bd_last; /* (struct bcom_bd*) end of ring buffer */ 34 u32 bd_start; /* (struct bcom_bd*) current bd */ 35 u32 buffer_size; /* size of receive buffer */ 36 }; 37 38 /* ata task incs that need to be set before enabling the task */ 39 struct bcom_ata_inc { 40 u16 pad0; 41 s16 incr_bytes; 42 u16 pad1; 43 s16 incr_dst; 44 u16 pad2; 45 s16 incr_src; 46 }; 47 48 49 /* ======================================================================== */ 50 /* Task support code */ 51 /* ======================================================================== */ 52 53 struct bcom_task * 54 bcom_ata_init(int queue_len, int maxbufsize) 55 { 56 struct bcom_task *tsk; 57 struct bcom_ata_var *var; 58 struct bcom_ata_inc *inc; 59 60 /* Prefetch breaks ATA DMA. Turn it off for ATA DMA */ 61 bcom_disable_prefetch(); 62 63 tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0); 64 if (!tsk) 65 return NULL; 66 67 tsk->flags = BCOM_FLAGS_NONE; 68 69 bcom_ata_reset_bd(tsk); 70 71 var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum); 72 inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 73 74 if (bcom_load_image(tsk->tasknum, bcom_ata_task)) { 75 bcom_task_free(tsk); 76 return NULL; 77 } 78 79 var->enable = bcom_eng->regs_base + 80 offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]); 81 var->bd_base = tsk->bd_pa; 82 var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size); 83 var->bd_start = tsk->bd_pa; 84 var->buffer_size = maxbufsize; 85 86 /* Configure some stuff */ 87 bcom_set_task_pragma(tsk->tasknum, BCOM_ATA_PRAGMA); 88 bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum); 89 90 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_RX], BCOM_IPR_ATA_RX); 91 out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_TX], BCOM_IPR_ATA_TX); 92 93 out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */ 94 95 return tsk; 96 } 97 EXPORT_SYMBOL_GPL(bcom_ata_init); 98 99 void bcom_ata_rx_prepare(struct bcom_task *tsk) 100 { 101 struct bcom_ata_inc *inc; 102 103 inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 104 105 inc->incr_bytes = -(s16)sizeof(u32); 106 inc->incr_src = 0; 107 inc->incr_dst = sizeof(u32); 108 109 bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_RX); 110 } 111 EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare); 112 113 void bcom_ata_tx_prepare(struct bcom_task *tsk) 114 { 115 struct bcom_ata_inc *inc; 116 117 inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 118 119 inc->incr_bytes = -(s16)sizeof(u32); 120 inc->incr_src = sizeof(u32); 121 inc->incr_dst = 0; 122 123 bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_TX); 124 } 125 EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare); 126 127 void bcom_ata_reset_bd(struct bcom_task *tsk) 128 { 129 struct bcom_ata_var *var; 130 131 /* Reset all BD */ 132 memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); 133 134 tsk->index = 0; 135 tsk->outdex = 0; 136 137 var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum); 138 var->bd_start = var->bd_base; 139 } 140 EXPORT_SYMBOL_GPL(bcom_ata_reset_bd); 141 142 void bcom_ata_release(struct bcom_task *tsk) 143 { 144 /* Nothing special for the ATA tasks */ 145 bcom_task_free(tsk); 146 } 147 EXPORT_SYMBOL_GPL(bcom_ata_release); 148 149 150 MODULE_DESCRIPTION("BestComm ATA task driver"); 151 MODULE_AUTHOR("John Rigby"); 152 MODULE_LICENSE("GPL v2"); 153