Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
torvalds
GitHub Repository: torvalds/linux
Path: blob/master/drivers/dma/bestcomm/ata.c
26282 views
1
// SPDX-License-Identifier: GPL-2.0-only
2
/*
3
* Bestcomm ATA task driver
4
*
5
* Patterned after bestcomm/fec.c by Dale Farnsworth <[email protected]>
6
* 2003-2004 (c) MontaVista, Software, Inc.
7
*
8
* Copyright (C) 2006-2007 Sylvain Munaut <[email protected]>
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
154