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" menu "LCD Configuration"
depends on AM335X_LCDC depends on AM335X_LCDC
config AM335X_LCDC_VRAMBASE config AM335X_LCDC_FB_VBASE
hex "Video RAM base address" hex "Video RAM base address (virtual)"
default 0xa0010000 default 0x80000000
---help--- ---help---
Base address of the video RAM frame buffer. The default is Base address of the video RAM frame buffer. The default of 0x80000000
(AM335X_EXTDRAM_CS0 + 0x00010000) 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 config AM335X_LCDC_USE_CLKIN
bool "Use optional input clock" bool "Use optional input clock"

View File

@ -66,6 +66,13 @@
* Pre-processor Definitions * 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 * Name: showprogress
* *
@ -105,9 +112,8 @@
extern uint32_t _vector_start; /* Beginning of vector block */ extern uint32_t _vector_start; /* Beginning of vector block */
extern uint32_t _vector_end; /* End+1 of vector block */ extern uint32_t _vector_end; /* End+1 of vector block */
/**************************************************************************** #define SAMA5_LCDC_FBNSECTIONS \
* Private Functions ((CONFIG_SAMA5_LCDC_FB_SIZE + 0x000fffff) >> 20)
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Private Data * Private Data
@ -120,32 +126,55 @@ extern uint32_t _vector_end; /* End+1 of vector block */
#ifndef CONFIG_ARCH_ROMPGTABLE #ifndef CONFIG_ARCH_ROMPGTABLE
static const struct section_mapping_s g_section_mapping[] = 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_GPMC_MMUFLAGS, AM335X_GPMC_NSECTIONS
}, },
{ AM335X_BROM_PSECTION, AM335X_BROM_VSECTION, {
AM335X_BROM_PSECTION, AM335X_BROM_VSECTION,
AM335X_BROM_MMUFLAGS, AM335X_BROM_NSECTIONS 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_ISRAM_MMUFLAGS, AM335X_ISRAM_NSECTIONS
}, },
{ AM335X_OCMC0_PSECTION, AM335X_OCMC0_VSECTION, {
AM335X_OCMC0_PSECTION, AM335X_OCMC0_VSECTION,
AM335X_OCMC0_MMUFLAGS, AM335X_OCMC0_NSECTIONS 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_PERIPH_MMUFLAGS, AM335X_PERIPH_NSECTIONS
}, },
{ AM335X_DDR_PSECTION, AM335X_DDR_VSECTION, {
AM335X_DDR_PSECTION, AM335X_DDR_VSECTION,
AM335X_DDR_MMUFLAGS, AM335X_DDR_NSECTIONS 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 \ #define NMAPPINGS \
(sizeof(g_section_mapping) / sizeof(struct section_mapping_s)) (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 #endif
/****************************************************************************
* Private Functions
****************************************************************************/
/**************************************************************************** /****************************************************************************
* Name: am335x_setupmappings * Name: am335x_setupmappings
* *

View File

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

View File

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

View File

@ -137,6 +137,13 @@
# define CONFIG_AM335X_LCDC_FDD 128 # define CONFIG_AM335X_LCDC_FDD 128
#endif #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 * Public Types
****************************************************************************/ ****************************************************************************/
@ -168,19 +175,6 @@ struct am335x_panel_info_s
uint32_t fdd; /* Palette loading delay */ 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 * Public Functions
****************************************************************************/ ****************************************************************************/
@ -217,8 +211,6 @@ struct am335x_fbinfo_s
* *
* Input Parameters: * Input Parameters:
* panel - Provides information about the connect LCD panel. * panel - Provides information about the connect LCD panel.
* fbinfo - Provides information about the pre-allocate framebuffer
* memory.
* *
* Returned value: * Returned value:
* Zero (OK) is returned on success; a negated errno value is returned in * 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, int am335x_lcd_initialize(FAR const struct am335x_panel_info_s *panel);
FAR const struct am335x_fbinfo_s *fbinfo);
/**************************************************************************** /****************************************************************************
* Name: am335x_lcdclear * 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 * len - The length of the EDID data in bytes
* panel - A user provided location to receive the panel data. * panel - A user provided location to receive the panel data.
* selected - A user provided location to receive the selected video mode. * selected - A user provided location to receive the selected video mode.
* fbinfo - Provides information about the pre-allocate framebuffer
* memory.
* *
* Returned value: * Returned value:
* None. Always succeeds. The logic will fallback to VGA mode if no * 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, void am335x_lcd_edid(FAR const uint8_t *edid, size_t edid_len,
FAR struct am335x_panel_info_s *panel, FAR struct am335x_panel_info_s *panel,
FAR struct edid_videomode_s *selected, FAR struct edid_videomode_s *selected);
FAR const struct am335x_fbinfo_s *fbinfo);
/**************************************************************************** /****************************************************************************
* Name: am335x_backlight * 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. * regions, making it non-cacheable and non-buffereable.
* *
* If SDRAM will be reconfigured, then we will defer setup of the framebuffer * 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. * SDRAM.
*/ */