Skip to content

Commit

Permalink
Merge tag 'omapdrm-4.12' of git://git.kernel.org/pub/scm/linux/kernel…
Browse files Browse the repository at this point in the history
…/git/tomba/linux into drm-next

omapdrm changes for 4.12

Main changes include:

* Add support for render nodes.
* Refactor omapdss code to allow multiple DISPC implementations. This is pre-work for DSS6 support.
* Fix replication logic bug, which caused RGB565 fb to be shown too dark on a 24bit display.
* Improve detection of display stack readiness, which should remove the probe order issues.
* Link panel-dpi with its backlight, so that they are turned on/off in sync.
* Fix possibly incorrect setup of sync and data-enable signals.
* Get rid of DRM_OMAP_NUM_CRTCS config option.

* tag 'omapdrm-4.12' of git://git.kernel.org/pub/scm/linux/kernel/git/tomba/linux: (34 commits)
  drm/omap: Major omap_modeset_init() cleanup
  drm/omap: Remove the obsolete #define omap_plane _omap_plane hack
  drm/omap: Fix one ugly indentation style break left by coccinelle
  drm/omap: Rename enum omap_plane to enum omap_plane_id
  drm/omap: Get rid of DRM_OMAP_NUM_CRTCS config option
  drm/omap: fix crash on module unload
  drm/omap: use drm_atomic_helper_shutdown()
  drm/omap: fix display SYNC/DE flags
  drm/omap: dispc: improve debug print of display flags
  drm/omap: displays: panel-dpi: Support for handling backlight devices
  drm/omap: poll only connectors where the connect/disconnect can be checked
  drm/omap: display: Add displays in sorted order to the panel_list
  drm/omap: Use omapdss_stack_is_ready() to check that the display stack is up
  drm/omap: dss: Support for detecting display stack readiness
  drm/omap: dss: Functions to check components in the display/output list
  drm/omap: fix replication logic
  drm/omap: remove unused dispc_wb_enable & dispc_wb_is_enabled
  drm/omap: remove all EXPORT_SYMBOLs from dispc.c
  drm/omap: use dispc_ops
  drm/omap: fill dispc_ops
  ...
  • Loading branch information
Dave Airlie committed Apr 3, 2017
2 parents 320d8c3 + e8e13b1 commit e1b489d
Show file tree
Hide file tree
Showing 26 changed files with 802 additions and 540 deletions.
3 changes: 3 additions & 0 deletions Documentation/devicetree/bindings/display/panel/panel-dpi.txt
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ Optional properties:
- enable-gpios: panel enable gpio
- reset-gpios: GPIO to control the RESET pin
- vcc-supply: phandle of regulator that will be used to enable power to the display
- backlight: phandle of the backlight device

Required nodes:
- "panel-timing" containing video timings
Expand All @@ -22,6 +23,8 @@ lcd0: display@0 {
compatible = "samsung,lte430wq-f0c", "panel-dpi";
label = "lcd";

backlight = <&backlight>;

port {
lcd_in: endpoint {
remote-endpoint = <&dpi_out>;
Expand Down
9 changes: 0 additions & 9 deletions drivers/gpu/drm/omapdrm/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -10,15 +10,6 @@ config DRM_OMAP

if DRM_OMAP

config DRM_OMAP_NUM_CRTCS
int "Number of CRTCs"
range 1 10
default 1 if ARCH_OMAP2 || ARCH_OMAP3
default 2 if ARCH_OMAP4
help
Select the number of video overlays which can be used as framebuffers.
The remaining overlays are reserved for video.

source "drivers/gpu/drm/omapdrm/dss/Kconfig"
source "drivers/gpu/drm/omapdrm/displays/Kconfig"

Expand Down
37 changes: 35 additions & 2 deletions drivers/gpu/drm/omapdrm/displays/panel-dpi.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
#include <linux/of.h>
#include <linux/of_gpio.h>
#include <linux/regulator/consumer.h>
#include <linux/backlight.h>

#include <video/omap-panel-data.h>
#include <video/of_display_timing.h>
Expand All @@ -30,6 +31,8 @@ struct panel_drv_data {

struct videomode vm;

struct backlight_device *backlight;

/* used for non-DT boot, to be removed */
int backlight_gpio;

Expand Down Expand Up @@ -97,6 +100,11 @@ static int panel_dpi_enable(struct omap_dss_device *dssdev)
if (gpio_is_valid(ddata->backlight_gpio))
gpio_set_value_cansleep(ddata->backlight_gpio, 1);

if (ddata->backlight) {
ddata->backlight->props.power = FB_BLANK_UNBLANK;
backlight_update_status(ddata->backlight);
}

dssdev->state = OMAP_DSS_DISPLAY_ACTIVE;

return 0;
Expand All @@ -113,6 +121,11 @@ static void panel_dpi_disable(struct omap_dss_device *dssdev)
if (gpio_is_valid(ddata->backlight_gpio))
gpio_set_value_cansleep(ddata->backlight_gpio, 0);

if (ddata->backlight) {
ddata->backlight->props.power = FB_BLANK_POWERDOWN;
backlight_update_status(ddata->backlight);
}

gpiod_set_value_cansleep(ddata->enable_gpio, 0);
regulator_disable(ddata->vcc_supply);

Expand Down Expand Up @@ -209,6 +222,7 @@ static int panel_dpi_probe_of(struct platform_device *pdev)
{
struct panel_drv_data *ddata = platform_get_drvdata(pdev);
struct device_node *node = pdev->dev.of_node;
struct device_node *bl_node;
struct omap_dss_device *in;
int r;
struct display_timing timing;
Expand Down Expand Up @@ -236,23 +250,39 @@ static int panel_dpi_probe_of(struct platform_device *pdev)

ddata->backlight_gpio = -ENOENT;

bl_node = of_parse_phandle(node, "backlight", 0);
if (bl_node) {
ddata->backlight = of_find_backlight_by_node(bl_node);
of_node_put(bl_node);

if (!ddata->backlight)
return -EPROBE_DEFER;
}

r = of_get_display_timing(node, "panel-timing", &timing);
if (r) {
dev_err(&pdev->dev, "failed to get video timing\n");
return r;
goto error_free_backlight;
}

videomode_from_timing(&timing, &ddata->vm);

in = omapdss_of_find_source_for_first_ep(node);
if (IS_ERR(in)) {
dev_err(&pdev->dev, "failed to find video source\n");
return PTR_ERR(in);
r = PTR_ERR(in);
goto error_free_backlight;
}

ddata->in = in;

return 0;

error_free_backlight:
if (ddata->backlight)
put_device(&ddata->backlight->dev);

return r;
}

static int panel_dpi_probe(struct platform_device *pdev)
Expand Down Expand Up @@ -321,6 +351,9 @@ static int __exit panel_dpi_remove(struct platform_device *pdev)

omap_dss_put_device(in);

if (ddata->backlight)
put_device(&ddata->backlight->dev);

return 0;
}

Expand Down
4 changes: 4 additions & 0 deletions drivers/gpu/drm/omapdrm/dss/Kconfig
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
config OMAP2_DSS_INIT
bool

config OMAP_DSS_BASE
tristate

menuconfig OMAP2_DSS
tristate "OMAP2+ Display Subsystem support"
select OMAP_DSS_BASE
select VIDEOMODE_HELPERS
select OMAP2_DSS_INIT
select HDMI
Expand Down
8 changes: 6 additions & 2 deletions drivers/gpu/drm/omapdrm/dss/Makefile
Original file line number Diff line number Diff line change
@@ -1,8 +1,12 @@
obj-$(CONFIG_OMAP2_DSS_INIT) += omapdss-boot-init.o

obj-$(CONFIG_OMAP_DSS_BASE) += omapdss-base.o
omapdss-base-y := base.o display.o dss-of.o output.o

obj-$(CONFIG_OMAP2_DSS) += omapdss.o
# Core DSS files
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o display.o \
output.o dss-of.o pll.o video-pll.o
omapdss-y := core.o dss.o dss_features.o dispc.o dispc_coefs.o \
pll.o video-pll.o
omapdss-$(CONFIG_OMAP2_DSS_DPI) += dpi.o
omapdss-$(CONFIG_OMAP2_DSS_RFBI) += rfbi.o
omapdss-$(CONFIG_OMAP2_DSS_VENC) += venc.o
Expand Down
140 changes: 140 additions & 0 deletions drivers/gpu/drm/omapdrm/dss/base.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,140 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/list.h>
#include "omapdss.h"

static bool dss_initialized;
static const struct dispc_ops *ops;

static struct list_head omapdss_comp_list;

struct omapdss_comp_node {
struct list_head list;
struct device_node *node;
bool dss_core_component;
};

void omapdss_set_is_initialized(bool set)
{
dss_initialized = set;
}
EXPORT_SYMBOL(omapdss_set_is_initialized);

bool omapdss_is_initialized(void)
{
return dss_initialized;
}
EXPORT_SYMBOL(omapdss_is_initialized);

void dispc_set_ops(const struct dispc_ops *o)
{
ops = o;
}
EXPORT_SYMBOL(dispc_set_ops);

const struct dispc_ops *dispc_get_ops(void)
{
return ops;
}
EXPORT_SYMBOL(dispc_get_ops);

static bool omapdss_list_contains(const struct device_node *node)
{
struct omapdss_comp_node *comp;

list_for_each_entry(comp, &omapdss_comp_list, list) {
if (comp->node == node)
return true;
}

return false;
}

static void omapdss_walk_device(struct device *dev, struct device_node *node,
bool dss_core)
{
struct device_node *n;
struct omapdss_comp_node *comp = devm_kzalloc(dev, sizeof(*comp),
GFP_KERNEL);

if (comp) {
comp->node = node;
comp->dss_core_component = dss_core;
list_add(&comp->list, &omapdss_comp_list);
}

/*
* of_graph_get_remote_port_parent() prints an error if there is no
* port/ports node. To avoid that, check first that there's the node.
*/
n = of_get_child_by_name(node, "ports");
if (!n)
n = of_get_child_by_name(node, "port");
if (!n)
return;

of_node_put(n);

n = NULL;
while ((n = of_graph_get_next_endpoint(node, n)) != NULL) {
struct device_node *pn = of_graph_get_remote_port_parent(n);

if (!pn)
continue;

if (!of_device_is_available(pn) || omapdss_list_contains(pn)) {
of_node_put(pn);
continue;
}

omapdss_walk_device(dev, pn, false);
}
}

void omapdss_gather_components(struct device *dev)
{
struct device_node *child;

INIT_LIST_HEAD(&omapdss_comp_list);

omapdss_walk_device(dev, dev->of_node, true);

for_each_available_child_of_node(dev->of_node, child) {
if (!of_find_property(child, "compatible", NULL))
continue;

omapdss_walk_device(dev, child, true);
}
}
EXPORT_SYMBOL(omapdss_gather_components);

static bool omapdss_component_is_loaded(struct omapdss_comp_node *comp)
{
if (comp->dss_core_component)
return true;
if (omapdss_component_is_display(comp->node))
return true;
if (omapdss_component_is_output(comp->node))
return true;

return false;
}

bool omapdss_stack_is_ready(void)
{
struct omapdss_comp_node *comp;

list_for_each_entry(comp, &omapdss_comp_list, list) {
if (!omapdss_component_is_loaded(comp))
return false;
}

return true;
}
EXPORT_SYMBOL(omapdss_stack_is_ready);

MODULE_AUTHOR("Tomi Valkeinen <tomi.valkeinen@ti.com>");
MODULE_DESCRIPTION("OMAP Display Subsystem Base");
MODULE_LICENSE("GPL v2");
Loading

0 comments on commit e1b489d

Please sign in to comment.