Merge branch 'upstream/analogix-dp-20160705' of git://github.com/yakir-Yang/linux into drm-next
Please consider merging this tag, which contains the v4 misc fixes and add RK3399 eDP support patches[0] I sent on 2016-06-29, rebased onto v4.7-rc5. * 'upstream/analogix-dp-20160705' of git://github.com/yakir-Yang/linux: dt-bindings: analogix_dp: rockchip: correct the wrong compatible name drm/rockchip: analogix_dp: introduce the pclk for grf drm/bridge: analogix_dp: fix no drm hpd event when panel plug in drm/rockchip: analogix_dp: update the comments about why need to hardcode VOP output mode drm/rockchip: analogix_dp: correct the connector display color format and bpc drm/bridge: analogix_dp: passing the connector as an argument in .get_modes() drm/rockchip: analogix_dp: make panel detect to an optional action drm/rockchip: analogix_dp: add rk3399 eDP support drm/bridge: analogix_dp: some rockchip chips need to flip REF_CLK bit setting drm/bridge: analogix_dp: correct the register bit define error in ANALOGIX_DP_PLL_REG_1 drm/rockchip: analogix_dp: split the lcdc select setting into device data
This commit is contained in:
@@ -5,6 +5,7 @@ Required properties for dp-controller:
|
|||||||
platform specific such as:
|
platform specific such as:
|
||||||
* "samsung,exynos5-dp"
|
* "samsung,exynos5-dp"
|
||||||
* "rockchip,rk3288-dp"
|
* "rockchip,rk3288-dp"
|
||||||
|
* "rockchip,rk3399-edp"
|
||||||
-reg:
|
-reg:
|
||||||
physical base address of the controller and length
|
physical base address of the controller and length
|
||||||
of memory mapped region.
|
of memory mapped region.
|
||||||
|
@@ -2,7 +2,8 @@ Rockchip RK3288 specific extensions to the Analogix Display Port
|
|||||||
================================
|
================================
|
||||||
|
|
||||||
Required properties:
|
Required properties:
|
||||||
- compatible: "rockchip,rk3288-edp";
|
- compatible: "rockchip,rk3288-dp",
|
||||||
|
"rockchip,rk3399-edp";
|
||||||
|
|
||||||
- reg: physical base address of the controller and length
|
- reg: physical base address of the controller and length
|
||||||
|
|
||||||
@@ -27,6 +28,12 @@ Required properties:
|
|||||||
Port 0: contained 2 endpoints, connecting to the output of vop.
|
Port 0: contained 2 endpoints, connecting to the output of vop.
|
||||||
Port 1: contained 1 endpoint, connecting to the input of panel.
|
Port 1: contained 1 endpoint, connecting to the input of panel.
|
||||||
|
|
||||||
|
Optional property for different chips:
|
||||||
|
- clocks: from common clock binding: handle to grf_vio clock.
|
||||||
|
|
||||||
|
- clock-names: from common clock binding:
|
||||||
|
Required elements: "grf"
|
||||||
|
|
||||||
For the below properties, please refer to Analogix DP binding document:
|
For the below properties, please refer to Analogix DP binding document:
|
||||||
* Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
|
* Documentation/devicetree/bindings/drm/bridge/analogix_dp.txt
|
||||||
- phys (required)
|
- phys (required)
|
||||||
|
@@ -938,7 +938,7 @@ int analogix_dp_get_modes(struct drm_connector *connector)
|
|||||||
num_modes += drm_panel_get_modes(dp->plat_data->panel);
|
num_modes += drm_panel_get_modes(dp->plat_data->panel);
|
||||||
|
|
||||||
if (dp->plat_data->get_modes)
|
if (dp->plat_data->get_modes)
|
||||||
num_modes += dp->plat_data->get_modes(dp->plat_data);
|
num_modes += dp->plat_data->get_modes(dp->plat_data, connector);
|
||||||
|
|
||||||
return num_modes;
|
return num_modes;
|
||||||
}
|
}
|
||||||
@@ -1208,6 +1208,7 @@ static int analogix_dp_dt_parse_pdata(struct analogix_dp_device *dp)
|
|||||||
|
|
||||||
switch (dp->plat_data->dev_type) {
|
switch (dp->plat_data->dev_type) {
|
||||||
case RK3288_DP:
|
case RK3288_DP:
|
||||||
|
case RK3399_EDP:
|
||||||
/*
|
/*
|
||||||
* Like Rk3288 DisplayPort TRM indicate that "Main link
|
* Like Rk3288 DisplayPort TRM indicate that "Main link
|
||||||
* containing 4 physical lanes of 2.7/1.62 Gbps/lane".
|
* containing 4 physical lanes of 2.7/1.62 Gbps/lane".
|
||||||
|
@@ -127,10 +127,10 @@ enum analog_power_block {
|
|||||||
};
|
};
|
||||||
|
|
||||||
enum dp_irq_type {
|
enum dp_irq_type {
|
||||||
DP_IRQ_TYPE_HP_CABLE_IN,
|
DP_IRQ_TYPE_HP_CABLE_IN = BIT(0),
|
||||||
DP_IRQ_TYPE_HP_CABLE_OUT,
|
DP_IRQ_TYPE_HP_CABLE_OUT = BIT(1),
|
||||||
DP_IRQ_TYPE_HP_CHANGE,
|
DP_IRQ_TYPE_HP_CHANGE = BIT(2),
|
||||||
DP_IRQ_TYPE_UNKNOWN,
|
DP_IRQ_TYPE_UNKNOWN = BIT(3),
|
||||||
};
|
};
|
||||||
|
|
||||||
struct video_info {
|
struct video_info {
|
||||||
|
@@ -74,8 +74,12 @@ void analogix_dp_init_analog_param(struct analogix_dp_device *dp)
|
|||||||
reg = SEL_24M | TX_DVDD_BIT_1_0625V;
|
reg = SEL_24M | TX_DVDD_BIT_1_0625V;
|
||||||
writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
|
writel(reg, dp->reg_base + ANALOGIX_DP_ANALOG_CTL_2);
|
||||||
|
|
||||||
if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP)) {
|
if (dp->plat_data && is_rockchip(dp->plat_data->dev_type)) {
|
||||||
writel(REF_CLK_24M, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
|
reg = REF_CLK_24M;
|
||||||
|
if (dp->plat_data->dev_type == RK3288_DP)
|
||||||
|
reg ^= REF_CLK_MASK;
|
||||||
|
|
||||||
|
writel(reg, dp->reg_base + ANALOGIX_DP_PLL_REG_1);
|
||||||
writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
|
writel(0x95, dp->reg_base + ANALOGIX_DP_PLL_REG_2);
|
||||||
writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
|
writel(0x40, dp->reg_base + ANALOGIX_DP_PLL_REG_3);
|
||||||
writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
|
writel(0x58, dp->reg_base + ANALOGIX_DP_PLL_REG_4);
|
||||||
@@ -244,7 +248,7 @@ void analogix_dp_set_analog_power_down(struct analogix_dp_device *dp,
|
|||||||
u32 reg;
|
u32 reg;
|
||||||
u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
|
u32 phy_pd_addr = ANALOGIX_DP_PHY_PD;
|
||||||
|
|
||||||
if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
|
if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
|
||||||
phy_pd_addr = ANALOGIX_DP_PD;
|
phy_pd_addr = ANALOGIX_DP_PD;
|
||||||
|
|
||||||
switch (block) {
|
switch (block) {
|
||||||
@@ -448,7 +452,7 @@ void analogix_dp_init_aux(struct analogix_dp_device *dp)
|
|||||||
analogix_dp_reset_aux(dp);
|
analogix_dp_reset_aux(dp);
|
||||||
|
|
||||||
/* Disable AUX transaction H/W retry */
|
/* Disable AUX transaction H/W retry */
|
||||||
if (dp->plat_data && (dp->plat_data->dev_type == RK3288_DP))
|
if (dp->plat_data && is_rockchip(dp->plat_data->dev_type))
|
||||||
reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
|
reg = AUX_BIT_PERIOD_EXPECTED_DELAY(0) |
|
||||||
AUX_HW_RETRY_COUNT_SEL(3) |
|
AUX_HW_RETRY_COUNT_SEL(3) |
|
||||||
AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
|
AUX_HW_RETRY_INTERVAL_600_MICROSECONDS;
|
||||||
|
@@ -163,8 +163,9 @@
|
|||||||
#define HSYNC_POLARITY_CFG (0x1 << 0)
|
#define HSYNC_POLARITY_CFG (0x1 << 0)
|
||||||
|
|
||||||
/* ANALOGIX_DP_PLL_REG_1 */
|
/* ANALOGIX_DP_PLL_REG_1 */
|
||||||
#define REF_CLK_24M (0x1 << 1)
|
#define REF_CLK_24M (0x1 << 0)
|
||||||
#define REF_CLK_27M (0x0 << 1)
|
#define REF_CLK_27M (0x0 << 0)
|
||||||
|
#define REF_CLK_MASK (0x1 << 0)
|
||||||
|
|
||||||
/* ANALOGIX_DP_LANE_MAP */
|
/* ANALOGIX_DP_LANE_MAP */
|
||||||
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
|
#define LANE3_MAP_LOGIC_LANE_0 (0x0 << 6)
|
||||||
|
@@ -67,10 +67,10 @@ static int exynos_dp_poweroff(struct analogix_dp_plat_data *plat_data)
|
|||||||
return exynos_dp_crtc_clock_enable(plat_data, false);
|
return exynos_dp_crtc_clock_enable(plat_data, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data)
|
static int exynos_dp_get_modes(struct analogix_dp_plat_data *plat_data,
|
||||||
|
struct drm_connector *connector)
|
||||||
{
|
{
|
||||||
struct exynos_dp_device *dp = to_dp(plat_data);
|
struct exynos_dp_device *dp = to_dp(plat_data);
|
||||||
struct drm_connector *connector = dp->connector;
|
|
||||||
struct drm_display_mode *mode;
|
struct drm_display_mode *mode;
|
||||||
int num_modes = 0;
|
int num_modes = 0;
|
||||||
|
|
||||||
|
@@ -14,6 +14,7 @@
|
|||||||
|
|
||||||
#include <linux/component.h>
|
#include <linux/component.h>
|
||||||
#include <linux/mfd/syscon.h>
|
#include <linux/mfd/syscon.h>
|
||||||
|
#include <linux/of_device.h>
|
||||||
#include <linux/of_graph.h>
|
#include <linux/of_graph.h>
|
||||||
#include <linux/regmap.h>
|
#include <linux/regmap.h>
|
||||||
#include <linux/reset.h>
|
#include <linux/reset.h>
|
||||||
@@ -33,13 +34,28 @@
|
|||||||
#include "rockchip_drm_drv.h"
|
#include "rockchip_drm_drv.h"
|
||||||
#include "rockchip_drm_vop.h"
|
#include "rockchip_drm_vop.h"
|
||||||
|
|
||||||
|
#define RK3288_GRF_SOC_CON6 0x25c
|
||||||
|
#define RK3288_EDP_LCDC_SEL BIT(5)
|
||||||
|
#define RK3399_GRF_SOC_CON20 0x6250
|
||||||
|
#define RK3399_EDP_LCDC_SEL BIT(5)
|
||||||
|
|
||||||
|
#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
|
||||||
|
|
||||||
#define to_dp(nm) container_of(nm, struct rockchip_dp_device, nm)
|
#define to_dp(nm) container_of(nm, struct rockchip_dp_device, nm)
|
||||||
|
|
||||||
/* dp grf register offset */
|
/**
|
||||||
#define GRF_SOC_CON6 0x025c
|
* struct rockchip_dp_chip_data - splite the grf setting of kind of chips
|
||||||
#define GRF_EDP_LCD_SEL_MASK BIT(5)
|
* @lcdsel_grf_reg: grf register offset of lcdc select
|
||||||
#define GRF_EDP_SEL_VOP_LIT BIT(5)
|
* @lcdsel_big: reg value of selecting vop big for eDP
|
||||||
#define GRF_EDP_SEL_VOP_BIG 0
|
* @lcdsel_lit: reg value of selecting vop little for eDP
|
||||||
|
* @chip_type: specific chip type
|
||||||
|
*/
|
||||||
|
struct rockchip_dp_chip_data {
|
||||||
|
u32 lcdsel_grf_reg;
|
||||||
|
u32 lcdsel_big;
|
||||||
|
u32 lcdsel_lit;
|
||||||
|
u32 chip_type;
|
||||||
|
};
|
||||||
|
|
||||||
struct rockchip_dp_device {
|
struct rockchip_dp_device {
|
||||||
struct drm_device *drm_dev;
|
struct drm_device *drm_dev;
|
||||||
@@ -48,9 +64,12 @@ struct rockchip_dp_device {
|
|||||||
struct drm_display_mode mode;
|
struct drm_display_mode mode;
|
||||||
|
|
||||||
struct clk *pclk;
|
struct clk *pclk;
|
||||||
|
struct clk *grfclk;
|
||||||
struct regmap *grf;
|
struct regmap *grf;
|
||||||
struct reset_control *rst;
|
struct reset_control *rst;
|
||||||
|
|
||||||
|
const struct rockchip_dp_chip_data *data;
|
||||||
|
|
||||||
struct analogix_dp_plat_data plat_data;
|
struct analogix_dp_plat_data plat_data;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -92,6 +111,23 @@ static int rockchip_dp_powerdown(struct analogix_dp_plat_data *plat_data)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int rockchip_dp_get_modes(struct analogix_dp_plat_data *plat_data,
|
||||||
|
struct drm_connector *connector)
|
||||||
|
{
|
||||||
|
struct drm_display_info *di = &connector->display_info;
|
||||||
|
/* VOP couldn't output YUV video format for eDP rightly */
|
||||||
|
u32 mask = DRM_COLOR_FORMAT_YCRCB444 | DRM_COLOR_FORMAT_YCRCB422;
|
||||||
|
|
||||||
|
if ((di->color_formats & mask)) {
|
||||||
|
DRM_DEBUG_KMS("Swapping display color format from YUV to RGB\n");
|
||||||
|
di->color_formats &= ~mask;
|
||||||
|
di->color_formats |= DRM_COLOR_FORMAT_RGB444;
|
||||||
|
di->bpc = 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
|
rockchip_dp_drm_encoder_mode_fixup(struct drm_encoder *encoder,
|
||||||
const struct drm_display_mode *mode,
|
const struct drm_display_mode *mode,
|
||||||
@@ -119,17 +155,23 @@ static void rockchip_dp_drm_encoder_enable(struct drm_encoder *encoder)
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
if (ret)
|
if (ret)
|
||||||
val = GRF_EDP_SEL_VOP_LIT | (GRF_EDP_LCD_SEL_MASK << 16);
|
val = dp->data->lcdsel_lit;
|
||||||
else
|
else
|
||||||
val = GRF_EDP_SEL_VOP_BIG | (GRF_EDP_LCD_SEL_MASK << 16);
|
val = dp->data->lcdsel_big;
|
||||||
|
|
||||||
dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
|
dev_dbg(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
|
||||||
|
|
||||||
ret = regmap_write(dp->grf, GRF_SOC_CON6, val);
|
ret = clk_prepare_enable(dp->grfclk);
|
||||||
if (ret != 0) {
|
if (ret < 0) {
|
||||||
dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
|
dev_err(dp->dev, "failed to enable grfclk %d\n", ret);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = regmap_write(dp->grf, dp->data->lcdsel_grf_reg, val);
|
||||||
|
if (ret != 0)
|
||||||
|
dev_err(dp->dev, "Could not write to GRF: %d\n", ret);
|
||||||
|
|
||||||
|
clk_disable_unprepare(dp->grfclk);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
|
static void rockchip_dp_drm_encoder_nop(struct drm_encoder *encoder)
|
||||||
@@ -143,22 +185,29 @@ rockchip_dp_drm_encoder_atomic_check(struct drm_encoder *encoder,
|
|||||||
struct drm_connector_state *conn_state)
|
struct drm_connector_state *conn_state)
|
||||||
{
|
{
|
||||||
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
|
||||||
|
struct rockchip_dp_device *dp = to_dp(encoder);
|
||||||
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* FIXME(Yakir): driver should configure the CRTC output video
|
* The hardware IC designed that VOP must output the RGB10 video
|
||||||
* mode with the display information which indicated the monitor
|
* format to eDP controller, and if eDP panel only support RGB8,
|
||||||
* support colorimetry.
|
* then eDP controller should cut down the video data, not via VOP
|
||||||
*
|
* controller, that's why we need to hardcode the VOP output mode
|
||||||
* But don't know why the CRTC driver seems could only output the
|
* to RGA10 here.
|
||||||
* RGBaaa rightly. For example, if connect the "innolux,n116bge"
|
|
||||||
* eDP screen, EDID would indicated that screen only accepted the
|
|
||||||
* 6bpc mode. But if I configure CRTC to RGB666 output, then eDP
|
|
||||||
* screen would show a blue picture (RGB888 show a green picture).
|
|
||||||
* But if I configure CTRC to RGBaaa, and eDP driver still keep
|
|
||||||
* RGB666 input video mode, then screen would works prefect.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
s->output_mode = ROCKCHIP_OUT_MODE_AAAA;
|
||||||
s->output_type = DRM_MODE_CONNECTOR_eDP;
|
s->output_type = DRM_MODE_CONNECTOR_eDP;
|
||||||
|
if (dp->data->chip_type == RK3399_EDP) {
|
||||||
|
/*
|
||||||
|
* For RK3399, VOP Lit must code the out mode to RGB888,
|
||||||
|
* VOP Big must code the out mode to RGB10.
|
||||||
|
*/
|
||||||
|
ret = drm_of_encoder_active_endpoint_id(dp->dev->of_node,
|
||||||
|
encoder);
|
||||||
|
if (ret > 0)
|
||||||
|
s->output_mode = ROCKCHIP_OUT_MODE_P888;
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@@ -192,6 +241,16 @@ static int rockchip_dp_init(struct rockchip_dp_device *dp)
|
|||||||
return PTR_ERR(dp->grf);
|
return PTR_ERR(dp->grf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
dp->grfclk = devm_clk_get(dev, "grf");
|
||||||
|
if (PTR_ERR(dp->grfclk) == -ENOENT) {
|
||||||
|
dp->grfclk = NULL;
|
||||||
|
} else if (PTR_ERR(dp->grfclk) == -EPROBE_DEFER) {
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
} else if (IS_ERR(dp->grfclk)) {
|
||||||
|
dev_err(dev, "failed to get grf clock\n");
|
||||||
|
return PTR_ERR(dp->grfclk);
|
||||||
|
}
|
||||||
|
|
||||||
dp->pclk = devm_clk_get(dev, "pclk");
|
dp->pclk = devm_clk_get(dev, "pclk");
|
||||||
if (IS_ERR(dp->pclk)) {
|
if (IS_ERR(dp->pclk)) {
|
||||||
dev_err(dev, "failed to get pclk property\n");
|
dev_err(dev, "failed to get pclk property\n");
|
||||||
@@ -246,6 +305,7 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
|
|||||||
void *data)
|
void *data)
|
||||||
{
|
{
|
||||||
struct rockchip_dp_device *dp = dev_get_drvdata(dev);
|
struct rockchip_dp_device *dp = dev_get_drvdata(dev);
|
||||||
|
const struct rockchip_dp_chip_data *dp_data;
|
||||||
struct drm_device *drm_dev = data;
|
struct drm_device *drm_dev = data;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
@@ -256,10 +316,15 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
|
|||||||
*/
|
*/
|
||||||
dev_set_drvdata(dev, NULL);
|
dev_set_drvdata(dev, NULL);
|
||||||
|
|
||||||
|
dp_data = of_device_get_match_data(dev);
|
||||||
|
if (!dp_data)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
ret = rockchip_dp_init(dp);
|
ret = rockchip_dp_init(dp);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
dp->data = dp_data;
|
||||||
dp->drm_dev = drm_dev;
|
dp->drm_dev = drm_dev;
|
||||||
|
|
||||||
ret = rockchip_dp_drm_create_encoder(dp);
|
ret = rockchip_dp_drm_create_encoder(dp);
|
||||||
@@ -270,9 +335,10 @@ static int rockchip_dp_bind(struct device *dev, struct device *master,
|
|||||||
|
|
||||||
dp->plat_data.encoder = &dp->encoder;
|
dp->plat_data.encoder = &dp->encoder;
|
||||||
|
|
||||||
dp->plat_data.dev_type = RK3288_DP;
|
dp->plat_data.dev_type = dp->data->chip_type;
|
||||||
dp->plat_data.power_on = rockchip_dp_poweron;
|
dp->plat_data.power_on = rockchip_dp_poweron;
|
||||||
dp->plat_data.power_off = rockchip_dp_powerdown;
|
dp->plat_data.power_off = rockchip_dp_powerdown;
|
||||||
|
dp->plat_data.get_modes = rockchip_dp_get_modes;
|
||||||
|
|
||||||
return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
|
return analogix_dp_bind(dev, dp->drm_dev, &dp->plat_data);
|
||||||
}
|
}
|
||||||
@@ -292,38 +358,33 @@ static int rockchip_dp_probe(struct platform_device *pdev)
|
|||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *panel_node, *port, *endpoint;
|
struct device_node *panel_node, *port, *endpoint;
|
||||||
|
struct drm_panel *panel = NULL;
|
||||||
struct rockchip_dp_device *dp;
|
struct rockchip_dp_device *dp;
|
||||||
struct drm_panel *panel;
|
|
||||||
|
|
||||||
port = of_graph_get_port_by_id(dev->of_node, 1);
|
port = of_graph_get_port_by_id(dev->of_node, 1);
|
||||||
if (!port) {
|
if (port) {
|
||||||
dev_err(dev, "can't find output port\n");
|
endpoint = of_get_child_by_name(port, "endpoint");
|
||||||
return -EINVAL;
|
of_node_put(port);
|
||||||
}
|
if (!endpoint) {
|
||||||
|
dev_err(dev, "no output endpoint found\n");
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
||||||
endpoint = of_get_child_by_name(port, "endpoint");
|
panel_node = of_graph_get_remote_port_parent(endpoint);
|
||||||
of_node_put(port);
|
of_node_put(endpoint);
|
||||||
if (!endpoint) {
|
if (!panel_node) {
|
||||||
dev_err(dev, "no output endpoint found\n");
|
dev_err(dev, "no output node found\n");
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
panel_node = of_graph_get_remote_port_parent(endpoint);
|
panel = of_drm_find_panel(panel_node);
|
||||||
of_node_put(endpoint);
|
|
||||||
if (!panel_node) {
|
|
||||||
dev_err(dev, "no output node found\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
|
|
||||||
panel = of_drm_find_panel(panel_node);
|
|
||||||
if (!panel) {
|
|
||||||
DRM_ERROR("failed to find panel\n");
|
|
||||||
of_node_put(panel_node);
|
of_node_put(panel_node);
|
||||||
return -EPROBE_DEFER;
|
if (!panel) {
|
||||||
|
DRM_ERROR("failed to find panel\n");
|
||||||
|
return -EPROBE_DEFER;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
of_node_put(panel_node);
|
|
||||||
|
|
||||||
dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
|
dp = devm_kzalloc(dev, sizeof(*dp), GFP_KERNEL);
|
||||||
if (!dp)
|
if (!dp)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
@@ -356,8 +417,23 @@ static const struct dev_pm_ops rockchip_dp_pm_ops = {
|
|||||||
#endif
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static const struct rockchip_dp_chip_data rk3399_edp = {
|
||||||
|
.lcdsel_grf_reg = RK3399_GRF_SOC_CON20,
|
||||||
|
.lcdsel_big = HIWORD_UPDATE(0, RK3399_EDP_LCDC_SEL),
|
||||||
|
.lcdsel_lit = HIWORD_UPDATE(RK3399_EDP_LCDC_SEL, RK3399_EDP_LCDC_SEL),
|
||||||
|
.chip_type = RK3399_EDP,
|
||||||
|
};
|
||||||
|
|
||||||
|
static const struct rockchip_dp_chip_data rk3288_dp = {
|
||||||
|
.lcdsel_grf_reg = RK3288_GRF_SOC_CON6,
|
||||||
|
.lcdsel_big = HIWORD_UPDATE(0, RK3288_EDP_LCDC_SEL),
|
||||||
|
.lcdsel_lit = HIWORD_UPDATE(RK3288_EDP_LCDC_SEL, RK3288_EDP_LCDC_SEL),
|
||||||
|
.chip_type = RK3288_DP,
|
||||||
|
};
|
||||||
|
|
||||||
static const struct of_device_id rockchip_dp_dt_ids[] = {
|
static const struct of_device_id rockchip_dp_dt_ids[] = {
|
||||||
{.compatible = "rockchip,rk3288-dp",},
|
{.compatible = "rockchip,rk3288-dp", .data = &rk3288_dp },
|
||||||
|
{.compatible = "rockchip,rk3399-edp", .data = &rk3399_edp },
|
||||||
{}
|
{}
|
||||||
};
|
};
|
||||||
MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
|
MODULE_DEVICE_TABLE(of, rockchip_dp_dt_ids);
|
||||||
|
@@ -16,8 +16,14 @@
|
|||||||
enum analogix_dp_devtype {
|
enum analogix_dp_devtype {
|
||||||
EXYNOS_DP,
|
EXYNOS_DP,
|
||||||
RK3288_DP,
|
RK3288_DP,
|
||||||
|
RK3399_EDP,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static inline bool is_rockchip(enum analogix_dp_devtype type)
|
||||||
|
{
|
||||||
|
return type == RK3288_DP || type == RK3399_EDP;
|
||||||
|
}
|
||||||
|
|
||||||
struct analogix_dp_plat_data {
|
struct analogix_dp_plat_data {
|
||||||
enum analogix_dp_devtype dev_type;
|
enum analogix_dp_devtype dev_type;
|
||||||
struct drm_panel *panel;
|
struct drm_panel *panel;
|
||||||
@@ -28,7 +34,8 @@ struct analogix_dp_plat_data {
|
|||||||
int (*power_off)(struct analogix_dp_plat_data *);
|
int (*power_off)(struct analogix_dp_plat_data *);
|
||||||
int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *,
|
int (*attach)(struct analogix_dp_plat_data *, struct drm_bridge *,
|
||||||
struct drm_connector *);
|
struct drm_connector *);
|
||||||
int (*get_modes)(struct analogix_dp_plat_data *);
|
int (*get_modes)(struct analogix_dp_plat_data *,
|
||||||
|
struct drm_connector *);
|
||||||
};
|
};
|
||||||
|
|
||||||
int analogix_dp_resume(struct device *dev);
|
int analogix_dp_resume(struct device *dev);
|
||||||
|
Reference in New Issue
Block a user