1 /*
2 * Copyright (c) 2006-2023, RT-Thread Development Team
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 *
6 * Email: opensource_embedded@phytium.com.cn
7 *
8 * Change Logs:
9 * Date Author Notes
10 * 2023-11-07 wangzongqiang first version
11 *
12 */
13 #include <string.h>
14 #include "rtconfig.h"
15 #include <rtthread.h>
16 #include <rtdevice.h>
17 #define LOG_TAG "dc_drv"
18 #include "drv_log.h"
19 #include "drv_dc.h"
20 #include "mm_aspace.h"
21 #include "fparameters.h"
22 #include "fdcdp.h"
23 #include "fdc.h"
24 #include "fdp_hw.h"
25
26
27 #ifdef RT_USING_SMART
28 #include "ioremap.h"
29 #endif
30 static rt_uint8_t _rt_framebuffer[1024 * 768 * 4] __aligned(128) = {0};
31
32 static struct rt_device_graphic_info _dc_info;
33
34 typedef struct
35 {
36 u32 bit_depth;
37 u32 bpc;
38 u32 color_depth;
39 u32 clock_mode;
40 u32 color_rep;
41 u32 width;
42 u32 height;
43 } FuserCfg;
44
45 static const FuserCfg user_cfg = {
46 .bit_depth = 8,
47 .bpc = 8,
48 .color_depth = 32,
49 .clock_mode = 1,
50 .color_rep = 0,
51 .width = 640,
52 .height = 480
53 };
54
55 void rt_hw_dc_register(struct phytium_dc_bus *dc_control_bus, const char *name, rt_uint32_t flag, void *data);
56
dc_config(struct phytium_dc_bus * dc_control_bus)57 static rt_err_t dc_config(struct phytium_dc_bus *dc_control_bus)
58 {
59 RT_ASSERT(dc_control_bus);
60 rt_uint32_t chan = dc_control_bus->fdc_id;
61 FDcDp *instance_p = &dc_control_bus->dc_handle;
62
63 return RT_EOK;
64 }
65
rt_dc_init(struct phytium_dc_bus * device)66 static rt_err_t rt_dc_init(struct phytium_dc_bus *device)
67 {
68 RT_ASSERT(device != RT_NULL);
69 rt_err_t ret;
70 FDcDp *instance_p = &device->dc_handle;
71 rt_uint32_t chan = device->fdc_id;
72
73 FDcDpCfgInitialize(instance_p, chan);
74 instance_p->dc_instance_p[chan].config = *FDcLookupConfig(chan);
75 instance_p->dp_instance_p[chan].config = *FDpLookupConfig(chan);
76 instance_p->dc_instance_p[chan].crtc.bpc = user_cfg.bpc;
77 instance_p->dc_instance_p[chan].color_depth = user_cfg.color_depth;
78 instance_p->dc_instance_p[chan].channel = chan;
79 instance_p->dc_instance_p[chan].fb_addr = (uintptr)_rt_framebuffer;/*当前例程虚拟地址和物理地址一致,实际需要根据需要进行映射*/
80 instance_p->dc_instance_p[chan].fb_virtual = (uintptr)_rt_framebuffer;
81 instance_p->dp_instance_p[chan].trans_config.clock_mode = user_cfg.clock_mode;
82 instance_p->dp_instance_p[chan].trans_config.color_rep_format = user_cfg.color_rep;
83 instance_p->dp_instance_p[chan].trans_config.bit_depth = user_cfg.bit_depth;
84
85 FDcDpGeneralCfgInitial(instance_p, chan);
86 _dc_info.framebuffer = (rt_uint8_t *)instance_p->dc_instance_p[chan].fb_addr;
87 _dc_info.bits_per_pixel = DISPLAY_COLOR_DEPTH;
88 _dc_info.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB565P;
89 _dc_info.width = FB_XSIZE;
90 _dc_info.height = FB_YSIZE;
91 rt_hw_dc_register(device, device->name, RT_DEVICE_FLAG_RDWR, NULL);
92 dc_config(device);
93 ret = FDcDpInitial(instance_p, device->fdc_id, user_cfg.width, user_cfg.height);
94 if (ret != RT_EOK)
95 {
96 LOG_E("Init dc failed, ret: 0x%x", ret);
97 return -RT_ERROR;;
98 }
99 return RT_EOK;
100 }
101
rt_dc_control(rt_device_t dev,int cmd,void * args)102 static rt_err_t rt_dc_control(rt_device_t dev, int cmd, void *args)
103 {
104 RT_ASSERT(dev);
105 struct phytium_dc_bus *dc_bus;
106 dc_bus = (struct phytium_dc_bus *)(dev);
107
108 switch (cmd)
109 {
110 case RTGRAPHIC_CTRL_RECT_UPDATE:
111 break;
112 case RTGRAPHIC_CTRL_POWERON:
113 break;
114 case RTGRAPHIC_CTRL_POWEROFF:
115 break;
116 case RTGRAPHIC_CTRL_GET_INFO:
117 rt_memcpy(args, &_dc_info, sizeof(_dc_info));
118 break;
119 case RTGRAPHIC_CTRL_SET_MODE:
120 break;
121 }
122 return RT_EOK;
123 }
124
125 #ifdef RT_USING_DEVICE_OPS
126 const static struct rt_device_ops dc_ops =
127 {
128 rt_dc_init,
129 RT_NULL,
130 RT_NULL,
131 RT_NULL,
132 RT_NULL,
133 rt_dc_control
134 };
135 #endif
136
rt_hw_dc_register(struct phytium_dc_bus * dc_control_bus,const char * name,rt_uint32_t flag,void * data)137 void rt_hw_dc_register(struct phytium_dc_bus *dc_control_bus, const char *name, rt_uint32_t flag, void *data)
138 {
139 RT_ASSERT(dc_control_bus != RT_NULL);
140 struct rt_device *dc;
141 dc = &(dc_control_bus->parent);
142 dc->type = RT_Device_Class_Graphic;
143 #ifdef RT_USING_DEVICE_OPS
144 dc->ops = &dc_ops;
145 #else
146 dc->init = rt_dc_init;
147 dc->control = rt_dc_control;
148 #endif
149 dc->user_data = data;
150 /* register Display Controller device to RT-Thread */
151 rt_device_register(dc, name, RT_DEVICE_FLAG_RDWR);
152 }
153
154 #if defined(RT_USING_DC_CHANNEL0)
155 static struct phytium_dc_bus dev_dc0;
156 #endif
157 #if defined(RT_USING_DC_CHANNEL1)
158 static struct phytium_dc_bus dev_dc1;
159 #endif
160
rt_hw_dc_init(void)161 int rt_hw_dc_init(void)
162 {
163 #if defined(RT_USING_DC_CHANNEL0)
164 dev_dc0.name = "DC0";
165 dev_dc0.fdc_id = FDCDP_ID0;
166 rt_dc_init(&dev_dc0);
167 #endif
168 #if defined(RT_USING_DC_CHANNEL1)
169 dev_dc1.name = "DC1";
170 dev_dc1.fdc_id = FDCDP_ID1;
171 rt_dc_init(&dev_dc1);
172 #endif
173 return RT_EOK;
174 }
175
176 INIT_DEVICE_EXPORT(rt_hw_dc_init);
177