mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-10-02 17:40:41 +09:00
Merge branch 'next' of git://git.denx.de/u-boot-usb into next
- Assorted XHCI improvements
This commit is contained in:
commit
7e373a1a6a
@ -236,8 +236,7 @@ static void xhci_link_segments(struct xhci_segment *prev,
|
|||||||
*/
|
*/
|
||||||
val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control);
|
val = le32_to_cpu(prev->trbs[TRBS_PER_SEGMENT-1].link.control);
|
||||||
val &= ~TRB_TYPE_BITMASK;
|
val &= ~TRB_TYPE_BITMASK;
|
||||||
val |= (TRB_LINK << TRB_TYPE_SHIFT);
|
val |= TRB_TYPE(TRB_LINK);
|
||||||
|
|
||||||
prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val);
|
prev->trbs[TRBS_PER_SEGMENT-1].link.control = cpu_to_le32(val);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -826,25 +825,22 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
|
|||||||
|
|
||||||
/* Step 4 - ring already allocated */
|
/* Step 4 - ring already allocated */
|
||||||
/* Step 5 */
|
/* Step 5 */
|
||||||
ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT);
|
ep0_ctx->ep_info2 = cpu_to_le32(EP_TYPE(CTRL_EP));
|
||||||
debug("SPEED = %d\n", speed);
|
debug("SPEED = %d\n", speed);
|
||||||
|
|
||||||
switch (speed) {
|
switch (speed) {
|
||||||
case USB_SPEED_SUPER:
|
case USB_SPEED_SUPER:
|
||||||
ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) <<
|
ep0_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(512));
|
||||||
MAX_PACKET_SHIFT));
|
|
||||||
debug("Setting Packet size = 512bytes\n");
|
debug("Setting Packet size = 512bytes\n");
|
||||||
break;
|
break;
|
||||||
case USB_SPEED_HIGH:
|
case USB_SPEED_HIGH:
|
||||||
/* USB core guesses at a 64-byte max packet first for FS devices */
|
/* USB core guesses at a 64-byte max packet first for FS devices */
|
||||||
case USB_SPEED_FULL:
|
case USB_SPEED_FULL:
|
||||||
ep0_ctx->ep_info2 |= cpu_to_le32(((64 & MAX_PACKET_MASK) <<
|
ep0_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(64));
|
||||||
MAX_PACKET_SHIFT));
|
|
||||||
debug("Setting Packet size = 64bytes\n");
|
debug("Setting Packet size = 64bytes\n");
|
||||||
break;
|
break;
|
||||||
case USB_SPEED_LOW:
|
case USB_SPEED_LOW:
|
||||||
ep0_ctx->ep_info2 |= cpu_to_le32(((8 & MAX_PACKET_MASK) <<
|
ep0_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(8));
|
||||||
MAX_PACKET_SHIFT));
|
|
||||||
debug("Setting Packet size = 8bytes\n");
|
debug("Setting Packet size = 8bytes\n");
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@ -853,9 +849,7 @@ void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
|
/* EP 0 can handle "burst" sizes of 1, so Max Burst Size field is 0 */
|
||||||
ep0_ctx->ep_info2 |=
|
ep0_ctx->ep_info2 |= cpu_to_le32(MAX_BURST(0) | ERROR_COUNT(3));
|
||||||
cpu_to_le32(((0 & MAX_BURST_MASK) << MAX_BURST_SHIFT) |
|
|
||||||
((3 & ERROR_COUNT_MASK) << ERROR_COUNT_SHIFT));
|
|
||||||
|
|
||||||
trb_64 = virt_to_phys(virt_dev->eps[0].ring->first_seg->trbs);
|
trb_64 = virt_to_phys(virt_dev->eps[0].ring->first_seg->trbs);
|
||||||
ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state);
|
ep0_ctx->deq = cpu_to_le64(trb_64 | virt_dev->eps[0].ring->cycle_state);
|
||||||
|
@ -258,6 +258,7 @@ static int xhci_mtk_probe(struct udevice *dev)
|
|||||||
if (ret)
|
if (ret)
|
||||||
goto ssusb_init_err;
|
goto ssusb_init_err;
|
||||||
|
|
||||||
|
mtk->ctrl.quirks = XHCI_MTK_HOST;
|
||||||
hcor = (struct xhci_hcor *)((uintptr_t)mtk->hcd +
|
hcor = (struct xhci_hcor *)((uintptr_t)mtk->hcd +
|
||||||
HC_LENGTH(xhci_readl(&mtk->hcd->cr_capbase)));
|
HC_LENGTH(xhci_readl(&mtk->hcd->cr_capbase)));
|
||||||
|
|
||||||
|
@ -146,6 +146,7 @@ static int xhci_rcar_ofdata_to_platdata(struct udevice *dev)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static const struct udevice_id xhci_rcar_ids[] = {
|
static const struct udevice_id xhci_rcar_ids[] = {
|
||||||
|
{ .compatible = "renesas,rcar-gen3-xhci" },
|
||||||
{ .compatible = "renesas,xhci-r8a7795" },
|
{ .compatible = "renesas,xhci-r8a7795" },
|
||||||
{ .compatible = "renesas,xhci-r8a7796" },
|
{ .compatible = "renesas,xhci-r8a7796" },
|
||||||
{ .compatible = "renesas,xhci-r8a77965" },
|
{ .compatible = "renesas,xhci-r8a77965" },
|
||||||
|
@ -298,55 +298,57 @@ void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr, u32 slot_id,
|
|||||||
xhci_writel(&ctrl->dba->doorbell[0], DB_VALUE_HOST);
|
xhci_writel(&ctrl->dba->doorbell[0], DB_VALUE_HOST);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/*
|
||||||
* The TD size is the number of bytes remaining in the TD (including this TRB),
|
* For xHCI 1.0 host controllers, TD size is the number of max packet sized
|
||||||
* right shifted by 10.
|
* packets remaining in the TD (*not* including this TRB).
|
||||||
* It must fit in bits 21:17, so it can't be bigger than 31.
|
|
||||||
*
|
*
|
||||||
* @param remainder remaining packets to be sent
|
* Total TD packet count = total_packet_count =
|
||||||
* @return remainder if remainder is less than max else max
|
* DIV_ROUND_UP(TD size in bytes / wMaxPacketSize)
|
||||||
*/
|
|
||||||
static u32 xhci_td_remainder(unsigned int remainder)
|
|
||||||
{
|
|
||||||
u32 max = (1 << (21 - 17 + 1)) - 1;
|
|
||||||
|
|
||||||
if ((remainder >> 10) >= max)
|
|
||||||
return max << 17;
|
|
||||||
else
|
|
||||||
return (remainder >> 10) << 17;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Finds out the remanining packets to be sent
|
|
||||||
*
|
*
|
||||||
* @param running_total total size sent so far
|
* Packets transferred up to and including this TRB = packets_transferred =
|
||||||
|
* rounddown(total bytes transferred including this TRB / wMaxPacketSize)
|
||||||
|
*
|
||||||
|
* TD size = total_packet_count - packets_transferred
|
||||||
|
*
|
||||||
|
* For xHCI 0.96 and older, TD size field should be the remaining bytes
|
||||||
|
* including this TRB, right shifted by 10
|
||||||
|
*
|
||||||
|
* For all hosts it must fit in bits 21:17, so it can't be bigger than 31.
|
||||||
|
* This is taken care of in the TRB_TD_SIZE() macro
|
||||||
|
*
|
||||||
|
* The last TRB in a TD must have the TD size set to zero.
|
||||||
|
*
|
||||||
|
* @param ctrl host controller data structure
|
||||||
|
* @param transferred total size sent so far
|
||||||
* @param trb_buff_len length of the TRB Buffer
|
* @param trb_buff_len length of the TRB Buffer
|
||||||
* @param total_packet_count total packet count
|
* @param td_total_len total packet count
|
||||||
* @param maxpacketsize max packet size of current pipe
|
* @param maxp max packet size of current pipe
|
||||||
* @param num_trbs_left number of TRBs left to be processed
|
* @param more_trbs_coming indicate last trb in TD
|
||||||
* @return 0 if running_total or trb_buff_len is 0, else remainder
|
* @return remainder
|
||||||
*/
|
*/
|
||||||
static u32 xhci_v1_0_td_remainder(int running_total,
|
static u32 xhci_td_remainder(struct xhci_ctrl *ctrl, int transferred,
|
||||||
int trb_buff_len,
|
int trb_buff_len, unsigned int td_total_len,
|
||||||
unsigned int total_packet_count,
|
int maxp, bool more_trbs_coming)
|
||||||
int maxpacketsize,
|
|
||||||
unsigned int num_trbs_left)
|
|
||||||
{
|
{
|
||||||
int packets_transferred;
|
u32 total_packet_count;
|
||||||
|
|
||||||
|
/* MTK xHCI 0.96 contains some features from 1.0 */
|
||||||
|
if (ctrl->hci_version < 0x100 && !(ctrl->quirks & XHCI_MTK_HOST))
|
||||||
|
return ((td_total_len - transferred) >> 10);
|
||||||
|
|
||||||
/* One TRB with a zero-length data packet. */
|
/* One TRB with a zero-length data packet. */
|
||||||
if (num_trbs_left == 0 || (running_total == 0 && trb_buff_len == 0))
|
if (!more_trbs_coming || (transferred == 0 && trb_buff_len == 0) ||
|
||||||
|
trb_buff_len == td_total_len)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/* for MTK xHCI 0.96, TD size include this TRB, but not in 1.x */
|
||||||
* All the TRB queueing functions don't count the current TRB in
|
if ((ctrl->quirks & XHCI_MTK_HOST) && (ctrl->hci_version < 0x100))
|
||||||
* running_total.
|
trb_buff_len = 0;
|
||||||
*/
|
|
||||||
packets_transferred = (running_total + trb_buff_len) / maxpacketsize;
|
|
||||||
|
|
||||||
if ((total_packet_count - packets_transferred) > 31)
|
total_packet_count = DIV_ROUND_UP(td_total_len, maxp);
|
||||||
return 31 << 17;
|
|
||||||
return (total_packet_count - packets_transferred) << 17;
|
/* Queueing functions don't count the current TRB into transferred */
|
||||||
|
return (total_packet_count - ((transferred + trb_buff_len) / maxp));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -572,7 +574,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
union xhci_trb *event;
|
union xhci_trb *event;
|
||||||
|
|
||||||
int running_total, trb_buff_len;
|
int running_total, trb_buff_len;
|
||||||
unsigned int total_packet_count;
|
bool more_trbs_coming = true;
|
||||||
int maxpacketsize;
|
int maxpacketsize;
|
||||||
u64 addr;
|
u64 addr;
|
||||||
int ret;
|
int ret;
|
||||||
@ -636,8 +638,6 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
running_total = 0;
|
running_total = 0;
|
||||||
maxpacketsize = usb_maxpacket(udev, pipe);
|
maxpacketsize = usb_maxpacket(udev, pipe);
|
||||||
|
|
||||||
total_packet_count = DIV_ROUND_UP(length, maxpacketsize);
|
|
||||||
|
|
||||||
/* How much data is in the first TRB? */
|
/* How much data is in the first TRB? */
|
||||||
/*
|
/*
|
||||||
* How much data is (potentially) left before the 64KB boundary?
|
* How much data is (potentially) left before the 64KB boundary?
|
||||||
@ -672,34 +672,30 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
* Chain all the TRBs together; clear the chain bit in the last
|
* Chain all the TRBs together; clear the chain bit in the last
|
||||||
* TRB to indicate it's the last TRB in the chain.
|
* TRB to indicate it's the last TRB in the chain.
|
||||||
*/
|
*/
|
||||||
if (num_trbs > 1)
|
if (num_trbs > 1) {
|
||||||
field |= TRB_CHAIN;
|
field |= TRB_CHAIN;
|
||||||
else
|
} else {
|
||||||
field |= TRB_IOC;
|
field |= TRB_IOC;
|
||||||
|
more_trbs_coming = false;
|
||||||
|
}
|
||||||
|
|
||||||
/* Only set interrupt on short packet for IN endpoints */
|
/* Only set interrupt on short packet for IN endpoints */
|
||||||
if (usb_pipein(pipe))
|
if (usb_pipein(pipe))
|
||||||
field |= TRB_ISP;
|
field |= TRB_ISP;
|
||||||
|
|
||||||
/* Set the TRB length, TD size, and interrupter fields. */
|
/* Set the TRB length, TD size, and interrupter fields. */
|
||||||
if (HC_VERSION(xhci_readl(&ctrl->hccr->cr_capbase)) < 0x100)
|
remainder = xhci_td_remainder(ctrl, running_total, trb_buff_len,
|
||||||
remainder = xhci_td_remainder(length - running_total);
|
length, maxpacketsize,
|
||||||
else
|
more_trbs_coming);
|
||||||
remainder = xhci_v1_0_td_remainder(running_total,
|
|
||||||
trb_buff_len,
|
|
||||||
total_packet_count,
|
|
||||||
maxpacketsize,
|
|
||||||
num_trbs - 1);
|
|
||||||
|
|
||||||
length_field = ((trb_buff_len & TRB_LEN_MASK) |
|
length_field = (TRB_LEN(trb_buff_len) |
|
||||||
remainder |
|
TRB_TD_SIZE(remainder) |
|
||||||
((0 & TRB_INTR_TARGET_MASK) <<
|
TRB_INTR_TARGET(0));
|
||||||
TRB_INTR_TARGET_SHIFT));
|
|
||||||
|
|
||||||
trb_fields[0] = lower_32_bits(addr);
|
trb_fields[0] = lower_32_bits(addr);
|
||||||
trb_fields[1] = upper_32_bits(addr);
|
trb_fields[1] = upper_32_bits(addr);
|
||||||
trb_fields[2] = length_field;
|
trb_fields[2] = length_field;
|
||||||
trb_fields[3] = field | (TRB_NORMAL << TRB_TYPE_SHIFT);
|
trb_fields[3] = field | TRB_TYPE(TRB_NORMAL);
|
||||||
|
|
||||||
queue_trb(ctrl, ring, (num_trbs > 1), trb_fields);
|
queue_trb(ctrl, ring, (num_trbs > 1), trb_fields);
|
||||||
|
|
||||||
@ -764,6 +760,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
|
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
|
||||||
struct xhci_ring *ep_ring;
|
struct xhci_ring *ep_ring;
|
||||||
union xhci_trb *event;
|
union xhci_trb *event;
|
||||||
|
u32 remainder;
|
||||||
|
|
||||||
debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n",
|
debug("req=%u (%#x), type=%u (%#x), value=%u (%#x), index=%u\n",
|
||||||
req->request, req->request,
|
req->request, req->request,
|
||||||
@ -825,17 +822,17 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
/* Queue setup TRB - see section 6.4.1.2.1 */
|
/* Queue setup TRB - see section 6.4.1.2.1 */
|
||||||
/* FIXME better way to translate setup_packet into two u32 fields? */
|
/* FIXME better way to translate setup_packet into two u32 fields? */
|
||||||
field = 0;
|
field = 0;
|
||||||
field |= TRB_IDT | (TRB_SETUP << TRB_TYPE_SHIFT);
|
field |= TRB_IDT | TRB_TYPE(TRB_SETUP);
|
||||||
if (start_cycle == 0)
|
if (start_cycle == 0)
|
||||||
field |= 0x1;
|
field |= 0x1;
|
||||||
|
|
||||||
/* xHCI 1.0 6.4.1.2.1: Transfer Type field */
|
/* xHCI 1.0 6.4.1.2.1: Transfer Type field */
|
||||||
if (HC_VERSION(xhci_readl(&ctrl->hccr->cr_capbase)) >= 0x100) {
|
if (ctrl->hci_version >= 0x100 || ctrl->quirks & XHCI_MTK_HOST) {
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
if (req->requesttype & USB_DIR_IN)
|
if (req->requesttype & USB_DIR_IN)
|
||||||
field |= (TRB_DATA_IN << TRB_TX_TYPE_SHIFT);
|
field |= TRB_TX_TYPE(TRB_DATA_IN);
|
||||||
else
|
else
|
||||||
field |= (TRB_DATA_OUT << TRB_TX_TYPE_SHIFT);
|
field |= TRB_TX_TYPE(TRB_DATA_OUT);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -851,8 +848,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
trb_fields[1] = le16_to_cpu(req->index) |
|
trb_fields[1] = le16_to_cpu(req->index) |
|
||||||
le16_to_cpu(req->length) << 16;
|
le16_to_cpu(req->length) << 16;
|
||||||
/* TRB_LEN | (TRB_INTR_TARGET) */
|
/* TRB_LEN | (TRB_INTR_TARGET) */
|
||||||
trb_fields[2] = (8 | ((0 & TRB_INTR_TARGET_MASK) <<
|
trb_fields[2] = (TRB_LEN(8) | TRB_INTR_TARGET(0));
|
||||||
TRB_INTR_TARGET_SHIFT));
|
|
||||||
/* Immediate data in pointer */
|
/* Immediate data in pointer */
|
||||||
trb_fields[3] = field;
|
trb_fields[3] = field;
|
||||||
queue_trb(ctrl, ep_ring, true, trb_fields);
|
queue_trb(ctrl, ep_ring, true, trb_fields);
|
||||||
@ -862,16 +858,18 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
/* If there's data, queue data TRBs */
|
/* If there's data, queue data TRBs */
|
||||||
/* Only set interrupt on short packet for IN endpoints */
|
/* Only set interrupt on short packet for IN endpoints */
|
||||||
if (usb_pipein(pipe))
|
if (usb_pipein(pipe))
|
||||||
field = TRB_ISP | (TRB_DATA << TRB_TYPE_SHIFT);
|
field = TRB_ISP | TRB_TYPE(TRB_DATA);
|
||||||
else
|
else
|
||||||
field = (TRB_DATA << TRB_TYPE_SHIFT);
|
field = TRB_TYPE(TRB_DATA);
|
||||||
|
|
||||||
length_field = (length & TRB_LEN_MASK) | xhci_td_remainder(length) |
|
remainder = xhci_td_remainder(ctrl, 0, length, length,
|
||||||
((0 & TRB_INTR_TARGET_MASK) << TRB_INTR_TARGET_SHIFT);
|
usb_maxpacket(udev, pipe), true);
|
||||||
|
length_field = TRB_LEN(length) | TRB_TD_SIZE(remainder) |
|
||||||
|
TRB_INTR_TARGET(0);
|
||||||
debug("length_field = %d, length = %d,"
|
debug("length_field = %d, length = %d,"
|
||||||
"xhci_td_remainder(length) = %d , TRB_INTR_TARGET(0) = %d\n",
|
"xhci_td_remainder(length) = %d , TRB_INTR_TARGET(0) = %d\n",
|
||||||
length_field, (length & TRB_LEN_MASK),
|
length_field, TRB_LEN(length),
|
||||||
xhci_td_remainder(length), 0);
|
TRB_TD_SIZE(remainder), 0);
|
||||||
|
|
||||||
if (length > 0) {
|
if (length > 0) {
|
||||||
if (req->requesttype & USB_DIR_IN)
|
if (req->requesttype & USB_DIR_IN)
|
||||||
@ -901,11 +899,10 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
|
|||||||
|
|
||||||
trb_fields[0] = 0;
|
trb_fields[0] = 0;
|
||||||
trb_fields[1] = 0;
|
trb_fields[1] = 0;
|
||||||
trb_fields[2] = ((0 & TRB_INTR_TARGET_MASK) << TRB_INTR_TARGET_SHIFT);
|
trb_fields[2] = TRB_INTR_TARGET(0);
|
||||||
/* Event on completion */
|
/* Event on completion */
|
||||||
trb_fields[3] = field | TRB_IOC |
|
trb_fields[3] = field | TRB_IOC |
|
||||||
(TRB_STATUS << TRB_TYPE_SHIFT) |
|
TRB_TYPE(TRB_STATUS) | ep_ring->cycle_state;
|
||||||
ep_ring->cycle_state;
|
|
||||||
|
|
||||||
queue_trb(ctrl, ep_ring, false, trb_fields);
|
queue_trb(ctrl, ep_ring, false, trb_fields);
|
||||||
|
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#include <linux/bug.h>
|
#include <linux/bug.h>
|
||||||
#include <linux/delay.h>
|
#include <linux/delay.h>
|
||||||
#include <linux/errno.h>
|
#include <linux/errno.h>
|
||||||
|
#include <linux/iopoll.h>
|
||||||
#include <usb/xhci.h>
|
#include <usb/xhci.h>
|
||||||
|
|
||||||
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
|
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
|
||||||
@ -143,23 +144,19 @@ struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev)
|
|||||||
* @param usec time to wait till
|
* @param usec time to wait till
|
||||||
* @return 0 if handshake is success else < 0 on failure
|
* @return 0 if handshake is success else < 0 on failure
|
||||||
*/
|
*/
|
||||||
static int handshake(uint32_t volatile *ptr, uint32_t mask,
|
static int
|
||||||
uint32_t done, int usec)
|
handshake(uint32_t volatile *ptr, uint32_t mask, uint32_t done, int usec)
|
||||||
{
|
{
|
||||||
uint32_t result;
|
uint32_t result;
|
||||||
|
int ret;
|
||||||
|
|
||||||
do {
|
ret = readx_poll_sleep_timeout(xhci_readl, ptr, result,
|
||||||
result = xhci_readl(ptr);
|
(result & mask) == done || result == U32_MAX,
|
||||||
if (result == ~(uint32_t)0)
|
1, usec);
|
||||||
|
if (result == U32_MAX) /* card removed */
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
result &= mask;
|
|
||||||
if (result == done)
|
|
||||||
return 0;
|
|
||||||
usec--;
|
|
||||||
udelay(1);
|
|
||||||
} while (usec > 0);
|
|
||||||
|
|
||||||
return -ETIMEDOUT;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -618,8 +615,7 @@ static int xhci_set_configuration(struct usb_device *udev)
|
|||||||
cpu_to_le32(EP_MAX_ESIT_PAYLOAD_HI(max_esit_payload) |
|
cpu_to_le32(EP_MAX_ESIT_PAYLOAD_HI(max_esit_payload) |
|
||||||
EP_INTERVAL(interval) | EP_MULT(mult));
|
EP_INTERVAL(interval) | EP_MULT(mult));
|
||||||
|
|
||||||
ep_ctx[ep_index]->ep_info2 =
|
ep_ctx[ep_index]->ep_info2 = cpu_to_le32(EP_TYPE(ep_type));
|
||||||
cpu_to_le32(ep_type << EP_TYPE_SHIFT);
|
|
||||||
ep_ctx[ep_index]->ep_info2 |=
|
ep_ctx[ep_index]->ep_info2 |=
|
||||||
cpu_to_le32(MAX_PACKET
|
cpu_to_le32(MAX_PACKET
|
||||||
(get_unaligned(&endpt_desc->wMaxPacketSize)));
|
(get_unaligned(&endpt_desc->wMaxPacketSize)));
|
||||||
@ -650,7 +646,7 @@ static int xhci_set_configuration(struct usb_device *udev)
|
|||||||
* are put into reserved DWs in Slot and Endpoint Contexts
|
* are put into reserved DWs in Slot and Endpoint Contexts
|
||||||
* for synchronous endpoints.
|
* for synchronous endpoints.
|
||||||
*/
|
*/
|
||||||
if (IS_ENABLED(CONFIG_USB_XHCI_MTK)) {
|
if (ctrl->quirks & XHCI_MTK_HOST) {
|
||||||
ep_ctx[ep_index]->reserved[0] =
|
ep_ctx[ep_index]->reserved[0] =
|
||||||
cpu_to_le32(EP_BPKTS(1) | EP_BBM(1));
|
cpu_to_le32(EP_BPKTS(1) | EP_BBM(1));
|
||||||
}
|
}
|
||||||
@ -832,8 +828,7 @@ int xhci_check_maxpacket(struct usb_device *udev)
|
|||||||
ctrl->devs[slot_id]->out_ctx, ep_index);
|
ctrl->devs[slot_id]->out_ctx, ep_index);
|
||||||
in_ctx = ctrl->devs[slot_id]->in_ctx;
|
in_ctx = ctrl->devs[slot_id]->in_ctx;
|
||||||
ep_ctx = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
|
ep_ctx = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
|
||||||
ep_ctx->ep_info2 &= cpu_to_le32(~((0xffff & MAX_PACKET_MASK)
|
ep_ctx->ep_info2 &= cpu_to_le32(~MAX_PACKET(MAX_PACKET_MASK));
|
||||||
<< MAX_PACKET_SHIFT));
|
|
||||||
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size));
|
ep_ctx->ep_info2 |= cpu_to_le32(MAX_PACKET(max_packet_size));
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1257,8 +1252,7 @@ static int xhci_lowlevel_init(struct xhci_ctrl *ctrl)
|
|||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
reg = xhci_readl(&hccr->cr_hcsparams1);
|
reg = xhci_readl(&hccr->cr_hcsparams1);
|
||||||
descriptor.hub.bNbrPorts = ((reg & HCS_MAX_PORTS_MASK) >>
|
descriptor.hub.bNbrPorts = HCS_MAX_PORTS(reg);
|
||||||
HCS_MAX_PORTS_SHIFT);
|
|
||||||
printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
|
printf("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
|
||||||
|
|
||||||
/* Port Indicators */
|
/* Port Indicators */
|
||||||
@ -1283,6 +1277,7 @@ static int xhci_lowlevel_init(struct xhci_ctrl *ctrl)
|
|||||||
|
|
||||||
reg = HC_VERSION(xhci_readl(&hccr->cr_capbase));
|
reg = HC_VERSION(xhci_readl(&hccr->cr_capbase));
|
||||||
printf("USB XHCI %x.%02x\n", reg >> 8, reg & 0xff);
|
printf("USB XHCI %x.%02x\n", reg >> 8, reg & 0xff);
|
||||||
|
ctrl->hci_version = reg;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -101,8 +101,6 @@ struct xhci_hccr {
|
|||||||
/* bits 8:18, Max Interrupters */
|
/* bits 8:18, Max Interrupters */
|
||||||
#define HCS_MAX_INTRS(p) (((p) >> 8) & 0x7ff)
|
#define HCS_MAX_INTRS(p) (((p) >> 8) & 0x7ff)
|
||||||
/* bits 24:31, Max Ports - max value is 0x7F = 127 ports */
|
/* bits 24:31, Max Ports - max value is 0x7F = 127 ports */
|
||||||
#define HCS_MAX_PORTS_SHIFT 24
|
|
||||||
#define HCS_MAX_PORTS_MASK (0xff << HCS_MAX_PORTS_SHIFT)
|
|
||||||
#define HCS_MAX_PORTS(p) (((p) >> 24) & 0xff)
|
#define HCS_MAX_PORTS(p) (((p) >> 24) & 0xff)
|
||||||
|
|
||||||
/* HCSPARAMS2 - hcs_params2 - bitmasks */
|
/* HCSPARAMS2 - hcs_params2 - bitmasks */
|
||||||
@ -634,11 +632,8 @@ struct xhci_ep_ctx {
|
|||||||
*/
|
*/
|
||||||
#define FORCE_EVENT (0x1)
|
#define FORCE_EVENT (0x1)
|
||||||
#define ERROR_COUNT(p) (((p) & 0x3) << 1)
|
#define ERROR_COUNT(p) (((p) & 0x3) << 1)
|
||||||
#define ERROR_COUNT_SHIFT (1)
|
|
||||||
#define ERROR_COUNT_MASK (0x3)
|
|
||||||
#define CTX_TO_EP_TYPE(p) (((p) >> 3) & 0x7)
|
#define CTX_TO_EP_TYPE(p) (((p) >> 3) & 0x7)
|
||||||
#define EP_TYPE(p) ((p) << 3)
|
#define EP_TYPE(p) ((p) << 3)
|
||||||
#define EP_TYPE_SHIFT (3)
|
|
||||||
#define ISOC_OUT_EP 1
|
#define ISOC_OUT_EP 1
|
||||||
#define BULK_OUT_EP 2
|
#define BULK_OUT_EP 2
|
||||||
#define INT_OUT_EP 3
|
#define INT_OUT_EP 3
|
||||||
@ -649,13 +644,10 @@ struct xhci_ep_ctx {
|
|||||||
/* bit 6 reserved */
|
/* bit 6 reserved */
|
||||||
/* bit 7 is Host Initiate Disable - for disabling stream selection */
|
/* bit 7 is Host Initiate Disable - for disabling stream selection */
|
||||||
#define MAX_BURST(p) (((p)&0xff) << 8)
|
#define MAX_BURST(p) (((p)&0xff) << 8)
|
||||||
#define MAX_BURST_MASK (0xff)
|
|
||||||
#define MAX_BURST_SHIFT (8)
|
|
||||||
#define CTX_TO_MAX_BURST(p) (((p) >> 8) & 0xff)
|
#define CTX_TO_MAX_BURST(p) (((p) >> 8) & 0xff)
|
||||||
#define MAX_PACKET(p) (((p)&0xffff) << 16)
|
#define MAX_PACKET(p) (((p)&0xffff) << 16)
|
||||||
#define MAX_PACKET_MASK (0xffff)
|
#define MAX_PACKET_MASK (0xffff)
|
||||||
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
|
#define MAX_PACKET_DECODED(p) (((p) >> 16) & 0xffff)
|
||||||
#define MAX_PACKET_SHIFT (16)
|
|
||||||
|
|
||||||
/* Get max packet size from ep desc. Bit 10..0 specify the max packet size.
|
/* Get max packet size from ep desc. Bit 10..0 specify the max packet size.
|
||||||
* USB2.0 spec 9.6.6.
|
* USB2.0 spec 9.6.6.
|
||||||
@ -849,10 +841,9 @@ struct xhci_event_cmd {
|
|||||||
/* Normal TRB fields */
|
/* Normal TRB fields */
|
||||||
/* transfer_len bitmasks - bits 0:16 */
|
/* transfer_len bitmasks - bits 0:16 */
|
||||||
#define TRB_LEN(p) ((p) & 0x1ffff)
|
#define TRB_LEN(p) ((p) & 0x1ffff)
|
||||||
#define TRB_LEN_MASK (0x1ffff)
|
/* TD Size, packets remaining in this TD, bits 21:17 (5 bits, so max 31) */
|
||||||
|
#define TRB_TD_SIZE(p) (min((p), (u32)31) << 17)
|
||||||
/* Interrupter Target - which MSI-X vector to target the completion event at */
|
/* Interrupter Target - which MSI-X vector to target the completion event at */
|
||||||
#define TRB_INTR_TARGET_SHIFT (22)
|
|
||||||
#define TRB_INTR_TARGET_MASK (0x3ff)
|
|
||||||
#define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22)
|
#define TRB_INTR_TARGET(p) (((p) & 0x3ff) << 22)
|
||||||
#define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff)
|
#define GET_INTR_TARGET(p) (((p) >> 22) & 0x3ff)
|
||||||
#define TRB_TBC(p) (((p) & 0x3) << 7)
|
#define TRB_TBC(p) (((p) & 0x3) << 7)
|
||||||
@ -882,7 +873,6 @@ struct xhci_event_cmd {
|
|||||||
/* Control transfer TRB specific fields */
|
/* Control transfer TRB specific fields */
|
||||||
#define TRB_DIR_IN (1<<16)
|
#define TRB_DIR_IN (1<<16)
|
||||||
#define TRB_TX_TYPE(p) ((p) << 16)
|
#define TRB_TX_TYPE(p) ((p) << 16)
|
||||||
#define TRB_TX_TYPE_SHIFT (16)
|
|
||||||
#define TRB_DATA_OUT 2
|
#define TRB_DATA_OUT 2
|
||||||
#define TRB_DATA_IN 3
|
#define TRB_DATA_IN 3
|
||||||
|
|
||||||
@ -903,7 +893,6 @@ union xhci_trb {
|
|||||||
/* TRB bit mask */
|
/* TRB bit mask */
|
||||||
#define TRB_TYPE_BITMASK (0xfc00)
|
#define TRB_TYPE_BITMASK (0xfc00)
|
||||||
#define TRB_TYPE(p) ((p) << 10)
|
#define TRB_TYPE(p) ((p) << 10)
|
||||||
#define TRB_TYPE_SHIFT (10)
|
|
||||||
#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10)
|
#define TRB_FIELD_TO_TYPE(p) (((p) & TRB_TYPE_BITMASK) >> 10)
|
||||||
|
|
||||||
/* TRB type IDs */
|
/* TRB type IDs */
|
||||||
@ -1227,6 +1216,9 @@ struct xhci_ctrl {
|
|||||||
struct xhci_scratchpad *scratchpad;
|
struct xhci_scratchpad *scratchpad;
|
||||||
struct xhci_virt_device *devs[MAX_HC_SLOTS];
|
struct xhci_virt_device *devs[MAX_HC_SLOTS];
|
||||||
int rootdev;
|
int rootdev;
|
||||||
|
u16 hci_version;
|
||||||
|
u32 quirks;
|
||||||
|
#define XHCI_MTK_HOST BIT(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
unsigned long trb_addr(struct xhci_segment *seg, union xhci_trb *trb);
|
unsigned long trb_addr(struct xhci_segment *seg, union xhci_trb *trb);
|
||||||
|
Loading…
Reference in New Issue
Block a user