Orange Pi5 kernel

Deprecated Linux kernel 5.10.110 for OrangePi 5/5B/5+ boards

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