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