#define DSI_RK312x 0x3128
#define DSI_RK3368 0x3368
#define DSI_RK3366 0x3366
+#define DSI_RK3399 0x3399
#define DSI_ERR -1
#include <linux/kernel.h>
#include "rk32_mipi_dsi.h"
#include <linux/rockchip/iomap.h>
#include <linux/rockchip/cpu.h>
+#include<linux/mfd/syscon.h>
+#include<linux/regmap.h>
#define MIPI_DBG(x...) /* printk(KERN_INFO x) */
static int rk32_dsi_read_reg(struct dsi *dsi, u16 reg, u32 *pval)
{
- if (dsi->ops.id == DSI_RK3288)
+ if (dsi->ops.id == DSI_RK3288 ||
+ dsi->ops.id == DSI_RK3399)
*pval = __raw_readl(dsi->host.membase + (reg - MIPI_DSI_HOST_OFFSET));
else if (dsi->ops.id == DSI_RK312x ||
dsi->ops.id == DSI_RK3368 ||
static int rk32_dsi_write_reg(struct dsi *dsi, u16 reg, u32 *pval)
{
- if (dsi->ops.id == DSI_RK3288)
+ if (dsi->ops.id == DSI_RK3288 ||
+ dsi->ops.id == DSI_RK3399)
__raw_writel(*pval, dsi->host.membase + (reg - MIPI_DSI_HOST_OFFSET));
else if (dsi->ops.id == DSI_RK312x ||
dsi->ops.id == DSI_RK3368 ||
/* enable ref clock */
clk_prepare_enable(dsi->phy.refclk);
clk_prepare_enable(dsi->dsi_pclk);
+ if (dsi->ops.id == DSI_RK3399)
+ clk_prepare_enable(dsi->dsi_host_pclk);
udelay(10);
switch (dsi->host.lane) {
static int rk_phy_power_up(struct dsi *dsi)
{
- if (dsi->ops.id == DSI_RK3288)
+ if (dsi->ops.id == DSI_RK3288 ||
+ dsi->ops.id == DSI_RK3399)
rk32_phy_power_up(dsi);
else if (dsi->ops.id == DSI_RK312x ||
dsi->ops.id == DSI_RK3368 ||
rk32_dsi_set_bits(dsi, 0, phy_shutdownz);
clk_disable_unprepare(dsi->phy.refclk);
clk_disable_unprepare(dsi->dsi_pclk);
+ if (dsi->ops.id == DSI_RK3399)
+ clk_disable_unprepare(dsi->dsi_host_pclk);
return 0;
}
static int rk_phy_power_down(struct dsi *dsi)
{
- if (dsi->ops.id == DSI_RK3288)
+ if (dsi->ops.id == DSI_RK3288 ||
+ dsi->ops.id == DSI_RK3399)
rk32_phy_power_down(dsi);
else if (dsi->ops.id == DSI_RK312x ||
dsi->ops.id == DSI_RK3368 ||
static int rk_phy_init(struct dsi *dsi)
{
- if (dsi->ops.id == DSI_RK3288)
+ if (dsi->ops.id == DSI_RK3288 ||
+ dsi->ops.id == DSI_RK3399)
rk32_phy_init(dsi);
else if (dsi->ops.id == DSI_RK312x ||
dsi->ops.id == DSI_RK3368 ||
}
if (dsi->ops.id == DSI_RK3288 ||
dsi->ops.id == DSI_RK3368 ||
- dsi->ops.id == DSI_RK3366) {
+ dsi->ops.id == DSI_RK3366 ||
+ dsi->ops.id == DSI_RK3399) {
rk32_dsi_set_bits(dsi, 1, hsync_active_low);
rk32_dsi_set_bits(dsi, 1, vsync_active_low);
rk32_dsi_set_bits(dsi, 10, TO_CLK_DIVISION);
rk32_dsi_set_bits(dsi, 1000, hstx_to_cnt); /* no sure */
rk32_dsi_set_bits(dsi, 1000, lprx_to_cnt);
- rk32_dsi_set_bits(dsi, 100, phy_stop_wait_time);
+ if (dsi->ops.id == DSI_RK3399)
+ rk32_dsi_set_bits(dsi, 32, phy_stop_wait_time);
+ else
+ rk32_dsi_set_bits(dsi, 100, phy_stop_wait_time);
/* enable send command in low power mode */
rk32_dsi_set_bits(dsi, 4, outvact_lpcmd_time);
dsi->phy.sys_clk = dsi->phy.ref_clk;
printk("dsi->phy.sys_clk =%d\n", dsi->phy.sys_clk);
- if (dsi->ops.id == DSI_RK3288) {
+ if (dsi->ops.id == DSI_RK3288 ||
+ dsi->ops.id == DSI_RK3399) {
if ((screen->hs_tx_clk <= 90 * MHz) || (screen->hs_tx_clk >= 1500 * MHz))
dsi->phy.ddr_clk = 1500 * MHz; /* default is 1.5HGz */
else
MIPI_DBG("rk32_init_phy_mode----------lcdc_id=%d\n", lcdc_id);
/* Only the rk3288 VOP need setting the VOP output. */
- if (dsi0->ops.id != DSI_RK3288)
- return;
-
- /* D-PHY mode select */
- if (rk_mipi_get_dsi_num() == 1) {
- if (lcdc_id == 1)
- /* 1'b1: VOP LIT output to DSI host0;1'b0: VOP BIG output to DSI host0 */
- val0 = 0x1 << 22 | 0x1 << 6;
- else
- val0 = 0x1 << 22 | 0x0 << 6;
- writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
- } else {
- if (lcdc_id == 1) {
- val0 = 0x1 << 25 | 0x1 << 9 | 0x1 << 22 | 0x1 << 6;
- val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14;
+ if (dsi0->ops.id == DSI_RK3288) {
+ /* D-PHY mode select */
+ if (rk_mipi_get_dsi_num() == 1) {
+ if (lcdc_id == 1)
+ /* 1'b1: VOP LIT output to DSI host0;1'b0: VOP BIG output to DSI host0 */
+ val0 = 0x1 << 22 | 0x1 << 6;
+ else
+ val0 = 0x1 << 22 | 0x0 << 6;
+ writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
} else {
- val0 = 0x1 << 25 | 0x0 << 9 | 0x1 << 22 | 0x0 << 14;
- val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14;
+ if (lcdc_id == 1) {
+ val0 = 0x1 << 25 | 0x1 << 9 | 0x1 << 22 | 0x1 << 6;
+ val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14;
+ } else {
+ val0 = 0x1 << 25 | 0x0 << 9 | 0x1 << 22 | 0x0 << 14;
+ val1 = 0x1 << 31 | 0x1 << 30 | 0x0 << 15 | 0x1 << 14;
+ }
+ writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
+ writel_relaxed(val1, RK_GRF_VIRT + RK3288_GRF_SOC_CON14);
}
- writel_relaxed(val0, RK_GRF_VIRT + RK3288_GRF_SOC_CON6);
- writel_relaxed(val1, RK_GRF_VIRT + RK3288_GRF_SOC_CON14);
+ } else if (dsi0->ops.id == DSI_RK3399) {
+ val0 = 0x1 << 16 | 0x0;
+ regmap_write(dsi0->grf_base, RK3399_GRF_CON20, val0);
+
+ val0 = 0x1 << 28 | 0x0 << 12;
+ val0 |= 0xf << 20 | 0x0 << 4;
+ val0 |= 0xf << 16 | 0x0;
+ regmap_write(dsi0->grf_base, RK3399_GRF_CON22, val0);
}
}
.dsi_id = DSI_RK3366,
};
+static struct dsi_type dsi_rk3399 = {
+ .label = "rk3399-dsi",
+ .dsi_id = DSI_RK3399,
+};
+
static const struct of_device_id of_rk_mipi_dsi_match[] = {
{ .compatible = "rockchip,rk32-dsi", .data = &dsi_rk32},
{ .compatible = "rockchip,rk312x-dsi", .data = &dsi_rk312x},
{ .compatible = "rockchip,rk3368-dsi", .data = &dsi_rk3368},
{ .compatible = "rockchip,rk3366-dsi", .data = &dsi_rk3366},
+ { .compatible = "rockchip,rk3399-dsi", .data = &dsi_rk3399},
{ /* Sentinel */ }
};
struct rk_screen *screen;
struct mipi_dsi_screen *dsi_screen;
struct resource *res_host, *res_phy;
+ struct device_node *np = pdev->dev.of_node;
const struct dsi_type *data;
const struct of_device_id *of_id =
of_match_device(of_rk_mipi_dsi_match, &pdev->dev);
}
dsi->ops.id = data->dsi_id;
printk(KERN_INFO "%s\n", data->label);
- if (dsi->ops.id == DSI_RK3288) {
+ if (dsi->ops.id == DSI_RK3288 ||
+ dsi->ops.id == DSI_RK3399) {
res_host = platform_get_resource(pdev, IORESOURCE_MEM, 0);
dsi->host.membase = devm_ioremap_resource(&pdev->dev, res_host);
if (IS_ERR(dsi->host.membase)) {
}
}
+ if (dsi->ops.id == DSI_RK3399) {
+ /* Get mipi phy cfg clk */
+ dsi->dsi_host_pclk = devm_clk_get(&pdev->dev, "mipi_dphy_cfg");
+ if (unlikely(IS_ERR(dsi->dsi_host_pclk))) {
+ dev_err(&pdev->dev, "get mipi_dphy_cfg clock fail\n");
+ return PTR_ERR(dsi->dsi_host_pclk);
+ }
+
+ dsi->grf_base = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
+ if (IS_ERR(dsi->grf_base)) {
+ dev_err(&pdev->dev, "can't find mipi grf property\n");
+ dsi->grf_base = NULL;
+ }
+ }
+
dsi->host.irq = platform_get_irq(pdev, 0);
if (dsi->host.irq < 0) {
dev_err(&pdev->dev, "no irq resource?\n");
} else if (dsi->ops.id == DSI_RK3368 ||
dsi->ops.id == DSI_RK3366)
clk_prepare_enable(dsi->dsi_host_pclk);
+ else if (dsi->ops.id == DSI_RK3399)
+ clk_prepare_enable(dsi->dsi_host_pclk);
dsi->clk_on = 1;
udelay(10);