^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) // SPDX-License-Identifier: GPL-2.0+
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) * Freescale QUICC Engine USB Host Controller Driver
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5) * Copyright (c) Freescale Semicondutor, Inc. 2006.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) * Shlomi Gridish <gridish@freescale.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) * Jerry Huang <Chang-Ming.Huang@freescale.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8) * Copyright (c) Logic Product Development, Inc. 2007
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) * Peter Barada <peterb@logicpd.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) * Copyright (c) MontaVista Software, Inc. 2008.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11) * Anton Vorontsov <avorontsov@ru.mvista.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) #include <linux/kernel.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) #include <linux/types.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) #include <linux/errno.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17) #include <linux/slab.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) #include <linux/list.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19) #include <linux/io.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20) #include <linux/usb.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) #include <linux/usb/hcd.h>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) #include "fhci.h"
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) #define DUMMY_BD_BUFFER 0xdeadbeef
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) #define DUMMY2_BD_BUFFER 0xbaadf00d
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) /* Transaction Descriptors bits */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) #define TD_R 0x8000 /* ready bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29) #define TD_W 0x2000 /* wrap bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) #define TD_I 0x1000 /* interrupt on completion */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) #define TD_L 0x0800 /* last */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32) #define TD_TC 0x0400 /* transmit CRC */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) #define TD_CNF 0x0200 /* CNF - Must be always 1 */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) #define TD_LSP 0x0100 /* Low-speed transaction */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) #define TD_PID 0x00c0 /* packet id */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) #define TD_RXER 0x0020 /* Rx error or not */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) #define TD_NAK 0x0010 /* No ack. */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) #define TD_STAL 0x0008 /* Stall received */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) #define TD_TO 0x0004 /* time out */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) #define TD_UN 0x0002 /* underrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42) #define TD_NO 0x0010 /* Rx Non Octet Aligned Packet */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) #define TD_AB 0x0008 /* Frame Aborted */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) #define TD_CR 0x0004 /* CRC Error */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) #define TD_OV 0x0002 /* Overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) #define TD_BOV 0x0001 /* Buffer Overrun */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) #define TD_ERRORS (TD_NAK | TD_STAL | TD_TO | TD_UN | \
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) TD_NO | TD_AB | TD_CR | TD_OV | TD_BOV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) #define TD_PID_DATA0 0x0080 /* Data 0 toggle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52) #define TD_PID_DATA1 0x00c0 /* Data 1 toggle */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) #define TD_PID_TOGGLE 0x00c0 /* Data 0/1 toggle mask */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55) #define TD_TOK_SETUP 0x0000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) #define TD_TOK_OUT 0x4000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) #define TD_TOK_IN 0x8000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) #define TD_ISO 0x1000
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59) #define TD_ENDP 0x0780
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) #define TD_ADDR 0x007f
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) #define TD_ENDP_SHIFT 7
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64) struct usb_td {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) __be16 status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) __be16 length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) __be32 buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) __be16 extra;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) __be16 reserved;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) };
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) static struct usb_td __iomem *next_bd(struct usb_td __iomem *base,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) struct usb_td __iomem *td,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) u16 status)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) if (status & TD_W)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) return base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) return ++td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) void fhci_push_dummy_bd(struct endpoint *ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) if (!ep->already_pushed_dummy_bd) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85) u16 td_status = in_be16(&ep->empty_td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) out_be32(&ep->empty_td->buf_ptr, DUMMY_BD_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) /* get the next TD in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) ep->already_pushed_dummy_bd = true;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94) /* destroy an USB endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) void fhci_ep0_free(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) struct endpoint *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) int size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101) if (ep) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) if (ep->td_base)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103) cpm_muram_free(cpm_muram_offset(ep->td_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) if (kfifo_initialized(&ep->conf_frame_Q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106) size = cq_howmany(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) for (; size; size--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) struct packet *pkt = cq_get(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) cq_delete(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115) if (kfifo_initialized(&ep->empty_frame_Q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) size = cq_howmany(&ep->empty_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) for (; size; size--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118) struct packet *pkt = cq_get(&ep->empty_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) cq_delete(&ep->empty_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125) if (kfifo_initialized(&ep->dummy_packets_Q)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) size = cq_howmany(&ep->dummy_packets_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) for (; size; size--) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128) u8 *buff = cq_get(&ep->dummy_packets_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) kfree(buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) cq_delete(&ep->dummy_packets_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135) kfree(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) usb->ep0 = NULL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) * create the endpoint structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143) * arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) * usb A pointer to the data structure of the USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) * data_mem The data memory partition(BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146) * ring_len TD ring length
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) u32 fhci_create_ep(struct fhci_usb *usb, enum fhci_mem_alloc data_mem,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) u32 ring_len)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) struct endpoint *ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152) struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) unsigned long ep_offset;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) char *err_for = "endpoint PRAM";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) int ep_mem_size;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) u32 i;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) /* we need at least 3 TDs in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159) if (!(ring_len > 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) fhci_err(usb->fhci, "illegal TD ring length parameters\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161) return -EINVAL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164) ep = kzalloc(sizeof(*ep), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) if (!ep)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) ep_mem_size = ring_len * sizeof(*td) + sizeof(struct fhci_ep_pram);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169) ep_offset = cpm_muram_alloc(ep_mem_size, 32);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) if (IS_ERR_VALUE(ep_offset))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172) ep->td_base = cpm_muram_addr(ep_offset);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) /* zero all queue pointers */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) if (cq_new(&ep->conf_frame_Q, ring_len + 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) cq_new(&ep->empty_frame_Q, ring_len + 2) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177) cq_new(&ep->dummy_packets_Q, ring_len + 2)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) err_for = "frame_queues";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) for (i = 0; i < (ring_len + 1); i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) struct packet *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) u8 *buff;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) pkt = kmalloc(sizeof(*pkt), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) if (!pkt) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188) err_for = "frame";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) buff = kmalloc_array(1028, sizeof(*buff), GFP_KERNEL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193) if (!buff) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) kfree(pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) err_for = "buffer";
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196) goto err;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) cq_put(&ep->empty_frame_Q, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) cq_put(&ep->dummy_packets_Q, buff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) /* we put the endpoint parameter RAM right behind the TD ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) ep->ep_pram_ptr = (void __iomem *)ep->td_base + sizeof(*td) * ring_len;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) ep->conf_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) ep->empty_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) ep->already_pushed_dummy_bd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) /* initialize tds */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212) for (i = 0; i < ring_len; i++) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) out_be16(&td->status, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) td++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) td--;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) /* endpoint structure has been created */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) usb->ep0 = ep;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) err:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) fhci_ep0_free(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229) kfree(ep);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) fhci_err(usb->fhci, "no memory for the %s\n", err_for);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return -ENOMEM;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) * initialize the endpoint register according to the given parameters
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) * artuments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238) * usb A pointer to the data strucutre of the USB
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) * ep A pointer to the endpoint structre
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) * data_mem The data memory partition(BUS)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) void fhci_init_ep_registers(struct fhci_usb *usb, struct endpoint *ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) enum fhci_mem_alloc data_mem)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) u8 rt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) /* set the endpoint registers according to the endpoint */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) out_be16(&usb->fhci->regs->usb_usep[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249) USB_TRANS_CTR | USB_EP_MF | USB_EP_RTE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) out_be16(&usb->fhci->pram->ep_ptr[0],
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) cpm_muram_offset(ep->ep_pram_ptr));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) rt = (BUS_MODE_BO_BE | BUS_MODE_GBL);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254) #ifdef MULTI_DATA_BUS
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) if (data_mem == MEM_SECONDARY)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) rt |= BUS_MODE_DTB;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257) #endif
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) out_8(&ep->ep_pram_ptr->rx_func_code, rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) out_8(&ep->ep_pram_ptr->tx_func_code, rt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) out_be16(&ep->ep_pram_ptr->rx_buff_len, 1028);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) out_be16(&ep->ep_pram_ptr->rx_base, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262) out_be16(&ep->ep_pram_ptr->tx_base, cpm_muram_offset(ep->td_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) out_be16(&ep->ep_pram_ptr->rx_bd_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) out_be16(&ep->ep_pram_ptr->tx_bd_ptr, cpm_muram_offset(ep->td_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265) out_be32(&ep->ep_pram_ptr->tx_state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) * Collect the submitted frames and inform the application about them
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270) * It is also preparing the TDs for new frames. If the Tx interrupts
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) * are disabled, the application should call that routine to get
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) * confirmation about the submitted frames. Otherwise, the routine is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273) * called from the interrupt service routine during the Tx interrupt.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) * In that case the application is informed by calling the application
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) * specific 'fhci_transaction_confirm' routine
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) static void fhci_td_transaction_confirm(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) struct packet *pkt;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281) struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) u16 extra_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) u16 td_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) u32 buf;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) * collect transmitted BDs from the chip. The routine clears all BDs
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) * with R bit = 0 and the pointer to data buffer is not NULL, that is
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) * BDs which point to the transmitted data buffer
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 292) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 293) td = ep->conf_td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 294) td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 295) td_length = in_be16(&td->length);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 296) buf = in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 297) extra_data = in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 298)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 299) /* check if the TD is empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 300) if (!(!(td_status & TD_R) && ((td_status & ~TD_W) || buf)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 301) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 302) /* check if it is a dummy buffer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 303) else if ((buf == DUMMY_BD_BUFFER) && !(td_status & ~TD_W))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 304) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 305)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 306) /* mark TD as empty */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 307) clrbits16(&td->status, ~TD_W);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 308) out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 309) out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 310) out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 311) /* advance the TD pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 312) ep->conf_td = next_bd(ep->td_base, ep->conf_td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 313)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 314) /* check if it is a dummy buffer(type2) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 315) if ((buf == DUMMY2_BD_BUFFER) && !(td_status & ~TD_W))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 316) continue;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 317)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 318) pkt = cq_get(&ep->conf_frame_Q);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 319) if (!pkt)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 320) fhci_err(usb->fhci, "no frame to confirm\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 321)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 322) if (td_status & TD_ERRORS) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 323) if (td_status & TD_RXER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 324) if (td_status & TD_CR)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 325) pkt->status = USB_TD_RX_ER_CRC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 326) else if (td_status & TD_AB)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 327) pkt->status = USB_TD_RX_ER_BITSTUFF;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 328) else if (td_status & TD_OV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 329) pkt->status = USB_TD_RX_ER_OVERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 330) else if (td_status & TD_BOV)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 331) pkt->status = USB_TD_RX_DATA_OVERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 332) else if (td_status & TD_NO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 333) pkt->status = USB_TD_RX_ER_NONOCT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 334) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 335) fhci_err(usb->fhci, "illegal error "
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 336) "occurred\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 337) } else if (td_status & TD_NAK)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 338) pkt->status = USB_TD_TX_ER_NAK;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 339) else if (td_status & TD_TO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 340) pkt->status = USB_TD_TX_ER_TIMEOUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 341) else if (td_status & TD_UN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 342) pkt->status = USB_TD_TX_ER_UNDERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 343) else if (td_status & TD_STAL)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 344) pkt->status = USB_TD_TX_ER_STALL;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 345) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 346) fhci_err(usb->fhci, "illegal error occurred\n");
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 347) } else if ((extra_data & TD_TOK_IN) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 348) pkt->len > td_length - CRC_SIZE) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 349) pkt->status = USB_TD_RX_DATA_UNDERUN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 350) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 351)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 352) if (extra_data & TD_TOK_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 353) pkt->len = td_length - CRC_SIZE;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 354) else if (pkt->info & PKT_ZLP)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 355) pkt->len = 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 356) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 357) pkt->len = td_length;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 358)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 359) fhci_transaction_confirm(usb, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 360) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 361) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 362)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 363) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 364) * Submitting a data frame to a specified endpoint of a USB device
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 365) * The frame is put in the driver's transmit queue for this endpoint
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 366) *
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 367) * Arguments:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 368) * usb A pointer to the USB structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 369) * pkt A pointer to the user frame structure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 370) * trans_type Transaction tyep - IN,OUT or SETUP
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 371) * dest_addr Device address - 0~127
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 372) * dest_ep Endpoint number of the device - 0~16
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 373) * trans_mode Pipe type - ISO,Interrupt,bulk or control
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 374) * dest_speed USB speed - Low speed or FULL speed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 375) * data_toggle Data sequence toggle - 0 or 1
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 376) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 377) u32 fhci_host_transaction(struct fhci_usb *usb,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 378) struct packet *pkt,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 379) enum fhci_ta_type trans_type,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 380) u8 dest_addr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 381) u8 dest_ep,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 382) enum fhci_tf_mode trans_mode,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 383) enum fhci_speed dest_speed, u8 data_toggle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 384) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 385) struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 386) struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 387) u16 extra_data;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 388) u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 389)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 390) fhci_usb_disable_interrupt(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 391) /* start from the next BD that should be filled */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 392) td = ep->empty_td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 393) td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 394)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 395) if (td_status & TD_R && in_be16(&td->length)) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 396) /* if the TD is not free */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 397) fhci_usb_enable_interrupt(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 398) return -1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 399) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 400)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 401) /* get the next TD in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 402) ep->empty_td = next_bd(ep->td_base, ep->empty_td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 403) fhci_usb_enable_interrupt(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 404) pkt->priv_data = td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 405) out_be32(&td->buf_ptr, virt_to_phys(pkt->data));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 406) /* sets up transaction parameters - addr,endp,dir,and type */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 407) extra_data = (dest_ep << TD_ENDP_SHIFT) | dest_addr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 408) switch (trans_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 409) case FHCI_TA_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 410) extra_data |= TD_TOK_IN;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 411) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 412) case FHCI_TA_OUT:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 413) extra_data |= TD_TOK_OUT;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 414) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 415) case FHCI_TA_SETUP:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 416) extra_data |= TD_TOK_SETUP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 417) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 418) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 419) if (trans_mode == FHCI_TF_ISO)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 420) extra_data |= TD_ISO;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 421) out_be16(&td->extra, extra_data);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 422)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 423) /* sets up the buffer descriptor */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 424) td_status = ((td_status & TD_W) | TD_R | TD_L | TD_I | TD_CNF);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 425) if (!(pkt->info & PKT_NO_CRC))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 426) td_status |= TD_TC;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 427)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 428) switch (trans_type) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 429) case FHCI_TA_IN:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 430) if (data_toggle)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 431) pkt->info |= PKT_PID_DATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 432) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 433) pkt->info |= PKT_PID_DATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 434) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 435) default:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 436) if (data_toggle) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 437) td_status |= TD_PID_DATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 438) pkt->info |= PKT_PID_DATA1;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 439) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 440) td_status |= TD_PID_DATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 441) pkt->info |= PKT_PID_DATA0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 442) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 443) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 444) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 445)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 446) if ((dest_speed == FHCI_LOW_SPEED) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 447) (usb->port_status == FHCI_PORT_FULL))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 448) td_status |= TD_LSP;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 449)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 450) out_be16(&td->status, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 451)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 452) /* set up buffer length */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 453) if (trans_type == FHCI_TA_IN)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 454) out_be16(&td->length, pkt->len + CRC_SIZE);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 455) else
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 456) out_be16(&td->length, pkt->len);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 457)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 458) /* put the frame to the confirmation queue */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 459) cq_put(&ep->conf_frame_Q, pkt);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 460)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 461) if (cq_howmany(&ep->conf_frame_Q) == 1)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 462) out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 463)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 464) return 0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 465) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 466)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 467) /* Reset the Tx BD ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 468) void fhci_flush_bds(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 469) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 470) u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 471) struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 472) struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 473)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 474) td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 475) while (1) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 476) td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 477) in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 478) in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 479)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 480) /* if the TD is not empty - we'll confirm it as Timeout */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 481) if (td_status & TD_R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 482) out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 483) /* if this TD is dummy - let's skip this TD */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 484) else if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 485) out_be32(&td->buf_ptr, DUMMY2_BD_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 486) /* if this is the last TD - break */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 487) if (td_status & TD_W)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 488) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 489)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 490) td++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 491) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 492)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 493) fhci_td_transaction_confirm(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 494)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 495) td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 496) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 497) out_be16(&td->status, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 498) out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 499) out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 500) out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 501) td++;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 502) } while (!(in_be16(&td->status) & TD_W));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 503) out_be16(&td->status, TD_W); /* for last TD set Wrap bit */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 504) out_be16(&td->length, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 505) out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 506) out_be16(&td->extra, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 507)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 508) out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 509) in_be16(&ep->ep_pram_ptr->tx_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 510) out_be32(&ep->ep_pram_ptr->tx_state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 511) out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 512) ep->empty_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 513) ep->conf_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 514) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 515)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 516) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 517) * Flush all transmitted packets from TDs in the actual frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 518) * This routine is called when something wrong with the controller and
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 519) * we want to get rid of the actual frame and start again next frame
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 520) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 521) void fhci_flush_actual_frame(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 522) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 523) u8 mode;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 524) u16 tb_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 525) u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 526) u32 buf_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 527) struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 528) struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 529)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 530) /* disable the USB controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 531) mode = in_8(&usb->fhci->regs->usb_usmod);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 532) out_8(&usb->fhci->regs->usb_usmod, mode & ~USB_MODE_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 533)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 534) tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 535) td = cpm_muram_addr(tb_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 536) td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 537) buf_ptr = in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 538) in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 539) do {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 540) if (td_status & TD_R) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 541) out_be16(&td->status, (td_status & ~TD_R) | TD_TO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 542) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 543) out_be32(&td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 544) ep->already_pushed_dummy_bd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 545) break;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 546) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 547)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 548) /* advance the TD pointer */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 549) td = next_bd(ep->td_base, td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 550) td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 551) buf_ptr = in_be32(&td->buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 552) in_be16(&td->extra);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 553) } while ((td_status & TD_R) || buf_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 554)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 555) fhci_td_transaction_confirm(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 556)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 557) out_be16(&ep->ep_pram_ptr->tx_bd_ptr,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 558) in_be16(&ep->ep_pram_ptr->tx_base));
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 559) out_be32(&ep->ep_pram_ptr->tx_state, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 560) out_be16(&ep->ep_pram_ptr->tx_cnt, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 561) ep->empty_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 562) ep->conf_td = ep->td_base;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 563)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 564) usb->actual_frame->frame_status = FRAME_TIMER_END_TRANSMISSION;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 565)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 566) /* reset the event register */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 567) out_be16(&usb->fhci->regs->usb_usber, 0xffff);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 568) /* enable the USB controller */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 569) out_8(&usb->fhci->regs->usb_usmod, mode | USB_MODE_EN);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 570) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 571)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 572) /* handles Tx confirm and Tx error interrupt */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 573) void fhci_tx_conf_interrupt(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 574) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 575) fhci_td_transaction_confirm(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 576)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 577) /*
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 578) * Schedule another transaction to this frame only if we have
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 579) * already confirmed all transaction in the frame.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 580) */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 581) if (((fhci_get_sof_timer_count(usb) < usb->max_frame_usage) ||
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 582) (usb->actual_frame->frame_status & FRAME_END_TRANSMISSION)) &&
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 583) (list_empty(&usb->actual_frame->tds_list)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 584) fhci_schedule_transactions(usb);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 585) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 586)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 587) void fhci_host_transmit_actual_frame(struct fhci_usb *usb)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 588) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 589) u16 tb_ptr;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 590) u16 td_status;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 591) struct usb_td __iomem *td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 592) struct endpoint *ep = usb->ep0;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 593)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 594) tb_ptr = in_be16(&ep->ep_pram_ptr->tx_bd_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 595) td = cpm_muram_addr(tb_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 596)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 597) if (in_be32(&td->buf_ptr) == DUMMY_BD_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 598) struct usb_td __iomem *old_td = td;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 599)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 600) ep->already_pushed_dummy_bd = false;
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 601) td_status = in_be16(&td->status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 602) /* gets the next TD in the ring */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 603) td = next_bd(ep->td_base, td, td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 604) tb_ptr = cpm_muram_offset(td);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 605) out_be16(&ep->ep_pram_ptr->tx_bd_ptr, tb_ptr);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 606)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 607) /* start transmit only if we have something in the TDs */
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 608) if (in_be16(&td->status) & TD_R)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 609) out_8(&usb->fhci->regs->usb_uscom, USB_CMD_STR_FIFO);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 610)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 611) if (in_be32(&ep->conf_td->buf_ptr) == DUMMY_BD_BUFFER) {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 612) out_be32(&old_td->buf_ptr, 0);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 613) ep->conf_td = next_bd(ep->td_base, ep->conf_td,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 614) td_status);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 615) } else {
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 616) out_be32(&old_td->buf_ptr, DUMMY2_BD_BUFFER);
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 617) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 618) }
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 619) }