Squashed commit of the following:

arch/arm/src/am335x:  Add logic to map the framebuffer to a non-cached, non-buffered memory region.
    arch/arm/src/am335x:  Remove struct am335x_fbinfo_s.  Replaced with configuration settings that provide the same information.
This commit is contained in:
Gregory Nutt 2019-07-08 13:23:56 -06:00
parent b58f598d31
commit ed91fa34a0
6 changed files with 93 additions and 73 deletions

View File

@ -253,12 +253,26 @@ config AM335X_DDR_MAPSIZE
menu "LCD Configuration"
depends on AM335X_LCDC
config AM335X_LCDC_VRAMBASE
hex "Video RAM base address"
default 0xa0010000
config AM335X_LCDC_FB_VBASE
hex "Video RAM base address (virtual)"
default 0x80000000
---help---
Base address of the video RAM frame buffer. The default is
(AM335X_EXTDRAM_CS0 + 0x00010000)
Base address of the video RAM frame buffer. The default of 0x80000000
assumes that the framebuffer lies at the beginning of DRAM and that
a 1-to-1 virtual-to-physical address mapping is used.
config AM335X_LCDC_FB_PBASE
hex "Video RAM base address (physical)"
default 0x80000000
---help---
Base address of the video RAM frame buffer. The default of 0x80000000
assumes that the framebuffer lies at the beginning of DRAM.
config AM335X_LCDC_FB_SIZE
hex "Video RAM base size"
default 0x00100000
---help---
Size of the video RAM frame buffer. Default: 1Mb.
config AM335X_LCDC_USE_CLKIN
bool "Use optional input clock"

View File

@ -66,6 +66,13 @@
* Pre-processor Definitions
****************************************************************************/
/* If the LCDC is enabled, then this will provide the number of sections
* to map for the framebuffer.
*/
#define AM335X_LCDC_FBNSECTIONS \
((CONFIG_AM335X_LCDC_FB_SIZE + 0x000fffff) >> 20)
/****************************************************************************
* Name: showprogress
*
@ -105,9 +112,8 @@
extern uint32_t _vector_start; /* Beginning of vector block */
extern uint32_t _vector_end; /* End+1 of vector block */
/****************************************************************************
* Private Functions
****************************************************************************/
#define SAMA5_LCDC_FBNSECTIONS \
((CONFIG_SAMA5_LCDC_FB_SIZE + 0x000fffff) >> 20)
/****************************************************************************
* Private Data
@ -120,32 +126,55 @@ extern uint32_t _vector_end; /* End+1 of vector block */
#ifndef CONFIG_ARCH_ROMPGTABLE
static const struct section_mapping_s g_section_mapping[] =
{
{ AM335X_GPMC_PSECTION, AM335X_GPMC_VSECTION, /* Includes vectors and page table */
{
AM335X_GPMC_PSECTION, AM335X_GPMC_VSECTION, /* Includes vectors and page table */
AM335X_GPMC_MMUFLAGS, AM335X_GPMC_NSECTIONS
},
{ AM335X_BROM_PSECTION, AM335X_BROM_VSECTION,
{
AM335X_BROM_PSECTION, AM335X_BROM_VSECTION,
AM335X_BROM_MMUFLAGS, AM335X_BROM_NSECTIONS
},
{ AM335X_ISRAM_PSECTION, AM335X_ISRAM_VSECTION,
{
AM335X_ISRAM_PSECTION, AM335X_ISRAM_VSECTION,
AM335X_ISRAM_MMUFLAGS, AM335X_ISRAM_NSECTIONS
},
{ AM335X_OCMC0_PSECTION, AM335X_OCMC0_VSECTION,
{
AM335X_OCMC0_PSECTION, AM335X_OCMC0_VSECTION,
AM335X_OCMC0_MMUFLAGS, AM335X_OCMC0_NSECTIONS
},
{ AM335X_PERIPH_PSECTION, AM335X_PERIPH_VSECTION,
{
AM335X_PERIPH_PSECTION, AM335X_PERIPH_VSECTION,
AM335X_PERIPH_MMUFLAGS, AM335X_PERIPH_NSECTIONS
},
{ AM335X_DDR_PSECTION, AM335X_DDR_VSECTION,
{
AM335X_DDR_PSECTION, AM335X_DDR_VSECTION,
AM335X_DDR_MMUFLAGS, AM335X_DDR_NSECTIONS
}
#ifdef CONFIG_AM335X_LCDC
,
/* LCDC Framebuffer. This entry reprograms a part of one of the above
* regions, making it non-cache-able and non-buffer-able.
*/
{
CONFIG_AM335X_LCDC_FB_PBASE, CONFIG_AM335X_LCDC_FB_VBASE,
MMU_IOFLAGS, AM335X_LCDC_FBNSECTIONS
}
#endif
};
#define NMAPPINGS \
(sizeof(g_section_mapping) / sizeof(struct section_mapping_s))
const size_t g_num_mappings = NMAPPINGS;
static const size_t g_num_mappings = NMAPPINGS;
#endif
/****************************************************************************
* Private Functions
****************************************************************************/
/****************************************************************************
* Name: am335x_setupmappings
*

View File

@ -113,8 +113,7 @@ static uint32_t
****************************************************************************/
static bool
am335x_videomode_valid(FAR const struct edid_videomode_s *videomode,
FAR const struct am335x_fbinfo_s *fbinfo)
am335x_videomode_valid(FAR const struct edid_videomode_s *videomode)
{
size_t fbstride;
size_t fbsize;
@ -193,7 +192,7 @@ static bool
fbstride = (videomode->hdisplay * AM335X_BPP + 7) >> 3;
fbsize = videomode->vdisplay * fbstride;
if (fbsize > fbinfo->fbsize)
if (fbsize > AM335X_LCDC_FB_SIZE)
{
return false;
}
@ -218,8 +217,7 @@ static bool
****************************************************************************/
static const struct edid_videomode_s *
am335x_lcd_pickmode(FAR struct edid_info_s *ei,
FAR const struct am335x_fbinfo_s *fbinfo)
am335x_lcd_pickmode(FAR struct edid_info_s *ei)
{
FAR const struct edid_videomode_s *videomode;
int n;
@ -232,7 +230,7 @@ static const struct edid_videomode_s *
if (ei->edid_preferred_mode != NULL)
{
if (am335x_videomode_valid(ei->edid_preferred_mode, fbinfo))
if (am335x_videomode_valid(ei->edid_preferred_mode))
{
videomode = ei->edid_preferred_mode;
return videomode;
@ -250,7 +248,7 @@ static const struct edid_videomode_s *
for (n = 0; n < ei->edid_nmodes; n++)
{
if (am335x_videomode_valid(&ei->edid_modes[n], fbinfo))
if (am335x_videomode_valid(&ei->edid_modes[n]))
{
videomode = &ei->edid_modes[n];
break;
@ -347,8 +345,6 @@ void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode,
* len - The length of the EDID data in bytes
* panel - A user provided location to receive the panel data.
* selected - A user provided location to receive the selected video mode.
* fbinfo - Provides information about the pre-allocate framebuffer
* memory.
*
* Returned value:
* None. Always succeeds. The logic will fallback to VGA mode if no
@ -359,8 +355,7 @@ void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode,
void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len,
FAR struct am335x_panel_info_s *panel,
FAR struct edid_videomode_s *selected,
FAR const struct am335x_fbinfo_s *fbinfo)
FAR struct edid_videomode_s *selected)
{
FAR const struct edid_videomode_s *videomode = NULL;
struct edid_info_s ei;
@ -373,7 +368,7 @@ void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len,
if (edid_parse(edid, &ei) == 0)
{
videomode = am335x_lcd_pickmode(&ei, fbinfo);
videomode = am335x_lcd_pickmode(&ei);
}
else
{

View File

@ -134,8 +134,6 @@ struct am335x_lcd_dev_s
sem_t exclsem; /* Assure mutually exclusive access */
nxgl_coord_t stride; /* Width of framebuffer in bytes */
size_t fbsize; /* Size of the framebuffer allocation */
FAR void *fbmem; /* Allocated framebuffer memory (virtual) */
FAR void *fbphys; /* Allocated framebuffer memory (physical) */
};
/****************************************************************************
@ -192,9 +190,9 @@ static int am335x_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno,
if (vtable != NULL && planeno == 0 && pinfo != NULL)
{
#ifdef CONFIG_BUILD_KERNEL
pinfo->fbmem = priv->fbphys;
pinfo->fbmem = (FAR void *)CONFIG_AM335X_LCDC_FB_PBASE;
#else
pinfo->fbmem = priv->fbmem;
pinfo->fbmem = (FAR void *)CONFIG_AM335X_LCDC_FB_VBASE;
#endif
pinfo->fblen = priv->fbsize;
pinfo->stride = priv->stride;
@ -286,17 +284,17 @@ static int am335x_lcd_interrupt(int irq, void *context, void *arg)
if ((regval & LCD_IRQ_EOF0) != 0)
{
putreg32(AM335X_LCD_DMA_FB0_BASE, priv->fbphys);
putreg32(AM335X_LCD_DMA_FB0_BASE, CONFIG_AM335X_LCDC_FB_PBASE);
putreg32(AM335X_LCD_DMA_FB0_CEIL,
priv->fbphys + priv->fbsize - 1);
CONFIG_AM335X_LCDC_FB_PBASE + priv->fbsize - 1);
regval &= ~LCD_IRQ_EOF0;
}
if ((regval & LCD_IRQ_EOF1) != 0)
{
putreg32(AM335X_LCD_DMA_FB1_BASE, priv->fbphys);
putreg32(AM335X_LCD_DMA_FB1_BASE, CONFIG_AM335X_LCDC_FB_PBASE);
putreg32(AM335X_LCD_DMA_FB1_CEIL,
priv->fbphys + priv->fbsize - 1);
CONFIG_AM335X_LCDC_FB_PBASE + priv->fbsize - 1);
regval &= ~LCD_IRQ_EOF1;
}
@ -393,8 +391,6 @@ static uint32_t am335x_lcd_divisor(uint32_t reference, uint32_t freq)
*
* Input Parameters:
* panel - Provides information about the connect LCD panel.
* fbinfo - Provides information about the pre-allocate framebuffer
* memory.
*
* Returned value:
* Zero (OK) is returned on success; a negated errno value is returned in
@ -402,8 +398,7 @@ static uint32_t am335x_lcd_divisor(uint32_t reference, uint32_t freq)
*
****************************************************************************/
int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel,
FAR const struct am335x_fbinfo_s *fbinfo)
int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel)
{
struct am335x_lcd_dev_s *priv = &g_lcddev;
uint32_t regval;
@ -423,7 +418,7 @@ int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel,
int div;
int ret;
DEBUGASSERT(panel != NULL && fbinfo != NULL);
DEBUGASSERT(panel != NULL);
/* Configure LCD pins */
@ -487,11 +482,9 @@ int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel,
/* Save framebuffer information */
priv->fbmem = fbinfo->fbmem;
priv->fbphys = fbinfo->fbphys;
priv->stride = (priv->panel.width * priv->panel.bpp + 7) >> 3;
priv->fbsize = priv->stride * priv->panel.height;
DEBUGASSERT(priv->fbsize <= fbinfo->fbsize);
DEBUGASSERT(priv->fbsize <= AM335X_LCDC_FB_SIZE);
/* Attach the LCD interrupt */
@ -671,10 +664,10 @@ int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel,
regval |= (0 << LCD_DMA_CTRL_TH_FIFO_RDY_SHIFT);
putreg32(AM335X_LCD_DMA_CTRL, regval);
putreg32(AM335X_LCD_DMA_FB0_BASE, priv->fbphys);
putreg32(AM335X_LCD_DMA_FB0_BASE, priv->fbphys + priv->fbsize - 1);
putreg32(AM335X_LCD_DMA_FB1_BASE, priv->fbphys);
putreg32(AM335X_LCD_DMA_FB1_CEIL, priv->fbphys + priv->fbsize - 1);
putreg32(AM335X_LCD_DMA_FB0_BASE, CONFIG_AM335X_LCDC_FB_PBASE);
putreg32(AM335X_LCD_DMA_FB0_BASE, CONFIG_AM335X_LCDC_FB_PBASE + priv->fbsize - 1);
putreg32(AM335X_LCD_DMA_FB1_BASE, CONFIG_AM335X_LCDC_FB_PBASE);
putreg32(AM335X_LCD_DMA_FB1_CEIL, CONFIG_AM335X_LCDC_FB_PBASE + priv->fbsize - 1);
/* Enable LCD */
@ -803,16 +796,17 @@ void am335x_lcdclear(nxgl_mxpixel_t color)
{
struct am335x_lcd_dev_s *priv = &g_lcddev;
#if AM335X_BPP > 16
uint32_t *dest = (uint32_t *)priv->fbmem;
uint32_t *dest = (uint32_t *)CONFIG_AM335X_LCDC_FB_VBASE;
int incr = sizeof(uint32_t);
#else
uint16_t *dest = (uint16_t *)priv->fbmem;
uint16_t *dest = (uint16_t *)CONFIG_AM335X_LCDC_FB_VBASE;
int incr = sizeof(uint16_t);
#endif
int i;
lcdinfo("Clearing display: color=%04x VRAM=%p size=%lu\n",
color, priv->fbmem, (unsigned long)priv->fbsize);
lcdinfo("Clearing display: color=%04x VRAM=%08lx size=%lu\n",
color, (unsigned long)CONFIG_AM335X_LCDC_FB_VBASE,
(unsigned long)priv->fbsize);
for (i = 0; i < priv->fbsize; i += incr)
{

View File

@ -137,6 +137,13 @@
# define CONFIG_AM335X_LCDC_FDD 128
#endif
#if (CONFIG_AM335X_LCDC_FB_SIZE & 0x000fffff) != 0
# warning "Framebuffer size must be a multiple of 1Mb"
#endif
#define AM335X_LCDC_FB_SIZE \
((CONFIG_AM335X_LCDC_FB_SIZE + 0x000fffff) & ~0x000fffff)
/****************************************************************************
* Public Types
****************************************************************************/
@ -168,19 +175,6 @@ struct am335x_panel_info_s
uint32_t fdd; /* Palette loading delay */
};
/* A special memory region is set aside for the framebuffer. This region
* must be set aside in the linker script and assigned a virtual address
* during initialization. The framebuffer memory region must be non-
* cached.
*/
struct am335x_fbinfo_s
{
FAR void *fbmem; /* Virtual address of the framebuffer */
FAR void *fbphys; /* Physical address of the framebuffer */
size_t fbsize; /* Size of the framebuffer region */
};
/****************************************************************************
* Public Functions
****************************************************************************/
@ -217,8 +211,6 @@ struct am335x_fbinfo_s
*
* Input Parameters:
* panel - Provides information about the connect LCD panel.
* fbinfo - Provides information about the pre-allocate framebuffer
* memory.
*
* Returned value:
* Zero (OK) is returned on success; a negated errno value is returned in
@ -226,8 +218,7 @@ struct am335x_fbinfo_s
*
****************************************************************************/
int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel,
FAR const struct am335x_fbinfo_s *fbinfo);
int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel);
/****************************************************************************
* Name: am335x_lcdclear
@ -280,8 +271,6 @@ void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode,
* len - The length of the EDID data in bytes
* panel - A user provided location to receive the panel data.
* selected - A user provided location to receive the selected video mode.
* fbinfo - Provides information about the pre-allocate framebuffer
* memory.
*
* Returned value:
* None. Always succeeds. The logic will fallback to VGA mode if no
@ -292,8 +281,7 @@ void am335x_lcd_videomode(FAR const struct edid_videomode_s *videomode,
void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len,
FAR struct am335x_panel_info_s *panel,
FAR struct edid_videomode_s *selected,
FAR const struct am335x_fbinfo_s *fbinfo);
FAR struct edid_videomode_s *selected);
/****************************************************************************
* Name: am335x_backlight

View File

@ -255,7 +255,7 @@ const struct section_mapping_s g_section_mapping[] =
* regions, making it non-cacheable and non-buffereable.
*
* If SDRAM will be reconfigured, then we will defer setup of the framebuffer
* until after the SDRAM remapping (since the framebuffer problem resides) in
* until after the SDRAM remapping since the framebuffer probablyresides in
* SDRAM.
*/