1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Copyright (C) 2020 Marek Vasut <marex@denx.de> 4 * 5 * Based on tc358764.c by 6 * Andrzej Hajda <a.hajda@samsung.com> 7 * Maciej Purski <m.purski@samsung.com> 8 * 9 * Based on rpi_touchscreen.c by 10 * Eric Anholt <eric@anholt.net> 11 */ 12 13 #include <linux/delay.h> 14 #include <linux/gpio/consumer.h> 15 #include <linux/mod_devicetable.h> 16 #include <linux/module.h> 17 #include <linux/of_graph.h> 18 #include <linux/regulator/consumer.h> 19 20 #include <video/mipi_display.h> 21 22 #include <drm/drm_atomic_helper.h> 23 #include <drm/drm_crtc.h> 24 #include <drm/drm_mipi_dsi.h> 25 #include <drm/drm_of.h> 26 #include <drm/drm_panel.h> 27 #include <drm/drm_print.h> 28 #include <drm/drm_probe_helper.h> 29 30 /* PPI layer registers */ 31 #define PPI_STARTPPI 0x0104 /* START control bit */ 32 #define PPI_LPTXTIMECNT 0x0114 /* LPTX timing signal */ 33 #define PPI_D0S_ATMR 0x0144 34 #define PPI_D1S_ATMR 0x0148 35 #define PPI_D0S_CLRSIPOCOUNT 0x0164 /* Assertion timer for Lane 0 */ 36 #define PPI_D1S_CLRSIPOCOUNT 0x0168 /* Assertion timer for Lane 1 */ 37 #define PPI_START_FUNCTION 1 38 39 /* DSI layer registers */ 40 #define DSI_STARTDSI 0x0204 /* START control bit of DSI-TX */ 41 #define DSI_LANEENABLE 0x0210 /* Enables each lane */ 42 #define DSI_RX_START 1 43 44 /* LCDC/DPI Host Registers, based on guesswork that this matches TC358764 */ 45 #define LCDCTRL 0x0420 /* Video Path Control */ 46 #define LCDCTRL_MSF BIT(0) /* Magic square in RGB666 */ 47 #define LCDCTRL_VTGEN BIT(4)/* Use chip clock for timing */ 48 #define LCDCTRL_UNK6 BIT(6) /* Unknown */ 49 #define LCDCTRL_EVTMODE BIT(5) /* Event mode */ 50 #define LCDCTRL_RGB888 BIT(8) /* RGB888 mode */ 51 #define LCDCTRL_HSPOL BIT(17) /* Polarity of HSYNC signal */ 52 #define LCDCTRL_DEPOL BIT(18) /* Polarity of DE signal */ 53 #define LCDCTRL_VSPOL BIT(19) /* Polarity of VSYNC signal */ 54 #define LCDCTRL_VSDELAY(v) (((v) & 0xfff) << 20) /* VSYNC delay */ 55 56 /* SPI Master Registers */ 57 #define SPICMR 0x0450 58 #define SPITCR 0x0454 59 60 /* System Controller Registers */ 61 #define SYSCTRL 0x0464 62 63 /* System registers */ 64 #define LPX_PERIOD 3 65 66 /* Lane enable PPI and DSI register bits */ 67 #define LANEENABLE_CLEN BIT(0) 68 #define LANEENABLE_L0EN BIT(1) 69 #define LANEENABLE_L1EN BIT(2) 70 71 struct tc358762 { 72 struct device *dev; 73 struct drm_bridge bridge; 74 struct regulator *regulator; 75 struct drm_bridge *panel_bridge; 76 struct gpio_desc *reset_gpio; 77 bool pre_enabled; 78 int error; 79 }; 80 81 static int tc358762_clear_error(struct tc358762 *ctx) 82 { 83 int ret = ctx->error; 84 85 ctx->error = 0; 86 return ret; 87 } 88 89 static void tc358762_write(struct tc358762 *ctx, u16 addr, u32 val) 90 { 91 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 92 ssize_t ret; 93 u8 data[6]; 94 95 if (ctx->error) 96 return; 97 98 data[0] = addr; 99 data[1] = addr >> 8; 100 data[2] = val; 101 data[3] = val >> 8; 102 data[4] = val >> 16; 103 data[5] = val >> 24; 104 105 ret = mipi_dsi_generic_write(dsi, data, sizeof(data)); 106 if (ret < 0) 107 ctx->error = ret; 108 } 109 110 static inline struct tc358762 *bridge_to_tc358762(struct drm_bridge *bridge) 111 { 112 return container_of(bridge, struct tc358762, bridge); 113 } 114 115 static int tc358762_init(struct tc358762 *ctx) 116 { 117 tc358762_write(ctx, DSI_LANEENABLE, 118 LANEENABLE_L0EN | LANEENABLE_CLEN); 119 tc358762_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5); 120 tc358762_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5); 121 tc358762_write(ctx, PPI_D0S_ATMR, 0); 122 tc358762_write(ctx, PPI_D1S_ATMR, 0); 123 tc358762_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD); 124 125 tc358762_write(ctx, SPICMR, 0x00); 126 tc358762_write(ctx, LCDCTRL, LCDCTRL_VSDELAY(1) | LCDCTRL_RGB888 | 127 LCDCTRL_UNK6 | LCDCTRL_VTGEN); 128 tc358762_write(ctx, SYSCTRL, 0x040f); 129 msleep(100); 130 131 tc358762_write(ctx, PPI_STARTPPI, PPI_START_FUNCTION); 132 tc358762_write(ctx, DSI_STARTDSI, DSI_RX_START); 133 134 msleep(100); 135 136 return tc358762_clear_error(ctx); 137 } 138 139 static void tc358762_post_disable(struct drm_bridge *bridge, struct drm_bridge_state *state) 140 { 141 struct tc358762 *ctx = bridge_to_tc358762(bridge); 142 int ret; 143 144 /* 145 * The post_disable hook might be called multiple times. 146 * We want to avoid regulator imbalance below. 147 */ 148 if (!ctx->pre_enabled) 149 return; 150 151 ctx->pre_enabled = false; 152 153 if (ctx->reset_gpio) 154 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 155 156 ret = regulator_disable(ctx->regulator); 157 if (ret < 0) 158 dev_err(ctx->dev, "error disabling regulators (%d)\n", ret); 159 } 160 161 static void tc358762_pre_enable(struct drm_bridge *bridge, struct drm_bridge_state *state) 162 { 163 struct tc358762 *ctx = bridge_to_tc358762(bridge); 164 int ret; 165 166 ret = regulator_enable(ctx->regulator); 167 if (ret < 0) 168 dev_err(ctx->dev, "error enabling regulators (%d)\n", ret); 169 170 if (ctx->reset_gpio) { 171 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 172 usleep_range(5000, 10000); 173 } 174 175 ctx->pre_enabled = true; 176 } 177 178 static void tc358762_enable(struct drm_bridge *bridge, struct drm_bridge_state *state) 179 { 180 struct tc358762 *ctx = bridge_to_tc358762(bridge); 181 int ret; 182 183 ret = tc358762_init(ctx); 184 if (ret < 0) 185 dev_err(ctx->dev, "error initializing bridge (%d)\n", ret); 186 } 187 188 static int tc358762_attach(struct drm_bridge *bridge, 189 enum drm_bridge_attach_flags flags) 190 { 191 struct tc358762 *ctx = bridge_to_tc358762(bridge); 192 193 return drm_bridge_attach(bridge->encoder, ctx->panel_bridge, 194 bridge, flags); 195 } 196 197 static const struct drm_bridge_funcs tc358762_bridge_funcs = { 198 .atomic_post_disable = tc358762_post_disable, 199 .atomic_pre_enable = tc358762_pre_enable, 200 .atomic_enable = tc358762_enable, 201 .atomic_duplicate_state = drm_atomic_helper_bridge_duplicate_state, 202 .atomic_destroy_state = drm_atomic_helper_bridge_destroy_state, 203 .atomic_reset = drm_atomic_helper_bridge_reset, 204 .attach = tc358762_attach, 205 }; 206 207 static int tc358762_parse_dt(struct tc358762 *ctx) 208 { 209 struct drm_bridge *panel_bridge; 210 struct device *dev = ctx->dev; 211 212 panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); 213 if (IS_ERR(panel_bridge)) 214 return PTR_ERR(panel_bridge); 215 216 ctx->panel_bridge = panel_bridge; 217 218 /* Reset GPIO is optional */ 219 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 220 if (IS_ERR(ctx->reset_gpio)) 221 return PTR_ERR(ctx->reset_gpio); 222 223 return 0; 224 } 225 226 static int tc358762_configure_regulators(struct tc358762 *ctx) 227 { 228 ctx->regulator = devm_regulator_get(ctx->dev, "vddc"); 229 if (IS_ERR(ctx->regulator)) 230 return PTR_ERR(ctx->regulator); 231 232 return 0; 233 } 234 235 static int tc358762_probe(struct mipi_dsi_device *dsi) 236 { 237 struct device *dev = &dsi->dev; 238 struct tc358762 *ctx; 239 int ret; 240 241 ctx = devm_kzalloc(dev, sizeof(struct tc358762), GFP_KERNEL); 242 if (!ctx) 243 return -ENOMEM; 244 245 mipi_dsi_set_drvdata(dsi, ctx); 246 247 ctx->dev = dev; 248 ctx->pre_enabled = false; 249 250 /* TODO: Find out how to get dual-lane mode working */ 251 dsi->lanes = 1; 252 dsi->format = MIPI_DSI_FMT_RGB888; 253 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | 254 MIPI_DSI_MODE_LPM | MIPI_DSI_MODE_VIDEO_HSE; 255 256 ret = tc358762_parse_dt(ctx); 257 if (ret < 0) 258 return ret; 259 260 ret = tc358762_configure_regulators(ctx); 261 if (ret < 0) 262 return ret; 263 264 ctx->bridge.funcs = &tc358762_bridge_funcs; 265 ctx->bridge.type = DRM_MODE_CONNECTOR_DPI; 266 ctx->bridge.of_node = dev->of_node; 267 ctx->bridge.pre_enable_prev_first = true; 268 269 drm_bridge_add(&ctx->bridge); 270 271 ret = mipi_dsi_attach(dsi); 272 if (ret < 0) { 273 drm_bridge_remove(&ctx->bridge); 274 dev_err(dev, "failed to attach dsi\n"); 275 } 276 277 return ret; 278 } 279 280 static void tc358762_remove(struct mipi_dsi_device *dsi) 281 { 282 struct tc358762 *ctx = mipi_dsi_get_drvdata(dsi); 283 284 mipi_dsi_detach(dsi); 285 drm_bridge_remove(&ctx->bridge); 286 } 287 288 static const struct of_device_id tc358762_of_match[] = { 289 { .compatible = "toshiba,tc358762" }, 290 { } 291 }; 292 MODULE_DEVICE_TABLE(of, tc358762_of_match); 293 294 static struct mipi_dsi_driver tc358762_driver = { 295 .probe = tc358762_probe, 296 .remove = tc358762_remove, 297 .driver = { 298 .name = "tc358762", 299 .of_match_table = tc358762_of_match, 300 }, 301 }; 302 module_mipi_dsi_driver(tc358762_driver); 303 304 MODULE_AUTHOR("Marek Vasut <marex@denx.de>"); 305 MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358762 DSI/DPI Bridge"); 306 MODULE_LICENSE("GPL v2"); 307