drm/rockchip: lvds: Set lvds dual channel according to "dual-channel" property from DT

Change-Id: I5ee46c0fe197fe9b22e3485e973875f81e2f2f9e
Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
This commit is contained in:
Wyon Bi
2019-01-03 08:36:29 +08:00
committed by Tao Huang
parent b46f1487be
commit 157f85929e
2 changed files with 13 additions and 114 deletions

View File

@@ -33,7 +33,6 @@
#include "rockchip_drm_drv.h"
#include "rockchip_drm_vop.h"
#include "rockchip_lvds.h"
#define HIWORD_UPDATE(v, h, l) (((v) << (l)) | (GENMASK(h, l) << 16))
@@ -72,9 +71,6 @@
#define RK3368_LVDS_MSBSEL(x) HIWORD_UPDATE(x, 11, 11)
#define RK3368_LVDS_P2S_EN(x) HIWORD_UPDATE(x, 6, 6)
#define DISPLAY_OUTPUT_LVDS 1
#define DISPLAY_OUTPUT_DUAL_LVDS 2
enum lvds_format {
LVDS_8BIT_MODE_FORMAT_1,
LVDS_8BIT_MODE_FORMAT_2,
@@ -94,10 +90,9 @@ struct rockchip_lvds {
struct phy *phy;
struct regmap *grf;
const struct rockchip_lvds_funcs *funcs;
enum lvds_format format;
bool data_swap;
int output;
bool dual_channel;
struct drm_panel *panel;
struct drm_bridge *bridge;
@@ -106,19 +101,6 @@ struct rockchip_lvds {
struct drm_display_mode mode;
};
static inline int lvds_name_to_output(const char *s)
{
if (!s)
return -EINVAL;
if (strncmp(s, "lvds", 4) == 0)
return DISPLAY_OUTPUT_LVDS;
else if (strncmp(s, "duallvds", 8) == 0)
return DISPLAY_OUTPUT_DUAL_LVDS;
return -EINVAL;
}
static inline struct rockchip_lvds *connector_to_lvds(struct drm_connector *c)
{
return container_of(c, struct rockchip_lvds, connector);
@@ -285,67 +267,21 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
struct drm_device *drm_dev = data;
struct drm_encoder *encoder = &lvds->encoder;
struct drm_connector *connector = &lvds->connector;
struct device_node *remote = NULL;
struct device_node *port, *endpoint;
int ret;
const char *name;
port = of_graph_get_port_by_id(dev->of_node, 1);
if (!port) {
dev_err(dev, "can't found port point, please init lvds panel port!\n");
return -EINVAL;
}
for_each_child_of_node(port, endpoint) {
remote = of_graph_get_remote_port_parent(endpoint);
if (!remote) {
dev_err(dev, "can't found panel node, please init!\n");
ret = -EINVAL;
goto err_put_port;
}
if (!of_device_is_available(remote)) {
of_node_put(remote);
remote = NULL;
continue;
}
break;
}
if (!remote) {
dev_err(dev, "can't found remote node, please init!\n");
ret = -EINVAL;
goto err_put_port;
}
lvds->panel = of_drm_find_panel(remote);
if (!lvds->panel)
lvds->bridge = of_drm_find_bridge(remote);
if (!lvds->panel && !lvds->bridge) {
DRM_ERROR("failed to find panel and bridge node\n");
ret = -EPROBE_DEFER;
goto err_put_remote;
}
if (of_property_read_string(remote, "rockchip,output", &name))
lvds->output = DISPLAY_OUTPUT_LVDS;
else
lvds->output = lvds_name_to_output(name);
if (lvds->output < 0) {
dev_err(dev, "invalid output type [%s]\n", name);
ret = lvds->output;
goto err_put_remote;
}
ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
&lvds->panel, &lvds->bridge);
if (ret)
return ret;
encoder->port = dev->of_node;
encoder->possible_crtcs = drm_of_find_possible_crtcs(drm_dev,
dev->of_node);
ret = drm_encoder_init(drm_dev, encoder, &rockchip_lvds_encoder_funcs,
DRM_MODE_ENCODER_LVDS, NULL);
if (ret < 0) {
DRM_ERROR("failed to initialize encoder with drm\n");
goto err_put_remote;
return ret;
}
drm_encoder_helper_add(encoder, &rockchip_lvds_encoder_helper_funcs);
@@ -367,33 +303,25 @@ static int rockchip_lvds_bind(struct device *dev, struct device *master,
ret = drm_panel_attach(lvds->panel, connector);
if (ret < 0) {
DRM_ERROR("failed to attach connector and encoder\n");
DRM_ERROR("failed to attach panel: %d\n", ret);
goto err_free_connector;
}
} else {
lvds->bridge->encoder = encoder;
ret = drm_bridge_attach(drm_dev, lvds->bridge);
if (ret) {
DRM_ERROR("Failed to attach bridge to drm\n");
DRM_ERROR("Failed to attach bridge: %d\n", ret);
goto err_free_encoder;
}
encoder->bridge = lvds->bridge;
}
of_node_put(remote);
of_node_put(port);
return 0;
err_free_connector:
drm_connector_cleanup(connector);
err_free_encoder:
drm_encoder_cleanup(encoder);
err_put_remote:
of_node_put(remote);
err_put_port:
of_node_put(port);
return ret;
}
@@ -429,6 +357,8 @@ static int rockchip_lvds_probe(struct platform_device *pdev)
lvds->funcs = of_device_get_match_data(dev);
platform_set_drvdata(pdev, lvds);
lvds->dual_channel = of_property_read_bool(dev->of_node,
"dual-channel");
lvds->data_swap = of_property_read_bool(dev->of_node,
"rockchip,data-swap");
@@ -500,24 +430,18 @@ static void rk3288_lvds_enable(struct rockchip_lvds *lvds)
{
struct drm_display_mode *mode = &lvds->mode;
int pipe;
bool dual_channel;
u32 val;
if (lvds->output == DISPLAY_OUTPUT_DUAL_LVDS)
dual_channel = true;
else
dual_channel = false;
pipe = drm_of_encoder_active_endpoint_id(lvds->dev->of_node,
&lvds->encoder);
regmap_write(lvds->grf, RK3288_GRF_SOC_CON6,
RK3288_LVDS_LCDC_SEL(pipe));
val = RK3288_LVDS_PWRDWN(0) | RK3288_LVDS_CON_CLKINV(0) |
RK3288_LVDS_CON_CHASEL(dual_channel) |
RK3288_LVDS_CON_CHASEL(lvds->dual_channel) |
RK3288_LVDS_CON_SELECT(lvds->format);
if (dual_channel) {
if (lvds->dual_channel) {
u32 h_bp = mode->htotal - mode->hsync_start;
val |= RK3288_LVDS_CON_ENABLE_2(1) |
@@ -536,7 +460,7 @@ static void rk3288_lvds_enable(struct rockchip_lvds *lvds)
regmap_write(lvds->grf, RK3288_GRF_SOC_CON7, val);
phy_set_bus_width(lvds->phy, dual_channel ? 2 : 1);
phy_set_bus_width(lvds->phy, lvds->dual_channel ? 2 : 1);
}
static void rk3288_lvds_disable(struct rockchip_lvds *lvds)

View File

@@ -1,25 +0,0 @@
/*
* Copyright (C) Fuzhou Rockchip Electronics Co.Ltd
* Author:
* hjc <hjc@rock-chips.com>
* mark yao <mark.yao@rock-chips.com>
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*/
#ifndef _ROCKCHIP_LVDS_
#define _ROCKCHIP_LVDS_
#define LVDS_24BIT (0 << 1)
#define LVDS_18BIT (1 << 1)
#define LVDS_FORMAT_VESA (0 << 0)
#define LVDS_FORMAT_JEIDA (1 << 0)
#endif /* _ROCKCHIP_LVDS_ */