From ca3d15e44b795dadff563918a96b99a448d32ec4 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Fri, 4 May 2018 10:14:04 +0530 Subject: [PATCH 1/4] Revert "usb: host: xhci: Remove helper API retuning dcba dma address" This reverts commit 9c1d883952b8430994a302d10aab2bc8130bcd97. Add back helper API to return dcba dma address. Change-Id: I769c42d53f19bbefb65d491823911b39ec620751 Signed-off-by: Ajay Agarwal --- drivers/usb/host/xhci.c | 12 ++++++++++++ include/linux/usb/hcd.h | 2 ++ 2 files changed, 14 insertions(+) diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c index 7e76573c8236..8a4217c0c56c 100644 --- a/drivers/usb/host/xhci.c +++ b/drivers/usb/host/xhci.c @@ -4999,6 +4999,17 @@ dma_addr_t xhci_get_sec_event_ring_dma_addr(struct usb_hcd *hcd, return 0; } +static dma_addr_t xhci_get_dcba_dma_addr(struct usb_hcd *hcd, + struct usb_device *udev) +{ + struct xhci_hcd *xhci = hcd_to_xhci(hcd); + + if (!(xhci->xhc_state & XHCI_STATE_HALTED) && xhci->dcbaa) + return xhci->dcbaa->dev_context_ptrs[udev->slot_id]; + + return 0; +} + dma_addr_t xhci_get_xfer_ring_dma_addr(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep) { @@ -5094,6 +5105,7 @@ static const struct hc_driver xhci_hc_driver = { .sec_event_ring_cleanup = xhci_sec_event_ring_cleanup, .get_sec_event_ring_dma_addr = xhci_get_sec_event_ring_dma_addr, .get_xfer_ring_dma_addr = xhci_get_xfer_ring_dma_addr, + .get_dcba_dma_addr = xhci_get_dcba_dma_addr, .get_core_id = xhci_get_core_id, }; diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 8cbf59e6406b..925401c30abe 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -403,6 +403,8 @@ struct hc_driver { unsigned intr_num); dma_addr_t (*get_xfer_ring_dma_addr)(struct usb_hcd *hcd, struct usb_device *udev, struct usb_host_endpoint *ep); + dma_addr_t (*get_dcba_dma_addr)(struct usb_hcd *hcd, + struct usb_device *udev); int (*get_core_id)(struct usb_hcd *hcd); }; From d2b0c86b23cf583ca513fe7219052ca367da2243 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Fri, 4 May 2018 10:15:01 +0530 Subject: [PATCH 2/4] Revert "usb: core: Remove helper APIs returning dcba dma address" This reverts commit 039bcf340ea35f1e5c4a81f290455570097d7d62. Add back helper APIs to return dcba dma address. Change-Id: Ia65e98691d1a3c241694f07215c12605832f574d Signed-off-by: Ajay Agarwal --- drivers/usb/core/hcd.c | 11 +++++++++++ drivers/usb/core/usb.c | 10 ++++++++++ include/linux/usb.h | 1 + include/linux/usb/hcd.h | 1 + 4 files changed, 23 insertions(+) diff --git a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c index 592f45e6dbac..d7b580cf7f57 100644 --- a/drivers/usb/core/hcd.c +++ b/drivers/usb/core/hcd.c @@ -2241,6 +2241,17 @@ usb_hcd_get_sec_event_ring_dma_addr(struct usb_device *udev, return hcd->driver->get_sec_event_ring_dma_addr(hcd, intr_num); } +dma_addr_t +usb_hcd_get_dcba_dma_addr(struct usb_device *udev) +{ + struct usb_hcd *hcd = bus_to_hcd(udev->bus); + + if (!HCD_RH_RUNNING(hcd)) + return 0; + + return hcd->driver->get_dcba_dma_addr(hcd, udev); +} + dma_addr_t usb_hcd_get_xfer_ring_dma_addr(struct usb_device *udev, struct usb_host_endpoint *ep) diff --git a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c index 65bf86f18a34..e64fd6570a23 100644 --- a/drivers/usb/core/usb.c +++ b/drivers/usb/core/usb.c @@ -697,6 +697,16 @@ usb_get_sec_event_ring_dma_addr(struct usb_device *dev, } EXPORT_SYMBOL(usb_get_sec_event_ring_dma_addr); +dma_addr_t +usb_get_dcba_dma_addr(struct usb_device *dev) +{ + if (dev->state == USB_STATE_NOTATTACHED) + return 0; + + return usb_hcd_get_dcba_dma_addr(dev); +} +EXPORT_SYMBOL(usb_get_dcba_dma_addr); + dma_addr_t usb_get_xfer_ring_dma_addr(struct usb_device *dev, struct usb_host_endpoint *ep) { diff --git a/include/linux/usb.h b/include/linux/usb.h index 1821d34c24a5..2189e292d50c 100644 --- a/include/linux/usb.h +++ b/include/linux/usb.h @@ -753,6 +753,7 @@ extern int usb_sec_event_ring_cleanup(struct usb_device *dev, extern dma_addr_t usb_get_sec_event_ring_dma_addr(struct usb_device *dev, unsigned intr_num); +extern dma_addr_t usb_get_dcba_dma_addr(struct usb_device *dev); extern dma_addr_t usb_get_xfer_ring_dma_addr(struct usb_device *dev, struct usb_host_endpoint *ep); extern int usb_get_controller_id(struct usb_device *dev); diff --git a/include/linux/usb/hcd.h b/include/linux/usb/hcd.h index 925401c30abe..f603b46ff48a 100644 --- a/include/linux/usb/hcd.h +++ b/include/linux/usb/hcd.h @@ -451,6 +451,7 @@ extern int usb_hcd_sec_event_ring_cleanup(struct usb_device *udev, extern dma_addr_t usb_hcd_get_sec_event_ring_dma_addr(struct usb_device *udev, unsigned intr_num); +extern dma_addr_t usb_hcd_get_dcba_dma_addr(struct usb_device *udev); extern dma_addr_t usb_hcd_get_xfer_ring_dma_addr(struct usb_device *udev, struct usb_host_endpoint *ep); From 74e61f1fd5aac27ca6bf6027f0935ad03fcd36bb Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Fri, 4 May 2018 10:15:49 +0530 Subject: [PATCH 3/4] Revert "sound: usb: Pass device speed instead of dcba information" This reverts commit 8177d0955dfdcc7910a261af04d9214018e38d13. ADSP requires dcba memory information. Hence pass it from driver. Change-Id: Ibaf120ba130a24329ef88c7755154e50ba3a7335 Signed-off-by: Ajay Agarwal --- sound/usb/usb_audio_qmi_svc.c | 76 +++++++++++++++++++++++------------ 1 file changed, 50 insertions(+), 26 deletions(-) diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index 0e83ff2877de..519da1369421 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -46,7 +46,8 @@ /* event ring iova base address */ #define IOVA_BASE 0x1000 -#define IOVA_XFER_RING_BASE (IOVA_BASE + PAGE_SIZE * (SNDRV_CARDS + 1)) +#define IOVA_DCBA_BASE 0x2000 +#define IOVA_XFER_RING_BASE (IOVA_DCBA_BASE + PAGE_SIZE * (SNDRV_CARDS + 1)) #define IOVA_XFER_BUF_BASE (IOVA_XFER_RING_BASE + PAGE_SIZE * SNDRV_CARDS * 32) #define IOVA_XFER_RING_MAX (IOVA_XFER_BUF_BASE - PAGE_SIZE) #define IOVA_XFER_BUF_MAX (0xfffff000 - PAGE_SIZE) @@ -83,6 +84,8 @@ struct uaudio_dev { unsigned int card_num; atomic_t in_use; struct kref kref; + unsigned long dcba_iova; + size_t dcba_size; wait_queue_head_t disconnect_wq; /* interface specific */ @@ -99,6 +102,9 @@ struct uaudio_qmi_dev { struct iommu_domain *domain; /* list to keep track of available iova */ + struct list_head dcba_list; + size_t dcba_iova_size; + unsigned long curr_dcba_iova; struct list_head xfer_ring_list; size_t xfer_ring_iova_size; unsigned long curr_xfer_ring_iova; @@ -145,6 +151,7 @@ static struct msg_desc uaudio_stream_ind_desc = { enum mem_type { MEM_EVENT_RING, + MEM_DCBA, MEM_XFER_RING, MEM_XFER_BUF, }; @@ -170,24 +177,6 @@ enum usb_qmi_audio_format { USB_QMI_PCM_FORMAT_U32_BE, }; -static enum usb_audio_device_speed_enum_v01 -get_speed_info(enum usb_device_speed udev_speed) -{ - switch (udev_speed) { - case USB_SPEED_LOW: - return USB_AUDIO_DEVICE_SPEED_LOW_V01; - case USB_SPEED_FULL: - return USB_AUDIO_DEVICE_SPEED_FULL_V01; - case USB_SPEED_HIGH: - return USB_AUDIO_DEVICE_SPEED_HIGH_V01; - case USB_SPEED_SUPER: - return USB_AUDIO_DEVICE_SPEED_SUPER_V01; - default: - pr_err("%s: udev speed %d\n", __func__, udev_speed); - return USB_AUDIO_DEVICE_SPEED_INVALID_V01; - } -} - static unsigned long uaudio_get_iova(unsigned long *curr_iova, size_t *curr_iova_size, struct list_head *head, size_t size) { @@ -287,6 +276,10 @@ static unsigned long uaudio_iommu_map(enum mem_type mtype, phys_addr_t pa, if (uaudio_qdev->er_phys_addr == pa) map = false; break; + case MEM_DCBA: + va = uaudio_get_iova(&uaudio_qdev->curr_dcba_iova, + &uaudio_qdev->dcba_iova_size, &uaudio_qdev->dcba_list, size); + break; case MEM_XFER_RING: va = uaudio_get_iova(&uaudio_qdev->curr_xfer_ring_iova, &uaudio_qdev->xfer_ring_iova_size, &uaudio_qdev->xfer_ring_list, @@ -371,7 +364,10 @@ static void uaudio_iommu_unmap(enum mem_type mtype, unsigned long va, else unmap = false; break; - + case MEM_DCBA: + uaudio_put_iova(va, size, &uaudio_qdev->dcba_list, + &uaudio_qdev->dcba_iova_size); + break; case MEM_XFER_RING: uaudio_put_iova(va, size, &uaudio_qdev->xfer_ring_list, &uaudio_qdev->xfer_ring_iova_size); @@ -413,7 +409,8 @@ static int prepare_qmi_response(struct snd_usb_substream *subs, void *hdr_ptr; u8 *xfer_buf; u32 len, mult, remainder, xfer_buf_len; - unsigned long va, tr_data_va = 0, tr_sync_va = 0, xfer_buf_va = 0; + unsigned long va, tr_data_va = 0, tr_sync_va = 0, dcba_va = 0, + xfer_buf_va = 0; phys_addr_t xhci_pa, xfer_buf_pa; iface = usb_ifnum_to_if(subs->dev, subs->interface); @@ -592,17 +589,33 @@ skip_sync_ep: resp->xhci_mem_info.evt_ring.size = PAGE_SIZE; uaudio_qdev->er_phys_addr = xhci_pa; - resp->speed_info = get_speed_info(subs->dev->speed); - if (resp->speed_info == USB_AUDIO_DEVICE_SPEED_INVALID_V01) + /* dcba */ + xhci_pa = usb_get_dcba_dma_addr(subs->dev); + if (!xhci_pa) { + pr_err("%s:failed to get dcba dma address\n", __func__); goto unmap_er; + } - resp->speed_info_valid = 1; + if (!uadev[card_num].dcba_iova) { /* mappped per usb device */ + va = uaudio_iommu_map(MEM_DCBA, xhci_pa, PAGE_SIZE); + if (!va) + goto unmap_er; + + uadev[card_num].dcba_iova = va; + uadev[card_num].dcba_size = PAGE_SIZE; + } + + dcba_va = uadev[card_num].dcba_iova; + resp->xhci_mem_info.dcba.va = PREPEND_SID_TO_IOVA(dcba_va, + uaudio_qdev->sid); + resp->xhci_mem_info.dcba.pa = xhci_pa; + resp->xhci_mem_info.dcba.size = PAGE_SIZE; /* data transfer ring */ xhci_pa = resp->xhci_mem_info.tr_data.pa; va = uaudio_iommu_map(MEM_XFER_RING, xhci_pa, PAGE_SIZE); if (!va) - goto unmap_er; + goto unmap_dcba; tr_data_va = va; resp->xhci_mem_info.tr_data.va = PREPEND_SID_TO_IOVA(va, @@ -702,6 +715,8 @@ unmap_sync: uaudio_iommu_unmap(MEM_XFER_RING, tr_sync_va, PAGE_SIZE); unmap_data: uaudio_iommu_unmap(MEM_XFER_RING, tr_data_va, PAGE_SIZE); +unmap_dcba: + uaudio_iommu_unmap(MEM_DCBA, dcba_va, PAGE_SIZE); unmap_er: uaudio_iommu_unmap(MEM_EVENT_RING, IOVA_BASE, PAGE_SIZE); err: @@ -747,6 +762,11 @@ static void uaudio_dev_cleanup(struct uaudio_dev *dev) dev->info[if_idx].intf_num, dev->card_num); } + /* iommu_unmap dcba iova for a usb device */ + uaudio_iommu_unmap(MEM_DCBA, dev->dcba_iova, dev->dcba_size); + + dev->dcba_iova = 0; + dev->dcba_size = 0; dev->num_intf = 0; /* free interface info */ @@ -1216,7 +1236,11 @@ static int uaudio_qmi_plat_probe(struct platform_device *pdev) goto free_domain; } - /* initialize xfer ring and xfer buf iova list */ + /* initialize dcba, xfer ring and xfer buf iova list */ + INIT_LIST_HEAD(&uaudio_qdev->dcba_list); + uaudio_qdev->curr_dcba_iova = IOVA_DCBA_BASE; + uaudio_qdev->dcba_iova_size = SNDRV_CARDS * PAGE_SIZE; + INIT_LIST_HEAD(&uaudio_qdev->xfer_ring_list); uaudio_qdev->curr_xfer_ring_iova = IOVA_XFER_RING_BASE; uaudio_qdev->xfer_ring_iova_size = From c342078792a4813368f1127272a26039112decb5 Mon Sep 17 00:00:00 2001 From: Ajay Agarwal Date: Fri, 4 May 2018 10:17:14 +0530 Subject: [PATCH 4/4] Revert "sound: usb: Provide controller number in QMI response" This reverts commit 9730f9cdc0874d372a3eb10680ed8622e26db2bb. Remote entity does not require the controller number. Tunnel mode audio will only work with the primary controller. Hence remove support for providing controller num. Change-Id: Ife8c0ca969334c57046a91bae428b5f89f9e0566 Signed-off-by: Ajay Agarwal --- sound/usb/usb_audio_qmi_svc.c | 7 ------ sound/usb/usb_audio_qmi_v01.c | 40 ----------------------------------- sound/usb/usb_audio_qmi_v01.h | 16 +------------- 3 files changed, 1 insertion(+), 62 deletions(-) diff --git a/sound/usb/usb_audio_qmi_svc.c b/sound/usb/usb_audio_qmi_svc.c index 519da1369421..dc66b6016f8d 100644 --- a/sound/usb/usb_audio_qmi_svc.c +++ b/sound/usb/usb_audio_qmi_svc.c @@ -555,13 +555,6 @@ skip_sync_ep: resp->interrupter_num = uaudio_qdev->intr_num; resp->interrupter_num_valid = 1; - ret = usb_get_controller_id(subs->dev); - if (ret < 0) - goto err; - - resp->controller_num = ret; - resp->controller_num_valid = 1; - /* map xhci data structures PA memory to iova */ /* event ring */ diff --git a/sound/usb/usb_audio_qmi_v01.c b/sound/usb/usb_audio_qmi_v01.c index 9b97fd22a099..beff1aaf4981 100644 --- a/sound/usb/usb_audio_qmi_v01.c +++ b/sound/usb/usb_audio_qmi_v01.c @@ -632,46 +632,6 @@ struct elem_info qmi_uaudio_stream_resp_msg_v01_ei[] = { struct qmi_uaudio_stream_resp_msg_v01, interrupter_num), }, - { - .data_type = QMI_OPT_FLAG, - .elem_len = 1, - .elem_size = sizeof(uint8_t), - .is_array = NO_ARRAY, - .tlv_type = 0x1C, - .offset = offsetof( - struct qmi_uaudio_stream_resp_msg_v01, - speed_info_valid), - }, - { - .data_type = QMI_SIGNED_4_BYTE_ENUM, - .elem_len = 1, - .elem_size = sizeof(enum usb_audio_device_speed_enum_v01), - .is_array = NO_ARRAY, - .tlv_type = 0x1C, - .offset = offsetof( - struct qmi_uaudio_stream_resp_msg_v01, - speed_info), - }, - { - .data_type = QMI_OPT_FLAG, - .elem_len = 1, - .elem_size = sizeof(uint8_t), - .is_array = NO_ARRAY, - .tlv_type = 0x1D, - .offset = offsetof( - struct qmi_uaudio_stream_resp_msg_v01, - controller_num_valid), - }, - { - .data_type = QMI_UNSIGNED_1_BYTE, - .elem_len = 1, - .elem_size = sizeof(uint8_t), - .is_array = NO_ARRAY, - .tlv_type = 0x1D, - .offset = offsetof( - struct qmi_uaudio_stream_resp_msg_v01, - controller_num), - }, { .data_type = QMI_EOTI, .is_array = NO_ARRAY, diff --git a/sound/usb/usb_audio_qmi_v01.h b/sound/usb/usb_audio_qmi_v01.h index 32315fde0907..f3b6eb05d5f0 100644 --- a/sound/usb/usb_audio_qmi_v01.h +++ b/sound/usb/usb_audio_qmi_v01.h @@ -77,16 +77,6 @@ enum usb_audio_device_indication_enum_v01 { USB_AUDIO_DEVICE_INDICATION_ENUM_MAX_VAL_V01 = INT_MAX, }; -enum usb_audio_device_speed_enum_v01 { - USB_AUDIO_DEVICE_SPEED_ENUM_MIN_VAL_V01 = INT_MIN, - USB_AUDIO_DEVICE_SPEED_INVALID_V01 = 0, - USB_AUDIO_DEVICE_SPEED_LOW_V01 = 1, - USB_AUDIO_DEVICE_SPEED_FULL_V01 = 2, - USB_AUDIO_DEVICE_SPEED_HIGH_V01 = 3, - USB_AUDIO_DEVICE_SPEED_SUPER_V01 = 4, - USB_AUDIO_DEVICE_SPEED_ENUM_MAX_VAL_V01 = INT_MAX, -}; - struct qmi_uaudio_stream_req_msg_v01 { uint8_t enable; uint32_t usb_token; @@ -128,12 +118,8 @@ struct qmi_uaudio_stream_resp_msg_v01 { struct apps_mem_info_v01 xhci_mem_info; uint8_t interrupter_num_valid; uint8_t interrupter_num; - uint8_t speed_info_valid; - enum usb_audio_device_speed_enum_v01 speed_info; - uint8_t controller_num_valid; - uint8_t controller_num; }; -#define QMI_UAUDIO_STREAM_RESP_MSG_V01_MAX_MSG_LEN 202 +#define QMI_UAUDIO_STREAM_RESP_MSG_V01_MAX_MSG_LEN 191 extern struct elem_info qmi_uaudio_stream_resp_msg_v01_ei[]; struct qmi_uaudio_stream_ind_msg_v01 {