forked from torvalds/linux
-
Notifications
You must be signed in to change notification settings - Fork 6
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
drm/tve200: Add new driver for TVE200
This adds a new DRM driver for the Faraday Technology TVE200 block. This "TV Encoder" encodes a ITU-T BT.656 stream and can be found in the StorLink SL3516 (later Cortina Systems CS3516) as well as the Grain Media GM8180. I do not have definitive word from anyone at Faraday that this IP block is theirs, but it bears the hallmark of their 3-digit version code (200) and is used in two SoCs from completely different companies. (Grain Media was fully owned by Faraday until it was transferred to NovoTek this january, and Faraday did lots of work on the StorLink SoCs.) The D-Link DIR-685 uses this in connection with the Ilitek ILI9322 panel driver that supports BT.656 input, while the GM8180 apparently has been used with the Cirrus Logic CS4954 digital video encoder. The oldest user seems to be something called Techwall 2835. This driver is heavily inspired by Eric Anholt's PL111 driver and therefore I have mentioned all the ancestor authors in the header file. Acked-by: Daniel Vetter <daniel.vetter@ffwll.ch> Reviewed-by: Eric Anholt <eric@anholt.net> Signed-off-by: Linus Walleij <linus.walleij@linaro.org> Link: https://patchwork.freedesktop.org/patch/msgid/20170820100557.24991-2-linus.walleij@linaro.org
- Loading branch information
Showing
11 changed files
with
912 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
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -15,6 +15,7 @@ Linux GPU Driver Developer's Guide | |
pl111 | ||
tegra | ||
tinydrm | ||
tve200 | ||
vc4 | ||
vga-switcheroo | ||
vgaarbiter | ||
|
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,6 @@ | ||
================================== | ||
drm/tve200 Faraday TV Encoder 200 | ||
================================== | ||
|
||
.. kernel-doc:: drivers/gpu/drm/tve200/tve200_drv.c | ||
:doc: Faraday TV Encoder 200 |
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
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,15 @@ | ||
config DRM_TVE200 | ||
tristate "DRM Support for Faraday TV Encoder TVE200" | ||
depends on DRM | ||
depends on CMA | ||
depends on ARM || COMPILE_TEST | ||
depends on OF | ||
select DRM_PANEL | ||
select DRM_KMS_HELPER | ||
select DRM_KMS_CMA_HELPER | ||
select DRM_GEM_CMA_HELPER | ||
select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE | ||
help | ||
Choose this option for DRM support for the Faraday TV Encoder | ||
TVE200 Controller. | ||
If M is selected the module will be called tve200_drm. |
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,5 @@ | ||
tve200_drm-y += tve200_connector.o \ | ||
tve200_display.o \ | ||
tve200_drv.o | ||
|
||
obj-$(CONFIG_DRM_TVE200) += tve200_drm.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,125 @@ | ||
/* | ||
* Copyright (C) 2017 Linus Walleij <linus.walleij@linaro.org> | ||
* Parts of this file were based on sources as follows: | ||
* | ||
* Copyright (C) 2006-2008 Intel Corporation | ||
* Copyright (C) 2007 Amos Lee <amos_lee@storlinksemi.com> | ||
* Copyright (C) 2007 Dave Airlie <airlied@linux.ie> | ||
* Copyright (C) 2011 Texas Instruments | ||
* Copyright (C) 2017 Eric Anholt | ||
* | ||
* This program is free software and is provided to you under the terms of the | ||
* GNU General Public License version 2 as published by the Free Software | ||
* Foundation, and any use by you of this program is subject to the terms of | ||
* such GNU licence. | ||
*/ | ||
|
||
/** | ||
* tve200_drm_connector.c | ||
* Implementation of the connector functions for the Faraday TV Encoder | ||
*/ | ||
#include <linux/version.h> | ||
#include <linux/shmem_fs.h> | ||
#include <linux/dma-buf.h> | ||
|
||
#include <drm/drmP.h> | ||
#include <drm/drm_atomic_helper.h> | ||
#include <drm/drm_crtc_helper.h> | ||
#include <drm/drm_of.h> | ||
#include <drm/drm_panel.h> | ||
|
||
#include "tve200_drm.h" | ||
|
||
static void tve200_connector_destroy(struct drm_connector *connector) | ||
{ | ||
struct tve200_drm_connector *tve200con = | ||
to_tve200_connector(connector); | ||
|
||
if (tve200con->panel) | ||
drm_panel_detach(tve200con->panel); | ||
|
||
drm_connector_unregister(connector); | ||
drm_connector_cleanup(connector); | ||
} | ||
|
||
static enum drm_connector_status tve200_connector_detect(struct drm_connector | ||
*connector, bool force) | ||
{ | ||
struct tve200_drm_connector *tve200con = | ||
to_tve200_connector(connector); | ||
|
||
return (tve200con->panel ? | ||
connector_status_connected : | ||
connector_status_disconnected); | ||
} | ||
|
||
static int tve200_connector_helper_get_modes(struct drm_connector *connector) | ||
{ | ||
struct tve200_drm_connector *tve200con = | ||
to_tve200_connector(connector); | ||
|
||
if (!tve200con->panel) | ||
return 0; | ||
|
||
return drm_panel_get_modes(tve200con->panel); | ||
} | ||
|
||
static const struct drm_connector_funcs connector_funcs = { | ||
.fill_modes = drm_helper_probe_single_connector_modes, | ||
.destroy = tve200_connector_destroy, | ||
.detect = tve200_connector_detect, | ||
.reset = drm_atomic_helper_connector_reset, | ||
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, | ||
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state, | ||
}; | ||
|
||
static const struct drm_connector_helper_funcs connector_helper_funcs = { | ||
.get_modes = tve200_connector_helper_get_modes, | ||
}; | ||
|
||
/* | ||
* Walks the OF graph to find the panel node and then asks DRM to look | ||
* up the panel. | ||
*/ | ||
static struct drm_panel *tve200_get_panel(struct device *dev) | ||
{ | ||
struct device_node *endpoint, *panel_node; | ||
struct device_node *np = dev->of_node; | ||
struct drm_panel *panel; | ||
|
||
endpoint = of_graph_get_next_endpoint(np, NULL); | ||
if (!endpoint) { | ||
dev_err(dev, "no endpoint to fetch panel\n"); | ||
return NULL; | ||
} | ||
|
||
/* Don't proceed if we have an endpoint but no panel_node tied to it */ | ||
panel_node = of_graph_get_remote_port_parent(endpoint); | ||
of_node_put(endpoint); | ||
if (!panel_node) { | ||
dev_err(dev, "no valid panel node\n"); | ||
return NULL; | ||
} | ||
|
||
panel = of_drm_find_panel(panel_node); | ||
of_node_put(panel_node); | ||
|
||
return panel; | ||
} | ||
|
||
int tve200_connector_init(struct drm_device *dev) | ||
{ | ||
struct tve200_drm_dev_private *priv = dev->dev_private; | ||
struct tve200_drm_connector *tve200con = &priv->connector; | ||
struct drm_connector *connector = &tve200con->connector; | ||
|
||
drm_connector_init(dev, connector, &connector_funcs, | ||
DRM_MODE_CONNECTOR_DPI); | ||
drm_connector_helper_add(connector, &connector_helper_funcs); | ||
|
||
tve200con->panel = tve200_get_panel(dev->dev); | ||
if (tve200con->panel) | ||
drm_panel_attach(tve200con->panel, connector); | ||
|
||
return 0; | ||
} |
Oops, something went wrong.