diff options
| author | Vincent Palatin <vpalatin@chromium.org> | 2015-01-20 11:38:53 -0500 |
|---|---|---|
| committer | Thierry Reding <treding@nvidia.com> | 2015-03-24 06:16:47 -0400 |
| commit | b2ea8772799d3a0f747eddcf2006fa70e86fad81 (patch) | |
| tree | aae86692ee2cc1e9da7b4ddceea1a796be335c1a | |
| parent | c517d838eb7d07bbe9507871fab3931deccff539 (diff) | |
drm/bridge: Add I2C based driver for ps8622/ps8625 bridge
This patch adds drm_bridge driver for parade DisplayPort
to LVDS bridge chip.
Signed-off-by: Vincent Palatin <vpalatin@chromium.org>
Signed-off-by: Andrew Bresticker <abrestic@chromium.org>
Signed-off-by: Sean Paul <seanpaul@chromium.org>
Signed-off-by: Rahul Sharma <rahul.sharma@samsung.com>
Signed-off-by: Ajay Kumar <ajaykumar.rs@samsung.com>
Acked-by: Inki Dae <inki.dae@samsung.com>
Tested-by: Rahul Sharma <rahul.sharma@samsung.com>
Tested-by: Javier Martinez Canillas <javier.martinez@collabora.co.uk>
Tested-by: Gustavo Padovan <gustavo.padovan@collabora.co.uk>
Tested-by: Sjoerd Simons <sjoerd.simons@collabora.co.uk>
[treding@nvidia.com: break cyclic dependency, add KMS helper dependency]
Signed-off-by: Thierry Reding <treding@nvidia.com>
| -rw-r--r-- | drivers/gpu/drm/bridge/Kconfig | 11 | ||||
| -rw-r--r-- | drivers/gpu/drm/bridge/Makefile | 1 | ||||
| -rw-r--r-- | drivers/gpu/drm/bridge/ps8622.c | 684 |
3 files changed, 696 insertions, 0 deletions
diff --git a/drivers/gpu/drm/bridge/Kconfig b/drivers/gpu/drm/bridge/Kconfig index f38bbcdf929b..acef3223772c 100644 --- a/drivers/gpu/drm/bridge/Kconfig +++ b/drivers/gpu/drm/bridge/Kconfig | |||
| @@ -11,3 +11,14 @@ config DRM_PTN3460 | |||
| 11 | select DRM_PANEL | 11 | select DRM_PANEL |
| 12 | ---help--- | 12 | ---help--- |
| 13 | ptn3460 eDP-LVDS bridge chip driver. | 13 | ptn3460 eDP-LVDS bridge chip driver. |
| 14 | |||
| 15 | config DRM_PS8622 | ||
| 16 | tristate "Parade eDP/LVDS bridge" | ||
| 17 | depends on DRM | ||
| 18 | depends on OF | ||
| 19 | select DRM_PANEL | ||
| 20 | select DRM_KMS_HELPER | ||
| 21 | select BACKLIGHT_LCD_SUPPORT | ||
| 22 | select BACKLIGHT_CLASS_DEVICE | ||
| 23 | ---help--- | ||
| 24 | parade eDP-LVDS bridge chip driver. | ||
diff --git a/drivers/gpu/drm/bridge/Makefile b/drivers/gpu/drm/bridge/Makefile index d8a8cfd12fbb..8dfebd984370 100644 --- a/drivers/gpu/drm/bridge/Makefile +++ b/drivers/gpu/drm/bridge/Makefile | |||
| @@ -1,4 +1,5 @@ | |||
| 1 | ccflags-y := -Iinclude/drm | 1 | ccflags-y := -Iinclude/drm |
| 2 | 2 | ||
| 3 | obj-$(CONFIG_DRM_PS8622) += ps8622.o | ||
| 3 | obj-$(CONFIG_DRM_PTN3460) += ptn3460.o | 4 | obj-$(CONFIG_DRM_PTN3460) += ptn3460.o |
| 4 | obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o | 5 | obj-$(CONFIG_DRM_DW_HDMI) += dw_hdmi.o |
diff --git a/drivers/gpu/drm/bridge/ps8622.c b/drivers/gpu/drm/bridge/ps8622.c new file mode 100644 index 000000000000..5474a3957dc5 --- /dev/null +++ b/drivers/gpu/drm/bridge/ps8622.c | |||
| @@ -0,0 +1,684 @@ | |||
| 1 | /* | ||
| 2 | * Parade PS8622 eDP/LVDS bridge driver | ||
| 3 | * | ||
| 4 | * Copyright (C) 2014 Google, Inc. | ||
| 5 | * | ||
| 6 | * This software is licensed under the terms of the GNU General Public | ||
| 7 | * License version 2, as published by the Free Software Foundation, and | ||
| 8 | * may be copied, distributed, and modified under those terms. | ||
| 9 | * | ||
| 10 | * This program is distributed in the hope that it will be useful, | ||
| 11 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
| 12 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
| 13 | * GNU General Public License for more details. | ||
| 14 | */ | ||
| 15 | |||
| 16 | #include <linux/backlight.h> | ||
| 17 | #include <linux/delay.h> | ||
| 18 | #include <linux/err.h> | ||
| 19 | #include <linux/fb.h> | ||
| 20 | #include <linux/gpio.h> | ||
| 21 | #include <linux/i2c.h> | ||
| 22 | #include <linux/module.h> | ||
| 23 | #include <linux/of.h> | ||
| 24 | #include <linux/of_device.h> | ||
| 25 | #include <linux/of_graph.h> | ||
| 26 | #include <linux/pm.h> | ||
| 27 | #include <linux/regulator/consumer.h> | ||
| 28 | |||
| 29 | #include <drm/drm_panel.h> | ||
| 30 | |||
| 31 | #include "drmP.h" | ||
| 32 | #include "drm_crtc.h" | ||
| 33 | #include "drm_crtc_helper.h" | ||
| 34 | |||
| 35 | /* Brightness scale on the Parade chip */ | ||
| 36 | #define PS8622_MAX_BRIGHTNESS 0xff | ||
| 37 | |||
| 38 | /* Timings taken from the version 1.7 datasheet for the PS8622/PS8625 */ | ||
| 39 | #define PS8622_POWER_RISE_T1_MIN_US 10 | ||
| 40 | #define PS8622_POWER_RISE_T1_MAX_US 10000 | ||
| 41 | #define PS8622_RST_HIGH_T2_MIN_US 3000 | ||
| 42 | #define PS8622_RST_HIGH_T2_MAX_US 30000 | ||
| 43 | #define PS8622_PWMO_END_T12_MS 200 | ||
| 44 | #define PS8622_POWER_FALL_T16_MAX_US 10000 | ||
| 45 | #define PS8622_POWER_OFF_T17_MS 500 | ||
| 46 | |||
| 47 | #if ((PS8622_RST_HIGH_T2_MIN_US + PS8622_POWER_RISE_T1_MAX_US) > \ | ||
| 48 | (PS8622_RST_HIGH_T2_MAX_US + PS8622_POWER_RISE_T1_MIN_US)) | ||
| 49 | #error "T2.min + T1.max must be less than T2.max + T1.min" | ||
| 50 | #endif | ||
| 51 | |||
| 52 | struct ps8622_bridge { | ||
| 53 | struct drm_connector connector; | ||
| 54 | struct i2c_client *client; | ||
| 55 | struct drm_bridge bridge; | ||
| 56 | struct drm_panel *panel; | ||
| 57 | struct regulator *v12; | ||
| 58 | struct backlight_device *bl; | ||
| 59 | |||
| 60 | struct gpio_desc *gpio_slp; | ||
| 61 | struct gpio_desc *gpio_rst; | ||
| 62 | |||
| 63 | u32 max_lane_count; | ||
| 64 | u32 lane_count; | ||
| 65 | |||
| 66 | bool enabled; | ||
| 67 | }; | ||
| 68 | |||
| 69 | static inline struct ps8622_bridge * | ||
| 70 | bridge_to_ps8622(struct drm_bridge *bridge) | ||
| 71 | { | ||
| 72 | return container_of(bridge, struct ps8622_bridge, bridge); | ||
| 73 | } | ||
| 74 | |||
| 75 | static inline struct ps8622_bridge * | ||
| 76 | connector_to_ps8622(struct drm_connector *connector) | ||
| 77 | { | ||
| 78 | return container_of(connector, struct ps8622_bridge, connector); | ||
| 79 | } | ||
| 80 | |||
| 81 | static int ps8622_set(struct i2c_client *client, u8 page, u8 reg, u8 val) | ||
| 82 | { | ||
| 83 | int ret; | ||
| 84 | struct i2c_adapter *adap = client->adapter; | ||
| 85 | struct i2c_msg msg; | ||
| 86 | u8 data[] = {reg, val}; | ||
| 87 | |||
| 88 | msg.addr = client->addr + page; | ||
| 89 | msg.flags = 0; | ||
| 90 | msg.len = sizeof(data); | ||
| 91 | msg.buf = data; | ||
| 92 | |||
| 93 | ret = i2c_transfer(adap, &msg, 1); | ||
| 94 | if (ret != 1) | ||
| 95 | pr_warn("PS8622 I2C write (0x%02x,0x%02x,0x%02x) failed: %d\n", | ||
| 96 | client->addr + page, reg, val, ret); | ||
| 97 | return !(ret == 1); | ||
| 98 | } | ||
| 99 | |||
| 100 | static int ps8622_send_config(struct ps8622_bridge *ps8622) | ||
| 101 | { | ||
| 102 | struct i2c_client *cl = ps8622->client; | ||
| 103 | int err = 0; | ||
| 104 | |||
| 105 | /* HPD low */ | ||
| 106 | err = ps8622_set(cl, 0x02, 0xa1, 0x01); | ||
| 107 | if (err) | ||
| 108 | goto error; | ||
| 109 | |||
| 110 | /* SW setting: [1:0] SW output 1.2V voltage is lower to 96% */ | ||
| 111 | err = ps8622_set(cl, 0x04, 0x14, 0x01); | ||
| 112 | if (err) | ||
| 113 | goto error; | ||
| 114 | |||
| 115 | /* RCO SS setting: [5:4] = b01 0.5%, b10 1%, b11 1.5% */ | ||
| 116 | err = ps8622_set(cl, 0x04, 0xe3, 0x20); | ||
| 117 | if (err) | ||
| 118 | goto error; | ||
| 119 | |||
| 120 | /* [7] RCO SS enable */ | ||
| 121 | err = ps8622_set(cl, 0x04, 0xe2, 0x80); | ||
| 122 | if (err) | ||
| 123 | goto error; | ||
| 124 | |||
| 125 | /* RPHY Setting | ||
| 126 | * [3:2] CDR tune wait cycle before measure for fine tune | ||
| 127 | * b00: 1us b01: 0.5us b10:2us, b11: 4us | ||
| 128 | */ | ||
| 129 | err = ps8622_set(cl, 0x04, 0x8a, 0x0c); | ||
| 130 | if (err) | ||
| 131 | goto error; | ||
| 132 | |||
| 133 | /* [3] RFD always on */ | ||
| 134 | err = ps8622_set(cl, 0x04, 0x89, 0x08); | ||
| 135 | if (err) | ||
| 136 | goto error; | ||
| 137 | |||
| 138 | /* CTN lock in/out: 20000ppm/80000ppm. Lock out 2 times. */ | ||
| 139 | err = ps8622_set(cl, 0x04, 0x71, 0x2d); | ||
| 140 | if (err) | ||
| 141 | goto error; | ||
| 142 | |||
| 143 | /* 2.7G CDR settings: NOF=40LSB for HBR CDR setting */ | ||
| 144 | err = ps8622_set(cl, 0x04, 0x7d, 0x07); | ||
| 145 | if (err) | ||
| 146 | goto error; | ||
| 147 | |||
| 148 | /* [1:0] Fmin=+4bands */ | ||
| 149 | err = ps8622_set(cl, 0x04, 0x7b, 0x00); | ||
| 150 | if (err) | ||
| 151 | goto error; | ||
| 152 | |||
| 153 | /* [7:5] DCO_FTRNG=+-40% */ | ||
| 154 | err = ps8622_set(cl, 0x04, 0x7a, 0xfd); | ||
| 155 | if (err) | ||
| 156 | goto error; | ||
| 157 | |||
| 158 | /* 1.62G CDR settings: [5:2]NOF=64LSB [1:0]DCO scale is 2/5 */ | ||
| 159 | err = ps8622_set(cl, 0x04, 0xc0, 0x12); | ||
| 160 | if (err) | ||
| 161 | goto error; | ||
| 162 | |||
| 163 | /* Gitune=-37% */ | ||
| 164 | err = ps8622_set(cl, 0x04, 0xc1, 0x92); | ||
| 165 | |||
