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

display.c (7686B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * linux/drivers/video/omap2/dss/display.c
      4 *
      5 * Copyright (C) 2009 Nokia Corporation
      6 * Author: Tomi Valkeinen <tomi.valkeinen@nokia.com>
      7 *
      8 * Some code and ideas taken from drivers/video/omap/ driver
      9 * by Imre Deak.
     10 */
     11
     12#define DSS_SUBSYS_NAME "DISPLAY"
     13
     14#include <linux/kernel.h>
     15#include <linux/module.h>
     16#include <linux/jiffies.h>
     17#include <linux/platform_device.h>
     18#include <linux/of.h>
     19
     20#include <video/omapfb_dss.h>
     21#include "dss.h"
     22#include "dss_features.h"
     23
     24void omapdss_default_get_resolution(struct omap_dss_device *dssdev,
     25			u16 *xres, u16 *yres)
     26{
     27	*xres = dssdev->panel.timings.x_res;
     28	*yres = dssdev->panel.timings.y_res;
     29}
     30EXPORT_SYMBOL(omapdss_default_get_resolution);
     31
     32int omapdss_default_get_recommended_bpp(struct omap_dss_device *dssdev)
     33{
     34	switch (dssdev->type) {
     35	case OMAP_DISPLAY_TYPE_DPI:
     36		if (dssdev->phy.dpi.data_lines == 24)
     37			return 24;
     38		else
     39			return 16;
     40
     41	case OMAP_DISPLAY_TYPE_DBI:
     42		if (dssdev->ctrl.pixel_size == 24)
     43			return 24;
     44		else
     45			return 16;
     46	case OMAP_DISPLAY_TYPE_DSI:
     47		if (dsi_get_pixel_size(dssdev->panel.dsi_pix_fmt) > 16)
     48			return 24;
     49		else
     50			return 16;
     51	case OMAP_DISPLAY_TYPE_VENC:
     52	case OMAP_DISPLAY_TYPE_SDI:
     53	case OMAP_DISPLAY_TYPE_HDMI:
     54	case OMAP_DISPLAY_TYPE_DVI:
     55		return 24;
     56	default:
     57		BUG();
     58		return 0;
     59	}
     60}
     61EXPORT_SYMBOL(omapdss_default_get_recommended_bpp);
     62
     63void omapdss_default_get_timings(struct omap_dss_device *dssdev,
     64		struct omap_video_timings *timings)
     65{
     66	*timings = dssdev->panel.timings;
     67}
     68EXPORT_SYMBOL(omapdss_default_get_timings);
     69
     70int dss_suspend_all_devices(void)
     71{
     72	struct omap_dss_device *dssdev = NULL;
     73
     74	for_each_dss_dev(dssdev) {
     75		if (!dssdev->driver)
     76			continue;
     77
     78		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE) {
     79			dssdev->driver->disable(dssdev);
     80			dssdev->activate_after_resume = true;
     81		} else {
     82			dssdev->activate_after_resume = false;
     83		}
     84	}
     85
     86	return 0;
     87}
     88
     89int dss_resume_all_devices(void)
     90{
     91	struct omap_dss_device *dssdev = NULL;
     92
     93	for_each_dss_dev(dssdev) {
     94		if (!dssdev->driver)
     95			continue;
     96
     97		if (dssdev->activate_after_resume) {
     98			dssdev->driver->enable(dssdev);
     99			dssdev->activate_after_resume = false;
    100		}
    101	}
    102
    103	return 0;
    104}
    105
    106void dss_disable_all_devices(void)
    107{
    108	struct omap_dss_device *dssdev = NULL;
    109
    110	for_each_dss_dev(dssdev) {
    111		if (!dssdev->driver)
    112			continue;
    113
    114		if (dssdev->state == OMAP_DSS_DISPLAY_ACTIVE)
    115			dssdev->driver->disable(dssdev);
    116	}
    117}
    118
    119static LIST_HEAD(panel_list);
    120static DEFINE_MUTEX(panel_list_mutex);
    121static int disp_num_counter;
    122
    123int omapdss_register_display(struct omap_dss_device *dssdev)
    124{
    125	struct omap_dss_driver *drv = dssdev->driver;
    126	int id;
    127
    128	/*
    129	 * Note: this presumes all the displays are either using DT or non-DT,
    130	 * which normally should be the case. This also presumes that all
    131	 * displays either have an DT alias, or none has.
    132	 */
    133
    134	if (dssdev->dev->of_node) {
    135		id = of_alias_get_id(dssdev->dev->of_node, "display");
    136
    137		if (id < 0)
    138			id = disp_num_counter++;
    139	} else {
    140		id = disp_num_counter++;
    141	}
    142
    143	snprintf(dssdev->alias, sizeof(dssdev->alias), "display%d", id);
    144
    145	/* Use 'label' property for name, if it exists */
    146	if (dssdev->dev->of_node)
    147		of_property_read_string(dssdev->dev->of_node, "label",
    148			&dssdev->name);
    149
    150	if (dssdev->name == NULL)
    151		dssdev->name = dssdev->alias;
    152
    153	if (drv && drv->get_resolution == NULL)
    154		drv->get_resolution = omapdss_default_get_resolution;
    155	if (drv && drv->get_recommended_bpp == NULL)
    156		drv->get_recommended_bpp = omapdss_default_get_recommended_bpp;
    157	if (drv && drv->get_timings == NULL)
    158		drv->get_timings = omapdss_default_get_timings;
    159
    160	mutex_lock(&panel_list_mutex);
    161	list_add_tail(&dssdev->panel_list, &panel_list);
    162	mutex_unlock(&panel_list_mutex);
    163	return 0;
    164}
    165EXPORT_SYMBOL(omapdss_register_display);
    166
    167void omapdss_unregister_display(struct omap_dss_device *dssdev)
    168{
    169	mutex_lock(&panel_list_mutex);
    170	list_del(&dssdev->panel_list);
    171	mutex_unlock(&panel_list_mutex);
    172}
    173EXPORT_SYMBOL(omapdss_unregister_display);
    174
    175struct omap_dss_device *omap_dss_get_device(struct omap_dss_device *dssdev)
    176{
    177	if (!try_module_get(dssdev->owner))
    178		return NULL;
    179
    180	if (get_device(dssdev->dev) == NULL) {
    181		module_put(dssdev->owner);
    182		return NULL;
    183	}
    184
    185	return dssdev;
    186}
    187EXPORT_SYMBOL(omap_dss_get_device);
    188
    189void omap_dss_put_device(struct omap_dss_device *dssdev)
    190{
    191	put_device(dssdev->dev);
    192	module_put(dssdev->owner);
    193}
    194EXPORT_SYMBOL(omap_dss_put_device);
    195
    196/*
    197 * ref count of the found device is incremented.
    198 * ref count of from-device is decremented.
    199 */
    200struct omap_dss_device *omap_dss_get_next_device(struct omap_dss_device *from)
    201{
    202	struct list_head *l;
    203	struct omap_dss_device *dssdev;
    204
    205	mutex_lock(&panel_list_mutex);
    206
    207	if (list_empty(&panel_list)) {
    208		dssdev = NULL;
    209		goto out;
    210	}
    211
    212	if (from == NULL) {
    213		dssdev = list_first_entry(&panel_list, struct omap_dss_device,
    214				panel_list);
    215		omap_dss_get_device(dssdev);
    216		goto out;
    217	}
    218
    219	omap_dss_put_device(from);
    220
    221	list_for_each(l, &panel_list) {
    222		dssdev = list_entry(l, struct omap_dss_device, panel_list);
    223		if (dssdev == from) {
    224			if (list_is_last(l, &panel_list)) {
    225				dssdev = NULL;
    226				goto out;
    227			}
    228
    229			dssdev = list_entry(l->next, struct omap_dss_device,
    230					panel_list);
    231			omap_dss_get_device(dssdev);
    232			goto out;
    233		}
    234	}
    235
    236	WARN(1, "'from' dssdev not found\n");
    237
    238	dssdev = NULL;
    239out:
    240	mutex_unlock(&panel_list_mutex);
    241	return dssdev;
    242}
    243EXPORT_SYMBOL(omap_dss_get_next_device);
    244
    245struct omap_dss_device *omap_dss_find_device(void *data,
    246		int (*match)(struct omap_dss_device *dssdev, void *data))
    247{
    248	struct omap_dss_device *dssdev = NULL;
    249
    250	while ((dssdev = omap_dss_get_next_device(dssdev)) != NULL) {
    251		if (match(dssdev, data))
    252			return dssdev;
    253	}
    254
    255	return NULL;
    256}
    257EXPORT_SYMBOL(omap_dss_find_device);
    258
    259void videomode_to_omap_video_timings(const struct videomode *vm,
    260		struct omap_video_timings *ovt)
    261{
    262	memset(ovt, 0, sizeof(*ovt));
    263
    264	ovt->pixelclock = vm->pixelclock;
    265	ovt->x_res = vm->hactive;
    266	ovt->hbp = vm->hback_porch;
    267	ovt->hfp = vm->hfront_porch;
    268	ovt->hsw = vm->hsync_len;
    269	ovt->y_res = vm->vactive;
    270	ovt->vbp = vm->vback_porch;
    271	ovt->vfp = vm->vfront_porch;
    272	ovt->vsw = vm->vsync_len;
    273
    274	ovt->vsync_level = vm->flags & DISPLAY_FLAGS_VSYNC_HIGH ?
    275		OMAPDSS_SIG_ACTIVE_HIGH :
    276		OMAPDSS_SIG_ACTIVE_LOW;
    277	ovt->hsync_level = vm->flags & DISPLAY_FLAGS_HSYNC_HIGH ?
    278		OMAPDSS_SIG_ACTIVE_HIGH :
    279		OMAPDSS_SIG_ACTIVE_LOW;
    280	ovt->de_level = vm->flags & DISPLAY_FLAGS_DE_HIGH ?
    281		OMAPDSS_SIG_ACTIVE_HIGH :
    282		OMAPDSS_SIG_ACTIVE_LOW;
    283	ovt->data_pclk_edge = vm->flags & DISPLAY_FLAGS_PIXDATA_POSEDGE ?
    284		OMAPDSS_DRIVE_SIG_RISING_EDGE :
    285		OMAPDSS_DRIVE_SIG_FALLING_EDGE;
    286
    287	ovt->sync_pclk_edge = ovt->data_pclk_edge;
    288}
    289EXPORT_SYMBOL(videomode_to_omap_video_timings);
    290
    291void omap_video_timings_to_videomode(const struct omap_video_timings *ovt,
    292		struct videomode *vm)
    293{
    294	memset(vm, 0, sizeof(*vm));
    295
    296	vm->pixelclock = ovt->pixelclock;
    297
    298	vm->hactive = ovt->x_res;
    299	vm->hback_porch = ovt->hbp;
    300	vm->hfront_porch = ovt->hfp;
    301	vm->hsync_len = ovt->hsw;
    302	vm->vactive = ovt->y_res;
    303	vm->vback_porch = ovt->vbp;
    304	vm->vfront_porch = ovt->vfp;
    305	vm->vsync_len = ovt->vsw;
    306
    307	if (ovt->hsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
    308		vm->flags |= DISPLAY_FLAGS_HSYNC_HIGH;
    309	else
    310		vm->flags |= DISPLAY_FLAGS_HSYNC_LOW;
    311
    312	if (ovt->vsync_level == OMAPDSS_SIG_ACTIVE_HIGH)
    313		vm->flags |= DISPLAY_FLAGS_VSYNC_HIGH;
    314	else
    315		vm->flags |= DISPLAY_FLAGS_VSYNC_LOW;
    316
    317	if (ovt->de_level == OMAPDSS_SIG_ACTIVE_HIGH)
    318		vm->flags |= DISPLAY_FLAGS_DE_HIGH;
    319	else
    320		vm->flags |= DISPLAY_FLAGS_DE_LOW;
    321
    322	if (ovt->data_pclk_edge == OMAPDSS_DRIVE_SIG_RISING_EDGE)
    323		vm->flags |= DISPLAY_FLAGS_PIXDATA_POSEDGE;
    324	else
    325		vm->flags |= DISPLAY_FLAGS_PIXDATA_NEGEDGE;
    326}
    327EXPORT_SYMBOL(omap_video_timings_to_videomode);