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

Commit 71cb7592 authored by Subramanian Ananthanarayanan's avatar Subramanian Ananthanarayanan Committed by Gerrit - the friendly Code Review server
Browse files

pci: msm: Update NTN3 de-emphasis values via I2C



Change is to update the de-emphasis value of NTN3
via i2c register writes to resolve link failure
issues seen on MBB platforms.

Change-Id: If90e5efc19691a14c3d5f12af78df9ff5c2b2a25
Signed-off-by: default avatarSubramanian Ananthanarayanan <skananth@codeaurora.org>
parent 3ea3b051
Loading
Loading
Loading
Loading
+51 −0
Original line number Diff line number Diff line
@@ -698,6 +698,11 @@ struct msm_pcie_drv_info {
	struct completion completion;
};

struct pcie_i2c_reg_update {
	u32 offset;
	u32 val;
};

/* i2c control interface for a i2c client device */
struct pcie_i2c_ctrl {
	struct i2c_client *client;
@@ -708,6 +713,8 @@ struct pcie_i2c_ctrl {
	u32 ep_reset_gpio_mask;
	u32 *dump_regs;
	u32 dump_reg_count;
	struct pcie_i2c_reg_update *reg_update;
	u32 reg_update_count;

	/* client specific callbacks */
	int (*client_i2c_read)(struct i2c_client *client, u32 reg_addr,
@@ -716,6 +723,7 @@ struct pcie_i2c_ctrl {
				u32 val);
	int (*client_i2c_reset)(struct pcie_i2c_ctrl *i2c_ctrl, bool reset);
	void (*client_i2c_dump_regs)(struct pcie_i2c_ctrl *i2c_ctrl);
	void (*client_i2c_de_emphasis_wa)(struct pcie_i2c_ctrl *i2c_ctrl);
};

enum i2c_client_id {
@@ -4496,6 +4504,28 @@ static void ntn3_dump_regs(struct pcie_i2c_ctrl *i2c_ctrl)
	}
}

static void ntn3_de_emphasis_wa(struct pcie_i2c_ctrl *i2c_ctrl)
{
	int i, val;
	struct msm_pcie_dev_t *pcie_dev = container_of(i2c_ctrl,
						       struct msm_pcie_dev_t,
						       i2c_ctrl);

	PCIE_DBG(pcie_dev, "PCIe: RC%d: NTN3 reg update\n", pcie_dev->rc_idx);

	for (i = 0; i < i2c_ctrl->reg_update_count; i++) {
		i2c_ctrl->client_i2c_write(i2c_ctrl->client, i2c_ctrl->reg_update[i].offset,
					   i2c_ctrl->reg_update[i].val);
		/*Read to make sure writes are completed*/
		i2c_ctrl->client_i2c_read(i2c_ctrl->client, i2c_ctrl->reg_update[i].offset,
					   &val);
		PCIE_DBG(pcie_dev, "PCIe: RC%d: NTN3 reg off:0x%x wr_val:0x%x rd_val:0x%x\n",
			pcie_dev->rc_idx, i2c_ctrl->reg_update[i].offset,
			i2c_ctrl->reg_update[i].val, val);
	}

}

static int msm_pcie_enable(struct msm_pcie_dev_t *dev)
{
	int ret = 0;
@@ -4609,6 +4639,9 @@ static int msm_pcie_enable(struct msm_pcie_dev_t *dev)

	ep_up_timeout = jiffies + usecs_to_jiffies(EP_UP_TIMEOUT_US);

	if (dev->i2c_ctrl.client && dev->i2c_ctrl.client_i2c_de_emphasis_wa)
		dev->i2c_ctrl.client_i2c_de_emphasis_wa(&dev->i2c_ctrl);

	msm_pcie_config_sid(dev);
	msm_pcie_config_controller(dev);

@@ -5909,6 +5942,23 @@ static int msm_pcie_i2c_ctrl_init(struct msm_pcie_dev_t *pcie_dev)
			i2c_ctrl->dump_reg_count = 0;
	}

	of_get_property(i2c_client_node, "reg_update", &size);

	if (size) {
		i2c_ctrl->reg_update = devm_kzalloc(dev, size, GFP_KERNEL);
		if (!i2c_ctrl->reg_update)
			return -ENOMEM;

		i2c_ctrl->reg_update_count = size / sizeof(*i2c_ctrl->reg_update);

		ret = of_property_read_u32_array(i2c_client_node,
						"reg_update",
						(unsigned int *)i2c_ctrl->reg_update,
						size/sizeof(i2c_ctrl->reg_update->offset));
		if (ret)
			i2c_ctrl->reg_update_count = 0;
	}

	return 0;
}

@@ -6982,6 +7032,7 @@ static int pcie_i2c_ctrl_probe(struct i2c_client *client,
		i2c_ctrl->client_i2c_write = ntn3_i2c_write;
		i2c_ctrl->client_i2c_reset = ntn3_ep_reset_ctrl;
		i2c_ctrl->client_i2c_dump_regs = ntn3_dump_regs;
		i2c_ctrl->client_i2c_de_emphasis_wa = ntn3_de_emphasis_wa;
	} else {
		dev_err(&client->dev, "invalid client id %d\n", client_id);
	}