// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (c) 2018, The Linux Foundation. All rights reserved.
* datasheet: http://www.ti.com/lit/ds/symlink/sn65dsi86.pdf
*/
#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/regmap.h>
#include <linux/regulator/consumer.h>
#include <drm/drm_atomic.h>
#include <drm/drm_atomic_helper.h>
#include <drm/drm_bridge.h>
#include <drm/drm_dp_helper.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_ENH_FRAME_REG 0x5A
#define VSTREAM_ENABLE BIT(3)
#define SN_DATA_FORMAT_REG 0x5B
#define BPP_18_RGB BIT(0)
#define SN_HPD_DISABLE_REG 0x5C
#define HPD_DISABLE BIT(0)
#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_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_ML_TX_MODE_REG 0x96
#define ML_TX_MAIN_LINK_OFF 0
#define ML_TX_NORMAL_MODE BIT(0)
#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_NUM_GPIOS 4
#define SN_GPIO_PHYSICAL_OFFSET 1
/**
* struct ti_sn_bridge - Platform data for ti-sn65dsi86 driver.
* @dev: Pointer to our device.
* @regmap: Regmap for accessing i2c.
* @aux: Our aux channel.
* @bridge: Our bridge.
* @connector: Our connector.
* @debugfs: Used for managing our debugfs.
* @host_node: Remote DSI node.
* @dsi: Our MIPI DSI source.
* @refclk: Our reference clock.
* @panel: Our panel.
* @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.
*
* @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.
*/
struct ti_sn_bridge {
struct device *dev;
struct regmap *regmap;
struct drm_dp_aux aux;
struct drm_bridge bridge;
struct drm_connector connector;
struct dentry *debugfs;
struct device_node *host_node;
struct mipi_dsi_device *dsi;
struct clk *refclk;
struct drm_panel *panel;
struct gpio_desc *enable_gpio;
struct regulator_bulk_data supplies[SN_REGULATOR_SUPPLY_NUM];
int dp_lanes;
struct gpio_chip gchip;
DECLARE_BITMAP(gchip_output, SN_NUM_GPIOS);
};
static const struct regmap_range ti_sn_bridge_volatile_ranges[] = {
{ .range_min = 0, .range_max = 0xFF },
};
static const struct regmap_access_table ti_sn_bridge_volatile_table = {
.yes_ranges = ti_sn_bridge_volatile_ranges,
.n_yes_ranges = ARRAY_SIZE(ti_sn_bridge_volatile_ranges),
};
static const struct regmap_config ti_sn_bridge_regmap_config = {
.reg_bits = 8,
.val_bits = 8,
.