Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

os/drivers/lcd/: Remove logo specific code from bus specific files #6614

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion os/drivers/lcd/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ config LCD_YRES

config LCD_LOGO
bool "Lcd screen image shown at boot time"
default y
default n
---help---
This screen image is shown at boot time.
This image is shown till App makes first rendering call.
Expand Down
3 changes: 3 additions & 0 deletions os/drivers/lcd/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,9 @@ ifeq ($(CONFIG_LCD),y)
# Support for the generic LCD framebufer front-end
CSRCS += lcd_dev.c

# Support for LCD initial bootup screen
CSRCS += lcd_logo.c

ifeq ($(CONFIG_LCD_FRAMEBUFFER),y)
CSRCS += lcd_framebuffer.c
endif
Expand Down
48 changes: 37 additions & 11 deletions os/drivers/lcd/lcd_dev.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,7 @@
#include <stdio.h>
#include <sched.h>

#include "lcd_logo.h"
#include <tinyara/fs/fs.h>
#include <tinyara/fs/ioctl.h>
#include <tinyara/lcd/lcd_dev.h>
Expand Down Expand Up @@ -93,6 +94,7 @@ struct lcd_s {
bool do_wait;
#endif
};

/****************************************************************************
* Private Function Prototypes
****************************************************************************/
Expand Down Expand Up @@ -247,6 +249,7 @@ static int lcddev_ioctl(FAR struct file *filep, int cmd, unsigned long arg)
}
break;
case LCDDEVIO_PUTAREA: {
lcd_logo_release_buffer();
#if defined(CONFIG_LCD_FLUSH_THREAD)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If CONFIG_LCD_FLUSH_THREAD is enabled, we don't need buffer for only lcd logo

if (priv->empty == true) {
priv->lcd_area = (FAR const struct lcddev_area_s *)arg;
Expand Down Expand Up @@ -401,6 +404,29 @@ static void lcd_flushing_thread(int argc, char **argv)
}
#endif

void lcd_init_put_image(struct lcd_s *lcd_info)
{
int xres;
int yres;
size_t cols;
size_t pixel_size;
size_t row_size;
uint8_t *lcd_init_fullscreen_image; // Buffer containing full screen data with logo at the center of screen
FAR struct fb_videoinfo_s video_info;
FAR struct lcddev_area_s *lcd_area;

lcd_init_fullscreen_image = lcd_logo_allocate_buffer();
lcd_info->dev->getvideoinfo(lcd_info->dev, &video_info);
xres = video_info.xres;
yres = video_info.yres;
lcd_logo_fill_buffer(xres, yres); // Fill buffer at center of screen
lcd_area = &(lcd_info->lcd_area);
cols = lcd_area->col_end - lcd_area->col_start + 1;
pixel_size = lcd_info->planeinfo[lcd_area->planeno].bpp > 1 ? lcd_info->planeinfo[lcd_area->planeno].bpp >> 3 : 1;
row_size = lcd_area->stride > 0 ? lcd_area->stride : cols * pixel_size;
lcd_info->planeinfo[lcd_area->planeno].putarea(lcd_info->dev, 0, yres, 0, xres, (u8 *)lcd_init_fullscreen_image, row_size);
}

/****************************************************************************
* Public Functions
****************************************************************************/
Expand Down Expand Up @@ -442,6 +468,7 @@ int lcddev_register(struct lcd_dev_s *dev)
}

lcd_info->dev = dev;

#if defined(CONFIG_LCD_FLUSH_THREAD)
sem_init(&lcd_info->flushing_sem, 0, 0);
lcd_info->do_wait = false;
Expand Down Expand Up @@ -470,20 +497,19 @@ int lcddev_register(struct lcd_dev_s *dev)
#ifdef CONFIG_PM
lcd_info->pm_domain = pm_domain_register("LCD");
#endif

lcd_init_put_image(dev);
sem_init(&lcd_info->sem, 0, 1);
if (dev->setpower) {
ret = dev->setpower(dev, CONFIG_LCD_MAXPOWER);
if (ret != OK) {
goto cleanup;
}
#ifdef CONFIG_PM
(void)pm_suspend(lcd_info->pm_domain);
#endif
}
if (lcd_info->dev->getplaneinfo) {
lcd_info->dev->getplaneinfo(lcd_info->dev, 0, &lcd_info->planeinfo); //plane no is taken 0 here
lcd_init_put_image(lcd_info);
if (dev->setpower) {
ret = dev->setpower(dev, CONFIG_LCD_MAXPOWER);
if (ret != OK) {
goto cleanup;
}
#ifdef CONFIG_PM
(void)pm_suspend(lcd_info->pm_domain);
#endif
}
snprintf(devname, 16, "/dev/lcd0");
ret = register_driver(devname, &g_lcddev_fops, 0666, lcd_info);
if (ret != OK) {
Expand Down
93 changes: 93 additions & 0 deletions os/drivers/lcd/lcd_logo.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
/****************************************************************************
*
* Copyright 2024 Samsung Electronics All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
****************************************************************************/

/****************************************************************************
* Included Files
****************************************************************************/
#include <sys/types.h>
#include "lcd_logo.h"
#include <debug.h>

extern const uint8_t lcd_logo_raw_data[LOGO_XRES * LOGO_YRES * 2];
uint8_t *lcd_init_fullscreen_image = NULL;

#if defined(CONFIG_LCD_SW_ROTATION)
extern uint8_t* get_lcd_buffer(void);
#endif
/* Memory optimization applied in case of software rotation is used in driver Rotation buffer
* If rotation is enabled, then we have two buffers allocated for rotation.
* During bootup, rotation buffer will not be used (No putarea call from application)
* Therefore, the rotation buffer can be safely used for storing logo data.
*
* If rotation is disabled, then we need to allocate memory for full screen data
* and it will allocate memory to lcd_init_fullscreen_image buffer.
*
* If rotation is enabled, then lcd_init_fullscreen_image contains pointer of rotation buffer
*
* Define a callback function in driver get_lcd_buffer() which can return pointer
* of the buffer used for rotation. */

uint8_t* lcd_logo_allocate_buffer(void)
{
#if defined(CONFIG_LCD_SW_ROTATION)
lcd_init_fullscreen_image = get_lcd_buffer();
#else
lcd_init_fullscreen_image = (uint8_t *)kmm_malloc(CONFIG_LCD_XRES * CONFIG_LCD_YRES * 2 + 1);
if (!lcd_init_fullscreen_image) {
lcddbg("ERROR: LCD logo data memory allocation failed\n");
return;
}
#endif
}

void lcd_logo_release_buffer(void)
{
#if !defined(CONFIG_LCD_SW_ROTATION)
if (lcd_init_fullscreen_image != NULL) {
kmm_free(lcd_init_fullscreen_image);
}
#endif
if (!lcd_init_fullscreen_image) {
lcd_init_fullscreen_image = NULL;
}
}
Comment on lines +60 to +68
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
#if !defined(CONFIG_LCD_SW_ROTATION)
if (lcd_init_fullscreen_image != NULL) {
kmm_free(lcd_init_fullscreen_image);
}
#endif
if (!lcd_init_fullscreen_image) {
lcd_init_fullscreen_image = NULL;
}
}
if (!lcd_init_fullscreen_image) {
#if !defined(CONFIG_LCD_SW_ROTATION)
kmm_free(lcd_init_fullscreen_image);
#endif
lcd_init_fullscreen_image = NULL;
}
}


void lcd_logo_fill_buffer(int xres, int yres)
{
int logo_arr_index = 0;
int lcd_data_col_count = 0;
int lcd_data_index = xres * (yres - LOGO_YRES) + (xres - LOGO_XRES);

if (!lcd_init_fullscreen_image) {
lcddbg("ERROR: LOGO buffer is not initialized\n");
}

memset(lcd_init_fullscreen_image, LCD_BLACK_VAL, xres * yres * 2);
#if defined(CONFIG_LCD_LOGO)
while (logo_arr_index < (LOGO_YRES * LOGO_XRES * 2)) {
lcd_init_fullscreen_image[lcd_data_index] = lcd_logo_raw_data[logo_arr_index++];
lcd_init_fullscreen_image[lcd_data_index + 1] = lcd_logo_raw_data[logo_arr_index++];
lcd_data_index += 2;
lcd_data_col_count += 1;
if (lcd_data_col_count == LOGO_XRES) {
lcd_data_index += ((xres - LOGO_XRES) * 2);
lcd_data_col_count = 0;
}
}
#endif
}
9 changes: 6 additions & 3 deletions os/drivers/lcd/lcd_logo.h
Original file line number Diff line number Diff line change
Expand Up @@ -23,12 +23,15 @@

#define LCD_BLACK_VAL 0
#ifdef CONFIG_LCD_LOGO_52_340
#define LOGO_XRES 52
#define LOGO_YRES 340
#define LOGO_XRES 340
#define LOGO_YRES 52
#else
#define LOGO_XRES 0
#define LOGO_YRES 0
#endif /* CONFIG_LCD_LOGO_52_340 */

#endif /* __DRIVER_LCD_LOGO_H */
uint8_t* lcd_logo_allocate_buffer(void);
void lcd_logo_release_buffer(void);
void lcd_logo_fill_buffer(int xres, int yres);

#endif /* __DRIVER_LCD_LOGO_H */
56 changes: 5 additions & 51 deletions os/drivers/lcd/mipi_lcd.c
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@
#endif
#include <tinyara/mipidsi/mipi_dsi.h>
#include <tinyara/mipidsi/mipi_display.h>
#include "lcd_logo.h"
#include <debug.h>
#include <assert.h>

Expand All @@ -39,9 +38,6 @@
#define CONFIG_LCD_MAXPOWER 100
#endif

extern const uint8_t lcd_logo_raw_data[]; // Buffer containing only logo
static uint8_t *lcd_init_fullscreen_image = NULL; // Buffer containing full screen data with logo on specific position

#if defined(CONFIG_LCD_SW_ROTATION)
#define NUM_OF_LCD_BUFFER 2
static uint8_t *lcd_buffer[NUM_OF_LCD_BUFFER] = { NULL, NULL }; //Two lcd buffers to avoid screen tearing
Expand Down Expand Up @@ -239,10 +235,6 @@ static int lcd_putarea(FAR struct lcd_dev_s *dev, fb_coord_t row_start, fb_coord
priv->config->lcd_put_area((u8 *)lcd_buffer[lcd_buffer_index], row_start, col_start, row_end, col_end);
lcd_buffer_index = (1 - lcd_buffer_index);
#else
if (lcd_init_fullscreen_image != NULL) {
kmm_free(lcd_init_fullscreen_image);
lcd_init_fullscreen_image = NULL;
}
priv->config->lcd_put_area((u8 *)buffer, row_start, col_start, row_end, col_end);
#endif
return OK;
Expand Down Expand Up @@ -405,52 +397,14 @@ static int lcd_setcontrast(FAR struct lcd_dev_s *dev, unsigned int contrast)
{
return OK;
}

FAR void lcd_init_put_image(FAR struct lcd_dev_s *dev)
{
int logo_arr_index = 0;
int lcd_data_index = CONFIG_LCD_XRES * (CONFIG_LCD_YRES - LOGO_YRES) + (CONFIG_LCD_XRES - LOGO_XRES);
int lcd_data_col_count = 0;
FAR struct mipi_lcd_dev_s *priv = (FAR struct mipi_lcd_dev_s *)dev;

/* Memory optimization applied using Rotation buffer
* If rotation is enabled, then we have two buffers allocated for rotation.
* During bootup, rotation buffer will not be used (No putarea call from application)
* Therefore, the rotation buffer can be safely used for storing logo data.
*
* If rotation is disabled, then we need to allocate memory for full screen data
* and it will allocate memory to lcd_init_fullscreen_image buffer.
*
* If rotation is enabled, then lcd_init_fullscreen_image contains pointer of rotation buffer */
#if defined(CONFIG_LCD_SW_ROTATION)
lcd_init_fullscreen_image = lcd_buffer[lcd_buffer_index];
uint8_t* get_lcd_buffer(void)
{
uint8_t *buffer = lcd_buffer[lcd_buffer_index];
lcd_buffer_index = (1 - lcd_buffer_index);
#else
lcd_init_fullscreen_image = (uint8_t *)kmm_malloc(CONFIG_LCD_XRES * CONFIG_LCD_YRES * 2 + 1);
if (!lcd_init_fullscreen_image) {
lcddbg("ERROR: LCD logo data memory allocation failed\n");
return;
}
#endif
/* Filling buffer with black color using memset and
* then filling it with logo data on specific index in while loop */
memset(lcd_init_fullscreen_image, LCD_BLACK_VAL, CONFIG_LCD_XRES * CONFIG_LCD_YRES * 2);

#if defined(CONFIG_LCD_LOGO)
while (logo_arr_index < (LOGO_YRES * LOGO_XRES * 2)) {
lcd_init_fullscreen_image[lcd_data_index] = lcd_logo_raw_data[logo_arr_index++];
lcd_init_fullscreen_image[lcd_data_index + 1] = lcd_logo_raw_data[logo_arr_index++];
lcd_data_index += 2;
lcd_data_col_count += 1;
if (lcd_data_col_count == LOGO_XRES) {
lcd_data_index += ((CONFIG_LCD_XRES - LOGO_XRES) * 2);
lcd_data_col_count = 0;
}
}
#endif

priv->config->lcd_put_area((u8 *)lcd_init_fullscreen_image, 1, 1, CONFIG_LCD_XRES, CONFIG_LCD_YRES); // 1, 1 -> Start index of the frame buffer
return buffer;
}
#endif

FAR struct lcd_dev_s *mipi_lcdinitialize(FAR struct mipi_dsi_device *dsi, struct mipi_lcd_config_s *config)
{
Expand Down