mirror of
https://github.com/hardkernel/linux.git
synced 2026-06-08 20:07:46 +09:00
drm/bridge: parade-ps8622: fix some usage to make it work on rockchip platform
Change-Id: Ia8dd97389f6e532141bba501a9d75feb264ebc53 Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
This commit is contained in:
@@ -11,21 +11,42 @@ Optional properties:
|
||||
- use-external-pwm: backlight will be controlled by an external PWM
|
||||
- video interfaces: Device node can contain video interface port
|
||||
nodes for panel according to [1].
|
||||
- dual-channel: boolean. if it exists, enable dual channel mode
|
||||
|
||||
[1]: Documentation/devicetree/bindings/media/video-interfaces.txt
|
||||
|
||||
Example:
|
||||
lvds-bridge@48 {
|
||||
compatible = "parade,ps8622";
|
||||
|
||||
&i2c4 {
|
||||
status = "okay";
|
||||
|
||||
ps8625: ps8625@48 {
|
||||
compatible = "parade,ps8625";
|
||||
reg = <0x48>;
|
||||
sleep-gpios = <&gpc3 6 1 0 0>;
|
||||
reset-gpios = <&gpc3 1 1 0 0>;
|
||||
lane-count = <1>;
|
||||
sleep-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
|
||||
reset-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>;
|
||||
lane-count = <2>;
|
||||
use-external-pwm;
|
||||
|
||||
ports {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
|
||||
port@0 {
|
||||
bridge_out: endpoint {
|
||||
remote-endpoint = <&panel_in>;
|
||||
reg = <0>;
|
||||
|
||||
ps8625_in_edp: endpoint {
|
||||
remote-endpoint = <&edp_out_ps8625>;
|
||||
};
|
||||
};
|
||||
|
||||
port@1 {
|
||||
reg = <1>;
|
||||
|
||||
ps8625_out_panel: endpoint {
|
||||
remote-endpoint = <&panel_in_ps8625>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
@@ -28,6 +28,7 @@
|
||||
#include <linux/regulator/consumer.h>
|
||||
|
||||
#include <drm/drm_panel.h>
|
||||
#include <drm/drm_of.h>
|
||||
|
||||
#include "drmP.h"
|
||||
#include "drm_crtc.h"
|
||||
@@ -64,6 +65,8 @@ struct ps8622_bridge {
|
||||
|
||||
u32 max_lane_count;
|
||||
u32 lane_count;
|
||||
u32 bus_format;
|
||||
bool dual_channel;
|
||||
|
||||
bool enabled;
|
||||
};
|
||||
@@ -102,6 +105,7 @@ static int ps8622_set(struct i2c_client *client, u8 page, u8 reg, u8 val)
|
||||
static int ps8622_send_config(struct ps8622_bridge *ps8622)
|
||||
{
|
||||
struct i2c_client *cl = ps8622->client;
|
||||
u8 format;
|
||||
int err = 0;
|
||||
|
||||
/* HPD low */
|
||||
@@ -305,8 +309,22 @@ static int ps8622_send_config(struct ps8622_bridge *ps8622)
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Set LVDS output as 6bit-VESA mapping, single LVDS channel */
|
||||
err = ps8622_set(cl, 0x01, 0xcc, 0x13);
|
||||
switch (ps8622->bus_format) {
|
||||
case MEDIA_BUS_FMT_RGB666_1X7X3_SPWG:
|
||||
format = 0x03;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_RGB888_1X7X4_JEIDA:
|
||||
format = 0x01;
|
||||
break;
|
||||
case MEDIA_BUS_FMT_RGB888_1X7X4_SPWG:
|
||||
default:
|
||||
format = 0x00;
|
||||
break;
|
||||
}
|
||||
|
||||
/* Set LVDS color depth, data mapping and single/dual link */
|
||||
err = ps8622_set(cl, 0x01, 0xcc, 0x10 | (ps8622->dual_channel << 2) |
|
||||
format);
|
||||
if (err)
|
||||
goto error;
|
||||
|
||||
@@ -467,11 +485,22 @@ static void ps8622_post_disable(struct drm_bridge *bridge)
|
||||
|
||||
static int ps8622_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct ps8622_bridge *ps8622;
|
||||
struct ps8622_bridge *ps8622 = connector_to_ps8622(connector);
|
||||
struct drm_display_info *info = &connector->display_info;
|
||||
u32 bus_format = MEDIA_BUS_FMT_RGB888_1X24;
|
||||
int num_modes = 0;
|
||||
|
||||
ps8622 = connector_to_ps8622(connector);
|
||||
num_modes = drm_panel_get_modes(ps8622->panel);
|
||||
|
||||
return drm_panel_get_modes(ps8622->panel);
|
||||
if (info->num_bus_formats)
|
||||
ps8622->bus_format = info->bus_formats[0];
|
||||
else
|
||||
ps8622->bus_format = MEDIA_BUS_FMT_RGB888_1X7X4_SPWG;
|
||||
|
||||
drm_display_info_set_bus_formats(&connector->display_info,
|
||||
&bus_format, 1);
|
||||
|
||||
return num_modes;
|
||||
}
|
||||
|
||||
static struct drm_encoder *ps8622_best_encoder(struct drm_connector *connector)
|
||||
@@ -519,6 +548,7 @@ static int ps8622_attach(struct drm_bridge *bridge)
|
||||
return -ENODEV;
|
||||
}
|
||||
|
||||
ps8622->connector.port = ps8622->client->dev.of_node;
|
||||
ps8622->connector.polled = DRM_CONNECTOR_POLL_HPD;
|
||||
ret = drm_connector_init(bridge->dev, &ps8622->connector,
|
||||
&ps8622_connector_funcs, DRM_MODE_CONNECTOR_LVDS);
|
||||
@@ -528,7 +558,6 @@ static int ps8622_attach(struct drm_bridge *bridge)
|
||||
}
|
||||
drm_connector_helper_add(&ps8622->connector,
|
||||
&ps8622_connector_helper_funcs);
|
||||
drm_connector_register(&ps8622->connector);
|
||||
drm_mode_connector_attach_encoder(&ps8622->connector,
|
||||
bridge->encoder);
|
||||
|
||||
@@ -559,7 +588,6 @@ static int ps8622_probe(struct i2c_client *client,
|
||||
const struct i2c_device_id *id)
|
||||
{
|
||||
struct device *dev = &client->dev;
|
||||
struct device_node *endpoint, *panel_node;
|
||||
struct ps8622_bridge *ps8622;
|
||||
int ret;
|
||||
|
||||
@@ -567,19 +595,16 @@ static int ps8622_probe(struct i2c_client *client,
|
||||
if (!ps8622)
|
||||
return -ENOMEM;
|
||||
|
||||
endpoint = of_graph_get_next_endpoint(dev->of_node, NULL);
|
||||
if (endpoint) {
|
||||
panel_node = of_graph_get_remote_port_parent(endpoint);
|
||||
if (panel_node) {
|
||||
ps8622->panel = of_drm_find_panel(panel_node);
|
||||
of_node_put(panel_node);
|
||||
if (!ps8622->panel)
|
||||
return -EPROBE_DEFER;
|
||||
}
|
||||
}
|
||||
ret = drm_of_find_panel_or_bridge(dev->of_node, 1, -1,
|
||||
&ps8622->panel, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
ps8622->client = client;
|
||||
|
||||
ps8622->dual_channel = of_property_read_bool(dev->of_node,
|
||||
"dual-channel");
|
||||
|
||||
ps8622->v12 = devm_regulator_get(dev, "vdd12");
|
||||
if (IS_ERR(ps8622->v12)) {
|
||||
dev_info(dev, "no 1.2v regulator found for PS8622\n");
|
||||
|
||||
Reference in New Issue
Block a user