@@ -24,6 +24,10 @@ config DRM_MIPI_DSI
bool
depends on DRM
+config DRM_HW_BLOCK
+ bool
+ depends on DRM
+
config DRM_USB
tristate
depends on DRM
@@ -18,7 +18,7 @@ drm-y := drm_auth.o drm_buffer.o drm_bufs.o drm_cache.o \
drm-$(CONFIG_COMPAT) += drm_ioc32.o
drm-$(CONFIG_DRM_GEM_CMA_HELPER) += drm_gem_cma_helper.o
drm-$(CONFIG_PCI) += ati_pcigart.o
-drm-$(CONFIG_DRM_PANEL) += drm_panel.o
+drm-$(CONFIG_DRM_HW_BLOCK) += drm_hw_block.o
drm-usb-y := drm_usb.o
new file mode 100644
@@ -0,0 +1,104 @@
+/*
+ * Copyright (C) 2013, NVIDIA Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <linux/err.h>
+#include <linux/module.h>
+
+#include <drm/drm_crtc.h>
+#include <drm/drm_hw_block.h>
+
+static DEFINE_MUTEX(hw_block_lock);
+static LIST_HEAD(hw_block_list);
+
+void drm_hw_block_init(struct drm_hw_block *block)
+{
+ INIT_LIST_HEAD(&block->list);
+}
+EXPORT_SYMBOL(drm_hw_block_init);
+
+int drm_hw_block_add(struct drm_hw_block *block)
+{
+ mutex_lock(&hw_block_lock);
+ list_add_tail(&block->list, &hw_block_list);
+ mutex_unlock(&hw_block_lock);
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_hw_block_add);
+
+void drm_hw_block_remove(struct drm_hw_block *block)
+{
+ mutex_lock(&hw_block_lock);
+ list_del_init(&block->list);
+ mutex_unlock(&hw_block_lock);
+}
+EXPORT_SYMBOL(drm_hw_block_remove);
+
+int drm_hw_block_attach(struct drm_hw_block *block,
+ struct drm_connector *connector)
+{
+ if (block->type == DRM_HW_BLOCK_PANEL) {
+ if (block->connector)
+ return -EBUSY;
+
+ block->connector = connector;
+ }
+
+ block->drm = connector->dev;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_hw_block_attach);
+
+int drm_hw_block_detach(struct drm_hw_block *block)
+{
+ block->connector = NULL;
+ block->drm = NULL;
+
+ return 0;
+}
+EXPORT_SYMBOL(drm_hw_block_detach);
+
+#ifdef CONFIG_OF
+struct drm_hw_block *of_drm_find_hw_block(struct device_node *np)
+{
+ struct drm_hw_block *block;
+
+ mutex_lock(&hw_block_lock);
+
+ list_for_each_entry(block, &hw_block_list, list) {
+ if (block->dev->of_node == np) {
+ mutex_unlock(&hw_block_lock);
+ return block;
+ }
+ }
+
+ mutex_unlock(&hw_block_lock);
+ return NULL;
+}
+EXPORT_SYMBOL(of_drm_find_hw_block);
+#endif
+
+MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
+MODULE_DESCRIPTION("DRM hardware block infrastructure");
+MODULE_LICENSE("GPL and additional rights");
deleted file mode 100644
@@ -1,100 +0,0 @@
-/*
- * Copyright (C) 2013, NVIDIA Corporation. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#include <linux/err.h>
-#include <linux/module.h>
-
-#include <drm/drm_crtc.h>
-#include <drm/drm_panel.h>
-
-static DEFINE_MUTEX(panel_lock);
-static LIST_HEAD(panel_list);
-
-void drm_panel_init(struct drm_panel *panel)
-{
- INIT_LIST_HEAD(&panel->list);
-}
-EXPORT_SYMBOL(drm_panel_init);
-
-int drm_panel_add(struct drm_panel *panel)
-{
- mutex_lock(&panel_lock);
- list_add_tail(&panel->list, &panel_list);
- mutex_unlock(&panel_lock);
-
- return 0;
-}
-EXPORT_SYMBOL(drm_panel_add);
-
-void drm_panel_remove(struct drm_panel *panel)
-{
- mutex_lock(&panel_lock);
- list_del_init(&panel->list);
- mutex_unlock(&panel_lock);
-}
-EXPORT_SYMBOL(drm_panel_remove);
-
-int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector)
-{
- if (panel->connector)
- return -EBUSY;
-
- panel->connector = connector;
- panel->drm = connector->dev;
-
- return 0;
-}
-EXPORT_SYMBOL(drm_panel_attach);
-
-int drm_panel_detach(struct drm_panel *panel)
-{
- panel->connector = NULL;
- panel->drm = NULL;
-
- return 0;
-}
-EXPORT_SYMBOL(drm_panel_detach);
-
-#ifdef CONFIG_OF
-struct drm_panel *of_drm_find_panel(struct device_node *np)
-{
- struct drm_panel *panel;
-
- mutex_lock(&panel_lock);
-
- list_for_each_entry(panel, &panel_list, list) {
- if (panel->dev->of_node == np) {
- mutex_unlock(&panel_lock);
- return panel;
- }
- }
-
- mutex_unlock(&panel_lock);
- return NULL;
-}
-EXPORT_SYMBOL(of_drm_find_panel);
-#endif
-
-MODULE_AUTHOR("Thierry Reding <treding@nvidia.com>");
-MODULE_DESCRIPTION("DRM panel infrastructure");
-MODULE_LICENSE("GPL and additional rights");
@@ -8,6 +8,7 @@ config DRM_EXYNOS
select FB_CFB_IMAGEBLIT
select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
select VIDEOMODE_HELPERS
+ select DRM_PANEL
help
Choose this option if you have a Samsung SoC EXYNOS chipset.
If M is selected the module will be called exynosdrm.
@@ -1,6 +1,7 @@
config DRM_PANEL
bool
depends on DRM
+ select DRM_HW_BLOCK
help
Panel registration and lookup framework.
@@ -32,7 +32,7 @@
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
#include <drm/drm_mipi_dsi.h>
-#include <drm/drm_panel.h>
+#include <drm/drm_hw_block.h>
struct panel_desc {
const struct drm_display_mode *modes;
@@ -48,7 +48,7 @@ struct panel_desc {
#define GPIO_ACTIVE_LOW (1 << 0)
struct panel_simple {
- struct drm_panel base;
+ struct drm_hw_block base;
bool enabled;
const struct panel_desc *desc;
@@ -61,9 +61,9 @@ struct panel_simple {
int enable_gpio;
};
-static inline struct panel_simple *to_panel_simple(struct drm_panel *panel)
+static inline struct panel_simple *to_panel_simple(struct drm_hw_block *block)
{
- return container_of(panel, struct panel_simple, base);
+ return container_of(block, struct panel_simple, base);
}
static int panel_simple_get_fixed_modes(struct panel_simple *panel)
@@ -98,9 +98,9 @@ static int panel_simple_get_fixed_modes(struct panel_simple *panel)
return num;
}
-static int panel_simple_disable(struct drm_panel *panel)
+static int panel_simple_disable(struct drm_hw_block *block)
{
- struct panel_simple *p = to_panel_simple(panel);
+ struct panel_simple *p = to_panel_simple(block);
if (!p->enabled)
return 0;
@@ -123,9 +123,9 @@ static int panel_simple_disable(struct drm_panel *panel)
return 0;
}
-static int panel_simple_enable(struct drm_panel *panel)
+static int panel_simple_enable(struct drm_hw_block *block)
{
- struct panel_simple *p = to_panel_simple(panel);
+ struct panel_simple *p = to_panel_simple(block);
int err;
if (p->enabled)
@@ -133,7 +133,7 @@ static int panel_simple_enable(struct drm_panel *panel)
err = regulator_enable(p->supply);
if (err < 0) {
- dev_err(panel->dev, "failed to enable supply: %d\n", err);
+ dev_err(block->dev, "failed to enable supply: %d\n", err);
return err;
}
@@ -154,16 +154,16 @@ static int panel_simple_enable(struct drm_panel *panel)
return 0;
}
-static int panel_simple_get_modes(struct drm_panel *panel)
+static int panel_simple_get_modes(struct drm_hw_block *block)
{
- struct panel_simple *p = to_panel_simple(panel);
+ struct panel_simple *p = to_panel_simple(block);
int num = 0;
/* probe EDID if a DDC bus is available */
if (p->ddc) {
- struct edid *edid = drm_get_edid(panel->connector, p->ddc);
+ struct edid *edid = drm_get_edid(block->connector, p->ddc);
if (edid) {
- num += drm_add_edid_modes(panel->connector, edid);
+ num += drm_add_edid_modes(block->connector, edid);
kfree(edid);
}
}
@@ -246,11 +246,12 @@ static int panel_simple_probe(struct device *dev, const struct panel_desc *desc)
}
}
- drm_panel_init(&panel->base);
+ panel->base.type = DRM_HW_BLOCK_PANEL;
+ drm_hw_block_init(&panel->base);
panel->base.dev = dev;
- panel->base.funcs = &panel_simple_funcs;
+ panel->base.panel_funcs = &panel_simple_funcs;
- err = drm_panel_add(&panel->base);
+ err = drm_hw_block_add(&panel->base);
if (err < 0)
goto free_ddc;
@@ -275,8 +276,8 @@ static int panel_simple_remove(struct device *dev)
{
struct panel_simple *panel = dev_get_drvdata(dev);
- drm_panel_detach(&panel->base);
- drm_panel_remove(&panel->base);
+ drm_hw_block_detach(&panel->base);
+ drm_hw_block_remove(&panel->base);
panel_simple_disable(&panel->base);
@@ -194,7 +194,7 @@ struct tegra_output {
const struct tegra_output_ops *ops;
enum tegra_output_type type;
- struct drm_panel *panel;
+ struct drm_hw_block *block;
struct i2c_adapter *ddc;
const struct edid *edid;
unsigned int hpd_irq;
@@ -29,7 +29,7 @@
#include <linux/reset.h>
#include <drm/drm_mipi_dsi.h>
-#include <drm/drm_panel.h>
+#include <drm/drm_hw_block.h>
#include <video/mipi_display.h>
@@ -792,8 +792,8 @@ static int tegra_dsi_host_attach(struct mipi_dsi_host *host,
dsi->format = device->format;
dsi->lanes = device->lanes;
- output->panel = of_drm_find_panel(device->dev.of_node);
- if (output->panel) {
+ output->block = of_drm_find_hw_block(device->dev.of_node);
+ if (output->block) {
if (output->connector.dev)
drm_helper_hpd_irq_event(output->connector.dev);
}
@@ -807,11 +807,11 @@ static int tegra_dsi_host_detach(struct mipi_dsi_host *host,
struct tegra_dsi *dsi = host_to_tegra(host);
struct tegra_output *output = &dsi->output;
- if (output->panel && &device->dev == output->panel->dev) {
+ if (output->block && &device->dev == output->block->dev) {
if (output->connector.dev)
drm_helper_hpd_irq_event(output->connector.dev);
- output->panel = NULL;
+ output->block = NULL;
}
return 0;
@@ -9,7 +9,7 @@
#include <linux/of_gpio.h>
-#include <drm/drm_panel.h>
+#include <drm/drm_hw_block.h>
#include "drm.h"
static int tegra_connector_get_modes(struct drm_connector *connector)
@@ -18,8 +18,8 @@ static int tegra_connector_get_modes(struct drm_connector *connector)
struct edid *edid = NULL;
int err = 0;
- if (output->panel) {
- err = output->panel->funcs->get_modes(output->panel);
+ if (output->block) {
+ err = output->block->panel_funcs->get_modes(output->block);
if (err > 0)
return err;
}
@@ -79,7 +79,7 @@ tegra_connector_detect(struct drm_connector *connector, bool force)
else
status = connector_status_connected;
} else {
- if (!output->panel)
+ if (!output->block)
status = connector_status_disconnected;
else
status = connector_status_connected;
@@ -128,14 +128,14 @@ static const struct drm_encoder_funcs encoder_funcs = {
static void tegra_encoder_dpms(struct drm_encoder *encoder, int mode)
{
struct tegra_output *output = encoder_to_output(encoder);
- struct drm_panel *panel = output->panel;
+ struct drm_hw_block *block = output->block;
if (mode != DRM_MODE_DPMS_ON) {
- drm_panel_disable(panel);
+ drm_hw_block_disable(block);
tegra_output_disable(output);
} else {
tegra_output_enable(output);
- drm_panel_enable(panel);
+ drm_hw_block_enable(block);
}
}
@@ -195,8 +195,8 @@ int tegra_output_probe(struct tegra_output *output)
panel = of_parse_phandle(output->of_node, "nvidia,panel", 0);
if (panel) {
- output->panel = of_drm_find_panel(panel);
- if (!output->panel)
+ output->block = of_drm_find_hw_block(panel);
+ if (!output->block)
return -EPROBE_DEFER;
of_node_put(panel);
@@ -300,8 +300,8 @@ int tegra_output_init(struct drm_device *drm, struct tegra_output *output)
drm_connector_helper_add(&output->connector, &connector_helper_funcs);
output->connector.dpms = DRM_MODE_DPMS_OFF;
- if (output->panel)
- drm_panel_attach(output->panel, &output->connector);
+ if (output->block)
+ drm_hw_block_attach(output->block, &output->connector);
drm_encoder_init(drm, &output->encoder, &encoder_funcs, encoder);
drm_encoder_helper_add(&output->encoder, &encoder_helper_funcs);
new file mode 100644
@@ -0,0 +1,127 @@
+/*
+ * Copyright (C) 2013, NVIDIA Corporation. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sub license,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial portions
+ * of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#ifndef __DRM_HW_BLOCK_H__
+#define __DRM_HW_BLOCK_H__
+
+#include <linux/list.h>
+
+struct drm_connector;
+struct drm_device;
+struct drm_hw_block;
+struct drm_display_mode;
+
+enum drm_block_type {
+ DRM_HW_BLOCK_PANEL,
+ DRM_HW_BLOCK_LVDS,
+ /* TODO. add other bridge type types if needed. */
+};
+struct drm_panel_funcs {
+ int (*disable)(struct drm_hw_block *block);
+ int (*enable)(struct drm_hw_block *block);
+ int (*get_modes)(struct drm_hw_block *block);
+};
+
+struct drm_lvds_funcs {
+ bool (*mode_fixup)(struct drm_hw_block *bridge,
+ const struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+ int (*disable)(struct drm_hw_block *block);
+ int (*enable)(struct drm_hw_block *block);
+ void (*mode_set)(struct drm_hw_block *block,
+ struct drm_display_mode *mode,
+ struct drm_display_mode *adjusted_mode);
+ void (*pre_enable)(struct drm_hw_block *block);
+ void (*destroy)(struct drm_hw_block *block);
+};
+
+struct drm_hw_block {
+ enum drm_block_type type;
+ struct device *dev;
+ struct drm_device *drm;
+
+ struct drm_connector *connector;
+
+ const struct drm_panel_funcs *panel_funcs;
+ const struct drm_lvds_funcs *lvds_funcs;
+
+ /* TODO. Add callbacks for other bridge types if needed. */
+
+ struct list_head list;
+};
+
+static inline int drm_hw_block_disable(struct drm_hw_block *block)
+{
+ if (!block)
+ return -EINVAL;
+
+ if (block->type == DRM_HW_BLOCK_PANEL) {
+ if (block->panel_funcs && block->panel_funcs->disable)
+ return block->panel_funcs->disable(block);
+ }
+
+ if (block->type == DRM_HW_BLOCK_LVDS) {
+ if (block->lvds_funcs && block->lvds_funcs->disable)
+ return block->lvds_funcs->disable(block);
+ }
+
+ return -ENOSYS;
+}
+
+static inline int drm_hw_block_enable(struct drm_hw_block *block)
+{
+ if (!block)
+ return -EINVAL;
+
+ if (block->type == DRM_HW_BLOCK_PANEL) {
+ if (block->panel_funcs && block->panel_funcs->enable)
+ return block->panel_funcs->enable(block);
+ }
+
+ if (block->type == DRM_HW_BLOCK_LVDS) {
+ if (block->lvds_funcs && block->lvds_funcs->enable)
+ return block->lvds_funcs->enable(block);
+ }
+
+ return -ENOSYS;
+}
+
+void drm_hw_block_init(struct drm_hw_block *block);
+
+int drm_hw_block_add(struct drm_hw_block *block);
+void drm_hw_block_remove(struct drm_hw_block *block);
+
+int drm_hw_block_attach(struct drm_hw_block *block,
+ struct drm_connector *connector);
+int drm_hw_block_detach(struct drm_hw_block *block);
+
+#ifdef CONFIG_OF
+struct drm_hw_block *of_drm_find_hw_block(struct device_node *np);
+#else
+static inline struct drm_hw_block *of_drm_find_hw_block(struct device_node *np)
+{
+ return NULL;
+}
+#endif
+
+#endif
deleted file mode 100644
@@ -1,82 +0,0 @@
-/*
- * Copyright (C) 2013, NVIDIA Corporation. All rights reserved.
- *
- * Permission is hereby granted, free of charge, to any person obtaining a
- * copy of this software and associated documentation files (the "Software"),
- * to deal in the Software without restriction, including without limitation
- * the rights to use, copy, modify, merge, publish, distribute, sub license,
- * and/or sell copies of the Software, and to permit persons to whom the
- * Software is furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice (including the
- * next paragraph) shall be included in all copies or substantial portions
- * of the Software.
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
- * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
- * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
- * DEALINGS IN THE SOFTWARE.
- */
-
-#ifndef __DRM_PANEL_H__
-#define __DRM_PANEL_H__
-
-#include <linux/list.h>
-
-struct drm_connector;
-struct drm_device;
-struct drm_panel;
-
-struct drm_panel_funcs {
- int (*disable)(struct drm_panel *panel);
- int (*enable)(struct drm_panel *panel);
- int (*get_modes)(struct drm_panel *panel);
-};
-
-struct drm_panel {
- struct drm_device *drm;
- struct drm_connector *connector;
- struct device *dev;
-
- const struct drm_panel_funcs *funcs;
-
- struct list_head list;
-};
-
-static inline int drm_panel_disable(struct drm_panel *panel)
-{
- if (panel && panel->funcs && panel->funcs->disable)
- return panel->funcs->disable(panel);
-
- return panel ? -ENOSYS : -EINVAL;
-}
-
-static inline int drm_panel_enable(struct drm_panel *panel)
-{
- if (panel && panel->funcs && panel->funcs->enable)
- return panel->funcs->enable(panel);
-
- return panel ? -ENOSYS : -EINVAL;
-}
-
-void drm_panel_init(struct drm_panel *panel);
-
-int drm_panel_add(struct drm_panel *panel);
-void drm_panel_remove(struct drm_panel *panel);
-
-int drm_panel_attach(struct drm_panel *panel, struct drm_connector *connector);
-int drm_panel_detach(struct drm_panel *panel);
-
-#ifdef CONFIG_OF
-struct drm_panel *of_drm_find_panel(struct device_node *np);
-#else
-static inline struct drm_panel *of_drm_find_panel(struct device_node *np)
-{
- return NULL;
-}
-#endif
-
-#endif
This patch integrates existing drm_panel and drm_bridge frameworks to one integrated framework, drm_hw_block. For this, I had already sent a email to make a discussion[1] about how we could support all bridges, one bridge between crtc and encoder, and another bridge between encoder and panel. Now existing drm_panel could be used only for real panel, and drm_bridge only for lvds bridge devices between encoder and panel. However, some embedded SoC have bridge devices of other type between crtc and encoder, i.e. Image Enhancer chip. So the existing encoder driver couldn't control such bridge commonly using existing drm_bridge because only drm_encoder has drm_bridge. Below shows how encoder driver could control bridge device using existing drm_bridge. display controller ----- bridge1 ----- mipi dsi ----- bridge2 ----- panel | /|\ /|\ |---------------| | controlled by drm_bridge | | | |---------------------------| controlled by drm_panel In the other hands, drm_panel has no any dependency of drm_encoder, and its infrastructure could be used by crtc driver with a little change. So this integrated framework basically uses existing infrastructure of drm_panel, and just adds drm_lvds structure to it for backward compatibility. And then, we could add a new bridge type, i.e. drm_enhancer in the near future. So this patch is just ready for that. As a result, if we add drm_enhancer, crtc driver could control a bridge device between crtc and encoder like below. display controller ----- bridge1 ----- mipi dsi ----- bridge2 ----- panel | /|\ | /|\ /|\ |--------------------| |---------------| | controlled by drm_enhancer controlled by drm_lvds | | | |--------------------------| controlled by drm_panel Changelog v2: - Call enable and disable callback according to bridge type. - Correct module description. [1] http://www.spinics.net/lists/dri-devel/msg55555.html Signed-off-by: Inki Dae <inki.dae@samsung.com> --- drivers/gpu/drm/Kconfig | 4 ++ drivers/gpu/drm/Makefile | 2 +- drivers/gpu/drm/drm_hw_block.c | 104 ++++++++++++++++++++++++++++ drivers/gpu/drm/drm_panel.c | 100 -------------------------- drivers/gpu/drm/exynos/Kconfig | 1 + drivers/gpu/drm/panel/Kconfig | 1 + drivers/gpu/drm/panel/panel-simple.c | 37 +++++----- drivers/gpu/drm/tegra/drm.h | 2 +- drivers/gpu/drm/tegra/dsi.c | 10 +-- drivers/gpu/drm/tegra/output.c | 22 +++--- include/drm/drm_hw_block.h | 127 ++++++++++++++++++++++++++++++++++ include/drm/drm_panel.h | 82 ---------------------- 12 files changed, 274 insertions(+), 218 deletions(-) create mode 100644 drivers/gpu/drm/drm_hw_block.c delete mode 100644 drivers/gpu/drm/drm_panel.c create mode 100644 include/drm/drm_hw_block.h delete mode 100644 include/drm/drm_panel.h