mirror of
https://xff.cz/git/u-boot/
synced 2025-09-03 17:52:07 +02:00
usb: xhci: Implement DMA mapping
An XHCI controller that sits behind an IOMMU needs to map and unmap its memory buffers to do DMA. Implement this by inroducing new xhci_dma_map() and xhci_dma_unmap() helper functions. The xhci_dma_map() function replaces the existing xhci_virt_to_bus() function in the sense that it returns the bus address in the case of simple address translation in the absence of an IOMMU. The xhci_bus_to_virt() function is eliminated by storing the CPU address of the allocated scratchpad memory in struct xhci_ctrl. Signed-off-by: Mark Kettenis <kettenis@openbsd.org> Reviewed-by: Marek Vasut <marex@denx.de>
This commit is contained in:
@@ -16,6 +16,7 @@
|
||||
#ifndef HOST_XHCI_H_
|
||||
#define HOST_XHCI_H_
|
||||
|
||||
#include <iommu.h>
|
||||
#include <phys2bus.h>
|
||||
#include <asm/types.h>
|
||||
#include <asm/cache.h>
|
||||
@@ -490,6 +491,7 @@ struct xhci_container_ctx {
|
||||
|
||||
int size;
|
||||
u8 *bytes;
|
||||
dma_addr_t dma;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -688,6 +690,8 @@ struct xhci_input_control_ctx {
|
||||
struct xhci_device_context_array {
|
||||
/* 64-bit device addresses; we only write 32-bit addresses */
|
||||
__le64 dev_context_ptrs[MAX_HC_SLOTS];
|
||||
/* private xHCD pointers */
|
||||
dma_addr_t dma;
|
||||
};
|
||||
/* TODO: write function to set the 64-bit device DMA address */
|
||||
/*
|
||||
@@ -997,6 +1001,7 @@ struct xhci_segment {
|
||||
union xhci_trb *trbs;
|
||||
/* private to HCD */
|
||||
struct xhci_segment *next;
|
||||
dma_addr_t dma;
|
||||
};
|
||||
|
||||
struct xhci_ring {
|
||||
@@ -1025,11 +1030,14 @@ struct xhci_erst_entry {
|
||||
struct xhci_erst {
|
||||
struct xhci_erst_entry *entries;
|
||||
unsigned int num_entries;
|
||||
/* xhci->event_ring keeps track of segment dma addresses */
|
||||
dma_addr_t erst_dma_addr;
|
||||
/* Num entries the ERST can contain */
|
||||
unsigned int erst_size;
|
||||
};
|
||||
|
||||
struct xhci_scratchpad {
|
||||
void *scratchpad;
|
||||
u64 *sp_array;
|
||||
};
|
||||
|
||||
@@ -1216,6 +1224,7 @@ struct xhci_ctrl {
|
||||
struct xhci_virt_device *devs[MAX_HC_SLOTS];
|
||||
int rootdev;
|
||||
u16 hci_version;
|
||||
int page_size;
|
||||
u32 quirks;
|
||||
#define XHCI_MTK_HOST BIT(0)
|
||||
};
|
||||
@@ -1226,7 +1235,7 @@ struct xhci_ctrl {
|
||||
#define xhci_to_dev(_ctrl) NULL
|
||||
#endif
|
||||
|
||||
unsigned long trb_addr(struct xhci_segment *seg, union xhci_trb *trb);
|
||||
dma_addr_t xhci_trb_virt_to_dma(struct xhci_segment *seg, union xhci_trb *trb);
|
||||
struct xhci_input_control_ctx
|
||||
*xhci_get_input_control_ctx(struct xhci_container_ctx *ctx);
|
||||
struct xhci_slot_ctx *xhci_get_slot_ctx(struct xhci_ctrl *ctrl,
|
||||
@@ -1243,7 +1252,7 @@ void xhci_slot_copy(struct xhci_ctrl *ctrl,
|
||||
struct xhci_container_ctx *out_ctx);
|
||||
void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl,
|
||||
struct usb_device *udev, int hop_portnr);
|
||||
void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr,
|
||||
void xhci_queue_command(struct xhci_ctrl *ctrl, dma_addr_t addr,
|
||||
u32 slot_id, u32 ep_index, trb_type cmd);
|
||||
void xhci_acknowledge_event(struct xhci_ctrl *ctrl);
|
||||
union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected);
|
||||
@@ -1284,14 +1293,22 @@ extern struct dm_usb_ops xhci_usb_ops;
|
||||
|
||||
struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev);
|
||||
|
||||
static inline dma_addr_t xhci_virt_to_bus(struct xhci_ctrl *ctrl, void *addr)
|
||||
static inline dma_addr_t xhci_dma_map(struct xhci_ctrl *ctrl, void *addr,
|
||||
size_t size)
|
||||
{
|
||||
#if CONFIG_IS_ENABLED(IOMMU)
|
||||
return dev_iommu_dma_map(xhci_to_dev(ctrl), addr, size);
|
||||
#else
|
||||
return dev_phys_to_bus(xhci_to_dev(ctrl), virt_to_phys(addr));
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline void *xhci_bus_to_virt(struct xhci_ctrl *ctrl, dma_addr_t addr)
|
||||
static inline void xhci_dma_unmap(struct xhci_ctrl *ctrl, dma_addr_t addr,
|
||||
size_t size)
|
||||
{
|
||||
return phys_to_virt(dev_bus_to_phys(xhci_to_dev(ctrl), addr));
|
||||
#if CONFIG_IS_ENABLED(IOMMU)
|
||||
dev_iommu_dma_unmap(xhci_to_dev(ctrl), addr, size);
|
||||
#endif
|
||||
}
|
||||
|
||||
#endif /* HOST_XHCI_H_ */
|
||||
|
Reference in New Issue
Block a user