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:
parent
152682ed57
commit
1a8d717c29
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
@ -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
|
||||
|
|
@ -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", ®))
|
||||
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", ®))
|
||||
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)) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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) {
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
},
|
||||
{}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
};
|
||||
|
|
|
|||
Loading…
Reference in New Issue