6d98fdc06f6cce314eb27fc0c42fb43d0b6daba7
[linux-2.6-microblaze.git] / drivers / gpu / drm / hisilicon / hibmc / hibmc_drm_vdac.c
1 // SPDX-License-Identifier: GPL-2.0-or-later
2 /* Hisilicon Hibmc SoC drm driver
3  *
4  * Based on the bochs drm driver.
5  *
6  * Copyright (c) 2016 Huawei Limited.
7  *
8  * Author:
9  *      Rongrong Zou <zourongrong@huawei.com>
10  *      Rongrong Zou <zourongrong@gmail.com>
11  *      Jianhua Li <lijianhua@huawei.com>
12  */
13
14 #include <drm/drm_atomic_helper.h>
15 #include <drm/drm_probe_helper.h>
16 #include <drm/drm_print.h>
17
18 #include "hibmc_drm_drv.h"
19 #include "hibmc_drm_regs.h"
20
21 static int hibmc_connector_get_modes(struct drm_connector *connector)
22 {
23         return drm_add_modes_noedid(connector, 800, 600);
24 }
25
26 static enum drm_mode_status hibmc_connector_mode_valid(struct drm_connector *connector,
27                                       struct drm_display_mode *mode)
28 {
29         return MODE_OK;
30 }
31
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,
36 };
37
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,
44 };
45
46 static struct drm_connector *
47 hibmc_connector_init(struct hibmc_drm_private *priv)
48 {
49         struct drm_device *dev = priv->dev;
50         struct drm_connector *connector;
51         int ret;
52
53         connector = devm_kzalloc(dev->dev, sizeof(*connector), GFP_KERNEL);
54         if (!connector) {
55                 DRM_ERROR("failed to alloc memory when init connector\n");
56                 return ERR_PTR(-ENOMEM);
57         }
58
59         ret = drm_connector_init(dev, connector,
60                                  &hibmc_connector_funcs,
61                                  DRM_MODE_CONNECTOR_VGA);
62         if (ret) {
63                 DRM_ERROR("failed to init connector: %d\n", ret);
64                 return ERR_PTR(ret);
65         }
66         drm_connector_helper_add(connector,
67                                  &hibmc_connector_helper_funcs);
68
69         return connector;
70 }
71
72 static void hibmc_encoder_mode_set(struct drm_encoder *encoder,
73                                    struct drm_display_mode *mode,
74                                    struct drm_display_mode *adj_mode)
75 {
76         u32 reg;
77         struct drm_device *dev = encoder->dev;
78         struct hibmc_drm_private *priv = dev->dev_private;
79
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);
86 }
87
88 static const struct drm_encoder_helper_funcs hibmc_encoder_helper_funcs = {
89         .mode_set = hibmc_encoder_mode_set,
90 };
91
92 static const struct drm_encoder_funcs hibmc_encoder_funcs = {
93         .destroy = drm_encoder_cleanup,
94 };
95
96 int hibmc_vdac_init(struct hibmc_drm_private *priv)
97 {
98         struct drm_device *dev = priv->dev;
99         struct drm_encoder *encoder;
100         struct drm_connector *connector;
101         int ret;
102
103         connector = hibmc_connector_init(priv);
104         if (IS_ERR(connector)) {
105                 DRM_ERROR("failed to create connector: %ld\n",
106                           PTR_ERR(connector));
107                 return PTR_ERR(connector);
108         }
109
110         encoder = devm_kzalloc(dev->dev, sizeof(*encoder), GFP_KERNEL);
111         if (!encoder) {
112                 DRM_ERROR("failed to alloc memory when init encoder\n");
113                 return -ENOMEM;
114         }
115
116         encoder->possible_crtcs = 0x1;
117         ret = drm_encoder_init(dev, encoder, &hibmc_encoder_funcs,
118                                DRM_MODE_ENCODER_DAC, NULL);
119         if (ret) {
120                 DRM_ERROR("failed to init encoder: %d\n", ret);
121                 return ret;
122         }
123
124         drm_encoder_helper_add(encoder, &hibmc_encoder_helper_funcs);
125         drm_connector_attach_encoder(connector, encoder);
126
127         return 0;
128 }