0001
0002
0003
0004
0005
0006 #include <linux/clk.h>
0007 #include <linux/delay.h>
0008 #include <linux/interrupt.h>
0009 #include <linux/io.h>
0010 #include <linux/module.h>
0011 #include <linux/of_device.h>
0012 #include <linux/pinctrl/pinconf-generic.h>
0013 #include <linux/pinctrl/pinctrl.h>
0014 #include <linux/pinctrl/pinmux.h>
0015 #include <linux/platform_device.h>
0016 #include <linux/pm_runtime.h>
0017 #include <linux/regulator/consumer.h>
0018 #include <linux/reset.h>
0019 #include <linux/workqueue.h>
0020
0021 #include <drm/display/drm_dp_helper.h>
0022 #include <drm/display/drm_dp_aux_bus.h>
0023 #include <drm/drm_panel.h>
0024
0025 #include "dp.h"
0026 #include "dpaux.h"
0027 #include "drm.h"
0028 #include "trace.h"
0029
0030 static DEFINE_MUTEX(dpaux_lock);
0031 static LIST_HEAD(dpaux_list);
0032
0033 struct tegra_dpaux_soc {
0034 unsigned int cmh;
0035 unsigned int drvz;
0036 unsigned int drvi;
0037 };
0038
0039 struct tegra_dpaux {
0040 struct drm_dp_aux aux;
0041 struct device *dev;
0042
0043 const struct tegra_dpaux_soc *soc;
0044
0045 void __iomem *regs;
0046 int irq;
0047
0048 struct tegra_output *output;
0049
0050 struct reset_control *rst;
0051 struct clk *clk_parent;
0052 struct clk *clk;
0053
0054 struct regulator *vdd;
0055
0056 struct completion complete;
0057 struct work_struct work;
0058 struct list_head list;
0059
0060 #ifdef CONFIG_GENERIC_PINCONF
0061 struct pinctrl_dev *pinctrl;
0062 struct pinctrl_desc desc;
0063 #endif
0064 };
0065
0066 static inline struct tegra_dpaux *to_dpaux(struct drm_dp_aux *aux)
0067 {
0068 return container_of(aux, struct tegra_dpaux, aux);
0069 }
0070
0071 static inline struct tegra_dpaux *work_to_dpaux(struct work_struct *work)
0072 {
0073 return container_of(work, struct tegra_dpaux, work);
0074 }
0075
0076 static inline u32 tegra_dpaux_readl(struct tegra_dpaux *dpaux,
0077 unsigned int offset)
0078 {
0079 u32 value = readl(dpaux->regs + (offset << 2));
0080
0081 trace_dpaux_readl(dpaux->dev, offset, value);
0082
0083 return value;
0084 }
0085
0086 static inline void tegra_dpaux_writel(struct tegra_dpaux *dpaux,
0087 u32 value, unsigned int offset)
0088 {
0089 trace_dpaux_writel(dpaux->dev, offset, value);
0090 writel(value, dpaux->regs + (offset << 2));
0091 }
0092
0093 static void tegra_dpaux_write_fifo(struct tegra_dpaux *dpaux, const u8 *buffer,
0094 size_t size)
0095 {
0096 size_t i, j;
0097
0098 for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
0099 size_t num = min_t(size_t, size - i * 4, 4);
0100 u32 value = 0;
0101
0102 for (j = 0; j < num; j++)
0103 value |= buffer[i * 4 + j] << (j * 8);
0104
0105 tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXDATA_WRITE(i));
0106 }
0107 }
0108
0109 static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer,
0110 size_t size)
0111 {
0112 size_t i, j;
0113
0114 for (i = 0; i < DIV_ROUND_UP(size, 4); i++) {
0115 size_t num = min_t(size_t, size - i * 4, 4);
0116 u32 value;
0117
0118 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXDATA_READ(i));
0119
0120 for (j = 0; j < num; j++)
0121 buffer[i * 4 + j] = value >> (j * 8);
0122 }
0123 }
0124
0125 static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
0126 struct drm_dp_aux_msg *msg)
0127 {
0128 unsigned long timeout = msecs_to_jiffies(250);
0129 struct tegra_dpaux *dpaux = to_dpaux(aux);
0130 unsigned long status;
0131 ssize_t ret = 0;
0132 u8 reply = 0;
0133 u32 value;
0134
0135
0136 if (msg->size > 16)
0137 return -EINVAL;
0138
0139
0140
0141
0142
0143 if (msg->size < 1) {
0144 switch (msg->request & ~DP_AUX_I2C_MOT) {
0145 case DP_AUX_I2C_WRITE_STATUS_UPDATE:
0146 case DP_AUX_I2C_WRITE:
0147 case DP_AUX_I2C_READ:
0148 value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
0149 break;
0150
0151 default:
0152 return -EINVAL;
0153 }
0154 } else {
0155
0156 value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
0157 }
0158
0159 switch (msg->request & ~DP_AUX_I2C_MOT) {
0160 case DP_AUX_I2C_WRITE:
0161 if (msg->request & DP_AUX_I2C_MOT)
0162 value |= DPAUX_DP_AUXCTL_CMD_MOT_WR;
0163 else
0164 value |= DPAUX_DP_AUXCTL_CMD_I2C_WR;
0165
0166 break;
0167
0168 case DP_AUX_I2C_READ:
0169 if (msg->request & DP_AUX_I2C_MOT)
0170 value |= DPAUX_DP_AUXCTL_CMD_MOT_RD;
0171 else
0172 value |= DPAUX_DP_AUXCTL_CMD_I2C_RD;
0173
0174 break;
0175
0176 case DP_AUX_I2C_WRITE_STATUS_UPDATE:
0177 if (msg->request & DP_AUX_I2C_MOT)
0178 value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
0179 else
0180 value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ;
0181
0182 break;
0183
0184 case DP_AUX_NATIVE_WRITE:
0185 value |= DPAUX_DP_AUXCTL_CMD_AUX_WR;
0186 break;
0187
0188 case DP_AUX_NATIVE_READ:
0189 value |= DPAUX_DP_AUXCTL_CMD_AUX_RD;
0190 break;
0191
0192 default:
0193 return -EINVAL;
0194 }
0195
0196 tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
0197 tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
0198
0199 if ((msg->request & DP_AUX_I2C_READ) == 0) {
0200 tegra_dpaux_write_fifo(dpaux, msg->buffer, msg->size);
0201 ret = msg->size;
0202 }
0203
0204
0205 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXCTL);
0206 value |= DPAUX_DP_AUXCTL_TRANSACTREQ;
0207 tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
0208
0209 status = wait_for_completion_timeout(&dpaux->complete, timeout);
0210 if (!status)
0211 return -ETIMEDOUT;
0212
0213
0214 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
0215 tegra_dpaux_writel(dpaux, 0xf00, DPAUX_DP_AUXSTAT);
0216
0217 if (value & DPAUX_DP_AUXSTAT_TIMEOUT_ERROR)
0218 return -ETIMEDOUT;
0219
0220 if ((value & DPAUX_DP_AUXSTAT_RX_ERROR) ||
0221 (value & DPAUX_DP_AUXSTAT_SINKSTAT_ERROR) ||
0222 (value & DPAUX_DP_AUXSTAT_NO_STOP_ERROR))
0223 return -EIO;
0224
0225 switch ((value & DPAUX_DP_AUXSTAT_REPLY_TYPE_MASK) >> 16) {
0226 case 0x00:
0227 reply = DP_AUX_NATIVE_REPLY_ACK;
0228 break;
0229
0230 case 0x01:
0231 reply = DP_AUX_NATIVE_REPLY_NACK;
0232 break;
0233
0234 case 0x02:
0235 reply = DP_AUX_NATIVE_REPLY_DEFER;
0236 break;
0237
0238 case 0x04:
0239 reply = DP_AUX_I2C_REPLY_NACK;
0240 break;
0241
0242 case 0x08:
0243 reply = DP_AUX_I2C_REPLY_DEFER;
0244 break;
0245 }
0246
0247 if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
0248 if (msg->request & DP_AUX_I2C_READ) {
0249 size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK;
0250
0251
0252
0253
0254
0255
0256 if (count != msg->size) {
0257 ret = -EBUSY;
0258 goto out;
0259 }
0260
0261 tegra_dpaux_read_fifo(dpaux, msg->buffer, count);
0262 ret = count;
0263 }
0264 }
0265
0266 msg->reply = reply;
0267
0268 out:
0269 return ret;
0270 }
0271
0272 static void tegra_dpaux_hotplug(struct work_struct *work)
0273 {
0274 struct tegra_dpaux *dpaux = work_to_dpaux(work);
0275
0276 if (dpaux->output)
0277 drm_helper_hpd_irq_event(dpaux->output->connector.dev);
0278 }
0279
0280 static irqreturn_t tegra_dpaux_irq(int irq, void *data)
0281 {
0282 struct tegra_dpaux *dpaux = data;
0283 u32 value;
0284
0285
0286 value = tegra_dpaux_readl(dpaux, DPAUX_INTR_AUX);
0287 tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX);
0288
0289 if (value & (DPAUX_INTR_PLUG_EVENT | DPAUX_INTR_UNPLUG_EVENT))
0290 schedule_work(&dpaux->work);
0291
0292 if (value & DPAUX_INTR_IRQ_EVENT) {
0293
0294 }
0295
0296 if (value & DPAUX_INTR_AUX_DONE)
0297 complete(&dpaux->complete);
0298
0299 return IRQ_HANDLED;
0300 }
0301
0302 enum tegra_dpaux_functions {
0303 DPAUX_PADCTL_FUNC_AUX,
0304 DPAUX_PADCTL_FUNC_I2C,
0305 DPAUX_PADCTL_FUNC_OFF,
0306 };
0307
0308 static void tegra_dpaux_pad_power_down(struct tegra_dpaux *dpaux)
0309 {
0310 u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
0311
0312 value |= DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
0313
0314 tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
0315 }
0316
0317 static void tegra_dpaux_pad_power_up(struct tegra_dpaux *dpaux)
0318 {
0319 u32 value = tegra_dpaux_readl(dpaux, DPAUX_HYBRID_SPARE);
0320
0321 value &= ~DPAUX_HYBRID_SPARE_PAD_POWER_DOWN;
0322
0323 tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_SPARE);
0324 }
0325
0326 static int tegra_dpaux_pad_config(struct tegra_dpaux *dpaux, unsigned function)
0327 {
0328 u32 value;
0329
0330 switch (function) {
0331 case DPAUX_PADCTL_FUNC_AUX:
0332 value = DPAUX_HYBRID_PADCTL_AUX_CMH(dpaux->soc->cmh) |
0333 DPAUX_HYBRID_PADCTL_AUX_DRVZ(dpaux->soc->drvz) |
0334 DPAUX_HYBRID_PADCTL_AUX_DRVI(dpaux->soc->drvi) |
0335 DPAUX_HYBRID_PADCTL_AUX_INPUT_RCV |
0336 DPAUX_HYBRID_PADCTL_MODE_AUX;
0337 break;
0338
0339 case DPAUX_PADCTL_FUNC_I2C:
0340 value = DPAUX_HYBRID_PADCTL_I2C_SDA_INPUT_RCV |
0341 DPAUX_HYBRID_PADCTL_I2C_SCL_INPUT_RCV |
0342 DPAUX_HYBRID_PADCTL_AUX_CMH(dpaux->soc->cmh) |
0343 DPAUX_HYBRID_PADCTL_AUX_DRVZ(dpaux->soc->drvz) |
0344 DPAUX_HYBRID_PADCTL_AUX_DRVI(dpaux->soc->drvi) |
0345 DPAUX_HYBRID_PADCTL_MODE_I2C;
0346 break;
0347
0348 case DPAUX_PADCTL_FUNC_OFF:
0349 tegra_dpaux_pad_power_down(dpaux);
0350 return 0;
0351
0352 default:
0353 return -ENOTSUPP;
0354 }
0355
0356 tegra_dpaux_writel(dpaux, value, DPAUX_HYBRID_PADCTL);
0357 tegra_dpaux_pad_power_up(dpaux);
0358
0359 return 0;
0360 }
0361
0362 #ifdef CONFIG_GENERIC_PINCONF
0363 static const struct pinctrl_pin_desc tegra_dpaux_pins[] = {
0364 PINCTRL_PIN(0, "DP_AUX_CHx_P"),
0365 PINCTRL_PIN(1, "DP_AUX_CHx_N"),
0366 };
0367
0368 static const unsigned tegra_dpaux_pin_numbers[] = { 0, 1 };
0369
0370 static const char * const tegra_dpaux_groups[] = {
0371 "dpaux-io",
0372 };
0373
0374 static const char * const tegra_dpaux_functions[] = {
0375 "aux",
0376 "i2c",
0377 "off",
0378 };
0379
0380 static int tegra_dpaux_get_groups_count(struct pinctrl_dev *pinctrl)
0381 {
0382 return ARRAY_SIZE(tegra_dpaux_groups);
0383 }
0384
0385 static const char *tegra_dpaux_get_group_name(struct pinctrl_dev *pinctrl,
0386 unsigned int group)
0387 {
0388 return tegra_dpaux_groups[group];
0389 }
0390
0391 static int tegra_dpaux_get_group_pins(struct pinctrl_dev *pinctrl,
0392 unsigned group, const unsigned **pins,
0393 unsigned *num_pins)
0394 {
0395 *pins = tegra_dpaux_pin_numbers;
0396 *num_pins = ARRAY_SIZE(tegra_dpaux_pin_numbers);
0397
0398 return 0;
0399 }
0400
0401 static const struct pinctrl_ops tegra_dpaux_pinctrl_ops = {
0402 .get_groups_count = tegra_dpaux_get_groups_count,
0403 .get_group_name = tegra_dpaux_get_group_name,
0404 .get_group_pins = tegra_dpaux_get_group_pins,
0405 .dt_node_to_map = pinconf_generic_dt_node_to_map_group,
0406 .dt_free_map = pinconf_generic_dt_free_map,
0407 };
0408
0409 static int tegra_dpaux_get_functions_count(struct pinctrl_dev *pinctrl)
0410 {
0411 return ARRAY_SIZE(tegra_dpaux_functions);
0412 }
0413
0414 static const char *tegra_dpaux_get_function_name(struct pinctrl_dev *pinctrl,
0415 unsigned int function)
0416 {
0417 return tegra_dpaux_functions[function];
0418 }
0419
0420 static int tegra_dpaux_get_function_groups(struct pinctrl_dev *pinctrl,
0421 unsigned int function,
0422 const char * const **groups,
0423 unsigned * const num_groups)
0424 {
0425 *num_groups = ARRAY_SIZE(tegra_dpaux_groups);
0426 *groups = tegra_dpaux_groups;
0427
0428 return 0;
0429 }
0430
0431 static int tegra_dpaux_set_mux(struct pinctrl_dev *pinctrl,
0432 unsigned int function, unsigned int group)
0433 {
0434 struct tegra_dpaux *dpaux = pinctrl_dev_get_drvdata(pinctrl);
0435
0436 return tegra_dpaux_pad_config(dpaux, function);
0437 }
0438
0439 static const struct pinmux_ops tegra_dpaux_pinmux_ops = {
0440 .get_functions_count = tegra_dpaux_get_functions_count,
0441 .get_function_name = tegra_dpaux_get_function_name,
0442 .get_function_groups = tegra_dpaux_get_function_groups,
0443 .set_mux = tegra_dpaux_set_mux,
0444 };
0445 #endif
0446
0447 static int tegra_dpaux_probe(struct platform_device *pdev)
0448 {
0449 struct tegra_dpaux *dpaux;
0450 struct resource *regs;
0451 u32 value;
0452 int err;
0453
0454 dpaux = devm_kzalloc(&pdev->dev, sizeof(*dpaux), GFP_KERNEL);
0455 if (!dpaux)
0456 return -ENOMEM;
0457
0458 dpaux->soc = of_device_get_match_data(&pdev->dev);
0459 INIT_WORK(&dpaux->work, tegra_dpaux_hotplug);
0460 init_completion(&dpaux->complete);
0461 INIT_LIST_HEAD(&dpaux->list);
0462 dpaux->dev = &pdev->dev;
0463
0464 regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
0465 dpaux->regs = devm_ioremap_resource(&pdev->dev, regs);
0466 if (IS_ERR(dpaux->regs))
0467 return PTR_ERR(dpaux->regs);
0468
0469 dpaux->irq = platform_get_irq(pdev, 0);
0470 if (dpaux->irq < 0)
0471 return -ENXIO;
0472
0473 if (!pdev->dev.pm_domain) {
0474 dpaux->rst = devm_reset_control_get(&pdev->dev, "dpaux");
0475 if (IS_ERR(dpaux->rst)) {
0476 dev_err(&pdev->dev,
0477 "failed to get reset control: %ld\n",
0478 PTR_ERR(dpaux->rst));
0479 return PTR_ERR(dpaux->rst);
0480 }
0481 }
0482
0483 dpaux->clk = devm_clk_get(&pdev->dev, NULL);
0484 if (IS_ERR(dpaux->clk)) {
0485 dev_err(&pdev->dev, "failed to get module clock: %ld\n",
0486 PTR_ERR(dpaux->clk));
0487 return PTR_ERR(dpaux->clk);
0488 }
0489
0490 dpaux->clk_parent = devm_clk_get(&pdev->dev, "parent");
0491 if (IS_ERR(dpaux->clk_parent)) {
0492 dev_err(&pdev->dev, "failed to get parent clock: %ld\n",
0493 PTR_ERR(dpaux->clk_parent));
0494 return PTR_ERR(dpaux->clk_parent);
0495 }
0496
0497 err = clk_set_rate(dpaux->clk_parent, 270000000);
0498 if (err < 0) {
0499 dev_err(&pdev->dev, "failed to set clock to 270 MHz: %d\n",
0500 err);
0501 return err;
0502 }
0503
0504 dpaux->vdd = devm_regulator_get_optional(&pdev->dev, "vdd");
0505 if (IS_ERR(dpaux->vdd)) {
0506 if (PTR_ERR(dpaux->vdd) != -ENODEV) {
0507 if (PTR_ERR(dpaux->vdd) != -EPROBE_DEFER)
0508 dev_err(&pdev->dev,
0509 "failed to get VDD supply: %ld\n",
0510 PTR_ERR(dpaux->vdd));
0511
0512 return PTR_ERR(dpaux->vdd);
0513 }
0514
0515 dpaux->vdd = NULL;
0516 }
0517
0518 platform_set_drvdata(pdev, dpaux);
0519 pm_runtime_enable(&pdev->dev);
0520 pm_runtime_get_sync(&pdev->dev);
0521
0522 err = devm_request_irq(dpaux->dev, dpaux->irq, tegra_dpaux_irq, 0,
0523 dev_name(dpaux->dev), dpaux);
0524 if (err < 0) {
0525 dev_err(dpaux->dev, "failed to request IRQ#%u: %d\n",
0526 dpaux->irq, err);
0527 return err;
0528 }
0529
0530 disable_irq(dpaux->irq);
0531
0532 dpaux->aux.transfer = tegra_dpaux_transfer;
0533 dpaux->aux.dev = &pdev->dev;
0534
0535 drm_dp_aux_init(&dpaux->aux);
0536
0537
0538
0539
0540
0541
0542
0543
0544
0545 err = tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_I2C);
0546 if (err < 0)
0547 return err;
0548
0549 #ifdef CONFIG_GENERIC_PINCONF
0550 dpaux->desc.name = dev_name(&pdev->dev);
0551 dpaux->desc.pins = tegra_dpaux_pins;
0552 dpaux->desc.npins = ARRAY_SIZE(tegra_dpaux_pins);
0553 dpaux->desc.pctlops = &tegra_dpaux_pinctrl_ops;
0554 dpaux->desc.pmxops = &tegra_dpaux_pinmux_ops;
0555 dpaux->desc.owner = THIS_MODULE;
0556
0557 dpaux->pinctrl = devm_pinctrl_register(&pdev->dev, &dpaux->desc, dpaux);
0558 if (IS_ERR(dpaux->pinctrl)) {
0559 dev_err(&pdev->dev, "failed to register pincontrol\n");
0560 return PTR_ERR(dpaux->pinctrl);
0561 }
0562 #endif
0563
0564 value = DPAUX_INTR_AUX_DONE | DPAUX_INTR_IRQ_EVENT |
0565 DPAUX_INTR_UNPLUG_EVENT | DPAUX_INTR_PLUG_EVENT;
0566 tegra_dpaux_writel(dpaux, value, DPAUX_INTR_EN_AUX);
0567 tegra_dpaux_writel(dpaux, value, DPAUX_INTR_AUX);
0568
0569 mutex_lock(&dpaux_lock);
0570 list_add_tail(&dpaux->list, &dpaux_list);
0571 mutex_unlock(&dpaux_lock);
0572
0573 err = devm_of_dp_aux_populate_ep_devices(&dpaux->aux);
0574 if (err < 0) {
0575 dev_err(dpaux->dev, "failed to populate AUX bus: %d\n", err);
0576 return err;
0577 }
0578
0579 return 0;
0580 }
0581
0582 static int tegra_dpaux_remove(struct platform_device *pdev)
0583 {
0584 struct tegra_dpaux *dpaux = platform_get_drvdata(pdev);
0585
0586 cancel_work_sync(&dpaux->work);
0587
0588
0589 tegra_dpaux_pad_power_down(dpaux);
0590
0591 pm_runtime_put_sync(&pdev->dev);
0592 pm_runtime_disable(&pdev->dev);
0593
0594 mutex_lock(&dpaux_lock);
0595 list_del(&dpaux->list);
0596 mutex_unlock(&dpaux_lock);
0597
0598 return 0;
0599 }
0600
0601 #ifdef CONFIG_PM
0602 static int tegra_dpaux_suspend(struct device *dev)
0603 {
0604 struct tegra_dpaux *dpaux = dev_get_drvdata(dev);
0605 int err = 0;
0606
0607 if (dpaux->rst) {
0608 err = reset_control_assert(dpaux->rst);
0609 if (err < 0) {
0610 dev_err(dev, "failed to assert reset: %d\n", err);
0611 return err;
0612 }
0613 }
0614
0615 usleep_range(1000, 2000);
0616
0617 clk_disable_unprepare(dpaux->clk_parent);
0618 clk_disable_unprepare(dpaux->clk);
0619
0620 return err;
0621 }
0622
0623 static int tegra_dpaux_resume(struct device *dev)
0624 {
0625 struct tegra_dpaux *dpaux = dev_get_drvdata(dev);
0626 int err;
0627
0628 err = clk_prepare_enable(dpaux->clk);
0629 if (err < 0) {
0630 dev_err(dev, "failed to enable clock: %d\n", err);
0631 return err;
0632 }
0633
0634 err = clk_prepare_enable(dpaux->clk_parent);
0635 if (err < 0) {
0636 dev_err(dev, "failed to enable parent clock: %d\n", err);
0637 goto disable_clk;
0638 }
0639
0640 usleep_range(1000, 2000);
0641
0642 if (dpaux->rst) {
0643 err = reset_control_deassert(dpaux->rst);
0644 if (err < 0) {
0645 dev_err(dev, "failed to deassert reset: %d\n", err);
0646 goto disable_parent;
0647 }
0648
0649 usleep_range(1000, 2000);
0650 }
0651
0652 return 0;
0653
0654 disable_parent:
0655 clk_disable_unprepare(dpaux->clk_parent);
0656 disable_clk:
0657 clk_disable_unprepare(dpaux->clk);
0658 return err;
0659 }
0660 #endif
0661
0662 static const struct dev_pm_ops tegra_dpaux_pm_ops = {
0663 SET_RUNTIME_PM_OPS(tegra_dpaux_suspend, tegra_dpaux_resume, NULL)
0664 };
0665
0666 static const struct tegra_dpaux_soc tegra124_dpaux_soc = {
0667 .cmh = 0x02,
0668 .drvz = 0x04,
0669 .drvi = 0x18,
0670 };
0671
0672 static const struct tegra_dpaux_soc tegra210_dpaux_soc = {
0673 .cmh = 0x02,
0674 .drvz = 0x04,
0675 .drvi = 0x30,
0676 };
0677
0678 static const struct tegra_dpaux_soc tegra194_dpaux_soc = {
0679 .cmh = 0x02,
0680 .drvz = 0x04,
0681 .drvi = 0x2c,
0682 };
0683
0684 static const struct of_device_id tegra_dpaux_of_match[] = {
0685 { .compatible = "nvidia,tegra194-dpaux", .data = &tegra194_dpaux_soc },
0686 { .compatible = "nvidia,tegra186-dpaux", .data = &tegra210_dpaux_soc },
0687 { .compatible = "nvidia,tegra210-dpaux", .data = &tegra210_dpaux_soc },
0688 { .compatible = "nvidia,tegra124-dpaux", .data = &tegra124_dpaux_soc },
0689 { },
0690 };
0691 MODULE_DEVICE_TABLE(of, tegra_dpaux_of_match);
0692
0693 struct platform_driver tegra_dpaux_driver = {
0694 .driver = {
0695 .name = "tegra-dpaux",
0696 .of_match_table = tegra_dpaux_of_match,
0697 .pm = &tegra_dpaux_pm_ops,
0698 },
0699 .probe = tegra_dpaux_probe,
0700 .remove = tegra_dpaux_remove,
0701 };
0702
0703 struct drm_dp_aux *drm_dp_aux_find_by_of_node(struct device_node *np)
0704 {
0705 struct tegra_dpaux *dpaux;
0706
0707 mutex_lock(&dpaux_lock);
0708
0709 list_for_each_entry(dpaux, &dpaux_list, list)
0710 if (np == dpaux->dev->of_node) {
0711 mutex_unlock(&dpaux_lock);
0712 return &dpaux->aux;
0713 }
0714
0715 mutex_unlock(&dpaux_lock);
0716
0717 return NULL;
0718 }
0719
0720 int drm_dp_aux_attach(struct drm_dp_aux *aux, struct tegra_output *output)
0721 {
0722 struct tegra_dpaux *dpaux = to_dpaux(aux);
0723 unsigned long timeout;
0724 int err;
0725
0726 aux->drm_dev = output->connector.dev;
0727 err = drm_dp_aux_register(aux);
0728 if (err < 0)
0729 return err;
0730
0731 output->connector.polled = DRM_CONNECTOR_POLL_HPD;
0732 dpaux->output = output;
0733
0734 if (output->panel) {
0735 enum drm_connector_status status;
0736
0737 if (dpaux->vdd) {
0738 err = regulator_enable(dpaux->vdd);
0739 if (err < 0)
0740 return err;
0741 }
0742
0743 timeout = jiffies + msecs_to_jiffies(250);
0744
0745 while (time_before(jiffies, timeout)) {
0746 status = drm_dp_aux_detect(aux);
0747
0748 if (status == connector_status_connected)
0749 break;
0750
0751 usleep_range(1000, 2000);
0752 }
0753
0754 if (status != connector_status_connected)
0755 return -ETIMEDOUT;
0756 }
0757
0758 enable_irq(dpaux->irq);
0759 return 0;
0760 }
0761
0762 int drm_dp_aux_detach(struct drm_dp_aux *aux)
0763 {
0764 struct tegra_dpaux *dpaux = to_dpaux(aux);
0765 unsigned long timeout;
0766 int err;
0767
0768 drm_dp_aux_unregister(aux);
0769 disable_irq(dpaux->irq);
0770
0771 if (dpaux->output->panel) {
0772 enum drm_connector_status status;
0773
0774 if (dpaux->vdd) {
0775 err = regulator_disable(dpaux->vdd);
0776 if (err < 0)
0777 return err;
0778 }
0779
0780 timeout = jiffies + msecs_to_jiffies(250);
0781
0782 while (time_before(jiffies, timeout)) {
0783 status = drm_dp_aux_detect(aux);
0784
0785 if (status == connector_status_disconnected)
0786 break;
0787
0788 usleep_range(1000, 2000);
0789 }
0790
0791 if (status != connector_status_disconnected)
0792 return -ETIMEDOUT;
0793
0794 dpaux->output = NULL;
0795 }
0796
0797 return 0;
0798 }
0799
0800 enum drm_connector_status drm_dp_aux_detect(struct drm_dp_aux *aux)
0801 {
0802 struct tegra_dpaux *dpaux = to_dpaux(aux);
0803 u32 value;
0804
0805 value = tegra_dpaux_readl(dpaux, DPAUX_DP_AUXSTAT);
0806
0807 if (value & DPAUX_DP_AUXSTAT_HPD_STATUS)
0808 return connector_status_connected;
0809
0810 return connector_status_disconnected;
0811 }
0812
0813 int drm_dp_aux_enable(struct drm_dp_aux *aux)
0814 {
0815 struct tegra_dpaux *dpaux = to_dpaux(aux);
0816
0817 return tegra_dpaux_pad_config(dpaux, DPAUX_PADCTL_FUNC_AUX);
0818 }
0819
0820 int drm_dp_aux_disable(struct drm_dp_aux *aux)
0821 {
0822 struct tegra_dpaux *dpaux = to_dpaux(aux);
0823
0824 tegra_dpaux_pad_power_down(dpaux);
0825
0826 return 0;
0827 }