From ed91fa34a0b83dcbb6f2e0ee4c14dd97d1b8423e Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Mon, 8 Jul 2019 13:23:56 -0600 Subject: [PATCH] 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. --- arch/arm/src/am335x/Kconfig | 24 +++++++++--- arch/arm/src/am335x/am335x_boot.c | 49 ++++++++++++++++++++----- arch/arm/src/am335x/am335x_edid.c | 19 ++++------ arch/arm/src/am335x/am335x_lcdc.c | 42 +++++++++------------ arch/arm/src/am335x/am335x_lcdc.h | 30 +++++---------- arch/arm/src/sama5/sama5d2x_memorymap.c | 2 +- 6 files changed, 93 insertions(+), 73 deletions(-) diff --git a/arch/arm/src/am335x/Kconfig b/arch/arm/src/am335x/Kconfig index b7ee6fa19bb..98e5141e38c 100644 --- a/arch/arm/src/am335x/Kconfig +++ b/arch/arm/src/am335x/Kconfig @@ -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" diff --git a/arch/arm/src/am335x/am335x_boot.c b/arch/arm/src/am335x/am335x_boot.c index a948bd1ebd7..14e5159b37e 100644 --- a/arch/arm/src/am335x/am335x_boot.c +++ b/arch/arm/src/am335x/am335x_boot.c @@ -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 * diff --git a/arch/arm/src/am335x/am335x_edid.c b/arch/arm/src/am335x/am335x_edid.c index bc93a7b06b9..1d5aed8d177 100644 --- a/arch/arm/src/am335x/am335x_edid.c +++ b/arch/arm/src/am335x/am335x_edid.c @@ -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 { diff --git a/arch/arm/src/am335x/am335x_lcdc.c b/arch/arm/src/am335x/am335x_lcdc.c index bc9a17f90a6..1aeb115eeb4 100644 --- a/arch/arm/src/am335x/am335x_lcdc.c +++ b/arch/arm/src/am335x/am335x_lcdc.c @@ -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) { diff --git a/arch/arm/src/am335x/am335x_lcdc.h b/arch/arm/src/am335x/am335x_lcdc.h index 6f001d5d3a8..03a59663d1a 100644 --- a/arch/arm/src/am335x/am335x_lcdc.h +++ b/arch/arm/src/am335x/am335x_lcdc.h @@ -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 diff --git a/arch/arm/src/sama5/sama5d2x_memorymap.c b/arch/arm/src/sama5/sama5d2x_memorymap.c index a9dc6cdabab..dd4310923de 100644 --- a/arch/arm/src/sama5/sama5d2x_memorymap.c +++ b/arch/arm/src/sama5/sama5d2x_memorymap.c @@ -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. */