From 93ba78ece1eb153be1519b254b7ae4e1f8289b70 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 20 Jan 2015 14:52:39 +0100 Subject: ARM: MXS: imx28evk: Add lowlevel support This switches the imx28evk to multiimage support and adds the lowlevel initialization to make the bootlets unnecessary. Signed-off-by: Sascha Hauer --- arch/arm/boards/freescale-mx28-evk/lowlevel.c | 58 ++++++++++++++++++++++++++- arch/arm/mach-mxs/Kconfig | 1 + images/Makefile.mxs | 10 +++++ 3 files changed, 67 insertions(+), 2 deletions(-) diff --git a/arch/arm/boards/freescale-mx28-evk/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c index 3c7248ef65..a46a080518 100644 --- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c +++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c @@ -1,11 +1,65 @@ +#define pr_fmt(fmt) "Freescale MX28evk: " fmt +#define DEBUG + #include #include #include #include #include +#include +#include +#include +#include +#include -void __naked barebox_arm_reset_vector(void) +ENTRY_FUNCTION(start_barebox_freescale_mx28evk, r0, r1, r2) { - arm_cpu_lowlevel_init(); barebox_arm_entry(IMX_MEMORY_BASE, SZ_128M, NULL); } + +static const uint32_t iomux_pads[] = { + /* EMI */ + EMI_DATA0, EMI_DATA1, EMI_DATA2, EMI_DATA3, EMI_DATA4, EMI_DATA5, + EMI_DATA6, EMI_DATA7, EMI_DATA8, EMI_DATA9, EMI_DATA10, EMI_DATA11, + EMI_DATA12, EMI_DATA13, EMI_DATA14, EMI_DATA15, EMI_ODT0, EMI_DQM0, + EMI_ODT1, EMI_DQM1, EMI_DDR_OPEN_FB, EMI_CLK, EMI_DSQ0, EMI_DSQ1, + EMI_DDR_OPEN, EMI_A0, EMI_A1, EMI_A2, EMI_A3, EMI_A4, EMI_A5, + EMI_A6, EMI_A7, EMI_A8, EMI_A9, EMI_A10, EMI_A11, EMI_A12, EMI_A13, + EMI_A14, EMI_BA0, EMI_BA1, EMI_BA2, EMI_CASN, EMI_RASN, EMI_WEN, + EMI_CE0N, EMI_CE1N, EMI_CKE, + + /* Debug UART */ + PWM0_DUART_RX | VE_3_3V, + PWM1_DUART_TX | VE_3_3V, +}; + +static noinline void freescale_mx28evk_init(void) +{ + int i; + + /* initialize muxing */ + for (i = 0; i < ARRAY_SIZE(iomux_pads); i++) + imx_gpio_mode(iomux_pads[i]); + + pr_debug("initializing power...\n"); + + mx28_power_init_battery_input(); + + pr_debug("initializing SDRAM...\n"); + + mx28_mem_init(); + + pr_debug("DONE\n"); +} + +ENTRY_FUNCTION(prep_start_barebox_freescale_mx28evk, r0, r1, r2) +{ + void (*back)(unsigned long) = (void *)get_lr(); + + relocate_to_current_adr(); + setup_c(); + + freescale_mx28evk_init(); + + back(0); +} diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index 4022710007..ef5d22313a 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -69,6 +69,7 @@ config MACH_TX28 config MACH_MX28EVK bool "mx28-evk" select MXS_OCOTP + select HAVE_PBL_MULTI_IMAGES help Say Y here if you are using the Freescale i.MX28-EVK board diff --git a/images/Makefile.mxs b/images/Makefile.mxs index abff255c3d..e2cdbd2a27 100644 --- a/images/Makefile.mxs +++ b/images/Makefile.mxs @@ -32,6 +32,16 @@ image-$(CONFIG_MACH_TX28) += barebox-karo-tx28-sd.img FILE_barebox-karo-tx28-2nd.img = start_barebox_karo_tx28.pblx image-$(CONFIG_MACH_TX28) += barebox-karo-tx28-2nd.img +pblx-$(CONFIG_MACH_MX28EVK) += start_barebox_freescale_mx28evk prep_start_barebox_freescale_mx28evk +PREP_start_barebox_freescale_mx28evk.pblx.mxsbs = start_barebox_freescale_mx28evk_prep +CFG_start_barebox_freescale_mx28evk.mxsbs = $(mxs28cfg) +FILE_barebox-freescale-mx28evk-bootstream.img = start_barebox_freescale_mx28evk.mxsbs +image-$(CONFIG_MACH_MX28EVK) += barebox-freescale-mx28evk-bootstream.img +FILE_barebox-freescale-mx28evk-sd.img = start_barebox_freescale_mx28evk.mxsbs.mxssd +image-$(CONFIG_MACH_MX28EVK) += barebox-freescale-mx28evk-sd.img +FILE_barebox-freescale-mx28evk-2nd.img = start_barebox_freescale_mx28evk.pblx +image-$(CONFIG_MACH_MX28EVK) += barebox-freescale-mx28evk-2nd.img + pblx-$(CONFIG_MACH_IMX233_OLINUXINO) += start_barebox_olinuxino_imx23 prep_start_barebox_olinuxino_imx23 PREP_start_barebox_olinuxino_imx23.pblx.mxsbs = start_barebox_olinuxino_imx23_prep; CFG_start_barebox_olinuxino_imx23.mxsbs = $(mxs23cfg) -- cgit v1.2.3 From c69237d38372fd5ba178cd02c3e9c506bfe4599b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 20 Jan 2015 15:08:08 +0100 Subject: ARM: MXS: imx28evk: Update environment and config This switches the imx28evk to new environment and updates the defconfig file for tons of new features. Signed-off-by: Sascha Hauer --- arch/arm/boards/freescale-mx28-evk/env/config | 50 ------------------- arch/arm/configs/freescale-mx28-evk_defconfig | 71 ++++++++++++++++++++------- arch/arm/mach-mxs/Kconfig | 1 + 3 files changed, 54 insertions(+), 68 deletions(-) delete mode 100644 arch/arm/boards/freescale-mx28-evk/env/config diff --git a/arch/arm/boards/freescale-mx28-evk/env/config b/arch/arm/boards/freescale-mx28-evk/env/config deleted file mode 100644 index adbe7f4973..0000000000 --- a/arch/arm/boards/freescale-mx28-evk/env/config +++ /dev/null @@ -1,50 +0,0 @@ -#!/bin/sh - -#user= - -# use 'dhcp' to do dhcp in barebox and in kernel -# use 'none' if you want to skip kernel ip autoconfiguration -ip=dhcp - -# or set your networking parameters here -#eth0.ipaddr=a.b.c.d -#eth0.netmask=a.b.c.d -#eth0.serverip=a.b.c.d -#eth0.gateway=a.b.c.d -#eth0.ethaddr=de:ad:be:ef:00:00 - -# can be either 'tftp', 'nfs', 'nand', 'nor' or 'disk' -kernel_loc=tftp -# can be either 'net', 'nand', 'nor', 'disk' or 'initrd' -rootfs_loc=net - -# for flash based rootfs: 'jffs2' or 'ubifs' -# in case of disk any regular filesystem like 'ext2', 'ext3', 'reiserfs' -rootfs_type=ext2 -# where is the rootfs in case of 'rootfs_loc=disk' (linux name) -rootfs_part_linux_dev=mmcblk0p4 -rootfsimage=rootfs-${global.hostname}.$rootfs_type - -# where is the kernel image in case of 'kernel_loc=disk' -kernel_part=disk0.2 - -kernelimage=zImage-${global.hostname} -bareboximage=barebox-${global.hostname}.bin -bareboxenvimage=barebox-${global.hostname}.bin - -if [ -n $user ]; then - bareboximage="$user"-"$bareboximage" - bareboxenvimage="$user"-"$bareboxenvimage" - kernelimage="$user"-"$kernelimage" - rootfsimage="$user"-"$rootfsimage" - nfsroot="/home/$user/nfsroot/${global.hostname}" -else - nfsroot="/path/to/nfs/root" -fi - -autoboot_timeout=3 - -bootargs="console=ttyAMA0,115200" - -# set a fancy prompt (if support is compiled in) -PS1="\e[1;32mbarebox@\e[1;31m\h:\w\e[0m " diff --git a/arch/arm/configs/freescale-mx28-evk_defconfig b/arch/arm/configs/freescale-mx28-evk_defconfig index b6a63200c7..22ed7bc3ef 100644 --- a/arch/arm/configs/freescale-mx28-evk_defconfig +++ b/arch/arm/configs/freescale-mx28-evk_defconfig @@ -3,37 +3,71 @@ CONFIG_ARCH_IMX28=y CONFIG_MACH_MX28EVK=y CONFIG_AEABI=y CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_ARM_UNWIND=y CONFIG_MMU=y -CONFIG_TEXT_BASE=0x43000000 -CONFIG_MALLOC_SIZE=0x800000 -CONFIG_BROKEN=y -CONFIG_LONGHELP=y -CONFIG_GLOB=y +CONFIG_TEXT_BASE=0x0 +CONFIG_MALLOC_SIZE=0x0 +CONFIG_MALLOC_TLSF=y +CONFIG_KALLSYMS=y +CONFIG_RELOCATABLE=y CONFIG_HUSH_FANCY_PROMPT=y CONFIG_CMDLINE_EDITING=y CONFIG_AUTO_COMPLETE=y -CONFIG_DEFAULT_ENVIRONMENT_GENERIC=y -CONFIG_DEFAULT_ENVIRONMENT_PATH="arch/arm/boards/freescale-mx28-evk/env" +CONFIG_MENU=y +CONFIG_BLSPEC=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_RESET_SOURCE=y CONFIG_DEBUG_INFO=y -CONFIG_CMD_EDIT=y -CONFIG_CMD_SLEEP=y -CONFIG_CMD_SAVEENV=y +CONFIG_CMD_DMESG=y +CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_VERBOSE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_GO=y +CONFIG_CMD_RESET=y +CONFIG_CMD_UIMAGE=y +CONFIG_CMD_PARTITION=y CONFIG_CMD_EXPORT=y +CONFIG_CMD_LOADENV=y CONFIG_CMD_PRINTENV=y -CONFIG_CMD_READLINE=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_CMP=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_LN=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_LET=y +CONFIG_CMD_MSLEEP=y +CONFIG_CMD_READF=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_HOST=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_PING=y CONFIG_CMD_TFTP=y CONFIG_CMD_ECHO_E=y -CONFIG_CMD_BOOTM_SHOW_TYPE=y -CONFIG_CMD_RESET=y -CONFIG_CMD_GO=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_MENUTREE=y CONFIG_CMD_SPLASH=y +CONFIG_CMD_READLINE=y CONFIG_CMD_TIMEOUT=y -CONFIG_CMD_PARTITION=y +CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_MM=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DETECT=y +CONFIG_CMD_FLASH=y CONFIG_CMD_GPIO=y +CONFIG_CMD_NANDTEST=y +CONFIG_CMD_SPI=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OFTREE=y CONFIG_NET=y -CONFIG_CMD_DHCP=y -CONFIG_CMD_PING=y -CONFIG_NET_RESOLV=y CONFIG_DRIVER_SERIAL_AUART=y CONFIG_DRIVER_NET_FEC_IMX=y CONFIG_DRIVER_SPI_MXS=y @@ -48,4 +82,5 @@ CONFIG_MCI_MXS=y CONFIG_MXS_APBH_DMA=y CONFIG_FS_TFTP=y CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index ef5d22313a..5b50e82fc8 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -68,6 +68,7 @@ config MACH_TX28 config MACH_MX28EVK bool "mx28-evk" + select HAVE_DEFAULT_ENVIRONMENT_NEW select MXS_OCOTP select HAVE_PBL_MULTI_IMAGES help -- cgit v1.2.3 From 39189a5dded46d5bd00d87100a4e161a9da4f387 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:10:08 +0100 Subject: ARM: MXS: Fix vddd brownout setting The brownout setting can be at maximum 7*25mV below the voltage setting of the regulator. Set it to the minimum Voltage which is 1325mV. Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/power-init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 977c6e4e27..bc3d65932a 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -1177,7 +1177,7 @@ static void __mx23_power_init(int has_battery) mxs_enable_output_rail_protection(); mxs_power_set_vddx(&mx23_vddio_cfg, 3300, 3150); - mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); + mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325); mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | @@ -1234,7 +1234,7 @@ static void __mx28_power_init(int has_battery) mxs_enable_output_rail_protection(); mxs_power_set_vddx(&mx28_vddio_cfg, 3300, 3150); - mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1000); + mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | -- cgit v1.2.3 From c722646be66100d19837e7604708dba2649e1753 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Wed, 28 Jan 2015 07:42:02 +0100 Subject: MXS: power-init: inline only once used functions mxs_power_init_4p2_params and mxs_power_init_4p2_regulator are used only once, so inline the code. Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/power-init.c | 158 +++++++++++++++++------------------------ 1 file changed, 65 insertions(+), 93 deletions(-) diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index bc3d65932a..366b3f2f6f 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -298,36 +298,6 @@ static void mxs_src_power_init(void) clrbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_DCDC_XFER); } -/** - * mxs_power_init_4p2_params() - Configure the parameters of the 4P2 regulator - * - * This function configures the necessary parameters for the 4P2 linear - * regulator to supply the DC-DC converter from 5V input. - */ -static void mxs_power_init_4p2_params(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)IMX_POWER_BASE; - - /* Setup 4P2 parameters */ - clrsetbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, - POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET)); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_HEADROOM_ADJ_MASK, - 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); - - clrsetbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_DROPOUT_CTRL_MASK, - POWER_DCDC4P2_DROPOUT_CTRL_100MV | - POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL); - - clrsetbits_le32(&power_regs->hw_power_5vctrl, - POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, - 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); -} - /** * mxs_enable_4p2_dcdc_input() - Enable or disable the DCDC input from 4P2 * @xfer: Select if the input shall be enabled or disabled @@ -431,17 +401,78 @@ static void mxs_enable_4p2_dcdc_input(int xfer) } /** - * mxs_power_init_4p2_regulator() - Start the 4P2 regulator + * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source + * + * This function configures the DC-DC converter to be supplied from the 4P2 + * linear regulator. + */ +static void mxs_power_init_dcdc_4p2_source(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)IMX_POWER_BASE; + + if (!(readl(&power_regs->hw_power_dcdc4p2) & + POWER_DCDC4P2_ENABLE_DCDC)) { + hang(); + } + + mxs_enable_4p2_dcdc_input(1); + + if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { + clrbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_ENABLE_DCDC); + writel(POWER_5VCTRL_ENABLE_DCDC, + &power_regs->hw_power_5vctrl_clr); + charger_4p2_disable(); + } +} + +/** + * mxs_power_enable_4p2() - Power up the 4P2 regulator * - * This function enables the 4P2 regulator and switches the DC-DC converter - * to use the 4P2 input. + * This function drives the process of powering up the 4P2 linear regulator + * and switching the DC-DC converter input over to the 4P2 linear regulator. */ -static void mxs_power_init_4p2_regulator(void) +static void mxs_power_enable_4p2(void) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; + uint32_t vdddctrl, vddactrl, vddioctrl; uint32_t tmp, tmp2; + vdddctrl = readl(&power_regs->hw_power_vdddctrl); + vddactrl = readl(&power_regs->hw_power_vddactrl); + vddioctrl = readl(&power_regs->hw_power_vddioctrl); + + setbits_le32(&power_regs->hw_power_vdddctrl, + POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | + POWER_VDDDCTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddactrl, + POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG | + POWER_VDDACTRL_PWDN_BRNOUT); + + setbits_le32(&power_regs->hw_power_vddioctrl, + POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT); + + /* Setup 4P2 parameters */ + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_CMPTRIP_MASK | POWER_DCDC4P2_TRG_MASK, + POWER_DCDC4P2_TRG_4V2 | (31 << POWER_DCDC4P2_CMPTRIP_OFFSET)); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_HEADROOM_ADJ_MASK, + 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); + + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, + POWER_DCDC4P2_DROPOUT_CTRL_MASK, + POWER_DCDC4P2_DROPOUT_CTRL_100MV | + POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL); + + clrsetbits_le32(&power_regs->hw_power_5vctrl, + POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, + 0x3f << POWER_5VCTRL_CHARGE_4P2_ILIMIT_OFFSET); + setbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_ENABLE_4P2); writel(POWER_CHARGE_ENABLE_LOAD, &power_regs->hw_power_charge_set); @@ -516,65 +547,6 @@ static void mxs_power_init_4p2_regulator(void) clrbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_BO_MASK); writel(POWER_CTRL_DCDC4P2_BO_IRQ, &power_regs->hw_power_ctrl_clr); -} - -/** - * mxs_power_init_dcdc_4p2_source() - Switch DC-DC converter to 4P2 source - * - * This function configures the DC-DC converter to be supplied from the 4P2 - * linear regulator. - */ -static void mxs_power_init_dcdc_4p2_source(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)IMX_POWER_BASE; - - if (!(readl(&power_regs->hw_power_dcdc4p2) & - POWER_DCDC4P2_ENABLE_DCDC)) { - hang(); - } - - mxs_enable_4p2_dcdc_input(1); - - if (readl(&power_regs->hw_power_ctrl) & POWER_CTRL_VBUS_VALID_IRQ) { - clrbits_le32(&power_regs->hw_power_dcdc4p2, - POWER_DCDC4P2_ENABLE_DCDC); - writel(POWER_5VCTRL_ENABLE_DCDC, - &power_regs->hw_power_5vctrl_clr); - charger_4p2_disable(); - } -} - -/** - * mxs_power_enable_4p2() - Power up the 4P2 regulator - * - * This function drives the process of powering up the 4P2 linear regulator - * and switching the DC-DC converter input over to the 4P2 linear regulator. - */ -static void mxs_power_enable_4p2(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)IMX_POWER_BASE; - uint32_t vdddctrl, vddactrl, vddioctrl; - uint32_t tmp; - - vdddctrl = readl(&power_regs->hw_power_vdddctrl); - vddactrl = readl(&power_regs->hw_power_vddactrl); - vddioctrl = readl(&power_regs->hw_power_vddioctrl); - - setbits_le32(&power_regs->hw_power_vdddctrl, - POWER_VDDDCTRL_DISABLE_FET | POWER_VDDDCTRL_ENABLE_LINREG | - POWER_VDDDCTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddactrl, - POWER_VDDACTRL_DISABLE_FET | POWER_VDDACTRL_ENABLE_LINREG | - POWER_VDDACTRL_PWDN_BRNOUT); - - setbits_le32(&power_regs->hw_power_vddioctrl, - POWER_VDDIOCTRL_DISABLE_FET | POWER_VDDIOCTRL_PWDN_BRNOUT); - - mxs_power_init_4p2_params(); - mxs_power_init_4p2_regulator(); /* Shutdown battery (none present) */ if (!mxs_is_batt_ready()) { -- cgit v1.2.3 From 2a0f2d46fd4b4e6d0da83dee944916a7ce7013b1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:11:59 +0100 Subject: ARM: MXS: Do not register devices with device tree support When a device tree is present the SoC internal devices come from it, so do not register them as platform devices. Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/soc-imx23.c | 3 +++ arch/arm/mach-mxs/soc-imx28.c | 3 +++ 2 files changed, 6 insertions(+) diff --git a/arch/arm/mach-mxs/soc-imx23.c b/arch/arm/mach-mxs/soc-imx23.c index b21986536f..ece91e55e6 100644 --- a/arch/arm/mach-mxs/soc-imx23.c +++ b/arch/arm/mach-mxs/soc-imx23.c @@ -38,6 +38,9 @@ EXPORT_SYMBOL(reset_cpu); static int imx23_devices_init(void) { + if (of_get_root_node()) + return 0; + add_generic_device("imx23-dma-apbh", 0, NULL, MXS_APBH_BASE, 0x2000, IORESOURCE_MEM, NULL); add_generic_device("imx23-clkctrl", 0, NULL, IMX_CCM_BASE, 0x100, IORESOURCE_MEM, NULL); diff --git a/arch/arm/mach-mxs/soc-imx28.c b/arch/arm/mach-mxs/soc-imx28.c index c7252f537e..001c969f3c 100644 --- a/arch/arm/mach-mxs/soc-imx28.c +++ b/arch/arm/mach-mxs/soc-imx28.c @@ -56,6 +56,9 @@ postcore_initcall(imx28_init); static int imx28_devices_init(void) { + if (of_get_root_node()) + return 0; + add_generic_device("imx28-dma-apbh", 0, NULL, MXS_APBH_BASE, 0x2000, IORESOURCE_MEM, NULL); add_generic_device("imx28-clkctrl", 0, NULL, IMX_CCM_BASE, 0x100, IORESOURCE_MEM, NULL); -- cgit v1.2.3 From 478ea1c0b1e4db8275786ff7fb285d61d7697656 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 21:29:41 +0100 Subject: ARM: MXS: Make gpio a driver This turns the MXS gpio support into a driver. Signed-off-by: Sascha Hauer --- arch/arm/Kconfig | 1 + arch/arm/mach-mxs/iomux-imx.c | 60 -------------- arch/arm/mach-mxs/soc-imx23.c | 3 + arch/arm/mach-mxs/soc-imx28.c | 5 ++ drivers/gpio/Kconfig | 3 + drivers/gpio/Makefile | 1 + drivers/gpio/gpio-mxs.c | 186 ++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 199 insertions(+), 60 deletions(-) create mode 100644 drivers/gpio/gpio-mxs.c diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 09bbe05bad..f682803bf1 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -120,6 +120,7 @@ config ARCH_MVEBU config ARCH_MXS bool "Freescale i.MX23/28 (mxs) based" + select GPIOLIB select GENERIC_GPIO select COMMON_CLK select CLKDEV_LOOKUP diff --git a/arch/arm/mach-mxs/iomux-imx.c b/arch/arm/mach-mxs/iomux-imx.c index 84c6ca4ca7..68a4e3cbd6 100644 --- a/arch/arm/mach-mxs/iomux-imx.c +++ b/arch/arm/mach-mxs/iomux-imx.c @@ -75,12 +75,6 @@ static unsigned calc_output_reg(unsigned no) return ((no >> 5) << 4) + HW_PINCTRL_DOUT0; } -static unsigned calc_input_reg(unsigned no) -{ - /* each register controls 32 pads */ - return ((no >> 5) << 4) + HW_PINCTRL_DIN0; -} - /** * @param[in] m One pin define per call from iomux-mx23.h/iomux-mx28.h */ @@ -168,57 +162,3 @@ void imx_gpio_mode(uint32_t m) } } } - -int gpio_direction_input(unsigned gpio) -{ - unsigned reg_offset; - - if (gpio > MAX_GPIO_NO) - return -EINVAL; - - reg_offset = calc_output_enable_reg(gpio); - writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + reg_offset + STMP_OFFSET_REG_CLR); - - return 0; -} - -int gpio_direction_output(unsigned gpio, int val) -{ - unsigned reg_offset; - - if (gpio > MAX_GPIO_NO) - return -EINVAL; - - /* first set the output value... */ - reg_offset = calc_output_reg(gpio); - writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + - reg_offset + (val != 0 ? STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR)); - /* ...then the direction */ - reg_offset = calc_output_enable_reg(gpio); - writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + reg_offset + STMP_OFFSET_REG_SET); - - return 0; -} - -void gpio_set_value(unsigned gpio, int val) -{ - unsigned reg_offset; - - reg_offset = calc_output_reg(gpio); - writel(0x1 << (gpio % 32), IMX_IOMUXC_BASE + - reg_offset + (val != 0 ? - STMP_OFFSET_REG_SET : STMP_OFFSET_REG_CLR)); -} - -int gpio_get_value(unsigned gpio) -{ - uint32_t reg; - unsigned reg_offset; - - reg_offset = calc_input_reg(gpio); - reg = readl(IMX_IOMUXC_BASE + reg_offset); - if (reg & (0x1 << (gpio % 32))) - return 1; - - return 0; -} diff --git a/arch/arm/mach-mxs/soc-imx23.c b/arch/arm/mach-mxs/soc-imx23.c index ece91e55e6..339c57748f 100644 --- a/arch/arm/mach-mxs/soc-imx23.c +++ b/arch/arm/mach-mxs/soc-imx23.c @@ -43,6 +43,9 @@ static int imx23_devices_init(void) add_generic_device("imx23-dma-apbh", 0, NULL, MXS_APBH_BASE, 0x2000, IORESOURCE_MEM, NULL); add_generic_device("imx23-clkctrl", 0, NULL, IMX_CCM_BASE, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx23-gpio", 0, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); + add_generic_device("imx23-gpio", 1, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); + add_generic_device("imx23-gpio", 2, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); return 0; } diff --git a/arch/arm/mach-mxs/soc-imx28.c b/arch/arm/mach-mxs/soc-imx28.c index 001c969f3c..4f0d89508c 100644 --- a/arch/arm/mach-mxs/soc-imx28.c +++ b/arch/arm/mach-mxs/soc-imx28.c @@ -61,6 +61,11 @@ static int imx28_devices_init(void) add_generic_device("imx28-dma-apbh", 0, NULL, MXS_APBH_BASE, 0x2000, IORESOURCE_MEM, NULL); add_generic_device("imx28-clkctrl", 0, NULL, IMX_CCM_BASE, 0x100, IORESOURCE_MEM, NULL); + add_generic_device("imx28-gpio", 0, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); + add_generic_device("imx28-gpio", 1, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); + add_generic_device("imx28-gpio", 2, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); + add_generic_device("imx28-gpio", 3, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); + add_generic_device("imx28-gpio", 4, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); return 0; } diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 0ca7df450a..c8b1efb1f2 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -41,6 +41,9 @@ config GPIO_GENERIC_PLATFORM config GPIO_IMX def_bool ARCH_IMX +config GPIO_MXS + def_bool ARCH_MXS + config GPIO_JZ4740 bool "GPIO support for Ingenic SoCs" depends on MACH_MIPS_XBURST diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile index 510d146ff5..508e228bac 100644 --- a/drivers/gpio/Makefile +++ b/drivers/gpio/Makefile @@ -6,6 +6,7 @@ obj-$(CONFIG_GPIO_CLPS711X) += gpio-clps711x.o obj-$(CONFIG_GPIO_DIGIC) += gpio-digic.o obj-$(CONFIG_GPIO_GENERIC) += gpio-generic.o obj-$(CONFIG_GPIO_IMX) += gpio-imx.o +obj-$(CONFIG_GPIO_MXS) += gpio-mxs.o obj-$(CONFIG_GPIO_JZ4740) += gpio-jz4740.o obj-$(CONFIG_GPIO_MALTA_FPGA_I2C) += gpio-malta-fpga-i2c.o obj-$(CONFIG_GPIO_ORION) += gpio-orion.o diff --git a/drivers/gpio/gpio-mxs.c b/drivers/gpio/gpio-mxs.c new file mode 100644 index 0000000000..30f9589831 --- /dev/null +++ b/drivers/gpio/gpio-mxs.c @@ -0,0 +1,186 @@ +/* + * Freescale MXS gpio support + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include +#include + +struct mxs_gpio_chip { + void __iomem *base; + void __iomem *din; + void __iomem *doe; + void __iomem *dout; + struct gpio_chip chip; + struct mxs_gpio_regs *regs; +}; + +struct mxs_gpio_regs { + unsigned int din; + unsigned int doe; + unsigned int dout; +}; + +static struct mxs_gpio_regs regs_mxs23 = { + .din = 0x0600, + .dout = 0x0500, + .doe = 0x0700, +}; + +static struct mxs_gpio_regs regs_mxs28 = { + .din = 0x0900, + .dout = 0x0700, + .doe = 0x0b00, +}; + +static void mxs_gpio_set_value(struct gpio_chip *chip, unsigned gpio, int value) +{ + struct mxs_gpio_chip *mxsgpio = container_of(chip, struct mxs_gpio_chip, chip); + + if (value) + writel(0x1 << gpio, mxsgpio->dout + STMP_OFFSET_REG_SET); + else + writel(0x1 << gpio, mxsgpio->dout + STMP_OFFSET_REG_CLR); +} + +static int mxs_gpio_direction_input(struct gpio_chip *chip, unsigned gpio) +{ + struct mxs_gpio_chip *mxsgpio = container_of(chip, struct mxs_gpio_chip, chip); + + writel(0x1 << gpio, mxsgpio->doe + STMP_OFFSET_REG_CLR); + + return 0; +} + + +static int mxs_gpio_direction_output(struct gpio_chip *chip, unsigned gpio, int value) +{ + struct mxs_gpio_chip *mxsgpio = container_of(chip, struct mxs_gpio_chip, chip); + + mxs_gpio_set_value(chip, gpio, value); + writel(0x1 << gpio, mxsgpio->doe + STMP_OFFSET_REG_SET); + + return 0; +} + +static int mxs_gpio_get_value(struct gpio_chip *chip, unsigned gpio) +{ + struct mxs_gpio_chip *mxsgpio = container_of(chip, struct mxs_gpio_chip, chip); + + if (readl(mxsgpio->din) & (1 << gpio)) + return 1; + else + return 0; +} + +static int mxs_get_direction(struct gpio_chip *chip, unsigned gpio) +{ + struct mxs_gpio_chip *mxsgpio = container_of(chip, struct mxs_gpio_chip, chip); + + if (readl(mxsgpio->doe) & (1 << gpio)) + return GPIOF_DIR_OUT; + else + return GPIOF_DIR_IN; +} + +static struct gpio_ops mxs_gpio_ops = { + .direction_input = mxs_gpio_direction_input, + .direction_output = mxs_gpio_direction_output, + .get = mxs_gpio_get_value, + .set = mxs_gpio_set_value, + .get_direction = mxs_get_direction, +}; + +static int mxs_gpio_probe(struct device_d *dev) +{ + struct mxs_gpio_chip *mxsgpio; + struct mxs_gpio_regs *regs; + int ret, id; + + ret = dev_get_drvdata(dev, (unsigned long *)®s); + if (ret) + return ret; + + mxsgpio = xzalloc(sizeof(*mxsgpio)); + mxsgpio->chip.ops = &mxs_gpio_ops; + if (dev->id < 0) { + id = of_alias_get_id(dev->device_node, "gpio"); + if (id < 0) + return id; + mxsgpio->base = dev_get_mem_region(dev->parent, 0); + mxsgpio->chip.base = id * 32; + } else { + id = dev->id; + mxsgpio->base = dev_get_mem_region(dev, 0); + mxsgpio->chip.base = dev->id * 32; + } + + if (IS_ERR(mxsgpio->base)) + return PTR_ERR(mxsgpio->base); + + mxsgpio->doe = mxsgpio->base + regs->doe + id * 0x10; + mxsgpio->dout = mxsgpio->base + regs->dout + id * 0x10; + mxsgpio->din = mxsgpio->base + regs->din + id * 0x10; + + mxsgpio->chip.ngpio = 32; + mxsgpio->chip.dev = dev; + mxsgpio->regs = regs; + gpiochip_add(&mxsgpio->chip); + + dev_dbg(dev, "probed gpiochip%d with base %d\n", dev->id, mxsgpio->chip.base); + + return 0; +} + +static __maybe_unused struct of_device_id mxs_gpio_dt_ids[] = { + { + .compatible = "fsl,imx23-gpio", + .data = (unsigned long)®s_mxs23, + }, { + .compatible = "fsl,imx28-gpio", + .data = (unsigned long)®s_mxs28, + }, { + /* sentinel */ + } +}; + +static struct platform_device_id mxs_gpio_ids[] = { + { + .name = "imx23-gpio", + .driver_data = (unsigned long)®s_mxs23, + }, { + .name = "imx28-gpio", + .driver_data = (unsigned long)®s_mxs28, + }, { + /* sentinel */ + }, +}; + +static struct driver_d mxs_gpio_driver = { + .name = "gpio-mxs", + .probe = mxs_gpio_probe, + .of_compatible = DRV_OF_COMPAT(mxs_gpio_dt_ids), + .id_table = mxs_gpio_ids, +}; + +static int mxs_gpio_add(void) +{ + platform_driver_register(&mxs_gpio_driver); + return 0; +} +core_initcall(mxs_gpio_add); -- cgit v1.2.3 From 846f27cf928ff24b54cfe8512945ae4fcb2bd52a Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 22:44:53 +0100 Subject: mci: mxs: Add devicetree support Add device tree compatibles and allow retrieving data from device tree instead of platform_data only. Signed-off-by: Sascha Hauer --- drivers/mci/mxs.c | 50 +++++++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 23 deletions(-) diff --git a/drivers/mci/mxs.c b/drivers/mci/mxs.c index 367964c1d0..b36fb13254 100644 --- a/drivers/mci/mxs.c +++ b/drivers/mci/mxs.c @@ -549,11 +549,6 @@ static int mxs_mci_probe(struct device_d *hw_dev) struct mci_host *host; unsigned long rate; - if (hw_dev->platform_data == NULL) { - dev_err(hw_dev, "Missing platform data\n"); - return -EINVAL; - } - mxs_mci = xzalloc(sizeof(*mxs_mci)); host = &mxs_mci->host; @@ -567,9 +562,16 @@ static int mxs_mci_probe(struct device_d *hw_dev) return PTR_ERR(mxs_mci->regs); /* feed forward the platform specific values */ - host->voltages = pd->voltages; - host->host_caps = pd->caps; - host->devname = pd->devname; + if (pd) { + host->voltages = pd->voltages; + host->host_caps = pd->caps; + host->devname = pd->devname; + host->f_min = pd->f_min; + host->f_max = pd->f_max; + } else { + host->voltages = MMC_VDD_32_33 | MMC_VDD_33_34, /* fixed to 3.3 V */ + mci_of_parse(host); + } mxs_mci->clk = clk_get(hw_dev, NULL); if (IS_ERR(mxs_mci->clk)) @@ -579,22 +581,13 @@ static int mxs_mci_probe(struct device_d *hw_dev) rate = clk_get_rate(mxs_mci->clk); - if (pd->f_min == 0) { - host->f_min = rate / 254 / 256; - dev_dbg(hw_dev, "Min. frequency is %u Hz\n", host->f_min); - } else { - host->f_min = pd->f_min; - dev_dbg(hw_dev, "Min. frequency is %u Hz, could be %lu Hz\n", - host->f_min, rate / 254 / 256); - } - if (pd->f_max == 0) { + if (host->f_min < 400000) + host->f_min = 400000; + if (host->f_max == 0) host->f_max = rate / 2 / 1; - dev_dbg(hw_dev, "Max. frequency is %u Hz\n", host->f_max); - } else { - host->f_max = pd->f_max; - dev_dbg(hw_dev, "Max. frequency is %u Hz, could be %lu Hz\n", - host->f_max, rate / 2 / 1); - } + + dev_dbg(hw_dev, "Max. frequency is %u Hz\n", host->f_max); + dev_dbg(hw_dev, "Min. frequency is %u Hz\n", host->f_min); if (IS_ENABLED(CONFIG_MCI_INFO)) { mxs_mci->f_min = host->f_min; @@ -605,8 +598,19 @@ static int mxs_mci_probe(struct device_d *hw_dev) return mci_register(host); } +static __maybe_unused struct of_device_id mxs_mmc_compatible[] = { + { + .compatible = "fsl,imx23-mmc", + }, { + .compatible = "fsl,imx28-mmc", + }, { + /* sentinel */ + } +}; + static struct driver_d mxs_mci_driver = { .name = "mxs_mci", .probe = mxs_mci_probe, + .of_compatible = DRV_OF_COMPAT(mxs_mmc_compatible), }; device_platform_driver(mxs_mci_driver); -- cgit v1.2.3 From f0535fe5eee24fd78643dcd2e448c2f7d0c386ee Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 22:45:16 +0100 Subject: serial: stm_serial: Add devicetree support This adds device tree support for the stm serial driver. This driver really is a AMBA primecell, so the amba-pl011 could be used. However, the current code tries to get the apb_pclk before the clocks are registered, so this does not work. Use the stm driver instead until a solution is found. Signed-off-by: Sascha Hauer --- drivers/serial/stm-serial.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/drivers/serial/stm-serial.c b/drivers/serial/stm-serial.c index e5f57dc6e7..8bb242b14d 100644 --- a/drivers/serial/stm-serial.c +++ b/drivers/serial/stm-serial.c @@ -189,9 +189,18 @@ static void stm_serial_remove(struct device_d *dev) free(priv); } +static __maybe_unused struct of_device_id stm_serial_dt_ids[] = { + { + .compatible = "arm,pl011", + }, { + /* sentinel */ + } +}; + static struct driver_d stm_serial_driver = { .name = "stm_serial", .probe = stm_serial_probe, .remove = stm_serial_remove, + .of_compatible = DRV_OF_COMPAT(stm_serial_dt_ids), }; console_platform_driver(stm_serial_driver); -- cgit v1.2.3 From f3ff746d20931b681f5f1fcac44aea317b06dac0 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 22:47:13 +0100 Subject: ARM: MXS: Create ocotp device in SoC code The ocotp device is completely SoC internal, no need to register it from boards. Register it from SoC code instead. Signed-off-by: Sascha Hauer --- arch/arm/boards/crystalfontz-cfa10036/cfa10036.c | 3 --- arch/arm/boards/freescale-mx28-evk/mx28-evk.c | 2 -- arch/arm/boards/karo-tx28/tx28-stk5.c | 3 --- arch/arm/mach-mxs/soc-imx28.c | 1 + 4 files changed, 1 insertion(+), 8 deletions(-) diff --git a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c index 1412eff4a7..6e83570c55 100644 --- a/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c +++ b/arch/arm/boards/crystalfontz-cfa10036/cfa10036.c @@ -127,9 +127,6 @@ static int cfa10036_devices_init(void) add_generic_device("mxs_mci", 0, NULL, IMX_SSP0_BASE, SZ_8K, IORESOURCE_MEM, &mci_pdata); - add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, SZ_8K, - IORESOURCE_MEM, NULL); - i2c_register_board_info(0, cfa10036_i2c_devices, ARRAY_SIZE(cfa10036_i2c_devices)); add_generic_device_res("i2c-gpio", 0, NULL, 0, &i2c_gpio_pdata); diff --git a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c index dce6d31030..d77a6c7156 100644 --- a/arch/arm/boards/freescale-mx28-evk/mx28-evk.c +++ b/arch/arm/boards/freescale-mx28-evk/mx28-evk.c @@ -275,8 +275,6 @@ static int mx28_evk_devices_init(void) add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 0x2000, IORESOURCE_MEM, &mx28_evk_fb_pdata); - add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0x2000, - IORESOURCE_MEM, NULL); mx28_evk_get_ethaddr(); /* must be after registering ocotp */ mx28_evk_fec_reset(); diff --git a/arch/arm/boards/karo-tx28/tx28-stk5.c b/arch/arm/boards/karo-tx28/tx28-stk5.c index c4c51099b4..9b86d1c883 100644 --- a/arch/arm/boards/karo-tx28/tx28-stk5.c +++ b/arch/arm/boards/karo-tx28/tx28-stk5.c @@ -382,9 +382,6 @@ void base_board_init(void) add_generic_device("stmfb", 0, NULL, IMX_FB_BASE, 0x2000, IORESOURCE_MEM, &tx28_fb_pdata); - add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0x2000, - IORESOURCE_MEM, NULL); - tx28_get_ethaddr(); add_generic_device("imx28-fec", 0, NULL, IMX_FEC0_BASE, 0x4000, diff --git a/arch/arm/mach-mxs/soc-imx28.c b/arch/arm/mach-mxs/soc-imx28.c index 4f0d89508c..b4ec38d912 100644 --- a/arch/arm/mach-mxs/soc-imx28.c +++ b/arch/arm/mach-mxs/soc-imx28.c @@ -66,6 +66,7 @@ static int imx28_devices_init(void) add_generic_device("imx28-gpio", 2, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); add_generic_device("imx28-gpio", 3, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); add_generic_device("imx28-gpio", 4, NULL, IMX_IOMUXC_BASE, 0x2000, IORESOURCE_MEM, NULL); + add_generic_device("ocotp", 0, NULL, IMX_OCOTP_BASE, 0x2000, IORESOURCE_MEM, NULL); return 0; } -- cgit v1.2.3 From f765925bb9fc5b0989bb9abf95d39aa03a847b37 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 22:47:59 +0100 Subject: ARM: MXS: ocotp: Add devicetree support Add the device tree compatible strings. Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/ocotp.c | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/arch/arm/mach-mxs/ocotp.c b/arch/arm/mach-mxs/ocotp.c index abdd445b5d..2029b90acb 100644 --- a/arch/arm/mach-mxs/ocotp.c +++ b/arch/arm/mach-mxs/ocotp.c @@ -207,9 +207,18 @@ static int mxs_ocotp_probe(struct device_d *dev) return 0; } +static __maybe_unused struct of_device_id mxs_ocotp_compatible[] = { + { + .compatible = "fsl,ocotp", + }, { + /* sentinel */ + } +}; + static struct driver_d mxs_ocotp_driver = { .name = DRIVERNAME, .probe = mxs_ocotp_probe, + .of_compatible = DRV_OF_COMPAT(mxs_ocotp_compatible), }; static int mxs_ocotp_init(void) -- cgit v1.2.3 From c42178d9fcbd54ea1696929b5cd351b5683f6d9d Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 22:48:48 +0100 Subject: of: Create platform_device when creating AMBA device failed If creating an AMBA device failed, maybe because AMBA support is not compiled in, register the device as regular platform device. Signed-off-by: Sascha Hauer --- drivers/of/platform.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 92ef53443f..ab3ccab3b6 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c @@ -312,8 +312,8 @@ static int of_platform_bus_create(struct device_node *bus, } if (of_device_is_compatible(bus, "arm,primecell")) { - of_amba_device_create(bus); - return 0; + if (of_amba_device_create(bus)) + return 0; } dev = of_platform_device_create(bus, parent); -- cgit v1.2.3 From 7e22de9c3c786f23493bed6847887fe5f6787078 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:02:50 +0100 Subject: pbl: Add support for memory_display The PBL has console support now, so add memory_display support aswell which can be a good debugging aid. Signed-off-by: Sascha Hauer --- common/Makefile | 1 + pbl/console.c | 10 ++++++++++ 2 files changed, 11 insertions(+) diff --git a/common/Makefile b/common/Makefile index 282ddbca25..ee5dca7023 100644 --- a/common/Makefile +++ b/common/Makefile @@ -1,5 +1,6 @@ obj-y += memory.o obj-y += memory_display.o +pbl-$(CONFIG_PBL_CONSOLE) += memory_display.o obj-y += clock.o obj-y += console_common.o obj-y += startup.o diff --git a/pbl/console.c b/pbl/console.c index 3875e2aafd..a9859ad162 100644 --- a/pbl/console.c +++ b/pbl/console.c @@ -30,3 +30,13 @@ int pr_print(int level, const char *fmt, ...) return i; } + +int ctrlc(void) +{ + return 0; +} + +void console_putc(unsigned int ch, char c) +{ + putc_ll(c); +} -- cgit v1.2.3 From 3a0122c712187b8a9312a8b58e479e67b14d843b Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:05:39 +0100 Subject: pinctrl: Add MXS pinctrl driver This adds a device tree pinctrl driver for MXS. Signed-off-by: Sascha Hauer --- drivers/pinctrl/Kconfig | 7 ++ drivers/pinctrl/Makefile | 1 + drivers/pinctrl/pinctrl-mxs.c | 171 ++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 179 insertions(+) create mode 100644 drivers/pinctrl/pinctrl-mxs.c diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index 4cbc167cd0..5c69928e75 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -37,6 +37,13 @@ comment "OFDEVICE is not enabled." comment "Without device tree support PINCTRL won't do anything" endif +config PINCTRL_MXS + bool "MXS pinctrl" + depends on ARCH_MXS + default ARCH_MXS + help + This pinmux controller is found on i.MX23,28 + config PINCTRL_ROCKCHIP select GPIO_GENERIC select MFD_SYSCON diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index 724e6d7d06..af9b30df0f 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -3,6 +3,7 @@ obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V3) += imx-iomux-v3.o +obj-$(CONFIG_PINCTRL_MXS) += pinctrl-mxs.o obj-$(CONFIG_PINCTRL_ROCKCHIP) += pinctrl-rockchip.o obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o obj-$(CONFIG_PINCTRL_TEGRA20) += pinctrl-tegra20.o diff --git a/drivers/pinctrl/pinctrl-mxs.c b/drivers/pinctrl/pinctrl-mxs.c new file mode 100644 index 0000000000..ec0aaec67f --- /dev/null +++ b/drivers/pinctrl/pinctrl-mxs.c @@ -0,0 +1,171 @@ +/* + * pinctrl-mxs.c - MXS pinctrl support + * + * Copyright (c) 2015 Sascha Hauer + * + * See file CREDITS for list of people who contributed to this + * project. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + */ + +#include +#include +#include +#include +#include +#include +#include + +struct mxs_pinctrl { + void __iomem *base; + struct pinctrl_device pinctrl; +}; + +#define PINID(bank, pin) ((bank) * 32 + (pin)) +#define MUXID_TO_PINID(m) PINID((m) >> 12 & 0xf, (m) >> 4 & 0xff) +#define MUXID_TO_MUXSEL(m) ((m) & 0xf) +#define PINID_TO_BANK(p) ((p) >> 5) +#define PINID_TO_PIN(p) ((p) % 32) + +static int mxs_pinctrl_set_state(struct pinctrl_device *pdev, struct device_node *np) +{ + struct mxs_pinctrl *iomux = container_of(pdev, struct mxs_pinctrl, pinctrl); + const __be32 *list; + int npins, size, i; + u32 val, ma, vol, pull; + int ret; + int ma_present = 0, vol_present = 0, pull_present = 0; + + dev_dbg(iomux->pinctrl.dev, "set state: %s\n", np->full_name); + + list = of_get_property(np, "fsl,pinmux-ids", &size); + if (!list) + return -EINVAL; + + if (!size || size % 4) { + dev_err(iomux->pinctrl.dev, "Invalid fsl,pins property in %s\n", + np->full_name); + return -EINVAL; + } + + npins = size / 4; + + ret = of_property_read_u32(np, "fsl,drive-strength", &ma); + if (!ret) + ma_present = 1; + + ret = of_property_read_u32(np, "fsl,voltage", &vol); + if (!ret) + vol_present = 1; + + ret = of_property_read_u32(np, "fsl,pull-up", &pull); + if (!ret) + pull_present = 1; + + for (i = 0; i < npins; i++) { + int muxsel, pinid, bank, pin, shift; + void __iomem *reg; + + val = be32_to_cpu(*list++); + + muxsel = MUXID_TO_MUXSEL(val); + pinid = MUXID_TO_PINID(val); + + bank = PINID_TO_BANK(pinid); + pin = PINID_TO_PIN(pinid); + reg = iomux->base + 0x100; + reg += bank * 0x20 + pin / 16 * 0x10; + shift = pin % 16 * 2; + + writel(0x3 << shift, reg + STMP_OFFSET_REG_CLR); + writel(muxsel << shift, reg + STMP_OFFSET_REG_SET); + + dev_dbg(iomux->pinctrl.dev, "pin %d, mux %d, ma: %d, vol: %d, pull: %d\n", + pinid, muxsel, ma, vol, pull); + + /* drive */ + reg = iomux->base + 0x300; + reg += bank * 0x40 + pin / 8 * 0x10; + + /* mA */ + if (ma_present) { + shift = pin % 8 * 4; + writel(0x3 << shift, reg + STMP_OFFSET_REG_CLR); + writel(ma << shift, reg + STMP_OFFSET_REG_SET); + } + + /* vol */ + if (vol_present) { + shift = pin % 8 * 4 + 2; + if (vol) + writel(1 << shift, reg + STMP_OFFSET_REG_SET); + else + writel(1 << shift, reg + STMP_OFFSET_REG_CLR); + } + + /* pull */ + if (pull_present) { + reg = iomux->base + 0x600; + reg += bank * 0x10; + shift = pin; + if (pull) + writel(1 << shift, reg + STMP_OFFSET_REG_SET); + else + writel(1 << shift, reg + STMP_OFFSET_REG_CLR); + } + } + + return 0; +} + +static struct pinctrl_ops mxs_pinctrl_ops = { + .set_state = mxs_pinctrl_set_state, +}; + +static int mxs_pinctrl_probe(struct device_d *dev) +{ + struct mxs_pinctrl *iomux; + int ret = 0; + + iomux = xzalloc(sizeof(*iomux)); + + iomux->base = dev_get_mem_region(dev, 0); + + iomux->pinctrl.dev = dev; + iomux->pinctrl.ops = &mxs_pinctrl_ops; + + ret = pinctrl_register(&iomux->pinctrl); + if (ret) + free(iomux); + + return ret; +} + +static __maybe_unused struct of_device_id mxs_pinctrl_dt_ids[] = { + { + .compatible = "fsl,imx28-pinctrl", + }, { + /* sentinel */ + } +}; + +static struct driver_d mxs_pinctrl_driver = { + .name = "mxs-pinctrl", + .probe = mxs_pinctrl_probe, + .of_compatible = DRV_OF_COMPAT(mxs_pinctrl_dt_ids), +}; + +static int mxs_pinctrl_init(void) +{ + return platform_driver_register(&mxs_pinctrl_driver); +} +postcore_initcall(mxs_pinctrl_init); -- cgit v1.2.3 From e0c61f3be3d72acfdcc3a43701016b548c446645 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:09:35 +0100 Subject: ARM: MXS: Setup vdda in power prep Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/mem-init.c | 15 --------------- arch/arm/mach-mxs/power-init.c | 15 +++++++++++++++ 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/arch/arm/mach-mxs/mem-init.c b/arch/arm/mach-mxs/mem-init.c index 9773f94903..43165ac100 100644 --- a/arch/arm/mach-mxs/mem-init.c +++ b/arch/arm/mach-mxs/mem-init.c @@ -255,17 +255,6 @@ void mxs_mem_setup_cpu_and_hbus(void) mxs_early_delay(15000); } -void mxs_mem_setup_vdda(void) -{ - struct mxs_power_regs *power_regs = - (struct mxs_power_regs *)IMX_POWER_BASE; - - writel((0xc << POWER_VDDACTRL_TRG_OFFSET) | - (0x7 << POWER_VDDACTRL_BO_OFFSET_OFFSET) | - POWER_VDDACTRL_LINREG_OFFSET_1STEPS_BELOW, - &power_regs->hw_power_vddactrl); -} - static void mx23_mem_setup_vddmem(void) { struct mxs_power_regs *power_regs = @@ -287,8 +276,6 @@ void mx23_mem_init(void) /* Fractional divider for ref_emi is 33 ; 480 * 18 / 33 = 266MHz */ mxs_mem_init_clock(33); - mxs_mem_setup_vdda(); - /* * Reset/ungate the EMI block. This is essential, otherwise the system * suffers from memory instability. This thing is mx23 specific and is @@ -340,8 +327,6 @@ void mx28_mem_init(void) /* Fractional divider for ref_emi is 21 ; 480 * 18 / 21 = 411MHz */ mxs_mem_init_clock(21); - mxs_mem_setup_vdda(); - /* Set DDR2 mode */ writel(PINCTRL_EMI_DS_CTRL_DDR_MODE_DDR2, IMX_IOMUXC_BASE + 0x1b80); diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 366b3f2f6f..407b776399 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -993,6 +993,19 @@ static const struct mxs_vddx_cfg mxs_vddmem_cfg = { .bo_offset_offset = 0, }; +static const struct mxs_vddx_cfg mxs_vdda_cfg = { + .reg = &(((struct mxs_power_regs *)IMX_POWER_BASE)-> + hw_power_vddactrl), + .step_mV = 25, + .lowest_mV = 1500, + .powered_by_linreg = NULL, + .trg_mask = POWER_VDDACTRL_TRG_MASK, + .bo_irq = POWER_CTRL_VDDA_BO_IRQ, + .bo_enirq = POWER_CTRL_ENIRQ_VDDA_BO, + .bo_offset_mask = POWER_VDDACTRL_BO_OFFSET_MASK, + .bo_offset_offset = POWER_VDDACTRL_BO_OFFSET_OFFSET, +}; + /** * mxs_power_set_vddx() - Configure voltage on DC-DC converter rail * @cfg: Configuration data of the DC-DC converter rail @@ -1151,6 +1164,7 @@ static void __mx23_power_init(int has_battery) mxs_power_set_vddx(&mx23_vddio_cfg, 3300, 3150); mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325); mxs_power_set_vddx(&mxs_vddmem_cfg, 2500, 1700); + mxs_power_set_vddx(&mxs_vdda_cfg, 1800, 1650); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | @@ -1207,6 +1221,7 @@ static void __mx28_power_init(int has_battery) mxs_power_set_vddx(&mx28_vddio_cfg, 3300, 3150); mxs_power_set_vddx(&mxs_vddd_cfg, 1500, 1325); + mxs_power_set_vddx(&mxs_vdda_cfg, 1800, 1650); writel(POWER_CTRL_VDDD_BO_IRQ | POWER_CTRL_VDDA_BO_IRQ | POWER_CTRL_VDDIO_BO_IRQ | POWER_CTRL_VDD5V_DROOP_IRQ | -- cgit v1.2.3 From 1a63678cb2be569865079a5c2663dd4a454857aa Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:10:49 +0100 Subject: ARM: MXS: Add regulator debug print Signed-off-by: Sascha Hauer --- arch/arm/mach-mxs/power-init.c | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 407b776399..5d4d0892d8 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -24,6 +24,40 @@ #include #include +static void mxs_power_status(void) +{ + struct mxs_power_regs *power_regs = + (struct mxs_power_regs *)IMX_POWER_BASE; + static int linregofs[] = { 0, 1, -1, -2 }; + + uint32_t vddio = readl(&power_regs->hw_power_vddioctrl); + uint32_t vdda = readl(&power_regs->hw_power_vddactrl); + uint32_t vddd = readl(&power_regs->hw_power_vdddctrl); + uint32_t vddmem = readl(&power_regs->hw_power_vddmemctrl); + + printf("vddio: %dmV (BO -%dmV), Linreg enabled, Linreg offset: %d, FET %sabled\n", + (vddio & 0x1f) * 50 + 2800, + ((vddio >> 8) & 0x7) * 50, + linregofs[((vdda >> 12) & 0x3)], + (vddio & (1 << 16)) ? "dis" : "en"); + printf("vdda: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n", + (vdda & 0x1f) * 25 + 1500, + ((vdda >> 8) & 0x7) * 25, + (vdda & (1 << 17)) ? "en" : "dis", + linregofs[((vdda >> 12) & 0x3)], + (vdda & (1 << 16)) ? "dis" : "en"); + printf("vddd: %dmV (BO -%dmV), Linreg %sabled, Linreg offset: %d, FET %sabled\n", + (vddd & 0x1f) * 25 + 800, + ((vddd >> 8) & 0x7) * 25, + (vddd & (1 << 21)) ? "en" : "dis", + linregofs[((vdda >> 16) & 0x3)], + (vdda & (1 << 20)) ? "dis" : "en"); + printf("vddmem: %dmV (BO -%dmV), Linreg %sabled\n", + (vddmem & 0x1f) * 25 + 1100, + ((vddmem >> 5) & 0x7) * 25, + (vddmem & (1 << 8)) ? "en" : "dis"); +} + /* * This delay function is intended to be used only in early stage of boot, where * clock are not set up yet. The timer used here is reset on every boot and @@ -1197,6 +1231,7 @@ static void __mx28_power_init(int has_battery) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; + mxs_power_status(); mxs_power_clock2xtal(); mxs_power_set_auto_restart(); mxs_power_set_linreg(); @@ -1231,6 +1266,8 @@ static void __mx28_power_init(int has_battery) writel(POWER_5VCTRL_PWDN_5VBRNOUT, &power_regs->hw_power_5vctrl_set); mxs_early_delay(1000); + + mxs_power_status(); } void mx28_power_init(void) -- cgit v1.2.3 From 4d70da63a4847bebbaa4437ef78d4675ae44d0c1 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:11:23 +0100 Subject: ARM: MXS: power-init: Add parameters to mx28_power_init() Instead of introducing new functions each time a new power supply situation is to be added, this patch adds parameters to mx28_power_init. Right now there are three parameters: - has_battery - true when this board has a battery. - use_battery_input - true when this board is supplied from the battery input, but has a DC source instead of a real battery - use_5v_input - true when this board can use the 5V input The third one is introduced with this patch and allow to boot a board from 5v (USB) source only. The main necessary change this needs is that the DC-DC converter must always be sourced from DCDC_4P2 (DROPOUT_CTRL field of HW_POWER_DCDC4P2) Signed-off-by: Sascha Hauer --- arch/arm/boards/freescale-mx28-evk/lowlevel.c | 2 +- arch/arm/boards/imx233-olinuxino/lowlevel.c | 2 +- arch/arm/boards/karo-tx28/lowlevel.c | 2 +- arch/arm/mach-mxs/include/mach/init.h | 8 ++-- arch/arm/mach-mxs/power-init.c | 67 ++++++++++++++++----------- 5 files changed, 48 insertions(+), 33 deletions(-) diff --git a/arch/arm/boards/freescale-mx28-evk/lowlevel.c b/arch/arm/boards/freescale-mx28-evk/lowlevel.c index a46a080518..1f567568da 100644 --- a/arch/arm/boards/freescale-mx28-evk/lowlevel.c +++ b/arch/arm/boards/freescale-mx28-evk/lowlevel.c @@ -43,7 +43,7 @@ static noinline void freescale_mx28evk_init(void) pr_debug("initializing power...\n"); - mx28_power_init_battery_input(); + mx28_power_init(0, 1, 0); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/imx233-olinuxino/lowlevel.c b/arch/arm/boards/imx233-olinuxino/lowlevel.c index 6e4b830485..ce46f7e143 100644 --- a/arch/arm/boards/imx233-olinuxino/lowlevel.c +++ b/arch/arm/boards/imx233-olinuxino/lowlevel.c @@ -154,7 +154,7 @@ static noinline void imx23_olinuxino_init(void) pr_debug("initializing power...\n"); - mx23_power_init(); + mx23_power_init(0, 1, 0); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/boards/karo-tx28/lowlevel.c b/arch/arm/boards/karo-tx28/lowlevel.c index c5fdda1902..96a8b9bfc6 100644 --- a/arch/arm/boards/karo-tx28/lowlevel.c +++ b/arch/arm/boards/karo-tx28/lowlevel.c @@ -43,7 +43,7 @@ static noinline void karo_tx28_init(void) pr_debug("initializing power...\n"); - mx28_power_init_battery_input(); + mx28_power_init(0, 1, 0); pr_debug("initializing SDRAM...\n"); diff --git a/arch/arm/mach-mxs/include/mach/init.h b/arch/arm/mach-mxs/include/mach/init.h index 1f9d8d48c0..90b413e47e 100644 --- a/arch/arm/mach-mxs/include/mach/init.h +++ b/arch/arm/mach-mxs/include/mach/init.h @@ -12,10 +12,10 @@ void mxs_early_delay(int delay); -void mx23_power_init(void); -void mx23_power_init_battery_input(void); -void mx28_power_init(void); -void mx28_power_init_battery_input(void); +void mx23_power_init(int __has_battery, int __use_battery_input, + int __use_5v_input); +void mx28_power_init(int __has_battery, int __use_battery_input, + int __use_5v_input); void mxs_power_wait_pswitch(void); extern uint32_t mx28_dram_vals[]; diff --git a/arch/arm/mach-mxs/power-init.c b/arch/arm/mach-mxs/power-init.c index 5d4d0892d8..595b51c5ba 100644 --- a/arch/arm/mach-mxs/power-init.c +++ b/arch/arm/mach-mxs/power-init.c @@ -24,6 +24,22 @@ #include #include +/* + * has_battery - true when this board has a battery. + */ +static int has_battery; + +/* + * use_battery_input - true when this board is supplied from the + * battery input, but has a DC source instead of a real battery + */ +static int use_battery_input; + +/* + * use_5v_input - true when this board can use the 5V input + */ +static int use_5v_input; + static void mxs_power_status(void) { struct mxs_power_regs *power_regs = @@ -472,7 +488,7 @@ static void mxs_power_enable_4p2(void) struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; uint32_t vdddctrl, vddactrl, vddioctrl; - uint32_t tmp, tmp2; + uint32_t tmp, tmp2, dropout_ctrl; vdddctrl = readl(&power_regs->hw_power_vdddctrl); vddactrl = readl(&power_regs->hw_power_vddactrl); @@ -498,10 +514,15 @@ static void mxs_power_enable_4p2(void) POWER_5VCTRL_HEADROOM_ADJ_MASK, 0x4 << POWER_5VCTRL_HEADROOM_ADJ_OFFSET); + if (has_battery || use_battery_input) + dropout_ctrl = POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL; + else + dropout_ctrl = POWER_DCDC4P2_DROPOUT_CTRL_SRC_4P2; + clrsetbits_le32(&power_regs->hw_power_dcdc4p2, POWER_DCDC4P2_DROPOUT_CTRL_MASK, POWER_DCDC4P2_DROPOUT_CTRL_100MV | - POWER_DCDC4P2_DROPOUT_CTRL_SRC_SEL); + dropout_ctrl); clrsetbits_le32(&power_regs->hw_power_5vctrl, POWER_5VCTRL_CHARGE_4P2_ILIMIT_MASK, @@ -1162,11 +1183,16 @@ static void mx23_ungate_power(void) * This function calls all the power block initialization functions in * proper sequence to start the power block. */ -static void __mx23_power_init(int has_battery) +void mx23_power_init(int __has_battery, int __use_battery_input, + int __use_5v_input) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; + has_battery = __has_battery; + use_battery_input = __use_battery_input; + use_5v_input = __use_5v_input; + mx23_ungate_power(); mxs_power_clock2xtal(); @@ -1180,8 +1206,10 @@ static void __mx23_power_init(int has_battery) if (has_battery) mxs_power_configure_power_source(); - else + else if (use_battery_input) mxs_enable_battery_input(); + else if (use_5v_input) + mxs_boot_valid_5v(); mxs_power_clock2pll(); @@ -1210,27 +1238,22 @@ static void __mx23_power_init(int has_battery) mxs_early_delay(1000); } -void mx23_power_init(void) -{ - __mx23_power_init(1); -} - -void mx23_power_init_battery_input(void) -{ - __mx23_power_init(0); -} - /** * mx28_power_init() - The power block init main function * * This function calls all the power block initialization functions in * proper sequence to start the power block. */ -static void __mx28_power_init(int has_battery) +void mx28_power_init(int __has_battery, int __use_battery_input, + int __use_5v_input) { struct mxs_power_regs *power_regs = (struct mxs_power_regs *)IMX_POWER_BASE; + has_battery = __has_battery; + use_battery_input = __use_battery_input; + use_5v_input = __use_5v_input; + mxs_power_status(); mxs_power_clock2xtal(); mxs_power_set_auto_restart(); @@ -1243,8 +1266,10 @@ static void __mx28_power_init(int has_battery) if (has_battery) mxs_power_configure_power_source(); - else + else if (use_battery_input) mxs_enable_battery_input(); + else if (use_5v_input) + mxs_boot_valid_5v(); mxs_power_clock2pll(); @@ -1270,16 +1295,6 @@ static void __mx28_power_init(int has_battery) mxs_power_status(); } -void mx28_power_init(void) -{ - __mx28_power_init(1); -} - -void mx28_power_init_battery_input(void) -{ - __mx28_power_init(0); -} - /** * mxs_power_wait_pswitch() - Wait for power switch to be pressed * -- cgit v1.2.3 From 99dc5005935070e1680e5f08dd1cd9eee1f2f284 Mon Sep 17 00:00:00 2001 From: Sascha Hauer Date: Tue, 27 Jan 2015 23:04:33 +0100 Subject: ARM: MXS: Add duckbill board support Signed-off-by: Sascha Hauer --- arch/arm/boards/Makefile | 1 + arch/arm/boards/duckbill/Makefile | 2 + arch/arm/boards/duckbill/board.c | 82 +++++++++++++++++++++++++++++ arch/arm/boards/duckbill/lowlevel.c | 73 ++++++++++++++++++++++++++ arch/arm/configs/duckbill_defconfig | 100 ++++++++++++++++++++++++++++++++++++ arch/arm/dts/Makefile | 1 + arch/arm/dts/imx28-duckbill.dts | 15 ++++++ arch/arm/mach-mxs/Kconfig | 8 +++ images/Makefile.mxs | 10 ++++ 9 files changed, 292 insertions(+) create mode 100644 arch/arm/boards/duckbill/Makefile create mode 100644 arch/arm/boards/duckbill/board.c create mode 100644 arch/arm/boards/duckbill/lowlevel.c create mode 100644 arch/arm/configs/duckbill_defconfig create mode 100644 arch/arm/dts/imx28-duckbill.dts diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 9961ca8f11..d81d3601e8 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -20,6 +20,7 @@ obj-$(CONFIG_MACH_CFA10036) += crystalfontz-cfa10036/ obj-$(CONFIG_MACH_CHUMBY) += chumby_falconwing/ obj-$(CONFIG_MACH_CLEP7212) += clep7212/ obj-$(CONFIG_MACH_DFI_FS700_M60) += dfi-fs700-m60/ +obj-$(CONFIG_MACH_DUCKBILL) += duckbill/ obj-$(CONFIG_MACH_DSS11) += dss11/ obj-$(CONFIG_MACH_EDB93012) += edb93xx/ obj-$(CONFIG_MACH_EDB9301) += edb93xx/ diff --git a/arch/arm/boards/duckbill/Makefile b/arch/arm/boards/duckbill/Makefile new file mode 100644 index 0000000000..01c7a259e9 --- /dev/null +++ b/arch/arm/boards/duckbill/Makefile @@ -0,0 +1,2 @@ +obj-y += board.o +lwl-y += lowlevel.o diff --git a/arch/arm/boards/duckbill/board.c b/arch/arm/boards/duckbill/board.c new file mode 100644 index 0000000000..3c6ab8e596 --- /dev/null +++ b/arch/arm/boards/duckbill/board.c @@ -0,0 +1,82 @@ +/* + * Copyright (C) 2010 Juergen Beisert, Pengutronix + * Copyright (C) 2011 Marc Kleine-Budde, Pengutronix + * Copyright (C) 2011 Wolfram Sang, Pengutronix + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of + * the License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +static void duckbill_get_ethaddr(void) +{ + u8 mac_ocotp[3], mac[6]; + int ret; + + ret = mxs_ocotp_read(mac_ocotp, 3, 0); + if (ret != 3) { + pr_err("Reading MAC from OCOTP failed!\n"); + return; + } + + mac[0] = 0x00; + mac[1] = 0x04; + mac[2] = 0x9f; + mac[3] = mac_ocotp[2]; + mac[4] = mac_ocotp[1]; + mac[5] = mac_ocotp[0]; + + eth_register_ethaddr(0, mac); +} + +static struct fsl_usb2_platform_data usb_pdata = { + .operating_mode = FSL_USB2_DR_DEVICE, + .phy_mode = FSL_USB2_PHY_UTMI, +}; + +static int duckbill_devices_init(void) +{ + duckbill_get_ethaddr(); /* must be after registering ocotp */ + + imx28_usb_phy0_enable(); + add_generic_device("fsl-udc", DEVICE_ID_DYNAMIC, NULL, IMX_USB0_BASE, + 0x200, IORESOURCE_MEM, &usb_pdata); + + return 0; +} +fs_initcall(duckbill_devices_init); + +static int duckbill_console_init(void) +{ + barebox_set_model("I2SE Duckbill"); + barebox_set_hostname("duckbill"); + + return 0; +} +console_initcall(duckbill_console_init); diff --git a/arch/arm/boards/duckbill/lowlevel.c b/arch/arm/boards/duckbill/lowlevel.c new file mode 100644 index 0000000000..77d2e83aed --- /dev/null +++ b/arch/arm/boards/duckbill/lowlevel.c @@ -0,0 +1,73 @@ +#define pr_fmt(fmt) "Freescale MX28evk: " fmt +#define DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern char __dtb_imx28_duckbill_start[]; + +ENTRY_FUNCTION(start_barebox_duckbill, r0, r1, r2) +{ + void *fdt; + + pr_debug("here we are!\n"); + + fdt = __dtb_imx28_duckbill_start - get_runtime_offset(); + + barebox_arm_entry(IMX_MEMORY_BASE, SZ_128M, fdt); +} + +static const uint32_t iomux_pads[] = { + /* EMI */ + EMI_DATA0, EMI_DATA1, EMI_DATA2, EMI_DATA3, EMI_DATA4, EMI_DATA5, + EMI_DATA6, EMI_DATA7, EMI_DATA8, EMI_DATA9, EMI_DATA10, EMI_DATA11, + EMI_DATA12, EMI_DATA13, EMI_DATA14, EMI_DATA15, EMI_ODT0, EMI_DQM0, + EMI_ODT1, EMI_DQM1, EMI_DDR_OPEN_FB, EMI_CLK, EMI_DSQ0, EMI_DSQ1, + EMI_DDR_OPEN, EMI_A0, EMI_A1, EMI_A2, EMI_A3, EMI_A4, EMI_A5, + EMI_A6, EMI_A7, EMI_A8, EMI_A9, EMI_A10, EMI_A11, EMI_A12, EMI_A13, + EMI_A14, EMI_BA0, EMI_BA1, EMI_BA2, EMI_CASN, EMI_RASN, EMI_WEN, + EMI_CE0N, EMI_CE1N, EMI_CKE, + + /* Debug UART */ + PWM0_DUART_RX | VE_3_3V, + PWM1_DUART_TX | VE_3_3V, +}; + +static noinline void duckbill_init(void) +{ + int i; + + /* initialize muxing */ + for (i = 0; i < ARRAY_SIZE(iomux_pads); i++) + imx_gpio_mode(iomux_pads[i]); + + pr_debug("initializing power...\n"); + + mx28_power_init(0, 0, 1); + + pr_debug("initializing SDRAM...\n"); + + mx28_mem_init(); + + pr_debug("DONE\n"); +} + +ENTRY_FUNCTION(prep_start_barebox_duckbill, r0, r1, r2) +{ + void (*back)(unsigned long) = (void *)get_lr(); + + relocate_to_current_adr(); + setup_c(); + + duckbill_init(); + + back(0); +} diff --git a/arch/arm/configs/duckbill_defconfig b/arch/arm/configs/duckbill_defconfig new file mode 100644 index 0000000000..6210416130 --- /dev/null +++ b/arch/arm/configs/duckbill_defconfig @@ -0,0 +1,100 @@ +CONFIG_ARCH_MXS=y +CONFIG_ARCH_IMX28=y +CONFIG_MACH_DUCKBILL=y +CONFIG_ARCH_MXS_USBLOADER=y +CONFIG_AEABI=y +CONFIG_ARM_OPTIMZED_STRING_FUNCTIONS=y +CONFIG_ARM_UNWIND=y +CONFIG_MMU=y +CONFIG_TEXT_BASE=0x0 +CONFIG_MALLOC_SIZE=0x0 +CONFIG_MALLOC_TLSF=y +CONFIG_KALLSYMS=y +CONFIG_RELOCATABLE=y +CONFIG_HUSH_FANCY_PROMPT=y +CONFIG_CMDLINE_EDITING=y +CONFIG_AUTO_COMPLETE=y +CONFIG_MENU=y +CONFIG_BLSPEC=y +CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y +CONFIG_RESET_SOURCE=y +CONFIG_DEBUG_INFO=y +CONFIG_CMD_DMESG=y +CONFIG_LONGHELP=y +CONFIG_CMD_IOMEM=y +CONFIG_CMD_MEMINFO=y +CONFIG_CMD_BOOTM_SHOW_TYPE=y +CONFIG_CMD_BOOTM_VERBOSE=y +CONFIG_CMD_BOOTM_INITRD=y +CONFIG_CMD_GO=y +CONFIG_CMD_RESET=y +CONFIG_CMD_UIMAGE=y +CONFIG_CMD_PARTITION=y +CONFIG_CMD_EXPORT=y +CONFIG_CMD_LOADENV=y +CONFIG_CMD_PRINTENV=y +CONFIG_CMD_MAGICVAR=y +CONFIG_CMD_MAGICVAR_HELP=y +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_CMP=y +CONFIG_CMD_FILETYPE=y +CONFIG_CMD_LN=y +CONFIG_CMD_MD5SUM=y +CONFIG_CMD_UNCOMPRESS=y +CONFIG_CMD_LET=y +CONFIG_CMD_MSLEEP=y +CONFIG_CMD_READF=y +CONFIG_CMD_SLEEP=y +CONFIG_CMD_DHCP=y +CONFIG_CMD_HOST=y +CONFIG_CMD_MIITOOL=y +CONFIG_CMD_PING=y +CONFIG_CMD_TFTP=y +CONFIG_CMD_ECHO_E=y +CONFIG_CMD_EDIT=y +CONFIG_CMD_MENUTREE=y +CONFIG_CMD_SPLASH=y +CONFIG_CMD_READLINE=y +CONFIG_CMD_TIMEOUT=y +CONFIG_CMD_CRC=y +CONFIG_CMD_CRC_CMP=y +CONFIG_CMD_MM=y +CONFIG_CMD_CLK=y +CONFIG_CMD_DETECT=y +CONFIG_CMD_FLASH=y +CONFIG_CMD_GPIO=y +CONFIG_CMD_LED=y +CONFIG_CMD_NANDTEST=y +CONFIG_CMD_SPI=y +CONFIG_CMD_LED_TRIGGER=y +CONFIG_CMD_USBGADGET=y +CONFIG_CMD_OF_NODE=y +CONFIG_CMD_OF_PROPERTY=y +CONFIG_CMD_OFTREE=y +CONFIG_NET=y +CONFIG_OFDEVICE=y +CONFIG_OF_BAREBOX_DRIVERS=y +CONFIG_DRIVER_SERIAL_AUART=y +CONFIG_DRIVER_NET_FEC_IMX=y +CONFIG_DRIVER_SPI_MXS=y +CONFIG_MTD=y +CONFIG_NAND=y +CONFIG_NAND_MXS=y +CONFIG_USB_GADGET=y +CONFIG_USB_GADGET_DFU=y +CONFIG_USB_GADGET_SERIAL=y +CONFIG_USB_GADGET_FASTBOOT=y +CONFIG_VIDEO=y +CONFIG_DRIVER_VIDEO_STM=y +CONFIG_MCI=y +CONFIG_MCI_STARTUP=y +CONFIG_MCI_MXS=y +CONFIG_LED=y +CONFIG_LED_GPIO=y +CONFIG_LED_GPIO_OF=y +CONFIG_LED_TRIGGERS=y +CONFIG_MXS_APBH_DMA=y +CONFIG_FS_TFTP=y +CONFIG_FS_FAT=y +CONFIG_FS_FAT_WRITE=y +CONFIG_FS_FAT_LFN=y diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index dc32dd37c2..f7166286c2 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -10,6 +10,7 @@ obj-y += empty.o pbl-dtb-$(CONFIG_MACH_AFI_GF) += am335x-afi-gf.dtb.o pbl-dtb-$(CONFIG_MACH_BEAGLEBONE) += am335x-bone.dtb.o am335x-boneblack.dtb.o am335x-bone-common.dtb.o pbl-dtb-$(CONFIG_MACH_DFI_FS700_M60) += imx6q-dfi-fs700-m60-6q.dtb.o imx6dl-dfi-fs700-m60-6s.dtb.o +pbl-dtb-$(CONFIG_MACH_DUCKBILL) += imx28-duckbill.dtb.o pbl-dtb-$(CONFIG_MACH_EFIKA_MX_SMARTBOOK) += imx51-genesi-efika-sb.dtb.o pbl-dtb-$(CONFIG_MACH_EMBEST_RIOTBOARD) += imx6s-riotboard.dtb.o pbl-dtb-$(CONFIG_MACH_EMBEDSKY_E9) += imx6q-embedsky-e9.dtb.o diff --git a/arch/arm/dts/imx28-duckbill.dts b/arch/arm/dts/imx28-duckbill.dts new file mode 100644 index 0000000000..2a995a7938 --- /dev/null +++ b/arch/arm/dts/imx28-duckbill.dts @@ -0,0 +1,15 @@ +#include + +/ { + chosen { + stdout-path = &duart; + }; +}; + +&duart { + arm,primecell-periphid = <0x00041011>; +}; + +&ocotp { + status = "okay"; +}; diff --git a/arch/arm/mach-mxs/Kconfig b/arch/arm/mach-mxs/Kconfig index 5b50e82fc8..ea0fa5a62b 100644 --- a/arch/arm/mach-mxs/Kconfig +++ b/arch/arm/mach-mxs/Kconfig @@ -74,6 +74,14 @@ config MACH_MX28EVK help Say Y here if you are using the Freescale i.MX28-EVK board +config MACH_DUCKBILL + bool "Duckbill" + select HAVE_DEFAULT_ENVIRONMENT_NEW + select MXS_OCOTP + select HAVE_PBL_MULTI_IMAGES + help + Say Y here if you are using the I2SE Duckbill board + config MACH_CFA10036 bool "cfa-10036" select HAVE_DEFAULT_ENVIRONMENT_NEW diff --git a/images/Makefile.mxs b/images/Makefile.mxs index e2cdbd2a27..733f83bd1f 100644 --- a/images/Makefile.mxs +++ b/images/Makefile.mxs @@ -22,6 +22,16 @@ board = $(srctree)/arch/$(ARCH)/boards mxs23cfg = $(srctree)/arch/arm/mach-mxs/mxs23img.cfg mxs28cfg = $(srctree)/arch/arm/mach-mxs/mxs28img.cfg +pblx-$(CONFIG_MACH_DUCKBILL) += start_barebox_duckbill prep_start_barebox_duckbill +PREP_start_barebox_duckbill.pblx.mxsbs = start_barebox_duckbill_prep +CFG_start_barebox_duckbill.mxsbs = $(mxs28cfg) +FILE_barebox-duckbill-bootstream.img = start_barebox_duckbill.mxsbs +image-$(CONFIG_MACH_DUCKBILL) += barebox-duckbill-bootstream.img +FILE_barebox-duckbill-sd.img = start_barebox_duckbill.mxsbs.mxssd +image-$(CONFIG_MACH_DUCKBILL) += barebox-duckbill-sd.img +FILE_barebox-duckbill-2nd.img = start_barebox_duckbill.pblx +image-$(CONFIG_MACH_DUCKBILL) += barebox-duckbill-2nd.img + pblx-$(CONFIG_MACH_TX28) += start_barebox_karo_tx28 prep_start_barebox_karo_tx28 PREP_start_barebox_karo_tx28.pblx.mxsbs = start_barebox_karo_tx28_prep CFG_start_barebox_karo_tx28.mxsbs = $(mxs28cfg) -- cgit v1.2.3