0001
0002
0003
0004
0005
0006
0007 #include <linux/delay.h>
0008 #include <linux/gpio/consumer.h>
0009 #include <linux/pinctrl/consumer.h>
0010
0011 #include "msm_kms.h"
0012 #include "hdmi.h"
0013
0014 static void msm_hdmi_phy_reset(struct hdmi *hdmi)
0015 {
0016 unsigned int val;
0017
0018 val = hdmi_read(hdmi, REG_HDMI_PHY_CTRL);
0019
0020 if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
0021
0022 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0023 val & ~HDMI_PHY_CTRL_SW_RESET);
0024 } else {
0025
0026 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0027 val | HDMI_PHY_CTRL_SW_RESET);
0028 }
0029
0030 if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
0031
0032 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0033 val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
0034 } else {
0035
0036 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0037 val | HDMI_PHY_CTRL_SW_RESET_PLL);
0038 }
0039
0040 msleep(100);
0041
0042 if (val & HDMI_PHY_CTRL_SW_RESET_LOW) {
0043
0044 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0045 val | HDMI_PHY_CTRL_SW_RESET);
0046 } else {
0047
0048 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0049 val & ~HDMI_PHY_CTRL_SW_RESET);
0050 }
0051
0052 if (val & HDMI_PHY_CTRL_SW_RESET_PLL_LOW) {
0053
0054 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0055 val | HDMI_PHY_CTRL_SW_RESET_PLL);
0056 } else {
0057
0058 hdmi_write(hdmi, REG_HDMI_PHY_CTRL,
0059 val & ~HDMI_PHY_CTRL_SW_RESET_PLL);
0060 }
0061 }
0062
0063 static void enable_hpd_clocks(struct hdmi *hdmi, bool enable)
0064 {
0065 const struct hdmi_platform_config *config = hdmi->config;
0066 struct device *dev = &hdmi->pdev->dev;
0067 int i, ret;
0068
0069 if (enable) {
0070 for (i = 0; i < config->hpd_clk_cnt; i++) {
0071 if (config->hpd_freq && config->hpd_freq[i]) {
0072 ret = clk_set_rate(hdmi->hpd_clks[i],
0073 config->hpd_freq[i]);
0074 if (ret)
0075 dev_warn(dev,
0076 "failed to set clk %s (%d)\n",
0077 config->hpd_clk_names[i], ret);
0078 }
0079
0080 ret = clk_prepare_enable(hdmi->hpd_clks[i]);
0081 if (ret) {
0082 DRM_DEV_ERROR(dev,
0083 "failed to enable hpd clk: %s (%d)\n",
0084 config->hpd_clk_names[i], ret);
0085 }
0086 }
0087 } else {
0088 for (i = config->hpd_clk_cnt - 1; i >= 0; i--)
0089 clk_disable_unprepare(hdmi->hpd_clks[i]);
0090 }
0091 }
0092
0093 int msm_hdmi_hpd_enable(struct drm_bridge *bridge)
0094 {
0095 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
0096 struct hdmi *hdmi = hdmi_bridge->hdmi;
0097 const struct hdmi_platform_config *config = hdmi->config;
0098 struct device *dev = &hdmi->pdev->dev;
0099 uint32_t hpd_ctrl;
0100 int ret;
0101 unsigned long flags;
0102
0103 ret = regulator_bulk_enable(config->hpd_reg_cnt, hdmi->hpd_regs);
0104 if (ret) {
0105 DRM_DEV_ERROR(dev, "failed to enable hpd regulators: %d\n", ret);
0106 goto fail;
0107 }
0108
0109 ret = pinctrl_pm_select_default_state(dev);
0110 if (ret) {
0111 DRM_DEV_ERROR(dev, "pinctrl state chg failed: %d\n", ret);
0112 goto fail;
0113 }
0114
0115 if (hdmi->hpd_gpiod)
0116 gpiod_set_value_cansleep(hdmi->hpd_gpiod, 1);
0117
0118 pm_runtime_get_sync(dev);
0119 enable_hpd_clocks(hdmi, true);
0120
0121 msm_hdmi_set_mode(hdmi, false);
0122 msm_hdmi_phy_reset(hdmi);
0123 msm_hdmi_set_mode(hdmi, true);
0124
0125 hdmi_write(hdmi, REG_HDMI_USEC_REFTIMER, 0x0001001b);
0126
0127
0128 hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
0129 HDMI_HPD_INT_CTRL_INT_CONNECT |
0130 HDMI_HPD_INT_CTRL_INT_EN);
0131
0132
0133 spin_lock_irqsave(&hdmi->reg_lock, flags);
0134 hpd_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_CTRL);
0135 hpd_ctrl |= HDMI_HPD_CTRL_TIMEOUT(0x1fff);
0136
0137
0138 hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
0139 ~HDMI_HPD_CTRL_ENABLE & hpd_ctrl);
0140 hdmi_write(hdmi, REG_HDMI_HPD_CTRL,
0141 HDMI_HPD_CTRL_ENABLE | hpd_ctrl);
0142 spin_unlock_irqrestore(&hdmi->reg_lock, flags);
0143
0144 return 0;
0145
0146 fail:
0147 return ret;
0148 }
0149
0150 void msm_hdmi_hpd_disable(struct hdmi_bridge *hdmi_bridge)
0151 {
0152 struct hdmi *hdmi = hdmi_bridge->hdmi;
0153 const struct hdmi_platform_config *config = hdmi->config;
0154 struct device *dev = &hdmi->pdev->dev;
0155 int ret;
0156
0157
0158 hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, 0);
0159
0160 msm_hdmi_set_mode(hdmi, false);
0161
0162 enable_hpd_clocks(hdmi, false);
0163 pm_runtime_put(dev);
0164
0165 ret = pinctrl_pm_select_sleep_state(dev);
0166 if (ret)
0167 dev_warn(dev, "pinctrl state chg failed: %d\n", ret);
0168
0169 ret = regulator_bulk_disable(config->hpd_reg_cnt, hdmi->hpd_regs);
0170 if (ret)
0171 dev_warn(dev, "failed to disable hpd regulator: %d\n", ret);
0172 }
0173
0174 void msm_hdmi_hpd_irq(struct drm_bridge *bridge)
0175 {
0176 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
0177 struct hdmi *hdmi = hdmi_bridge->hdmi;
0178 uint32_t hpd_int_status, hpd_int_ctrl;
0179
0180
0181 hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
0182 hpd_int_ctrl = hdmi_read(hdmi, REG_HDMI_HPD_INT_CTRL);
0183
0184 if ((hpd_int_ctrl & HDMI_HPD_INT_CTRL_INT_EN) &&
0185 (hpd_int_status & HDMI_HPD_INT_STATUS_INT)) {
0186 bool detected = !!(hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED);
0187
0188
0189 hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL,
0190 HDMI_HPD_INT_CTRL_INT_ACK);
0191
0192 DBG("status=%04x, ctrl=%04x", hpd_int_status, hpd_int_ctrl);
0193
0194
0195 hpd_int_ctrl = HDMI_HPD_INT_CTRL_INT_EN;
0196 if (!detected)
0197 hpd_int_ctrl |= HDMI_HPD_INT_CTRL_INT_CONNECT;
0198 hdmi_write(hdmi, REG_HDMI_HPD_INT_CTRL, hpd_int_ctrl);
0199
0200 queue_work(hdmi->workq, &hdmi_bridge->hpd_work);
0201 }
0202 }
0203
0204 static enum drm_connector_status detect_reg(struct hdmi *hdmi)
0205 {
0206 uint32_t hpd_int_status;
0207
0208 pm_runtime_get_sync(&hdmi->pdev->dev);
0209 enable_hpd_clocks(hdmi, true);
0210
0211 hpd_int_status = hdmi_read(hdmi, REG_HDMI_HPD_INT_STATUS);
0212
0213 enable_hpd_clocks(hdmi, false);
0214 pm_runtime_put(&hdmi->pdev->dev);
0215
0216 return (hpd_int_status & HDMI_HPD_INT_STATUS_CABLE_DETECTED) ?
0217 connector_status_connected : connector_status_disconnected;
0218 }
0219
0220 #define HPD_GPIO_INDEX 2
0221 static enum drm_connector_status detect_gpio(struct hdmi *hdmi)
0222 {
0223 return gpiod_get_value(hdmi->hpd_gpiod) ?
0224 connector_status_connected :
0225 connector_status_disconnected;
0226 }
0227
0228 enum drm_connector_status msm_hdmi_bridge_detect(
0229 struct drm_bridge *bridge)
0230 {
0231 struct hdmi_bridge *hdmi_bridge = to_hdmi_bridge(bridge);
0232 struct hdmi *hdmi = hdmi_bridge->hdmi;
0233 enum drm_connector_status stat_gpio, stat_reg;
0234 int retry = 20;
0235
0236
0237
0238
0239
0240 if (!hdmi->hpd_gpiod)
0241 return detect_reg(hdmi);
0242
0243 do {
0244 stat_gpio = detect_gpio(hdmi);
0245 stat_reg = detect_reg(hdmi);
0246
0247 if (stat_gpio == stat_reg)
0248 break;
0249
0250 mdelay(10);
0251 } while (--retry);
0252
0253
0254
0255
0256
0257 if (stat_gpio != stat_reg) {
0258 DBG("HDMI_HPD_INT_STATUS tells us: %d", stat_reg);
0259 DBG("hpd gpio tells us: %d", stat_gpio);
0260 }
0261
0262 return stat_gpio;
0263 }