488 lines · c
1// SPDX-License-Identifier: GPL-2.02/*3 * Panel driver for the TPO TPG110 400CH LTPS TFT LCD Single Chip4 * Digital Driver.5 *6 * This chip drives a TFT LCD, so it does not know what kind of7 * display is actually connected to it, so the width and height of that8 * display needs to be supplied from the machine configuration.9 *10 * Author:11 * Linus Walleij <linus.walleij@linaro.org>12 */13#include <drm/drm_modes.h>14#include <drm/drm_panel.h>15 16#include <linux/bitops.h>17#include <linux/delay.h>18#include <linux/gpio/consumer.h>19#include <linux/init.h>20#include <linux/kernel.h>21#include <linux/module.h>22#include <linux/of.h>23#include <linux/platform_device.h>24#include <linux/spi/spi.h>25 26#define TPG110_TEST 0x0027#define TPG110_CHIPID 0x0128#define TPG110_CTRL1 0x0229#define TPG110_RES_MASK GENMASK(2, 0)30#define TPG110_RES_800X480 0x0731#define TPG110_RES_640X480 0x0632#define TPG110_RES_480X272 0x0533#define TPG110_RES_480X640 0x0434#define TPG110_RES_480X272_D 0x01 /* Dual scan: outputs 800x480 */35#define TPG110_RES_400X240_D 0x00 /* Dual scan: outputs 800x480 */36#define TPG110_CTRL2 0x0337#define TPG110_CTRL2_PM BIT(0)38#define TPG110_CTRL2_RES_PM_CTRL BIT(7)39 40/**41 * struct tpg110_panel_mode - lookup struct for the supported modes42 */43struct tpg110_panel_mode {44 /**45 * @name: the name of this panel46 */47 const char *name;48 /**49 * @magic: the magic value from the detection register50 */51 u32 magic;52 /**53 * @mode: the DRM display mode for this panel54 */55 struct drm_display_mode mode;56 /**57 * @bus_flags: the DRM bus flags for this panel e.g. inverted clock58 */59 u32 bus_flags;60};61 62/**63 * struct tpg110 - state container for the TPG110 panel64 */65struct tpg110 {66 /**67 * @dev: the container device68 */69 struct device *dev;70 /**71 * @spi: the corresponding SPI device72 */73 struct spi_device *spi;74 /**75 * @panel: the DRM panel instance for this device76 */77 struct drm_panel panel;78 /**79 * @panel_mode: the panel mode as detected80 */81 const struct tpg110_panel_mode *panel_mode;82 /**83 * @width: the width of this panel in mm84 */85 u32 width;86 /**87 * @height: the height of this panel in mm88 */89 u32 height;90 /**91 * @grestb: reset GPIO line92 */93 struct gpio_desc *grestb;94};95 96/*97 * TPG110 modes, these are the simple modes, the dualscan modes that98 * take 400x240 or 480x272 in and display as 800x480 are not listed.99 */100static const struct tpg110_panel_mode tpg110_modes[] = {101 {102 .name = "800x480 RGB",103 .magic = TPG110_RES_800X480,104 .mode = {105 .clock = 33200,106 .hdisplay = 800,107 .hsync_start = 800 + 40,108 .hsync_end = 800 + 40 + 1,109 .htotal = 800 + 40 + 1 + 216,110 .vdisplay = 480,111 .vsync_start = 480 + 10,112 .vsync_end = 480 + 10 + 1,113 .vtotal = 480 + 10 + 1 + 35,114 },115 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,116 },117 {118 .name = "640x480 RGB",119 .magic = TPG110_RES_640X480,120 .mode = {121 .clock = 25200,122 .hdisplay = 640,123 .hsync_start = 640 + 24,124 .hsync_end = 640 + 24 + 1,125 .htotal = 640 + 24 + 1 + 136,126 .vdisplay = 480,127 .vsync_start = 480 + 18,128 .vsync_end = 480 + 18 + 1,129 .vtotal = 480 + 18 + 1 + 27,130 },131 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,132 },133 {134 .name = "480x272 RGB",135 .magic = TPG110_RES_480X272,136 .mode = {137 .clock = 9000,138 .hdisplay = 480,139 .hsync_start = 480 + 2,140 .hsync_end = 480 + 2 + 1,141 .htotal = 480 + 2 + 1 + 43,142 .vdisplay = 272,143 .vsync_start = 272 + 2,144 .vsync_end = 272 + 2 + 1,145 .vtotal = 272 + 2 + 1 + 12,146 },147 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,148 },149 {150 .name = "480x640 RGB",151 .magic = TPG110_RES_480X640,152 .mode = {153 .clock = 20500,154 .hdisplay = 480,155 .hsync_start = 480 + 2,156 .hsync_end = 480 + 2 + 1,157 .htotal = 480 + 2 + 1 + 43,158 .vdisplay = 640,159 .vsync_start = 640 + 4,160 .vsync_end = 640 + 4 + 1,161 .vtotal = 640 + 4 + 1 + 8,162 },163 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,164 },165 {166 .name = "400x240 RGB",167 .magic = TPG110_RES_400X240_D,168 .mode = {169 .clock = 8300,170 .hdisplay = 400,171 .hsync_start = 400 + 20,172 .hsync_end = 400 + 20 + 1,173 .htotal = 400 + 20 + 1 + 108,174 .vdisplay = 240,175 .vsync_start = 240 + 2,176 .vsync_end = 240 + 2 + 1,177 .vtotal = 240 + 2 + 1 + 20,178 },179 .bus_flags = DRM_BUS_FLAG_PIXDATA_DRIVE_POSEDGE,180 },181};182 183static inline struct tpg110 *184to_tpg110(struct drm_panel *panel)185{186 return container_of(panel, struct tpg110, panel);187}188 189static u8 tpg110_readwrite_reg(struct tpg110 *tpg, bool write,190 u8 address, u8 outval)191{192 struct spi_message m;193 struct spi_transfer t[2];194 u8 buf[2];195 int ret;196 197 spi_message_init(&m);198 memset(t, 0, sizeof(t));199 200 if (write) {201 /*202 * Clear address bit 0, 1 when writing, just to be sure203 * The actual bit indicating a write here is bit 1, bit204 * 0 is just surplus to pad it up to 8 bits.205 */206 buf[0] = address << 2;207 buf[0] &= ~0x03;208 buf[1] = outval;209 210 t[0].bits_per_word = 8;211 t[0].tx_buf = &buf[0];212 t[0].len = 1;213 214 t[1].tx_buf = &buf[1];215 t[1].len = 1;216 t[1].bits_per_word = 8;217 } else {218 /* Set address bit 0 to 1 to read */219 buf[0] = address << 1;220 buf[0] |= 0x01;221 222 /*223 * The last bit/clock is Hi-Z turnaround cycle, so we need224 * to send only 7 bits here. The 8th bit is the high impedance225 * turn-around cycle.226 */227 t[0].bits_per_word = 7;228 t[0].tx_buf = &buf[0];229 t[0].len = 1;230 231 t[1].rx_buf = &buf[1];232 t[1].len = 1;233 t[1].bits_per_word = 8;234 }235 236 spi_message_add_tail(&t[0], &m);237 spi_message_add_tail(&t[1], &m);238 ret = spi_sync(tpg->spi, &m);239 if (ret) {240 dev_err(tpg->dev, "SPI message error %d\n", ret);241 return ret;242 }243 if (write)244 return 0;245 /* Read */246 return buf[1];247}248 249static u8 tpg110_read_reg(struct tpg110 *tpg, u8 address)250{251 return tpg110_readwrite_reg(tpg, false, address, 0);252}253 254static void tpg110_write_reg(struct tpg110 *tpg, u8 address, u8 outval)255{256 tpg110_readwrite_reg(tpg, true, address, outval);257}258 259static int tpg110_startup(struct tpg110 *tpg)260{261 u8 val;262 int i;263 264 /* De-assert the reset signal */265 gpiod_set_value_cansleep(tpg->grestb, 0);266 usleep_range(1000, 2000);267 dev_dbg(tpg->dev, "de-asserted GRESTB\n");268 269 /* Test display communication */270 tpg110_write_reg(tpg, TPG110_TEST, 0x55);271 val = tpg110_read_reg(tpg, TPG110_TEST);272 if (val != 0x55) {273 dev_err(tpg->dev, "failed communication test\n");274 return -ENODEV;275 }276 277 val = tpg110_read_reg(tpg, TPG110_CHIPID);278 dev_info(tpg->dev, "TPG110 chip ID: %d version: %d\n",279 val >> 4, val & 0x0f);280 281 /* Show display resolution */282 val = tpg110_read_reg(tpg, TPG110_CTRL1);283 val &= TPG110_RES_MASK;284 switch (val) {285 case TPG110_RES_400X240_D:286 dev_info(tpg->dev, "IN 400x240 RGB -> OUT 800x480 RGB (dual scan)\n");287 break;288 case TPG110_RES_480X272_D:289 dev_info(tpg->dev, "IN 480x272 RGB -> OUT 800x480 RGB (dual scan)\n");290 break;291 case TPG110_RES_480X640:292 dev_info(tpg->dev, "480x640 RGB\n");293 break;294 case TPG110_RES_480X272:295 dev_info(tpg->dev, "480x272 RGB\n");296 break;297 case TPG110_RES_640X480:298 dev_info(tpg->dev, "640x480 RGB\n");299 break;300 case TPG110_RES_800X480:301 dev_info(tpg->dev, "800x480 RGB\n");302 break;303 default:304 dev_err(tpg->dev, "ILLEGAL RESOLUTION 0x%02x\n", val);305 break;306 }307 308 /* From the producer side, this is the same resolution */309 if (val == TPG110_RES_480X272_D)310 val = TPG110_RES_480X272;311 312 for (i = 0; i < ARRAY_SIZE(tpg110_modes); i++) {313 const struct tpg110_panel_mode *pm;314 315 pm = &tpg110_modes[i];316 if (pm->magic == val) {317 tpg->panel_mode = pm;318 break;319 }320 }321 if (i == ARRAY_SIZE(tpg110_modes)) {322 dev_err(tpg->dev, "unsupported mode (%02x) detected\n", val);323 return -ENODEV;324 }325 326 val = tpg110_read_reg(tpg, TPG110_CTRL2);327 dev_info(tpg->dev, "resolution and standby is controlled by %s\n",328 (val & TPG110_CTRL2_RES_PM_CTRL) ? "software" : "hardware");329 /* Take control over resolution and standby */330 val |= TPG110_CTRL2_RES_PM_CTRL;331 tpg110_write_reg(tpg, TPG110_CTRL2, val);332 333 return 0;334}335 336static int tpg110_disable(struct drm_panel *panel)337{338 struct tpg110 *tpg = to_tpg110(panel);339 u8 val;340 341 /* Put chip into standby */342 val = tpg110_read_reg(tpg, TPG110_CTRL2_PM);343 val &= ~TPG110_CTRL2_PM;344 tpg110_write_reg(tpg, TPG110_CTRL2_PM, val);345 346 return 0;347}348 349static int tpg110_enable(struct drm_panel *panel)350{351 struct tpg110 *tpg = to_tpg110(panel);352 u8 val;353 354 /* Take chip out of standby */355 val = tpg110_read_reg(tpg, TPG110_CTRL2_PM);356 val |= TPG110_CTRL2_PM;357 tpg110_write_reg(tpg, TPG110_CTRL2_PM, val);358 359 return 0;360}361 362/**363 * tpg110_get_modes() - return the appropriate mode364 * @panel: the panel to get the mode for365 * @connector: reference to the central DRM connector control structure366 *367 * This currently does not present a forest of modes, instead it368 * presents the mode that is configured for the system under use,369 * and which is detected by reading the registers of the display.370 */371static int tpg110_get_modes(struct drm_panel *panel,372 struct drm_connector *connector)373{374 struct tpg110 *tpg = to_tpg110(panel);375 struct drm_display_mode *mode;376 377 connector->display_info.width_mm = tpg->width;378 connector->display_info.height_mm = tpg->height;379 connector->display_info.bus_flags = tpg->panel_mode->bus_flags;380 381 mode = drm_mode_duplicate(connector->dev, &tpg->panel_mode->mode);382 if (!mode)383 return -ENOMEM;384 drm_mode_set_name(mode);385 mode->type = DRM_MODE_TYPE_DRIVER | DRM_MODE_TYPE_PREFERRED;386 387 mode->width_mm = tpg->width;388 mode->height_mm = tpg->height;389 390 drm_mode_probed_add(connector, mode);391 392 return 1;393}394 395static const struct drm_panel_funcs tpg110_drm_funcs = {396 .disable = tpg110_disable,397 .enable = tpg110_enable,398 .get_modes = tpg110_get_modes,399};400 401static int tpg110_probe(struct spi_device *spi)402{403 struct device *dev = &spi->dev;404 struct device_node *np = dev->of_node;405 struct tpg110 *tpg;406 int ret;407 408 tpg = devm_kzalloc(dev, sizeof(*tpg), GFP_KERNEL);409 if (!tpg)410 return -ENOMEM;411 tpg->dev = dev;412 413 /* We get the physical display dimensions from the DT */414 ret = of_property_read_u32(np, "width-mm", &tpg->width);415 if (ret)416 dev_err(dev, "no panel width specified\n");417 ret = of_property_read_u32(np, "height-mm", &tpg->height);418 if (ret)419 dev_err(dev, "no panel height specified\n");420 421 /* This asserts the GRESTB signal, putting the display into reset */422 tpg->grestb = devm_gpiod_get(dev, "grestb", GPIOD_OUT_HIGH);423 if (IS_ERR(tpg->grestb)) {424 dev_err(dev, "no GRESTB GPIO\n");425 return -ENODEV;426 }427 428 spi->bits_per_word = 8;429 spi->mode |= SPI_3WIRE_HIZ;430 ret = spi_setup(spi);431 if (ret < 0) {432 dev_err(dev, "spi setup failed.\n");433 return ret;434 }435 tpg->spi = spi;436 437 ret = tpg110_startup(tpg);438 if (ret)439 return ret;440 441 drm_panel_init(&tpg->panel, dev, &tpg110_drm_funcs,442 DRM_MODE_CONNECTOR_DPI);443 444 ret = drm_panel_of_backlight(&tpg->panel);445 if (ret)446 return ret;447 448 spi_set_drvdata(spi, tpg);449 450 drm_panel_add(&tpg->panel);451 452 return 0;453}454 455static void tpg110_remove(struct spi_device *spi)456{457 struct tpg110 *tpg = spi_get_drvdata(spi);458 459 drm_panel_remove(&tpg->panel);460}461 462static const struct of_device_id tpg110_match[] = {463 { .compatible = "tpo,tpg110", },464 {},465};466MODULE_DEVICE_TABLE(of, tpg110_match);467 468static const struct spi_device_id tpg110_ids[] = {469 { "tpg110" },470 { },471};472MODULE_DEVICE_TABLE(spi, tpg110_ids);473 474static struct spi_driver tpg110_driver = {475 .probe = tpg110_probe,476 .remove = tpg110_remove,477 .id_table = tpg110_ids,478 .driver = {479 .name = "tpo-tpg110-panel",480 .of_match_table = tpg110_match,481 },482};483module_spi_driver(tpg110_driver);484 485MODULE_AUTHOR("Linus Walleij <linus.walleij@linaro.org>");486MODULE_DESCRIPTION("TPO TPG110 panel driver");487MODULE_LICENSE("GPL v2");488