19a322993SPhilippe De Muyter /* 29a322993SPhilippe De Muyter * Bestcomm ATA task driver 39a322993SPhilippe De Muyter * 49a322993SPhilippe De Muyter * 59a322993SPhilippe De Muyter * Patterned after bestcomm/fec.c by Dale Farnsworth <dfarnsworth@mvista.com> 69a322993SPhilippe De Muyter * 2003-2004 (c) MontaVista, Software, Inc. 79a322993SPhilippe De Muyter * 89a322993SPhilippe De Muyter * Copyright (C) 2006-2007 Sylvain Munaut <tnt@246tNt.com> 99a322993SPhilippe De Muyter * Copyright (C) 2006 Freescale - John Rigby 109a322993SPhilippe De Muyter * 119a322993SPhilippe De Muyter * This file is licensed under the terms of the GNU General Public License 129a322993SPhilippe De Muyter * version 2. This program is licensed "as is" without any warranty of any 139a322993SPhilippe De Muyter * kind, whether express or implied. 149a322993SPhilippe De Muyter */ 159a322993SPhilippe De Muyter 169a322993SPhilippe De Muyter #include <linux/kernel.h> 179a322993SPhilippe De Muyter #include <linux/module.h> 189a322993SPhilippe De Muyter #include <linux/types.h> 199a322993SPhilippe De Muyter #include <asm/io.h> 209a322993SPhilippe De Muyter 219a322993SPhilippe De Muyter #include <linux/fsl/bestcomm/bestcomm.h> 229a322993SPhilippe De Muyter #include <linux/fsl/bestcomm/bestcomm_priv.h> 239a322993SPhilippe De Muyter #include <linux/fsl/bestcomm/ata.h> 249a322993SPhilippe De Muyter 259a322993SPhilippe De Muyter 269a322993SPhilippe De Muyter /* ======================================================================== */ 279a322993SPhilippe De Muyter /* Task image/var/inc */ 289a322993SPhilippe De Muyter /* ======================================================================== */ 299a322993SPhilippe De Muyter 309a322993SPhilippe De Muyter /* ata task image */ 319a322993SPhilippe De Muyter extern u32 bcom_ata_task[]; 329a322993SPhilippe De Muyter 339a322993SPhilippe De Muyter /* ata task vars that need to be set before enabling the task */ 349a322993SPhilippe De Muyter struct bcom_ata_var { 359a322993SPhilippe De Muyter u32 enable; /* (u16*) address of task's control register */ 369a322993SPhilippe De Muyter u32 bd_base; /* (struct bcom_bd*) beginning of ring buffer */ 379a322993SPhilippe De Muyter u32 bd_last; /* (struct bcom_bd*) end of ring buffer */ 389a322993SPhilippe De Muyter u32 bd_start; /* (struct bcom_bd*) current bd */ 399a322993SPhilippe De Muyter u32 buffer_size; /* size of receive buffer */ 409a322993SPhilippe De Muyter }; 419a322993SPhilippe De Muyter 429a322993SPhilippe De Muyter /* ata task incs that need to be set before enabling the task */ 439a322993SPhilippe De Muyter struct bcom_ata_inc { 449a322993SPhilippe De Muyter u16 pad0; 459a322993SPhilippe De Muyter s16 incr_bytes; 469a322993SPhilippe De Muyter u16 pad1; 479a322993SPhilippe De Muyter s16 incr_dst; 489a322993SPhilippe De Muyter u16 pad2; 499a322993SPhilippe De Muyter s16 incr_src; 509a322993SPhilippe De Muyter }; 519a322993SPhilippe De Muyter 529a322993SPhilippe De Muyter 539a322993SPhilippe De Muyter /* ======================================================================== */ 549a322993SPhilippe De Muyter /* Task support code */ 559a322993SPhilippe De Muyter /* ======================================================================== */ 569a322993SPhilippe De Muyter 579a322993SPhilippe De Muyter struct bcom_task * 589a322993SPhilippe De Muyter bcom_ata_init(int queue_len, int maxbufsize) 599a322993SPhilippe De Muyter { 609a322993SPhilippe De Muyter struct bcom_task *tsk; 619a322993SPhilippe De Muyter struct bcom_ata_var *var; 629a322993SPhilippe De Muyter struct bcom_ata_inc *inc; 639a322993SPhilippe De Muyter 649a322993SPhilippe De Muyter /* Prefetch breaks ATA DMA. Turn it off for ATA DMA */ 659a322993SPhilippe De Muyter bcom_disable_prefetch(); 669a322993SPhilippe De Muyter 679a322993SPhilippe De Muyter tsk = bcom_task_alloc(queue_len, sizeof(struct bcom_ata_bd), 0); 689a322993SPhilippe De Muyter if (!tsk) 699a322993SPhilippe De Muyter return NULL; 709a322993SPhilippe De Muyter 719a322993SPhilippe De Muyter tsk->flags = BCOM_FLAGS_NONE; 729a322993SPhilippe De Muyter 739a322993SPhilippe De Muyter bcom_ata_reset_bd(tsk); 749a322993SPhilippe De Muyter 759a322993SPhilippe De Muyter var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum); 769a322993SPhilippe De Muyter inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 779a322993SPhilippe De Muyter 789a322993SPhilippe De Muyter if (bcom_load_image(tsk->tasknum, bcom_ata_task)) { 799a322993SPhilippe De Muyter bcom_task_free(tsk); 809a322993SPhilippe De Muyter return NULL; 819a322993SPhilippe De Muyter } 829a322993SPhilippe De Muyter 839a322993SPhilippe De Muyter var->enable = bcom_eng->regs_base + 849a322993SPhilippe De Muyter offsetof(struct mpc52xx_sdma, tcr[tsk->tasknum]); 859a322993SPhilippe De Muyter var->bd_base = tsk->bd_pa; 869a322993SPhilippe De Muyter var->bd_last = tsk->bd_pa + ((tsk->num_bd-1) * tsk->bd_size); 879a322993SPhilippe De Muyter var->bd_start = tsk->bd_pa; 889a322993SPhilippe De Muyter var->buffer_size = maxbufsize; 899a322993SPhilippe De Muyter 909a322993SPhilippe De Muyter /* Configure some stuff */ 919a322993SPhilippe De Muyter bcom_set_task_pragma(tsk->tasknum, BCOM_ATA_PRAGMA); 929a322993SPhilippe De Muyter bcom_set_task_auto_start(tsk->tasknum, tsk->tasknum); 939a322993SPhilippe De Muyter 949a322993SPhilippe De Muyter out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_RX], BCOM_IPR_ATA_RX); 959a322993SPhilippe De Muyter out_8(&bcom_eng->regs->ipr[BCOM_INITIATOR_ATA_TX], BCOM_IPR_ATA_TX); 969a322993SPhilippe De Muyter 979a322993SPhilippe De Muyter out_be32(&bcom_eng->regs->IntPend, 1<<tsk->tasknum); /* Clear ints */ 989a322993SPhilippe De Muyter 999a322993SPhilippe De Muyter return tsk; 1009a322993SPhilippe De Muyter } 1019a322993SPhilippe De Muyter EXPORT_SYMBOL_GPL(bcom_ata_init); 1029a322993SPhilippe De Muyter 1039a322993SPhilippe De Muyter void bcom_ata_rx_prepare(struct bcom_task *tsk) 1049a322993SPhilippe De Muyter { 1059a322993SPhilippe De Muyter struct bcom_ata_inc *inc; 1069a322993SPhilippe De Muyter 1079a322993SPhilippe De Muyter inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 1089a322993SPhilippe De Muyter 1099a322993SPhilippe De Muyter inc->incr_bytes = -(s16)sizeof(u32); 1109a322993SPhilippe De Muyter inc->incr_src = 0; 1119a322993SPhilippe De Muyter inc->incr_dst = sizeof(u32); 1129a322993SPhilippe De Muyter 1139a322993SPhilippe De Muyter bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_RX); 1149a322993SPhilippe De Muyter } 1159a322993SPhilippe De Muyter EXPORT_SYMBOL_GPL(bcom_ata_rx_prepare); 1169a322993SPhilippe De Muyter 1179a322993SPhilippe De Muyter void bcom_ata_tx_prepare(struct bcom_task *tsk) 1189a322993SPhilippe De Muyter { 1199a322993SPhilippe De Muyter struct bcom_ata_inc *inc; 1209a322993SPhilippe De Muyter 1219a322993SPhilippe De Muyter inc = (struct bcom_ata_inc *) bcom_task_inc(tsk->tasknum); 1229a322993SPhilippe De Muyter 1239a322993SPhilippe De Muyter inc->incr_bytes = -(s16)sizeof(u32); 1249a322993SPhilippe De Muyter inc->incr_src = sizeof(u32); 1259a322993SPhilippe De Muyter inc->incr_dst = 0; 1269a322993SPhilippe De Muyter 1279a322993SPhilippe De Muyter bcom_set_initiator(tsk->tasknum, BCOM_INITIATOR_ATA_TX); 1289a322993SPhilippe De Muyter } 1299a322993SPhilippe De Muyter EXPORT_SYMBOL_GPL(bcom_ata_tx_prepare); 1309a322993SPhilippe De Muyter 1319a322993SPhilippe De Muyter void bcom_ata_reset_bd(struct bcom_task *tsk) 1329a322993SPhilippe De Muyter { 1339a322993SPhilippe De Muyter struct bcom_ata_var *var; 1349a322993SPhilippe De Muyter 1359a322993SPhilippe De Muyter /* Reset all BD */ 136*adec566bSAnatolij Gustschin memset_io(tsk->bd, 0x00, tsk->num_bd * tsk->bd_size); 1379a322993SPhilippe De Muyter 1389a322993SPhilippe De Muyter tsk->index = 0; 1399a322993SPhilippe De Muyter tsk->outdex = 0; 1409a322993SPhilippe De Muyter 1419a322993SPhilippe De Muyter var = (struct bcom_ata_var *) bcom_task_var(tsk->tasknum); 1429a322993SPhilippe De Muyter var->bd_start = var->bd_base; 1439a322993SPhilippe De Muyter } 1449a322993SPhilippe De Muyter EXPORT_SYMBOL_GPL(bcom_ata_reset_bd); 1459a322993SPhilippe De Muyter 1469a322993SPhilippe De Muyter void bcom_ata_release(struct bcom_task *tsk) 1479a322993SPhilippe De Muyter { 1489a322993SPhilippe De Muyter /* Nothing special for the ATA tasks */ 1499a322993SPhilippe De Muyter bcom_task_free(tsk); 1509a322993SPhilippe De Muyter } 1519a322993SPhilippe De Muyter EXPORT_SYMBOL_GPL(bcom_ata_release); 1529a322993SPhilippe De Muyter 1539a322993SPhilippe De Muyter 1549a322993SPhilippe De Muyter MODULE_DESCRIPTION("BestComm ATA task driver"); 1559a322993SPhilippe De Muyter MODULE_AUTHOR("John Rigby"); 1569a322993SPhilippe De Muyter MODULE_LICENSE("GPL v2"); 1579a322993SPhilippe De Muyter 158