From 5633a296ebb970d0a6be839fb37eaf8a11aa35f8 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 2 Feb 2015 17:13:29 +0100 Subject: sunxi: video: Do not use CONFIG_SYS_MEM_TOP_HIDE for the framebuffer Do not use CONFIG_SYS_MEM_TOP_HIDE for the framebuffer, instead override board_get_usable_ram_top to make sure that u-boot is not relocated into the area where we want to use the framebuffer, and patch the devicetree from sunxi_simplefb_setup() to tell the kernel to not touch the framebuffer. This makes u-boot properly see the framebuffer as dram, and initalize the level 2 cache for it, fixing the very slow cfb scrolling problem. As an added bonus this stops us from reserving the framebuffer when simplefb is not used because an older kernel is booted, or hdp is used and no hdmi cable was plugged in, freeing up the memory for kernel use in these cases. Reported-by: Siarhei Siamashka Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/video/sunxi_display.c | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index f5f24fc020..cd5963a751 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -1060,6 +1060,11 @@ static const char *sunxi_get_mon_desc(enum sunxi_monitor monitor) return NULL; /* never reached */ } +ulong board_get_usable_ram_top(ulong total_size) +{ + return gd->ram_top - CONFIG_SUNXI_MAX_FB_SIZE; +} + void *video_hw_init(void) { static GraphicDevice *graphic_device = &sunxi_display.graphic_device; @@ -1076,7 +1081,7 @@ void *video_hw_init(void) memset(&sunxi_display, 0, sizeof(struct sunxi_display)); printf("Reserved %dkB of RAM for Framebuffer.\n", - CONFIG_SUNXI_FB_SIZE >> 10); + CONFIG_SUNXI_MAX_FB_SIZE >> 10); gd->fb_base = gd->ram_top; video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, @@ -1194,6 +1199,7 @@ int sunxi_simplefb_setup(void *blob) { static GraphicDevice *graphic_device = &sunxi_display.graphic_device; int offset, ret; + u64 start, size; const char *pipeline = NULL; #ifdef CONFIG_MACH_SUN4I @@ -1237,6 +1243,20 @@ int sunxi_simplefb_setup(void *blob) return 0; /* Keep older kernels working */ } + /* + * Do not report the framebuffer as free RAM to the OS, note we cannot + * use fdt_add_mem_rsv() here, because then it is still seen as RAM, + * and e.g. Linux refuses to iomap RAM on ARM, see: + * linux/arch/arm/mm/ioremap.c around line 301. + */ + start = gd->bd->bi_dram[0].start; + size = gd->bd->bi_dram[0].size - CONFIG_SUNXI_MAX_FB_SIZE; + ret = fdt_fixup_memory_banks(blob, &start, &size, 1); + if (ret) { + eprintf("Cannot setup simplefb: Error reserving memory\n"); + return ret; + } + ret = fdt_setup_simplefb_node(blob, offset, gd->fb_base, graphic_device->winSizeX, graphic_device->winSizeY, graphic_device->winSizeX * graphic_device->gdfBytesPP, -- cgit From 20779ec3a5d7b3cad4fdc960d9e2e898fab259b3 Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Mon, 2 Feb 2015 18:00:53 +0100 Subject: sunxi: video: Dynamically reserve framebuffer memory Only use CONFIG_SUNXI_MAX_FB_SIZE to reserve memory at the top when relocating u-boot, and calculate the actual amount of memory necessary when setting up the video-mode and use only that, freeing up some additional memory for use by the kernel. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/video/sunxi_display.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index cd5963a751..dbda97e746 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -46,6 +46,7 @@ struct sunxi_display { GraphicDevice graphic_device; enum sunxi_monitor monitor; unsigned int depth; + unsigned int fb_size; } sunxi_display; #ifdef CONFIG_VIDEO_HDMI @@ -1080,10 +1081,6 @@ void *video_hw_init(void) memset(&sunxi_display, 0, sizeof(struct sunxi_display)); - printf("Reserved %dkB of RAM for Framebuffer.\n", - CONFIG_SUNXI_MAX_FB_SIZE >> 10); - gd->fb_base = gd->ram_top; - video_get_ctfb_res_modes(RES_MODE_1024x768, 24, &mode, &sunxi_display.depth, &options); #ifdef CONFIG_VIDEO_HDMI @@ -1174,6 +1171,17 @@ void *video_hw_init(void) mode->yres, sunxi_get_mon_desc(sunxi_display.monitor)); } + sunxi_display.fb_size = + (mode->xres * mode->yres * 4 + 0xfff) & ~0xfff; + if (sunxi_display.fb_size > CONFIG_SUNXI_MAX_FB_SIZE) { + printf("Error need %dkB for fb, but only %dkB is reserved\n", + sunxi_display.fb_size >> 10, + CONFIG_SUNXI_MAX_FB_SIZE >> 10); + return NULL; + } + + gd->fb_base = gd->bd->bi_dram[0].start + + gd->bd->bi_dram[0].size - sunxi_display.fb_size; sunxi_engines_init(); sunxi_mode_set(mode, gd->fb_base - CONFIG_SYS_SDRAM_BASE); @@ -1250,7 +1258,7 @@ int sunxi_simplefb_setup(void *blob) * linux/arch/arm/mm/ioremap.c around line 301. */ start = gd->bd->bi_dram[0].start; - size = gd->bd->bi_dram[0].size - CONFIG_SUNXI_MAX_FB_SIZE; + size = gd->bd->bi_dram[0].size - sunxi_display.fb_size; ret = fdt_fixup_memory_banks(blob, &start, &size, 1); if (ret) { eprintf("Cannot setup simplefb: Error reserving memory\n"); -- cgit From b1b912ddf3041627e99899cfc09e015a54f9910e Mon Sep 17 00:00:00 2001 From: Hans de Goede Date: Wed, 11 Feb 2015 09:05:18 +0100 Subject: sunxi: otg: Fix peripheral mode Peripheral mode needs us to signal vusb high to the phy for it to work, just like the host mode does. Signed-off-by: Hans de Goede Acked-by: Ian Campbell --- drivers/usb/musb-new/sunxi.c | 13 +------------ 1 file changed, 1 insertion(+), 12 deletions(-) (limited to 'drivers') diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 778916df00..4646a3d9fe 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -145,16 +145,6 @@ static void USBC_ForceIdToHigh(__iomem void *base) musb_writel(base, USBC_REG_o_ISCR, reg_val); } -static void USBC_ForceVbusValidDisable(__iomem void *base) -{ - u32 reg_val; - - reg_val = musb_readl(base, USBC_REG_o_ISCR); - reg_val &= ~(0x03 << USBC_BP_ISCR_FORCE_VBUS_VALID); - reg_val = USBC_WakeUp_ClearChangeDetect(reg_val); - musb_writel(base, USBC_REG_o_ISCR, reg_val); -} - static void USBC_ForceVbusValidToHigh(__iomem void *base) { u32 reg_val; @@ -248,12 +238,11 @@ static int sunxi_musb_init(struct musb *musb) if (is_host_enabled(musb)) { /* Host mode */ USBC_ForceIdToLow(musb->mregs); - USBC_ForceVbusValidToHigh(musb->mregs); } else { /* Peripheral mode */ USBC_ForceIdToHigh(musb->mregs); - USBC_ForceVbusValidDisable(musb->mregs); } + USBC_ForceVbusValidToHigh(musb->mregs); return 0; } -- cgit