I have a prototype board, when ever I try to run an graphical program using vivante drivers the system segfaults.
We suspect, after switching from ddr3 to lpddr2 which caused a memory address change, that the vivante drivers might need to be updated for the change. A basic driver with a linux FB works fine but the accelerated graphics is busted.
Might this be the cause? Any hints on how to fix?
Solved! Go to Solution.
Ok, this has now be FIXED!
Here's the scoop: Yes, it's a memory problem. Since the board is using LPDDR2, this shifts the Memory Map for the device up by 2G (0x80000000). Even though one needs to make the changes in 2 places:
- /arch/arm/plat-mxc/include/mach/memory.h change MX6_PHYS_OFFSET to be 0x80000000
- /arch/arm/plat-mxc/devcies/platform-viv_gpu.c change the .phys_baseaddr in the imx_viv_gpu_data structure to also be 0x80000000
Apparently the memory manager still needs to be told that memory to be used is > 2G.
In the board file, this line in the _reserve() function:
phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
SZ_4K, SZ_512M);
Needs to be modified to:
phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
SZ_4K, (SZ_2G + SZ_1G));
This 3rd parameter, per the function definition, is the "max size of memory". Since this board has 1GB (which I was using previously as the parameter and still getting a kernel crash), I simply added in the +2GB offset caused by the use of the LPDDR2 and the shift it causes in the memory mapping.
And VOILA!!! We have liftoff - the kernel now boots and loads the GPU up and I am now getting some Graphical output.
Regards,
Stephen Beckwith
Kevin,
I'm having a similar problem with a customer's board. It's a modified SABRE reference design, one of the key changes being: LPDDR2!
I have the system booting successfully with 3.0.35 kernel in a "non-GPU" setup that works fine on 2 different displays (a 4.3" and a 2.7"). However, toggling on the GPU causes the same hang you see @ Boot time.
I too suspect the code referenced in the thread that does this memory allocation. The customer's "board file" did not have this code initially present and was missing some key data structures. Adding this all back (referenced from the SABRE SD board file), it's still a no-go.
I already changed the MX6_PHYS_OFFSET - per another thread (and patch). This gets the kernel to run/boot OK (which means u-boot setup is "in-sync" as well). With the GPU enabled, there's no booting.
Agreed that this code seems to be suspect in some way, though not sure why.
Which kernel version are you using for setup?
Can anyone @ FSL address this? CPU is a imx6D.
Regards,
Stephen Beckwith
Embedded Linux Engineer
Timesys Corp.
Ok, this has now be FIXED!
Here's the scoop: Yes, it's a memory problem. Since the board is using LPDDR2, this shifts the Memory Map for the device up by 2G (0x80000000). Even though one needs to make the changes in 2 places:
- /arch/arm/plat-mxc/include/mach/memory.h change MX6_PHYS_OFFSET to be 0x80000000
- /arch/arm/plat-mxc/devcies/platform-viv_gpu.c change the .phys_baseaddr in the imx_viv_gpu_data structure to also be 0x80000000
Apparently the memory manager still needs to be told that memory to be used is > 2G.
In the board file, this line in the _reserve() function:
phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
SZ_4K, SZ_512M);
Needs to be modified to:
phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
SZ_4K, (SZ_2G + SZ_1G));
This 3rd parameter, per the function definition, is the "max size of memory". Since this board has 1GB (which I was using previously as the parameter and still getting a kernel crash), I simply added in the +2GB offset caused by the use of the LPDDR2 and the shift it causes in the memory mapping.
And VOILA!!! We have liftoff - the kernel now boots and loads the GPU up and I am now getting some Graphical output.
Regards,
Stephen Beckwith
Quake arena here I come
Have you gotten a chance to look at the uboot config? Do you need any more information?
I'm not sure about the exact issue now but I think i have an issue with reserving memory for the gpu
This particular block of code seems to cause the system to stop booting. I'm still trying to understand what this is for. DMA? What could cause this to fail?
phys_addr_t phys;
if (imx6q_gpu_pdata.reserved_mem_size) {
phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
SZ_4K, SZ_512M);
memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
imx6q_gpu_pdata.reserved_mem_base = phys;
}
Didn't quite work, still getting a seg fault with opengl
Are there any logs that might help me figure out why?
Which BSP release are you using ? are you using x11 ? did you tried the unit_test provided in our BSP ?
regards,
Andre
I'll see if i have one, right now we are using something that timesys gave us. We outsourced our board bring up to them. So I'm taking it and integrating in with all our stuff. Right now the video is really choppy only going through the IPU with a framebuffer, I assume since the IPU works the GPU should work...
here are the unit tests
./galRunTest2 ./libgal2DAlphaBlending001.so -c ./galTestCommon.cfg
*ERROR* Failed to construct OS object (status = -27)
Initialize test failed
*snip*
Are you installing the gpu driver?
modprobe galcore
regards,
Andre
Nope, I just realized that a few minutes ago, I thought it was included in the vivante package but apparnetly you have to add the module part of it to the kernel.
With that said, it doesn't work at all, the boot process now stops on this "Uncompressing Linux... done, booting the kernel." line.
I think maybe its failing on this section
return; // adding this to see if the below is a problem.
#if defined(CONFIG_MXC_GPU_VIV) || defined(CONFIG_MXC_GPU_VIV_MODULE)
phys_addr_t phys;
if (imx6q_gpu_pdata.reserved_mem_size) {
phys = memblock_alloc_base(imx6q_gpu_pdata.reserved_mem_size,
SZ_4K, SZ_512M);
memblock_remove(phys, imx6q_gpu_pdata.reserved_mem_size);
imx6q_gpu_pdata.reserved_mem_base = phys;
}
#endif
I figured since i built a module it should still be able start the kernel but those ifdefs seem ot possibly cause problems during boot
The return I added skips that section, seems to work, up until I reach this point.
[ 5.769373] Galcore version 4.6.9.6622
then I locks up again.
If i edit the memory space, arch/arm/plat-mxc/include/mach/memory.h is the correct file to make that modification?
It looks like i went from 0x10000000 to 0x80000000
-#define MX6_PHYS_OFFSET UL(0x10000000)
+#define MX6_PHYS_OFFSET UL(0x80000000)
I could be looking at the wrong thing though.
How does your u-boot config file look like (include/configs/...)? Are you building galcore as built-in driver or as a kernel module?
I'm building the GALCORE as a module, here is our config
#ifndef __CONFIG_H
#define __CONFIG_H
#define CONFIG_MX6
#define CONFIG_MX6Q
#include "mx6_common.h"
#define CONFIG_DISPLAY_CPUINFO
#define CONFIG_DISPLAY_BOARDINFO
#define CONFIG_MACH_TYPE 4546
#include <asm/arch/imx-regs.h>
#include <asm/imx-common/gpio.h>
#define CONFIG_CMDLINE_TAG
#define CONFIG_SETUP_MEMORY_TAGS
#define CONFIG_INITRD_TAG
/* Size of malloc() pool */
#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + 2 * 1024 * 1024)
#define CONFIG_BOARD_EARLY_INIT_F
#define CONFIG_MXC_GPIO
#define CONFIG_MXC_UART
#define CONFIG_MXC_UART_BASE UART2_BASE
/* SPI Flash */
#define CONFIG_IMX_ECSPI
#define CONFIG_CMD_SF
#define CONFIG_SPI_FLASH
#define CONFIG_SPI_FLASH_SPANSION
#define CONFIG_MXC_SPI
#define CONFIG_SF_DEFAULT_BUS 0
#define CONFIG_SF_DEFAULT_CS (0|(IMX_GPIO_NR(2, 30)<<8))
#define CONFIG_SF_DEFAULT_SPEED 25000000
#define CONFIG_SF_DEFAULT_MODE (SPI_MODE_0)
#undef MAX_SPI_BYTES
#define MAX_SPI_BYTES (64 * 4)
#define CONFIG_SPI_FLASH_BAR
/* MMC Configs */
#define CONFIG_FSL_ESDHC
#define CONFIG_FSL_USDHC
#define CONFIG_SYS_FSL_ESDHC_ADDR 0
#define CONFIG_SYS_FSL_USDHC_NUM 2
#define CONFIG_MMC
#define CONFIG_CMD_MMC
#define CONFIG_GENERIC_MMC
#define CONFIG_BOUNCE_BUFFER
#define CONFIG_CMD_FAT
#define CONFIG_CMD_EXT2
#define CONFIG_DOS_PARTITION
#define CONFIG_CMD_PING
#define CONFIG_CMD_DHCP
#define CONFIG_CMD_MII
#define CONFIG_CMD_NET
#define CONFIG_FEC_MXC
#define CONFIG_MII
#define IMX_FEC_BASE ENET_BASE_ADDR
#define CONFIG_FEC_XCV_TYPE RMII
#define CONFIG_FEC_MXC_PHYADDR 0
/* allow to overwrite serial and ethaddr */
#define CONFIG_ENV_OVERWRITE
#define CONFIG_CONS_INDEX 2
#define CONFIG_BAUDRATE 115200
/* Command definition */
#include <config_cmd_default.h>
#undef CONFIG_CMD_IMLS
#define CONFIG_BOOTDELAY 3
#define CONFIG_LOADADDR 0x80800000
#define CONFIG_SYS_TEXT_BASE 0x87800000
#define CONFIG_EXTRA_ENV_SETTINGS \
"script=boot.scr\0" \
"uimage=uImage\0" \
"console=ttymxc1\0" \
"fdt_high=0xffffffff\0" \
"initrd_high=0xffffffff\0" \
"mmcdev=0\0" \
"mmcpart=1\0" \
"mmcroot=/dev/mmcblk0p1 rootwait rw\0" \
"mmcargs=setenv bootargs console=${console},${baudrate} " \
"root=${mmcroot}\0" \
"loadbootscript=" \
"fatload mmc ${mmcdev}:${mmcpart} ${loadaddr} ${script};\0" \
"bootscript=echo Running bootscript from mmc ...; " \
"source\0" \
"loaduimage=ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} ${uimage}\0" \
"mmcboot=echo Booting from mmc ...; " \
"run mmcargs; " \
"bootm\0" \
"netargs=setenv bootargs console=${console},${baudrate} " \
"root=/dev/nfs " \
"ip=dhcp nfsroot=${serverip}:${nfsroot},v3,tcp\0" \
"netboot=echo Booting from net ...; " \
"run netargs; " \
"dhcp ${uimage}; bootm\0" \
"load_uboot=echo loading U-Boot to ${loadaddr} from mmc...; " \
"mmc rescan; " \
"ext2load mmc ${mmcdev}:${mmcpart} ${loadaddr} u-boot.imx\0" \
"flash_uboot=echo flashing U-Boot from ${loadaddr}...; " \
"sf probe; " \
"sf erase 0 0x40000; " \
"sf write ${loadaddr} 0x400 0x40000\0" \
"upgrade_uboot=run load_uboot flash_uboot\0" \
#define CONFIG_BOOTCOMMAND \
"mmc dev ${mmcdev};" \
"mmc dev ${mmcdev}; if mmc rescan; then " \
"if run loadbootscript; then " \
"run bootscript; " \
"else " \
"if run loaduimage; then " \
"run mmcboot; " \
"else run netboot; " \
"fi; " \
"fi; " \
"else run netboot; fi"
#define CONFIG_ARP_TIMEOUT 200UL
/* Miscellaneous configurable options */
#define CONFIG_SYS_LONGHELP
#define CONFIG_SYS_HUSH_PARSER
#define CONFIG_SYS_PROMPT "MX6Q CAMARO U-Boot > "
#define CONFIG_AUTO_COMPLETE
#define CONFIG_SYS_CBSIZE 256
/* Print Buffer Size */
#define CONFIG_SYS_PBSIZE (CONFIG_SYS_CBSIZE + sizeof(CONFIG_SYS_PROMPT) + 16)
#define CONFIG_SYS_MAXARGS 16
#define CONFIG_SYS_BARGSIZE CONFIG_SYS_CBSIZE
#define CONFIG_SYS_MEMTEST_START 0x80000000
#define CONFIG_SYS_MEMTEST_END 0x80010000
#define CONFIG_SYS_LOAD_ADDR CONFIG_LOADADDR
#define CONFIG_SYS_HZ 1000
#define CONFIG_CMDLINE_EDITING
/* Physical Memory Map */
#define CONFIG_NR_DRAM_BANKS 1
#define PHYS_SDRAM MMDC1_ARB_BASE_ADDR
#define PHYS_SDRAM_SIZE (1u * 1024 * 1024 * 1024)
#define CONFIG_SYS_SDRAM_BASE PHYS_SDRAM
#define CONFIG_SYS_INIT_RAM_ADDR IRAM_BASE_ADDR
#define CONFIG_SYS_INIT_RAM_SIZE IRAM_SIZE
#define CONFIG_SYS_INIT_SP_OFFSET \
(CONFIG_SYS_INIT_RAM_SIZE - GENERATED_GBL_DATA_SIZE)
#define CONFIG_SYS_INIT_SP_ADDR \
(CONFIG_SYS_INIT_RAM_ADDR + CONFIG_SYS_INIT_SP_OFFSET)
#define CONFIG_SYS_NO_FLASH
#define CONFIG_ENV_IS_IN_SPI_FLASH
#define CONFIG_ENV_SECT_SIZE (256 * 1024)
#define CONFIG_ENV_SIZE CONFIG_ENV_SECT_SIZE
#define CONFIG_ENV_OFFSET (1024 * 1024)
#define CONFIG_ENV_SPI_BUS CONFIG_SF_DEFAULT_BUS
#define CONFIG_ENV_SPI_CS CONFIG_SF_DEFAULT_CS
#define CONFIG_ENV_SPI_MODE CONFIG_SF_DEFAULT_MODE
#define CONFIG_ENV_SPI_MAX_HZ CONFIG_SF_DEFAULT_SPEED
#define CONFIG_OF_LIBFDT
#define CONFIG_CMD_BOOTZ
#endif /* __CONFIG_H */
What kind of memory address change did you do? If memory space changed from starting from 0x00000000 to 0x80000000, you'll need to adjust .phys_base addr in platform-viv_gpu.c file for imx6_gpu_data structure.
This is what we had to change to get the lpddr working
--- a/arch/arm/plat-mxc/include/mach/memory.h
+++ b/arch/arm/plat-mxc/include/mach/memory.h
@@ -22,7 +22,7 @@
-#define MX6_PHYS_OFFSET UL(0x10000000)
+#define MX6_PHYS_OFFSET UL(0x80000000)
So I'm updating the file to be like the IMX6SL define
.phys_baseaddr = MX6SL_MMDC0_ARB_BASE_ADDR
I'll let you know if this works, it'll be a Christmas miracle for us!