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

Commit 5c199f1d authored by Mayank Rana's avatar Mayank Rana
Browse files

dwc3-msm: Map IPA channel doorbell address with USB device



USB controller needs to ring doorbell to IPA channel. When USB
SMMU stage S1 is enabled, it is must to map IPA channel related
doorbell address with USB device context bank otherwise unmapped
SMMU access related page fault is seen when USB controller tries
to ring the doorbell.

Change-Id: Ic624a9d6b2c0b106edda6a80aafa804bc3051bf9
Signed-off-by: default avatarMayank Rana <mrana@codeaurora.org>
parent 0806caf4
Loading
Loading
Loading
Loading
+22 −40
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017, Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -410,17 +410,17 @@ static int ipa_connect_channels(struct gsi_data_port *d_port)
			ipa_out_channel_out_params.db_reg_phs_addr_lsb);

	d_port->in_channel_handle = ipa_in_channel_out_params.clnt_hdl;
	d_port->in_db_reg_phs_addr_lsb =
	d_port->in_request.db_reg_phs_addr_lsb =
		ipa_in_channel_out_params.db_reg_phs_addr_lsb;
	d_port->in_db_reg_phs_addr_msb =
	d_port->in_request.db_reg_phs_addr_msb =
		ipa_in_channel_out_params.db_reg_phs_addr_msb;

	if (gsi->prot_id != IPA_USB_DIAG) {
		d_port->out_channel_handle =
			ipa_out_channel_out_params.clnt_hdl;
		d_port->out_db_reg_phs_addr_lsb =
		d_port->out_request.db_reg_phs_addr_lsb =
			ipa_out_channel_out_params.db_reg_phs_addr_lsb;
		d_port->out_db_reg_phs_addr_msb =
		d_port->out_request.db_reg_phs_addr_msb =
			ipa_out_channel_out_params.db_reg_phs_addr_msb;
	}
	return ret;
@@ -429,22 +429,19 @@ static int ipa_connect_channels(struct gsi_data_port *d_port)
static void ipa_data_path_enable(struct gsi_data_port *d_port)
{
	struct f_gsi *gsi = d_port_to_gsi(d_port);
	struct usb_gsi_request req;
	u64 dbl_register_addr;
	bool block_db = false;


	log_event_dbg("in_db_reg_phs_addr_lsb = %x",
			gsi->d_port.in_db_reg_phs_addr_lsb);
	log_event_dbg("IN: db_reg_phs_addr_lsb = %x",
			gsi->d_port.in_request.db_reg_phs_addr_lsb);
	usb_gsi_ep_op(gsi->d_port.in_ep,
			(void *)&gsi->d_port.in_db_reg_phs_addr_lsb,
			&gsi->d_port.in_request,
			GSI_EP_OP_STORE_DBL_INFO);

	if (gsi->d_port.out_ep) {
		log_event_dbg("out_db_reg_phs_addr_lsb = %x",
				gsi->d_port.out_db_reg_phs_addr_lsb);
		log_event_dbg("OUT: db_reg_phs_addr_lsb = %x",
				gsi->d_port.out_request.db_reg_phs_addr_lsb);
		usb_gsi_ep_op(gsi->d_port.out_ep,
				(void *)&gsi->d_port.out_db_reg_phs_addr_lsb,
				&gsi->d_port.out_request,
				GSI_EP_OP_STORE_DBL_INFO);

		usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request,
@@ -455,29 +452,12 @@ static void ipa_data_path_enable(struct gsi_data_port *d_port)
	usb_gsi_ep_op(d_port->in_ep, (void *)&block_db,
				GSI_EP_OP_SET_CLR_BLOCK_DBL);

	/* GSI channel DBL address for USB IN endpoint */
	dbl_register_addr = gsi->d_port.in_db_reg_phs_addr_msb;
	dbl_register_addr = dbl_register_addr << 32;
	dbl_register_addr =
		dbl_register_addr | gsi->d_port.in_db_reg_phs_addr_lsb;
	usb_gsi_ep_op(gsi->d_port.in_ep, &gsi->d_port.in_request,
						GSI_EP_OP_RING_DB);

	/* use temp gsi request to pass 64 bit dbl reg addr and num_bufs */
	req.buf_base_addr = &dbl_register_addr;

	req.num_bufs = gsi->d_port.in_request.num_bufs;
	usb_gsi_ep_op(gsi->d_port.in_ep, &req, GSI_EP_OP_RING_DB);

	if (gsi->d_port.out_ep) {
		/* GSI channel DBL address for USB OUT endpoint */
		dbl_register_addr = gsi->d_port.out_db_reg_phs_addr_msb;
		dbl_register_addr = dbl_register_addr << 32;
		dbl_register_addr = dbl_register_addr |
					gsi->d_port.out_db_reg_phs_addr_lsb;
		/* use temp request to pass 64 bit dbl reg addr and num_bufs */
		req.buf_base_addr = &dbl_register_addr;
		req.num_bufs = gsi->d_port.out_request.num_bufs;
		usb_gsi_ep_op(gsi->d_port.out_ep, &req, GSI_EP_OP_RING_DB);
	}
	if (gsi->d_port.out_ep)
		usb_gsi_ep_op(gsi->d_port.out_ep, &gsi->d_port.out_request,
						GSI_EP_OP_RING_DB);
}

static void ipa_disconnect_handler(struct gsi_data_port *d_port)
@@ -494,11 +474,13 @@ static void ipa_disconnect_handler(struct gsi_data_port *d_port)
		 */
		usb_gsi_ep_op(d_port->in_ep, (void *)&block_db,
				GSI_EP_OP_SET_CLR_BLOCK_DBL);
		usb_gsi_ep_op(gsi->d_port.in_ep, NULL, GSI_EP_OP_DISABLE);
		usb_gsi_ep_op(gsi->d_port.in_ep,
				&gsi->d_port.in_request, GSI_EP_OP_DISABLE);
	}

	if (gsi->d_port.out_ep)
		usb_gsi_ep_op(gsi->d_port.out_ep, NULL, GSI_EP_OP_DISABLE);
		usb_gsi_ep_op(gsi->d_port.out_ep,
				&gsi->d_port.out_request, GSI_EP_OP_DISABLE);

	gsi->d_port.net_ready_trigger = false;
}
@@ -3010,7 +2992,7 @@ static ssize_t gsi_info_show(struct config_item *item, char *page)
				gsi->d_port.in_channel_handle);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10x\n", "IN Chnl Dbl Addr: ",
				gsi->d_port.in_db_reg_phs_addr_lsb);
				gsi->d_port.in_request.db_reg_phs_addr_lsb);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10u\n", "IN TRB Ring Len: ",
				ipa_chnl_params->xfer_ring_len);
@@ -3044,7 +3026,7 @@ static ssize_t gsi_info_show(struct config_item *item, char *page)
			gsi->d_port.out_channel_handle);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10x\n", "OUT Channel Dbl Addr: ",
			gsi->d_port.out_db_reg_phs_addr_lsb);
			gsi->d_port.out_request.db_reg_phs_addr_lsb);
		len += scnprintf(buf + len, PAGE_SIZE - len,
		"%25s %10u\n", "OUT TRB Ring Len: ",
			ipa_chnl_params->xfer_ring_len);
+1 −5
Original line number Diff line number Diff line
/*
 * Copyright (c) 2015-2017, The Linux Foundation. All rights reserved.
 * Copyright (c) 2015-2018, The Linux Foundation. All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 and
@@ -218,10 +218,6 @@ struct gsi_data_port {
	struct ipa_usb_teth_params ipa_init_params;
	int in_channel_handle;
	int out_channel_handle;
	u32 in_db_reg_phs_addr_lsb;
	u32 in_db_reg_phs_addr_msb;
	u32 out_db_reg_phs_addr_lsb;
	u32 out_db_reg_phs_addr_msb;
	u32 in_xfer_rsc_index;
	u32 out_xfer_rsc_index;
	u16 in_last_trb_addr;