123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323 |
- /*
- * Copyright (c) 2006-2021, RT-Thread Development Team
- *
- * SPDX-License-Identifier: Apache-2.0
- *
- * Change Logs:
- * Date Author Notes
- * 2020-10-26 bigmagic first version
- */
- #include <stdint.h>
- #include <rtthread.h>
- #include "mbox.h"
- #include "drv_hdmi.h"
- #ifdef USING_LCD_CONSOLE
- #include "lcd_console.h"
- #endif
- #if defined(BSP_USING_HDMI_DISPLAY) || defined(BSP_USING_DSI_DISPLAY)
- #define LCD_WIDTH (800)
- #define LCD_HEIGHT (480)
- #define LCD_DEPTH (4)
- #define LCD_BPP (32)
- #define TAG_ALLOCATE_BUFFER 0x00040001
- #define TAG_SET_PHYS_WIDTH_HEIGHT 0x00048003
- #define TAG_SET_VIRT_WIDTH_HEIGHT 0x00048004
- #define TAG_SET_DEPTH 0x00048005
- #define TAG_SET_PIXEL_ORDER 0x00048006
- #define TAG_GET_PITCH 0x00040008
- #define TAG_SET_VIRT_OFFSET 0x00048009
- #define TAG_END 0x00000000
- enum {
- MBOX_TAG_FB_GET_GPIOVIRT = 0x00040010,
- MBOX_TAG_FB_ALLOCATE_BUFFER = 0x00040001,
- MBOX_TAG_FB_RELEASE_BUFFER = 0x00048001,
- MBOX_TAG_FB_BLANK_SCREEN = 0x00040002,
- MBOX_TAG_FB_GET_PHYS_WH = 0x00040003,
- MBOX_TAG_FB_TEST_PHYS_WH = 0x00044003,
- MBOX_TAG_FB_SET_PHYS_WH = 0x00048003,
- MBOX_TAG_FB_GET_VIRT_WH = 0x00040004,
- MBOX_TAG_FB_TEST_VIRT_WH = 0x00044004,
- MBOX_TAG_FB_SET_VIRT_WH = 0x00048004,
- MBOX_TAG_FB_GET_DEPTH = 0x00040005,
- MBOX_TAG_FB_TEST_DEPTH = 0x00044005,
- MBOX_TAG_FB_SET_DEPTH = 0x00048005,
- MBOX_TAG_FB_GET_PIXEL_ORDER = 0x00040006,
- MBOX_TAG_FB_TEST_PIXEL_ORDER = 0x00044006,
- MBOX_TAG_FB_SET_PIXEL_ORDER = 0x00048006,
- MBOX_TAG_FB_GET_ALPHA_MODE = 0x00040007,
- MBOX_TAG_FB_TEST_ALPHA_MODE = 0x00044007,
- MBOX_TAG_FB_SET_ALPHA_MODE = 0x00048007,
- MBOX_TAG_FB_GET_PITCH = 0x00040008,
- MBOX_TAG_FB_GET_VIRT_OFFSET = 0x00040009,
- MBOX_TAG_FB_TEST_VIRT_OFFSET = 0x00044009,
- MBOX_TAG_FB_SET_VIRT_OFFSET = 0x00048009,
- MBOX_TAG_FB_GET_OVERSCAN = 0x0004000a,
- MBOX_TAG_FB_TEST_OVERSCAN = 0x0004400a,
- MBOX_TAG_FB_SET_OVERSCAN = 0x0004800a,
- MBOX_TAG_FB_GET_PALETTE = 0x0004000b,
- MBOX_TAG_FB_TEST_PALETTE = 0x0004400b,
- MBOX_TAG_FB_SET_PALETTE = 0x0004800b,
- };
- #define LCD_DEVICE(dev) (struct rt_hdmi_fb_device*)(dev)
- static struct rt_hdmi_fb_device _hdmi;
- typedef rt_uint16_t color_t;
- rt_err_t hdmi_fb_open(rt_device_t dev, rt_uint16_t oflag)
- {
- return RT_EOK;
- }
- rt_err_t hdmi_fb_close(rt_device_t dev)
- {
- return RT_EOK;
- }
- rt_size_t hdmi_fb_read(rt_device_t dev, rt_off_t pos, void *buf, rt_size_t size)
- {
- return 0;
- }
- rt_size_t hdmi_fb_write(rt_device_t dev, rt_off_t pos, const void *buffer, rt_size_t size)
- {
- #ifdef USING_LCD_CONSOLE
- fb_print((char*)buffer);
- #endif
- return size;
- }
- rt_err_t hdmi_fb_control(rt_device_t dev, int cmd, void *args)
- {
- struct rt_hdmi_fb_device *lcd = LCD_DEVICE(dev);
- switch (cmd)
- {
- case RTGRAPHIC_CTRL_RECT_UPDATE:
- {
- struct rt_device_rect_info *info = (struct rt_device_rect_info*)args;
- info = info;
- }
- break;
- case RTGRAPHIC_CTRL_GET_INFO:
- {
- struct rt_device_graphic_info* info = (struct rt_device_graphic_info*)args;
- RT_ASSERT(info != RT_NULL);
- info->pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
- info->bits_per_pixel= 32;
- info->width = lcd->width;
- info->height = lcd->height;
- info->framebuffer = lcd->fb;
- }
- break;
- }
- return RT_EOK;
- }
- #ifdef RT_USING_DEVICE_OPS
- const static struct rt_device_ops hdmi_fb_ops =
- {
- RT_NULL,
- hdmi_fb_open,
- hdmi_fb_close,
- hdmi_fb_read,
- hdmi_fb_write,
- hdmi_fb_control,
- };
- #endif
- rt_err_t rt_hdmi_fb_device_init(struct rt_hdmi_fb_device *hdmi_fb, const char *name)
- {
- struct rt_device *device;
- RT_ASSERT(hdmi_fb != RT_NULL);
- device = &hdmi_fb->parent;
- /* set device type */
- device->type = RT_Device_Class_Graphic;
- /* initialize device interface */
- #ifdef RT_USING_DEVICE_OPS
- device->ops = &hdmi_fb_ops;
- #else
- device->init = RT_NULL;
- device->open = hdmi_fb_open;
- device->close = hdmi_fb_close;
- device->read = hdmi_fb_read;
- device->write = hdmi_fb_write;
- device->control = hdmi_fb_control;
- #endif
- /* register to device manager */
- rt_device_register(device, name, RT_DEVICE_FLAG_RDWR);
- return RT_EOK;
- }
- rt_uint32_t bcm271x_mbox_fb_get_gpiovirt(void)
- {
- mbox[0] = 8*4; // length of the message
- mbox[1] = MBOX_REQUEST; // this is a request message
- mbox[2] = MBOX_TAG_FB_GET_GPIOVIRT;
- mbox[3] = 4; // buffer size
- mbox[4] = 0; // len
- mbox[5] = 0; // id
- mbox[6] = 0;
- mbox[7] = MBOX_TAG_LAST;
- mbox_call(8, MMU_DISABLE);
- return (mbox[5] & 0x3fffffff);
- }
- rt_uint32_t bcm271x_mbox_fb_get_pitch(void)
- {
- mbox[0] = 8*4; // length of the message
- mbox[1] = MBOX_REQUEST; // this is a request message
- mbox[2] = MBOX_TAG_FB_GET_PITCH;
- mbox[3] = 4; // buffer size
- mbox[4] = 0; // len
- mbox[5] = 0; // id
- mbox[6] = 0;
- mbox[7] = MBOX_TAG_LAST;
- mbox_call(8, MMU_DISABLE);
- return mbox[5];
- }
- void bcm271x_mbox_fb_set_porder(int rgb)
- {
- mbox[0] = 8*4; // length of the message
- mbox[1] = MBOX_REQUEST; // this is a request message
- mbox[2] = MBOX_TAG_FB_SET_PIXEL_ORDER;
- mbox[3] = 4; // buffer size
- mbox[4] = 4; // len
- mbox[5] = rgb; // id
- mbox[6] = 0;
- mbox[7] = MBOX_TAG_LAST;
- mbox_call(8, MMU_DISABLE);
- }
- void bcm271x_mbox_fb_setoffset(int xoffset, int yoffset)
- {
- mbox[0] = 8*4; // length of the message
- mbox[1] = MBOX_REQUEST; // this is a request message
- mbox[2] = MBOX_TAG_FB_SET_VIRT_OFFSET;
- mbox[3] = 8; // buffer size
- mbox[4] = 8; // len
- mbox[5] = xoffset; // id
- mbox[6] = yoffset;
- mbox[7] = MBOX_TAG_LAST;
- mbox_call(8, MMU_DISABLE);
- }
- void bcm271x_mbox_fb_setalpha(int alpha)
- {
- mbox[0] = 8*4; // length of the message
- mbox[1] = MBOX_REQUEST; // this is a request message
- mbox[2] = MBOX_TAG_FB_SET_ALPHA_MODE;
- mbox[3] = 4; // buffer size
- mbox[4] = 4; // len
- mbox[5] = alpha; // id
- mbox[6] = 0;
- mbox[7] = MBOX_TAG_LAST;
- mbox_call(8, MMU_DISABLE);
- }
- void *bcm271x_mbox_fb_alloc(int width, int height, int bpp, int nrender)
- {
- mbox[0] = 4 * 35;
- mbox[1] = MBOX_REQUEST;
- mbox[2] = TAG_ALLOCATE_BUFFER;//get framebuffer, gets alignment on request
- mbox[3] = 8; //size
- mbox[4] = 4; //len
- mbox[5] = 4096; //The design of MBOX driver forces us to give the virtual address 0x3C100000
- mbox[6] = 0; //FrameBufferInfo.size
- mbox[7] = TAG_SET_PHYS_WIDTH_HEIGHT;
- mbox[8] = 8;
- mbox[9] = 8;
- mbox[10] = width;
- mbox[11] = height;
- mbox[12] = TAG_SET_VIRT_WIDTH_HEIGHT;
- mbox[13] = 8;
- mbox[14] = 8;
- mbox[15] = width;
- mbox[16] = height * nrender;
- mbox[17] = TAG_SET_DEPTH;
- mbox[18] = 4;
- mbox[19] = 4;
- mbox[20] = bpp;
- mbox[21] = TAG_SET_PIXEL_ORDER;
- mbox[22] = 4;
- mbox[23] = 0;
- mbox[24] = 0; //RGB, not BGR preferably
- mbox[25] = TAG_GET_PITCH;
- mbox[26] = 4;
- mbox[27] = 0;
- mbox[28] = 0;
- mbox[29] = TAG_SET_VIRT_OFFSET;
- mbox[30] = 8;
- mbox[31] = 8;
- mbox[32] = 0;
- mbox[33] = 0;
- mbox[34] = TAG_END;
- mbox_call(8, MMU_DISABLE);
- return (void *)((rt_uint32_t)(mbox[5] & 0x3fffffff));
- }
- int hdmi_fb_init(void)
- {
- _hdmi.fb = (rt_uint8_t *)bcm271x_mbox_fb_alloc(LCD_WIDTH, LCD_HEIGHT, LCD_BPP, 1);
- if(_hdmi.fb == RT_NULL)
- {
- rt_kprintf("init dsi or hdmi err!\n");
- return 0;
- }
- bcm271x_mbox_fb_setoffset(0, 0);
- bcm271x_mbox_fb_set_porder(0);
- _hdmi.width = LCD_WIDTH;
- _hdmi.height = LCD_HEIGHT;
- _hdmi.depth = LCD_DEPTH;
- _hdmi.pitch = 0;
- _hdmi.pixel_format = RTGRAPHIC_PIXEL_FORMAT_RGB888;
- rt_memset(_hdmi.fb, 0, LCD_WIDTH*LCD_HEIGHT*(LCD_BPP/8));
- //rt_kprintf("_hdmi.fb is %p\n", _hdmi.fb);
- rt_hdmi_fb_device_init(&_hdmi, "hdmi");
- return 0;
- }
- INIT_DEVICE_EXPORT(hdmi_fb_init);
- #endif /*BSP_USING_HDMI */
|