From nobody Mon Nov 25 00:48:10 2024 Received: from szxga02-in.huawei.com (szxga02-in.huawei.com [45.249.212.188]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id BA96A15B971 for ; Fri, 1 Nov 2024 10:55:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=45.249.212.188 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730458559; cv=none; b=CBfsQJW0EW0tDawf7BunaBBD5klFWvFO96RaYLbtN2eXYn966kMXiRG3co0gHuRJzW+3FuCuJMsE7TRay77Txuomw6fsEkS9rr+Xa/6NBA+KCoI2OzrgAyO7S7SftETc478dkmW7OOeGZhO6zX++oGctlOJEfLWA2heeQZ27eWk= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1730458559; c=relaxed/simple; bh=AX/StOmD1Iti36lrdMJ2swxHMy6Bexr96hq0eqDwK04=; h=From:To:CC:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=D0kLMVlZFtL2QH8tRtpWOuDWZpLiOw5FXoaSD3GqJLYLDE4rnllpr9zbE87J/zF4RELmCgQi00TfmNoYBJ+hijwxgDhw/CvypvL9guOuz0Z67k5GZgszF7KMqvN7bjz5o3ugrUWvwH12CHWg+xMR+9kY4UtbsUoL7AuleHWPwJA= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com; spf=pass smtp.mailfrom=huawei.com; arc=none smtp.client-ip=45.249.212.188 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=quarantine dis=none) header.from=huawei.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=huawei.com Received: from mail.maildlp.com (unknown [172.19.162.254]) by szxga02-in.huawei.com (SkyGuard) with ESMTP id 4XfyQ64rGQzdkdZ; Fri, 1 Nov 2024 18:53:18 +0800 (CST) Received: from kwepemd500013.china.huawei.com (unknown [7.221.188.12]) by mail.maildlp.com (Postfix) with ESMTPS id 372D91800F2; Fri, 1 Nov 2024 18:55:53 +0800 (CST) Received: from localhost.huawei.com (10.169.71.169) by kwepemd500013.china.huawei.com (7.221.188.12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.2.1258.34; Fri, 1 Nov 2024 18:55:51 +0800 From: Yongbang Shi To: , , , , , , , CC: , , , , , , , , Subject: [PATCH V3 drm-dp 4/4] drm/hisilicon/hibmc: add dp module in hibmc Date: Fri, 1 Nov 2024 18:50:28 +0800 Message-ID: <20241101105028.2177274-5-shiyongbang@huawei.com> X-Mailer: git-send-email 2.33.0 In-Reply-To: <20241101105028.2177274-1-shiyongbang@huawei.com> References: <20241101105028.2177274-1-shiyongbang@huawei.com> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: dggems703-chm.china.huawei.com (10.3.19.180) To kwepemd500013.china.huawei.com (7.221.188.12) Content-Type: text/plain; charset="utf-8" From: baihan li To support DP interface displaying in hibmc driver. Add a encoder and connector for DP modual. Signed-off-by: baihan li Signed-off-by: yongbang shi --- ChangeLog: v2 -> v3: - fix build errors reported by kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202410251136.1m7BlR68-lkp= @intel.com/ v1 -> v2: - deleting struct dp_mode and dp_mode_cfg function, suggested by Dmitry B= aryshkov. - modifying drm_simple_encoder_init function, suggested by Dmitry Baryshk= ov. - refactoring struct hibmc_connector, suggested by Dmitry Baryshkov. - withdrawing the modification in hibmc_kms_init, suggested by Dmitry Bar= yshkov. v1:https://lore.kernel.org/all/20240930100610.782363-1-shiyongbang@huawei= .com/ --- drivers/gpu/drm/hisilicon/hibmc/Makefile | 2 +- .../gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c | 128 ++++++++++++++++++ .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 16 +++ .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 21 +-- .../gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 41 +++--- .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 20 +-- 6 files changed, 188 insertions(+), 40 deletions(-) create mode 100644 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c diff --git a/drivers/gpu/drm/hisilicon/hibmc/Makefile b/drivers/gpu/drm/his= ilicon/hibmc/Makefile index 214228052ccf..95a4ed599d98 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/Makefile +++ b/drivers/gpu/drm/hisilicon/hibmc/Makefile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: GPL-2.0-only hibmc-drm-y :=3D hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm= _i2c.o \ - dp/dp_aux.o dp/dp_link.o dp/dp_hw.o + dp/dp_aux.o dp/dp_link.o dp/dp_hw.o hibmc_drm_dp.o =20 obj-$(CONFIG_DRM_HISI_HIBMC) +=3D hibmc-drm.o diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c b/drivers/gpu/d= rm/hisilicon/hibmc/hibmc_drm_dp.c new file mode 100644 index 000000000000..1e0f2ef39ba6 --- /dev/null +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c @@ -0,0 +1,128 @@ +// SPDX-License-Identifier: GPL-2.0-or-later +// Copyright (c) 2024 Hisilicon Limited. + +#include + +#include +#include +#include +#include +#include +#include + +#include "hibmc_drm_drv.h" +#include "dp/dp_hw.h" + +static int hibmc_dp_connector_get_modes(struct drm_connector *connector) +{ + int count; + + count =3D drm_add_modes_noedid(connector, connector->dev->mode_config.max= _width, + connector->dev->mode_config.max_height); + drm_set_preferred_mode(connector, 1024, 768); // temporary implementation + + return count; +} + +static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = =3D { + .get_modes =3D hibmc_dp_connector_get_modes, +}; + +static const struct drm_connector_funcs hibmc_dp_conn_funcs =3D { + .reset =3D drm_atomic_helper_connector_reset, + .fill_modes =3D drm_helper_probe_single_connector_modes, + .destroy =3D drm_connector_cleanup, + .atomic_duplicate_state =3D drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state =3D drm_atomic_helper_connector_destroy_state, +}; + +static int hibmc_dp_prepare(struct hibmc_dp *dp, struct drm_display_mode *= mode) +{ + int ret; + + hibmc_dp_display_en(dp, false); + + ret =3D hibmc_dp_mode_set(dp, mode); + if (ret) + drm_err(dp->drm_dev, "hibmc dp mode set failed: %d\n", ret); + + return ret; +} + +static void hibmc_dp_encoder_enable(struct drm_encoder *drm_encoder, + struct drm_atomic_state *state) +{ + struct hibmc_dp *dp =3D container_of(drm_encoder, struct hibmc_dp, encode= r); + struct drm_display_mode *mode =3D &drm_encoder->crtc->state->mode; + + if (hibmc_dp_prepare(dp, mode)) + return; + + hibmc_dp_display_en(dp, true); +} + +static void hibmc_dp_encoder_disable(struct drm_encoder *drm_encoder, + struct drm_atomic_state *state) +{ + struct hibmc_dp *dp =3D container_of(drm_encoder, struct hibmc_dp, encode= r); + + hibmc_dp_display_en(dp, false); +} + +static const struct drm_encoder_helper_funcs hibmc_dp_encoder_helper_funcs= =3D { + .atomic_enable =3D hibmc_dp_encoder_enable, + .atomic_disable =3D hibmc_dp_encoder_disable, +}; + +void hibmc_dp_uninit(struct hibmc_drm_private *priv) +{ + hibmc_dp_hw_uninit(&priv->dp); +} + +int hibmc_dp_init(struct hibmc_drm_private *priv) +{ + struct drm_device *dev =3D &priv->dev; + struct drm_crtc *crtc =3D &priv->crtc; + struct hibmc_dp *dp =3D &priv->dp; + struct drm_connector *connector =3D &dp->connector; + struct drm_encoder *encoder =3D &dp->encoder; + int ret; + + dp->mmio =3D priv->mmio; + dp->drm_dev =3D dev; + + ret =3D hibmc_dp_hw_init(&priv->dp); + if (ret) { + drm_err(dev, "hibmc dp hw init failed: %d\n", ret); + return ret; + } + + hibmc_dp_display_en(&priv->dp, false); + + encoder->possible_crtcs =3D drm_crtc_mask(crtc); + ret =3D drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL= ); + if (ret) { + drm_err(dev, "init dp encoder failed: %d\n", ret); + goto err_init; + } + + drm_encoder_helper_add(encoder, &hibmc_dp_encoder_helper_funcs); + + ret =3D drm_connector_init(dev, connector, &hibmc_dp_conn_funcs, + DRM_MODE_CONNECTOR_DisplayPort); + if (ret) { + drm_err(dev, "init dp connector failed: %d\n", ret); + goto err_init; + } + + drm_connector_helper_add(connector, &hibmc_dp_conn_helper_funcs); + + drm_connector_attach_encoder(connector, encoder); + + return 0; + +err_init: + hibmc_dp_hw_uninit(&priv->dp); + + return ret; +} diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c b/drivers/gpu/= drm/hisilicon/hibmc/hibmc_drm_drv.c index 9f9b19ea0587..f98ac94a18b9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c @@ -27,6 +27,10 @@ #include "hibmc_drm_drv.h" #include "hibmc_drm_regs.h" =20 +#define DP_HOST_SERDES_CTRL 0x1f001c +#define DP_HOST_SERDES_CTRL_VAL 0x8A00 +#define DP_HOST_SERDES_CTRL_MASK 0x7FFFE + DEFINE_DRM_GEM_FOPS(hibmc_fops); =20 static irqreturn_t hibmc_interrupt(int irq, void *arg) @@ -116,6 +120,14 @@ static int hibmc_kms_init(struct hibmc_drm_private *pr= iv) return ret; } =20 + /* if DP existed, init DP */ + if ((readl(priv->mmio + DP_HOST_SERDES_CTRL) & + DP_HOST_SERDES_CTRL_MASK) =3D=3D DP_HOST_SERDES_CTRL_VAL) { + ret =3D hibmc_dp_init(priv); + if (ret) + drm_err(dev, "failed to init dp: %d\n", ret); + } + ret =3D hibmc_vdac_init(priv); if (ret) { drm_err(dev, "failed to init vdac: %d\n", ret); @@ -239,6 +251,7 @@ static int hibmc_hw_init(struct hibmc_drm_private *priv) =20 static int hibmc_unload(struct drm_device *dev) { + struct hibmc_drm_private *priv =3D to_hibmc_drm_private(dev); struct pci_dev *pdev =3D to_pci_dev(dev->dev); =20 drm_atomic_helper_shutdown(dev); @@ -247,6 +260,9 @@ static int hibmc_unload(struct drm_device *dev) =20 pci_disable_msi(to_pci_dev(dev->dev)); =20 + if (priv->dp.encoder.possible_crtcs) + hibmc_dp_uninit(priv); + return 0; } =20 diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h b/drivers/gpu/= drm/hisilicon/hibmc/hibmc_drm_drv.h index 6b566f3aeecb..1b78d313a6c2 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h @@ -19,10 +19,12 @@ #include =20 #include +#include "dp/dp_hw.h" =20 -struct hibmc_connector { - struct drm_connector base; - +struct hibmc_vdac { + struct drm_device *dev; + struct drm_encoder encoder; + struct drm_connector connector; struct i2c_adapter adapter; struct i2c_algo_bit_data bit_data; }; @@ -35,13 +37,13 @@ struct hibmc_drm_private { struct drm_device dev; struct drm_plane primary_plane; struct drm_crtc crtc; - struct drm_encoder encoder; - struct hibmc_connector connector; + struct hibmc_dp dp; + struct hibmc_vdac vdac; }; =20 -static inline struct hibmc_connector *to_hibmc_connector(struct drm_connec= tor *connector) +static inline struct hibmc_vdac *to_hibmc_vdac(struct drm_connector *conne= ctor) { - return container_of(connector, struct hibmc_connector, base); + return container_of(connector, struct hibmc_vdac, connector); } =20 static inline struct hibmc_drm_private *to_hibmc_drm_private(struct drm_de= vice *dev) @@ -57,6 +59,9 @@ void hibmc_set_current_gate(struct hibmc_drm_private *pri= v, int hibmc_de_init(struct hibmc_drm_private *priv); int hibmc_vdac_init(struct hibmc_drm_private *priv); =20 -int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_connector *c= onnector); +int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *connec= tor); + +int hibmc_dp_init(struct hibmc_drm_private *priv); +void hibmc_dp_uninit(struct hibmc_drm_private *priv); =20 #endif diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c b/drivers/gpu/= drm/hisilicon/hibmc/hibmc_drm_i2c.c index e6e48651c15c..99b3b77b5445 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c @@ -25,8 +25,8 @@ =20 static void hibmc_set_i2c_signal(void *data, u32 mask, int value) { - struct hibmc_connector *hibmc_connector =3D data; - struct hibmc_drm_private *priv =3D to_hibmc_drm_private(hibmc_connector->= base.dev); + struct hibmc_vdac *vdac =3D data; + struct hibmc_drm_private *priv =3D to_hibmc_drm_private(vdac->connector.d= ev); u32 tmp_dir =3D readl(priv->mmio + GPIO_DATA_DIRECTION); =20 if (value) { @@ -45,8 +45,8 @@ static void hibmc_set_i2c_signal(void *data, u32 mask, in= t value) =20 static int hibmc_get_i2c_signal(void *data, u32 mask) { - struct hibmc_connector *hibmc_connector =3D data; - struct hibmc_drm_private *priv =3D to_hibmc_drm_private(hibmc_connector->= base.dev); + struct hibmc_vdac *vdac =3D data; + struct hibmc_drm_private *priv =3D to_hibmc_drm_private(vdac->connector.d= ev); u32 tmp_dir =3D readl(priv->mmio + GPIO_DATA_DIRECTION); =20 if ((tmp_dir & mask) !=3D mask) { @@ -77,22 +77,21 @@ static int hibmc_ddc_getscl(void *data) return hibmc_get_i2c_signal(data, I2C_SCL_MASK); } =20 -int hibmc_ddc_create(struct drm_device *drm_dev, - struct hibmc_connector *connector) +int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *vdac) { - connector->adapter.owner =3D THIS_MODULE; - snprintf(connector->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus"); - connector->adapter.dev.parent =3D drm_dev->dev; - i2c_set_adapdata(&connector->adapter, connector); - connector->adapter.algo_data =3D &connector->bit_data; - - connector->bit_data.udelay =3D 20; - connector->bit_data.timeout =3D usecs_to_jiffies(2000); - connector->bit_data.data =3D connector; - connector->bit_data.setsda =3D hibmc_ddc_setsda; - connector->bit_data.setscl =3D hibmc_ddc_setscl; - connector->bit_data.getsda =3D hibmc_ddc_getsda; - connector->bit_data.getscl =3D hibmc_ddc_getscl; - - return i2c_bit_add_bus(&connector->adapter); + vdac->adapter.owner =3D THIS_MODULE; + snprintf(vdac->adapter.name, I2C_NAME_SIZE, "HIS i2c bit bus"); + vdac->adapter.dev.parent =3D drm_dev->dev; + i2c_set_adapdata(&vdac->adapter, vdac); + vdac->adapter.algo_data =3D &vdac->bit_data; + + vdac->bit_data.udelay =3D 20; + vdac->bit_data.timeout =3D usecs_to_jiffies(2000); + vdac->bit_data.data =3D vdac; + vdac->bit_data.setsda =3D hibmc_ddc_setsda; + vdac->bit_data.setscl =3D hibmc_ddc_setscl; + vdac->bit_data.getsda =3D hibmc_ddc_getsda; + vdac->bit_data.getscl =3D hibmc_ddc_getscl; + + return i2c_bit_add_bus(&vdac->adapter); } diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c b/drivers/gpu= /drm/hisilicon/hibmc/hibmc_drm_vdac.c index 409c551c92af..05e19ea4c9f9 100644 --- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c @@ -24,11 +24,11 @@ =20 static int hibmc_connector_get_modes(struct drm_connector *connector) { - struct hibmc_connector *hibmc_connector =3D to_hibmc_connector(connector); + struct hibmc_vdac *vdac =3D to_hibmc_vdac(connector); const struct drm_edid *drm_edid; int count; =20 - drm_edid =3D drm_edid_read_ddc(connector, &hibmc_connector->adapter); + drm_edid =3D drm_edid_read_ddc(connector, &vdac->adapter); =20 drm_edid_connector_update(connector, drm_edid); =20 @@ -51,9 +51,9 @@ static int hibmc_connector_get_modes(struct drm_connector= *connector) =20 static void hibmc_connector_destroy(struct drm_connector *connector) { - struct hibmc_connector *hibmc_connector =3D to_hibmc_connector(connector); + struct hibmc_vdac *vdac =3D to_hibmc_vdac(connector); =20 - i2c_del_adapter(&hibmc_connector->adapter); + i2c_del_adapter(&vdac->adapter); drm_connector_cleanup(connector); } =20 @@ -93,20 +93,20 @@ static const struct drm_encoder_helper_funcs hibmc_enco= der_helper_funcs =3D { int hibmc_vdac_init(struct hibmc_drm_private *priv) { struct drm_device *dev =3D &priv->dev; - struct hibmc_connector *hibmc_connector =3D &priv->connector; - struct drm_encoder *encoder =3D &priv->encoder; + struct hibmc_vdac *vdac =3D &priv->vdac; + struct drm_encoder *encoder =3D &vdac->encoder; struct drm_crtc *crtc =3D &priv->crtc; - struct drm_connector *connector =3D &hibmc_connector->base; + struct drm_connector *connector =3D &vdac->connector; int ret; =20 - ret =3D hibmc_ddc_create(dev, hibmc_connector); + ret =3D hibmc_ddc_create(dev, vdac); if (ret) { drm_err(dev, "failed to create ddc: %d\n", ret); return ret; } =20 encoder->possible_crtcs =3D drm_crtc_mask(crtc); - ret =3D drm_simple_encoder_init(dev, encoder, DRM_MODE_ENCODER_DAC); + ret =3D drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_DAC, NULL); if (ret) { drm_err(dev, "failed to init encoder: %d\n", ret); return ret; @@ -117,7 +117,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) ret =3D drm_connector_init_with_ddc(dev, connector, &hibmc_connector_funcs, DRM_MODE_CONNECTOR_VGA, - &hibmc_connector->adapter); + &vdac->adapter); if (ret) { drm_err(dev, "failed to init connector: %d\n", ret); return ret; --=20 2.33.0