forked from Imagelibrary/rtems
bsps: Move arm-pl111-fb.c to bsps
This patch is a part of the BSP source reorganization. Update #3285.
This commit is contained in:
@@ -104,7 +104,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/i2c/i2c.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/i2c/i2c-config.c
|
||||
|
||||
# Framebuffer
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-pl111-fb.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/fb/arm-pl111.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/lpc24xx/start/fb-config.c
|
||||
|
||||
# Cache
|
||||
|
||||
@@ -78,7 +78,7 @@ librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/cache/cache-cp15.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/realview-pbx-a9/start/bspstarthooks.c
|
||||
|
||||
# Framebuffer
|
||||
librtemsbsp_a_SOURCES += ../shared/arm-pl111-fb.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/shared/fb/arm-pl111.c
|
||||
librtemsbsp_a_SOURCES += ../../../../../../bsps/arm/realview-pbx-a9/start/fb-config.c
|
||||
|
||||
###############################################################################
|
||||
|
||||
@@ -1,276 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2013 embedded brains GmbH. All rights reserved.
|
||||
*
|
||||
* embedded brains GmbH
|
||||
* Dornierstr. 4
|
||||
* 82178 Puchheim
|
||||
* Germany
|
||||
* <info@embedded-brains.de>
|
||||
*
|
||||
* The license and distribution terms for this file may be
|
||||
* found in the file LICENSE in this distribution or at
|
||||
* http://www.rtems.org/license/LICENSE.
|
||||
*/
|
||||
|
||||
#include <errno.h>
|
||||
#include <assert.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <rtems/framebuffer.h>
|
||||
#include <rtems/fb.h>
|
||||
#include <rtems/libio.h>
|
||||
|
||||
#include <bsp.h>
|
||||
#include <bsp/arm-pl111-fb.h>
|
||||
#include <bsp/fatal.h>
|
||||
|
||||
typedef struct {
|
||||
rtems_id semaphore;
|
||||
void *frame_buffer;
|
||||
} pl111_fb_context;
|
||||
|
||||
static pl111_fb_context pl111_fb_instance;
|
||||
|
||||
static const uint8_t pl111_bits_per_pixel[] = { 1, 2, 4, 8, 16, 24, 16, 12 };
|
||||
|
||||
static uint32_t pl111_fb_get_width(const pl111_fb_config *cfg)
|
||||
{
|
||||
return 16U * (PL111_LCD_TIMING0_PPL_GET(cfg->timing0) + 1U);
|
||||
}
|
||||
|
||||
static uint32_t pl111_fb_get_height(const pl111_fb_config *cfg)
|
||||
{
|
||||
return PL111_LCD_TIMING1_LPP_GET(cfg->timing1) + 1U;
|
||||
}
|
||||
|
||||
static uint32_t pl111_fb_get_bits_per_pixel(const pl111_fb_config *cfg)
|
||||
{
|
||||
return pl111_bits_per_pixel[PL111_LCD_CONTROL_LCD_BPP_GET(cfg->control)];
|
||||
}
|
||||
|
||||
static uint32_t pl111_fb_get_line_length_in_bytes(const pl111_fb_config *cfg)
|
||||
{
|
||||
uint32_t width = pl111_fb_get_width(cfg);
|
||||
uint32_t bits_per_pixel = pl111_fb_get_bits_per_pixel(cfg);
|
||||
|
||||
return width * ((bits_per_pixel + 7U) / 8U);
|
||||
}
|
||||
|
||||
static uint32_t pl111_fb_get_frame_buffer_size(const pl111_fb_config *cfg)
|
||||
{
|
||||
uint32_t line_length_in_bytes = pl111_fb_get_line_length_in_bytes(cfg);
|
||||
uint32_t height = pl111_fb_get_height(cfg);
|
||||
|
||||
return height * line_length_in_bytes;
|
||||
}
|
||||
|
||||
static void pl111_fb_power_delay(const pl111_fb_config *cfg)
|
||||
{
|
||||
rtems_interval delay = (cfg->power_delay_in_us + 1)
|
||||
/ rtems_configuration_get_microseconds_per_tick();
|
||||
rtems_status_code sc = rtems_task_wake_after(delay);
|
||||
assert(sc == RTEMS_SUCCESSFUL);
|
||||
}
|
||||
|
||||
static rtems_status_code pl111_fb_initialize(pl111_fb_context *ctx)
|
||||
{
|
||||
rtems_status_code sc = RTEMS_SUCCESSFUL;
|
||||
const pl111_fb_config *cfg = arm_pl111_fb_get_config();
|
||||
|
||||
ctx->frame_buffer = calloc(1, pl111_fb_get_frame_buffer_size(cfg));
|
||||
if (ctx->frame_buffer != NULL) {
|
||||
volatile pl111 *regs = cfg->regs;
|
||||
|
||||
(*cfg->set_up)(cfg);
|
||||
|
||||
regs->lcd.upbase = (uint32_t) ctx->frame_buffer;
|
||||
|
||||
regs->lcd.timing0 = cfg->timing0;
|
||||
regs->lcd.timing1 = cfg->timing1;
|
||||
regs->lcd.timing2 = cfg->timing2;
|
||||
regs->lcd.timing3 = cfg->timing3;
|
||||
regs->lcd.control = cfg->control;
|
||||
|
||||
(*cfg->pins_set_up)(cfg);
|
||||
|
||||
regs->lcd.control = cfg->control
|
||||
| PL111_LCD_CONTROL_LCD_EN;
|
||||
|
||||
pl111_fb_power_delay(cfg);
|
||||
|
||||
regs->lcd.control = cfg->control
|
||||
| PL111_LCD_CONTROL_LCD_EN
|
||||
| PL111_LCD_CONTROL_LCD_PWR;
|
||||
} else {
|
||||
sc = RTEMS_NO_MEMORY;
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
static void pl111_fb_destroy(const pl111_fb_context *ctx)
|
||||
{
|
||||
const pl111_fb_config *cfg = arm_pl111_fb_get_config();
|
||||
volatile pl111 *regs = cfg->regs;
|
||||
|
||||
free(ctx->frame_buffer);
|
||||
|
||||
regs->lcd.control = cfg->control
|
||||
| PL111_LCD_CONTROL_LCD_EN;
|
||||
|
||||
pl111_fb_power_delay(cfg);
|
||||
|
||||
regs->lcd.control = cfg->control;
|
||||
|
||||
(*cfg->pins_tear_down)(cfg);
|
||||
(*cfg->tear_down)(cfg);
|
||||
}
|
||||
|
||||
static void pl111_fb_get_fix_screen_info(struct fb_fix_screeninfo *info)
|
||||
{
|
||||
const pl111_fb_config *cfg = arm_pl111_fb_get_config();
|
||||
const pl111_fb_context *ctx = &pl111_fb_instance;
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
info->smem_start = ctx->frame_buffer;
|
||||
info->smem_len = pl111_fb_get_frame_buffer_size(cfg);
|
||||
info->type = FB_TYPE_PACKED_PIXELS;
|
||||
info->visual = FB_VISUAL_TRUECOLOR;
|
||||
info->line_length = pl111_fb_get_line_length_in_bytes(cfg);
|
||||
}
|
||||
|
||||
static void pl111_fb_get_var_screen_info(struct fb_var_screeninfo *info)
|
||||
{
|
||||
const pl111_fb_config *cfg = arm_pl111_fb_get_config();
|
||||
|
||||
memset(info, 0, sizeof(*info));
|
||||
|
||||
info->xres = pl111_fb_get_width(cfg);
|
||||
info->yres = pl111_fb_get_height(cfg);
|
||||
info->bits_per_pixel = pl111_fb_get_bits_per_pixel(cfg);
|
||||
}
|
||||
|
||||
static void pl111_fb_release(const pl111_fb_context *ctx)
|
||||
{
|
||||
rtems_status_code sc = rtems_semaphore_release(ctx->semaphore);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
bsp_fatal(BSP_ARM_PL111_FATAL_SEM_RELEASE);
|
||||
}
|
||||
}
|
||||
|
||||
rtems_device_driver frame_buffer_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
pl111_fb_context *ctx = &pl111_fb_instance;
|
||||
|
||||
sc = rtems_io_register_name(FRAMEBUFFER_DEVICE_0_NAME, major, 0);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
bsp_fatal(BSP_ARM_PL111_FATAL_REGISTER_DEV);
|
||||
}
|
||||
|
||||
sc = rtems_semaphore_create(
|
||||
rtems_build_name('F', 'B', ' ', ' '),
|
||||
1,
|
||||
RTEMS_COUNTING_SEMAPHORE,
|
||||
0,
|
||||
&ctx->semaphore
|
||||
);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
bsp_fatal(BSP_ARM_PL111_FATAL_SEM_CREATE);
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
rtems_device_driver frame_buffer_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
pl111_fb_context *ctx = &pl111_fb_instance;
|
||||
|
||||
sc = rtems_semaphore_obtain(
|
||||
ctx->semaphore,
|
||||
RTEMS_WAIT,
|
||||
RTEMS_NO_TIMEOUT
|
||||
);
|
||||
if (sc == RTEMS_SUCCESSFUL) {
|
||||
sc = pl111_fb_initialize(ctx);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
pl111_fb_release(ctx);
|
||||
}
|
||||
}
|
||||
|
||||
return sc;
|
||||
}
|
||||
|
||||
rtems_device_driver frame_buffer_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
const pl111_fb_context *ctx = &pl111_fb_instance;
|
||||
|
||||
pl111_fb_destroy(ctx);
|
||||
pl111_fb_release(ctx);
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver frame_buffer_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
rtems_device_driver frame_buffer_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
|
||||
rtems_device_driver frame_buffer_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *arg
|
||||
)
|
||||
{
|
||||
rtems_libio_ioctl_args_t *ioctl_arg = arg;
|
||||
int eno = 0;
|
||||
|
||||
switch (ioctl_arg->command) {
|
||||
case FBIOGET_FSCREENINFO:
|
||||
pl111_fb_get_fix_screen_info(ioctl_arg->buffer);
|
||||
break;
|
||||
case FBIOGET_VSCREENINFO:
|
||||
pl111_fb_get_var_screen_info(ioctl_arg->buffer);
|
||||
break;
|
||||
default:
|
||||
eno = EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
if (eno == 0) {
|
||||
ioctl_arg->ioctl_return = 0;
|
||||
} else {
|
||||
ioctl_arg->ioctl_return = -1;
|
||||
errno = eno;
|
||||
}
|
||||
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
Reference in New Issue
Block a user