-
Notifications
You must be signed in to change notification settings - Fork 23
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
evdi: add evdi driver into android linux kernel
Tracked-On: OAM-119803 Signed-off-by: Fei Li <fei1.li@intel.com> Signed-off-by: Junjie Mao <junjie.mao@intel.com> Signed-off-by: Zhong, Fangjian <fangjian.zhong@intel.com> Signed-off-by: Yuanyuan Zhao <yuanyuan.zhao@intel.com>
- Loading branch information
1 parent
8d0b376
commit e26bd74
Showing
26 changed files
with
5,380 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
# SPDX-License-Identifier: GPL-2.0 | ||
obj-y += evdi_platform_drv.o evdi_platform_dev.o evdi_sysfs.o evdi_modeset.o evdi_connector.o evdi_encoder.o evdi_drm_drv.o evdi_fb.o evdi_gem.o evdi_painter.o evdi_params.o evdi_cursor.o evdi_debug.o evdi_i2c.o evdi_ioc32.o |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,168 @@ | ||
// SPDX-License-Identifier: GPL-2.0-only | ||
/* | ||
* Copyright (C) 2012 Red Hat | ||
* Copyright (c) 2015 - 2020 DisplayLink (UK) Ltd. | ||
* | ||
* Based on parts on udlfb.c: | ||
* Copyright (C) 2009 its respective authors | ||
* | ||
* This file is subject to the terms and conditions of the GNU General Public | ||
* License v2. See the file COPYING in the main directory of this archive for | ||
* more details. | ||
*/ | ||
|
||
#include <linux/version.h> | ||
#include <drm/drm_crtc.h> | ||
#include <drm/drm_edid.h> | ||
#include <drm/drm_crtc_helper.h> | ||
#include <drm/drm_atomic_helper.h> | ||
#include "evdi_drm_drv.h" | ||
|
||
#if KERNEL_VERSION(5, 1, 0) <= LINUX_VERSION_CODE || defined(EL8) | ||
#include <drm/drm_probe_helper.h> | ||
#endif | ||
|
||
/* | ||
* dummy connector to just get EDID, | ||
* all EVDI appear to have a DVI-D | ||
*/ | ||
|
||
static int evdi_get_modes(struct drm_connector *connector) | ||
{ | ||
struct evdi_device *evdi = connector->dev->dev_private; | ||
struct edid *edid = NULL; | ||
int ret = 0; | ||
|
||
edid = (struct edid *)evdi_painter_get_edid_copy(evdi); | ||
|
||
if (!edid) { | ||
#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE || defined(EL8) | ||
drm_connector_update_edid_property(connector, NULL); | ||
#else | ||
drm_mode_connector_update_edid_property(connector, NULL); | ||
#endif | ||
return 0; | ||
} | ||
|
||
#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE || defined(EL8) | ||
ret = drm_connector_update_edid_property(connector, edid); | ||
#else | ||
ret = drm_mode_connector_update_edid_property(connector, edid); | ||
#endif | ||
|
||
if (ret) { | ||
EVDI_ERROR("Failed to set edid property! error: %d", ret); | ||
goto err; | ||
} | ||
|
||
ret = drm_add_edid_modes(connector, edid); | ||
EVDI_INFO("(card%d) Edid property set", evdi->dev_index); | ||
err: | ||
kfree(edid); | ||
return ret; | ||
} | ||
|
||
static enum drm_mode_status evdi_mode_valid(struct drm_connector *connector, | ||
struct drm_display_mode *mode) | ||
{ | ||
struct evdi_device *evdi = connector->dev->dev_private; | ||
uint32_t area_limit = mode->hdisplay * mode->vdisplay; | ||
uint32_t mode_limit = area_limit * drm_mode_vrefresh(mode); | ||
|
||
if (evdi->pixel_per_second_limit == 0) | ||
return MODE_OK; | ||
|
||
if (area_limit > evdi->pixel_area_limit || | ||
mode_limit > evdi->pixel_per_second_limit) { | ||
EVDI_WARN("(card%d) Mode %dx%d@%d rejected\n", | ||
evdi->dev_index, | ||
mode->hdisplay, | ||
mode->vdisplay, | ||
drm_mode_vrefresh(mode)); | ||
return MODE_BAD; | ||
} | ||
|
||
return MODE_OK; | ||
} | ||
|
||
static enum drm_connector_status | ||
evdi_detect(struct drm_connector *connector, __always_unused bool force) | ||
{ | ||
struct evdi_device *evdi = connector->dev->dev_private; | ||
|
||
EVDI_CHECKPT(); | ||
if (evdi_painter_is_connected(evdi->painter)) { | ||
EVDI_INFO("(card%d) Connector state: connected\n", | ||
evdi->dev_index); | ||
return connector_status_connected; | ||
} | ||
EVDI_VERBOSE("(card%d) Connector state: disconnected\n", | ||
evdi->dev_index); | ||
return connector_status_disconnected; | ||
} | ||
|
||
static void evdi_connector_destroy(struct drm_connector *connector) | ||
{ | ||
drm_connector_unregister(connector); | ||
drm_connector_cleanup(connector); | ||
kfree(connector); | ||
} | ||
|
||
static struct drm_encoder *evdi_best_encoder(struct drm_connector *connector) | ||
{ | ||
#if KERNEL_VERSION(5, 5, 0) <= LINUX_VERSION_CODE || defined(EL8) | ||
struct drm_encoder *encoder; | ||
|
||
drm_connector_for_each_possible_encoder(connector, encoder) { | ||
return encoder; | ||
} | ||
|
||
return NULL; | ||
#else | ||
return drm_encoder_find(connector->dev, | ||
NULL, | ||
connector->encoder_ids[0]); | ||
#endif | ||
} | ||
|
||
static struct drm_connector_helper_funcs evdi_connector_helper_funcs = { | ||
.get_modes = evdi_get_modes, | ||
.mode_valid = evdi_mode_valid, | ||
.best_encoder = evdi_best_encoder, | ||
}; | ||
|
||
static const struct drm_connector_funcs evdi_connector_funcs = { | ||
.detect = evdi_detect, | ||
.fill_modes = drm_helper_probe_single_connector_modes, | ||
.destroy = evdi_connector_destroy, | ||
.reset = drm_atomic_helper_connector_reset, | ||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | ||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state | ||
}; | ||
|
||
int evdi_connector_init(struct drm_device *dev, struct drm_encoder *encoder) | ||
{ | ||
struct drm_connector *connector; | ||
struct evdi_device *evdi = dev->dev_private; | ||
|
||
connector = kzalloc(sizeof(struct drm_connector), GFP_KERNEL); | ||
if (!connector) | ||
return -ENOMEM; | ||
|
||
/* TODO: Initialize connector with actual connector type */ | ||
drm_connector_init(dev, connector, &evdi_connector_funcs, | ||
DRM_MODE_CONNECTOR_DVII); | ||
drm_connector_helper_add(connector, &evdi_connector_helper_funcs); | ||
connector->polled = DRM_CONNECTOR_POLL_HPD; | ||
|
||
drm_connector_register(connector); | ||
|
||
evdi->conn = connector; | ||
|
||
#if KERNEL_VERSION(4, 19, 0) <= LINUX_VERSION_CODE || defined(EL8) | ||
drm_connector_attach_encoder(connector, encoder); | ||
#else | ||
drm_mode_connector_attach_encoder(connector, encoder); | ||
#endif | ||
return 0; | ||
} |
Oops, something went wrong.