video/drm: Add rockchip bridge framework

The current implementation assumes that the only possible peripheral
device is a panel. Using an output bridge device should also be possible.

Such sequence is required by Rockchip RK618 bridge, which is a RGB
peripheral bridge device.

Change-Id: I3e4e5e9e23c8ed7c74ed1276946b7b54f4cd5ee8
Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
This commit is contained in:
Wyon Bi 2018-11-30 17:23:04 +08:00
parent 152682ed57
commit 1a8d717c29
9 changed files with 311 additions and 127 deletions

View File

@ -1,6 +1,7 @@
menuconfig DRM_ROCKCHIP
bool "Rockchip DRM Support"
depends on DM_VIDEO && OF_LIVE
select VIDEO_BRIDGE
help
Rockchip SoCs provide video output capabilities for High-Definition
Multimedia Interface (HDMI), Low-voltage Differential Signalling

View File

@ -4,7 +4,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
obj-y += rockchip_display.o rockchip_crtc.o rockchip_phy.o \
obj-y += rockchip_display.o rockchip_crtc.o rockchip_phy.o rockchip_bridge.o \
rockchip_vop.o rockchip_vop_reg.o bmp_helper.o
obj-$(CONFIG_DRM_ROCKCHIP_MIPI_DSI) += rockchip_mipi_dsi.o

View File

@ -0,0 +1,42 @@
// SPDX-License-Identifier: GPL-2.0+
/*
* (C) Copyright 2008-2018 Fuzhou Rockchip Electronics Co., Ltd
*/
#include "rockchip_bridge.h"
void rockchip_bridge_pre_enable(struct rockchip_bridge *bridge)
{
if (!bridge)
return;
if (bridge->funcs && bridge->funcs->pre_enable)
bridge->funcs->pre_enable(bridge);
}
void rockchip_bridge_post_disable(struct rockchip_bridge *bridge)
{
if (!bridge)
return;
if (bridge->funcs && bridge->funcs->post_disable)
bridge->funcs->post_disable(bridge);
}
void rockchip_bridge_enable(struct rockchip_bridge *bridge)
{
if (!bridge)
return;
if (bridge->funcs && bridge->funcs->enable)
bridge->funcs->enable(bridge);
}
void rockchip_bridge_disable(struct rockchip_bridge *bridge)
{
if (!bridge)
return;
if (bridge->funcs && bridge->funcs->disable)
bridge->funcs->disable(bridge);
}

View File

@ -0,0 +1,36 @@
/* SPDX-License-Identifier: GPL-2.0+ */
/*
* (C) Copyright 2008-2018 Fuzhou Rockchip Electronics Co., Ltd
*/
#ifndef _ROCKCHIP_BRIDGE_H_
#define _ROCKCHIP_BRIDGE_H_
#include <config.h>
#include <common.h>
#include <dm/device.h>
#include <errno.h>
struct display_state;
struct rockchip_bridge;
struct rockchip_bridge_funcs {
void (*enable)(struct rockchip_bridge *bridge);
void (*disable)(struct rockchip_bridge *bridge);
void (*pre_enable)(struct rockchip_bridge *bridge);
void (*post_disable)(struct rockchip_bridge *bridge);
};
struct rockchip_bridge {
struct udevice *dev;
const struct rockchip_bridge_funcs *funcs;
struct display_state *state;
};
void rockchip_bridge_enable(struct rockchip_bridge *bridge);
void rockchip_bridge_disable(struct rockchip_bridge *bridge);
void rockchip_bridge_pre_enable(struct rockchip_bridge *bridge);
void rockchip_bridge_post_disable(struct rockchip_bridge *bridge);
#endif

View File

@ -18,6 +18,7 @@
#include <malloc.h>
#include <video.h>
#include <video_rockchip.h>
#include <video_bridge.h>
#include <dm/device.h>
#include <dm/uclass-internal.h>
#include <asm/arch-rockchip/resource_img.h>
@ -26,6 +27,7 @@
#include "rockchip_display.h"
#include "rockchip_crtc.h"
#include "rockchip_connector.h"
#include "rockchip_bridge.h"
#include "rockchip_phy.h"
#include "rockchip_panel.h"
#include <dm.h>
@ -169,65 +171,6 @@ static bool can_direct_logo(int bpp)
return bpp == 24 || bpp == 32;
}
static struct udevice *get_panel_device(struct display_state *state, ofnode conn_node)
{
struct panel_state *panel_state = &state->panel_state;
struct udevice *dev;
struct connector_state *conn_state = &state->conn_state;
ofnode node, ports_node, port_node;
struct device_node *port, *panel, *ep;
int ph;
int ret;
node = dev_read_subnode(conn_state->dev, "panel");
if (ofnode_valid(node) &&
of_device_is_available(ofnode_to_np(node))) {
ret = uclass_get_device_by_ofnode(UCLASS_PANEL, node, &dev);
if (!ret) {
panel_state->node = node;
return dev;
}
}
/* TODO: this path not tested */
ports_node = dev_read_subnode(conn_state->dev, "ports");
if (!ofnode_valid(ports_node))
return NULL;
ofnode_for_each_subnode(port_node, ports_node) {
ofnode_for_each_subnode(node, port_node) {
ph = ofnode_read_u32_default(node, "remote-endpoint", -1);
if (!ph)
continue;
ep = of_find_node_by_phandle(ph);
if (!ofnode_valid(np_to_ofnode(ep))) {
printf("Warn: can't find endpoint from phdl\n");
continue;
}
port = of_get_parent(ep);
if (!ofnode_valid(np_to_ofnode(port))) {
printf("Warn: can't find port node\n");
continue;
}
panel = of_get_parent(port);
if (!ofnode_valid(np_to_ofnode(panel))) {
printf("Warn: can't find panel node\n");
continue;
}
ret = uclass_get_device_by_ofnode(UCLASS_PANEL,
np_to_ofnode(panel),
&dev);
if (!ret) {
panel_state->node = np_to_ofnode(panel);
return dev;
}
}
}
return NULL;
}
static int connector_phy_init(struct display_state *state,
struct public_phy_data *data)
{
@ -292,27 +235,12 @@ static int connector_panel_init(struct display_state *state)
{
struct connector_state *conn_state = &state->conn_state;
struct panel_state *panel_state = &state->panel_state;
struct udevice *dev;
ofnode conn_node = conn_state->node;
const struct rockchip_panel *panel;
const struct rockchip_panel *panel = panel_state->panel;
ofnode dsp_lut_node;
int ret, len;
dm_scan_fdt_dev(conn_state->dev);
dev = get_panel_device(state, conn_node);
if (!dev) {
if (!panel)
return 0;
}
panel = (const struct rockchip_panel *)dev_get_driver_data(dev);
if (!panel) {
printf("failed to find panel driver\n");
return 0;
}
panel_state->dev = dev;
panel_state->panel = panel;
if (panel->funcs && panel->funcs->init) {
ret = panel->funcs->init(state);
@ -322,7 +250,7 @@ static int connector_panel_init(struct display_state *state)
}
}
dsp_lut_node = dev_read_subnode(dev, "dsp-lut");
dsp_lut_node = dev_read_subnode(panel->dev, "dsp-lut");
if (!ofnode_valid(dsp_lut_node)) {
debug("%s can not find dsp-lut node\n", __func__);
return 0;
@ -379,6 +307,7 @@ int drm_mode_vrefresh(const struct drm_display_mode *mode)
static int display_get_timing_from_dts(struct panel_state *panel_state,
struct drm_display_mode *mode)
{
struct rockchip_panel *panel = panel_state->panel;
int phandle;
int hactive, vactive, pixelclock;
int hfront_porch, hback_porch, hsync_len;
@ -386,7 +315,7 @@ static int display_get_timing_from_dts(struct panel_state *panel_state,
int val, flags = 0;
ofnode timing, native_mode;
timing = dev_read_subnode(panel_state->dev, "display-timings");
timing = dev_read_subnode(panel->dev, "display-timings");
if (!ofnode_valid(timing))
return -ENODEV;
@ -585,11 +514,10 @@ static int display_get_timing(struct display_state *state)
const struct drm_display_mode *m;
struct panel_state *panel_state = &state->panel_state;
const struct rockchip_panel *panel = panel_state->panel;
const struct rockchip_panel_funcs *panel_funcs = panel->funcs;
ofnode panel_node = panel_state->node;
int ret;
if (ofnode_valid(panel_node) && !display_get_timing_from_dts(panel_state, mode)) {
if (dev_of_valid(panel->dev) &&
!display_get_timing_from_dts(panel_state, mode)) {
printf("Using display timing dts\n");
goto done;
}
@ -605,8 +533,8 @@ static int display_get_timing(struct display_state *state)
int panel_bits_per_colourp;
/* In order to read EDID, the panel needs to be powered on */
if (panel_funcs->prepare) {
ret = panel_funcs->prepare(state);
if (panel->funcs->prepare) {
ret = panel->funcs->prepare(state);
if (ret) {
printf("failed to prepare panel\n");
return ret;
@ -620,8 +548,8 @@ static int display_get_timing(struct display_state *state)
edid_print_info((void *)&conn_state->edid);
goto done;
} else {
if (panel_funcs->unprepare)
panel_funcs->unprepare(state);
if (panel->funcs->unprepare)
panel->funcs->unprepare(state);
}
}
@ -645,6 +573,7 @@ done:
static int display_init(struct display_state *state)
{
struct connector_state *conn_state = &state->conn_state;
struct panel_state *panel_state = &state->panel_state;
const struct rockchip_connector *conn = conn_state->connector;
const struct rockchip_connector_funcs *conn_funcs = conn->funcs;
struct crtc_state *crtc_state = &state->crtc_state;
@ -698,13 +627,24 @@ static int display_init(struct display_state *state)
if (conn_funcs->get_timing) {
ret = conn_funcs->get_timing(state);
if (ret)
goto deinit;
} else {
} else if (panel_state->panel) {
ret = display_get_timing(state);
} else if (conn_state->bridge) {
int bpc;
ret = video_bridge_read_edid(conn_state->bridge->dev,
conn_state->edid, EDID_SIZE);
if (ret > 0) {
ret = edid_get_drm_mode(conn_state->edid, ret, mode,
&bpc);
if (!ret)
edid_print_info((void *)&conn_state->edid);
}
}
if (ret)
goto deinit;
}
drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
if (crtc_funcs->init) {
@ -842,6 +782,9 @@ static int display_enable(struct display_state *state)
goto unprepare_crtc;
}
if (conn_state->bridge)
rockchip_bridge_pre_enable(conn_state->bridge);
display_panel_prepare(state);
if (crtc_funcs->enable) {
@ -856,6 +799,9 @@ static int display_enable(struct display_state *state)
goto disable_crtc;
}
if (conn_state->bridge)
rockchip_bridge_enable(conn_state->bridge);
display_panel_enable(state);
state->is_enable = true;
@ -890,14 +836,20 @@ static int display_disable(struct display_state *state)
display_panel_disable(state);
if (crtc_funcs->disable)
crtc_funcs->disable(state);
if (conn_state->bridge)
rockchip_bridge_disable(conn_state->bridge);
if (conn_funcs->disable)
conn_funcs->disable(state);
if (crtc_funcs->disable)
crtc_funcs->disable(state);
display_panel_unprepare(state);
if (conn_state->bridge)
rockchip_bridge_post_disable(conn_state->bridge);
if (conn_funcs->unprepare)
conn_funcs->unprepare(state);
@ -1232,6 +1184,126 @@ void rockchip_show_logo(void)
}
}
enum {
PORT_DIR_IN,
PORT_DIR_OUT,
};
static struct rockchip_panel *rockchip_of_find_panel(struct udevice *dev)
{
ofnode panel_node, ports, port, ep;
struct udevice *panel_dev;
int ret;
panel_node = dev_read_subnode(dev, "panel");
if (ofnode_valid(panel_node) && ofnode_is_available(panel_node)) {
ret = uclass_get_device_by_ofnode(UCLASS_PANEL, panel_node,
&panel_dev);
if (!ret)
goto found;
}
ports = dev_read_subnode(dev, "ports");
if (!ofnode_valid(ports))
return NULL;
ofnode_for_each_subnode(port, ports) {
u32 reg;
if (ofnode_read_u32(port, "reg", &reg))
continue;
if (reg != PORT_DIR_OUT)
continue;
ofnode_for_each_subnode(ep, port) {
ofnode _ep, _port;
uint phandle;
if (ofnode_read_u32(ep, "remote-endpoint", &phandle))
continue;
_ep = ofnode_get_by_phandle(phandle);
if (!ofnode_valid(_ep))
continue;
_port = ofnode_get_parent(_ep);
if (!ofnode_valid(_port))
continue;
panel_node = ofnode_get_parent(_port);
if (!ofnode_valid(panel_node))
continue;
ret = uclass_get_device_by_ofnode(UCLASS_PANEL,
panel_node,
&panel_dev);
if (!ret)
goto found;
}
}
return NULL;
found:
return (struct rockchip_panel *)dev_get_driver_data(panel_dev);
}
static struct rockchip_bridge *rockchip_of_find_bridge(struct udevice *conn_dev)
{
ofnode node, ports, port, ep;
struct udevice *dev;
int ret;
ports = dev_read_subnode(conn_dev, "ports");
if (!ofnode_valid(ports))
return NULL;
ofnode_for_each_subnode(port, ports) {
u32 reg;
if (ofnode_read_u32(port, "reg", &reg))
continue;
if (reg != PORT_DIR_OUT)
continue;
ofnode_for_each_subnode(ep, port) {
ofnode _ep, _port, _ports;
uint phandle;
if (ofnode_read_u32(ep, "remote-endpoint", &phandle))
continue;
_ep = ofnode_get_by_phandle(phandle);
if (!ofnode_valid(_ep))
continue;
_port = ofnode_get_parent(_ep);
if (!ofnode_valid(_port))
continue;
_ports = ofnode_get_parent(_port);
if (!ofnode_valid(_ports))
continue;
node = ofnode_get_parent(_ports);
if (!ofnode_valid(node))
continue;
ret = uclass_get_device_by_ofnode(UCLASS_VIDEO_BRIDGE,
node, &dev);
if (!ret)
goto found;
}
}
return NULL;
found:
return (struct rockchip_bridge *)dev_get_driver_data(dev);
}
static struct udevice *rockchip_of_find_connector(ofnode endpoint)
{
ofnode ep, port, ports, conn;
@ -1274,6 +1346,8 @@ static int rockchip_display_probe(struct udevice *dev)
struct udevice *crtc_dev, *conn_dev;
struct rockchip_crtc *crtc;
const struct rockchip_connector *conn;
struct rockchip_panel *panel = NULL;
struct rockchip_bridge *bridge = NULL;
struct display_state *s;
const char *name;
int ret;
@ -1338,6 +1412,12 @@ static int rockchip_display_probe(struct udevice *dev)
conn = (const struct rockchip_connector *)dev_get_driver_data(conn_dev);
bridge = rockchip_of_find_bridge(conn_dev);
if (bridge)
panel = rockchip_of_find_panel(bridge->dev);
else
panel = rockchip_of_find_panel(conn_dev);
s = malloc(sizeof(*s));
if (!s)
continue;
@ -1363,9 +1443,11 @@ static int rockchip_display_probe(struct udevice *dev)
s->charge_logo_mode = ROCKCHIP_DISPLAY_CENTER;
s->blob = blob;
s->panel_state.panel = panel;
s->conn_state.node = conn_dev->node;
s->conn_state.dev = conn_dev;
s->conn_state.connector = conn;
s->conn_state.bridge = bridge;
s->conn_state.overscan.left_margin = 100;
s->conn_state.overscan.right_margin = 100;
s->conn_state.overscan.top_margin = 100;
@ -1375,6 +1457,10 @@ static int rockchip_display_probe(struct udevice *dev)
s->crtc_state.crtc = crtc;
s->crtc_state.crtc_id = get_crtc_id(np_to_ofnode(ep_node));
s->node = node;
if (bridge)
bridge->state = s;
get_crtc_mcu_mode(&s->crtc_state);
if (connector_panel_init(s)) {

View File

@ -87,12 +87,9 @@ struct crtc_state {
};
struct panel_state {
struct udevice *dev;
ofnode node;
ofnode dsp_lut_node;
struct rockchip_panel *panel;
const struct rockchip_panel *panel;
void *private;
ofnode dsp_lut_node;
};
struct overscan {
@ -105,6 +102,7 @@ struct overscan {
struct connector_state {
struct udevice *dev;
const struct rockchip_connector *connector;
struct rockchip_bridge *bridge;
struct udevice *phy_dev;
struct rockchip_phy *phy;
ofnode node;
@ -167,6 +165,13 @@ struct display_state {
int is_enable;
};
static inline struct rockchip_panel *state_get_panel(struct display_state *s)
{
struct panel_state *panel_state = &s->panel_state;
return panel_state->panel;
}
int drm_mode_vrefresh(const struct drm_display_mode *mode);
int display_send_mcu_cmd(struct display_state *state, u32 type, u32 val);
bool drm_mode_is_420(const struct drm_display_info *display,

View File

@ -23,6 +23,7 @@
#include "rockchip_display.h"
#include "rockchip_crtc.h"
#include "rockchip_connector.h"
#include "rockchip_panel.h"
#include "rockchip_lvds.h"
enum rockchip_lvds_sub_devtype {
@ -524,8 +525,7 @@ static int rockchip_lvds_init(struct display_state *state)
const char *name;
int i, width;
struct resource lvds_phy, lvds_ctrl;
struct panel_state *panel_state = &state->panel_state;
ofnode panel_node = panel_state->node;
struct rockchip_panel *panel = state_get_panel(state);
int ret;
lvds = malloc(sizeof(*lvds));
@ -561,7 +561,7 @@ static int rockchip_lvds_init(struct display_state *state)
return -ENXIO;
}
ret = dev_read_string_index(panel_state->dev, "rockchip,output", 0, &name);
ret = dev_read_string_index(panel->dev, "rockchip,output", 0, &name);
if (ret)
/* default set it as output rgb */
lvds->output = DISPLAY_OUTPUT_RGB;
@ -572,7 +572,8 @@ static int rockchip_lvds_init(struct display_state *state)
free(lvds);
return lvds->output;
}
ret = dev_read_string_index(panel_state->dev, "rockchip,data-mapping", 0, &name);
ret = dev_read_string_index(panel->dev, "rockchip,data-mapping",
0, &name);
if (ret)
/* default set it as format jeida */
lvds->format = LVDS_FORMAT_JEIDA;
@ -584,7 +585,7 @@ static int rockchip_lvds_init(struct display_state *state)
free(lvds);
return lvds->format;
}
width = ofnode_read_u32_default(panel_node, "rockchip,data-width", 24);
width = dev_read_u32_default(panel->dev, "rockchip,data-width", 24);
if (width == 24) {
lvds->format |= LVDS_24BIT;
} else if (width == 18) {

View File

@ -183,8 +183,8 @@ static int rockchip_panel_send_mcu_cmds(struct display_state *state,
static int rockchip_panel_send_spi_cmds(struct display_state *state,
struct rockchip_panel_cmds *cmds)
{
struct panel_state *panel_state = &state->panel_state;
struct rockchip_panel_priv *priv = dev_get_priv(panel_state->dev);
struct rockchip_panel *panel = state_get_panel(state);
struct rockchip_panel_priv *priv = dev_get_priv(panel->dev);
int i;
if (!cmds)
@ -253,9 +253,9 @@ static int rockchip_panel_send_dsi_cmds(struct display_state *state,
static int rockchip_panel_prepare(struct display_state *state)
{
struct panel_state *panel_state = &state->panel_state;
struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel_state->dev);
struct rockchip_panel *panel = state_get_panel(state);
struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel->dev);
int ret;
if (priv->prepared)
@ -299,9 +299,9 @@ static int rockchip_panel_prepare(struct display_state *state)
static void rockchip_panel_unprepare(struct display_state *state)
{
struct panel_state *panel_state = &state->panel_state;
struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel_state->dev);
struct rockchip_panel *panel = state_get_panel(state);
struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel->dev);
int ret;
if (!priv->prepared)
@ -338,9 +338,9 @@ static void rockchip_panel_unprepare(struct display_state *state)
static int rockchip_panel_enable(struct display_state *state)
{
struct panel_state *panel_state = &state->panel_state;
struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel_state->dev);
struct rockchip_panel *panel = state_get_panel(state);
struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel->dev);
if (priv->enabled)
return 0;
@ -357,9 +357,9 @@ static int rockchip_panel_enable(struct display_state *state)
static void rockchip_panel_disable(struct display_state *state)
{
struct panel_state *panel_state = &state->panel_state;
struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel_state->dev);
struct rockchip_panel *panel = state_get_panel(state);
struct rockchip_panel_plat *plat = dev_get_platdata(panel->dev);
struct rockchip_panel_priv *priv = dev_get_priv(panel->dev);
if (!priv->enabled)
return;
@ -375,10 +375,9 @@ static void rockchip_panel_disable(struct display_state *state)
static int rockchip_panel_init(struct display_state *state)
{
struct connector_state *conn_state = &state->conn_state;
struct panel_state *panel_state = &state->panel_state;
struct rockchip_panel_plat *plat = dev_get_platdata(panel_state->dev);
struct rockchip_panel *panel = state_get_panel(state);
conn_state->bus_format = plat->bus_format;
conn_state->bus_format = panel->bus_format;
return 0;
}
@ -450,6 +449,9 @@ free_on_cmds:
static int rockchip_panel_probe(struct udevice *dev)
{
struct rockchip_panel_priv *priv = dev_get_priv(dev);
struct rockchip_panel_plat *plat = dev_get_platdata(dev);
struct rockchip_panel *panel =
(struct rockchip_panel *)dev_get_driver_data(dev);
int ret;
const char *cmd_type;
@ -515,6 +517,9 @@ static int rockchip_panel_probe(struct udevice *dev)
dm_gpio_set_value(&priv->reset_gpio, 0);
}
panel->dev = dev;
panel->bus_format = plat->bus_format;
return 0;
}
@ -532,7 +537,7 @@ static const struct drm_display_mode auo_b125han03_mode = {
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
static const struct rockchip_panel auo_b125han03_data = {
static const struct rockchip_panel auo_b125han03_driver_data = {
.funcs = &rockchip_panel_funcs,
.data = &auo_b125han03_mode,
};
@ -551,28 +556,32 @@ static const struct drm_display_mode lg_lp079qx1_sp0v_mode = {
.flags = DRM_MODE_FLAG_NVSYNC | DRM_MODE_FLAG_NHSYNC,
};
static const struct rockchip_panel lg_lp079qx1_sp0v_data = {
static const struct rockchip_panel lg_lp079qx1_sp0v_driver_data = {
.funcs = &rockchip_panel_funcs,
.data = &lg_lp079qx1_sp0v_mode,
};
static const struct rockchip_panel rockchip_panel_data = {
static const struct rockchip_panel panel_simple_driver_data = {
.funcs = &rockchip_panel_funcs,
};
static const struct rockchip_panel panel_simple_dsi_driver_data = {
.funcs = &rockchip_panel_funcs,
};
static const struct udevice_id rockchip_panel_ids[] = {
{
.compatible = "auo,b125han03",
.data = (ulong)&auo_b125han03_data,
.data = (ulong)&auo_b125han03_driver_data,
}, {
.compatible = "lg,lp079qx1-sp0v",
.data = (ulong)&lg_lp079qx1_sp0v_data,
.data = (ulong)&lg_lp079qx1_sp0v_driver_data,
}, {
.compatible = "simple-panel",
.data = (ulong)&rockchip_panel_data,
.data = (ulong)&panel_simple_driver_data,
}, {
.compatible = "simple-panel-dsi",
.data = (ulong)&rockchip_panel_data,
.data = (ulong)&panel_simple_dsi_driver_data,
},
{}
};

View File

@ -7,6 +7,8 @@
#ifndef _ROCKCHIP_PANEL_H_
#define _ROCKCHIP_PANEL_H_
struct display_state;
struct rockchip_panel_funcs {
int (*init)(struct display_state *state);
void (*deinit)(struct display_state *state);
@ -17,6 +19,8 @@ struct rockchip_panel_funcs {
};
struct rockchip_panel {
struct udevice *dev;
u32 bus_format;
const struct rockchip_panel_funcs *funcs;
const void *data;
};