|
@@ -8,20 +8,21 @@
|
|
|
#include <clk.h>
|
|
|
#include <display.h>
|
|
|
#include <dm.h>
|
|
|
+#include <dm/device_compat.h>
|
|
|
#include <edid.h>
|
|
|
#include <log.h>
|
|
|
#include <malloc.h>
|
|
|
#include <panel.h>
|
|
|
#include <regmap.h>
|
|
|
+#include <reset.h>
|
|
|
#include <syscon.h>
|
|
|
#include <asm/gpio.h>
|
|
|
#include <asm/io.h>
|
|
|
#include <asm/arch-rockchip/clock.h>
|
|
|
+#include <asm/arch-rockchip/hardware.h>
|
|
|
#include <asm/arch-rockchip/edp_rk3288.h>
|
|
|
#include <asm/arch-rockchip/grf_rk3288.h>
|
|
|
-#include <asm/arch-rockchip/hardware.h>
|
|
|
-#include <dt-bindings/clock/rk3288-cru.h>
|
|
|
-#include <linux/delay.h>
|
|
|
+#include <asm/arch-rockchip/grf_rk3399.h>
|
|
|
|
|
|
#define MAX_CR_LOOP 5
|
|
|
#define MAX_EQ_LOOP 5
|
|
@@ -37,18 +38,42 @@ static const char * const pre_emph_names[] = {
|
|
|
#define DP_VOLTAGE_MAX DP_TRAIN_VOLTAGE_SWING_1200
|
|
|
#define DP_PRE_EMPHASIS_MAX DP_TRAIN_PRE_EMPHASIS_9_5
|
|
|
|
|
|
+#define RK3288_GRF_SOC_CON6 0x025c
|
|
|
+#define RK3288_GRF_SOC_CON12 0x0274
|
|
|
+#define RK3399_GRF_SOC_CON20 0x6250
|
|
|
+#define RK3399_GRF_SOC_CON25 0x6264
|
|
|
+
|
|
|
+enum rockchip_dp_types {
|
|
|
+ RK3288_DP = 0,
|
|
|
+ RK3399_EDP
|
|
|
+};
|
|
|
+
|
|
|
+struct rockchip_dp_data {
|
|
|
+ unsigned long reg_vop_big_little;
|
|
|
+ unsigned long reg_vop_big_little_sel;
|
|
|
+ unsigned long reg_ref_clk_sel;
|
|
|
+ unsigned long ref_clk_sel_bit;
|
|
|
+ enum rockchip_dp_types chip_type;
|
|
|
+};
|
|
|
+
|
|
|
struct rk_edp_priv {
|
|
|
struct rk3288_edp *regs;
|
|
|
- struct rk3288_grf *grf;
|
|
|
+ void *grf;
|
|
|
struct udevice *panel;
|
|
|
struct link_train link_train;
|
|
|
u8 train_set[4];
|
|
|
};
|
|
|
|
|
|
-static void rk_edp_init_refclk(struct rk3288_edp *regs)
|
|
|
+static void rk_edp_init_refclk(struct rk3288_edp *regs, enum rockchip_dp_types chip_type)
|
|
|
{
|
|
|
writel(SEL_24M, ®s->analog_ctl_2);
|
|
|
- writel(REF_CLK_24M, ®s->pll_reg_1);
|
|
|
+ u32 reg;
|
|
|
+
|
|
|
+ reg = REF_CLK_24M;
|
|
|
+ if (chip_type == RK3288_DP)
|
|
|
+ reg ^= REF_CLK_MASK;
|
|
|
+ writel(reg, ®s->pll_reg_1);
|
|
|
+
|
|
|
|
|
|
writel(LDO_OUTPUT_V_SEL_145 | KVCO_DEFALUT | CHG_PUMP_CUR_SEL_5US |
|
|
|
V2L_CUR_SEL_1MA, ®s->pll_reg_2);
|
|
@@ -1029,6 +1054,9 @@ static int rk_edp_probe(struct udevice *dev)
|
|
|
struct display_plat *uc_plat = dev_get_uclass_plat(dev);
|
|
|
struct rk_edp_priv *priv = dev_get_priv(dev);
|
|
|
struct rk3288_edp *regs = priv->regs;
|
|
|
+ struct rockchip_dp_data *edp_data = (struct rockchip_dp_data *)dev_get_driver_data(dev);
|
|
|
+ struct reset_ctl dp_rst;
|
|
|
+
|
|
|
struct clk clk;
|
|
|
int ret;
|
|
|
|
|
@@ -1040,19 +1068,39 @@ static int rk_edp_probe(struct udevice *dev)
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
- int vop_id = uc_plat->source_id;
|
|
|
- debug("%s, uc_plat=%p, vop_id=%u\n", __func__, uc_plat, vop_id);
|
|
|
+ ret = reset_get_by_name(dev, "dp", &dp_rst);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "failed to get dp reset (ret=%d)\n", ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
|
|
|
- ret = clk_get_by_index(dev, 1, &clk);
|
|
|
- if (ret >= 0) {
|
|
|
- ret = clk_set_rate(&clk, 0);
|
|
|
- clk_free(&clk);
|
|
|
+ ret = reset_assert(&dp_rst);
|
|
|
+ if (ret) {
|
|
|
+ dev_err(dev, "failed to assert dp reset (ret=%d)\n", ret);
|
|
|
+ return ret;
|
|
|
}
|
|
|
+ udelay(20);
|
|
|
+
|
|
|
+ ret = reset_deassert(&dp_rst);
|
|
|
if (ret) {
|
|
|
- debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
|
|
|
+ dev_err(dev, "failed to deassert dp reset (ret=%d)\n", ret);
|
|
|
return ret;
|
|
|
}
|
|
|
|
|
|
+ int vop_id = uc_plat->source_id;
|
|
|
+ debug("%s, uc_plat=%p, vop_id=%u\n", __func__, uc_plat, vop_id);
|
|
|
+
|
|
|
+ if (edp_data->chip_type == RK3288_DP) {
|
|
|
+ ret = clk_get_by_index(dev, 1, &clk);
|
|
|
+ if (ret >= 0) {
|
|
|
+ ret = clk_set_rate(&clk, 0);
|
|
|
+ clk_free(&clk);
|
|
|
+ }
|
|
|
+ if (ret) {
|
|
|
+ debug("%s: Failed to set EDP clock: ret=%d\n", __func__, ret);
|
|
|
+ return ret;
|
|
|
+ }
|
|
|
+ }
|
|
|
ret = clk_get_by_index(uc_plat->src_dev, 0, &clk);
|
|
|
if (ret >= 0) {
|
|
|
ret = clk_set_rate(&clk, 192000000);
|
|
@@ -1065,15 +1113,17 @@ static int rk_edp_probe(struct udevice *dev)
|
|
|
}
|
|
|
|
|
|
/* grf_edp_ref_clk_sel: from internal 24MHz or 27MHz clock */
|
|
|
- rk_setreg(&priv->grf->soc_con12, 1 << 4);
|
|
|
+ rk_setreg(priv->grf + edp_data->reg_ref_clk_sel,
|
|
|
+ edp_data->ref_clk_sel_bit);
|
|
|
|
|
|
/* select epd signal from vop0 or vop1 */
|
|
|
- rk_clrsetreg(&priv->grf->soc_con6, (1 << 5),
|
|
|
- (vop_id == 1) ? (1 << 5) : (0 << 5));
|
|
|
+ rk_clrsetreg(priv->grf + edp_data->reg_vop_big_little,
|
|
|
+ edp_data->reg_vop_big_little_sel,
|
|
|
+ (vop_id == 1) ? edp_data->reg_vop_big_little_sel : 0);
|
|
|
|
|
|
rockchip_edp_wait_hpd(priv);
|
|
|
|
|
|
- rk_edp_init_refclk(regs);
|
|
|
+ rk_edp_init_refclk(regs, edp_data->chip_type);
|
|
|
rk_edp_init_interrupt(regs);
|
|
|
rk_edp_enable_sw_function(regs);
|
|
|
ret = rk_edp_init_analog_func(regs);
|
|
@@ -1089,8 +1139,25 @@ static const struct dm_display_ops dp_rockchip_ops = {
|
|
|
.enable = rk_edp_enable,
|
|
|
};
|
|
|
|
|
|
+static const struct rockchip_dp_data rk3399_edp = {
|
|
|
+ .reg_vop_big_little = RK3399_GRF_SOC_CON20,
|
|
|
+ .reg_vop_big_little_sel = BIT(5),
|
|
|
+ .reg_ref_clk_sel = RK3399_GRF_SOC_CON25,
|
|
|
+ .ref_clk_sel_bit = BIT(11),
|
|
|
+ .chip_type = RK3399_EDP,
|
|
|
+};
|
|
|
+
|
|
|
+static const struct rockchip_dp_data rk3288_dp = {
|
|
|
+ .reg_vop_big_little = RK3288_GRF_SOC_CON6,
|
|
|
+ .reg_vop_big_little_sel = BIT(5),
|
|
|
+ .reg_ref_clk_sel = RK3288_GRF_SOC_CON12,
|
|
|
+ .ref_clk_sel_bit = BIT(4),
|
|
|
+ .chip_type = RK3288_DP,
|
|
|
+};
|
|
|
+
|
|
|
static const struct udevice_id rockchip_dp_ids[] = {
|
|
|
- { .compatible = "rockchip,rk3288-edp" },
|
|
|
+ { .compatible = "rockchip,rk3288-edp", .data = (ulong)&rk3288_dp },
|
|
|
+ { .compatible = "rockchip,rk3399-edp", .data = (ulong)&rk3399_edp },
|
|
|
{ }
|
|
|
};
|
|
|
|