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 */ 45 #define LCDCTRL 0x0420 46 47 /* SPI Master Registers */ 48 #define SPICMR 0x0450 49 #define SPITCR 0x0454 50 51 /* System Controller Registers */ 52 #define SYSCTRL 0x0464 53 54 /* System registers */ 55 #define LPX_PERIOD 3 56 57 /* Lane enable PPI and DSI register bits */ 58 #define LANEENABLE_CLEN BIT(0) 59 #define LANEENABLE_L0EN BIT(1) 60 #define LANEENABLE_L1EN BIT(2) 61 62 struct tc358762 { 63 struct device *dev; 64 struct drm_bridge bridge; 65 struct regulator *regulator; 66 struct drm_bridge *panel_bridge; 67 struct gpio_desc *reset_gpio; 68 bool pre_enabled; 69 int error; 70 }; 71 72 static int tc358762_clear_error(struct tc358762 *ctx) 73 { 74 int ret = ctx->error; 75 76 ctx->error = 0; 77 return ret; 78 } 79 80 static void tc358762_write(struct tc358762 *ctx, u16 addr, u32 val) 81 { 82 struct mipi_dsi_device *dsi = to_mipi_dsi_device(ctx->dev); 83 ssize_t ret; 84 u8 data[6]; 85 86 if (ctx->error) 87 return; 88 89 data[0] = addr; 90 data[1] = addr >> 8; 91 data[2] = val; 92 data[3] = val >> 8; 93 data[4] = val >> 16; 94 data[5] = val >> 24; 95 96 ret = mipi_dsi_generic_write(dsi, data, sizeof(data)); 97 if (ret < 0) 98 ctx->error = ret; 99 } 100 101 static inline struct tc358762 *bridge_to_tc358762(struct drm_bridge *bridge) 102 { 103 return container_of(bridge, struct tc358762, bridge); 104 } 105 106 static int tc358762_init(struct tc358762 *ctx) 107 { 108 tc358762_write(ctx, DSI_LANEENABLE, 109 LANEENABLE_L0EN | LANEENABLE_CLEN); 110 tc358762_write(ctx, PPI_D0S_CLRSIPOCOUNT, 5); 111 tc358762_write(ctx, PPI_D1S_CLRSIPOCOUNT, 5); 112 tc358762_write(ctx, PPI_D0S_ATMR, 0); 113 tc358762_write(ctx, PPI_D1S_ATMR, 0); 114 tc358762_write(ctx, PPI_LPTXTIMECNT, LPX_PERIOD); 115 116 tc358762_write(ctx, SPICMR, 0x00); 117 tc358762_write(ctx, LCDCTRL, 0x00100150); 118 tc358762_write(ctx, SYSCTRL, 0x040f); 119 msleep(100); 120 121 tc358762_write(ctx, PPI_STARTPPI, PPI_START_FUNCTION); 122 tc358762_write(ctx, DSI_STARTDSI, DSI_RX_START); 123 124 msleep(100); 125 126 return tc358762_clear_error(ctx); 127 } 128 129 static void tc358762_post_disable(struct drm_bridge *bridge) 130 { 131 struct tc358762 *ctx = bridge_to_tc358762(bridge); 132 int ret; 133 134 /* 135 * The post_disable hook might be called multiple times. 136 * We want to avoid regulator imbalance below. 137 */ 138 if (!ctx->pre_enabled) 139 return; 140 141 ctx->pre_enabled = false; 142 143 if (ctx->reset_gpio) 144 gpiod_set_value_cansleep(ctx->reset_gpio, 0); 145 146 ret = regulator_disable(ctx->regulator); 147 if (ret < 0) 148 dev_err(ctx->dev, "error disabling regulators (%d)\n", ret); 149 } 150 151 static void tc358762_pre_enable(struct drm_bridge *bridge) 152 { 153 struct tc358762 *ctx = bridge_to_tc358762(bridge); 154 int ret; 155 156 ret = regulator_enable(ctx->regulator); 157 if (ret < 0) 158 dev_err(ctx->dev, "error enabling regulators (%d)\n", ret); 159 160 if (ctx->reset_gpio) { 161 gpiod_set_value_cansleep(ctx->reset_gpio, 1); 162 usleep_range(5000, 10000); 163 } 164 165 ret = tc358762_init(ctx); 166 if (ret < 0) 167 dev_err(ctx->dev, "error initializing bridge (%d)\n", ret); 168 169 ctx->pre_enabled = true; 170 } 171 172 static int tc358762_attach(struct drm_bridge *bridge, 173 enum drm_bridge_attach_flags flags) 174 { 175 struct tc358762 *ctx = bridge_to_tc358762(bridge); 176 177 return drm_bridge_attach(bridge->encoder, ctx->panel_bridge, 178 bridge, flags); 179 } 180 181 static const struct drm_bridge_funcs tc358762_bridge_funcs = { 182 .post_disable = tc358762_post_disable, 183 .pre_enable = tc358762_pre_enable, 184 .attach = tc358762_attach, 185 }; 186 187 static int tc358762_parse_dt(struct tc358762 *ctx) 188 { 189 struct drm_bridge *panel_bridge; 190 struct device *dev = ctx->dev; 191 192 panel_bridge = devm_drm_of_get_bridge(dev, dev->of_node, 1, 0); 193 if (IS_ERR(panel_bridge)) 194 return PTR_ERR(panel_bridge); 195 196 ctx->panel_bridge = panel_bridge; 197 198 /* Reset GPIO is optional */ 199 ctx->reset_gpio = devm_gpiod_get_optional(dev, "reset", GPIOD_OUT_LOW); 200 if (IS_ERR(ctx->reset_gpio)) 201 return PTR_ERR(ctx->reset_gpio); 202 203 return 0; 204 } 205 206 static int tc358762_configure_regulators(struct tc358762 *ctx) 207 { 208 ctx->regulator = devm_regulator_get(ctx->dev, "vddc"); 209 if (IS_ERR(ctx->regulator)) 210 return PTR_ERR(ctx->regulator); 211 212 return 0; 213 } 214 215 static int tc358762_probe(struct mipi_dsi_device *dsi) 216 { 217 struct device *dev = &dsi->dev; 218 struct tc358762 *ctx; 219 int ret; 220 221 ctx = devm_kzalloc(dev, sizeof(struct tc358762), GFP_KERNEL); 222 if (!ctx) 223 return -ENOMEM; 224 225 mipi_dsi_set_drvdata(dsi, ctx); 226 227 ctx->dev = dev; 228 ctx->pre_enabled = false; 229 230 /* TODO: Find out how to get dual-lane mode working */ 231 dsi->lanes = 1; 232 dsi->format = MIPI_DSI_FMT_RGB888; 233 dsi->mode_flags = MIPI_DSI_MODE_VIDEO | MIPI_DSI_MODE_VIDEO_SYNC_PULSE | 234 MIPI_DSI_MODE_LPM; 235 236 ret = tc358762_parse_dt(ctx); 237 if (ret < 0) 238 return ret; 239 240 ret = tc358762_configure_regulators(ctx); 241 if (ret < 0) 242 return ret; 243 244 ctx->bridge.funcs = &tc358762_bridge_funcs; 245 ctx->bridge.type = DRM_MODE_CONNECTOR_DPI; 246 ctx->bridge.of_node = dev->of_node; 247 ctx->bridge.pre_enable_prev_first = true; 248 249 drm_bridge_add(&ctx->bridge); 250 251 ret = mipi_dsi_attach(dsi); 252 if (ret < 0) { 253 drm_bridge_remove(&ctx->bridge); 254 dev_err(dev, "failed to attach dsi\n"); 255 } 256 257 return ret; 258 } 259 260 static void tc358762_remove(struct mipi_dsi_device *dsi) 261 { 262 struct tc358762 *ctx = mipi_dsi_get_drvdata(dsi); 263 264 mipi_dsi_detach(dsi); 265 drm_bridge_remove(&ctx->bridge); 266 } 267 268 static const struct of_device_id tc358762_of_match[] = { 269 { .compatible = "toshiba,tc358762" }, 270 { } 271 }; 272 MODULE_DEVICE_TABLE(of, tc358762_of_match); 273 274 static struct mipi_dsi_driver tc358762_driver = { 275 .probe = tc358762_probe, 276 .remove = tc358762_remove, 277 .driver = { 278 .name = "tc358762", 279 .of_match_table = tc358762_of_match, 280 }, 281 }; 282 module_mipi_dsi_driver(tc358762_driver); 283 284 MODULE_AUTHOR("Marek Vasut <marex@denx.de>"); 285 MODULE_DESCRIPTION("MIPI-DSI based Driver for TC358762 DSI/DPI Bridge"); 286 MODULE_LICENSE("GPL v2"); 287