diff --git a/drivers/gpu/drm/hisilicon/kirin/Kconfig b/drivers/gpu/drm/hisilicon/kirin/Kconfig index 290553e2f6b4..0f2a29e84296 100644 --- a/drivers/gpu/drm/hisilicon/kirin/Kconfig +++ b/drivers/gpu/drm/hisilicon/kirin/Kconfig @@ -6,7 +6,37 @@ config DRM_HISI_KIRIN select DRM_GEM_CMA_HELPER select DRM_KMS_CMA_HELPER select DRM_MIPI_DSI + select DRM_PANEL help - Choose this option if you have a hisilicon Kirin chipsets(hi6220). + Choose this option if you have a hisilicon Kirin chipsets. If M is selected the module will be called kirin-drm. +if DRM_HISI_KIRIN +config DRM_HISI_KIRIN620 + bool "DRM Support for Hisilicon Kirin620 Platform" + default n + depends on DRM_HISI_KIRIN + select DRM_KMS_HELPER + select DRM_GEM_CMA_HELPER + select DRM_KMS_CMA_HELPER + select DRM_MIPI_DSI + select DRM_PANEL + help + Choose this option if you have hisilicon Kirin Chipset(kirin620). + It includes kirin620 ade and dsi drivers. + If y is to build kirin620 drm into kirin drm drivers. + +config DRM_HISI_KIRIN960 + bool "DRM Support for Hisilicon Kirin960 Platform" + default n + depends on DRM_HISI_KIRIN + select DRM_KMS_HELPER + select DRM_GEM_CMA_HELPER + select DRM_KMS_CMA_HELPER + select DRM_MIPI_DSI + select DRM_PANEL + help + Choose this option if you have hisilicon Kirin Chipset(kirin960), such + as hikey board. It includes kirin620 dpe and dsi drivers. + If y is to build kirin960 drm into kirin drm drivers. +endif diff --git a/drivers/gpu/drm/hisilicon/kirin/Makefile b/drivers/gpu/drm/hisilicon/kirin/Makefile index d9323f66a7d4..66c37a8b813f 100644 --- a/drivers/gpu/drm/hisilicon/kirin/Makefile +++ b/drivers/gpu/drm/hisilicon/kirin/Makefile @@ -1,6 +1,12 @@ # SPDX-License-Identifier: GPL-2.0-only -kirin-drm-y := kirin_drm_drv.o \ - kirin_drm_ade.o +EXTRA_CFLAGS += \ + -Iinclude/drm -obj-$(CONFIG_DRM_HISI_KIRIN) += kirin-drm.o dw_drm_dsi.o +kirin-drm-y := kirin_drm_drv.o +kirin-drm-$(CONFIG_DRM_HISI_KIRIN620) += kirin_drm_ade.o +kirin-dsi-y := kirin_drm_dsi.o +kirin-dsi-$(CONFIG_DRM_HISI_KIRIN620) += kirin/dw_drm_dsi.o +kirin-dsi-$(CONFIG_DRM_HISI_KIRIN960) += kirin960/dw_drm_dsi.o + +obj-$(CONFIG_DRM_HISI_KIRIN) += kirin-drm.o kirin-dsi.o diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h b/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h index 19e81ff64fac..6c31ee0b487f 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h +++ b/drivers/gpu/drm/hisilicon/kirin/dw_dsi_reg.h @@ -8,7 +8,7 @@ #define __DW_DSI_REG_H__ #define MASK(x) (BIT(x) - 1) - +#define DEFAULT_MAX_TX_ESC_CLK (10 * 1000000UL) //for hikey960 /* * regs */ @@ -52,6 +52,50 @@ #define VID_VACTIVE_LINES 0x60 /* Vertical resolution */ #define VID_PKT_SIZE 0x3C /* Video packet size */ #define VID_MODE_CFG 0x38 /* Video mode configuration */ +/***************************for hikey960***********************************/ +#define GEN_HDR 0x6c +#define GEN_HDATA(data) (((data) & 0xffff) << 8) +#define GEN_HDATA_MASK (0xffff << 8) +#define GEN_HTYPE(type) (((type) & 0xff) << 0) +#define GEN_HTYPE_MASK 0xff +#define GEN_PLD_DATA 0x70 +#define CMD_PKT_STATUS 0x74 +#define GEN_CMD_EMPTY BIT(0) +#define GEN_CMD_FULL BIT(1) +#define GEN_PLD_W_EMPTY BIT(2) +#define GEN_PLD_W_FULL BIT(3) +#define GEN_PLD_R_EMPTY BIT(4) +#define GEN_PLD_R_FULL BIT(5) +#define GEN_RD_CMD_BUSY BIT(6) +#define CMD_MODE_CFG 0x68 +#define MAX_RD_PKT_SIZE_LP BIT(24) +#define DCS_LW_TX_LP BIT(19) +#define DCS_SR_0P_TX_LP BIT(18) +#define DCS_SW_1P_TX_LP BIT(17) +#define DCS_SW_0P_TX_LP BIT(16) +#define GEN_LW_TX_LP BIT(14) +#define GEN_SR_2P_TX_LP BIT(13) +#define GEN_SR_1P_TX_LP BIT(12) +#define GEN_SR_0P_TX_LP BIT(11) +#define GEN_SW_2P_TX_LP BIT(10) +#define GEN_SW_1P_TX_LP BIT(9) +#define GEN_SW_0P_TX_LP BIT(8) +#define EN_ACK_RQST BIT(1) +#define EN_TEAR_FX BIT(0) +#define CMD_PKT_STATUS_TIMEOUT_US 20000 +#define CMD_MODE_ALL_LP (MAX_RD_PKT_SIZE_LP | \ + DCS_LW_TX_LP | \ + DCS_SR_0P_TX_LP | \ + DCS_SW_1P_TX_LP | \ + DCS_SW_0P_TX_LP | \ + GEN_LW_TX_LP | \ + GEN_SR_2P_TX_LP | \ + GEN_SR_1P_TX_LP | \ + GEN_SR_0P_TX_LP | \ + GEN_SW_2P_TX_LP | \ + GEN_SW_1P_TX_LP | \ + GEN_SW_0P_TX_LP) +/***************************for hikey960***********************************/ #define PHY_TMR_CFG 0x9C /* Data lanes timing configuration */ #define BTA_TO_CNT 0x8C /* Response timeout definition */ #define PHY_TMR_LPCLK_CFG 0x98 /* clock lane timing configuration */ diff --git a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/kirin/dw_drm_dsi.c similarity index 85% rename from drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c rename to drivers/gpu/drm/hisilicon/kirin/kirin/dw_drm_dsi.c index 00e87c290796..11d3a1b59ca0 100644 --- a/drivers/gpu/drm/hisilicon/kirin/dw_drm_dsi.c +++ b/drivers/gpu/drm/hisilicon/kirin/kirin/dw_drm_dsi.c @@ -9,6 +9,7 @@ * Xinliang Liu * Xinliang Liu * Xinwei Kong + * Da Lv */ #include @@ -26,97 +27,10 @@ #include #include -#include "dw_dsi_reg.h" +#include "../kirin_drm_dsi.h" +#include "../dw_dsi_reg.h" #define MAX_TX_ESC_CLK 10 -#define ROUND(x, y) ((x) / (y) + \ - ((x) % (y) * 10 / (y) >= 5 ? 1 : 0)) -#define PHY_REF_CLK_RATE 19200000 -#define PHY_REF_CLK_PERIOD_PS (1000000000 / (PHY_REF_CLK_RATE / 1000)) - -#define encoder_to_dsi(encoder) \ - container_of(encoder, struct dw_dsi, encoder) -#define host_to_dsi(host) \ - container_of(host, struct dw_dsi, host) - -struct mipi_phy_params { - u32 clk_t_lpx; - u32 clk_t_hs_prepare; - u32 clk_t_hs_zero; - u32 clk_t_hs_trial; - u32 clk_t_wakeup; - u32 data_t_lpx; - u32 data_t_hs_prepare; - u32 data_t_hs_zero; - u32 data_t_hs_trial; - u32 data_t_ta_go; - u32 data_t_ta_get; - u32 data_t_wakeup; - u32 hstx_ckg_sel; - u32 pll_fbd_div5f; - u32 pll_fbd_div1f; - u32 pll_fbd_2p; - u32 pll_enbwt; - u32 pll_fbd_p; - u32 pll_fbd_s; - u32 pll_pre_div1p; - u32 pll_pre_p; - u32 pll_vco_750M; - u32 pll_lpf_rs; - u32 pll_lpf_cs; - u32 clklp2hs_time; - u32 clkhs2lp_time; - u32 lp2hs_time; - u32 hs2lp_time; - u32 clk_to_data_delay; - u32 data_to_clk_delay; - u32 lane_byte_clk_kHz; - u32 clk_division; -}; - -struct dsi_hw_ctx { - void __iomem *base; - struct clk *pclk; -}; - -struct dw_dsi { - struct drm_encoder encoder; - struct drm_bridge *bridge; - struct mipi_dsi_host host; - struct drm_display_mode cur_mode; - struct dsi_hw_ctx *ctx; - struct mipi_phy_params phy; - - u32 lanes; - enum mipi_dsi_pixel_format format; - unsigned long mode_flags; - bool enable; -}; - -struct dsi_data { - struct dw_dsi dsi; - struct dsi_hw_ctx ctx; -}; - -struct dsi_phy_range { - u32 min_range_kHz; - u32 max_range_kHz; - u32 pll_vco_750M; - u32 hstx_ckg_sel; -}; - -static const struct dsi_phy_range dphy_range_info[] = { - { 46875, 62500, 1, 7 }, - { 62500, 93750, 0, 7 }, - { 93750, 125000, 1, 6 }, - { 125000, 187500, 0, 6 }, - { 187500, 250000, 1, 5 }, - { 250000, 375000, 0, 5 }, - { 375000, 500000, 1, 4 }, - { 500000, 750000, 0, 4 }, - { 750000, 1000000, 1, 0 }, - { 1000000, 1500000, 0, 0 } -}; static u32 dsi_calc_phy_rate(u32 req_kHz, struct mipi_phy_params *phy) { @@ -568,24 +482,7 @@ static void dsi_mipi_init(struct dw_dsi *dsi) dsi->lanes, mode->clock, phy->lane_byte_clk_kHz); } -static void dsi_encoder_disable(struct drm_encoder *encoder) -{ - struct dw_dsi *dsi = encoder_to_dsi(encoder); - struct dsi_hw_ctx *ctx = dsi->ctx; - void __iomem *base = ctx->base; - - if (!dsi->enable) - return; - - writel(0, base + PWR_UP); - writel(0, base + LPCLK_CTRL); - writel(0, base + PHY_RSTZ); - clk_disable_unprepare(ctx->pclk); - - dsi->enable = false; -} - -static void dsi_encoder_enable(struct drm_encoder *encoder) +static void dsi_encoder_enable_sub(struct drm_encoder *encoder) { struct dw_dsi *dsi = encoder_to_dsi(encoder); struct dsi_hw_ctx *ctx = dsi->ctx; @@ -601,8 +498,6 @@ static void dsi_encoder_enable(struct drm_encoder *encoder) } dsi_mipi_init(dsi); - - dsi->enable = true; } static enum drm_mode_status dsi_encoder_phy_mode_valid( @@ -844,54 +739,13 @@ static int dsi_parse_dt(struct platform_device *pdev, struct dw_dsi *dsi) return 0; } -static int dsi_probe(struct platform_device *pdev) -{ - struct dsi_data *data; - struct dw_dsi *dsi; - struct dsi_hw_ctx *ctx; - int ret; - - data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL); - if (!data) { - DRM_ERROR("failed to allocate dsi data.\n"); - return -ENOMEM; - } - dsi = &data->dsi; - ctx = &data->ctx; - dsi->ctx = ctx; - - ret = dsi_parse_dt(pdev, dsi); - if (ret) - return ret; - - platform_set_drvdata(pdev, data); - - return component_add(&pdev->dev, &dsi_ops); -} - -static int dsi_remove(struct platform_device *pdev) -{ - component_del(&pdev->dev, &dsi_ops); - - return 0; -} - -static const struct of_device_id dsi_of_match[] = { - {.compatible = "hisilicon,hi6220-dsi"}, - { } +const struct kirin_dsi_ops kirin_dsi_620 = { + .version = KIRIN620_DSI, + .parse_dt = dsi_parse_dt, + .host_init = dsi_host_init, + .encoder_enable = dsi_encoder_enable_sub, + .encoder_valid = dsi_encoder_mode_valid }; -MODULE_DEVICE_TABLE(of, dsi_of_match); - -static struct platform_driver dsi_driver = { - .probe = dsi_probe, - .remove = dsi_remove, - .driver = { - .name = "dw-dsi", - .of_match_table = dsi_of_match, - }, -}; - -module_platform_driver(dsi_driver); MODULE_AUTHOR("Xinliang Liu "); MODULE_AUTHOR("Xinliang Liu "); diff --git a/drivers/gpu/drm/hisilicon/kirin/kirin960/dw_drm_dsi.c b/drivers/gpu/drm/hisilicon/kirin/kirin960/dw_drm_dsi.c new file mode 100644 index 000000000000..9ddeb6280427 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/kirin/kirin960/dw_drm_dsi.c @@ -0,0 +1,1269 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * DesignWare MIPI DSI Host Controller v1.02 driver + * + * Copyright (c) 2016 Linaro Limited. + * Copyright (c) 2014-2016 Hisilicon Limited. + * + * Author: + * + * + * + * + */ + +#include +#include +#include +#include +#include +#include