1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Hisilicon Hibmc SoC drm driver
4 * Based on the bochs drm driver.
6 * Copyright (c) 2016 Huawei Limited.
9 * Rongrong Zou <zourongrong@huawei.com>
10 * Rongrong Zou <zourongrong@gmail.com>
11 * Jianhua Li <lijianhua@huawei.com>
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_probe_helper.h>
16 #include <drm/drm_print.h>
18 #include "hibmc_drm_drv.h"
19 #include "hibmc_drm_regs.h"
21 static int hibmc_connector_get_modes(struct drm_connector
*connector
)
23 return drm_add_modes_noedid(connector
, 800, 600);
26 static enum drm_mode_status
hibmc_connector_mode_valid(struct drm_connector
*connector
,
27 struct drm_display_mode
*mode
)
32 static const struct drm_connector_helper_funcs
33 hibmc_connector_helper_funcs
= {
34 .get_modes
= hibmc_connector_get_modes
,
35 .mode_valid
= hibmc_connector_mode_valid
,
38 static const struct drm_connector_funcs hibmc_connector_funcs
= {
39 .fill_modes
= drm_helper_probe_single_connector_modes
,
40 .destroy
= drm_connector_cleanup
,
41 .reset
= drm_atomic_helper_connector_reset
,
42 .atomic_duplicate_state
= drm_atomic_helper_connector_duplicate_state
,
43 .atomic_destroy_state
= drm_atomic_helper_connector_destroy_state
,
46 static struct drm_connector
*
47 hibmc_connector_init(struct hibmc_drm_private
*priv
)
49 struct drm_device
*dev
= priv
->dev
;
50 struct drm_connector
*connector
;
53 connector
= devm_kzalloc(dev
->dev
, sizeof(*connector
), GFP_KERNEL
);
55 DRM_ERROR("failed to alloc memory when init connector\n");
56 return ERR_PTR(-ENOMEM
);
59 ret
= drm_connector_init(dev
, connector
,
60 &hibmc_connector_funcs
,
61 DRM_MODE_CONNECTOR_VGA
);
63 DRM_ERROR("failed to init connector: %d\n", ret
);
66 drm_connector_helper_add(connector
,
67 &hibmc_connector_helper_funcs
);
72 static void hibmc_encoder_mode_set(struct drm_encoder
*encoder
,
73 struct drm_display_mode
*mode
,
74 struct drm_display_mode
*adj_mode
)
77 struct drm_device
*dev
= encoder
->dev
;
78 struct hibmc_drm_private
*priv
= dev
->dev_private
;
80 reg
= readl(priv
->mmio
+ HIBMC_DISPLAY_CONTROL_HISILE
);
81 reg
|= HIBMC_DISPLAY_CONTROL_FPVDDEN(1);
82 reg
|= HIBMC_DISPLAY_CONTROL_PANELDATE(1);
83 reg
|= HIBMC_DISPLAY_CONTROL_FPEN(1);
84 reg
|= HIBMC_DISPLAY_CONTROL_VBIASEN(1);
85 writel(reg
, priv
->mmio
+ HIBMC_DISPLAY_CONTROL_HISILE
);
88 static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs
= {
89 .mode_set
= hibmc_encoder_mode_set
,
92 static const struct drm_encoder_funcs hibmc_encoder_funcs
= {
93 .destroy
= drm_encoder_cleanup
,
96 int hibmc_vdac_init(struct hibmc_drm_private
*priv
)
98 struct drm_device
*dev
= priv
->dev
;
99 struct drm_encoder
*encoder
;
100 struct drm_connector
*connector
;
103 connector
= hibmc_connector_init(priv
);
104 if (IS_ERR(connector
)) {
105 DRM_ERROR("failed to create connector: %ld\n",
107 return PTR_ERR(connector
);
110 encoder
= devm_kzalloc(dev
->dev
, sizeof(*encoder
), GFP_KERNEL
);
112 DRM_ERROR("failed to alloc memory when init encoder\n");
116 encoder
->possible_crtcs
= 0x1;
117 ret
= drm_encoder_init(dev
, encoder
, &hibmc_encoder_funcs
,
118 DRM_MODE_ENCODER_DAC
, NULL
);
120 DRM_ERROR("failed to init encoder: %d\n", ret
);
124 drm_encoder_helper_add(encoder
, &hibmc_encoder_helper_funcs
);
125 drm_connector_attach_encoder(connector
, encoder
);