cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

panel-dsi-cm.c (27586B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Generic DSI Command Mode panel driver
      4 *
      5 * Copyright (C) 2013 Texas Instruments
      6 * Author: Tomi Valkeinen <tomi.valkeinen@ti.com>
      7 */
      8
      9/* #define DEBUG */
     10
     11#include <linux/backlight.h>
     12#include <linux/delay.h>
     13#include <linux/fb.h>
     14#include <linux/gpio.h>
     15#include <linux/interrupt.h>
     16#include <linux/jiffies.h>
     17#include <linux/module.h>
     18#include <linux/platform_device.h>
     19#include <linux/sched/signal.h>
     20#include <linux/slab.h>
     21#include <linux/workqueue.h>
     22#include <linux/of_device.h>
     23#include <linux/of_gpio.h>
     24
     25#include <video/omapfb_dss.h>
     26#include <video/mipi_display.h>
     27
     28/* DSI Virtual channel. Hardcoded for now. */
     29#define TCH 0
     30
     31#define DCS_READ_NUM_ERRORS	0x05
     32#define DCS_BRIGHTNESS		0x51
     33#define DCS_CTRL_DISPLAY	0x53
     34#define DCS_GET_ID1		0xda
     35#define DCS_GET_ID2		0xdb
     36#define DCS_GET_ID3		0xdc
     37
     38struct panel_drv_data {
     39	struct omap_dss_device dssdev;
     40	struct omap_dss_device *in;
     41
     42	struct omap_video_timings timings;
     43
     44	struct platform_device *pdev;
     45
     46	struct mutex lock;
     47
     48	struct backlight_device *bldev;
     49
     50	unsigned long	hw_guard_end;	/* next value of jiffies when we can
     51					 * issue the next sleep in/out command
     52					 */
     53	unsigned long	hw_guard_wait;	/* max guard time in jiffies */
     54
     55	/* panel HW configuration from DT or platform data */
     56	int reset_gpio;
     57	int ext_te_gpio;
     58
     59	bool use_dsi_backlight;
     60
     61	struct omap_dsi_pin_config pin_config;
     62
     63	/* runtime variables */
     64	bool enabled;
     65
     66	bool te_enabled;
     67
     68	atomic_t do_update;
     69	int channel;
     70
     71	struct delayed_work te_timeout_work;
     72
     73	bool intro_printed;
     74
     75	bool ulps_enabled;
     76	unsigned ulps_timeout;
     77	struct delayed_work ulps_work;
     78};
     79
     80#define to_panel_data(p) container_of(p, struct panel_drv_data, dssdev)
     81
     82static irqreturn_t dsicm_te_isr(int irq, void *data);
     83static void dsicm_te_timeout_work_callback(struct work_struct *work);
     84static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable);
     85
     86static int dsicm_panel_reset(struct panel_drv_data *ddata);
     87
     88static void dsicm_ulps_work(struct work_struct *work);
     89
     90static void hw_guard_start(struct panel_drv_data *ddata, int guard_msec)
     91{
     92	ddata->hw_guard_wait = msecs_to_jiffies(guard_msec);
     93	ddata->hw_guard_end = jiffies + ddata->hw_guard_wait;
     94}
     95
     96static void hw_guard_wait(struct panel_drv_data *ddata)
     97{
     98	unsigned long wait = ddata->hw_guard_end - jiffies;
     99
    100	if ((long)wait > 0 && time_before_eq(wait, ddata->hw_guard_wait)) {
    101		set_current_state(TASK_UNINTERRUPTIBLE);
    102		schedule_timeout(wait);
    103	}
    104}
    105
    106static int dsicm_dcs_read_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 *data)
    107{
    108	struct omap_dss_device *in = ddata->in;
    109	int r;
    110	u8 buf[1];
    111
    112	r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd, buf, 1);
    113
    114	if (r < 0)
    115		return r;
    116
    117	*data = buf[0];
    118
    119	return 0;
    120}
    121
    122static int dsicm_dcs_write_0(struct panel_drv_data *ddata, u8 dcs_cmd)
    123{
    124	struct omap_dss_device *in = ddata->in;
    125	return in->ops.dsi->dcs_write(in, ddata->channel, &dcs_cmd, 1);
    126}
    127
    128static int dsicm_dcs_write_1(struct panel_drv_data *ddata, u8 dcs_cmd, u8 param)
    129{
    130	struct omap_dss_device *in = ddata->in;
    131	u8 buf[2] = { dcs_cmd, param };
    132
    133	return in->ops.dsi->dcs_write(in, ddata->channel, buf, 2);
    134}
    135
    136static int dsicm_sleep_in(struct panel_drv_data *ddata)
    137
    138{
    139	struct omap_dss_device *in = ddata->in;
    140	u8 cmd;
    141	int r;
    142
    143	hw_guard_wait(ddata);
    144
    145	cmd = MIPI_DCS_ENTER_SLEEP_MODE;
    146	r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, &cmd, 1);
    147	if (r)
    148		return r;
    149
    150	hw_guard_start(ddata, 120);
    151
    152	usleep_range(5000, 10000);
    153
    154	return 0;
    155}
    156
    157static int dsicm_sleep_out(struct panel_drv_data *ddata)
    158{
    159	int r;
    160
    161	hw_guard_wait(ddata);
    162
    163	r = dsicm_dcs_write_0(ddata, MIPI_DCS_EXIT_SLEEP_MODE);
    164	if (r)
    165		return r;
    166
    167	hw_guard_start(ddata, 120);
    168
    169	usleep_range(5000, 10000);
    170
    171	return 0;
    172}
    173
    174static int dsicm_get_id(struct panel_drv_data *ddata, u8 *id1, u8 *id2, u8 *id3)
    175{
    176	int r;
    177
    178	r = dsicm_dcs_read_1(ddata, DCS_GET_ID1, id1);
    179	if (r)
    180		return r;
    181	r = dsicm_dcs_read_1(ddata, DCS_GET_ID2, id2);
    182	if (r)
    183		return r;
    184	r = dsicm_dcs_read_1(ddata, DCS_GET_ID3, id3);
    185	if (r)
    186		return r;
    187
    188	return 0;
    189}
    190
    191static int dsicm_set_update_window(struct panel_drv_data *ddata,
    192		u16 x, u16 y, u16 w, u16 h)
    193{
    194	struct omap_dss_device *in = ddata->in;
    195	int r;
    196	u16 x1 = x;
    197	u16 x2 = x + w - 1;
    198	u16 y1 = y;
    199	u16 y2 = y + h - 1;
    200
    201	u8 buf[5];
    202	buf[0] = MIPI_DCS_SET_COLUMN_ADDRESS;
    203	buf[1] = (x1 >> 8) & 0xff;
    204	buf[2] = (x1 >> 0) & 0xff;
    205	buf[3] = (x2 >> 8) & 0xff;
    206	buf[4] = (x2 >> 0) & 0xff;
    207
    208	r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
    209	if (r)
    210		return r;
    211
    212	buf[0] = MIPI_DCS_SET_PAGE_ADDRESS;
    213	buf[1] = (y1 >> 8) & 0xff;
    214	buf[2] = (y1 >> 0) & 0xff;
    215	buf[3] = (y2 >> 8) & 0xff;
    216	buf[4] = (y2 >> 0) & 0xff;
    217
    218	r = in->ops.dsi->dcs_write_nosync(in, ddata->channel, buf, sizeof(buf));
    219	if (r)
    220		return r;
    221
    222	in->ops.dsi->bta_sync(in, ddata->channel);
    223
    224	return r;
    225}
    226
    227static void dsicm_queue_ulps_work(struct panel_drv_data *ddata)
    228{
    229	if (ddata->ulps_timeout > 0)
    230		schedule_delayed_work(&ddata->ulps_work,
    231				msecs_to_jiffies(ddata->ulps_timeout));
    232}
    233
    234static void dsicm_cancel_ulps_work(struct panel_drv_data *ddata)
    235{
    236	cancel_delayed_work(&ddata->ulps_work);
    237}
    238
    239static int dsicm_enter_ulps(struct panel_drv_data *ddata)
    240{
    241	struct omap_dss_device *in = ddata->in;
    242	int r;
    243
    244	if (ddata->ulps_enabled)
    245		return 0;
    246
    247	dsicm_cancel_ulps_work(ddata);
    248
    249	r = _dsicm_enable_te(ddata, false);
    250	if (r)
    251		goto err;
    252
    253	if (gpio_is_valid(ddata->ext_te_gpio))
    254		disable_irq(gpio_to_irq(ddata->ext_te_gpio));
    255
    256	in->ops.dsi->disable(in, false, true);
    257
    258	ddata->ulps_enabled = true;
    259
    260	return 0;
    261
    262err:
    263	dev_err(&ddata->pdev->dev, "enter ULPS failed");
    264	dsicm_panel_reset(ddata);
    265
    266	ddata->ulps_enabled = false;
    267
    268	dsicm_queue_ulps_work(ddata);
    269
    270	return r;
    271}
    272
    273static int dsicm_exit_ulps(struct panel_drv_data *ddata)
    274{
    275	struct omap_dss_device *in = ddata->in;
    276	int r;
    277
    278	if (!ddata->ulps_enabled)
    279		return 0;
    280
    281	r = in->ops.dsi->enable(in);
    282	if (r) {
    283		dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
    284		goto err1;
    285	}
    286
    287	in->ops.dsi->enable_hs(in, ddata->channel, true);
    288
    289	r = _dsicm_enable_te(ddata, true);
    290	if (r) {
    291		dev_err(&ddata->pdev->dev, "failed to re-enable TE");
    292		goto err2;
    293	}
    294
    295	if (gpio_is_valid(ddata->ext_te_gpio))
    296		enable_irq(gpio_to_irq(ddata->ext_te_gpio));
    297
    298	dsicm_queue_ulps_work(ddata);
    299
    300	ddata->ulps_enabled = false;
    301
    302	return 0;
    303
    304err2:
    305	dev_err(&ddata->pdev->dev, "failed to exit ULPS");
    306
    307	r = dsicm_panel_reset(ddata);
    308	if (!r) {
    309		if (gpio_is_valid(ddata->ext_te_gpio))
    310			enable_irq(gpio_to_irq(ddata->ext_te_gpio));
    311		ddata->ulps_enabled = false;
    312	}
    313err1:
    314	dsicm_queue_ulps_work(ddata);
    315
    316	return r;
    317}
    318
    319static int dsicm_wake_up(struct panel_drv_data *ddata)
    320{
    321	if (ddata->ulps_enabled)
    322		return dsicm_exit_ulps(ddata);
    323
    324	dsicm_cancel_ulps_work(ddata);
    325	dsicm_queue_ulps_work(ddata);
    326	return 0;
    327}
    328
    329static int dsicm_bl_update_status(struct backlight_device *dev)
    330{
    331	struct panel_drv_data *ddata = dev_get_drvdata(&dev->dev);
    332	struct omap_dss_device *in = ddata->in;
    333	int r;
    334	int level;
    335
    336	if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
    337			dev->props.power == FB_BLANK_UNBLANK)
    338		level = dev->props.brightness;
    339	else
    340		level = 0;
    341
    342	dev_dbg(&ddata->pdev->dev, "update brightness to %d\n", level);
    343
    344	mutex_lock(&ddata->lock);
    345
    346	if (ddata->enabled) {
    347		in->ops.dsi->bus_lock(in);
    348
    349		r = dsicm_wake_up(ddata);
    350		if (!r)
    351			r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, level);
    352
    353		in->ops.dsi->bus_unlock(in);
    354	} else {
    355		r = 0;
    356	}
    357
    358	mutex_unlock(&ddata->lock);
    359
    360	return r;
    361}
    362
    363static int dsicm_bl_get_intensity(struct backlight_device *dev)
    364{
    365	if (dev->props.fb_blank == FB_BLANK_UNBLANK &&
    366			dev->props.power == FB_BLANK_UNBLANK)
    367		return dev->props.brightness;
    368
    369	return 0;
    370}
    371
    372static const struct backlight_ops dsicm_bl_ops = {
    373	.get_brightness = dsicm_bl_get_intensity,
    374	.update_status  = dsicm_bl_update_status,
    375};
    376
    377static void dsicm_get_resolution(struct omap_dss_device *dssdev,
    378		u16 *xres, u16 *yres)
    379{
    380	*xres = dssdev->panel.timings.x_res;
    381	*yres = dssdev->panel.timings.y_res;
    382}
    383
    384static ssize_t dsicm_num_errors_show(struct device *dev,
    385		struct device_attribute *attr, char *buf)
    386{
    387	struct panel_drv_data *ddata = dev_get_drvdata(dev);
    388	struct omap_dss_device *in = ddata->in;
    389	u8 errors = 0;
    390	int r;
    391
    392	mutex_lock(&ddata->lock);
    393
    394	if (ddata->enabled) {
    395		in->ops.dsi->bus_lock(in);
    396
    397		r = dsicm_wake_up(ddata);
    398		if (!r)
    399			r = dsicm_dcs_read_1(ddata, DCS_READ_NUM_ERRORS,
    400					&errors);
    401
    402		in->ops.dsi->bus_unlock(in);
    403	} else {
    404		r = -ENODEV;
    405	}
    406
    407	mutex_unlock(&ddata->lock);
    408
    409	if (r)
    410		return r;
    411
    412	return sysfs_emit(buf, "%d\n", errors);
    413}
    414
    415static ssize_t dsicm_hw_revision_show(struct device *dev,
    416		struct device_attribute *attr, char *buf)
    417{
    418	struct panel_drv_data *ddata = dev_get_drvdata(dev);
    419	struct omap_dss_device *in = ddata->in;
    420	u8 id1, id2, id3;
    421	int r;
    422
    423	mutex_lock(&ddata->lock);
    424
    425	if (ddata->enabled) {
    426		in->ops.dsi->bus_lock(in);
    427
    428		r = dsicm_wake_up(ddata);
    429		if (!r)
    430			r = dsicm_get_id(ddata, &id1, &id2, &id3);
    431
    432		in->ops.dsi->bus_unlock(in);
    433	} else {
    434		r = -ENODEV;
    435	}
    436
    437	mutex_unlock(&ddata->lock);
    438
    439	if (r)
    440		return r;
    441
    442	return sysfs_emit(buf, "%02x.%02x.%02x\n", id1, id2, id3);
    443}
    444
    445static ssize_t dsicm_store_ulps(struct device *dev,
    446		struct device_attribute *attr,
    447		const char *buf, size_t count)
    448{
    449	struct panel_drv_data *ddata = dev_get_drvdata(dev);
    450	struct omap_dss_device *in = ddata->in;
    451	unsigned long t;
    452	int r;
    453
    454	r = kstrtoul(buf, 0, &t);
    455	if (r)
    456		return r;
    457
    458	mutex_lock(&ddata->lock);
    459
    460	if (ddata->enabled) {
    461		in->ops.dsi->bus_lock(in);
    462
    463		if (t)
    464			r = dsicm_enter_ulps(ddata);
    465		else
    466			r = dsicm_wake_up(ddata);
    467
    468		in->ops.dsi->bus_unlock(in);
    469	}
    470
    471	mutex_unlock(&ddata->lock);
    472
    473	if (r)
    474		return r;
    475
    476	return count;
    477}
    478
    479static ssize_t dsicm_show_ulps(struct device *dev,
    480		struct device_attribute *attr,
    481		char *buf)
    482{
    483	struct panel_drv_data *ddata = dev_get_drvdata(dev);
    484	unsigned t;
    485
    486	mutex_lock(&ddata->lock);
    487	t = ddata->ulps_enabled;
    488	mutex_unlock(&ddata->lock);
    489
    490	return sysfs_emit(buf, "%u\n", t);
    491}
    492
    493static ssize_t dsicm_store_ulps_timeout(struct device *dev,
    494		struct device_attribute *attr,
    495		const char *buf, size_t count)
    496{
    497	struct panel_drv_data *ddata = dev_get_drvdata(dev);
    498	struct omap_dss_device *in = ddata->in;
    499	unsigned long t;
    500	int r;
    501
    502	r = kstrtoul(buf, 0, &t);
    503	if (r)
    504		return r;
    505
    506	mutex_lock(&ddata->lock);
    507	ddata->ulps_timeout = t;
    508
    509	if (ddata->enabled) {
    510		/* dsicm_wake_up will restart the timer */
    511		in->ops.dsi->bus_lock(in);
    512		r = dsicm_wake_up(ddata);
    513		in->ops.dsi->bus_unlock(in);
    514	}
    515
    516	mutex_unlock(&ddata->lock);
    517
    518	if (r)
    519		return r;
    520
    521	return count;
    522}
    523
    524static ssize_t dsicm_show_ulps_timeout(struct device *dev,
    525		struct device_attribute *attr,
    526		char *buf)
    527{
    528	struct panel_drv_data *ddata = dev_get_drvdata(dev);
    529	unsigned t;
    530
    531	mutex_lock(&ddata->lock);
    532	t = ddata->ulps_timeout;
    533	mutex_unlock(&ddata->lock);
    534
    535	return sysfs_emit(buf, "%u\n", t);
    536}
    537
    538static DEVICE_ATTR(num_dsi_errors, S_IRUGO, dsicm_num_errors_show, NULL);
    539static DEVICE_ATTR(hw_revision, S_IRUGO, dsicm_hw_revision_show, NULL);
    540static DEVICE_ATTR(ulps, S_IRUGO | S_IWUSR,
    541		dsicm_show_ulps, dsicm_store_ulps);
    542static DEVICE_ATTR(ulps_timeout, S_IRUGO | S_IWUSR,
    543		dsicm_show_ulps_timeout, dsicm_store_ulps_timeout);
    544
    545static struct attribute *dsicm_attrs[] = {
    546	&dev_attr_num_dsi_errors.attr,
    547	&dev_attr_hw_revision.attr,
    548	&dev_attr_ulps.attr,
    549	&dev_attr_ulps_timeout.attr,
    550	NULL,
    551};
    552
    553static const struct attribute_group dsicm_attr_group = {
    554	.attrs = dsicm_attrs,
    555};
    556
    557static void dsicm_hw_reset(struct panel_drv_data *ddata)
    558{
    559	if (!gpio_is_valid(ddata->reset_gpio))
    560		return;
    561
    562	gpio_set_value(ddata->reset_gpio, 1);
    563	udelay(10);
    564	/* reset the panel */
    565	gpio_set_value(ddata->reset_gpio, 0);
    566	/* assert reset */
    567	udelay(10);
    568	gpio_set_value(ddata->reset_gpio, 1);
    569	/* wait after releasing reset */
    570	usleep_range(5000, 10000);
    571}
    572
    573static int dsicm_power_on(struct panel_drv_data *ddata)
    574{
    575	struct omap_dss_device *in = ddata->in;
    576	u8 id1, id2, id3;
    577	int r;
    578	struct omap_dss_dsi_config dsi_config = {
    579		.mode = OMAP_DSS_DSI_CMD_MODE,
    580		.pixel_format = OMAP_DSS_DSI_FMT_RGB888,
    581		.timings = &ddata->timings,
    582		.hs_clk_min = 150000000,
    583		.hs_clk_max = 300000000,
    584		.lp_clk_min = 7000000,
    585		.lp_clk_max = 10000000,
    586	};
    587
    588	if (ddata->pin_config.num_pins > 0) {
    589		r = in->ops.dsi->configure_pins(in, &ddata->pin_config);
    590		if (r) {
    591			dev_err(&ddata->pdev->dev,
    592				"failed to configure DSI pins\n");
    593			goto err0;
    594		}
    595	}
    596
    597	r = in->ops.dsi->set_config(in, &dsi_config);
    598	if (r) {
    599		dev_err(&ddata->pdev->dev, "failed to configure DSI\n");
    600		goto err0;
    601	}
    602
    603	r = in->ops.dsi->enable(in);
    604	if (r) {
    605		dev_err(&ddata->pdev->dev, "failed to enable DSI\n");
    606		goto err0;
    607	}
    608
    609	dsicm_hw_reset(ddata);
    610
    611	in->ops.dsi->enable_hs(in, ddata->channel, false);
    612
    613	r = dsicm_sleep_out(ddata);
    614	if (r)
    615		goto err;
    616
    617	r = dsicm_get_id(ddata, &id1, &id2, &id3);
    618	if (r)
    619		goto err;
    620
    621	r = dsicm_dcs_write_1(ddata, DCS_BRIGHTNESS, 0xff);
    622	if (r)
    623		goto err;
    624
    625	r = dsicm_dcs_write_1(ddata, DCS_CTRL_DISPLAY,
    626			(1<<2) | (1<<5));	/* BL | BCTRL */
    627	if (r)
    628		goto err;
    629
    630	r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_PIXEL_FORMAT,
    631		MIPI_DCS_PIXEL_FMT_24BIT);
    632	if (r)
    633		goto err;
    634
    635	r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_ON);
    636	if (r)
    637		goto err;
    638
    639	r = _dsicm_enable_te(ddata, ddata->te_enabled);
    640	if (r)
    641		goto err;
    642
    643	r = in->ops.dsi->enable_video_output(in, ddata->channel);
    644	if (r)
    645		goto err;
    646
    647	ddata->enabled = 1;
    648
    649	if (!ddata->intro_printed) {
    650		dev_info(&ddata->pdev->dev, "panel revision %02x.%02x.%02x\n",
    651			id1, id2, id3);
    652		ddata->intro_printed = true;
    653	}
    654
    655	in->ops.dsi->enable_hs(in, ddata->channel, true);
    656
    657	return 0;
    658err:
    659	dev_err(&ddata->pdev->dev, "error while enabling panel, issuing HW reset\n");
    660
    661	dsicm_hw_reset(ddata);
    662
    663	in->ops.dsi->disable(in, true, false);
    664err0:
    665	return r;
    666}
    667
    668static void dsicm_power_off(struct panel_drv_data *ddata)
    669{
    670	struct omap_dss_device *in = ddata->in;
    671	int r;
    672
    673	in->ops.dsi->disable_video_output(in, ddata->channel);
    674
    675	r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_DISPLAY_OFF);
    676	if (!r)
    677		r = dsicm_sleep_in(ddata);
    678
    679	if (r) {
    680		dev_err(&ddata->pdev->dev,
    681				"error disabling panel, issuing HW reset\n");
    682		dsicm_hw_reset(ddata);
    683	}
    684
    685	in->ops.dsi->disable(in, true, false);
    686
    687	ddata->enabled = 0;
    688}
    689
    690static int dsicm_panel_reset(struct panel_drv_data *ddata)
    691{
    692	dev_err(&ddata->pdev->dev, "performing LCD reset\n");
    693
    694	dsicm_power_off(ddata);
    695	dsicm_hw_reset(ddata);
    696	return dsicm_power_on(ddata);
    697}
    698
    699static int dsicm_connect(struct omap_dss_device *dssdev)
    700{
    701	struct panel_drv_data *ddata = to_panel_data(dssdev);
    702	struct omap_dss_device *in = ddata->in;
    703	struct device *dev = &ddata->pdev->dev;
    704	int r;
    705
    706	if (omapdss_device_is_connected(dssdev))
    707		return 0;
    708
    709	r = in->ops.dsi->connect(in, dssdev);
    710	if (r) {
    711		dev_err(dev, "Failed to connect to video source\n");
    712		return r;
    713	}
    714
    715	r = in->ops.dsi->request_vc(ddata->in, &ddata->channel);
    716	if (r) {
    717		dev_err(dev, "failed to get virtual channel\n");
    718		goto err_req_vc;
    719	}
    720
    721	r = in->ops.dsi->set_vc_id(ddata->in, ddata->channel, TCH);
    722	if (r) {
    723		dev_err(dev, "failed to set VC_ID\n");
    724		goto err_vc_id;
    725	}
    726
    727	return 0;
    728
    729err_vc_id:
    730	in->ops.dsi->release_vc(ddata->in, ddata->channel);
    731err_req_vc:
    732	in->ops.dsi->disconnect(in, dssdev);
    733	return r;
    734}
    735
    736static void dsicm_disconnect(struct omap_dss_device *dssdev)
    737{
    738	struct panel_drv_data *ddata = to_panel_data(dssdev);
    739	struct omap_dss_device *in = ddata->in;
    740
    741	if (!omapdss_device_is_connected(dssdev))
    742		return;
    743
    744	in->ops.dsi->release_vc(in, ddata->channel);
    745	in->ops.dsi->disconnect(in, dssdev);
    746}
    747
    748static int dsicm_enable(struct omap_dss_device *dssdev)
    749{
    750	struct panel_drv_data *ddata = to_panel_data(dssdev);
    751	struct omap_dss_device *in = ddata->in;
    752	int r;
    753
    754	dev_dbg(&ddata->pdev->dev, "enable\n");
    755
    756	mutex_lock(&ddata->lock);
    757
    758	if (!omapdss_device_is_connected(dssdev)) {
    759		r = -ENODEV;
    760		goto err;
    761	}
    762
    763	if (omapdss_device_is_enabled(dssdev)) {
    764		r = 0;
    765		goto err;
    766	}
    767
    768	in->ops.dsi->bus_lock(in);
    769
    770	r = dsicm_power_on(ddata);
    771
    772	in->ops.dsi->bus_unlock(in);
    773
    774	if (r)
    775		goto err;
    776
    777	dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;
    778
    779	mutex_unlock(&ddata->lock);
    780
    781	return 0;
    782err:
    783	dev_dbg(&ddata->pdev->dev, "enable failed\n");
    784	mutex_unlock(&ddata->lock);
    785	return r;
    786}
    787
    788static void dsicm_disable(struct omap_dss_device *dssdev)
    789{
    790	struct panel_drv_data *ddata = to_panel_data(dssdev);
    791	struct omap_dss_device *in = ddata->in;
    792	int r;
    793
    794	dev_dbg(&ddata->pdev->dev, "disable\n");
    795
    796	mutex_lock(&ddata->lock);
    797
    798	dsicm_cancel_ulps_work(ddata);
    799
    800	in->ops.dsi->bus_lock(in);
    801
    802	if (omapdss_device_is_enabled(dssdev)) {
    803		r = dsicm_wake_up(ddata);
    804		if (!r)
    805			dsicm_power_off(ddata);
    806	}
    807
    808	in->ops.dsi->bus_unlock(in);
    809
    810	dssdev->state = OMAP_DSS_DISPLAY_DISABLED;
    811
    812	mutex_unlock(&ddata->lock);
    813}
    814
    815static void dsicm_framedone_cb(int err, void *data)
    816{
    817	struct panel_drv_data *ddata = data;
    818	struct omap_dss_device *in = ddata->in;
    819
    820	dev_dbg(&ddata->pdev->dev, "framedone, err %d\n", err);
    821	in->ops.dsi->bus_unlock(ddata->in);
    822}
    823
    824static irqreturn_t dsicm_te_isr(int irq, void *data)
    825{
    826	struct panel_drv_data *ddata = data;
    827	struct omap_dss_device *in = ddata->in;
    828	int old;
    829	int r;
    830
    831	old = atomic_cmpxchg(&ddata->do_update, 1, 0);
    832
    833	if (old) {
    834		cancel_delayed_work(&ddata->te_timeout_work);
    835
    836		r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
    837				ddata);
    838		if (r)
    839			goto err;
    840	}
    841
    842	return IRQ_HANDLED;
    843err:
    844	dev_err(&ddata->pdev->dev, "start update failed\n");
    845	in->ops.dsi->bus_unlock(in);
    846	return IRQ_HANDLED;
    847}
    848
    849static void dsicm_te_timeout_work_callback(struct work_struct *work)
    850{
    851	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
    852					te_timeout_work.work);
    853	struct omap_dss_device *in = ddata->in;
    854
    855	dev_err(&ddata->pdev->dev, "TE not received for 250ms!\n");
    856
    857	atomic_set(&ddata->do_update, 0);
    858	in->ops.dsi->bus_unlock(in);
    859}
    860
    861static int dsicm_update(struct omap_dss_device *dssdev,
    862				    u16 x, u16 y, u16 w, u16 h)
    863{
    864	struct panel_drv_data *ddata = to_panel_data(dssdev);
    865	struct omap_dss_device *in = ddata->in;
    866	int r;
    867
    868	dev_dbg(&ddata->pdev->dev, "update %d, %d, %d x %d\n", x, y, w, h);
    869
    870	mutex_lock(&ddata->lock);
    871	in->ops.dsi->bus_lock(in);
    872
    873	r = dsicm_wake_up(ddata);
    874	if (r)
    875		goto err;
    876
    877	if (!ddata->enabled) {
    878		r = 0;
    879		goto err;
    880	}
    881
    882	/* XXX no need to send this every frame, but dsi break if not done */
    883	r = dsicm_set_update_window(ddata, 0, 0,
    884			dssdev->panel.timings.x_res,
    885			dssdev->panel.timings.y_res);
    886	if (r)
    887		goto err;
    888
    889	if (ddata->te_enabled && gpio_is_valid(ddata->ext_te_gpio)) {
    890		schedule_delayed_work(&ddata->te_timeout_work,
    891				msecs_to_jiffies(250));
    892		atomic_set(&ddata->do_update, 1);
    893	} else {
    894		r = in->ops.dsi->update(in, ddata->channel, dsicm_framedone_cb,
    895				ddata);
    896		if (r)
    897			goto err;
    898	}
    899
    900	/* note: no bus_unlock here. unlock is in framedone_cb */
    901	mutex_unlock(&ddata->lock);
    902	return 0;
    903err:
    904	in->ops.dsi->bus_unlock(in);
    905	mutex_unlock(&ddata->lock);
    906	return r;
    907}
    908
    909static int dsicm_sync(struct omap_dss_device *dssdev)
    910{
    911	struct panel_drv_data *ddata = to_panel_data(dssdev);
    912	struct omap_dss_device *in = ddata->in;
    913
    914	dev_dbg(&ddata->pdev->dev, "sync\n");
    915
    916	mutex_lock(&ddata->lock);
    917	in->ops.dsi->bus_lock(in);
    918	in->ops.dsi->bus_unlock(in);
    919	mutex_unlock(&ddata->lock);
    920
    921	dev_dbg(&ddata->pdev->dev, "sync done\n");
    922
    923	return 0;
    924}
    925
    926static int _dsicm_enable_te(struct panel_drv_data *ddata, bool enable)
    927{
    928	struct omap_dss_device *in = ddata->in;
    929	int r;
    930
    931	if (enable)
    932		r = dsicm_dcs_write_1(ddata, MIPI_DCS_SET_TEAR_ON, 0);
    933	else
    934		r = dsicm_dcs_write_0(ddata, MIPI_DCS_SET_TEAR_OFF);
    935
    936	if (!gpio_is_valid(ddata->ext_te_gpio))
    937		in->ops.dsi->enable_te(in, enable);
    938
    939	/* possible panel bug */
    940	msleep(100);
    941
    942	return r;
    943}
    944
    945static int dsicm_enable_te(struct omap_dss_device *dssdev, bool enable)
    946{
    947	struct panel_drv_data *ddata = to_panel_data(dssdev);
    948	struct omap_dss_device *in = ddata->in;
    949	int r;
    950
    951	mutex_lock(&ddata->lock);
    952
    953	if (ddata->te_enabled == enable)
    954		goto end;
    955
    956	in->ops.dsi->bus_lock(in);
    957
    958	if (ddata->enabled) {
    959		r = dsicm_wake_up(ddata);
    960		if (r)
    961			goto err;
    962
    963		r = _dsicm_enable_te(ddata, enable);
    964		if (r)
    965			goto err;
    966	}
    967
    968	ddata->te_enabled = enable;
    969
    970	in->ops.dsi->bus_unlock(in);
    971end:
    972	mutex_unlock(&ddata->lock);
    973
    974	return 0;
    975err:
    976	in->ops.dsi->bus_unlock(in);
    977	mutex_unlock(&ddata->lock);
    978
    979	return r;
    980}
    981
    982static int dsicm_get_te(struct omap_dss_device *dssdev)
    983{
    984	struct panel_drv_data *ddata = to_panel_data(dssdev);
    985	int r;
    986
    987	mutex_lock(&ddata->lock);
    988	r = ddata->te_enabled;
    989	mutex_unlock(&ddata->lock);
    990
    991	return r;
    992}
    993
    994static int dsicm_memory_read(struct omap_dss_device *dssdev,
    995		void *buf, size_t size,
    996		u16 x, u16 y, u16 w, u16 h)
    997{
    998	struct panel_drv_data *ddata = to_panel_data(dssdev);
    999	struct omap_dss_device *in = ddata->in;
   1000	int r;
   1001	int first = 1;
   1002	int plen;
   1003	unsigned buf_used = 0;
   1004
   1005	if (size < w * h * 3)
   1006		return -ENOMEM;
   1007
   1008	mutex_lock(&ddata->lock);
   1009
   1010	if (!ddata->enabled) {
   1011		r = -ENODEV;
   1012		goto err1;
   1013	}
   1014
   1015	size = min(w * h * 3,
   1016			dssdev->panel.timings.x_res *
   1017			dssdev->panel.timings.y_res * 3);
   1018
   1019	in->ops.dsi->bus_lock(in);
   1020
   1021	r = dsicm_wake_up(ddata);
   1022	if (r)
   1023		goto err2;
   1024
   1025	/* plen 1 or 2 goes into short packet. until checksum error is fixed,
   1026	 * use short packets. plen 32 works, but bigger packets seem to cause
   1027	 * an error. */
   1028	if (size % 2)
   1029		plen = 1;
   1030	else
   1031		plen = 2;
   1032
   1033	dsicm_set_update_window(ddata, x, y, w, h);
   1034
   1035	r = in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, plen);
   1036	if (r)
   1037		goto err2;
   1038
   1039	while (buf_used < size) {
   1040		u8 dcs_cmd = first ? 0x2e : 0x3e;
   1041		first = 0;
   1042
   1043		r = in->ops.dsi->dcs_read(in, ddata->channel, dcs_cmd,
   1044				buf + buf_used, size - buf_used);
   1045
   1046		if (r < 0) {
   1047			dev_err(dssdev->dev, "read error\n");
   1048			goto err3;
   1049		}
   1050
   1051		buf_used += r;
   1052
   1053		if (r < plen) {
   1054			dev_err(&ddata->pdev->dev, "short read\n");
   1055			break;
   1056		}
   1057
   1058		if (signal_pending(current)) {
   1059			dev_err(&ddata->pdev->dev, "signal pending, "
   1060					"aborting memory read\n");
   1061			r = -ERESTARTSYS;
   1062			goto err3;
   1063		}
   1064	}
   1065
   1066	r = buf_used;
   1067
   1068err3:
   1069	in->ops.dsi->set_max_rx_packet_size(in, ddata->channel, 1);
   1070err2:
   1071	in->ops.dsi->bus_unlock(in);
   1072err1:
   1073	mutex_unlock(&ddata->lock);
   1074	return r;
   1075}
   1076
   1077static void dsicm_ulps_work(struct work_struct *work)
   1078{
   1079	struct panel_drv_data *ddata = container_of(work, struct panel_drv_data,
   1080			ulps_work.work);
   1081	struct omap_dss_device *dssdev = &ddata->dssdev;
   1082	struct omap_dss_device *in = ddata->in;
   1083
   1084	mutex_lock(&ddata->lock);
   1085
   1086	if (dssdev->state != OMAP_DSS_DISPLAY_ACTIVE || !ddata->enabled) {
   1087		mutex_unlock(&ddata->lock);
   1088		return;
   1089	}
   1090
   1091	in->ops.dsi->bus_lock(in);
   1092
   1093	dsicm_enter_ulps(ddata);
   1094
   1095	in->ops.dsi->bus_unlock(in);
   1096	mutex_unlock(&ddata->lock);
   1097}
   1098
   1099static struct omap_dss_driver dsicm_ops = {
   1100	.connect	= dsicm_connect,
   1101	.disconnect	= dsicm_disconnect,
   1102
   1103	.enable		= dsicm_enable,
   1104	.disable	= dsicm_disable,
   1105
   1106	.update		= dsicm_update,
   1107	.sync		= dsicm_sync,
   1108
   1109	.get_resolution	= dsicm_get_resolution,
   1110	.get_recommended_bpp = omapdss_default_get_recommended_bpp,
   1111
   1112	.enable_te	= dsicm_enable_te,
   1113	.get_te		= dsicm_get_te,
   1114
   1115	.memory_read	= dsicm_memory_read,
   1116};
   1117
   1118static int dsicm_probe_of(struct platform_device *pdev)
   1119{
   1120	struct device_node *node = pdev->dev.of_node;
   1121	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
   1122	struct omap_dss_device *in;
   1123	int gpio;
   1124
   1125	gpio = of_get_named_gpio(node, "reset-gpios", 0);
   1126	if (!gpio_is_valid(gpio)) {
   1127		dev_err(&pdev->dev, "failed to parse reset gpio\n");
   1128		return gpio;
   1129	}
   1130	ddata->reset_gpio = gpio;
   1131
   1132	gpio = of_get_named_gpio(node, "te-gpios", 0);
   1133	if (gpio_is_valid(gpio) || gpio == -ENOENT) {
   1134		ddata->ext_te_gpio = gpio;
   1135	} else {
   1136		dev_err(&pdev->dev, "failed to parse TE gpio\n");
   1137		return gpio;
   1138	}
   1139
   1140	in = omapdss_of_find_source_for_first_ep(node);
   1141	if (IS_ERR(in)) {
   1142		dev_err(&pdev->dev, "failed to find video source\n");
   1143		return PTR_ERR(in);
   1144	}
   1145
   1146	ddata->in = in;
   1147
   1148	/* TODO: ulps, backlight */
   1149
   1150	return 0;
   1151}
   1152
   1153static int dsicm_probe(struct platform_device *pdev)
   1154{
   1155	struct backlight_properties props;
   1156	struct panel_drv_data *ddata;
   1157	struct backlight_device *bldev = NULL;
   1158	struct device *dev = &pdev->dev;
   1159	struct omap_dss_device *dssdev;
   1160	int r;
   1161
   1162	dev_dbg(dev, "probe\n");
   1163
   1164	if (!pdev->dev.of_node)
   1165		return -ENODEV;
   1166
   1167	ddata = devm_kzalloc(dev, sizeof(*ddata), GFP_KERNEL);
   1168	if (!ddata)
   1169		return -ENOMEM;
   1170
   1171	platform_set_drvdata(pdev, ddata);
   1172	ddata->pdev = pdev;
   1173
   1174	r = dsicm_probe_of(pdev);
   1175	if (r)
   1176		return r;
   1177
   1178	ddata->timings.x_res = 864;
   1179	ddata->timings.y_res = 480;
   1180	ddata->timings.pixelclock = 864 * 480 * 60;
   1181
   1182	dssdev = &ddata->dssdev;
   1183	dssdev->dev = dev;
   1184	dssdev->driver = &dsicm_ops;
   1185	dssdev->panel.timings = ddata->timings;
   1186	dssdev->type = OMAP_DISPLAY_TYPE_DSI;
   1187	dssdev->owner = THIS_MODULE;
   1188
   1189	dssdev->panel.dsi_pix_fmt = OMAP_DSS_DSI_FMT_RGB888;
   1190	dssdev->caps = OMAP_DSS_DISPLAY_CAP_MANUAL_UPDATE |
   1191		OMAP_DSS_DISPLAY_CAP_TEAR_ELIM;
   1192
   1193	r = omapdss_register_display(dssdev);
   1194	if (r) {
   1195		dev_err(dev, "Failed to register panel\n");
   1196		goto err_reg;
   1197	}
   1198
   1199	mutex_init(&ddata->lock);
   1200
   1201	atomic_set(&ddata->do_update, 0);
   1202
   1203	if (gpio_is_valid(ddata->reset_gpio)) {
   1204		r = devm_gpio_request_one(dev, ddata->reset_gpio,
   1205				GPIOF_OUT_INIT_LOW, "taal rst");
   1206		if (r) {
   1207			dev_err(dev, "failed to request reset gpio\n");
   1208			return r;
   1209		}
   1210	}
   1211
   1212	if (gpio_is_valid(ddata->ext_te_gpio)) {
   1213		r = devm_gpio_request_one(dev, ddata->ext_te_gpio,
   1214				GPIOF_IN, "taal irq");
   1215		if (r) {
   1216			dev_err(dev, "GPIO request failed\n");
   1217			return r;
   1218		}
   1219
   1220		r = devm_request_irq(dev, gpio_to_irq(ddata->ext_te_gpio),
   1221				dsicm_te_isr,
   1222				IRQF_TRIGGER_RISING,
   1223				"taal vsync", ddata);
   1224
   1225		if (r) {
   1226			dev_err(dev, "IRQ request failed\n");
   1227			return r;
   1228		}
   1229
   1230		INIT_DEFERRABLE_WORK(&ddata->te_timeout_work,
   1231					dsicm_te_timeout_work_callback);
   1232
   1233		dev_dbg(dev, "Using GPIO TE\n");
   1234	}
   1235
   1236	INIT_DELAYED_WORK(&ddata->ulps_work, dsicm_ulps_work);
   1237
   1238	dsicm_hw_reset(ddata);
   1239
   1240	if (ddata->use_dsi_backlight) {
   1241		memset(&props, 0, sizeof(struct backlight_properties));
   1242		props.max_brightness = 255;
   1243
   1244		props.type = BACKLIGHT_RAW;
   1245		bldev = backlight_device_register(dev_name(dev),
   1246				dev, ddata, &dsicm_bl_ops, &props);
   1247		if (IS_ERR(bldev)) {
   1248			r = PTR_ERR(bldev);
   1249			goto err_reg;
   1250		}
   1251
   1252		ddata->bldev = bldev;
   1253
   1254		bldev->props.fb_blank = FB_BLANK_UNBLANK;
   1255		bldev->props.power = FB_BLANK_UNBLANK;
   1256		bldev->props.brightness = 255;
   1257
   1258		dsicm_bl_update_status(bldev);
   1259	}
   1260
   1261	r = sysfs_create_group(&dev->kobj, &dsicm_attr_group);
   1262	if (r) {
   1263		dev_err(dev, "failed to create sysfs files\n");
   1264		goto err_sysfs_create;
   1265	}
   1266
   1267	return 0;
   1268
   1269err_sysfs_create:
   1270	if (bldev != NULL)
   1271		backlight_device_unregister(bldev);
   1272err_reg:
   1273	return r;
   1274}
   1275
   1276static int __exit dsicm_remove(struct platform_device *pdev)
   1277{
   1278	struct panel_drv_data *ddata = platform_get_drvdata(pdev);
   1279	struct omap_dss_device *dssdev = &ddata->dssdev;
   1280	struct backlight_device *bldev;
   1281
   1282	dev_dbg(&pdev->dev, "remove\n");
   1283
   1284	omapdss_unregister_display(dssdev);
   1285
   1286	dsicm_disable(dssdev);
   1287	dsicm_disconnect(dssdev);
   1288
   1289	sysfs_remove_group(&pdev->dev.kobj, &dsicm_attr_group);
   1290
   1291	bldev = ddata->bldev;
   1292	if (bldev != NULL) {
   1293		bldev->props.power = FB_BLANK_POWERDOWN;
   1294		dsicm_bl_update_status(bldev);
   1295		backlight_device_unregister(bldev);
   1296	}
   1297
   1298	omap_dss_put_device(ddata->in);
   1299
   1300	dsicm_cancel_ulps_work(ddata);
   1301
   1302	/* reset, to be sure that the panel is in a valid state */
   1303	dsicm_hw_reset(ddata);
   1304
   1305	return 0;
   1306}
   1307
   1308static const struct of_device_id dsicm_of_match[] = {
   1309	{ .compatible = "omapdss,panel-dsi-cm", },
   1310	{},
   1311};
   1312
   1313MODULE_DEVICE_TABLE(of, dsicm_of_match);
   1314
   1315static struct platform_driver dsicm_driver = {
   1316	.probe = dsicm_probe,
   1317	.remove = __exit_p(dsicm_remove),
   1318	.driver = {
   1319		.name = "panel-dsi-cm",
   1320		.of_match_table = dsicm_of_match,
   1321		.suppress_bind_attrs = true,
   1322	},
   1323};
   1324
   1325module_platform_driver(dsicm_driver);
   1326
   1327MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
   1328MODULE_DESCRIPTION("Generic DSI Command Mode Panel Driver");
   1329MODULE_LICENSE("GPL");