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 */ 27extern u32 bcom_ata_task[]; 28 29/* ata task vars that need to be set before enabling the task */ 30struct 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 */ 39struct 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 53struct bcom_task * 54bcom_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} 97EXPORT_SYMBOL_GPL(bcom_ata_init); 98 99void 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} 111EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare); 112 113void 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} 125EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare); 126 127void 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} 140EXPORT_SYMBOL_GPL(bcom_ata_reset_bd); 141 142void bcom_ata_release(struct bcom_task *tsk) 143{ 144 /* Nothing special for the ATA tasks */ 145 bcom_task_free(tsk); 146} 147EXPORT_SYMBOL_GPL(bcom_ata_release); 148 149 150MODULE_DESCRIPTION("BestComm ATA task driver"); 151MODULE_AUTHOR("John Rigby"); 152MODULE_LICENSE("GPL v2"); 153