// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2018, The Linux Foundation. All rights reserved.
 * datasheet: https://www.ti.com/lit/ds/symlink/sn65dsi86.pdf
 */

#include <linux/atomic.h>
#include <linux/auxiliary_bus.h>
#include <linux/bitfield.h>
#include <linux/bits.h>
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/gpio/consumer.h>
#include <linux/gpio/driver.h>
#include <linux/i2c.h>
#include <linux/iopoll.h>
#include <linux/module.h>
#include <linux/of_graph.h>
#include <linux/pm_runtime.h>
#include <linux/pwm.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>

#include <asm/unaligned.h>

#include <drm/display/drm_dp_aux_bus.h>
#include <drm/display/drm_dp_helper.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_bridge_connector.h>
#include <drm/drm_edid.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_of.h>
#include <drm/drm_panel.h>
#include <drm/drm_print.h>
#include <drm/drm_probe_helper.h>

#define SN_DEVICE_REV_REG			0x08
#define SN_DPPLL_SRC_REG			0x0A
#define  DPPLL_CLK_SRC_DSICLK			BIT(0)
#define  REFCLK_FREQ_MASK			GENMASK(3, 1)
#define  REFCLK_FREQ(x)				((x) << 1)
#define  DPPLL_SRC_DP_PLL_LOCK			BIT(7)
#define SN_PLL_ENABLE_REG			0x0D
#define SN_DSI_LANES_REG			0x10
#define  CHA_DSI_LANES_MASK			GENMASK(4, 3)
#define  CHA_DSI_LANES(x)			((x) << 3)
#define SN_DSIA_CLK_FREQ_REG			0x12
#define SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG	0x20
#define SN_CHA_VERTICAL_DISPLAY_SIZE_LOW_REG	0x24
#define SN_CHA_HSYNC_PULSE_WIDTH_LOW_REG	0x2C
#define SN_CHA_HSYNC_PULSE_WIDTH_HIGH_REG	0x2D
#define  CHA_HSYNC_POLARITY			BIT(7)
#define SN_CHA_VSYNC_PULSE_WIDTH_LOW_REG	0x30
#define SN_CHA_VSYNC_PULSE_WIDTH_HIGH_REG	0x31
#define  CHA_VSYNC_POLARITY			BIT(7)
#define SN_CHA_HORIZONTAL_BACK_PORCH_REG	0x34
#define SN_CHA_VERTICAL_BACK_PORCH_REG		0x36
#define SN_CHA_HORIZONTAL_FRONT_PORCH_REG	0x38
#define SN_CHA_VERTICAL_FRONT_PORCH_REG		0x3A
#define SN_LN_ASSIGN_REG			0x59
#define  LN_ASSIGN_WIDTH			2
#define SN_ENH_FRAME_REG			0x5A
#define  VSTREAM_ENABLE				BIT(3)
#define  LN_POLRS_OFFSET			4
#define  LN_POLRS_MASK				0xf0
#define SN_DATA_FORMAT_REG			0x5B
#define  BPP_18_RGB				BIT(0)
#define SN_HPD_DISABLE_REG			0x5C
#define  HPD_DISABLE				BIT(0)
#define  HPD_DEBOUNCED_STATE			BIT(4)
#define SN_GPIO_IO_REG				0x5E
#define  SN_GPIO_INPUT_SHIFT			4
#define  SN_GPIO_OUTPUT_SHIFT			0
#define SN_GPIO_CTRL_REG			0x5F
#define  SN_GPIO_MUX_INPUT			0
#define  SN_GPIO_MUX_OUTPUT			1
#define  SN_GPIO_MUX_SPECIAL			2
#define  SN_GPIO_MUX_MASK			0x3
#define SN_AUX_WDATA_REG(x)			(0x64 + (x))
#define SN_AUX_ADDR_19_16_REG			0x74
#define SN_AUX_ADDR_15_8_REG			0x75
#define SN_AUX_ADDR_7_0_REG			0x76
#define SN_AUX_ADDR_MASK			GENMASK(19, 0)
#define SN_AUX_LENGTH_REG			0x77
#define SN_AUX_CMD_REG				0x78
#define  AUX_CMD_SEND				BIT(0)
#define  AUX_CMD_REQ(x)				((x) << 4)
#define SN_AUX_RDATA_REG(x)			(0x79 + (x))
#define SN_SSC_CONFIG_REG			0x93
#define  DP_NUM_LANES_MASK			GENMASK(5, 4)
#define  DP_NUM_LANES(x)			((x) << 4)
#define SN_DATARATE_CONFIG_REG			0x94
#define  DP_DATARATE_MASK			GENMASK(7, 5)
#define  DP_DATARATE(x)				((x) << 5)
#define SN_TRAINING_SETTING_REG			0x95
#define  SCRAMBLE_DISABLE			BIT(4)
#define SN_ML_TX_MODE_REG			0x96
#define  ML_TX_MAIN_LINK_OFF			0
#define  ML_TX_NORMAL_MODE			BIT(0)
#define SN_PWM_PRE_DIV_REG			0xA0
#define SN_BACKLIGHT_SCALE_REG			0xA1
#define  BACKLIGHT_SCALE_MAX			0xFFFF
#define SN_BACKLIGHT_REG			0xA3
#define SN_PWM_EN_INV_REG			0xA5
#define  SN_PWM_INV_MASK			BIT(0)
#define  SN_PWM_EN_MASK				BIT(1)
#define SN_AUX_CMD_STATUS_REG			0xF4
#define  AUX_IRQ_STATUS_AUX_RPLY_TOUT		BIT(3)
#define  AUX_IRQ_STATUS_AUX_SHORT		BIT(5)
#define  AUX_IRQ_STATUS_NAT_I2C_FAIL		BIT(6)

#define MIN_DSI_CLK_FREQ_MHZ	40

/* fudge factor required to account for 8b/10b encoding */
#define DP_CLK_FUDGE_NUM	10
#define DP_CLK_FUDGE_DEN	8

/* Matches DP_AUX_MAX_PAYLOAD_BYTES (for now) */
#define SN_AUX_MAX_PAYLOAD_BYTES	16

#define SN_REGULATOR_SUPPLY_NUM		4

#define SN_MAX_DP_LANES			4
#define SN_NUM_GPIOS			4
#define SN_GPIO_PHYSICAL_OFFSET		1

#define SN_LINK_TRAINING_TRIES		10

#define SN_PWM_GPIO_IDX			3 /* 4th GPIO */

/**
 * struct ti_sn65dsi86 - Platform data for ti-sn65dsi86 driver.
 * @bridge_aux:   AUX-bus sub device for MIPI-to-eDP bridge functionality.
 * @gpio_aux:     AUX-bus sub device for GPIO controller functionality.
 * @aux_aux:      AUX-bus sub device for eDP AUX channel functionality.
 * @pwm_aux:      AUX-bus sub device for PWM controller functionality.
 *
 * @dev:          Pointer to the top level (i2c) device.
 * @regmap:       Regmap for accessing i2c.
 * @aux:          Our aux channel.
 * @bridge:       Our bridge.
 * @connector:    Our connector.
 * @host_node:    Remote DSI node.
 * @dsi:          Our MIPI DSI source.
 * @refclk:       Our reference clock.
 * @next_bridge:  The bridge on the eDP side.
 * @enable_gpio:  The GPIO we toggle to enable the bridge.
 * @supplies:     Data for bulk enabling/disabling our regulators.
 * @dp_lanes:     Count of dp_lanes we're using.
 * @ln_assign:    Value to program to the LN_ASSIGN register.
 * @ln_polrs:     Value for the 4-bit LN_POLRS field of SN_ENH_FRAME_REG.
 * @comms_enabled: If true then communication over the aux channel is enabled.
 * @comms_mutex:   Protects modification of comms_enabled.
 *
 * @gchip:        If we expose our GPIOs, this is used.
 * @gchip_output: A cache of whether we've set GPIOs to output.  This
 *                serves double-duty of keeping track of the direction and
 *                also keeping track of whether we've incremented the
 *                pm_runtime reference count for this pin, which we do
 *                whenever a pin is configured as an output.  This is a
 *                bitmap so we can do atomic ops on it without an extra
 *                lock so concurrent users of our 4 GPIOs don't stomp on
 *                each other's read-modify-write.
 *
 * @pchip:        pwm_chip if the PWM is exposed.
 * @pwm_enabled:  Used to track if the PWM signal is currently enabled.
 * @pwm_pin_busy: Track if GPIO4 is currently requested for GPIO or PWM.
 * @pwm_refclk_freq: Cache for the reference clock input to the PWM.
 */
struct ti_sn65dsi86 {
	struct auxiliary_device		*bridge_aux;
	struct auxiliary_device		*gpio_aux;
	struct auxiliary_device		*aux_aux;
	struct auxiliary_device		*pwm_aux;

	struct device			*dev;
	struct regmap			*regmap;
	struct drm_dp_aux		aux;
	struct drm_bridge		bridge;
	struct drm_connector		*connector;
	struct device_node		*host_node;
	struct mipi_dsi_device		*dsi;
	struct clk			*refclk;
	struct drm_bridge		*next_bridge;
	struct gpio_desc		*enable_gpio;
	struct regulator_bulk_data	supplies[SN_REGULATOR_SUPPLY_NUM];
	int				dp_lanes;
	u8				ln_assign;
	u8				ln_polrs;
	bool				comms_enabled;
	struct mutex			comms_mutex;

#if defined(CONFIG_OF_GPIO)
	struct gpio_chip		gchip;
	DECLARE_BITMAP(gchip_output, SN_NUM_GPIOS);
#endif
#if defined(CONFIG_PWM)
	struct pwm_chip			*pchip;
	bool				pwm_enabled;
	atomic_t			pwm_pin_busy;
#endif
	unsigned int			pwm_refclk_freq;
};

static const struct regmap_range ti_sn65dsi86_volatile_ranges[] = {
	{ .range_min = 0, .range_max = 0xFF },
};

static const struct regmap_access_table ti_sn_bridge_volatile_table = {
	.yes_ranges = ti_sn65dsi86_volatile_ranges,
	.n_yes_ranges = ARRAY_SIZE(ti_sn65dsi86_volatile_ranges),
};

static const struct regmap_config ti_sn65dsi86_regmap_config = {
	.reg_bits = 8,
	.val_bits = 8,
	.volatile_table = &ti_sn_bridge_volatile_table,
	.cache_type = REGCACHE_NONE,
	.max_register = 0xFF,
};

static int __maybe_unused ti_sn65dsi86_read_u16(struct ti_sn65dsi86 *pdata,
						unsigned int reg, u16 *val)
{
	u8 buf[2];
	int ret;

	ret = regmap_bulk_read(pdata->regmap, reg, buf, ARRAY_SIZE(buf));
	if (ret)
		return ret;

	*val = buf[0] | (buf[1] << 8);

	return 0;
}

static void ti_sn65dsi86_write_u16(struct ti_sn65dsi86 *pdata,
				   unsigned int reg, u16 val)
{
	u8 buf[2] = { val & 0xff, val >> 8 };

	regmap_bulk_write(pdata->regmap, reg, buf, ARRAY_SIZE(buf));
}

static u32 ti_sn_bridge_get_dsi_freq(struct ti_sn65dsi86 *pdata)
{
	u32 bit_rate_khz, clk_freq_khz;
	struct drm_display_mode *mode =
		&pdata->bridge.encoder->crtc->state->adjusted_mode;

	bit_rate_khz = mode->clock *
			mipi_dsi_pixel_format_to_bpp(pdata->dsi->format);
	clk_freq_khz = bit_rate_khz / (pdata->dsi->lanes * 2);

	return clk_freq_khz;
}

/* clk frequencies supported by bridge in Hz in case derived from REFCLK pin */
static const u32 ti_sn_bridge_refclk_lut[] = {
	12000000,
	19200000,
	26000000,
	27000000,
	38400000,
};

/* clk frequencies supported by bridge in Hz in case derived from DACP/N pin */
static const u32 ti_sn_bridge_dsiclk_lut[] = {
	468000000,
	384000000,
	416000000,
	486000000,
	460800000,
};

static void ti_sn_bridge_set_refclk_freq(struct ti_sn65dsi86 *pdata)
{
	int i;
	u32 refclk_rate;
	const u32 *refclk_lut;
	size_t refclk_lut_size;

	if (pdata->refclk) {
		refclk_rate = clk_get_rate(pdata->refclk);
		refclk_lut = ti_sn_bridge_refclk_lut;
		refclk_lut_size = ARRAY_SIZE(ti_sn_bridge_refclk_lut);
		clk_prepare_enable(pdata->refclk);
	} else {
		refclk_rate = ti_sn_bridge_get_dsi_freq(pdata) * 1000;
		refclk_lut = ti_sn_bridge_dsiclk_lut;
		refclk_lut_size = ARRAY_SIZE(ti_sn_bridge_dsiclk_lut);
	}

	/* for i equals to refclk_lut_size means default frequency */
	for (i = 0; i < refclk_lut_size; i++)
		if (refclk_lut[i] == refclk_rate)
			break;

	/* avoid buffer overflow and "1" is the default rate in the datasheet. */
	if (i >= refclk_lut_size)
		i = 1;

	regmap_update_bits(pdata->regmap, SN_DPPLL_SRC_REG, REFCLK_FREQ_MASK,
			   REFCLK_FREQ(i));

	/*
	 * The PWM refclk is based on the value written to SN_DPPLL_SRC_REG,
	 * regardless of its actual sourcing.
	 */
	pdata->pwm_refclk_freq = ti_sn_bridge_refclk_lut[i];
}

static void ti_sn65dsi86_enable_comms(struct ti_sn65dsi86 *pdata)
{
	mutex_lock(&pdata->comms_mutex);

	/* configure bridge ref_clk */
	ti_sn_bridge_set_refclk_freq(pdata);

	/*
	 * HPD on this bridge chip is a bit useless.  This is an eDP bridge
	 * so the HPD is an internal signal that's only there to signal that
	 * the panel is done powering up.  ...but the bridge chip debounces
	 * this signal by between 100 ms and 400 ms (depending on process,
	 * voltage, and temperate--I measured it at about 200 ms).  One
	 * particular panel asserted HPD 84 ms after it was powered on meaning
	 * that we saw HPD 284 ms after power on.  ...but the same panel said
	 * that instead of looking at HPD you could just hardcode a delay of
	 * 200 ms.  We'll assume that the panel driver will have the hardcoded
	 * delay in its prepare and always disable HPD.
	 *
	 * If HPD somehow makes sense on some future panel we'll have to
	 * change this to be conditional on someone specifying that HPD should
	 * be used.
	 */
	regmap_update_bits(pdata->regmap, SN_HPD_DISABLE_REG, HPD_DISABLE,
			   HPD_DISABLE);

	pdata->comms_enabled = true;

	mutex_unlock(&pdata->comms_mutex);
}

static void ti_sn65dsi86_disable_comms(struct ti_sn65dsi86 *pdata)
{
	mutex_lock(&pdata->comms_mutex);

	pdata->comms_enabled = false;
	clk_disable_unprepare(pdata->refclk);

	mutex_unlock(&pdata->comms_mutex);
}

static int __maybe_unused ti_sn65dsi86_resume(struct device *dev)
{
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(dev);
	int ret;

	ret = regulator_bulk_enable(SN_REGULATOR_SUPPLY_NUM, pdata->supplies);
	if (ret) {
		DRM_ERROR("failed to enable supplies %d\n", ret);
		return ret;
	}

	/* td2: min 100 us after regulators before enabling the GPIO */
	usleep_range(100, 110);

	gpiod_set_value_cansleep(pdata->enable_gpio, 1);

	/*
	 * If we have a reference clock we can enable communication w/ the
	 * panel (including the aux channel) w/out any need for an input clock
	 * so we can do it in resume which lets us read the EDID before
	 * pre_enable(). Without a reference clock we need the MIPI reference
	 * clock so reading early doesn't work.
	 */
	if (pdata->refclk)
		ti_sn65dsi86_enable_comms(pdata);

	return ret;
}

static int __maybe_unused ti_sn65dsi86_suspend(struct device *dev)
{
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(dev);
	int ret;

	if (pdata->refclk)
		ti_sn65dsi86_disable_comms(pdata);

	gpiod_set_value_cansleep(pdata->enable_gpio, 0);

	ret = regulator_bulk_disable(SN_REGULATOR_SUPPLY_NUM, pdata->supplies);
	if (ret)
		DRM_ERROR("failed to disable supplies %d\n", ret);

	return ret;
}

static const struct dev_pm_ops ti_sn65dsi86_pm_ops = {
	SET_RUNTIME_PM_OPS(ti_sn65dsi86_suspend, ti_sn65dsi86_resume, NULL)
	SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend,
				pm_runtime_force_resume)
};

static int status_show(struct seq_file *s, void *data)
{
	struct ti_sn65dsi86 *pdata = s->private;
	unsigned int reg, val;

	seq_puts(s, "STATUS REGISTERS:\n");

	pm_runtime_get_sync(pdata->dev);

	/* IRQ Status Registers, see Table 31 in datasheet */
	for (reg = 0xf0; reg <= 0xf8; reg++) {
		regmap_read(pdata->regmap, reg, &val);
		seq_printf(s, "[0x%02x] = 0x%08x\n", reg, val);
	}

	pm_runtime_put_autosuspend(pdata->dev);

	return 0;
}

DEFINE_SHOW_ATTRIBUTE(status);

static void ti_sn65dsi86_debugfs_remove(void *data)
{
	debugfs_remove_recursive(data);
}

static void ti_sn65dsi86_debugfs_init(struct ti_sn65dsi86 *pdata)
{
	struct device *dev = pdata->dev;
	struct dentry *debugfs;
	int ret;

	debugfs = debugfs_create_dir(dev_name(dev), NULL);

	/*
	 * We might get an error back if debugfs wasn't enabled in the kernel
	 * so let's just silently return upon failure.
	 */
	if (IS_ERR_OR_NULL(debugfs))
		return;

	ret = devm_add_action_or_reset(dev, ti_sn65dsi86_debugfs_remove, debugfs);
	if (ret)
		return;

	debugfs_create_file("status", 0600, debugfs, pdata, &status_fops);
}

/* -----------------------------------------------------------------------------
 * Auxiliary Devices (*not* AUX)
 */

static void ti_sn65dsi86_uninit_aux(void *data)
{
	auxiliary_device_uninit(data);
}

static void ti_sn65dsi86_delete_aux(void *data)
{
	auxiliary_device_delete(data);
}

static void ti_sn65dsi86_aux_device_release(struct device *dev)
{
	struct auxiliary_device *aux = container_of(dev, struct auxiliary_device, dev);

	kfree(aux);
}

static int ti_sn65dsi86_add_aux_device(struct ti_sn65dsi86 *pdata,
				       struct auxiliary_device **aux_out,
				       const char *name)
{
	struct device *dev = pdata->dev;
	struct auxiliary_device *aux;
	int ret;

	aux = kzalloc(sizeof(*aux), GFP_KERNEL);
	if (!aux)
		return -ENOMEM;

	aux->name = name;
	aux->dev.parent = dev;
	aux->dev.release = ti_sn65dsi86_aux_device_release;
	device_set_of_node_from_dev(&aux->dev, dev);
	ret = auxiliary_device_init(aux);
	if (ret) {
		kfree(aux);
		return ret;
	}
	ret = devm_add_action_or_reset(dev, ti_sn65dsi86_uninit_aux, aux);
	if (ret)
		return ret;

	ret = auxiliary_device_add(aux);
	if (ret)
		return ret;
	ret = devm_add_action_or_reset(dev, ti_sn65dsi86_delete_aux, aux);
	if (!ret)
		*aux_out = aux;

	return ret;
}

/* -----------------------------------------------------------------------------
 * AUX Adapter
 */

static struct ti_sn65dsi86 *aux_to_ti_sn65dsi86(struct drm_dp_aux *aux)
{
	return container_of(aux, struct ti_sn65dsi86, aux);
}

static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
				  struct drm_dp_aux_msg *msg)
{
	struct ti_sn65dsi86 *pdata = aux_to_ti_sn65dsi86(aux);
	u32 request = msg->request & ~(DP_AUX_I2C_MOT | DP_AUX_I2C_WRITE_STATUS_UPDATE);
	u32 request_val = AUX_CMD_REQ(msg->request);
	u8 *buf = msg->buffer;
	unsigned int len = msg->size;
	unsigned int short_len;
	unsigned int val;
	int ret;
	u8 addr_len[SN_AUX_LENGTH_REG + 1 - SN_AUX_ADDR_19_16_REG];

	if (len > SN_AUX_MAX_PAYLOAD_BYTES)
		return -EINVAL;

	pm_runtime_get_sync(pdata->dev);
	mutex_lock(&pdata->comms_mutex);

	/*
	 * If someone tries to do a DDC over AUX transaction before pre_enable()
	 * on a device without a dedicated reference clock then we just can't
	 * do it. Fail right away. This prevents non-refclk users from reading
	 * the EDID before enabling the panel but such is life.
	 */
	if (!pdata->comms_enabled) {
		ret = -EIO;
		goto exit;
	}

	switch (request) {
	case DP_AUX_NATIVE_WRITE:
	case DP_AUX_I2C_WRITE:
	case DP_AUX_NATIVE_READ:
	case DP_AUX_I2C_READ:
		regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val);
		/* Assume it's good */
		msg->reply = 0;
		break;
	default:
		ret = -EINVAL;
		goto exit;
	}

	BUILD_BUG_ON(sizeof(addr_len) != sizeof(__be32));
	put_unaligned_be32((msg->address & SN_AUX_ADDR_MASK) << 8 | len,
			   addr_len);
	regmap_bulk_write(pdata->regmap, SN_AUX_ADDR_19_16_REG, addr_len,
			  ARRAY_SIZE(addr_len));

	if (request == DP_AUX_NATIVE_WRITE || request == DP_AUX_I2C_WRITE)
		regmap_bulk_write(pdata->regmap, SN_AUX_WDATA_REG(0), buf, len);

	/* Clear old status bits before start so we don't get confused */
	regmap_write(pdata->regmap, SN_AUX_CMD_STATUS_REG,
		     AUX_IRQ_STATUS_NAT_I2C_FAIL |
		     AUX_IRQ_STATUS_AUX_RPLY_TOUT |
		     AUX_IRQ_STATUS_AUX_SHORT);

	regmap_write(pdata->regmap, SN_AUX_CMD_REG, request_val | AUX_CMD_SEND);

	/* Zero delay loop because i2c transactions are slow already */
	ret = regmap_read_poll_timeout(pdata->regmap, SN_AUX_CMD_REG, val,
				       !(val & AUX_CMD_SEND), 0, 50 * 1000);
	if (ret)
		goto exit;

	ret = regmap_read(pdata->regmap, SN_AUX_CMD_STATUS_REG, &val);
	if (ret)
		goto exit;

	if (val & AUX_IRQ_STATUS_AUX_RPLY_TOUT) {
		/*
		 * The hardware tried the message seven times per the DP spec
		 * but it hit a timeout. We ignore defers here because they're
		 * handled in hardware.
		 */
		ret = -ETIMEDOUT;
		goto exit;
	}

	if (val & AUX_IRQ_STATUS_AUX_SHORT) {
		ret = regmap_read(pdata->regmap, SN_AUX_LENGTH_REG, &short_len);
		len = min(len, short_len);
		if (ret)
			goto exit;
	} else if (val & AUX_IRQ_STATUS_NAT_I2C_FAIL) {
		switch (request) {
		case DP_AUX_I2C_WRITE:
		case DP_AUX_I2C_READ:
			msg->reply |= DP_AUX_I2C_REPLY_NACK;
			break;
		case DP_AUX_NATIVE_READ:
		case DP_AUX_NATIVE_WRITE:
			msg->reply |= DP_AUX_NATIVE_REPLY_NACK;
			break;
		}
		len = 0;
		goto exit;
	}

	if (request != DP_AUX_NATIVE_WRITE && request != DP_AUX_I2C_WRITE && len != 0)
		ret = regmap_bulk_read(pdata->regmap, SN_AUX_RDATA_REG(0), buf, len);

exit:
	mutex_unlock(&pdata->comms_mutex);
	pm_runtime_mark_last_busy(pdata->dev);
	pm_runtime_put_autosuspend(pdata->dev);

	if (ret)
		return ret;
	return len;
}

static int ti_sn_aux_wait_hpd_asserted(struct drm_dp_aux *aux, unsigned long wait_us)
{
	/*
	 * The HPD in this chip is a bit useless (See comment in
	 * ti_sn65dsi86_enable_comms) so if our driver is expected to wait
	 * for HPD, we just assume it's asserted after the wait_us delay.
	 *
	 * In case we are asked to wait forever (wait_us=0) take conservative
	 * 500ms delay.
	 */
	if (wait_us == 0)
		wait_us = 500000;

	usleep_range(wait_us, wait_us + 1000);

	return 0;
}

static int ti_sn_aux_probe(struct auxiliary_device *adev,
			   const struct auxiliary_device_id *id)
{
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);
	int ret;

	pdata->aux.name = "ti-sn65dsi86-aux";
	pdata->aux.dev = &adev->dev;
	pdata->aux.transfer = ti_sn_aux_transfer;
	pdata->aux.wait_hpd_asserted = ti_sn_aux_wait_hpd_asserted;
	drm_dp_aux_init(&pdata->aux);

	ret = devm_of_dp_aux_populate_ep_devices(&pdata->aux);
	if (ret)
		return ret;

	/*
	 * The eDP to MIPI bridge parts don't work until the AUX channel is
	 * setup so we don't add it in the main driver probe, we add it now.
	 */
	return ti_sn65dsi86_add_aux_device(pdata, &pdata->bridge_aux, "bridge");
}

static const struct auxiliary_device_id ti_sn_aux_id_table[] = {
	{ .name = "ti_sn65dsi86.aux", },
	{},
};

static struct auxiliary_driver ti_sn_aux_driver = {
	.name = "aux",
	.probe = ti_sn_aux_probe,
	.id_table = ti_sn_aux_id_table,
};

/*------------------------------------------------------------------------------
 * DRM Bridge
 */

static struct ti_sn65dsi86 *bridge_to_ti_sn65dsi86(struct drm_bridge *bridge)
{
	return container_of(bridge, struct ti_sn65dsi86, bridge);
}

static int ti_sn_attach_host(struct auxiliary_device *adev, struct ti_sn65dsi86 *pdata)
{
	int val;
	struct mipi_dsi_host *host;
	struct mipi_dsi_device *dsi;
	struct device *dev = pdata->dev;
	const struct mipi_dsi_device_info info = { .type = "ti_sn_bridge",
						   .channel = 0,
						   .node = NULL,
	};

	host = of_find_mipi_dsi_host_by_node(pdata->host_node);
	if (!host)
		return -EPROBE_DEFER;

	dsi = devm_mipi_dsi_device_register_full(&adev->dev, host, &info);
	if (IS_ERR(dsi))
		return PTR_ERR(dsi);

	/* TODO: setting to 4 MIPI lanes always for now */
	dsi->lanes = 4;
	dsi->format = MIPI_DSI_FMT_RGB888;
	dsi->mode_flags = MIPI_DSI_MODE_VIDEO;

	/* check if continuous dsi clock is required or not */
	pm_runtime_get_sync(dev);
	regmap_read(pdata->regmap, SN_DPPLL_SRC_REG, &val);
	pm_runtime_put_autosuspend(dev);
	if (!(val & DPPLL_CLK_SRC_DSICLK))
		dsi->mode_flags |= MIPI_DSI_CLOCK_NON_CONTINUOUS;

	pdata->dsi = dsi;

	return devm_mipi_dsi_attach(&adev->dev, dsi);
}

static int ti_sn_bridge_attach(struct drm_bridge *bridge,
			       enum drm_bridge_attach_flags flags)
{
	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
	int ret;

	pdata->aux.drm_dev = bridge->dev;
	ret = drm_dp_aux_register(&pdata->aux);
	if (ret < 0) {
		drm_err(bridge->dev, "Failed to register DP AUX channel: %d\n", ret);
		return ret;
	}

	/*
	 * Attach the next bridge.
	 * We never want the next bridge to *also* create a connector.
	 */
	ret = drm_bridge_attach(bridge->encoder, pdata->next_bridge,
				&pdata->bridge, flags | DRM_BRIDGE_ATTACH_NO_CONNECTOR);
	if (ret < 0)
		goto err_initted_aux;

	if (flags & DRM_BRIDGE_ATTACH_NO_CONNECTOR)
		return 0;

	pdata->connector = drm_bridge_connector_init(pdata->bridge.dev,
						     pdata->bridge.encoder);
	if (IS_ERR(pdata->connector)) {
		ret = PTR_ERR(pdata->connector);
		goto err_initted_aux;
	}

	drm_connector_attach_encoder(pdata->connector, pdata->bridge.encoder);

	return 0;

err_initted_aux:
	drm_dp_aux_unregister(&pdata->aux);
	return ret;
}

static void ti_sn_bridge_detach(struct drm_bridge *bridge)
{
	drm_dp_aux_unregister(&bridge_to_ti_sn65dsi86(bridge)->aux);
}

static enum drm_mode_status
ti_sn_bridge_mode_valid(struct drm_bridge *bridge,
			const struct drm_display_info *info,
			const struct drm_display_mode *mode)
{
	/* maximum supported resolution is 4K at 60 fps */
	if (mode->clock > 594000)
		return MODE_CLOCK_HIGH;

	/*
	 * The front and back porch registers are 8 bits, and pulse width
	 * registers are 15 bits, so reject any modes with larger periods.
	 */

	if ((mode->hsync_start - mode->hdisplay) > 0xff)
		return MODE_HBLANK_WIDE;

	if ((mode->vsync_start - mode->vdisplay) > 0xff)
		return MODE_VBLANK_WIDE;

	if ((mode->hsync_end - mode->hsync_start) > 0x7fff)
		return MODE_HSYNC_WIDE;

	if ((mode->vsync_end - mode->vsync_start) > 0x7fff)
		return MODE_VSYNC_WIDE;

	if ((mode->htotal - mode->hsync_end) > 0xff)
		return MODE_HBLANK_WIDE;

	if ((mode->vtotal - mode->vsync_end) > 0xff)
		return MODE_VBLANK_WIDE;

	return MODE_OK;
}

static void ti_sn_bridge_atomic_disable(struct drm_bridge *bridge,
					struct drm_bridge_state *old_bridge_state)
{
	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);

	/* disable video stream */
	regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, VSTREAM_ENABLE, 0);
}

static void ti_sn_bridge_set_dsi_rate(struct ti_sn65dsi86 *pdata)
{
	unsigned int bit_rate_mhz, clk_freq_mhz;
	unsigned int val;
	struct drm_display_mode *mode =
		&pdata->bridge.encoder->crtc->state->adjusted_mode;

	/* set DSIA clk frequency */
	bit_rate_mhz = (mode->clock / 1000) *
			mipi_dsi_pixel_format_to_bpp(pdata->dsi->format);
	clk_freq_mhz = bit_rate_mhz / (pdata->dsi->lanes * 2);

	/* for each increment in val, frequency increases by 5MHz */
	val = (MIN_DSI_CLK_FREQ_MHZ / 5) +
		(((clk_freq_mhz - MIN_DSI_CLK_FREQ_MHZ) / 5) & 0xFF);
	regmap_write(pdata->regmap, SN_DSIA_CLK_FREQ_REG, val);
}

static unsigned int ti_sn_bridge_get_bpp(struct drm_connector *connector)
{
	if (connector->display_info.bpc <= 6)
		return 18;
	else
		return 24;
}

/*
 * LUT index corresponds to register value and
 * LUT values corresponds to dp data rate supported
 * by the bridge in Mbps unit.
 */
static const unsigned int ti_sn_bridge_dp_rate_lut[] = {
	0, 1620, 2160, 2430, 2700, 3240, 4320, 5400
};

static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn65dsi86 *pdata, unsigned int bpp)
{
	unsigned int bit_rate_khz, dp_rate_mhz;
	unsigned int i;
	struct drm_display_mode *mode =
		&pdata->bridge.encoder->crtc->state->adjusted_mode;

	/* Calculate minimum bit rate based on our pixel clock. */
	bit_rate_khz = mode->clock * bpp;

	/* Calculate minimum DP data rate, taking 80% as per DP spec */
	dp_rate_mhz = DIV_ROUND_UP(bit_rate_khz * DP_CLK_FUDGE_NUM,
				   1000 * pdata->dp_lanes * DP_CLK_FUDGE_DEN);

	for (i = 1; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut) - 1; i++)
		if (ti_sn_bridge_dp_rate_lut[i] >= dp_rate_mhz)
			break;

	return i;
}

static unsigned int ti_sn_bridge_read_valid_rates(struct ti_sn65dsi86 *pdata)
{
	unsigned int valid_rates = 0;
	unsigned int rate_per_200khz;
	unsigned int rate_mhz;
	u8 dpcd_val;
	int ret;
	int i, j;

	ret = drm_dp_dpcd_readb(&pdata->aux, DP_EDP_DPCD_REV, &dpcd_val);
	if (ret != 1) {
		DRM_DEV_ERROR(pdata->dev,
			      "Can't read eDP rev (%d), assuming 1.1\n", ret);
		dpcd_val = DP_EDP_11;
	}

	if (dpcd_val >= DP_EDP_14) {
		/* eDP 1.4 devices must provide a custom table */
		__le16 sink_rates[DP_MAX_SUPPORTED_RATES];

		ret = drm_dp_dpcd_read(&pdata->aux, DP_SUPPORTED_LINK_RATES,
				       sink_rates, sizeof(sink_rates));

		if (ret != sizeof(sink_rates)) {
			DRM_DEV_ERROR(pdata->dev,
				"Can't read supported rate table (%d)\n", ret);

			/* By zeroing we'll fall back to DP_MAX_LINK_RATE. */
			memset(sink_rates, 0, sizeof(sink_rates));
		}

		for (i = 0; i < ARRAY_SIZE(sink_rates); i++) {
			rate_per_200khz = le16_to_cpu(sink_rates[i]);

			if (!rate_per_200khz)
				break;

			rate_mhz = rate_per_200khz * 200 / 1000;
			for (j = 0;
			     j < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut);
			     j++) {
				if (ti_sn_bridge_dp_rate_lut[j] == rate_mhz)
					valid_rates |= BIT(j);
			}
		}

		for (i = 0; i < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut); i++) {
			if (valid_rates & BIT(i))
				return valid_rates;
		}
		DRM_DEV_ERROR(pdata->dev,
			      "No matching eDP rates in table; falling back\n");
	}

	/* On older versions best we can do is use DP_MAX_LINK_RATE */
	ret = drm_dp_dpcd_readb(&pdata->aux, DP_MAX_LINK_RATE, &dpcd_val);
	if (ret != 1) {
		DRM_DEV_ERROR(pdata->dev,
			      "Can't read max rate (%d); assuming 5.4 GHz\n",
			      ret);
		dpcd_val = DP_LINK_BW_5_4;
	}

	switch (dpcd_val) {
	default:
		DRM_DEV_ERROR(pdata->dev,
			      "Unexpected max rate (%#x); assuming 5.4 GHz\n",
			      (int)dpcd_val);
		fallthrough;
	case DP_LINK_BW_5_4:
		valid_rates |= BIT(7);
		fallthrough;
	case DP_LINK_BW_2_7:
		valid_rates |= BIT(4);
		fallthrough;
	case DP_LINK_BW_1_62:
		valid_rates |= BIT(1);
		break;
	}

	return valid_rates;
}

static void ti_sn_bridge_set_video_timings(struct ti_sn65dsi86 *pdata)
{
	struct drm_display_mode *mode =
		&pdata->bridge.encoder->crtc->state->adjusted_mode;
	u8 hsync_polarity = 0, vsync_polarity = 0;

	if (mode->flags & DRM_MODE_FLAG_NHSYNC)
		hsync_polarity = CHA_HSYNC_POLARITY;
	if (mode->flags & DRM_MODE_FLAG_NVSYNC)
		vsync_polarity = CHA_VSYNC_POLARITY;

	ti_sn65dsi86_write_u16(pdata, SN_CHA_ACTIVE_LINE_LENGTH_LOW_REG,
			       mode->hdisplay);
	ti_sn65dsi86_write_u16(pdata, SN_CHA_VERTICAL_DISPLAY_SIZE_LOW_REG,
			       mode->vdisplay);
	regmap_write(pdata->regmap, SN_CHA_HSYNC_PULSE_WIDTH_LOW_REG,
		     (mode->hsync_end - mode->hsync_start) & 0xFF);
	regmap_write(pdata->regmap, SN_CHA_HSYNC_PULSE_WIDTH_HIGH_REG,
		     (((mode->hsync_end - mode->hsync_start) >> 8) & 0x7F) |
		     hsync_polarity);
	regmap_write(pdata->regmap, SN_CHA_VSYNC_PULSE_WIDTH_LOW_REG,
		     (mode->vsync_end - mode->vsync_start) & 0xFF);
	regmap_write(pdata->regmap, SN_CHA_VSYNC_PULSE_WIDTH_HIGH_REG,
		     (((mode->vsync_end - mode->vsync_start) >> 8) & 0x7F) |
		     vsync_polarity);

	regmap_write(pdata->regmap, SN_CHA_HORIZONTAL_BACK_PORCH_REG,
		     (mode->htotal - mode->hsync_end) & 0xFF);
	regmap_write(pdata->regmap, SN_CHA_VERTICAL_BACK_PORCH_REG,
		     (mode->vtotal - mode->vsync_end) & 0xFF);

	regmap_write(pdata->regmap, SN_CHA_HORIZONTAL_FRONT_PORCH_REG,
		     (mode->hsync_start - mode->hdisplay) & 0xFF);
	regmap_write(pdata->regmap, SN_CHA_VERTICAL_FRONT_PORCH_REG,
		     (mode->vsync_start - mode->vdisplay) & 0xFF);

	usleep_range(10000, 10500); /* 10ms delay recommended by spec */
}

static unsigned int ti_sn_get_max_lanes(struct ti_sn65dsi86 *pdata)
{
	u8 data;
	int ret;

	ret = drm_dp_dpcd_readb(&pdata->aux, DP_MAX_LANE_COUNT, &data);
	if (ret != 1) {
		DRM_DEV_ERROR(pdata->dev,
			      "Can't read lane count (%d); assuming 4\n", ret);
		return 4;
	}

	return data & DP_LANE_COUNT_MASK;
}

static int ti_sn_link_training(struct ti_sn65dsi86 *pdata, int dp_rate_idx,
			       const char **last_err_str)
{
	unsigned int val;
	int ret;
	int i;

	/* set dp clk frequency value */
	regmap_update_bits(pdata->regmap, SN_DATARATE_CONFIG_REG,
			   DP_DATARATE_MASK, DP_DATARATE(dp_rate_idx));

	/* enable DP PLL */
	regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 1);

	ret = regmap_read_poll_timeout(pdata->regmap, SN_DPPLL_SRC_REG, val,
				       val & DPPLL_SRC_DP_PLL_LOCK, 1000,
				       50 * 1000);
	if (ret) {
		*last_err_str = "DP_PLL_LOCK polling failed";
		goto exit;
	}

	/*
	 * We'll try to link train several times.  As part of link training
	 * the bridge chip will write DP_SET_POWER_D0 to DP_SET_POWER.  If
	 * the panel isn't ready quite it might respond NAK here which means
	 * we need to try again.
	 */
	for (i = 0; i < SN_LINK_TRAINING_TRIES; i++) {
		/* Semi auto link training mode */
		regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0x0A);
		ret = regmap_read_poll_timeout(pdata->regmap, SN_ML_TX_MODE_REG, val,
					       val == ML_TX_MAIN_LINK_OFF ||
					       val == ML_TX_NORMAL_MODE, 1000,
					       500 * 1000);
		if (ret) {
			*last_err_str = "Training complete polling failed";
		} else if (val == ML_TX_MAIN_LINK_OFF) {
			*last_err_str = "Link training failed, link is off";
			ret = -EIO;
			continue;
		}

		break;
	}

	/* If we saw quite a few retries, add a note about it */
	if (!ret && i > SN_LINK_TRAINING_TRIES / 2)
		DRM_DEV_INFO(pdata->dev, "Link training needed %d retries\n", i);

exit:
	/* Disable the PLL if we failed */
	if (ret)
		regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 0);

	return ret;
}

static void ti_sn_bridge_atomic_enable(struct drm_bridge *bridge,
				       struct drm_bridge_state *old_bridge_state)
{
	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
	struct drm_connector *connector;
	const char *last_err_str = "No supported DP rate";
	unsigned int valid_rates;
	int dp_rate_idx;
	unsigned int val;
	int ret = -EINVAL;
	int max_dp_lanes;
	unsigned int bpp;

	connector = drm_atomic_get_new_connector_for_encoder(old_bridge_state->base.state,
							     bridge->encoder);
	if (!connector) {
		dev_err_ratelimited(pdata->dev, "Could not get the connector\n");
		return;
	}

	max_dp_lanes = ti_sn_get_max_lanes(pdata);
	pdata->dp_lanes = min(pdata->dp_lanes, max_dp_lanes);

	/* DSI_A lane config */
	val = CHA_DSI_LANES(SN_MAX_DP_LANES - pdata->dsi->lanes);
	regmap_update_bits(pdata->regmap, SN_DSI_LANES_REG,
			   CHA_DSI_LANES_MASK, val);

	regmap_write(pdata->regmap, SN_LN_ASSIGN_REG, pdata->ln_assign);
	regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, LN_POLRS_MASK,
			   pdata->ln_polrs << LN_POLRS_OFFSET);

	/* set dsi clk frequency value */
	ti_sn_bridge_set_dsi_rate(pdata);

	/*
	 * The SN65DSI86 only supports ASSR Display Authentication method and
	 * this method is enabled for eDP panels. An eDP panel must support this
	 * authentication method. We need to enable this method in the eDP panel
	 * at DisplayPort address 0x0010A prior to link training.
	 *
	 * As only ASSR is supported by SN65DSI86, for full DisplayPort displays
	 * we need to disable the scrambler.
	 */
	if (pdata->bridge.type == DRM_MODE_CONNECTOR_eDP) {
		drm_dp_dpcd_writeb(&pdata->aux, DP_EDP_CONFIGURATION_SET,
				   DP_ALTERNATE_SCRAMBLER_RESET_ENABLE);

		regmap_update_bits(pdata->regmap, SN_TRAINING_SETTING_REG,
				   SCRAMBLE_DISABLE, 0);
	} else {
		regmap_update_bits(pdata->regmap, SN_TRAINING_SETTING_REG,
				   SCRAMBLE_DISABLE, SCRAMBLE_DISABLE);
	}

	bpp = ti_sn_bridge_get_bpp(connector);
	/* Set the DP output format (18 bpp or 24 bpp) */
	val = bpp == 18 ? BPP_18_RGB : 0;
	regmap_update_bits(pdata->regmap, SN_DATA_FORMAT_REG, BPP_18_RGB, val);

	/* DP lane config */
	val = DP_NUM_LANES(min(pdata->dp_lanes, 3));
	regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG, DP_NUM_LANES_MASK,
			   val);

	valid_rates = ti_sn_bridge_read_valid_rates(pdata);

	/* Train until we run out of rates */
	for (dp_rate_idx = ti_sn_bridge_calc_min_dp_rate_idx(pdata, bpp);
	     dp_rate_idx < ARRAY_SIZE(ti_sn_bridge_dp_rate_lut);
	     dp_rate_idx++) {
		if (!(valid_rates & BIT(dp_rate_idx)))
			continue;

		ret = ti_sn_link_training(pdata, dp_rate_idx, &last_err_str);
		if (!ret)
			break;
	}
	if (ret) {
		DRM_DEV_ERROR(pdata->dev, "%s (%d)\n", last_err_str, ret);
		return;
	}

	/* config video parameters */
	ti_sn_bridge_set_video_timings(pdata);

	/* enable video stream */
	regmap_update_bits(pdata->regmap, SN_ENH_FRAME_REG, VSTREAM_ENABLE,
			   VSTREAM_ENABLE);
}

static void ti_sn_bridge_atomic_pre_enable(struct drm_bridge *bridge,
					   struct drm_bridge_state *old_bridge_state)
{
	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);

	pm_runtime_get_sync(pdata->dev);

	if (!pdata->refclk)
		ti_sn65dsi86_enable_comms(pdata);

	/* td7: min 100 us after enable before DSI data */
	usleep_range(100, 110);
}

static void ti_sn_bridge_atomic_post_disable(struct drm_bridge *bridge,
					     struct drm_bridge_state *old_bridge_state)
{
	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);

	/* semi auto link training mode OFF */
	regmap_write(pdata->regmap, SN_ML_TX_MODE_REG, 0);
	/* Num lanes to 0 as per power sequencing in data sheet */
	regmap_update_bits(pdata->regmap, SN_SSC_CONFIG_REG, DP_NUM_LANES_MASK, 0);
	/* disable DP PLL */
	regmap_write(pdata->regmap, SN_PLL_ENABLE_REG, 0);

	if (!pdata->refclk)
		ti_sn65dsi86_disable_comms(pdata);

	pm_runtime_put_sync(pdata->dev);
}

static enum drm_connector_status ti_sn_bridge_detect(struct drm_bridge *bridge)
{
	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);
	int val = 0;

	pm_runtime_get_sync(pdata->dev);
	regmap_read(pdata->regmap, SN_HPD_DISABLE_REG, &val);
	pm_runtime_put_autosuspend(pdata->dev);

	return val & HPD_DEBOUNCED_STATE ? connector_status_connected
					 : connector_status_disconnected;
}

static const struct drm_edid *ti_sn_bridge_edid_read(struct drm_bridge *bridge,
						     struct drm_connector *connector)
{
	struct ti_sn65dsi86 *pdata = bridge_to_ti_sn65dsi86(bridge);

	return drm_edid_read_ddc(connector, &pdata->aux.ddc);
}

static const struct drm_bridge_funcs ti_sn_bridge_funcs = {
	.attach = ti_sn_bridge_attach,
	.detach = ti_sn_bridge_detach,
	.mode_valid = ti_sn_bridge_mode_valid,
	.edid_read = ti_sn_bridge_edid_read,
	.detect = ti_sn_bridge_detect,
	.atomic_pre_enable = ti_sn_bridge_atomic_pre_enable,
	.atomic_enable = ti_sn_bridge_atomic_enable,
	.atomic_disable = ti_sn_bridge_atomic_disable,
	.atomic_post_disable = ti_sn_bridge_atomic_post_disable,
	.atomic_reset = drm_atomic_helper_bridge_reset,
	.atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_bridge_destroy_state,
};

static void ti_sn_bridge_parse_lanes(struct ti_sn65dsi86 *pdata,
				     struct device_node *np)
{
	u32 lane_assignments[SN_MAX_DP_LANES] = { 0, 1, 2, 3 };
	u32 lane_polarities[SN_MAX_DP_LANES] = { };
	struct device_node *endpoint;
	u8 ln_assign = 0;
	u8 ln_polrs = 0;
	int dp_lanes;
	int i;

	/*
	 * Read config from the device tree about lane remapping and lane
	 * polarities.  These are optional and we assume identity map and
	 * normal polarity if nothing is specified.  It's OK to specify just
	 * data-lanes but not lane-polarities but not vice versa.
	 *
	 * Error checking is light (we just make sure we don't crash or
	 * buffer overrun) and we assume dts is well formed and specifying
	 * mappings that the hardware supports.
	 */
	endpoint = of_graph_get_endpoint_by_regs(np, 1, -1);
	dp_lanes = drm_of_get_data_lanes_count(endpoint, 1, SN_MAX_DP_LANES);
	if (dp_lanes > 0) {
		of_property_read_u32_array(endpoint, "data-lanes",
					   lane_assignments, dp_lanes);
		of_property_read_u32_array(endpoint, "lane-polarities",
					   lane_polarities, dp_lanes);
	} else {
		dp_lanes = SN_MAX_DP_LANES;
	}
	of_node_put(endpoint);

	/*
	 * Convert into register format.  Loop over all lanes even if
	 * data-lanes had fewer elements so that we nicely initialize
	 * the LN_ASSIGN register.
	 */
	for (i = SN_MAX_DP_LANES - 1; i >= 0; i--) {
		ln_assign = ln_assign << LN_ASSIGN_WIDTH | lane_assignments[i];
		ln_polrs = ln_polrs << 1 | lane_polarities[i];
	}

	/* Stash in our struct for when we power on */
	pdata->dp_lanes = dp_lanes;
	pdata->ln_assign = ln_assign;
	pdata->ln_polrs = ln_polrs;
}

static int ti_sn_bridge_parse_dsi_host(struct ti_sn65dsi86 *pdata)
{
	struct device_node *np = pdata->dev->of_node;

	pdata->host_node = of_graph_get_remote_node(np, 0, 0);

	if (!pdata->host_node) {
		DRM_ERROR("remote dsi host node not found\n");
		return -ENODEV;
	}

	return 0;
}

static int ti_sn_bridge_probe(struct auxiliary_device *adev,
			      const struct auxiliary_device_id *id)
{
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);
	struct device_node *np = pdata->dev->of_node;
	int ret;

	pdata->next_bridge = devm_drm_of_get_bridge(&adev->dev, np, 1, 0);
	if (IS_ERR(pdata->next_bridge))
		return dev_err_probe(&adev->dev, PTR_ERR(pdata->next_bridge),
				     "failed to create panel bridge\n");

	ti_sn_bridge_parse_lanes(pdata, np);

	ret = ti_sn_bridge_parse_dsi_host(pdata);
	if (ret)
		return ret;

	pdata->bridge.funcs = &ti_sn_bridge_funcs;
	pdata->bridge.of_node = np;
	pdata->bridge.type = pdata->next_bridge->type == DRM_MODE_CONNECTOR_DisplayPort
			   ? DRM_MODE_CONNECTOR_DisplayPort : DRM_MODE_CONNECTOR_eDP;

	if (pdata->bridge.type == DRM_MODE_CONNECTOR_DisplayPort)
		pdata->bridge.ops = DRM_BRIDGE_OP_EDID | DRM_BRIDGE_OP_DETECT;

	drm_bridge_add(&pdata->bridge);

	ret = ti_sn_attach_host(adev, pdata);
	if (ret) {
		dev_err_probe(&adev->dev, ret, "failed to attach dsi host\n");
		goto err_remove_bridge;
	}

	return 0;

err_remove_bridge:
	drm_bridge_remove(&pdata->bridge);
	return ret;
}

static void ti_sn_bridge_remove(struct auxiliary_device *adev)
{
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);

	if (!pdata)
		return;

	drm_bridge_remove(&pdata->bridge);

	of_node_put(pdata->host_node);
}

static const struct auxiliary_device_id ti_sn_bridge_id_table[] = {
	{ .name = "ti_sn65dsi86.bridge", },
	{},
};

static struct auxiliary_driver ti_sn_bridge_driver = {
	.name = "bridge",
	.probe = ti_sn_bridge_probe,
	.remove = ti_sn_bridge_remove,
	.id_table = ti_sn_bridge_id_table,
};

/* -----------------------------------------------------------------------------
 * PWM Controller
 */
#if defined(CONFIG_PWM)
static int ti_sn_pwm_pin_request(struct ti_sn65dsi86 *pdata)
{
	return atomic_xchg(&pdata->pwm_pin_busy, 1) ? -EBUSY : 0;
}

static void ti_sn_pwm_pin_release(struct ti_sn65dsi86 *pdata)
{
	atomic_set(&pdata->pwm_pin_busy, 0);
}

static struct ti_sn65dsi86 *pwm_chip_to_ti_sn_bridge(struct pwm_chip *chip)
{
	return pwmchip_get_drvdata(chip);
}

static int ti_sn_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct ti_sn65dsi86 *pdata = pwm_chip_to_ti_sn_bridge(chip);

	return ti_sn_pwm_pin_request(pdata);
}

static void ti_sn_pwm_free(struct pwm_chip *chip, struct pwm_device *pwm)
{
	struct ti_sn65dsi86 *pdata = pwm_chip_to_ti_sn_bridge(chip);

	ti_sn_pwm_pin_release(pdata);
}

/*
 * Limitations:
 * - The PWM signal is not driven when the chip is powered down, or in its
 *   reset state and the driver does not implement the "suspend state"
 *   described in the documentation. In order to save power, state->enabled is
 *   interpreted as denoting if the signal is expected to be valid, and is used
 *   to determine if the chip needs to be kept powered.
 * - Changing both period and duty_cycle is not done atomically, neither is the
 *   multi-byte register updates, so the output might briefly be undefined
 *   during update.
 */
static int ti_sn_pwm_apply(struct pwm_chip *chip, struct pwm_device *pwm,
			   const struct pwm_state *state)
{
	struct ti_sn65dsi86 *pdata = pwm_chip_to_ti_sn_bridge(chip);
	unsigned int pwm_en_inv;
	unsigned int backlight;
	unsigned int pre_div;
	unsigned int scale;
	u64 period_max;
	u64 period;
	int ret;

	if (!pdata->pwm_enabled) {
		ret = pm_runtime_resume_and_get(pwmchip_parent(chip));
		if (ret < 0)
			return ret;
	}

	if (state->enabled) {
		if (!pdata->pwm_enabled) {
			/*
			 * The chip might have been powered down while we
			 * didn't hold a PM runtime reference, so mux in the
			 * PWM function on the GPIO pin again.
			 */
			ret = regmap_update_bits(pdata->regmap, SN_GPIO_CTRL_REG,
						 SN_GPIO_MUX_MASK << (2 * SN_PWM_GPIO_IDX),
						 SN_GPIO_MUX_SPECIAL << (2 * SN_PWM_GPIO_IDX));
			if (ret) {
				dev_err(pwmchip_parent(chip), "failed to mux in PWM function\n");
				goto out;
			}
		}

		/*
		 * Per the datasheet the PWM frequency is given by:
		 *
		 *                          REFCLK_FREQ
		 *   PWM_FREQ = -----------------------------------
		 *               PWM_PRE_DIV * BACKLIGHT_SCALE + 1
		 *
		 * However, after careful review the author is convinced that
		 * the documentation has lost some parenthesis around
		 * "BACKLIGHT_SCALE + 1".
		 *
		 * With the period T_pwm = 1/PWM_FREQ this can be written:
		 *
		 *   T_pwm * REFCLK_FREQ = PWM_PRE_DIV * (BACKLIGHT_SCALE + 1)
		 *
		 * In order to keep BACKLIGHT_SCALE within its 16 bits,
		 * PWM_PRE_DIV must be:
		 *
		 *                     T_pwm * REFCLK_FREQ
		 *   PWM_PRE_DIV >= -------------------------
		 *                   BACKLIGHT_SCALE_MAX + 1
		 *
		 * To simplify the search and to favour higher resolution of
		 * the duty cycle over accuracy of the period, the lowest
		 * possible PWM_PRE_DIV is used. Finally the scale is
		 * calculated as:
		 *
		 *                      T_pwm * REFCLK_FREQ
		 *   BACKLIGHT_SCALE = ---------------------- - 1
		 *                          PWM_PRE_DIV
		 *
		 * Here T_pwm is represented in seconds, so appropriate scaling
		 * to nanoseconds is necessary.
		 */

		/* Minimum T_pwm is 1 / REFCLK_FREQ */
		if (state->period <= NSEC_PER_SEC / pdata->pwm_refclk_freq) {
			ret = -EINVAL;
			goto out;
		}

		/*
		 * Maximum T_pwm is 255 * (65535 + 1) / REFCLK_FREQ
		 * Limit period to this to avoid overflows
		 */
		period_max = div_u64((u64)NSEC_PER_SEC * 255 * (65535 + 1),
				     pdata->pwm_refclk_freq);
		period = min(state->period, period_max);

		pre_div = DIV64_U64_ROUND_UP(period * pdata->pwm_refclk_freq,
					     (u64)NSEC_PER_SEC * (BACKLIGHT_SCALE_MAX + 1));
		scale = div64_u64(period * pdata->pwm_refclk_freq, (u64)NSEC_PER_SEC * pre_div) - 1;

		/*
		 * The documentation has the duty ratio given as:
		 *
		 *     duty          BACKLIGHT
		 *   ------- = ---------------------
		 *    period    BACKLIGHT_SCALE + 1
		 *
		 * Solve for BACKLIGHT, substituting BACKLIGHT_SCALE according
		 * to definition above and adjusting for nanosecond
		 * representation of duty cycle gives us:
		 */
		backlight = div64_u64(state->duty_cycle * pdata->pwm_refclk_freq,
				      (u64)NSEC_PER_SEC * pre_div);
		if (backlight > scale)
			backlight = scale;

		ret = regmap_write(pdata->regmap, SN_PWM_PRE_DIV_REG, pre_div);
		if (ret) {
			dev_err(pwmchip_parent(chip), "failed to update PWM_PRE_DIV\n");
			goto out;
		}

		ti_sn65dsi86_write_u16(pdata, SN_BACKLIGHT_SCALE_REG, scale);
		ti_sn65dsi86_write_u16(pdata, SN_BACKLIGHT_REG, backlight);
	}

	pwm_en_inv = FIELD_PREP(SN_PWM_EN_MASK, state->enabled) |
		     FIELD_PREP(SN_PWM_INV_MASK, state->polarity == PWM_POLARITY_INVERSED);
	ret = regmap_write(pdata->regmap, SN_PWM_EN_INV_REG, pwm_en_inv);
	if (ret) {
		dev_err(pwmchip_parent(chip), "failed to update PWM_EN/PWM_INV\n");
		goto out;
	}

	pdata->pwm_enabled = state->enabled;
out:

	if (!pdata->pwm_enabled)
		pm_runtime_put_sync(pwmchip_parent(chip));

	return ret;
}

static int ti_sn_pwm_get_state(struct pwm_chip *chip, struct pwm_device *pwm,
			       struct pwm_state *state)
{
	struct ti_sn65dsi86 *pdata = pwm_chip_to_ti_sn_bridge(chip);
	unsigned int pwm_en_inv;
	unsigned int pre_div;
	u16 backlight;
	u16 scale;
	int ret;

	ret = regmap_read(pdata->regmap, SN_PWM_EN_INV_REG, &pwm_en_inv);
	if (ret)
		return ret;

	ret = ti_sn65dsi86_read_u16(pdata, SN_BACKLIGHT_SCALE_REG, &scale);
	if (ret)
		return ret;

	ret = ti_sn65dsi86_read_u16(pdata, SN_BACKLIGHT_REG, &backlight);
	if (ret)
		return ret;

	ret = regmap_read(pdata->regmap, SN_PWM_PRE_DIV_REG, &pre_div);
	if (ret)
		return ret;

	state->enabled = FIELD_GET(SN_PWM_EN_MASK, pwm_en_inv);
	if (FIELD_GET(SN_PWM_INV_MASK, pwm_en_inv))
		state->polarity = PWM_POLARITY_INVERSED;
	else
		state->polarity = PWM_POLARITY_NORMAL;

	state->period = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pre_div * (scale + 1),
					 pdata->pwm_refclk_freq);
	state->duty_cycle = DIV_ROUND_UP_ULL((u64)NSEC_PER_SEC * pre_div * backlight,
					     pdata->pwm_refclk_freq);

	if (state->duty_cycle > state->period)
		state->duty_cycle = state->period;

	return 0;
}

static const struct pwm_ops ti_sn_pwm_ops = {
	.request = ti_sn_pwm_request,
	.free = ti_sn_pwm_free,
	.apply = ti_sn_pwm_apply,
	.get_state = ti_sn_pwm_get_state,
};

static int ti_sn_pwm_probe(struct auxiliary_device *adev,
			   const struct auxiliary_device_id *id)
{
	struct pwm_chip *chip;
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);

	pdata->pchip = chip = devm_pwmchip_alloc(&adev->dev, 1, 0);
	if (IS_ERR(chip))
		return PTR_ERR(chip);

	pwmchip_set_drvdata(chip, pdata);

	chip->ops = &ti_sn_pwm_ops;
	chip->of_xlate = of_pwm_single_xlate;

	devm_pm_runtime_enable(&adev->dev);

	return pwmchip_add(chip);
}

static void ti_sn_pwm_remove(struct auxiliary_device *adev)
{
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);

	pwmchip_remove(pdata->pchip);

	if (pdata->pwm_enabled)
		pm_runtime_put_sync(&adev->dev);
}

static const struct auxiliary_device_id ti_sn_pwm_id_table[] = {
	{ .name = "ti_sn65dsi86.pwm", },
	{},
};

static struct auxiliary_driver ti_sn_pwm_driver = {
	.name = "pwm",
	.probe = ti_sn_pwm_probe,
	.remove = ti_sn_pwm_remove,
	.id_table = ti_sn_pwm_id_table,
};

static int __init ti_sn_pwm_register(void)
{
	return auxiliary_driver_register(&ti_sn_pwm_driver);
}

static void ti_sn_pwm_unregister(void)
{
	auxiliary_driver_unregister(&ti_sn_pwm_driver);
}

#else
static inline int ti_sn_pwm_pin_request(struct ti_sn65dsi86 *pdata) { return 0; }
static inline void ti_sn_pwm_pin_release(struct ti_sn65dsi86 *pdata) {}

static inline int ti_sn_pwm_register(void) { return 0; }
static inline void ti_sn_pwm_unregister(void) {}
#endif

/* -----------------------------------------------------------------------------
 * GPIO Controller
 */
#if defined(CONFIG_OF_GPIO)

static int tn_sn_bridge_of_xlate(struct gpio_chip *chip,
				 const struct of_phandle_args *gpiospec,
				 u32 *flags)
{
	if (WARN_ON(gpiospec->args_count < chip->of_gpio_n_cells))
		return -EINVAL;

	if (gpiospec->args[0] > chip->ngpio || gpiospec->args[0] < 1)
		return -EINVAL;

	if (flags)
		*flags = gpiospec->args[1];

	return gpiospec->args[0] - SN_GPIO_PHYSICAL_OFFSET;
}

static int ti_sn_bridge_gpio_get_direction(struct gpio_chip *chip,
					   unsigned int offset)
{
	struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip);

	/*
	 * We already have to keep track of the direction because we use
	 * that to figure out whether we've powered the device.  We can
	 * just return that rather than (maybe) powering up the device
	 * to ask its direction.
	 */
	return test_bit(offset, pdata->gchip_output) ?
		GPIO_LINE_DIRECTION_OUT : GPIO_LINE_DIRECTION_IN;
}

static int ti_sn_bridge_gpio_get(struct gpio_chip *chip, unsigned int offset)
{
	struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip);
	unsigned int val;
	int ret;

	/*
	 * When the pin is an input we don't forcibly keep the bridge
	 * powered--we just power it on to read the pin.  NOTE: part of
	 * the reason this works is that the bridge defaults (when
	 * powered back on) to all 4 GPIOs being configured as GPIO input.
	 * Also note that if something else is keeping the chip powered the
	 * pm_runtime functions are lightweight increments of a refcount.
	 */
	pm_runtime_get_sync(pdata->dev);
	ret = regmap_read(pdata->regmap, SN_GPIO_IO_REG, &val);
	pm_runtime_put_autosuspend(pdata->dev);

	if (ret)
		return ret;

	return !!(val & BIT(SN_GPIO_INPUT_SHIFT + offset));
}

static void ti_sn_bridge_gpio_set(struct gpio_chip *chip, unsigned int offset,
				  int val)
{
	struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip);
	int ret;

	if (!test_bit(offset, pdata->gchip_output)) {
		dev_err(pdata->dev, "Ignoring GPIO set while input\n");
		return;
	}

	val &= 1;
	ret = regmap_update_bits(pdata->regmap, SN_GPIO_IO_REG,
				 BIT(SN_GPIO_OUTPUT_SHIFT + offset),
				 val << (SN_GPIO_OUTPUT_SHIFT + offset));
	if (ret)
		dev_warn(pdata->dev,
			 "Failed to set bridge GPIO %u: %d\n", offset, ret);
}

static int ti_sn_bridge_gpio_direction_input(struct gpio_chip *chip,
					     unsigned int offset)
{
	struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip);
	int shift = offset * 2;
	int ret;

	if (!test_and_clear_bit(offset, pdata->gchip_output))
		return 0;

	ret = regmap_update_bits(pdata->regmap, SN_GPIO_CTRL_REG,
				 SN_GPIO_MUX_MASK << shift,
				 SN_GPIO_MUX_INPUT << shift);
	if (ret) {
		set_bit(offset, pdata->gchip_output);
		return ret;
	}

	/*
	 * NOTE: if nobody else is powering the device this may fully power
	 * it off and when it comes back it will have lost all state, but
	 * that's OK because the default is input and we're now an input.
	 */
	pm_runtime_put_autosuspend(pdata->dev);

	return 0;
}

static int ti_sn_bridge_gpio_direction_output(struct gpio_chip *chip,
					      unsigned int offset, int val)
{
	struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip);
	int shift = offset * 2;
	int ret;

	if (test_and_set_bit(offset, pdata->gchip_output))
		return 0;

	pm_runtime_get_sync(pdata->dev);

	/* Set value first to avoid glitching */
	ti_sn_bridge_gpio_set(chip, offset, val);

	/* Set direction */
	ret = regmap_update_bits(pdata->regmap, SN_GPIO_CTRL_REG,
				 SN_GPIO_MUX_MASK << shift,
				 SN_GPIO_MUX_OUTPUT << shift);
	if (ret) {
		clear_bit(offset, pdata->gchip_output);
		pm_runtime_put_autosuspend(pdata->dev);
	}

	return ret;
}

static int ti_sn_bridge_gpio_request(struct gpio_chip *chip, unsigned int offset)
{
	struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip);

	if (offset == SN_PWM_GPIO_IDX)
		return ti_sn_pwm_pin_request(pdata);

	return 0;
}

static void ti_sn_bridge_gpio_free(struct gpio_chip *chip, unsigned int offset)
{
	struct ti_sn65dsi86 *pdata = gpiochip_get_data(chip);

	/* We won't keep pm_runtime if we're input, so switch there on free */
	ti_sn_bridge_gpio_direction_input(chip, offset);

	if (offset == SN_PWM_GPIO_IDX)
		ti_sn_pwm_pin_release(pdata);
}

static const char * const ti_sn_bridge_gpio_names[SN_NUM_GPIOS] = {
	"GPIO1", "GPIO2", "GPIO3", "GPIO4"
};

static int ti_sn_gpio_probe(struct auxiliary_device *adev,
			    const struct auxiliary_device_id *id)
{
	struct ti_sn65dsi86 *pdata = dev_get_drvdata(adev->dev.parent);
	int ret;

	/* Only init if someone is going to use us as a GPIO controller */
	if (!of_property_read_bool(pdata->dev->of_node, "gpio-controller"))
		return 0;

	pdata->gchip.label = dev_name(pdata->dev);
	pdata->gchip.parent = pdata->dev;
	pdata->gchip.owner = THIS_MODULE;
	pdata->gchip.of_xlate = tn_sn_bridge_of_xlate;
	pdata->gchip.of_gpio_n_cells = 2;
	pdata->gchip.request = ti_sn_bridge_gpio_request;
	pdata->gchip.free = ti_sn_bridge_gpio_free;
	pdata->gchip.get_direction = ti_sn_bridge_gpio_get_direction;
	pdata->gchip.direction_input = ti_sn_bridge_gpio_direction_input;
	pdata->gchip.direction_output = ti_sn_bridge_gpio_direction_output;
	pdata->gchip.get = ti_sn_bridge_gpio_get;
	pdata->gchip.set = ti_sn_bridge_gpio_set;
	pdata->gchip.can_sleep = true;
	pdata->gchip.names = ti_sn_bridge_gpio_names;
	pdata->gchip.ngpio = SN_NUM_GPIOS;
	pdata->gchip.base = -1;
	ret = devm_gpiochip_add_data(&adev->dev, &pdata->gchip, pdata);
	if (ret)
		dev_err(pdata->dev, "can't add gpio chip\n");

	return ret;
}

static const struct auxiliary_device_id ti_sn_gpio_id_table[] = {
	{ .name = "ti_sn65dsi86.gpio", },
	{},
};

MODULE_DEVICE_TABLE(auxiliary, ti_sn_gpio_id_table);

static struct auxiliary_driver ti_sn_gpio_driver = {
	.name = "gpio",
	.probe = ti_sn_gpio_probe,
	.id_table = ti_sn_gpio_id_table,
};

static int __init ti_sn_gpio_register(void)
{
	return auxiliary_driver_register(&ti_sn_gpio_driver);
}

static void ti_sn_gpio_unregister(void)
{
	auxiliary_driver_unregister(&ti_sn_gpio_driver);
}

#else

static inline int ti_sn_gpio_register(void) { return 0; }
static inline void ti_sn_gpio_unregister(void) {}

#endif

/* -----------------------------------------------------------------------------
 * Probe & Remove
 */

static void ti_sn65dsi86_runtime_disable(void *data)
{
	pm_runtime_dont_use_autosuspend(data);
	pm_runtime_disable(data);
}

static int ti_sn65dsi86_parse_regulators(struct ti_sn65dsi86 *pdata)
{
	unsigned int i;
	const char * const ti_sn_bridge_supply_names[] = {
		"vcca", "vcc", "vccio", "vpll",
	};

	for (i = 0; i < SN_REGULATOR_SUPPLY_NUM; i++)
		pdata->supplies[i].supply = ti_sn_bridge_supply_names[i];

	return devm_regulator_bulk_get(pdata->dev, SN_REGULATOR_SUPPLY_NUM,
				       pdata->supplies);
}

static int ti_sn65dsi86_probe(struct i2c_client *client)
{
	struct device *dev = &client->dev;
	struct ti_sn65dsi86 *pdata;
	int ret;

	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
		DRM_ERROR("device doesn't support I2C\n");
		return -ENODEV;
	}

	pdata = devm_kzalloc(dev, sizeof(struct ti_sn65dsi86), GFP_KERNEL);
	if (!pdata)
		return -ENOMEM;
	dev_set_drvdata(dev, pdata);
	pdata->dev = dev;

	mutex_init(&pdata->comms_mutex);

	pdata->regmap = devm_regmap_init_i2c(client,
					     &ti_sn65dsi86_regmap_config);
	if (IS_ERR(pdata->regmap))
		return dev_err_probe(dev, PTR_ERR(pdata->regmap),
				     "regmap i2c init failed\n");

	pdata->enable_gpio = devm_gpiod_get_optional(dev, "enable",
						     GPIOD_OUT_LOW);
	if (IS_ERR(pdata->enable_gpio))
		return dev_err_probe(dev, PTR_ERR(pdata->enable_gpio),
				     "failed to get enable gpio from DT\n");

	ret = ti_sn65dsi86_parse_regulators(pdata);
	if (ret)
		return dev_err_probe(dev, ret, "failed to parse regulators\n");

	pdata->refclk = devm_clk_get_optional(dev, "refclk");
	if (IS_ERR(pdata->refclk))
		return dev_err_probe(dev, PTR_ERR(pdata->refclk),
				     "failed to get reference clock\n");

	pm_runtime_enable(dev);
	pm_runtime_set_autosuspend_delay(pdata->dev, 500);
	pm_runtime_use_autosuspend(pdata->dev);
	ret = devm_add_action_or_reset(dev, ti_sn65dsi86_runtime_disable, dev);
	if (ret)
		return ret;

	ti_sn65dsi86_debugfs_init(pdata);

	/*
	 * Break ourselves up into a collection of aux devices. The only real
	 * motiviation here is to solve the chicken-and-egg problem of probe
	 * ordering. The bridge wants the panel to be there when it probes.
	 * The panel wants its HPD GPIO (provided by sn65dsi86 on some boards)
	 * when it probes. The panel and maybe backlight might want the DDC
	 * bus or the pwm_chip. Having sub-devices allows the some sub devices
	 * to finish probing even if others return -EPROBE_DEFER and gets us
	 * around the problems.
	 */

	if (IS_ENABLED(CONFIG_OF_GPIO)) {
		ret = ti_sn65dsi86_add_aux_device(pdata, &pdata->gpio_aux, "gpio");
		if (ret)
			return ret;
	}

	if (IS_ENABLED(CONFIG_PWM)) {
		ret = ti_sn65dsi86_add_aux_device(pdata, &pdata->pwm_aux, "pwm");
		if (ret)
			return ret;
	}

	/*
	 * NOTE: At the end of the AUX channel probe we'll add the aux device
	 * for the bridge. This is because the bridge can't be used until the
	 * AUX channel is there and this is a very simple solution to the
	 * dependency problem.
	 */
	return ti_sn65dsi86_add_aux_device(pdata, &pdata->aux_aux, "aux");
}

static struct i2c_device_id ti_sn65dsi86_id[] = {
	{ "ti,sn65dsi86", 0},
	{},
};
MODULE_DEVICE_TABLE(i2c, ti_sn65dsi86_id);

static const struct of_device_id ti_sn65dsi86_match_table[] = {
	{.compatible = "ti,sn65dsi86"},
	{},
};
MODULE_DEVICE_TABLE(of, ti_sn65dsi86_match_table);

static struct i2c_driver ti_sn65dsi86_driver = {
	.driver = {
		.name = "ti_sn65dsi86",
		.of_match_table = ti_sn65dsi86_match_table,
		.pm = &ti_sn65dsi86_pm_ops,
	},
	.probe = ti_sn65dsi86_probe,
	.id_table = ti_sn65dsi86_id,
};

static int __init ti_sn65dsi86_init(void)
{
	int ret;

	ret = i2c_add_driver(&ti_sn65dsi86_driver);
	if (ret)
		return ret;

	ret = ti_sn_gpio_register();
	if (ret)
		goto err_main_was_registered;

	ret = ti_sn_pwm_register();
	if (ret)
		goto err_gpio_was_registered;

	ret = auxiliary_driver_register(&ti_sn_aux_driver);
	if (ret)
		goto err_pwm_was_registered;

	ret = auxiliary_driver_register(&ti_sn_bridge_driver);
	if (ret)
		goto err_aux_was_registered;

	return 0;

err_aux_was_registered:
	auxiliary_driver_unregister(&ti_sn_aux_driver);
err_pwm_was_registered:
	ti_sn_pwm_unregister();
err_gpio_was_registered:
	ti_sn_gpio_unregister();
err_main_was_registered:
	i2c_del_driver(&ti_sn65dsi86_driver);

	return ret;
}
module_init(ti_sn65dsi86_init);

static void __exit ti_sn65dsi86_exit(void)
{
	auxiliary_driver_unregister(&ti_sn_bridge_driver);
	auxiliary_driver_unregister(&ti_sn_aux_driver);
	ti_sn_pwm_unregister();
	ti_sn_gpio_unregister();
	i2c_del_driver(&ti_sn65dsi86_driver);
}
module_exit(ti_sn65dsi86_exit);

MODULE_AUTHOR("Sandeep Panda <spanda@codeaurora.org>");
MODULE_DESCRIPTION("sn65dsi86 DSI to eDP bridge driver");
MODULE_LICENSE("GPL v2");
