Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit c7e4b578 authored by Linux Build Service Account's avatar Linux Build Service Account Committed by Gerrit - the friendly Code Review server
Browse files

Merge "sound: usb: Pass device speed instead of dcba information"

parents 42f86311 81156edb
Loading
Loading
Loading
Loading
+26 −50
Original line number Diff line number Diff line
@@ -45,8 +45,7 @@
/*  event ring iova base address */
#define IOVA_BASE 0x1000

#define IOVA_DCBA_BASE 0x2000
#define IOVA_XFER_RING_BASE (IOVA_DCBA_BASE + PAGE_SIZE * (SNDRV_CARDS + 1))
#define IOVA_XFER_RING_BASE (IOVA_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,8 +82,6 @@ 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 */
@@ -101,9 +98,6 @@ 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;
@@ -150,7 +144,6 @@ static struct msg_desc uaudio_stream_ind_desc = {

enum mem_type {
	MEM_EVENT_RING,
	MEM_DCBA,
	MEM_XFER_RING,
	MEM_XFER_BUF,
};
@@ -176,6 +169,24 @@ 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)
{
@@ -275,10 +286,6 @@ 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,
@@ -363,10 +370,7 @@ 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);
@@ -408,8 +412,7 @@ 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, dcba_va = 0,
	xfer_buf_va = 0;
	unsigned long va, tr_data_va = 0, tr_sync_va = 0, xfer_buf_va = 0;
	phys_addr_t xhci_pa, xfer_buf_pa;

	iface = usb_ifnum_to_if(subs->dev, subs->interface);
@@ -588,33 +591,17 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
	resp->xhci_mem_info.evt_ring.size = PAGE_SIZE;
	uaudio_qdev->er_phys_addr = xhci_pa;

	/* dcba */
	xhci_pa = usb_get_dcba_dma_addr(subs->dev);
	if (!xhci_pa) {
		pr_err("%s:failed to get dcba dma address\n", __func__);
	resp->speed_info = get_speed_info(subs->dev->speed);
	if (resp->speed_info == USB_AUDIO_DEVICE_SPEED_INVALID_V01)
		goto unmap_er;
	}

	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;
	resp->speed_info_valid = 1;

	/* 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_dcba;
		goto unmap_er;

	tr_data_va = va;
	resp->xhci_mem_info.tr_data.va = PREPEND_SID_TO_IOVA(va,
@@ -714,8 +701,6 @@ static int prepare_qmi_response(struct snd_usb_substream *subs,
	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:
@@ -761,11 +746,6 @@ 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 */
@@ -1235,11 +1215,7 @@ static int uaudio_qmi_plat_probe(struct platform_device *pdev)
		goto free_domain;
	}

	/* 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;

	/* initialize xfer ring and xfer buf iova list */
	INIT_LIST_HEAD(&uaudio_qdev->xfer_ring_list);
	uaudio_qdev->curr_xfer_ring_iova = IOVA_XFER_RING_BASE;
	uaudio_qdev->xfer_ring_iova_size =