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

Commit 72ba1296 authored by Manu Gautam's avatar Manu Gautam
Browse files

USB: ci13xxx_msm_hsic: Add TLMM initialization support for HSIC



HSIC strobe and data lines are routed from TLMM. Add support to
pass TLMM register map from DT along with reg,value pair to
program strobe/data pads and their calibration setting.

Change-Id: I1f12d800b6e3a1c15fbc81ce4ff81d4297d6a57f
Signed-off-by: default avatarManu Gautam <mgautam@codeaurora.org>
parent 9f7af2ec
Loading
Loading
Loading
Loading
+8 −1
Original line number Diff line number Diff line
@@ -15,13 +15,20 @@ Required properties:

Optional properties :
- qcom,usb-id-core: USB Core Index to be used to bind with gadget driver.
- qcom,hsic-tlmm-init-seq: HSIC TLMM PADS initialization sequence with
  reg, value pairs.
- reg : offset and length of the register set in the memory map.
  This is required if 'qcom,hsic-tlmm-init-seq' is specified.
Example USB HSIC device node :
	hsic: hsic@f9a15000 {
		compatible = "qcom,hsic-peripheral";
		reg = <0xf9a15000 0x352>;
		reg = <0xf9a15000 0x352>,
		      <0x01112000 0xc>;
		interrupts = <0 136 0>;
		qcom,usb-id-core = <1>;
		vdd-supply = <&pmd9635_l2>;
		GDSC-supply = <&gdsc_usb_hsic>;
		qcom,vdd-voltage-level = <0 1200000 1200000>;
		qcom,hsic-tlmm-init-seq =
			<0x8 0x5 0x4 0x5 0x0 0x1>;
	};
+65 −19
Original line number Diff line number Diff line
@@ -56,12 +56,13 @@ struct msm_hsic_per {
	int				vdd_val[3];
	struct regulator		*hsic_gdsc;
	void __iomem			*regs;
	void __iomem			*tlmm_regs;
	int				irq;
	int				async_irq_no;
	atomic_t			in_lpm;
	struct workqueue_struct		*wq;
	struct work_struct		suspend_w;
	struct msm_hsic_peripheral_platform_data *pdata;
	struct ci13xxx_platform_data	*pdata;
	u32				bus_perf_client;
	struct msm_bus_scale_pdata	*bus_scale_table;
	enum usb_vdd_type		vdd_type;
@@ -363,7 +364,22 @@ static void msm_hsic_wakeup(void)

static void msm_hsic_start(void)
{
	int ret;
	struct msm_hsic_per *mhsic = the_mhsic;
	int ret, *seq, seq_count;

	/* Program TLMM pad configuration for HSIC */
	seq = mhsic->pdata->tlmm_init_seq;
	seq_count = mhsic->pdata->tlmm_seq_count;
	if (seq && seq_count) {
		while (seq[0] >= 0 && seq_count > 0) {
			writel_relaxed(seq[1],
					mhsic->tlmm_regs + seq[0]);
			seq += 2;
			seq_count -= 2;
		}
	}
	/* ensure above writes are completed before programming PHY */
	wmb();

	/* programmable length of connect signaling (33.2ns) */
	ret = ulpi_write(the_mhsic, 3, HSIC_DBG1_REG);
@@ -787,7 +803,7 @@ struct ci13xxx_platform_data *msm_hsic_peripheral_dt_to_pdata(
	struct device_node *node = pdev->dev.of_node;
	struct ci13xxx_platform_data *pdata;
	u32 core_id;
	int ret;
	int ret, len;

	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
	if (!pdata)
@@ -799,6 +815,23 @@ struct ci13xxx_platform_data *msm_hsic_peripheral_dt_to_pdata(
	else
		pdata->usb_core_id = (u8)core_id;

	of_get_property(node, "qcom,hsic-tlmm-init-seq", &len);
	if (len) {
		pdata->tlmm_init_seq = devm_kzalloc(&pdev->dev, len,
						    GFP_KERNEL);
		if (!pdata->tlmm_init_seq)
			return NULL;

		pdata->tlmm_seq_count = len / sizeof(*pdata->tlmm_init_seq);
		ret = of_property_read_u32_array(node,
				"qcom,hsic-tlmm-init-seq",
				pdata->tlmm_init_seq, pdata->tlmm_seq_count);
		if (ret) {
			dev_err(&pdev->dev, "hsic init-seq failed:%d\n", ret);
			pdata->tlmm_seq_count = 0;
		}
	}

	return pdata;
}

@@ -834,8 +867,7 @@ static int msm_hsic_probe(struct platform_device *pdev)
	the_mhsic = mhsic;
	platform_set_drvdata(pdev, mhsic);
	mhsic->dev = &pdev->dev;
	mhsic->pdata =
		(struct msm_hsic_peripheral_platform_data *)pdata->prv_data;
	mhsic->pdata = pdata;

	mhsic->irq = platform_get_irq(pdev, 0);
	if (mhsic->irq < 0) {
@@ -874,6 +906,20 @@ static int msm_hsic_probe(struct platform_device *pdev)
	}
	dev_info(&pdev->dev, "HSIC Peripheral regs = %p\n", mhsic->regs);

	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
	if (!res && pdata->tlmm_init_seq) {
		dev_err(&pdev->dev, "Unable to get TLMM memory resource\n");
		ret = -ENODEV;
		goto unmap;
	} else if (res) {
		mhsic->tlmm_regs =  devm_ioremap(&pdev->dev, res->start,
						 resource_size(res));
		if (IS_ERR(mhsic->tlmm_regs)) {
			ret = PTR_ERR(mhsic->tlmm_regs);
			goto unmap;
		}
	}

	ret = msm_hsic_config_gdsc(pdev, mhsic, true);
	if (ret) {
		dev_err(&pdev->dev, "unable to configure hsic gdsc\n");
+2 −0
Original line number Diff line number Diff line
@@ -532,6 +532,8 @@ struct msm_otg {

struct ci13xxx_platform_data {
	u8 usb_core_id;
	int *tlmm_init_seq;
	int tlmm_seq_count;
	/*
	 * value of 2^(log2_itc-1) will be used as the interrupt threshold
	 * (ITC), when log2_itc is between 1 to 7.