Skip to content

Commit 0ab6ea2

Browse files
Baihan Lilumag
authored andcommitted
drm/hisilicon/hibmc: add dp module in hibmc
To support DP interface displaying in hibmc driver. Add a encoder and connector for DP modual. The HPD function and get_edid function will be add in next series, so temporarily using 1024x768 as default in hibmc_dp_connector_get_modes() Signed-off-by: Baihan Li <[email protected]> Signed-off-by: Yongbang Shi <[email protected]> Reviewed-by: Dmitry Baryshkov <[email protected]> Reviewed-by: Tian Tao <[email protected]> Link: https://patchwork.freedesktop.org/patch/msgid/[email protected] Signed-off-by: Dmitry Baryshkov <[email protected]>
1 parent 587013d commit 0ab6ea2

File tree

4 files changed

+138
-1
lines changed

4 files changed

+138
-1
lines changed
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
# SPDX-License-Identifier: GPL-2.0-only
22
hibmc-drm-y := hibmc_drm_drv.o hibmc_drm_de.o hibmc_drm_vdac.o hibmc_drm_i2c.o \
3-
dp/dp_aux.o dp/dp_link.o dp/dp_hw.o
3+
dp/dp_aux.o dp/dp_link.o dp/dp_hw.o hibmc_drm_dp.o
44

55
obj-$(CONFIG_DRM_HISI_HIBMC) += hibmc-drm.o
Lines changed: 118 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
// SPDX-License-Identifier: GPL-2.0-or-later
2+
// Copyright (c) 2024 Hisilicon Limited.
3+
4+
#include <linux/io.h>
5+
6+
#include <drm/drm_probe_helper.h>
7+
#include <drm/drm_simple_kms_helper.h>
8+
#include <drm/drm_atomic_helper.h>
9+
#include <drm/drm_modes.h>
10+
#include <drm/drm_drv.h>
11+
#include <drm/drm_edid.h>
12+
13+
#include "hibmc_drm_drv.h"
14+
#include "dp/dp_hw.h"
15+
16+
static int hibmc_dp_connector_get_modes(struct drm_connector *connector)
17+
{
18+
int count;
19+
20+
count = drm_add_modes_noedid(connector, connector->dev->mode_config.max_width,
21+
connector->dev->mode_config.max_height);
22+
drm_set_preferred_mode(connector, 1024, 768); // temporary implementation
23+
24+
return count;
25+
}
26+
27+
static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
28+
.get_modes = hibmc_dp_connector_get_modes,
29+
};
30+
31+
static const struct drm_connector_funcs hibmc_dp_conn_funcs = {
32+
.reset = drm_atomic_helper_connector_reset,
33+
.fill_modes = drm_helper_probe_single_connector_modes,
34+
.destroy = drm_connector_cleanup,
35+
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
36+
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
37+
};
38+
39+
static inline int hibmc_dp_prepare(struct hibmc_dp *dp, struct drm_display_mode *mode)
40+
{
41+
int ret;
42+
43+
hibmc_dp_display_en(dp, false);
44+
45+
ret = hibmc_dp_mode_set(dp, mode);
46+
if (ret)
47+
drm_err(dp->drm_dev, "hibmc dp mode set failed: %d\n", ret);
48+
49+
return ret;
50+
}
51+
52+
static void hibmc_dp_encoder_enable(struct drm_encoder *drm_encoder,
53+
struct drm_atomic_state *state)
54+
{
55+
struct hibmc_dp *dp = container_of(drm_encoder, struct hibmc_dp, encoder);
56+
struct drm_display_mode *mode = &drm_encoder->crtc->state->mode;
57+
58+
if (hibmc_dp_prepare(dp, mode))
59+
return;
60+
61+
hibmc_dp_display_en(dp, true);
62+
}
63+
64+
static void hibmc_dp_encoder_disable(struct drm_encoder *drm_encoder,
65+
struct drm_atomic_state *state)
66+
{
67+
struct hibmc_dp *dp = container_of(drm_encoder, struct hibmc_dp, encoder);
68+
69+
hibmc_dp_display_en(dp, false);
70+
}
71+
72+
static const struct drm_encoder_helper_funcs hibmc_dp_encoder_helper_funcs = {
73+
.atomic_enable = hibmc_dp_encoder_enable,
74+
.atomic_disable = hibmc_dp_encoder_disable,
75+
};
76+
77+
int hibmc_dp_init(struct hibmc_drm_private *priv)
78+
{
79+
struct drm_device *dev = &priv->dev;
80+
struct drm_crtc *crtc = &priv->crtc;
81+
struct hibmc_dp *dp = &priv->dp;
82+
struct drm_connector *connector = &dp->connector;
83+
struct drm_encoder *encoder = &dp->encoder;
84+
int ret;
85+
86+
dp->mmio = priv->mmio;
87+
dp->drm_dev = dev;
88+
89+
ret = hibmc_dp_hw_init(&priv->dp);
90+
if (ret) {
91+
drm_err(dev, "hibmc dp hw init failed: %d\n", ret);
92+
return ret;
93+
}
94+
95+
hibmc_dp_display_en(&priv->dp, false);
96+
97+
encoder->possible_crtcs = drm_crtc_mask(crtc);
98+
ret = drmm_encoder_init(dev, encoder, NULL, DRM_MODE_ENCODER_TMDS, NULL);
99+
if (ret) {
100+
drm_err(dev, "init dp encoder failed: %d\n", ret);
101+
return ret;
102+
}
103+
104+
drm_encoder_helper_add(encoder, &hibmc_dp_encoder_helper_funcs);
105+
106+
ret = drm_connector_init(dev, connector, &hibmc_dp_conn_funcs,
107+
DRM_MODE_CONNECTOR_DisplayPort);
108+
if (ret) {
109+
drm_err(dev, "init dp connector failed: %d\n", ret);
110+
return ret;
111+
}
112+
113+
drm_connector_helper_add(connector, &hibmc_dp_conn_helper_funcs);
114+
115+
drm_connector_attach_encoder(connector, encoder);
116+
117+
return 0;
118+
}

drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@
2828
#include "hibmc_drm_drv.h"
2929
#include "hibmc_drm_regs.h"
3030

31+
#define HIBMC_DP_HOST_SERDES_CTRL 0x1f001c
32+
#define HIBMC_DP_HOST_SERDES_CTRL_VAL 0x8a00
33+
#define HIBMC_DP_HOST_SERDES_CTRL_MASK 0x7ffff
34+
3135
DEFINE_DRM_GEM_FOPS(hibmc_fops);
3236

3337
static irqreturn_t hibmc_interrupt(int irq, void *arg)
@@ -117,6 +121,14 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv)
117121
return ret;
118122
}
119123

124+
/* if DP existed, init DP */
125+
if ((readl(priv->mmio + HIBMC_DP_HOST_SERDES_CTRL) &
126+
HIBMC_DP_HOST_SERDES_CTRL_MASK) == HIBMC_DP_HOST_SERDES_CTRL_VAL) {
127+
ret = hibmc_dp_init(priv);
128+
if (ret)
129+
drm_err(dev, "failed to init dp: %d\n", ret);
130+
}
131+
120132
ret = hibmc_vdac_init(priv);
121133
if (ret) {
122134
drm_err(dev, "failed to init vdac: %d\n", ret);
@@ -327,6 +339,8 @@ static int hibmc_pci_probe(struct pci_dev *pdev,
327339
goto err_return;
328340
}
329341

342+
pci_set_master(pdev);
343+
330344
ret = hibmc_load(dev);
331345
if (ret) {
332346
drm_err(dev, "failed to load hibmc: %d\n", ret);

drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020

2121
#include <drm/drm_framebuffer.h>
2222

23+
#include "dp/dp_hw.h"
24+
2325
struct hibmc_vdac {
2426
struct drm_device *dev;
2527
struct drm_encoder encoder;
@@ -37,6 +39,7 @@ struct hibmc_drm_private {
3739
struct drm_plane primary_plane;
3840
struct drm_crtc crtc;
3941
struct hibmc_vdac vdac;
42+
struct hibmc_dp dp;
4043
};
4144

4245
static inline struct hibmc_vdac *to_hibmc_vdac(struct drm_connector *connector)
@@ -59,4 +62,6 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv);
5962

6063
int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *connector);
6164

65+
int hibmc_dp_init(struct hibmc_drm_private *priv);
66+
6267
#endif

0 commit comments

Comments
 (0)