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

Commit 49dc104d authored by Sujeev Dias's avatar Sujeev Dias Committed by Gerrit - the friendly Code Review server
Browse files

mhi: core: Reorganize mhi event ring configurations in DT



For better clarity, reorganize how MHI event rings
are configured in device node.

CRs-Fixed: 2244344
Change-Id: I27c734668d63bbd98b285360916a3a36c6fb97b4
Signed-off-by: default avatarSujeev Dias <sdias@codeaurora.org>
parent 05d90a59
Loading
Loading
Loading
Loading
+76 −22
Original line number Diff line number Diff line
@@ -65,26 +65,6 @@ Main node properties:
  Value type: Array of <string>
  Definition: Channel names configured in mhi,chan-cfg.

- mhi,ev-cfg
  Usage: required
  Value type: Array of <u32>
  Definition: Array of tuples describe event configuration.
	1st element: Event ring length in elements
	2nd element: Interrupt moderation time in ms
	3rd element: MSI associated with this event ring
	4th element: Dedicated channel number, if it's a dedicated event ring
	5th element: Event ring priority, set to 1 for now
	6th element: Event doorbell mode configuration as defined by
	enum MHI_BRSTMODE
		2 = burst mode disabled
		3 = burst mode enabled
	7th element: Bitwise configuration settings for the channel
		Bit mask:
		BIT(0) : Event ring associated with hardware channels
		BIT(1) : Client manages the event ring (use by napi_poll)
		BIT(2) : Event ring associated with offload channel
		BIT(3) : Event ring dedicated to control events only

- mhi,timeout
  Usage: optional
  Value type: <u32>
@@ -115,6 +95,63 @@ Main node properties:
  Value type: <u32>
  Definition: Size of each segment to allocate for BHIe vector table

==========================
mhi event node properties:
==========================

- mhi,num-elements
  Usage: required
  Value type: <u32>
  Definition: Number of elements event ring support

- mhi,intmod
  Usage: required
  Value type: <u32>
  Definition: interrupt moderation time in ms

- mhi,msi
  Usage: required
  Value type: <u32>
  Definition: MSI associated with this event ring

- mhi,chan
  Usage: optional
  Value type: <u32>
  Definition: Dedicated channel number, if it's a dedicated event ring

- mhi,priority
  Usage: required
  Value type: <u32>
  Definition: Event ring priority, set to 1 for now

- mhi,brstmode
  Usage: required
  Value type: <u32>
  Definition: Event doorbell mode configuration as defined by
	enum MHI_BRSTMODE
		2 = burst mode disabled
		3 = burst mode enabled

- mhi,hw-ev
  Usage: optional
  Value type: <bool>
  Definition: Event ring associated with hardware channels

- mhi,client-manage
  Usage: optional
  Value type: <bool>
  Definition: Client manages the event ring (use by napi_poll)

- mhi,offload
  Usage: optional
  Value type: <bool>
  Definition: Event ring associated with offload channel

- mhi,ctrl-ev
  Usage: optional
  Value type: <bool>
  Definition: Event ring dedicated to control events only

Children node properties:

MHI drivers that require DT can add driver specific information as a child node.
@@ -133,8 +170,25 @@ mhi_controller {
		       <2 64 1 1 2 1 1 0 0>, <3 64 1 2 2 1 1 0 0>;
	mhi,chan-names = "LOOPBACK", "LOOPBACK",
			 "SAHARA", "SAHARA";
	mhi,ev-cfg = <64 1 1 0 1 2 8>
		     <64 1 2 0 1 2 0>;
	mhi_event@0 {
		mhi,num-elements = <32>;
		mhi,intmod = <1>;
		mhi,msi = <1>;
		mhi,chan = <0>;
		mhi,priority = <1>;
		mhi,bstmode = <2>;
		mhi,ctrl-ev;
	};

	mhi_event@1 {
		mhi,num-elements = <256>;
		mhi,intmod = <1>;
		mhi,msi = <2>;
		mhi,chan = <0>;
		mhi,priority = <1>;
		mhi,bstmode = <2>;
	};

	mhi,fw-name = "sbl1.mbn";
	mhi,timeout = <500>;

+135 −0
Original line number Diff line number Diff line
/*
 * Copyright (c) 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
 * only version 2 as published by the Free Software Foundation.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 */

&soc {
	mhi_0: qcom,mhi {
		/* controller specific configuration */
		compatible = "qcom,mhi";
		qcom,pci-domain = <1>;
		qcom,pci-bus = <1>;
		qcom,pci-slot = <0>;
		qcom,smmu-cfg = <0x3>;
		qcom,msm-bus,name = "mhi";
		qcom,msm-bus,num-cases = <2>;
		qcom,msm-bus,num-paths = <1>;
		qcom,msm-bus,vectors-KBps =
					<100 512 0 0>,
					<100 512 1200000000 650000000>;

		/* mhi bus specific settings */
		mhi,max-channels = <106>;
		mhi,chan-cfg =
			<0 64 2 1 2 0 2 0 0>, <1 64 2 2 2 0 2 0 0>,
			<2 128 1 1 2 0 1 0 0>, <3 128 1 2 2 0 1 0 0>,
			<4 64 1 1 2 0 2 0 0>, <5 64 3 2 2 0 2 0 0>,
			<8 64 1 1 2 0 2 0 0>, <9 64 1 2 2 0 2 0 0>,
			<10 64 1 1 2 0 2 0 0>, <11 64 1 2 2 0 2 0 0>,
			<14 64 1 1 2 0 2 0 0>, <15 64 2 2 2 0 2 0 0>,
			<16 64 3 1 2 0 2 0 0>, <17 64 3 2 2 0 2 0 0>,
			<18 64 1 1 2 0 2 0 0>, <19 64 1 2 2 0 2 0 8>,
			<20 64 2 1 2 0 2 1 16>, <21 64 2 2 2 0 2 0 24>,
			<22 64 2 1 2 0 2 0 0>, <23 64 2 2 2 0 2 0 0>,
			<24 64 2 1 2 0 1 0 0>, <25 64 2 2 2 0 1 0 0>,
			<26 64 3 1 2 0 2 0 0>, <27 64 3 2 2 0 2 0 0>,
			<32 64 3 1 2 0 2 0 0>, <33 64 3 2 2 0 2 0 0>,
			<100 512 4 1 3 1 2 1 4>, <101 512 5 2 3 1 2 1 0>;
		mhi,chan-names = "LOOPBACK", "LOOPBACK",
				 "SAHARA", "SAHARA",
				 "DIAG", "DIAG",
				 "QDSS", "QDSS",
				 "EFS", "EFS",
				 "QMI0", "QMI0",
				 "QMI1", "QMI1",
				 "IP_CTRL", "IP_CTRL",
				 "IPCR", "IPCR",
				 "TF", "TF",
				 "BL", "BL",
				 "DCI", "DCI",
				 "DUN", "DUN",
				 "IP_HW0", "IP_HW0";

		mhi,timeout = <2000>;
		status = "disabled";

		#address-cells = <1>;
		#size-cells = <0>;

		mhi_event@0 {
			mhi,num-elements = <32>;
			mhi,intmod = <1>;
			mhi,msi = <1>;
			mhi,priority = <1>;
			mhi,brstmode = <2>;
			mhi,ctrl-ev;
		};

		mhi_event@1 {
			mhi,num-elements = <256>;
			mhi,intmod = <1>;
			mhi,msi = <2>;
			mhi,priority = <1>;
			mhi,brstmode = <2>;
		};

		mhi_event@2 {
			mhi,num-elements = <256>;
			mhi,intmod = <1>;
			mhi,msi = <3>;
			mhi,priority = <1>;
			mhi,brstmode = <2>;
		};

		mhi_event@3 {
			mhi,num-elements = <256>;
			mhi,intmod = <1>;
			mhi,msi = <4>;
			mhi,priority = <1>;
			mhi,brstmode = <2>;
		};

		mhi_event@4 {
			mhi,num-elements = <1024>;
			mhi,intmod = <5>;
			mhi,msi = <5>;
			mhi,chan = <100>;
			mhi,priority = <1>;
			mhi,brstmode = <3>;
			mhi,hw-ev;
		};

		mhi_event@5 {
			mhi,num-elements = <1024>;
			mhi,intmod = <5>;
			mhi,msi = <6>;
			mhi,chan = <101>;
			mhi,priority = <1>;
			mhi,brstmode = <3>;
			mhi,hw-ev;
			mhi,client-manage;
		};

		mhi_netdev_0: mhi_rmnet@0 {
			reg = <0x0>;
			mhi,chan = "IP_HW0";
			mhi,interface-name = "rmnet_mhi";
			mhi,mru = <0x4000>;
		};

		mhi_netdev_1: mhi_rmnet@1 {
			reg = <0x1>;
			mhi,chan = "IP_HW_ADPL";
			mhi,interface-name = "rmnet_mhi";
			mhi,mru = <0x4000>;
		};
	};
};
+1 −67
Original line number Diff line number Diff line
@@ -3465,73 +3465,6 @@
		qcom,smmu-coherent;
		status = "disabled";
	};

	mhi_0: qcom,mhi@0 {
		/* controller specific configuration */
		compatible = "qcom,mhi";
		qcom,pci-domain = <1>;
		qcom,pci-bus = <1>;
		qcom,pci-slot = <0>;
		qcom,smmu-cfg = <0x3>;
		qcom,msm-bus,name = "mhi";
		qcom,msm-bus,num-cases = <2>;
		qcom,msm-bus,num-paths = <1>;
		qcom,msm-bus,vectors-KBps =
					<100 512 0 0>,
					<100 512 1200000000 650000000>;

		/* mhi bus specific settings */
		mhi,max-channels = <106>;
		mhi,chan-cfg =
			<0 64 2 1 2 0 2 0 0>, <1 64 2 2 2 0 2 0 0>,
			<2 128 1 1 2 0 1 0 0>, <3 128 1 2 2 0 1 0 0>,
			<4 64 1 1 2 0 2 0 0>, <5 64 3 2 2 0 2 0 0>,
			<8 64 1 1 2 0 2 0 0>, <9 64 1 2 2 0 2 0 0>,
			<10 64 1 1 2 0 2 0 0>, <11 64 1 2 2 0 2 0 0>,
			<14 64 1 1 2 0 2 0 0>, <15 64 2 2 2 0 2 0 0>,
			<16 64 3 1 2 0 2 0 0>, <17 64 3 2 2 0 2 0 0>,
			<18 64 1 1 2 0 2 0 0>, <19 64 1 2 2 0 2 0 8>,
			<20 64 2 1 2 0 2 1 16>, <21 64 2 2 2 0 2 0 24>,
			<22 64 2 1 2 0 2 0 0>, <23 64 2 2 2 0 2 0 0>,
			<24 64 2 1 2 0 1 0 0>, <25 64 2 2 2 0 1 0 0>,
			<26 64 3 1 2 0 2 0 0>, <27 64 3 2 2 0 2 0 0>,
			<32 64 3 1 2 0 2 0 0>, <33 64 3 2 2 0 2 0 0>,
			<100 512 4 1 3 1 2 1 0x4>, <101 512 5 2 3 1 2 1 0>;
		mhi,chan-names = "LOOPBACK", "LOOPBACK",
				 "SAHARA", "SAHARA",
				 "DIAG", "DIAG",
				 "QDSS", "QDSS",
				 "EFS", "EFS",
				 "QMI0", "QMI0",
				 "QMI1", "QMI1",
				 "IP_CTRL", "IP_CTRL",
				 "IPCR", "IPCR",
				 "TF", "TF",
				 "BL", "BL",
				 "DCI", "DCI",
				 "DUN", "DUN",
				 "IP_HW0", "IP_HW0";
		mhi,ev-cfg = <32 0 1 0 1 2 0x8>,
			     <256 1 2 0 1 2 0>,
			     <256 1 3 0 1 2 0>,
			     <256 1 4 0 1 2 0>,
			     <1024 5 5 100 1 3 0x1>,
			     <1024 5 6 101 1 3 0x3>;
		mhi,timeout = <2000>;
		status = "disabled";

		mhi_netdev_0: mhi_rmnet@0 {
			     mhi,chan = "IP_HW0";
			     mhi,interface-name = "rmnet_mhi";
			     mhi,mru = <0x4000>;
		};

		mhi_netdev_1: mhi_rmnet@1 {
			     mhi,chan = "IP_HW_ADPL";
			     mhi,interface-name = "rmnet_mhi";
			     mhi,mru = <0x4000>;
		};
	};
};

&emac_gdsc {
@@ -3767,3 +3700,4 @@
#include "sm8150-thermal.dtsi"
#include "sm8150-usb.dtsi"
#include "sm8150-gpu.dtsi"
#include "sm8150-mhi.dtsi"
+56 −46
Original line number Diff line number Diff line
@@ -669,83 +669,93 @@ int mhi_device_configure(struct mhi_device *mhi_dev,
static int of_parse_ev_cfg(struct mhi_controller *mhi_cntrl,
			   struct device_node *of_node)
{
	struct {
		u32 ev_cfg[MHI_EV_CFG_MAX];
	} *ev_cfg;
	int num, i, ret;
	int i, ret, num = 0;
	struct mhi_event *mhi_event;
	u32 bit_cfg;
	struct device_node *child;

	num = of_property_count_elems_of_size(of_node, "mhi,ev-cfg",
					      sizeof(*ev_cfg));
	if (num <= 0)
		return -EINVAL;
	for_each_available_child_of_node(of_node, child) {
		if (!strcmp(child->name, "mhi_event"))
			num++;
	}

	ev_cfg = kcalloc(num, sizeof(*ev_cfg), GFP_KERNEL);
	if (!ev_cfg)
		return -ENOMEM;
	if (!num)
		return -EINVAL;

	mhi_cntrl->total_ev_rings = num;
	mhi_cntrl->mhi_event = kcalloc(num, sizeof(*mhi_cntrl->mhi_event),
				       GFP_KERNEL);
	if (!mhi_cntrl->mhi_event) {
		kfree(ev_cfg);
	if (!mhi_cntrl->mhi_event)
		return -ENOMEM;
	}

	ret = of_property_read_u32_array(of_node, "mhi,ev-cfg", (u32 *)ev_cfg,
					 num * sizeof(*ev_cfg) / sizeof(u32));
	/* populate ev ring */
	mhi_event = mhi_cntrl->mhi_event;
	i = 0;
	for_each_available_child_of_node(of_node, child) {
		if (strcmp(child->name, "mhi_event"))
			continue;

		mhi_event->er_index = i++;
		ret = of_property_read_u32(child, "mhi,num-elements",
					   (u32 *)&mhi_event->ring.elements);
		if (ret)
			goto error_ev_cfg;

	/* populate ev ring */
	mhi_event = mhi_cntrl->mhi_event;
	for (i = 0; i < mhi_cntrl->total_ev_rings; i++, mhi_event++) {
		mhi_event->er_index = i;
		mhi_event->ring.elements =
			ev_cfg[i].ev_cfg[MHI_EV_CFG_ELEMENTS];
		mhi_event->intmod = ev_cfg[i].ev_cfg[MHI_EV_CFG_INTMOD];
		mhi_event->msi = ev_cfg[i].ev_cfg[MHI_EV_CFG_MSI];
		mhi_event->chan = ev_cfg[i].ev_cfg[MHI_EV_CFG_CHAN];
		if (mhi_event->chan >= mhi_cntrl->max_chan)
		ret = of_property_read_u32(child, "mhi,intmod",
					   &mhi_event->intmod);
		if (ret)
			goto error_ev_cfg;

		ret = of_property_read_u32(child, "mhi,msi",
					   &mhi_event->msi);
		if (ret)
			goto error_ev_cfg;

		ret = of_property_read_u32(child, "mhi,chan",
					   &mhi_event->chan);
		if (!ret) {
			if (mhi_event->chan >= mhi_cntrl->max_chan)
				goto error_ev_cfg;
			/* this event ring has a dedicated channel */
		if (mhi_event->chan)
			mhi_event->mhi_chan =
				&mhi_cntrl->mhi_chan[mhi_event->chan];
		}

		ret = of_property_read_u32(child, "mhi,priority",
					   &mhi_event->priority);
		if (ret)
			goto error_ev_cfg;

		mhi_event->priority = ev_cfg[i].ev_cfg[MHI_EV_CFG_PRIORITY];
		mhi_event->db_cfg.brstmode =
			ev_cfg[i].ev_cfg[MHI_EV_CFG_BRSTMODE];
		if (MHI_INVALID_BRSTMODE(mhi_event->db_cfg.brstmode))
		ret = of_property_read_u32(child, "mhi,brstmode",
					   &mhi_event->db_cfg.brstmode);
		if (ret || MHI_INVALID_BRSTMODE(mhi_event->db_cfg.brstmode))
			goto error_ev_cfg;

		mhi_event->db_cfg.process_db =
			(mhi_event->db_cfg.brstmode == MHI_BRSTMODE_ENABLE) ?
			mhi_db_brstmode : mhi_db_brstmode_disable;

		bit_cfg = ev_cfg[i].ev_cfg[MHI_EV_CFG_BITCFG];
		if (bit_cfg & MHI_EV_CFG_BIT_HW_EV) {
			mhi_event->hw_ring = true;
		mhi_event->hw_ring = of_property_read_bool(child, "mhi,hw-ev");
		if (mhi_event->hw_ring)
			mhi_cntrl->hw_ev_rings++;
		} else
		else
			mhi_cntrl->sw_ev_rings++;
		mhi_event->cl_manage = of_property_read_bool(child,
							"mhi,client-manage");
		mhi_event->offload_ev = of_property_read_bool(child,
							      "mhi,offload");
		mhi_event->ctrl_ev = of_property_read_bool(child,
							   "mhi,ctrl-ev");

		mhi_event->cl_manage = !!(bit_cfg & MHI_EV_CFG_BIT_CL_MANAGE);
		mhi_event->offload_ev = !!(bit_cfg & MHI_EV_CFG_BIT_OFFLOAD_EV);
		mhi_event->ctrl_ev = !!(bit_cfg & MHI_EV_CFG_BIT_CTRL_EV);
		mhi_event++;
	}

	kfree(ev_cfg);

	/* we need msi for each event ring + additional one for BHI */
	mhi_cntrl->msi_required = mhi_cntrl->total_ev_rings + 1;

	return 0;

error_ev_cfg:
	kfree(ev_cfg);

	kfree(mhi_cntrl->mhi_event);
	return -EINVAL;
}
+0 −16
Original line number Diff line number Diff line
@@ -342,22 +342,6 @@ enum MHI_CH_CFG {
#define MHI_CH_CFG_BIT_PRE_ALLOC BIT(3) /* host allocate buffers for DL */
#define MHI_CH_CFG_BIT_AUTO_START BIT(4) /* host auto start channels */

enum MHI_EV_CFG {
	MHI_EV_CFG_ELEMENTS = 0,
	MHI_EV_CFG_INTMOD = 1,
	MHI_EV_CFG_MSI = 2,
	MHI_EV_CFG_CHAN = 3,
	MHI_EV_CFG_PRIORITY = 4,
	MHI_EV_CFG_BRSTMODE = 5,
	MHI_EV_CFG_BITCFG = 6,
	MHI_EV_CFG_MAX
};

#define MHI_EV_CFG_BIT_HW_EV BIT(0) /* hw event ring */
#define MHI_EV_CFG_BIT_CL_MANAGE BIT(1) /* client manages the event ring */
#define MHI_EV_CFG_BIT_OFFLOAD_EV BIT(2) /* satellite driver manges it */
#define MHI_EV_CFG_BIT_CTRL_EV BIT(3) /* ctrl event ring */

enum MHI_BRSTMODE {
	MHI_BRSTMODE_DISABLE = 0x2,
	MHI_BRSTMODE_ENABLE = 0x3,