drm/rockchip: dsi: Add support for rk3568

This patch adds support for Synopsys Designware MIPI DSI host IP
used on RK3568 SoC.

Change-Id: Ie3bed6bf8cebf32d9fb3e26ad71eba393cbdffe8
Signed-off-by: Wyon Bi <bivvy.bi@rock-chips.com>
Signed-off-by: Guochun Huang <hero.huang@rock-chips.com>
This commit is contained in:
Wyon Bi
2021-07-02 09:10:32 +08:00
committed by Tao Huang
parent df1b255055
commit 8c5e5dbba6

View File

@@ -17,7 +17,7 @@
#include <linux/regmap.h>
#include <video/mipi_display.h>
#include <uapi/linux/videodev2.h>
#include <drm/bridge/dw_mipi_dsi.h>
#include <drm/drm_mipi_dsi.h>
#include <drm/drm_of.h>
@@ -140,6 +140,7 @@
#define DW_MIPI_NEEDS_PHY_CFG_CLK BIT(0)
#define DW_MIPI_NEEDS_GRF_CLK BIT(1)
#define DW_MIPI_NEEDS_HCLK BIT(2)
#define PX30_GRF_PD_VO_CON1 0x0438
#define PX30_DSI_FORCETXSTOPMODE (0xf << 7)
@@ -172,6 +173,12 @@
#define RK3399_TXRX_ENABLECLK BIT(6)
#define RK3399_TXRX_BASEDIR BIT(5)
#define RK3568_GRF_VO_CON2 0x0368
#define RK3568_GRF_VO_CON3 0x036c
#define RK3568_DSI_FORCETXSTOPMODE (0xf << 4)
#define RK3568_DSI_TURNDISABLE (0x1 << 2)
#define RK3568_DSI_FORCERXMODE (0x1 << 0)
#define HIWORD_UPDATE(val, mask) (val | (mask) << 16)
#define to_dsi(nm) container_of(nm, struct dw_mipi_dsi_rockchip, nm)
@@ -221,11 +228,13 @@ struct dw_mipi_dsi_rockchip {
struct device *dev;
struct drm_encoder encoder;
void __iomem *base;
int id;
struct regmap *grf_regmap;
struct clk *pllref_clk;
struct clk *grf_clk;
struct clk *phy_cfg_clk;
struct clk *hclk;
/* dual-channel */
bool is_slave;
@@ -719,6 +728,8 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
{
struct rockchip_crtc_state *s = to_rockchip_crtc_state(crtc_state);
struct dw_mipi_dsi_rockchip *dsi = to_dsi(encoder);
struct drm_connector *connector = conn_state->connector;
struct drm_display_info *info = &connector->display_info;
switch (dsi->format) {
case MIPI_DSI_FMT_RGB888:
@@ -735,9 +746,18 @@ dw_mipi_dsi_encoder_atomic_check(struct drm_encoder *encoder,
return -EINVAL;
}
if (info->num_bus_formats)
s->bus_format = info->bus_formats[0];
else
s->bus_format = MEDIA_BUS_FMT_RGB888_1X24;
s->output_type = DRM_MODE_CONNECTOR_DSI;
if (dsi->slave)
s->output_flags = ROCKCHIP_OUTPUT_DSI_DUAL;
s->color_space = V4L2_COLORSPACE_DEFAULT;
s->output_if = dsi->id ? VOP_OUTPUT_IF_MIPI1 : VOP_OUTPUT_IF_MIPI0;
if (dsi->slave) {
s->output_flags |= ROCKCHIP_OUTPUT_DUAL_CHANNEL_LEFT_RIGHT_MODE;
s->output_if |= VOP_OUTPUT_IF_MIPI1;
}
return 0;
}
@@ -1032,6 +1052,7 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
while (cdata[i].reg) {
if (cdata[i].reg == res->start) {
dsi->cdata = &cdata[i];
dsi->id = i;
break;
}
@@ -1087,6 +1108,15 @@ static int dw_mipi_dsi_rockchip_probe(struct platform_device *pdev)
}
}
if (dsi->cdata->flags & DW_MIPI_NEEDS_HCLK) {
dsi->hclk = devm_clk_get(dev, "hclk");
if (IS_ERR(dsi->hclk)) {
ret = PTR_ERR(dsi->hclk);
DRM_DEV_ERROR(dev, "Unable to get hclk: %d\n", ret);
return ret;
}
}
dsi->grf_regmap = syscon_regmap_lookup_by_phandle(np, "rockchip,grf");
if (IS_ERR(dsi->grf_regmap)) {
DRM_DEV_ERROR(dsi->dev, "Unable to get rockchip,grf\n");
@@ -1129,6 +1159,27 @@ static int dw_mipi_dsi_rockchip_remove(struct platform_device *pdev)
return 0;
}
static __maybe_unused int dw_mipi_dsi_runtime_suspend(struct device *dev)
{
struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
clk_disable_unprepare(dsi->hclk);
return 0;
}
static __maybe_unused int dw_mipi_dsi_runtime_resume(struct device *dev)
{
struct dw_mipi_dsi_rockchip *dsi = dev_get_drvdata(dev);
return clk_prepare_enable(dsi->hclk);
}
static const struct dev_pm_ops dw_mipi_dsi_rockchip_pm_ops = {
SET_RUNTIME_PM_OPS(dw_mipi_dsi_runtime_suspend,
dw_mipi_dsi_runtime_resume, NULL)
};
static const struct rockchip_dw_dsi_chip_data px30_chip_data[] = {
{
.reg = 0xff450000,
@@ -1213,6 +1264,32 @@ static const struct rockchip_dw_dsi_chip_data rk3399_chip_data[] = {
{ /* sentinel */ }
};
static const struct rockchip_dw_dsi_chip_data rk3568_chip_data[] = {
{
.reg = 0xfe060000,
.lanecfg1_grf_reg = RK3568_GRF_VO_CON2,
.lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI_TURNDISABLE |
RK3568_DSI_FORCERXMODE |
RK3568_DSI_FORCETXSTOPMODE),
.flags = DW_MIPI_NEEDS_HCLK,
.max_data_lanes = 4,
},
{
.reg = 0xfe070000,
.lanecfg1_grf_reg = RK3568_GRF_VO_CON3,
.lanecfg1 = HIWORD_UPDATE(0, RK3568_DSI_TURNDISABLE |
RK3568_DSI_FORCERXMODE |
RK3568_DSI_FORCETXSTOPMODE),
.flags = DW_MIPI_NEEDS_HCLK,
.max_data_lanes = 4,
},
{ /* sentinel */ }
};
static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
{
.compatible = "rockchip,px30-mipi-dsi",
@@ -1223,6 +1300,9 @@ static const struct of_device_id dw_mipi_dsi_rockchip_dt_ids[] = {
}, {
.compatible = "rockchip,rk3399-mipi-dsi",
.data = &rk3399_chip_data,
}, {
.compatible = "rockchip,rk3568-mipi-dsi",
.data = &rk3568_chip_data,
},
{ /* sentinel */ }
};
@@ -1233,6 +1313,7 @@ struct platform_driver dw_mipi_dsi_rockchip_driver = {
.remove = dw_mipi_dsi_rockchip_remove,
.driver = {
.of_match_table = dw_mipi_dsi_rockchip_dt_ids,
.pm = &dw_mipi_dsi_rockchip_pm_ops,
.name = "dw-mipi-dsi-rockchip",
},
};