drm: Remove unnecessary drm_panel_attach and drm_panel_detach
[linux-2.6-microblaze.git] / drivers / gpu / drm / bridge / ti-sn65dsi86.c
index 6ad688b..454544e 100644 (file)
@@ -1,12 +1,14 @@
 // 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
+ * datasheet: https://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>
 #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 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_REGULATOR_SUPPLY_NUM                4
 
+#define SN_MAX_DP_LANES                        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.
+ * @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.
+ *
+ * @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;
@@ -102,6 +148,13 @@ struct ti_sn_bridge {
        struct gpio_desc                *enable_gpio;
        struct regulator_bulk_data      supplies[SN_REGULATOR_SUPPLY_NUM];
        int                             dp_lanes;
+       u8                              ln_assign;
+       u8                              ln_polrs;
+
+#if defined(CONFIG_OF_GPIO)
+       struct gpio_chip                gchip;
+       DECLARE_BITMAP(gchip_output, SN_NUM_GPIOS);
+#endif
 };
 
 static const struct regmap_range ti_sn_bridge_volatile_ranges[] = {
@@ -159,6 +212,8 @@ static int __maybe_unused ti_sn_bridge_suspend(struct device *dev)
 
 static const struct dev_pm_ops ti_sn_bridge_pm_ops = {
        SET_RUNTIME_PM_OPS(ti_sn_bridge_suspend, ti_sn_bridge_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)
@@ -339,9 +394,6 @@ static int ti_sn_bridge_attach(struct drm_bridge *bridge,
        }
        pdata->dsi = dsi;
 
-       /* attach panel to bridge */
-       drm_panel_attach(pdata->panel, &pdata->connector);
-
        return 0;
 
 err_dsi_attach:
@@ -451,7 +503,7 @@ static unsigned int ti_sn_bridge_get_bpp(struct ti_sn_bridge *pdata)
                return 24;
 }
 
-/**
+/*
  * LUT index corresponds to register value and
  * LUT values corresponds to dp data rate supported
  * by the bridge in Mbps unit.
@@ -475,7 +527,7 @@ static int ti_sn_bridge_calc_min_dp_rate_idx(struct ti_sn_bridge *pdata)
                                   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)
+               if (ti_sn_bridge_dp_rate_lut[i] >= dp_rate_mhz)
                        break;
 
        return i;
@@ -666,26 +718,20 @@ static void ti_sn_bridge_enable(struct drm_bridge *bridge)
        int dp_rate_idx;
        unsigned int val;
        int ret = -EINVAL;
+       int max_dp_lanes;
 
-       /*
-        * Run with the maximum number of lanes that the DP sink supports.
-        *
-        * Depending use cases, we might want to revisit this later because:
-        * - It's plausible that someone may have run fewer lines to the
-        *   sink than the sink actually supports, assuming that the lines
-        *   will just be driven at a higher rate.
-        * - The DP spec seems to indicate that it's more important to minimize
-        *   the number of lanes than the link rate.
-        *
-        * If we do revisit, it would be important to measure the power impact.
-        */
-       pdata->dp_lanes = ti_sn_get_max_lanes(pdata);
+       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(4 - pdata->dsi->lanes);
+       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);
 
@@ -827,6 +873,12 @@ static ssize_t ti_sn_aux_transfer(struct drm_dp_aux *aux,
                                     buf[i]);
        }
 
+       /* 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);
 
        ret = regmap_read_poll_timeout(pdata->regmap, SN_AUX_CMD_REG, val,
@@ -874,6 +926,236 @@ static int ti_sn_bridge_parse_dsi_host(struct ti_sn_bridge *pdata)
        return 0;
 }
 
+#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_sn_bridge *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_sn_bridge *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(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_sn_bridge *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_sn_bridge *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(pdata->dev);
+
+       return 0;
+}
+
+static int ti_sn_bridge_gpio_direction_output(struct gpio_chip *chip,
+                                             unsigned int offset, int val)
+{
+       struct ti_sn_bridge *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(pdata->dev);
+       }
+
+       return ret;
+}
+
+static void ti_sn_bridge_gpio_free(struct gpio_chip *chip, unsigned int offset)
+{
+       /* We won't keep pm_runtime if we're input, so switch there on free */
+       ti_sn_bridge_gpio_direction_input(chip, offset);
+}
+
+static const char * const ti_sn_bridge_gpio_names[SN_NUM_GPIOS] = {
+       "GPIO1", "GPIO2", "GPIO3", "GPIO4"
+};
+
+static int ti_sn_setup_gpio_controller(struct ti_sn_bridge *pdata)
+{
+       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.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(pdata->dev, &pdata->gchip, pdata);
+       if (ret)
+               dev_err(pdata->dev, "can't add gpio chip\n");
+
+       return ret;
+}
+
+#else
+
+static inline int ti_sn_setup_gpio_controller(struct ti_sn_bridge *pdata)
+{
+       return 0;
+}
+
+#endif
+
+static void ti_sn_bridge_parse_lanes(struct ti_sn_bridge *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 = of_property_count_u32_elems(endpoint, "data-lanes");
+       if (dp_lanes > 0 && dp_lanes <= SN_MAX_DP_LANES) {
+               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_probe(struct i2c_client *client,
                              const struct i2c_device_id *id)
 {
@@ -916,6 +1198,8 @@ static int ti_sn_bridge_probe(struct i2c_client *client,
                return ret;
        }
 
+       ti_sn_bridge_parse_lanes(pdata, client->dev.of_node);
+
        ret = ti_sn_bridge_parse_regulators(pdata);
        if (ret) {
                DRM_ERROR("failed to parse regulators\n");
@@ -937,6 +1221,12 @@ static int ti_sn_bridge_probe(struct i2c_client *client,
 
        pm_runtime_enable(pdata->dev);
 
+       ret = ti_sn_setup_gpio_controller(pdata);
+       if (ret) {
+               pm_runtime_disable(pdata->dev);
+               return ret;
+       }
+
        i2c_set_clientdata(client, pdata);
 
        pdata->aux.name = "ti-sn65dsi86-aux";