9
0
Fork 0

Merge branch 'for-next/imx'

This commit is contained in:
Sascha Hauer 2017-02-13 09:26:04 +01:00
commit 30139163b7
116 changed files with 8713 additions and 265 deletions

View File

@ -20,6 +20,7 @@ The Internal Boot Mode is supported on:
* i.MX51
* i.MX53
* i.MX6
* i.MX7
With the Internal Boot Mode, the images contain a header which describes
where the binary shall be loaded and started. These headers also contain

View File

@ -0,0 +1,54 @@
element14 WaRP7
===============
This CPU card is based on an NXP i.MX7S SoC.
Supported hardware
==================
- NXP PMIC PFUZE3000
- Kingston 08EMCP04-EL3AV100 eMCP (eMMC and LPDDR3 memory in one package)
- 8 GiB eMMC Triple-Level cell NAND flash, eMMC standard 5.0 (HS400)
- 512 MiB LPDDR3 SDRAM starting at address 0x80000000
Bootstrapping barebox
=====================
The device boots in internal boot mode from eMMC and is shipped with a
vendor modified u-boot imximage.
Barebox can be used as a drop-in replacement for the shipped bootloader.
The WaRP7 IO Board has a double DIP switch where switch number two defines the
boot source of the i.MX7 SoC:
+-----+
| |
| | O | <--- on = high level
| | | |
| O | | <--- off = low level
| |
| 1 2 |
+-----+
Bootsource is the internal eMMC:
+-----+
| |
| O | |
| | | |
| | O | <---- eMMC
| |
| 1 2 |
+-----+
Bootsource is the USB:
+-----+
| |
| O O | <---- USB
| | | |
| | | |
| |
| 1 2 |
+-----+

View File

@ -383,6 +383,29 @@ config ARM_SEMIHOSTING
the data on the host computer connected to the target via
debugging channel (JTAG, SWD). If unsure say N
config ARM_SECURE_MONITOR
bool
config ARM_PSCI
bool "enable Power State Coordination Interface (PSCI) support"
depends on CPU_V7
select ARM_SECURE_MONITOR
help
PSCI is used for controlling secondary CPU cores on some systems. Say
yes here if you have one of these.
config ARM_PSCI_DEBUG
bool "Enable PSCI debugging"
depends on ARM_PSCI
help
This enables debug output from the PSCI functions during runtime of the
Kernel. This needs board specific help, the board needs to provide a putc
function using psci_set_putc(). This putc function will then be called
during runtime of the Kernel, so it must be able to cope with that. It may
happen for example that the Kernel has turned off some clocks needed in the
putc function.
Only use for debugging.
endmenu
source common/Kconfig

View File

@ -140,4 +140,7 @@ obj-$(CONFIG_MACH_ZYLONITE) += zylonite/
obj-$(CONFIG_MACH_VARISCITE_MX6) += variscite-mx6/
obj-$(CONFIG_MACH_VSCOM_BALTOS) += vscom-baltos/
obj-$(CONFIG_MACH_QEMU_VIRT64) += qemu-virt64/
obj-$(CONFIG_MACH_WARP7) += element14-warp7/
obj-$(CONFIG_MACH_VF610_TWR) += freescale-vf610-twr/
obj-$(CONFIG_MACH_ZII_RDU2) += zii-imx6q-rdu2/
obj-$(CONFIG_MACH_ZII_VF610_DEV) += zii-vf610-dev/

View File

@ -0,0 +1,2 @@
obj-y += board.o
lwl-y += lowlevel.o

View File

@ -0,0 +1,35 @@
/*
* Copyright (C) 2017 Sascha Hauer, 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 <common.h>
#include <init.h>
#include <environment.h>
#include <mach/bbu.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
#include <partition.h>
#include <mach/generic.h>
#include <linux/sizes.h>
static int warp7_devices_init(void)
{
if (!of_machine_is_compatible("warp,imx7s-warp"))
return 0;
imx6_bbu_internal_mmc_register_handler("mmc", "/dev/mmc2.boot0.barebox",
BBU_HANDLER_FLAG_DEFAULT);
return 0;
}
device_initcall(warp7_devices_init);

View File

@ -0,0 +1,81 @@
/*
* Copyright (C) 2016 NXP Semiconductors
*
* SPDX-License-Identifier: GPL-2.0
*
* Refer docs/README.imxmage for more details about how-to configure
* and create imximage boot image
*
* The syntax is taken as close as possible with the kwbimage
*/
soc imx7
loadaddr 0x80000000
dcdofs 0x400
wm 32 0x30340004 0x4F400005
wm 32 0x30391000 0x00000002
wm 32 0x307a0000 0x03040008
wm 32 0x307a0064 0x00200038
wm 32 0x307a0490 0x00000001
wm 32 0x307a00d0 0x00350001
wm 32 0x307a00dc 0x00c3000a
wm 32 0x307a00e0 0x00010000
wm 32 0x307a00e4 0x00110006
wm 32 0x307a00f4 0x0000033f
wm 32 0x307a0100 0x0a0e110b
wm 32 0x307a0104 0x00020211
wm 32 0x307a0108 0x03060708
wm 32 0x307a010c 0x00a0500c
wm 32 0x307a0110 0x05020307
wm 32 0x307a0114 0x02020404
wm 32 0x307a0118 0x02020003
wm 32 0x307a011c 0x00000202
wm 32 0x307a0120 0x00000202
wm 32 0x307a0180 0x00600018
wm 32 0x307a0184 0x00e00100
wm 32 0x307a0190 0x02098205
wm 32 0x307a0194 0x00060303
wm 32 0x307a01a0 0x80400003
wm 32 0x307a01a4 0x00100020
wm 32 0x307a01a8 0x80100004
wm 32 0x307a0200 0x00000015
wm 32 0x307a0204 0x00161616
wm 32 0x307a0210 0x00000f0f
wm 32 0x307a0214 0x04040404
wm 32 0x307a0218 0x0f0f0404
wm 32 0x307a0240 0x06000600
wm 32 0x307a0244 0x00000000
wm 32 0x30391000 0x00000000
wm 32 0x30790000 0x17421e40
wm 32 0x30790004 0x10210100
wm 32 0x30790008 0x00010000
wm 32 0x30790010 0x0007080c
wm 32 0x307900b0 0x1010007e
wm 32 0x3079001C 0x01010000
wm 32 0x3079009c 0x00000d6e
wm 32 0x30790030 0x06060606
wm 32 0x30790020 0x0a0a0a0a
wm 32 0x30790050 0x01000008
wm 32 0x30790050 0x00000008
wm 32 0x30790018 0x0000000f
wm 32 0x307900c0 0x0e487304
wm 32 0x307900c0 0x0e4c7304
wm 32 0x307900c0 0x0e4c7306
wm 32 0x307900c0 0x0e4c7304
check 32 while_any_bit_clear 0x307900c4 0x1
wm 32 0x307900c0 0x0e487304
wm 32 0x30384130 0x00000000
wm 32 0x30340020 0x00000178
wm 32 0x30384130 0x00000002
check 32 while_any_bit_clear 0x307a0004 0x1

View File

@ -0,0 +1,48 @@
#define DEBUG
#include <io.h>
#include <common.h>
#include <linux/sizes.h>
#include <mach/generic.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <mach/debug_ll.h>
#include <asm/cache.h>
extern char __dtb_imx7s_warp_start[];
static noinline void warp7_start(void)
{
void __iomem *iomuxbase = IOMEM(MX7_IOMUXC_BASE_ADDR);
void __iomem *uart = IOMEM(MX7_UART1_BASE_ADDR);
void __iomem *ccmbase = IOMEM(MX7_CCM_BASE_ADDR);
void *fdt;
writel(0x3, ccmbase + 0x4000 + 16 * 148 + 0x8);
writel(0x10000000, ccmbase + 0x8000 + 128 * 95);
writel(0x3, ccmbase + 0x4000 + 16 * 148 + 0x4);
writel(0x0, iomuxbase + 0x128);
writel(0x0, iomuxbase + 0x12c);
imx7_uart_setup(uart);
pbl_set_putc(imx_uart_putc, uart);
pr_debug("Element14 i.MX7 Warp\n");
fdt = __dtb_imx7s_warp_start - get_runtime_offset();
barebox_arm_entry(0x80000000, SZ_512M, fdt);
}
ENTRY_FUNCTION(start_imx7s_element14_warp7, r0, r1, r2)
{
imx7_cpu_lowlevel_init();
arm_early_mmu_cache_invalidate();
relocate_to_current_adr();
setup_c();
barrier();
warp7_start();
}

View File

@ -2,6 +2,7 @@
#include <common.h>
#include <linux/sizes.h>
#include <mach/generic.h>
#include <mach/iomux-mx6.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
@ -11,12 +12,8 @@ static inline void setup_uart(void)
imx6_ungate_all_peripherals();
writel(0x1b0b1, iomuxbase + 0x0650);
writel(3, iomuxbase + 0x0280);
writel(0x1b0b1, iomuxbase + 0x0654);
writel(3, iomuxbase + 0x0284);
writel(1, iomuxbase + 0x0920);
imx_setup_pad(iomuxbase, MX6Q_PAD_CSI0_DAT10__UART1_TXD);
imx_setup_pad(iomuxbase, MX6Q_PAD_CSI0_DAT11__UART1_RXD);
imx6_uart_setup_ll();

View File

@ -27,16 +27,10 @@ extern char __dtb_vf610_twr_start[];
ENTRY_FUNCTION(start_vf610_twr, r0, r1, r2)
{
int i;
void *fdt;
void __iomem *mscm = IOMEM(VF610_MSCM_BASE_ADDR);
vf610_cpu_lowlevel_init();
for (i = 0; i < VF610_MSCM_IRSPRC_NUM; i++)
writew(VF610_MSCM_IRSPRC_CP0_EN,
mscm + VF610_MSCM_IRSPRC(i));
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();

View File

@ -0,0 +1,2 @@
obj-y += board.o
lwl-y += lowlevel.o

View File

@ -0,0 +1,171 @@
/*
* Copyright (C) 2016 Zodiac Inflight Innovation
* Author: Andrey Smirnov <andrew.smirnov@gmail.com>
*
* 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 <common.h>
#include <init.h>
#include <environment.h>
#include <mach/imx6-regs.h>
#include <gpio.h>
#include <asm/armlinux.h>
#include <generated/mach-types.h>
#include <partition.h>
#include <linux/phy.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <mach/generic.h>
#include <linux/sizes.h>
#include <net.h>
#include <mach/imx6.h>
#include <mach/devices-imx6.h>
#include <mach/iomux-mx6.h>
#include <spi/spi.h>
#include <mach/spi.h>
#include <mach/usb.h>
#include <mach/bbu.h>
#define RDU2_DAC1_RESET IMX_GPIO_NR(1, 0)
#define RDU2_DAC2_RESET IMX_GPIO_NR(1, 2)
#define RDU2_RST_TOUCH IMX_GPIO_NR(1, 7)
#define RDU2_NFC_RESET IMX_GPIO_NR(1, 17)
#define RDU2_HPA1_SDn IMX_GPIO_NR(1, 4)
#define RDU2_HPA2_SDn IMX_GPIO_NR(1, 5)
static const struct gpio rdu2_reset_gpios[] = {
{
.gpio = RDU2_DAC1_RESET,
.flags = GPIOF_OUT_INIT_LOW,
.label = "dac1-reset",
},
{
.gpio = RDU2_DAC2_RESET,
.flags = GPIOF_OUT_INIT_LOW,
.label = "dac2-reset",
},
{
.gpio = RDU2_RST_TOUCH,
.flags = GPIOF_OUT_INIT_LOW,
.label = "rst-touch#",
},
{
.gpio = RDU2_NFC_RESET,
.flags = GPIOF_OUT_INIT_HIGH,
.label = "nfc-reset",
},
{
.gpio = RDU2_HPA1_SDn,
.flags = GPIOF_OUT_INIT_LOW,
.label = "hpa1-sd-n",
},
{
.gpio = RDU2_HPA2_SDn,
.flags = GPIOF_OUT_INIT_LOW,
.label = "hpa2n-sd-n",
},
};
static int rdu2_reset_audio_touchscreen_nfc(void)
{
int ret;
if (!of_machine_is_compatible("zii,imx6q-zii-rdu2") &&
!of_machine_is_compatible("zii,imx6qp-zii-rdu2"))
return 0;
ret = gpio_request_array(rdu2_reset_gpios,
ARRAY_SIZE(rdu2_reset_gpios));
if (ret) {
pr_err("Failed to request RDU2 reset gpios: %s\n",
strerror(-ret));
return ret;
}
mdelay(100);
gpio_direction_output(RDU2_DAC1_RESET, 1);
gpio_direction_output(RDU2_DAC2_RESET, 1);
gpio_direction_output(RDU2_RST_TOUCH, 1);
gpio_direction_output(RDU2_NFC_RESET, 0);
gpio_direction_output(RDU2_HPA1_SDn, 1);
gpio_direction_output(RDU2_HPA2_SDn, 1);
mdelay(100);
return 0;
}
/*
* When this function is called "hog" pingroup in device tree needs to
* be already initialized
*/
late_initcall(rdu2_reset_audio_touchscreen_nfc);
static const struct gpio rdu2_front_panel_usb_gpios[] = {
{
.gpio = IMX_GPIO_NR(3, 19),
.flags = GPIOF_OUT_INIT_LOW,
.label = "usb-emulation",
},
{
.gpio = IMX_GPIO_NR(3, 20),
.flags = GPIOF_OUT_INIT_HIGH,
.label = "usb-mode1",
},
{
.gpio = IMX_GPIO_NR(3, 22),
.flags = GPIOF_OUT_INIT_LOW,
.label = "usb-pwr-ctrl-enn",
},
{
.gpio = IMX_GPIO_NR(3, 23),
.flags = GPIOF_OUT_INIT_HIGH,
.label = "usb-mode2",
},
};
static int rdu2_enable_front_panel_usb(void)
{
int ret;
if (!of_machine_is_compatible("zii,imx6q-zii-rdu2") &&
!of_machine_is_compatible("zii,imx6qp-zii-rdu2"))
return 0;
ret = gpio_request_array(rdu2_front_panel_usb_gpios,
ARRAY_SIZE(rdu2_front_panel_usb_gpios));
if (ret) {
pr_err("Failed to request RDU2 front panel USB gpios: %s\n",
strerror(-ret));
}
return ret;
}
late_initcall(rdu2_enable_front_panel_usb);
static int rdu2_devices_init(void)
{
if (!of_machine_is_compatible("zii,imx6q-zii-rdu2") &&
!of_machine_is_compatible("zii,imx6qp-zii-rdu2"))
return 0;
barebox_set_hostname("rdu2");
imx6_bbu_internal_spi_i2c_register_handler("SPI", "/dev/m25p0.barebox",
BBU_HANDLER_FLAG_DEFAULT);
imx6_bbu_internal_mmc_register_handler("eMMC", "/dev/mmc3", 0);
return 0;
}
device_initcall(rdu2_devices_init);

View File

@ -0,0 +1,17 @@
#!/bin/sh
# automount tftp server based on $eth0.serverip
mkdir -p /mnt/tftp
automount /mnt/tftp 'ifup eth1 && mount -t tftp $eth1.serverip /mnt/tftp'
# automount nfs server's nfsroot
mkdir -p /mnt/nfs
automount /mnt/nfs 'ifup eth1 && mount -t nfs ${eth1.serverip}:/home/${global.user}/nfsroot/${global.hostname} /mnt/nfs'
# FAT on usb disk example
#mkdir -p /mnt/fat
#automount -d /mnt/fat 'usb && [ -e /dev/disk0.0 ] && mount /dev/disk0.0 /mnt/fat'

View File

@ -0,0 +1,18 @@
#!/bin/sh
# ip setting (static/dhcp)
ip=dhcp
global.dhcp.vendor_id=barebox-${global.hostname}
# static setup used if ip=static
ipaddr=
netmask=
gateway=
serverip=
# MAC address if needed
#ethaddr=xx:xx:xx:xx:xx:xx
# put code to discover eth0 (i.e. 'usb') to /env/network/eth0-discover
exit 0

View File

@ -0,0 +1 @@
mmc1

View File

@ -0,0 +1,87 @@
loadaddr 0x10000000
soc imx6
dcdofs 0x400
wm 32 0x020e0798 0x000C0000
wm 32 0x020e0758 0x00000000
wm 32 0x020e0588 0x00000030
wm 32 0x020e0594 0x00000030
wm 32 0x020e056c 0x00000030
wm 32 0x020e0578 0x00000030
wm 32 0x020e074c 0x00000030
wm 32 0x020e057c 0x00000030
wm 32 0x020e058c 0x00000000
wm 32 0x020e059c 0x00000030
wm 32 0x020e05a0 0x00000030
wm 32 0x020e078c 0x00000030
wm 32 0x020e0750 0x00020000
wm 32 0x020e05a8 0x00000028
wm 32 0x020e05b0 0x00000028
wm 32 0x020e0524 0x00000028
wm 32 0x020e051c 0x00000028
wm 32 0x020e0518 0x00000028
wm 32 0x020e050c 0x00000028
wm 32 0x020e05b8 0x00000028
wm 32 0x020e05c0 0x00000028
wm 32 0x020e0774 0x00020000
wm 32 0x020e0784 0x00000028
wm 32 0x020e0788 0x00000028
wm 32 0x020e0794 0x00000028
wm 32 0x020e079c 0x00000028
wm 32 0x020e07a0 0x00000028
wm 32 0x020e07a4 0x00000028
wm 32 0x020e07a8 0x00000028
wm 32 0x020e0748 0x00000028
wm 32 0x020e05ac 0x00000028
wm 32 0x020e05b4 0x00000028
wm 32 0x020e0528 0x00000028
wm 32 0x020e0520 0x00000028
wm 32 0x020e0514 0x00000028
wm 32 0x020e0510 0x00000028
wm 32 0x020e05bc 0x00000028
wm 32 0x020e05c4 0x00000028
wm 32 0x021b0800 0xa1390003
wm 32 0x021b080c 0x001F001F
wm 32 0x021b0810 0x001F001F
wm 32 0x021b480c 0x001F001F
wm 32 0x021b4810 0x001F001F
wm 32 0x021b083c 0x43260335
wm 32 0x021b0840 0x031A030B
wm 32 0x021b483c 0x4323033B
wm 32 0x021b4840 0x0323026F
wm 32 0x021b0848 0x483D4545
wm 32 0x021b4848 0x44433E48
wm 32 0x021b0850 0x41444840
wm 32 0x021b4850 0x4835483E
wm 32 0x021b081c 0x33333333
wm 32 0x021b0820 0x33333333
wm 32 0x021b0824 0x33333333
wm 32 0x021b0828 0x33333333
wm 32 0x021b481c 0x33333333
wm 32 0x021b4820 0x33333333
wm 32 0x021b4824 0x33333333
wm 32 0x021b4828 0x33333333
wm 32 0x021b08b8 0x00000800
wm 32 0x021b48b8 0x00000800
wm 32 0x021b0004 0x00020036
wm 32 0x021b0008 0x09444040
wm 32 0x021b000c 0x8A8F7955
wm 32 0x021b0010 0xFF328F64
wm 32 0x021b0014 0x01FF00DB
wm 32 0x021b0018 0x00001740
wm 32 0x021b001c 0x00008000
wm 32 0x021b002c 0x000026d2
wm 32 0x021b0030 0x008F1023
wm 32 0x021b0040 0x00000047
wm 32 0x021b0000 0x841A0000
wm 32 0x021b001c 0x04088032
wm 32 0x021b001c 0x00008033
wm 32 0x021b001c 0x00048031
wm 32 0x021b001c 0x09408030
wm 32 0x021b001c 0x04008040
wm 32 0x021b0020 0x00005800
wm 32 0x021b0818 0x00011117
wm 32 0x021b4818 0x00011117
wm 32 0x021b0004 0x00025576
wm 32 0x021b0404 0x00011006
wm 32 0x021b001c 0x00000000

View File

@ -0,0 +1,132 @@
loadaddr 0x10000000
soc imx6
dcdofs 0x400
wm 32 0x020e0798 0x000C0000
wm 32 0x020e0758 0x00000000
wm 32 0x020e0588 0x00020030
wm 32 0x020e0594 0x00020030
wm 32 0x020e056c 0x00020030
wm 32 0x020e0578 0x00020030
wm 32 0x020e074c 0x00020030
wm 32 0x020e057c 0x00020030
wm 32 0x020e058c 0x00000000
wm 32 0x020e059c 0x00020030
wm 32 0x020e05a0 0x00020030
wm 32 0x020e078c 0x00020030
wm 32 0x020e0750 0x00020000
wm 32 0x020e05a8 0x00020030
wm 32 0x020e05b0 0x00020030
wm 32 0x020e0524 0x00020030
wm 32 0x020e051c 0x00020030
wm 32 0x020e0518 0x00020030
wm 32 0x020e050c 0x00020030
wm 32 0x020e05b8 0x00020030
wm 32 0x020e05c0 0x00020030
wm 32 0x020e0534 0x00018200
wm 32 0x020e0538 0x00008000
wm 32 0x020e053c 0x00018200
wm 32 0x020e0540 0x00018200
wm 32 0x020e0544 0x00018200
wm 32 0x020e0548 0x00018200
wm 32 0x020e054c 0x00018200
wm 32 0x020e0550 0x00018200
wm 32 0x020e0774 0x00020000
wm 32 0x020e0784 0x00020030
wm 32 0x020e0788 0x00020030
wm 32 0x020e0794 0x00020030
wm 32 0x020e079c 0x00020030
wm 32 0x020e07a0 0x00020030
wm 32 0x020e07a4 0x00020030
wm 32 0x020e07a8 0x00020030
wm 32 0x020e0748 0x00020030
wm 32 0x020e05ac 0x00020030
wm 32 0x020e05b4 0x00020030
wm 32 0x020e0528 0x00020030
wm 32 0x020e0520 0x00020030
wm 32 0x020e0514 0x00020030
wm 32 0x020e0510 0x00020030
wm 32 0x020e05bc 0x00020030
wm 32 0x020e05c4 0x00020030
wm 32 0x021b001c 0x00008000
wm 32 0x021b0800 0xA1390003
wm 32 0x021b080c 0x002A001F
wm 32 0x021b0810 0x002F002A
wm 32 0x021b480c 0x001F0031
wm 32 0x021b4810 0x001B0022
wm 32 0x021b083c 0x433C0354
wm 32 0x021b0840 0x03380330
wm 32 0x021b483c 0x43440358
wm 32 0x021b4840 0x03340300
wm 32 0x021b0848 0x483A4040
wm 32 0x021b4848 0x3E383648
wm 32 0x021b0850 0x3C424048
wm 32 0x021b4850 0x4C425042
wm 32 0x021b081c 0x33333333
wm 32 0x021b0820 0x33333333
wm 32 0x021b0824 0x33333333
wm 32 0x021b0828 0x33333333
wm 32 0x021b481c 0x33333333
wm 32 0x021b4820 0x33333333
wm 32 0x021b4824 0x33333333
wm 32 0x021b4828 0x33333333
wm 32 0x021b08c0 0x24912489
wm 32 0x021b48c0 0x24914452
wm 32 0x021b08b8 0x00000800
wm 32 0x021b48b8 0x00000800
wm 32 0x021b0004 0x00020036
wm 32 0x021b0008 0x09444040
wm 32 0x021b000c 0x898E7955
wm 32 0x021b0010 0xFF328F64
wm 32 0x021b0014 0x01FF00DB
wm 32 0x021b0018 0x00011740
wm 32 0x021b001c 0x00008000
wm 32 0x021b002c 0x000026D2
wm 32 0x021b0030 0x008E1023
wm 32 0x021b0040 0x00000047
wm 32 0x021b0400 0x14420000
wm 32 0x021b0000 0x841A0000
wm 32 0x021b0890 0x00400c58
wm 32 0x00bb0008 0x00000000
wm 32 0x00bb000c 0x2891E41A
wm 32 0x00bb0038 0x00000564
wm 32 0x00bb0014 0x00000040
wm 32 0x00bb0028 0x00000020
wm 32 0x00bb002c 0x00000020
wm 32 0x021b001c 0x02088032
wm 32 0x021b001c 0x00008033
wm 32 0x021b001c 0x00048031
wm 32 0x021b001c 0x19408030
wm 32 0x021b001c 0x04008040
wm 32 0x021b0020 0x00007800
wm 32 0x021b0818 0x00022227
wm 32 0x021b4818 0x00022227
wm 32 0x021b0004 0x00025576
wm 32 0x021b0404 0x00011006
wm 32 0x021b001c 0x00000000

View File

@ -0,0 +1,66 @@
/*
* Copyright (C) 2016 Zodiac Inflight Innovation
* Author: Andrey Smirnov <andrew.smirnov@gmail.com>
*
* 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 <debug_ll.h>
#include <common.h>
#include <mach/esdctl.h>
#include <mach/generic.h>
#include <mach/imx6.h>
#include <asm/barebox-arm.h>
static inline void setup_uart(void)
{
void __iomem *iomuxbase = IOMEM(MX6_IOMUXC_BASE_ADDR);
imx6_ungate_all_peripherals();
writel(0x1b0b1, iomuxbase + 0x0650);
writel(3, iomuxbase + 0x0280);
writel(0x1b0b1, iomuxbase + 0x0654);
writel(3, iomuxbase + 0x0284);
writel(1, iomuxbase + 0x0920);
imx6_uart_setup_ll();
putc_ll('>');
}
extern char __dtb_imx6q_zii_rdu2_start[];
extern char __dtb_imx6qp_zii_rdu2_start[];
ENTRY_FUNCTION(start_imx6q_zii_rdu2, r0, r1, r2)
{
void *fdt = __dtb_imx6q_zii_rdu2_start;
imx6_cpu_lowlevel_init();
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
imx6q_barebox_entry(fdt - get_runtime_offset());
}
ENTRY_FUNCTION(start_imx6qp_zii_rdu2, r0, r1, r2)
{
void *fdt = __dtb_imx6qp_zii_rdu2_start;
imx6_cpu_lowlevel_init();
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
imx6q_barebox_entry(fdt - get_runtime_offset());
}

View File

@ -0,0 +1,3 @@
obj-y += board.o
lwl-y += lowlevel.o
bbenv-y += defaultenv-zii-vf610-dev

View File

@ -0,0 +1,149 @@
/*
* Copyright (C) 2016 Zodiac Inflight Innovation
* Author: Andrey Smirnov <andrew.smirnov@gmail.com>
*
* 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 <common.h>
#include <init.h>
#include <gpio.h>
#include <environment.h>
#include <linux/clk.h>
#include <dt-bindings/clock/vf610-clock.h>
#include <envfs.h>
static int expose_signals(const struct gpio *signals,
size_t signal_num)
{
int ret, i;
ret = gpio_request_array(signals, signal_num);
if (ret)
return ret;
for (i = 0; i < signal_num; i++)
export_env_ull(signals[i].label, signals[i].gpio);
return 0;
}
static int zii_vf610_cfu1_expose_signals(void)
{
static const struct gpio signals[] = {
{
.gpio = 132,
.flags = GPIOF_IN,
.label = "fim_sd",
},
{
.gpio = 118,
.flags = GPIOF_OUT_INIT_LOW,
.label = "fim_tdis",
},
};
if (!of_machine_is_compatible("zii,vf610cfu1-a"))
return 0;
return expose_signals(signals, ARRAY_SIZE(signals));
}
late_initcall(zii_vf610_cfu1_expose_signals);
static int zii_vf610_cfu1_spu3_expose_signals(void)
{
static const struct gpio signals[] = {
{
.gpio = 107,
.flags = GPIOF_OUT_INIT_LOW,
.label = "soc_sw_rstn",
},
{
.gpio = 98,
.flags = GPIOF_IN,
.label = "e6352_intn",
},
};
if (!of_machine_is_compatible("zii,vf610spu3-a") &&
!of_machine_is_compatible("zii,vf610cfu1-a"))
return 0;
return expose_signals(signals, ARRAY_SIZE(signals));
}
late_initcall(zii_vf610_cfu1_spu3_expose_signals);
static int zii_vf610_dev_print_clocks(void)
{
int i;
struct clk *clk;
struct device_node *ccm_np;
const unsigned long MHz = 1000000;
const char *clk_names[] = { "cpu", "ddr", "bus", "ipg" };
if (!of_machine_is_compatible("zii,vf610dev"))
return 0;
ccm_np = of_find_compatible_node(NULL, NULL, "fsl,vf610-ccm");
if (!ccm_np) {
pr_err("Couln't get CCM node\n");
return -ENOENT;
}
for (i = 0; i < ARRAY_SIZE(clk_names); i++) {
unsigned long rate;
const char *name = clk_names[i];
clk = of_clk_get_by_name(ccm_np, name);
if (IS_ERR(clk)) {
pr_err("Failed to get '%s' clock (%ld)\n",
name, PTR_ERR(clk));
return PTR_ERR(clk);
}
rate = clk_get_rate(clk);
pr_info("%s clock : %8lu MHz\n", name, rate / MHz);
}
return 0;
}
late_initcall(zii_vf610_dev_print_clocks);
static int zii_vf610_dev_set_hostname(void)
{
size_t i;
static const struct {
const char *compatible;
const char *hostname;
} boards[] = {
{ "zii,vf610spu3-a", "spu3-rev-a" },
{ "zii,vf610cfu1-a", "cfu1-rev-a" },
{ "zii,vf610dev-b", "dev-rev-b" },
{ "zii,vf610dev-c", "dev-rev-c" },
{ "zii,vf610scu4-aib-c", "scu4-aib-rev-c" },
};
if (!of_machine_is_compatible("zii,vf610dev"))
return 0;
for (i = 0; i < ARRAY_SIZE(boards); i++) {
if (of_machine_is_compatible(boards[i].compatible)) {
barebox_set_hostname(boards[i].hostname);
break;
}
}
defaultenv_append_directory(defaultenv_zii_vf610_dev);
return 0;
}
late_initcall(zii_vf610_dev_set_hostname);

View File

@ -0,0 +1,4 @@
#!/bin/sh
global.bootm.image=/mnt/sd/zImage
global.bootm.oftree=/mnt/sd/${global.bootm.oftree}

View File

@ -0,0 +1,13 @@
#!/bin/sh
if [ x${global.hostname} = xdev-rev-b -o x${global.hostname} = xdev-rev-c ];
then
global sd=0
else
global sd=1
fi
mkdir -p /mnt/sd
automount /mnt/sd 'mci${global.sd}.probe=1 && mount /dev/disk${global.sd}.0 /mnt/sd'
exit 0

View File

@ -0,0 +1,4 @@
#!/bin/sh
global.bootm.oftree=vf610-zii-${global.hostname}.dtb

View File

@ -0,0 +1,243 @@
soc vf610
loadaddr 0x80000000
dcdofs 0x400
#define VF610_DDR_PAD_CTRL 0x00000180 /* 25 Ohm drive strength */
#define VF610_DDR_PAD_CTRL_1 0x00010180 /* 25 Ohm drive strength + differential input */
#define DDRMC_PHY_DQ_TIMING 0x00002613
#define DDRMC_PHY_DQS_TIMING 0x00002615
#define DDRMC_PHY_CTRL 0x00210000
#define DDRMC_PHY_MASTER_CTRL 0x0001012a
#define DDRMC_PHY_SLAVE_CTRL 0x00002000
#define DDRMC_PHY_OFF 0x00000000
#define DDRMC_PHY_PROC_PAD_ODT 0x00010101
#define CHECKPOINT(n) wm 32 0x3f000000 n
CHECKPOINT(1)
/* ======================= Clock initialization =======================*/
/*
* Ungate all IP block clocks
*/
wm 32 0x4006b040 0xffffffff
wm 32 0x4006b044 0xffffffff
wm 32 0x4006b048 0xffffffff
wm 32 0x4006b04c 0xffffffff
wm 32 0x4006b050 0xffffffff
wm 32 0x4006b058 0xffffffff
wm 32 0x4006b05c 0xffffffff
wm 32 0x4006b060 0xffffffff
wm 32 0x4006b064 0xffffffff
wm 32 0x4006b068 0xffffffff
wm 32 0x4006b06c 0xffffffff
/*
* Turn PLL2 on
*/
wm 32 0x40050030 0x00002001 /* Fout = Fin * 22 */
CHECKPOINT(2)
/*
* Wait for PLLs to lock
*/
check 32 while_any_bit_clear 0x40050030 0x80000000
CHECKPOINT(3)
clear_bits 32 0x4006b008 0x00000040
set_bits 32 0x4006b008 0x00002000
/* ======================= DDR IOMUX =======================*/
CHECKPOINT(4)
wm 32 0x40048220 0x00000180
wm 32 0x40048224 0x00000180
wm 32 0x40048228 0x00000180
wm 32 0x4004822c 0x00000180
wm 32 0x40048230 0x00000180
wm 32 0x40048234 0x00000180
wm 32 0x40048238 0x00000180
wm 32 0x4004823c 0x00000180
wm 32 0x40048240 0x00000180
wm 32 0x40048244 0x00000180
wm 32 0x40048248 0x00000180
wm 32 0x4004824c 0x00000180
wm 32 0x40048250 0x00000180
wm 32 0x40048254 0x00000180
wm 32 0x40048258 0x00000180
wm 32 0x4004825c 0x00000180
wm 32 0x40048260 0x00000180
wm 32 0x40048264 0x00000180
wm 32 0x40048268 0x00000180
wm 32 0x4004826c 0x00000180
wm 32 0x40048270 0x00000180
wm 32 0x40048274 0x00000180
wm 32 0x40048278 0x00000180
wm 32 0x4004827c 0x00010180
wm 32 0x40048280 0x00010180
wm 32 0x40048284 0x00010180
wm 32 0x40048288 0x00010180
wm 32 0x4004828c 0x00010180
wm 32 0x40048290 0x00010180
wm 32 0x40048294 0x00010180
wm 32 0x40048298 0x00010180
wm 32 0x4004829c 0x00010180
wm 32 0x400482a0 0x00010180
wm 32 0x400482a4 0x00010180
wm 32 0x400482a8 0x00010180
wm 32 0x400482ac 0x00010180
wm 32 0x400482b0 0x00010180
wm 32 0x400482b4 0x00010180
wm 32 0x400482b8 0x00010180
wm 32 0x400482bc 0x00010180
wm 32 0x400482c0 0x00010180
wm 32 0x400482c4 0x00010180
wm 32 0x400482c8 0x00010180
wm 32 0x400482cc 0x00000180
wm 32 0x400482d0 0x00000180
wm 32 0x400482d4 0x00000180
wm 32 0x400482d8 0x00000180
wm 32 0x4004821c 0x00000180
/* ======================= DDR Controller =======================*/
CHECKPOINT(5)
wm 32 0x400ae000 0x00000600
wm 32 0x400ae008 0x00000005
wm 32 0x400ae028 0x00013880
wm 32 0x400ae02c 0x00030d40
wm 32 0x400ae030 0x00000506
wm 32 0x400ae034 0x06040400
wm 32 0x400ae038 0x1006040e
wm 32 0x400ae040 0x04040000
wm 32 0x400ae044 0x006db00c
wm 32 0x400ae048 0x00000403
wm 32 0x400ae050 0x01000000
wm 32 0x400ae054 0x00060001
wm 32 0x400ae058 0x000c0000
wm 32 0x400ae05c 0x03000200
wm 32 0x400ae060 0x00000006
wm 32 0x400ae064 0x00010000
wm 32 0x400ae068 0x0c300068
wm 32 0x400ae070 0x00000000
wm 32 0x400ae074 0x00000003
wm 32 0x400ae078 0x0000000a
wm 32 0x400ae07c 0x006c0200
wm 32 0x400ae084 0x00010000
wm 32 0x400ae088 0x00050500
wm 32 0x400ae098 0x00000000
wm 32 0x400ae09c 0x04001002
wm 32 0x400ae0a4 0x00000001
wm 32 0x400ae0c0 0x00460420
wm 32 0x400ae0c4 0x00000000
wm 32 0x400ae0cc 0x00000000
wm 32 0x400ae0e4 0x02000000
wm 32 0x400ae108 0x01000200
wm 32 0x400ae10c 0x00000040
wm 32 0x400ae114 0x00000200
wm 32 0x400ae118 0x00000040
wm 32 0x400ae120 0x00000000
wm 32 0x400ae124 0x0a010100
wm 32 0x400ae128 0x01014040
wm 32 0x400ae12c 0x01010101
wm 32 0x400ae130 0x03030000
wm 32 0x400ae134 0x01000101
wm 32 0x400ae138 0x0700000c
wm 32 0x400ae13c 0x00000000
wm 32 0x400ae148 0x10000000
wm 32 0x400ae15c 0x01000000
wm 32 0x400ae160 0x00040000
wm 32 0x400ae164 0x00000002
wm 32 0x400ae16c 0x00020000
wm 32 0x400ae180 0x00002819
wm 32 0x400ae184 0x01000000
wm 32 0x400ae188 0x00000000
wm 32 0x400ae18c 0x00000000
wm 32 0x400ae198 0x00000000
wm 32 0x400ae1a4 0x00000c00
wm 32 0x400ae1a8 0x00000000
wm 32 0x400ae1b8 0x0000000c
wm 32 0x400ae1c8 0x00000000
wm 32 0x400ae1cc 0x00000000
wm 32 0x400ae1d4 0x00000000
wm 32 0x400ae1d8 0x01010000
wm 32 0x400ae1e0 0x02020000
wm 32 0x400ae1e4 0x00000202
wm 32 0x400ae1e8 0x01010064
wm 32 0x400ae1ec 0x00010101
wm 32 0x400ae1f0 0x00000064
wm 32 0x400ae1f8 0x00000800
wm 32 0x400ae210 0x00000506
wm 32 0x400ae224 0x00020000
wm 32 0x400ae228 0x01000000
wm 32 0x400ae22c 0x04070303
wm 32 0x400ae230 0x00000040
wm 32 0x400ae23c 0x06000080
wm 32 0x400ae240 0x04070303
wm 32 0x400ae244 0x00000040
wm 32 0x400ae248 0x00000040
wm 32 0x400ae24c 0x000f0000
wm 32 0x400ae250 0x000f0000
wm 32 0x400ae25c 0x00000101
wm 32 0x400ae268 0x682c4000
wm 32 0x400ae26c 0x00000012
wm 32 0x400ae278 0x00000006
wm 32 0x400ae284 0x00010202
/* ======================= DDR PHY =======================*/
CHECKPOINT(6)
wm 32 0x400ae400 0x00002613
wm 32 0x400ae440 0x00002613
wm 32 0x400ae480 0x00002613
wm 32 0x400ae404 0x00002615
wm 32 0x400ae444 0x00002615
wm 32 0x400ae408 0x00210000
wm 32 0x400ae448 0x00210000
wm 32 0x400ae488 0x00210000
wm 32 0x400ae40c 0x0001012a
wm 32 0x400ae44c 0x0001012a
wm 32 0x400ae48c 0x0001012a
wm 32 0x400ae410 0x00002000
wm 32 0x400ae450 0x00002000
wm 32 0x400ae490 0x00002000
wm 32 0x400ae4c4 0x00000000
wm 32 0x400ae4c8 0x00001100
wm 32 0x400ae4d0 0x00010101
wm 32 0x400ae000 0x00000601
CHECKPOINT(7)
check 32 while_any_bit_clear 0x400ae140 0x100
# check 32 while_any_bit_clear 0x400ae42c 0x1
# check 32 while_any_bit_clear 0x400ae46c 0x1
# check 32 while_any_bit_clear 0x400ae4ac 0x1
CHECKPOINT(8)
wm 32 0x80000000 0xa5a5a5a5
check 32 while_any_bit_clear 0x80000000 0xa5a5a5a5
wm 32 0x400ae000 0x00000600
wm 32 0x400ae000 0x00000601
check 32 while_any_bit_clear 0x400ae140 0x100
# check 32 while_any_bit_clear 0x400ae42c 0x1
# check 32 while_any_bit_clear 0x400ae46c 0x1
# check 32 while_any_bit_clear 0x400ae4ac 0x1
/* wm 32 0x3f040000 0xf0
check 32 while_any_bit_clear 0x3f040000 0x0f */
CHECKPOINT(9)

View File

@ -0,0 +1,137 @@
/*
* Copyright (C) 2016 Zodiac Inflight Innovation
* Author: Andrey Smirnov <andrew.smirnov@gmail.com>
*
* 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 <common.h>
#include <linux/sizes.h>
#include <mach/generic.h>
#include <asm/barebox-arm-head.h>
#include <asm/barebox-arm.h>
#include <mach/vf610-regs.h>
#include <mach/clock-vf610.h>
#include <mach/iomux-vf610.h>
#include <debug_ll.h>
static inline void setup_uart(void)
{
void __iomem *iomux = IOMEM(VF610_IOMUXC_BASE_ADDR);
vf610_ungate_all_peripherals();
vf610_setup_pad(iomux, VF610_PAD_PTB10__UART0_TX);
vf610_uart_setup_ll();
putc_ll('>');
}
enum zii_platform_vf610_type {
ZII_PLATFORM_VF610_DEV_REV_B = 0x01,
ZII_PLATFORM_VF610_SCU4_AIB = 0x02,
ZII_PLATFORM_VF610_SPU3 = 0x03,
ZII_PLATFORM_VF610_CFU1 = 0x04,
ZII_PLATFORM_VF610_DEV_REV_C = 0x05,
};
unsigned int get_system_type(void)
{
#define GPIO_PDIR 0x10
u32 pdir;
void __iomem *gpio2 = IOMEM(VF610_GPIO2_BASE_ADDR);
void __iomem *iomux = IOMEM(VF610_IOMUXC_BASE_ADDR);
unsigned low, high;
/*
* System type is encoded as a 4-bit number specified by the
* following pins (pulled up or down with resistors on the
* board).
*/
vf610_setup_pad(iomux, VF610_PAD_PTD16__GPIO_78);
vf610_setup_pad(iomux, VF610_PAD_PTD17__GPIO_77);
vf610_setup_pad(iomux, VF610_PAD_PTD18__GPIO_76);
vf610_setup_pad(iomux, VF610_PAD_PTD19__GPIO_75);
pdir = readl(gpio2 + GPIO_PDIR);
low = 75 % 32;
high = 78 % 32;
pdir &= GENMASK(high, low);
pdir >>= low;
return pdir;
}
extern char __dtb_vf610_zii_dev_rev_b_start[];
extern char __dtb_vf610_zii_dev_rev_c_start[];
extern char __dtb_vf610_zii_cfu1_rev_a_start[];
extern char __dtb_vf610_zii_spu3_rev_a_start[];
extern char __dtb_vf610_zii_scu4_aib_rev_c_start[];
ENTRY_FUNCTION(start_zii_vf610_dev, r0, r1, r2)
{
void *fdt;
const unsigned int system_type = get_system_type();
vf610_cpu_lowlevel_init();
if (IS_ENABLED(CONFIG_DEBUG_LL))
setup_uart();
switch (system_type) {
default:
/*
* GCC can be smart enough to, when DEBUG_LL is
* disabled, reduce this switch statement to a LUT
* fetch. Unfortunately here, this early in the boot
* process before any relocation/address fixups could
* happen, the address of that LUT used by the code is
* incorrect and any access to it would result in
* bogus values.
*
* Adding the following barrier() statement seem to
* force the compiler to always translate this block
* to a sequence of consecutive checks and jumps with
* relative fetches, which should work with or without
* relocation/fixups.
*/
barrier();
if (IS_ENABLED(CONFIG_DEBUG_LL)) {
relocate_to_current_adr();
setup_c();
puts_ll("*********************************\n");
puts_ll("* Unknown system type: ");
puthex_ll(system_type);
puts_ll("\n* Assuming devboard revision B\n");
puts_ll("*********************************\n");
}
case ZII_PLATFORM_VF610_DEV_REV_B: /* FALLTHROUGH */
fdt = __dtb_vf610_zii_dev_rev_b_start;
break;
case ZII_PLATFORM_VF610_SCU4_AIB:
fdt = __dtb_vf610_zii_scu4_aib_rev_c_start;
break;
case ZII_PLATFORM_VF610_DEV_REV_C:
fdt = __dtb_vf610_zii_dev_rev_c_start;
break;
case ZII_PLATFORM_VF610_CFU1:
fdt = __dtb_vf610_zii_cfu1_rev_a_start;
break;
case ZII_PLATFORM_VF610_SPU3:
fdt = __dtb_vf610_zii_spu3_rev_a_start;
break;
}
barebox_arm_entry(0x80000000, SZ_512M, fdt - get_runtime_offset());
}

View File

@ -0,0 +1,165 @@
CONFIG_ARCH_IMX=y
CONFIG_IMX_MULTI_BOARDS=y
CONFIG_MACH_SABRESD=y
CONFIG_MACH_ZII_VF610_DEV=y
CONFIG_IMX_IIM=y
CONFIG_IMX_IIM_FUSE_BLOW=y
CONFIG_THUMB2_BAREBOX=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_BOOTM_SHOW_TYPE=y
CONFIG_BOOTM_VERBOSE=y
CONFIG_BOOTM_INITRD=y
CONFIG_BOOTM_OFTREE=y
CONFIG_BOOTM_OFTREE_UIMAGE=y
CONFIG_BLSPEC=y
CONFIG_PARTITION_DISK_EFI=y
CONFIG_DEFAULT_ENVIRONMENT_GENERIC_NEW=y
CONFIG_RESET_SOURCE=y
CONFIG_CMD_DMESG=y
CONFIG_LONGHELP=y
CONFIG_CMD_IOMEM=y
CONFIG_CMD_IMD=y
CONFIG_CMD_MEMINFO=y
CONFIG_CMD_ARM_MMUINFO=y
CONFIG_CMD_REGULATOR=y
CONFIG_CMD_MMC_EXTCSD=y
# CONFIG_CMD_BOOTU is not set
CONFIG_CMD_GO=y
CONFIG_CMD_RESET=y
CONFIG_CMD_UIMAGE=y
CONFIG_CMD_PARTITION=y
CONFIG_CMD_UBIFORMAT=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_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_MIITOOL=y
CONFIG_CMD_PING=y
CONFIG_CMD_TFTP=y
CONFIG_CMD_ECHO_E=y
CONFIG_CMD_EDIT=y
CONFIG_CMD_MENU=y
CONFIG_CMD_MENU_MANAGEMENT=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_MEMTEST=y
CONFIG_CMD_MM=y
CONFIG_CMD_CLK=y
CONFIG_CMD_DETECT=y
CONFIG_CMD_FLASH=y
CONFIG_CMD_GPIO=y
CONFIG_CMD_I2C=y
CONFIG_CMD_LED=y
CONFIG_CMD_NANDTEST=y
CONFIG_CMD_SPI=y
CONFIG_CMD_LED_TRIGGER=y
CONFIG_CMD_USBGADGET=y
CONFIG_CMD_WD=y
CONFIG_CMD_BAREBOX_UPDATE=y
CONFIG_CMD_OF_NODE=y
CONFIG_CMD_OF_PROPERTY=y
CONFIG_CMD_OFTREE=y
CONFIG_CMD_TIME=y
CONFIG_NET=y
CONFIG_NET_NETCONSOLE=y
CONFIG_NET_RESOLV=y
CONFIG_OF_BAREBOX_DRIVERS=y
CONFIG_DRIVER_NET_FEC_IMX=y
CONFIG_AT803X_PHY=y
CONFIG_MICREL_PHY=y
CONFIG_NET_USB=y
CONFIG_NET_USB_ASIX=y
CONFIG_NET_USB_SMSC95XX=y
CONFIG_DRIVER_SPI_IMX=y
CONFIG_DRIVER_SPI_DSPI=y
CONFIG_I2C=y
CONFIG_I2C_IMX=y
CONFIG_MTD=y
CONFIG_MTD_RAW_DEVICE=y
CONFIG_MTD_DATAFLASH=y
CONFIG_MTD_M25P80=y
CONFIG_MTD_SST25L=y
CONFIG_NAND=y
CONFIG_NAND_ALLOW_ERASE_BAD=y
CONFIG_NAND_IMX=y
CONFIG_NAND_IMX_BBM=y
CONFIG_MTD_UBI=y
CONFIG_MTD_UBI_FASTMAP=y
CONFIG_DISK_AHCI=y
CONFIG_DISK_AHCI_IMX=y
CONFIG_DISK_INTF_PLATFORM_IDE=y
CONFIG_DISK_PATA_IMX=y
CONFIG_USB_HOST=y
CONFIG_USB_IMX_CHIPIDEA=y
CONFIG_USB_EHCI=y
CONFIG_USB_ULPI=y
CONFIG_USB_STORAGE=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_IMX_IPUV3=y
CONFIG_DRIVER_VIDEO_IMX_IPUV3_LVDS=y
CONFIG_DRIVER_VIDEO_IMX_IPUV3_HDMI=y
CONFIG_DRIVER_VIDEO_SIMPLEFB=y
CONFIG_DRIVER_VIDEO_EDID=y
CONFIG_MCI=y
CONFIG_MCI_MMC_BOOT_PARTITIONS=y
CONFIG_MCI_IMX_ESDHC=y
CONFIG_MFD_MC13XXX=y
CONFIG_MFD_MC34704=y
CONFIG_MFD_MC9SDZ60=y
CONFIG_MFD_STMPE=y
CONFIG_LED=y
CONFIG_LED_GPIO=y
CONFIG_LED_GPIO_OF=y
CONFIG_LED_TRIGGERS=y
CONFIG_EEPROM_AT25=y
CONFIG_EEPROM_AT24=y
CONFIG_KEYBOARD_GPIO=y
CONFIG_WATCHDOG=y
CONFIG_WATCHDOG_IMX=y
CONFIG_PWM=y
CONFIG_PWM_IMX=y
CONFIG_GPIO_STMPE=y
CONFIG_GPIO_SX150X=y
CONFIG_REGULATOR=y
CONFIG_REGULATOR_FIXED=y
CONFIG_GENERIC_PHY=y
CONFIG_USB_NOP_XCEIV=y
CONFIG_FS_EXT4=y
CONFIG_FS_TFTP=y
CONFIG_FS_NFS=y
CONFIG_FS_FAT=y
CONFIG_FS_FAT_WRITE=y
CONFIG_FS_FAT_LFN=y
CONFIG_FS_UBIFS=y
CONFIG_FS_UBIFS_COMPRESSION_LZO=y
CONFIG_PNG=y

View File

@ -34,6 +34,10 @@ ifeq ($(CONFIG_MMU),)
obj-y += no-mmu.o
endif
obj-$(CONFIG_ARM_PSCI) += psci.o
obj-$(CONFIG_ARM_SECURE_MONITOR) += smccc-call.o
obj-$(CONFIG_ARM_SECURE_MONITOR) += sm.o sm_as.o
obj-$(CONFIG_CPU_32v4T) += cache-armv4.o
pbl-$(CONFIG_CPU_32v4T) += cache-armv4.o
obj-$(CONFIG_CPU_32v5) += cache-armv5.o

311
arch/arm/cpu/psci.c Normal file
View File

@ -0,0 +1,311 @@
/*
* 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; version 2.
*
* 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.
*/
#define pr_fmt(fmt) "psci: " fmt
#include <common.h>
#include <asm/psci.h>
#include <asm/arm-smccc.h>
#include <asm/secure.h>
#include <asm/system.h>
#include <restart.h>
#include <globalvar.h>
#include <init.h>
#include <magicvar.h>
#ifdef CONFIG_ARM_PSCI_DEBUG
/*
* PSCI debugging functions. Board code can specify a putc() function
* which is used for debugging output. Beware that this function is
* called while the kernel is running. This means the kernel could have
* turned off clocks, configured other baudrates and other stuff that
* might confuse the putc function. So it can well be that the debugging
* code itself is the problem when somethings not working. You have been
* warned.
*/
static void (*__putc)(void *ctx, int c);
static void *putc_ctx;
void psci_set_putc(void (*putcf)(void *ctx, int c), void *ctx)
{
__putc = putcf;
putc_ctx = ctx;
}
void psci_putc(char c)
{
if (__putc)
__putc(putc_ctx, c);
}
int psci_puts(const char *str)
{
int n = 0;
while (*str) {
if (*str == '\n')
psci_putc('\r');
psci_putc(*str);
str++;
n++;
}
return n;
}
int psci_printf(const char *fmt, ...)
{
va_list args;
uint i;
char printbuffer[128];
va_start(args, fmt);
i = vsprintf(printbuffer, fmt, args);
va_end(args);
psci_puts(printbuffer);
return i;
}
#endif
static struct psci_ops *psci_ops;
void psci_set_ops(struct psci_ops *ops)
{
psci_ops = ops;
}
static unsigned long psci_version(void)
{
psci_printf("%s\n", __func__);
return ARM_PSCI_VER_1_0;
}
static unsigned long psci_cpu_suspend(u32 power_state, unsigned long entry,
u32 context_id)
{
psci_printf("%s\n", __func__);
if (psci_ops->cpu_off)
return psci_ops->cpu_suspend(power_state, entry, context_id);
return ARM_PSCI_RET_NOT_SUPPORTED;
}
static unsigned long psci_cpu_off(void)
{
psci_printf("%s\n", __func__);
if (psci_ops->cpu_off)
return psci_ops->cpu_off();
return ARM_PSCI_RET_NOT_SUPPORTED;
}
static unsigned long cpu_entry[ARM_SECURE_MAX_CPU];
static unsigned long context[ARM_SECURE_MAX_CPU];
static unsigned long psci_cpu_on(u32 cpu_id, unsigned long entry, u32 context_id)
{
psci_printf("%s: %d 0x%08lx\n", __func__, cpu_id, entry);
if (cpu_id >= ARM_SECURE_MAX_CPU)
return ARM_PSCI_RET_INVAL;
cpu_entry[cpu_id] = entry;
context[cpu_id] = context_id;
dsb();
if (psci_ops->cpu_on)
return psci_ops->cpu_on(cpu_id);
return ARM_PSCI_RET_NOT_SUPPORTED;
}
static unsigned long psci_system_off(void)
{
psci_printf("%s\n", __func__);
if (psci_ops->system_reset)
psci_ops->system_reset();
while(1);
return 0;
}
static unsigned long psci_system_reset(void)
{
psci_printf("%s\n", __func__);
if (psci_ops->system_reset)
psci_ops->system_reset();
restart_machine();
}
void psci_entry(u32 r0, u32 r1, u32 r2, u32 r3, u32 r4, u32 r5, u32 r6,
struct arm_smccc_res *res)
{
int mmuon;
unsigned long ttb;
mmuon = get_cr() & CR_M;
asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ttb));
psci_printf("%s entry, function: 0x%08x\n", __func__, r0);
switch (r0) {
case ARM_PSCI_0_2_FN_PSCI_VERSION:
res->a0 = psci_version();
break;
case ARM_PSCI_0_2_FN_CPU_SUSPEND:
res->a0 = psci_cpu_suspend(r1, r2, r3);
break;
case ARM_PSCI_0_2_FN_CPU_OFF:
res->a0 = psci_cpu_off();
break;
case ARM_PSCI_0_2_FN_CPU_ON:
res->a0 = psci_cpu_on(r1, r2, r3);
break;
case ARM_PSCI_0_2_FN_SYSTEM_OFF:
psci_system_off();
break;
case ARM_PSCI_0_2_FN_SYSTEM_RESET:
psci_system_reset();
break;
default:
res->a0 = ARM_PSCI_RET_NOT_SUPPORTED;
break;
}
}
static int of_psci_fixup(struct device_node *root, void *unused)
{
struct device_node *psci;
int ret;
if (bootm_arm_security_state() < ARM_STATE_NONSECURE)
return 0;
psci = of_create_node(root, "/psci");
if (!psci)
return -EINVAL;
ret = of_set_property(psci, "compatible", "arm,psci-1.0",
strlen("arm,psci-1.0") + 1, 1);
if (ret)
return ret;
ret = of_set_property(psci, "method", "smc",
strlen("smc") + 1, 1);
if (ret)
return ret;
return 0;
}
int psci_cpu_entry_c(void)
{
void (*entry)(u32 context);
int cpu;
u32 context_id;
__armv7_secure_monitor_install();
cpu = psci_get_cpu_id();
entry = (void *)cpu_entry[cpu];
context_id = context[cpu];
if (bootm_arm_security_state() == ARM_STATE_HYP)
armv7_switch_to_hyp();
psci_printf("core #%d enter function 0x%p\n", cpu, entry);
entry(context_id);
while (1);
}
static int armv7_psci_init(void)
{
return of_register_fixup(of_psci_fixup, NULL);
}
device_initcall(armv7_psci_init);
#ifdef DEBUG
#include <command.h>
#include <getopt.h>
#include "mmu.h"
void second_entry(void)
{
struct arm_smccc_res res;
psci_printf("2nd CPU online, now turn off again\n");
arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_OFF,
0, 0, 0, 0, 0, 0, 0, &res);
psci_printf("2nd CPU still alive?\n");
while (1);
}
static int do_smc(int argc, char *argv[])
{
int opt;
struct arm_smccc_res res = {
.a0 = 0xdeadbee0,
.a1 = 0xdeadbee1,
.a2 = 0xdeadbee2,
.a3 = 0xdeadbee3,
};
while ((opt = getopt(argc, argv, "nicz")) > 0) {
switch (opt) {
case 'n':
armv7_secure_monitor_install();
break;
case 'i':
arm_smccc_smc(ARM_PSCI_0_2_FN_PSCI_VERSION,
0, 0, 0, 0, 0, 0, 0, &res);
printf("found psci version %ld.%ld\n", res.a0 >> 16, res.a0 & 0xffff);
break;
case 'c':
arm_smccc_smc(ARM_PSCI_0_2_FN_CPU_ON,
1, (unsigned long)second_entry, 0, 0, 0, 0, 0, &res);
break;
}
}
return 0;
}
BAREBOX_CMD_HELP_START(smc)
BAREBOX_CMD_HELP_TEXT("Secure monitor code test command")
BAREBOX_CMD_HELP_TEXT("")
BAREBOX_CMD_HELP_TEXT("Options:")
BAREBOX_CMD_HELP_OPT ("-n", "Install secure monitor and switch to nonsecure mode")
BAREBOX_CMD_HELP_OPT ("-i", "Show information about installed PSCI version")
BAREBOX_CMD_HELP_OPT ("-c", "Start secondary CPU core")
BAREBOX_CMD_HELP_OPT ("-z", "Turn off secondary CPU core")
BAREBOX_CMD_HELP_END
BAREBOX_CMD_START(smc)
.cmd = do_smc,
BAREBOX_CMD_DESC("secure monitor test command")
BAREBOX_CMD_END
#endif

266
arch/arm/cpu/sm.c Normal file
View File

@ -0,0 +1,266 @@
/*
* (C) Copyright 2013
* Andre Przywara, Linaro <andre.przywara@linaro.org>
*
* Routines to transition ARMv7 processors from secure into non-secure state
* and from non-secure SVC into HYP mode
* needed to enable ARMv7 virtualization for current hypervisors
*
* SPDX-License-Identifier: GPL-2.0+
*/
#define pr_fmt(fmt) "secure: " fmt
#include <common.h>
#include <io.h>
#include <asm/gic.h>
#include <asm/system.h>
#include <init.h>
#include <globalvar.h>
#include <asm/arm-smccc.h>
#include <asm-generic/sections.h>
#include <asm/secure.h>
#include "mmu.h"
/* valid bits in CBAR register / PERIPHBASE value */
#define CBAR_MASK 0xFFFF8000
static unsigned int read_id_pfr1(void)
{
unsigned int reg;
asm("mrc p15, 0, %0, c0, c1, 1\n" : "=r"(reg));
return reg;
}
static u32 read_nsacr(void)
{
unsigned int reg;
asm("mrc p15, 0, %0, c1, c1, 2\n" : "=r"(reg));
return reg;
}
static void write_nsacr(u32 val)
{
asm("mcr p15, 0, %0, c1, c1, 2" : : "r"(val));
}
static void write_mvbar(u32 val)
{
asm("mcr p15, 0, %0, c12, c0, 1" : : "r"(val));
}
static unsigned long get_cbar(void)
{
unsigned periphbase;
/* get the GIC base address from the CBAR register */
asm("mrc p15, 4, %0, c15, c0, 0\n" : "=r" (periphbase));
/* the PERIPHBASE can be mapped above 4 GB (lower 8 bits used to
* encode this). Bail out here since we cannot access this without
* enabling paging.
*/
if ((periphbase & 0xff) != 0) {
pr_err("PERIPHBASE is above 4 GB, no access.\n");
return -1;
}
return periphbase & CBAR_MASK;
}
static unsigned long get_gicd_base_address(void)
{
return get_cbar() + GIC_DIST_OFFSET;
}
static int cpu_is_virt_capable(void)
{
return read_id_pfr1() & (1 << 12);
}
static unsigned long get_gicc_base_address(void)
{
unsigned long adr = get_cbar();
if (cpu_is_virt_capable())
adr += GIC_CPU_OFFSET_A15;
else
adr += GIC_CPU_OFFSET_A9;
return adr;
}
#define GICD_IGROUPRn 0x0080
int armv7_init_nonsec(void)
{
void __iomem *gicd = IOMEM(get_gicd_base_address());
unsigned itlinesnr, i;
u32 val;
/*
* the SCR register will be set directly in the monitor mode handler,
* according to the spec one should not tinker with it in secure state
* in SVC mode. Do not try to read it once in non-secure state,
* any access to it will trap.
*/
/* enable the GIC distributor */
val = readl(gicd + GICD_CTLR);
val |= 0x3;
writel(val, gicd + GICD_CTLR);
/* TYPER[4:0] contains an encoded number of available interrupts */
itlinesnr = readl(gicd + GICD_TYPER) & 0x1f;
/*
* Set all bits in the GIC group registers to one to allow access
* from non-secure state. The first 32 interrupts are private per
* CPU and will be set later when enabling the GIC for each core
*/
for (i = 1; i <= itlinesnr; i++)
writel(0xffffffff, gicd + GICD_IGROUPRn + 4 * i);
return 0;
}
/*
* armv7_secure_monitor_install - install secure monitor
*
* This function is entered in secure mode. It installs the secure
* monitor code and enters it using a smc call. This function is executed
* on every CPU. We leave this function returns in nonsecure mode.
*/
int __armv7_secure_monitor_install(void)
{
struct arm_smccc_res res;
void __iomem *gicd = IOMEM(get_gicd_base_address());
void __iomem *gicc = IOMEM(get_gicc_base_address());
u32 nsacr;
writel(0xffffffff, gicd + GICD_IGROUPRn);
writel(0x3, gicc + GICC_CTLR);
writel(0xff, gicc + GICC_PMR);
nsacr = read_nsacr();
nsacr |= 0x00043fff; /* all copros allowed in non-secure mode */
write_nsacr(nsacr);
write_mvbar((unsigned long)secure_monitor_init_vectors);
isb();
/* Initialize the secure monitor */
arm_smccc_smc(0, 0, 0, 0, 0, 0, 0, 0, &res);
/* We're in nonsecure mode now */
return 0;
}
static bool armv7_have_security_extensions(void)
{
return (read_id_pfr1() & 0xf0) != 0;
}
/*
* armv7_secure_monitor_install - install secure monitor
*
* This function is entered in secure mode. It installs the secure
* monitor code and enters it using a smc call. This function is executed
* once on the primary CPU only. We leave this function returns in nonsecure
* mode.
*/
int armv7_secure_monitor_install(void)
{
int mmuon;
unsigned long ttb, vbar;
if (!armv7_have_security_extensions()) {
pr_err("Security extensions not implemented.\n");
return -EINVAL;
}
mmuon = get_cr() & CR_M;
vbar = get_vbar();
asm volatile ("mrc p15, 0, %0, c2, c0, 0" : "=r"(ttb));
armv7_init_nonsec();
__armv7_secure_monitor_install();
asm volatile ("mcr p15, 0, %0, c2, c0, 0" : : "r"(ttb));
set_vbar(vbar);
if (mmuon) {
/*
* If the MMU was already turned on in secure mode, enable it in
* non-secure mode aswell
*/
__mmu_cache_on();
}
pr_debug("Initialized secure monitor\n");
return 0;
}
/*
* of_secure_monitor_fixup - reserve memory region for secure monitor
*
* We currently do not support putting the secure monitor into onchip RAM,
* hence it runs in SDRAM and we must reserve the memory region so that we
* won't get overwritten from the Kernel.
* Beware: despite the name this is not secure in any way. The Kernel obeys
* the reserve map, but only because it's nice. It could always overwrite the
* secure monitor and hijack secure mode.
*/
static int of_secure_monitor_fixup(struct device_node *root, void *unused)
{
unsigned long res_start, res_end;
res_start = (unsigned long)_stext;
res_end = (unsigned long)__bss_stop;
of_add_reserve_entry(res_start, res_end);
pr_debug("Reserved memory range from 0x%08lx to 0x%08lx\n", res_start, res_end);
return 0;
}
static enum arm_security_state bootm_secure_state;
static const char * const bootm_secure_state_names[] = {
[ARM_STATE_SECURE] = "secure",
[ARM_STATE_NONSECURE] = "nonsecure",
[ARM_STATE_HYP] = "hyp",
};
enum arm_security_state bootm_arm_security_state(void)
{
return bootm_secure_state;
}
const char *bootm_arm_security_state_name(enum arm_security_state state)
{
return bootm_secure_state_names[state];
}
static int sm_init(void)
{
of_register_fixup(of_secure_monitor_fixup, NULL);
globalvar_add_simple_enum("bootm.secure_state",
(unsigned int *)&bootm_secure_state,
bootm_secure_state_names,
ARRAY_SIZE(bootm_secure_state_names));
return 0;
}
device_initcall(sm_init);

168
arch/arm/cpu/sm_as.S Normal file
View File

@ -0,0 +1,168 @@
#include <linux/linkage.h>
#include <asm/ptrace.h>
#include <asm-generic/memory_layout.h>
#include <asm/secure.h>
#include <asm/system.h>
.arch_extension sec
.arch_extension virt
.section ".text","ax"
.arm
.align 5
.globl secure_monitor_init_vectors
secure_monitor_init_vectors:
1: b 1b /* reset */
1: b 1b /* undefined instruction */
b secure_monitor_init /* software interrupt (SWI) */
1: b 1b /* prefetch abort */
1: b 1b /* data abort */
1: b 1b /* (reserved) */
1: b 1b /* irq (interrupt) */
1: b 1b /* fiq (fast interrupt) */
#define CPUID_ARM_GENTIMER_MASK (0xF << CPUID_ARM_GENTIMER_SHIFT)
#define CPUID_ARM_GENTIMER_SHIFT 16
#define CPUID_ARM_VIRT_MASK (0xF << CPUID_ARM_VIRT_SHIFT)
#define CPUID_ARM_VIRT_SHIFT 12
.macro is_cpu_virt_capable tmp
mrc p15, 0, \tmp, c0, c1, 1 @ read ID_PFR1
and \tmp, \tmp, #CPUID_ARM_VIRT_MASK @ mask virtualization bits
cmp \tmp, #(1 << CPUID_ARM_VIRT_SHIFT)
.endm
@ Requires dense and single-cluster CPU ID space
ENTRY(psci_get_cpu_id)
mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
and r0, r0, #0xff /* return CPU ID in cluster */
bx lr
ENDPROC(psci_get_cpu_id)
ENTRY(secure_monitor_stack_setup)
mrc p15, 0, r0, c0, c0, 5 /* read MPIDR */
and r0, r0, #0xff /* CPU ID => r0 */
@ stack top = __secure_stack_end - (cpuid << ARM_PSCI_STACK_SHIFT)
ldr r1, =__secure_stack_end
sub r0, r1, r0, LSL #ARM_SECURE_STACK_SHIFT
sub r0, r0, #4 @ Save space for target PC
mov sp, r0
bx lr
ENDPROC(secure_monitor_stack_setup)
secure_monitor_init:
mov r3, lr
bl secure_monitor_stack_setup
push {r4-r7}
mov r7, r3
ldr r5, =secure_monitor_vectors @ Switch MVBAR to secure_monitor_vectors
mcr p15, 0, r5, c12, c0, 1
isb
#ifdef CONFIG_MMU
mrc p15, 0, r5, c1, c0, 0
tst r5, #CR_M
beq 1f
bl __mmu_cache_off
1:
#endif
mrc p15, 0, r5, c1, c1, 0 @ read SCR
bic r5, r5, #0x4a @ clear IRQ, EA, nET bits
orr r5, r5, #0x31 @ enable NS, AW, FW bits
@ FIQ preserved for secure mode
mov r6, #SVC_MODE @ default mode is SVC
is_cpu_virt_capable r4
orreq r5, r5, #0x100 @ allow HVC instruction
mcr p15, 0, r5, c1, c1, 0 @ write SCR (with NS bit set)
isb
mrceq p15, 0, r0, c12, c0, 1 @ get MVBAR value
mcreq p15, 4, r0, c12, c0, 0 @ write HVBAR
bne 1f
@ Reset CNTVOFF to 0 before leaving monitor mode
mrc p15, 0, r4, c0, c1, 1 @ read ID_PFR1
ands r4, r4, #CPUID_ARM_GENTIMER_MASK @ test arch timer bits
movne r4, #0
mcrrne p15, 4, r4, r4, c14 @ Reset CNTVOFF to zero
1:
mov lr, r7
mov ip, #(PSR_F_BIT | PSR_I_BIT | PSR_A_BIT) @ Set A, I and F
tst lr, #1 @ Check for Thumb PC
orrne ip, ip, #PSR_T_BIT @ Set T if Thumb
orr ip, ip, r6 @ Slot target mode in
msr spsr_cxfs, ip @ Set full SPSR
pop {r4-r7}
movs pc, lr @ ERET to non-secure
.align 5
secure_monitor_vectors:
1: b 1b /* reset */
1: b 1b /* undefined instruction */
b secure_monitor /* software interrupt (SWI) */
1: b 1b /* prefetch abort */
1: b 1b /* data abort */
1: b hyp_trap /* (reserved) */
1: b 1b /* irq (interrupt) */
1: b 1b /* fiq (fast interrupt) */
secure_monitor:
push {r4-r7,lr}
@ Switch to secure mode
mrc p15, 0, r7, c1, c1, 0
bic r4, r7, #1
mcr p15, 0, r4, c1, c1, 0
isb
/* r0-r6: Arguments */
sub sp, sp, #4*4 @ allocate result structure on stack
mov r12, sp
push {r4-r6, r12}
bl psci_entry
pop {r4-r6, r12}
ldm r12, {r0-r3}
add sp, sp, #4*4
/* r0-r3: results, r4-r14: preserved */
@ back to non-secure
mcr p15, 0, r7, c1, c1, 0
pop {r4-r7, lr}
movs pc, lr
hyp_trap:
mrs lr, elr_hyp @ for older asm: .byte 0x00, 0xe3, 0x0e, 0xe1
mov pc, lr @ do no switch modes, but
@ return to caller
ENTRY(armv7_switch_to_hyp)
mov r0, lr
mov r1, sp @ save SVC copy of LR and SP
isb
hvc #0 @ for older asm: .byte 0x70, 0x00, 0x40, 0xe1
mov sp, r1
mov lr, r0 @ restore SVC copy of LR and SP
bx lr
ENDPROC(armv7_switch_to_hyp)
ENTRY(psci_cpu_entry)
mrc p15, 0, r0, c1, c0, 1 @ ACTLR
orr r0, r0, #(1 << 6) @ Set SMP bit
mcr p15, 0, r0, c1, c0, 1 @ ACTLR
bl secure_monitor_stack_setup
bl psci_cpu_entry_c
ENDPROC(psci_cpu_entry)

64
arch/arm/cpu/smccc-call.S Normal file
View File

@ -0,0 +1,64 @@
/*
* Copyright (c) 2015, Linaro Limited
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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 <linux/linkage.h>
#include <asm/unwind.h>
.arch_extension sec
.arch_extension virt
.arm
/*
* Wrap c macros in asm macros to delay expansion until after the
* SMCCC asm macro is expanded.
*/
.macro SMCCC_SMC
smc #0
.endm
.macro SMCCC_HVC
hvc #0
.endm
.macro SMCCC instr
UNWIND( .fnstart)
mov r12, sp
push {r4-r7}
UNWIND( .save {r4-r7})
ldm r12, {r4-r7}
\instr
pop {r4-r7}
ldr r12, [sp, #(4 * 4)]
stm r12, {r0-r3}
bx lr
UNWIND( .fnend)
.endm
/*
* void smccc_smc(unsigned long a0, unsigned long a1, unsigned long a2,
* unsigned long a3, unsigned long a4, unsigned long a5,
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
*/
ENTRY(arm_smccc_smc)
SMCCC SMCCC_SMC
ENDPROC(arm_smccc_smc)
/*
* void smccc_hvc(unsigned long a0, unsigned long a1, unsigned long a2,
* unsigned long a3, unsigned long a4, unsigned long a5,
* unsigned long a6, unsigned long a7, struct arm_smccc_res *res)
*/
ENTRY(arm_smccc_hvc)
SMCCC SMCCC_HVC
ENDPROC(arm_smccc_hvc)

View File

@ -79,6 +79,15 @@ pbl-dtb-$(CONFIG_MACH_UDOO) += imx6q-udoo.dtb.o
pbl-dtb-$(CONFIG_MACH_USI_TOPKICK) += kirkwood-topkick-bb.dtb.o
pbl-dtb-$(CONFIG_MACH_VARISCITE_MX6) += imx6q-var-custom.dtb.o
pbl-dtb-$(CONFIG_MACH_VSCOM_BALTOS) += am335x-baltos-minimal.dtb.o
pbl-dtb-$(CONFIG_MACH_WARP7) += imx7s-warp.dtb.o
pbl-dtb-$(CONFIG_MACH_VF610_TWR) += vf610-twr.dtb.o
pbl-dtb-$(CONFIG_MACH_ZII_RDU2) += imx6q-zii-rdu2.dtb.o imx6qp-zii-rdu2.dtb.o
pbl-dtb-$(CONFIG_MACH_ZII_VF610_DEV) += \
vf610-zii-dev-rev-b.dtb.o \
vf610-zii-dev-rev-c.dtb.o \
vf610-zii-cfu1-rev-a.dtb.o \
vf610-zii-spu3-rev-a.dtb.o \
vf610-zii-scu4-aib-rev-c.dtb.o
clean-files := *.dtb *.dtb.S .*.dtc .*.pre .*.dts *.dtb.lzo

View File

@ -0,0 +1,52 @@
/*
* Copyright 2016 Zodiac Inflight Innovations
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include <arm/imx6q.dtsi>
#include "imx6q.dtsi"
#include "imx6qdl-zii-rdu2.dtsi"
/ {
model = "ZII RDU2 Board";
compatible = "zii,imx6q-zii-rdu2", "fsl,imx6q";
};

View File

@ -0,0 +1,541 @@
/*
* Copyright 2016 Zodiac Inflight Innovations
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <dt-bindings/gpio/gpio.h>
#include <dt-bindings/input/input.h>
/ {
chosen {
linux,stdout-path = &uart1;
environment@0 {
compatible = "barebox,environment";
device-path = &nor_flash, "partname:barebox-environment";
};
};
mdio {
compatible = "virtual,mdio-gpio";
#address-cells = <1>;
#size-cells = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_mdio1>;
gpios = <&gpio6 5 GPIO_ACTIVE_HIGH
&gpio6 4 GPIO_ACTIVE_HIGH>;
};
reg_28p0v: 28p0v {
/* main power in */
compatible = "regulator-fixed";
regulator-name = "28P0V";
regulator-min-microvolt = <28000000>;
regulator-max-microvolt = <28000000>;
regulator-always-on;
};
reg_12p0v: 12p0v {
/* main internal power */
compatible = "regulator-fixed";
vin-supply = <&reg_28p0v>;
regulator-name = "12P0V";
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
regulator-always-on;
};
reg_12p0v_periph: 12p0vperiph {
compatible = "regulator-fixed";
vin-supply = <&reg_28p0v>;
regulator-name = "12P0V-PERIPH";
regulator-min-microvolt = <12000000>;
regulator-max-microvolt = <12000000>;
/* controlled via "environment processor" */
regulator-always-on;
};
reg_5p0v_main: 5p0vmain {
compatible = "regulator-fixed";
vin-supply = <&reg_12p0v>;
regulator-name = "5P0MAIN";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
/* controlled via "environment processor" */
regulator-always-on;
};
reg_usb_otg_vbus: regulator@0 {
compatible = "regulator-fixed";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usb_otg_supply>;
vin-supply = <&reg_5p0v_main>;
regulator-name = "usb_otg_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
gpio = <&gpio3 22 GPIO_ACTIVE_LOW>;
startup-delay-us = <1000>;
};
reg_usb_h1_vbus: regulator@1 {
compatible = "regulator-fixed";
vin-supply = <&reg_5p0v_main>;
regulator-name = "usb_h1_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
};
};
&iomuxc {
pinctrl-names = "default";
imx6qdl-sabresd {
pinctrl_hog: hoggrp {
fsl,pins = <
/* USB Charging Controller */
MX6QDL_PAD_EIM_A25__GPIO5_IO02 0x1b0b0 /*USB_ATT_DETn*/
MX6QDL_PAD_EIM_D19__GPIO3_IO19 0x1b0b0 /*USB_EMULATION*/
MX6QDL_PAD_EIM_D20__GPIO3_IO20 0x1b0b0 /*USB_MODE1*/
MX6QDL_PAD_EIM_D21__GPIO3_IO21 0x1b0b0 /*USB_ALERTn*/
MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x1b0b0 /*USB_PWR_CTRL_ENn*/
MX6QDL_PAD_EIM_D23__GPIO3_IO23 0x1b0b0 /*USB_MODE2*/
MX6QDL_PAD_GPIO_1__USB_OTG_ID 0x13020 /*USB_OTG_ID*/
MX6QDL_PAD_GPIO_8__GPIO1_IO08 0x1b0b0 /*INT_TOUCH_N*/
/* DAC */
MX6QDL_PAD_GPIO_0__GPIO1_IO00 0x1b0b0 /*DAC1_RESET*/
MX6QDL_PAD_GPIO_2__GPIO1_IO02 0x1b0b0 /*DAC2_RESET*/
/* Need to Place */
MX6QDL_PAD_EIM_D30__GPIO3_IO30 0x1b0b0 /*RMII_INTRPT*/
MX6QDL_PAD_SD3_RST__GPIO7_IO08 0x1b8b0 /*SD_CARD_RESET - Open Drain Output*/
/* Test Points */
MX6QDL_PAD_SD3_DAT4__GPIO7_IO01 0x1b0b0 /*TP20*/
MX6QDL_PAD_SD3_DAT5__GPIO7_IO00 0x1b0b0 /*TP21*/
MX6QDL_PAD_SD3_DAT6__GPIO6_IO18 0x1b0b0 /*TP22*/
MX6QDL_PAD_SD3_DAT7__GPIO6_IO17 0x1b0b0 /*TP23*/
MX6QDL_PAD_KEY_ROW2__GPIO4_IO11 0x1b0b0 /*TP19*/
MX6QDL_PAD_NANDF_CS1__GPIO6_IO14 0x1b0b0 /*TP26*/
MX6QDL_PAD_NANDF_D4__GPIO2_IO04 0x1b0b0 /*TP27*/
MX6QDL_PAD_NANDF_D5__GPIO2_IO05 0x1b0b0 /*TP28*/
MX6QDL_PAD_NANDF_D6__GPIO2_IO06 0x1b0b0 /*TP29*/
MX6QDL_PAD_NANDF_D7__GPIO2_IO07 0x1b0b0 /*TP30*/
MX6QDL_PAD_EIM_BCLK__GPIO6_IO31 0x1b0b0 /*TP25*/
MX6QDL_PAD_CSI0_MCLK__GPIO5_IO19 0x1b0b0 /*TP39*/
MX6QDL_PAD_CSI0_PIXCLK__GPIO5_IO18 0x1b0b0 /*TP40*/
MX6QDL_PAD_CSI0_VSYNC__GPIO5_IO21 0x1b0b0 /*TP42*/
MX6QDL_PAD_CSI0_DATA_EN__GPIO5_IO20 0x1b0b0 /*TP43*/
MX6QDL_PAD_CSI0_DAT14__GPIO6_IO00 0x1b0b0 /*TP44*/
MX6QDL_PAD_CSI0_DAT15__GPIO6_IO01 0x1b0b0 /*TP45*/
MX6QDL_PAD_CSI0_DAT16__GPIO6_IO02 0x1b0b0 /*TP46*/
MX6QDL_PAD_DI0_PIN4__GPIO4_IO20 0x1b0b0 /*TP41*/
/* System Type */
MX6QDL_PAD_EIM_D26__GPIO3_IO26 0x1b0b0 /*SYS_TYPE_3*/
MX6QDL_PAD_EIM_D27__GPIO3_IO27 0x1b0b0 /*SYS_TYPE_2*/
MX6QDL_PAD_EIM_D28__GPIO3_IO28 0x1b0b0 /*SYS_TYPE_1*/
MX6QDL_PAD_EIM_D29__GPIO3_IO29 0x1b0b0 /*SYS_TYPE_0*/
/* Boot Mode Selection Pins */
MX6QDL_PAD_EIM_DA0__GPIO3_IO00 0x1b0b0 /*BT_CFG1_0*/
MX6QDL_PAD_EIM_DA1__GPIO3_IO01 0x1b0b0 /*BT_CFG1_1*/
MX6QDL_PAD_EIM_DA2__GPIO3_IO02 0x1b0b0 /*BT_CFG1_2*/
MX6QDL_PAD_EIM_DA3__GPIO3_IO03 0x1b0b0 /*BT_CFG1_3*/
MX6QDL_PAD_EIM_DA4__GPIO3_IO04 0x1b0b0 /*BT_CFG1_4*/
MX6QDL_PAD_EIM_DA5__GPIO3_IO05 0x1b0b0 /*BT_CFG1_5*/
MX6QDL_PAD_EIM_DA6__GPIO3_IO06 0x1b0b0 /*BT_CFG1_6*/
MX6QDL_PAD_EIM_DA7__GPIO3_IO07 0x1b0b0 /*BT_CFG1_7*/
MX6QDL_PAD_EIM_DA8__GPIO3_IO08 0x1b0b0 /*BT_CFG2_0*/
MX6QDL_PAD_EIM_DA9__GPIO3_IO09 0x1b0b0 /*BT_CFG2_1*/
MX6QDL_PAD_EIM_DA10__GPIO3_IO10 0x1b0b0 /*BT_CFG2_2*/
MX6QDL_PAD_EIM_DA11__GPIO3_IO11 0x1b0b0 /*BT_CFG2_3*/
MX6QDL_PAD_EIM_DA12__GPIO3_IO12 0x1b0b0 /*BT_CFG2_4*/
MX6QDL_PAD_EIM_DA13__GPIO3_IO13 0x1b0b0 /*BT_CFG2_5*/
MX6QDL_PAD_EIM_DA14__GPIO3_IO14 0x1b0b0 /*BT_CFG2_6*/
MX6QDL_PAD_EIM_DA15__GPIO3_IO15 0x1b0b0 /*BT_CFG2_7*/
MX6QDL_PAD_EIM_A16__GPIO2_IO22 0x1b0b0 /*BT_CFG3_0*/
MX6QDL_PAD_EIM_A17__GPIO2_IO21 0x1b0b0 /*BT_CFG3_1*/
MX6QDL_PAD_EIM_A18__GPIO2_IO20 0x1b0b0 /*BT_CFG3_2*/
MX6QDL_PAD_EIM_A19__GPIO2_IO19 0x1b0b0 /*BT_CFG3_3*/
MX6QDL_PAD_EIM_A20__GPIO2_IO18 0x1b0b0 /*BT_CFG3_4*/
MX6QDL_PAD_EIM_A21__GPIO2_IO17 0x1b0b0 /*BT_CFG3_5*/
MX6QDL_PAD_EIM_A22__GPIO2_IO16 0x1b0b0 /*BT_CFG3_6*/
MX6QDL_PAD_EIM_A23__GPIO6_IO06 0x1b0b0 /*BT_CFG3_7*/
MX6QDL_PAD_EIM_A24__GPIO5_IO04 0x1b0b0 /*BT_CFG4_0*/
MX6QDL_PAD_EIM_WAIT__GPIO5_IO00 0x1b0b0 /*BT_CFG4_1*/
MX6QDL_PAD_EIM_LBA__GPIO2_IO27 0x1b0b0 /*BT_CFG4_2*/
MX6QDL_PAD_EIM_EB0__GPIO2_IO28 0x1b0b0 /*BT_CFG4_3*/
MX6QDL_PAD_EIM_EB1__GPIO2_IO29 0x1b0b0 /*BT_CFG4_4*/
MX6QDL_PAD_EIM_RW__GPIO2_IO26 0x1b0b0 /*BT_CFG4_5*/
MX6QDL_PAD_EIM_EB3__GPIO2_IO31 0x1b0b0 /*BT_CFG4_7*/
MX6QDL_PAD_GPIO_4__GPIO1_IO04 0x1b0b0 /* HPA1_SDn */
MX6QDL_PAD_GPIO_5__GPIO1_IO05 0x1b0b0 /* HPA2_SDn */
MX6QDL_PAD_GPIO_7__GPIO1_IO07 0x1b0b0 /* RST_TOUCH# */
MX6QDL_PAD_SD1_DAT1__GPIO1_IO17 0x1b0b0 /* NFC_RESET */
>;
};
pinctrl_usb_otg_supply: usbotggrp {
fsl,pins = <
MX6QDL_PAD_EIM_D22__GPIO3_IO22 0x40000038
>;
};
pinctrl_ecspi1: ecspi1grp {
fsl,pins = <
/*MX6QDL_PAD_EIM_D17__GPIO3_IO17 0x1b0b0*/
MX6QDL_PAD_EIM_D17__ECSPI1_MISO 0x100b1
MX6QDL_PAD_EIM_D18__ECSPI1_MOSI 0x100b1
MX6QDL_PAD_EIM_D16__ECSPI1_SCLK 0x100b1
/*MX6QDL_PAD_EIM_EB2__ECSPI1_SS0 0x100b1*/
MX6QDL_PAD_EIM_EB2__GPIO2_IO30 0x1b0b1
/*MX6QDL_PAD_KEY_COL2__ECSPI1_SS1 0x1b0b1
MX6QDL_PAD_KEY_COL2__GPIO4_IO10*/
>;
};
pinctrl_enet: enetgrp {
fsl,pins = <
MX6QDL_PAD_GPIO_16__ENET_REF_CLK 0x4001b0a8
MX6QDL_PAD_ENET_MDIO__ENET_MDIO 0x1b0b0
MX6QDL_PAD_ENET_MDC__ENET_MDC 0x1b0b0
MX6QDL_PAD_ENET_TXD0__ENET_TX_DATA0 0x1b0b0
MX6QDL_PAD_ENET_TXD1__ENET_TX_DATA1 0x1b0b0
MX6QDL_PAD_ENET_TX_EN__ENET_TX_EN 0x1b0b0
MX6QDL_PAD_ENET_RX_ER__ENET_RX_ER 0x1b0b0
MX6QDL_PAD_ENET_RXD0__ENET_RX_DATA0 0x1b0b0
MX6QDL_PAD_ENET_RXD1__ENET_RX_DATA1 0x1b0b0
MX6QDL_PAD_ENET_CRS_DV__ENET_RX_EN 0x1b0b0
MX6QDL_PAD_ENET_REF_CLK__GPIO1_IO23 0x1b0b0
>;
};
pinctrl_ssi2: ssi3grp {
fsl,pins = <
MX6QDL_PAD_KEY_COL0__AUD5_TXC 0x130b0
MX6QDL_PAD_KEY_ROW0__AUD5_TXD 0x130b0
MX6QDL_PAD_KEY_COL1__AUD5_TXFS 0x130b0
>;
};
pinctrl_i2c1: i2c1grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT8__I2C1_SDA 0x4001b8b1
MX6QDL_PAD_CSI0_DAT9__I2C1_SCL 0x4001b8b1
>;
};
pinctrl_i2c2: i2c2grp {
fsl,pins = <
MX6QDL_PAD_KEY_COL3__I2C2_SCL 0x4001b8b1
MX6QDL_PAD_KEY_ROW3__I2C2_SDA 0x4001b8b1
>;
};
pinctrl_i2c3: i2c3grp {
fsl,pins = <
MX6QDL_PAD_GPIO_3__I2C3_SCL 0x4001b8b1
MX6QDL_PAD_GPIO_6__I2C3_SDA 0x4001b8b1
>;
};
pinctrl_i2c3_gpio: i2c3grp_gpio {
fsl,pins = <
MX6QDL_PAD_GPIO_3__GPIO1_IO03 0x1b0b1
MX6QDL_PAD_GPIO_6__GPIO1_IO06 0x1b0b1
>;
};
pinctrl_pcie: pciegrp {
fsl,pins = <
MX6QDL_PAD_GPIO_17__GPIO7_IO12 0x1b0b0
>;
};
pinctrl_uart1: uart1grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT10__UART1_TX_DATA 0x1b0b1
MX6QDL_PAD_CSI0_DAT11__UART1_RX_DATA 0x1b0b1
>;
};
pinctrl_uart3: uart3grp {
fsl,pins = <
MX6QDL_PAD_EIM_D24__UART3_TX_DATA 0x1b0b1
MX6QDL_PAD_EIM_D25__UART3_RX_DATA 0x1b0b1
>;
};
pinctrl_uart4: uart4grp {
fsl,pins = <
MX6QDL_PAD_CSI0_DAT12__UART4_TX_DATA 0x1b0b1
MX6QDL_PAD_CSI0_DAT13__UART4_RX_DATA 0x1b0b1
>;
};
pinctrl_usdhc2: usdhc2grp {
fsl,pins = <
MX6QDL_PAD_SD2_CMD__SD2_CMD 0x17069
MX6QDL_PAD_SD2_CLK__SD2_CLK 0x17069
MX6QDL_PAD_SD2_DAT0__SD2_DATA0 0x17069
MX6QDL_PAD_SD2_DAT1__SD2_DATA1 0x17069
MX6QDL_PAD_SD2_DAT2__SD2_DATA2 0x17069
MX6QDL_PAD_SD2_DAT3__SD2_DATA3 0x17069
>;
};
pinctrl_usdhc3: usdhc3grp {
fsl,pins = <
MX6QDL_PAD_SD3_CMD__SD3_CMD 0x17069
MX6QDL_PAD_SD3_CLK__SD3_CLK 0x17069
MX6QDL_PAD_SD3_DAT0__SD3_DATA0 0x17069
MX6QDL_PAD_SD3_DAT1__SD3_DATA1 0x17069
MX6QDL_PAD_SD3_DAT2__SD3_DATA2 0x17069
MX6QDL_PAD_SD3_DAT3__SD3_DATA3 0x17069
>;
};
pinctrl_usdhc4: usdhc4grp {
fsl,pins = <
MX6QDL_PAD_SD4_CMD__SD4_CMD 0x17059
MX6QDL_PAD_SD4_CLK__SD4_CLK 0x10059
MX6QDL_PAD_SD4_DAT0__SD4_DATA0 0x17059
MX6QDL_PAD_SD4_DAT1__SD4_DATA1 0x17059
MX6QDL_PAD_SD4_DAT2__SD4_DATA2 0x17059
MX6QDL_PAD_SD4_DAT3__SD4_DATA3 0x17059
MX6QDL_PAD_SD4_DAT4__SD4_DATA4 0x17059
MX6QDL_PAD_SD4_DAT5__SD4_DATA5 0x17059
MX6QDL_PAD_SD4_DAT6__SD4_DATA6 0x17059
MX6QDL_PAD_SD4_DAT7__SD4_DATA7 0x17059
MX6QDL_PAD_NANDF_ALE__SD4_RESET 0x1b0b1
>;
};
pinctrl_mdio1: bitbangmdiogrp {
fsl,pins = <
/* Bitbang MDIO for DEB Switch */
MX6QDL_PAD_CSI0_DAT19__GPIO6_IO05 0x1b030 /*SWITCH_MDC*/
MX6QDL_PAD_CSI0_DAT18__GPIO6_IO04 0x18830 /*SWITCH_MDIO*/
>;
};
};
};
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
status = "okay";
};
&uart4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart4>;
status = "okay";
};
&ecspi1 {
fsl,spi-num-chipselects = <1>;
cs-gpios = <&gpio2 30 0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_ecspi1>;
status = "okay";
nor_flash: m25p128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p128";
spi-max-frequency = <20000000>;
reg = <0>;
partition@0 {
label = "barebox";
reg = <0x0 0xc0000>;
};
partition@e0000 {
label = "barebox-environment";
reg = <0xc0000 0x40000>;
};
};
};
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
};
&tempmon {
barebox,sensor-name = "TEMPMON";
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
lm75@48 {
compatible = "national,lm75";
reg = <0x48>;
barebox,sensor-name = "Temp Sensor 1";
};
rtc: ds1341@68 {
compatible = "dallas,ds1341";
reg = <0x68>;
};
mx6_eeprom: at24@54 {
compatible = "at,24c128";
pagesize = <32>; /* TODO: VERIFY PAGE SIZE */
reg = <0x54>;
};
};
&i2c3 {
clock-frequency = <100000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c3>;
pinctrl-1 = <&pinctrl_i2c3_gpio>;
scl-gpios = <&gpio1 3 GPIO_ACTIVE_HIGH>;
sda-gpios = <&gpio1 6 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&ldb {
status = "okay";
lvds-channel@0 {
fsl,data-mapping = "spwg";
fsl,data-width = <24>;
status = "okay";
display-timings {
native-mode = <&timing_innolux_10_1>;
timing_innolux_10_1: innolux_10_1 {
clock-frequency = <71100000>;
hactive = <1280>;
vactive = <800>;
hback-porch = <40>;
hfront-porch = <40>;
vback-porch = <10>;
vfront-porch = <3>;
hsync-len = <80>;
vsync-len = <10>;
de-active = <1>;
pixelclk-active = <1>;
};
};
};
};
&pcie {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pcie>;
reset-gpio = <&gpio7 12 0>;
status = "okay";
};
&usdhc2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc2>;
bus-width = <4>;
cd-gpios = <&gpio2 2 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio2 3 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&usdhc3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc3>;
bus-width = <4>;
cd-gpios = <&gpio2 0 GPIO_ACTIVE_LOW>;
wp-gpios = <&gpio2 1 GPIO_ACTIVE_HIGH>;
status = "okay";
};
&usdhc4 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_usdhc4>;
bus-width = <8>;
non-removable;
no-1-8-v;
status = "okay";
};
&usbh1 {
vbus-supply = <&reg_usb_h1_vbus>;
status = "okay";
};
&usbotg {
vbus-supply = <&reg_usb_otg_vbus>;
disable-over-current;
dr_mode = "otg";
status = "okay";
};
&sata {
status = "okay";
};
&fec {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_enet>;
phy-mode = "rmii";
phy-reset-gpios = <&gpio1 23 0>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};
};

View File

@ -0,0 +1,52 @@
/*
* Copyright 2016 Zodiac Inflight Innovations
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively,
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include <arm/imx6qp.dtsi>
#include "imx6q.dtsi"
#include "imx6qdl-zii-rdu2.dtsi"
/ {
model = "ZII RDU2+ Board";
compatible = "zii,imx6qp-zii-rdu2", "fsl,imx6qp";
};

View File

@ -0,0 +1,62 @@
/*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <arm/imx7s-warp.dts>
#include "imx7s.dtsi"
/ {
chosen {
stdout-path = &uart1;
environment@0 {
compatible = "barebox,environment";
device-path = &bareboxenv;
};
};
memory {
device_type = "memory";
reg = <0x80000000 0x20000000>;
};
};
&usdhc3 {
boot0-partitions {
compatible = "fixed-partitions";
#address-cells = <1>;
#size-cells = <1>;
barebox@0 {
label = "barebox";
reg = <0x0 0x300000>;
};
bareboxenv: bareboxenv@300000 {
label = "bareboxenv";
reg = <0x300000 0x0>;
};
};
};
/*
/* The watchdog pinctrl is attached to the wrong iomux controller in
* the upstream dts file. This can be removed once we pull in the
* corresponding fix from the upstream dts files.
*/
&wdog1 {
pinctrl-0 = <&pinctrl_wdog_lpsr>;
};
&iomuxc_lpsr {
pinctrl_wdog_lpsr: wdoggrp {
fsl,pins = <
MX7D_PAD_GPIO1_IO00__WDOD1_WDOG_B 0x74
>;
};
};

4
arch/arm/dts/imx7s.dtsi Normal file
View File

@ -0,0 +1,4 @@
&gpt1 {
clocks = <&clks IMX7D_GPT1_ROOT_CLK>,
<&clks IMX7D_GPT1_ROOT_CLK>;
};

View File

@ -0,0 +1,208 @@
/*
* Copyright (C) 2015, 2016 Zodiac Inflight Innovations
*
* Based on an original 'vf610-twr.dts' which is Copyright 2015,
* Freescale Semiconductor, Inc.
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "vf610-zii-dev.dtsi"
/ {
model = "ZII VF610 CFU1 Switch Management Board";
compatible = "zii,vf610cfu1-a", "zii,vf610dev", "fsl,vf610";
aliases {
/delete-property/ serial1;
/delete-property/ serial2;
};
gpio-leds {
debug {
gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>;
};
fail {
label = "zii_fail";
gpios = <&gpio3 12 GPIO_ACTIVE_LOW>;
default-state = "off";
max-brightness = <1>;
};
status {
label = "zii_status";
gpios = <&gpio3 13 GPIO_ACTIVE_HIGH>;
default-state = "off";
max-brightness = <1>;
};
status_a {
label = "zii_status_a";
gpios = <&gpio3 14 GPIO_ACTIVE_HIGH>;
default-state = "off";
max-brightness = <1>;
};
status_b {
label = "zii_status_b";
gpios = <&gpio3 15 GPIO_ACTIVE_HIGH>;
default-state = "on";
max-brightness = <1>;
};
};
};
&dspi1 {
bus-num = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dspi1>;
status = "okay";
m25p128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p128", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
partition@0 {
label = "m25p128-0";
reg = <0x0 0x01000000>;
};
};
};
&esdhc0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc0>;
bus-width = <8>;
status = "okay";
};
&fec0 {
status = "disabled";
};
&i2c0 {
clock-frequency = <400000>;
pca9554@22 {
compatible = "nxp,pca9554";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
};
};
/delete-node/ &i2c1;
/delete-node/ &i2c2;
/delete-node/ &uart1;
/delete-node/ &uart2;
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_hog>;
pinctrl_hog: hoggrp {
fsl,pins = <
VF610_PAD_PTE2__GPIO_107 0x31c2 /* SOC_SW_RSTn */
VF610_PAD_PTB28__GPIO_98 0x31c1 /* E6352_INTn */
/* PTE27 is wired to signal SD on part CONN
* SFF-F4 via net FIM_DS. An active high
* on this indicates a received optical
* signal
* SPEED=0b11 HIGH, SRE=0b0, ODE=0b0, HYS=0b0
* DSE=0b001 150Ohm, PUS=0b10 100k UP
* PKE=0b0, PUE=0b0, OBE=0b0, IBE=0b1
*/
VF610_PAD_PTE27__GPIO_132 0x3061
/*
* PTE13 is wired to signal T_DIS on part CONN
* SFF-F4 via net FIM_TDIS. Setting this high
* will disable optical output from the SFF-F4
* SPEED=0b11 HIGH, SRE=0b0, ODE=0b0, HYS=0b0
* DSE=0b001 150Ohm, PUS=0b00 100k DOWN
* PKE=0b0, PUE=0b0, OBE=0b1, IBE=0b1
* TODO: probably want IBE=0b0
*/
VF610_PAD_PTE13__GPIO_118 0x3043
>;
};
pinctrl_dspi1: dspi1grp {
fsl,pins = <
VF610_PAD_PTD5__DSPI1_CS0 0x1182
VF610_PAD_PTC6__DSPI1_SIN 0x1181
VF610_PAD_PTC7__DSPI1_SOUT 0x1182
VF610_PAD_PTC8__DSPI1_SCK 0x1182
>;
};
pinctrl_esdhc0: esdhc0grp {
fsl,pins = <
VF610_PAD_PTC0__ESDHC0_CLK 0x31ef
VF610_PAD_PTC1__ESDHC0_CMD 0x31ef
VF610_PAD_PTC2__ESDHC0_DAT0 0x31ef
VF610_PAD_PTC3__ESDHC0_DAT1 0x31ef
VF610_PAD_PTC4__ESDHC0_DAT2 0x31ef
VF610_PAD_PTC5__ESDHC0_DAT3 0x31ef
VF610_PAD_PTD23__ESDHC0_DAT4 0x31ef
VF610_PAD_PTD22__ESDHC0_DAT5 0x31ef
VF610_PAD_PTD21__ESDHC0_DAT6 0x31ef
VF610_PAD_PTD20__ESDHC0_DAT7 0x31ef
>;
};
pinctrl_leds_debug: pinctrl-leds-debug {
fsl,pins = <
VF610_PAD_PTD3__GPIO_82 0x31c2
VF610_PAD_PTE3__GPIO_108 0x31c2
VF610_PAD_PTE4__GPIO_109 0x31c2
VF610_PAD_PTE5__GPIO_110 0x31c2
VF610_PAD_PTE6__GPIO_111 0x31c2
>;
};
};

View File

@ -0,0 +1,431 @@
/*
* Copyright (C) 2015, 2016 Zodiac Inflight Innovations
*
* Based on an original 'vf610-twr.dts' which is Copyright 2015,
* Freescale Semiconductor, Inc.
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "vf610-zii-dev.dtsi"
/*
* =============================================================
* The following code is shared with Linux kernel and should be
* removed once it trickles down from there eventually
* =============================================================
*/
/ {
model = "ZII VF610 Development Board, Rev B";
compatible = "zii,vf610dev-b", "zii,vf610dev", "fsl,vf610";
mdio-mux {
compatible = "mdio-mux-gpio";
pinctrl-0 = <&pinctrl_mdio_mux>;
pinctrl-names = "default";
gpios = <&gpio0 8 GPIO_ACTIVE_HIGH
&gpio0 9 GPIO_ACTIVE_HIGH
&gpio0 24 GPIO_ACTIVE_HIGH
&gpio0 25 GPIO_ACTIVE_HIGH>;
mdio-parent-bus = <&mdio1>;
#address-cells = <1>;
#size-cells = <0>;
mdio_mux_1: mdio@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
switch0: switch0@0 {
compatible = "marvell,mv88e6085";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
dsa,member = <0 0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan0";
};
port@1 {
reg = <1>;
label = "lan1";
};
port@2 {
reg = <2>;
label = "lan2";
};
switch0port5: port@5 {
reg = <5>;
label = "dsa";
phy-mode = "rgmii-txid";
link = <&switch1port6
&switch2port9>;
};
port@6 {
reg = <6>;
label = "cpu";
ethernet = <&fec1>;
fixed-link {
speed = <100>;
full-duplex;
};
};
};
};
};
mdio_mux_2: mdio@2 {
reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
switch1: switch1@0 {
compatible = "marvell,mv88e6085";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
dsa,member = <0 1>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan3";
phy-handle = <&switch1phy0>;
};
port@1 {
reg = <1>;
label = "lan4";
phy-handle = <&switch1phy1>;
};
port@2 {
reg = <2>;
label = "lan5";
phy-handle = <&switch1phy2>;
};
switch1port5: port@5 {
reg = <5>;
label = "dsa";
link = <&switch2port9>;
phy-mode = "rgmii-txid";
fixed-link {
speed = <1000>;
full-duplex;
};
};
switch1port6: port@6 {
reg = <6>;
label = "dsa";
phy-mode = "rgmii-txid";
link = <&switch0port5>;
};
};
mdio {
#address-cells = <1>;
#size-cells = <0>;
switch1phy0: switch1phy0@0 {
reg = <0>;
};
switch1phy1: switch1phy0@1 {
reg = <1>;
};
switch1phy2: switch1phy0@2 {
reg = <2>;
};
};
};
};
mdio_mux_4: mdio@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
switch2: switch2@0 {
compatible = "marvell,mv88e6085";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
dsa,member = <0 2>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "lan6";
};
port@1 {
reg = <1>;
label = "lan7";
};
port@2 {
reg = <2>;
label = "lan8";
};
port@3 {
reg = <3>;
label = "optical3";
fixed-link {
speed = <1000>;
full-duplex;
link-gpios = <&gpio6 2
GPIO_ACTIVE_HIGH>;
};
};
port@4 {
reg = <4>;
label = "optical4";
fixed-link {
speed = <1000>;
full-duplex;
link-gpios = <&gpio6 3
GPIO_ACTIVE_HIGH>;
};
};
switch2port9: port@9 {
reg = <9>;
label = "dsa";
phy-mode = "rgmii-txid";
link = <&switch1port5
&switch0port5>;
fixed-link {
speed = <1000>;
full-duplex;
};
};
};
};
};
mdio_mux_8: mdio@8 {
reg = <8>;
#address-cells = <1>;
#size-cells = <0>;
};
};
spi0 {
compatible = "spi-gpio";
pinctrl-0 = <&pinctrl_gpio_spi0>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
gpio-sck = <&gpio1 12 GPIO_ACTIVE_HIGH>;
gpio-mosi = <&gpio1 11 GPIO_ACTIVE_HIGH>;
gpio-miso = <&gpio1 10 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio1 9 GPIO_ACTIVE_HIGH
&gpio1 8 GPIO_ACTIVE_HIGH>;
num-chipselects = <2>;
m25p128@0 {
compatible = "m25p128", "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
spi-max-frequency = <1000000>;
};
at93c46d@1 {
compatible = "atmel,at93c46d";
pinctrl-0 = <&pinctrl_gpio_e6185_eeprom_sel>;
pinctrl-names = "default";
#address-cells = <0>;
#size-cells = <0>;
reg = <1>;
spi-max-frequency = <500000>;
spi-cs-high;
data-size = <16>;
select-gpios = <&gpio4 4 GPIO_ACTIVE_HIGH>;
};
};
};
&i2c0 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c0>;
status = "okay";
gpio5: pca9554@20 {
compatible = "nxp,pca9554";
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
};
gpio6: pca9554@22 {
compatible = "nxp,pca9554";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_pca9554_22>;
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
interrupt-parent = <&gpio2>;
interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
};
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
tca9548@70 {
compatible = "nxp,pca9548";
pinctrl-0 = <&pinctrl_i2c_mux_reset>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
sfp1: at24c04@50 {
compatible = "atmel,24c02";
reg = <0x50>;
};
};
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
sfp2: at24c04@50 {
compatible = "atmel,24c02";
reg = <0x50>;
};
};
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
sfp3: at24c04@50 {
compatible = "atmel,24c02";
reg = <0x50>;
};
};
i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
sfp4: at24c04@50 {
compatible = "atmel,24c02";
reg = <0x50>;
};
};
i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
};
};
};
&iomuxc {
pinctrl_gpio_e6185_eeprom_sel: pinctrl-gpio-e6185-eeprom-spi0 {
fsl,pins = <
VF610_PAD_PTE27__GPIO_132 0x33e2
>;
};
pinctrl_gpio_spi0: pinctrl-gpio-spi0 {
fsl,pins = <
VF610_PAD_PTB22__GPIO_44 0x33e2
VF610_PAD_PTB21__GPIO_43 0x33e2
VF610_PAD_PTB20__GPIO_42 0x33e1
VF610_PAD_PTB19__GPIO_41 0x33e2
VF610_PAD_PTB18__GPIO_40 0x33e2
>;
};
pinctrl_mdio_mux: pinctrl-mdio-mux {
fsl,pins = <
VF610_PAD_PTA18__GPIO_8 0x31c2
VF610_PAD_PTA19__GPIO_9 0x31c2
VF610_PAD_PTB2__GPIO_24 0x31c2
VF610_PAD_PTB3__GPIO_25 0x31c2
>;
};
pinctrl_pca9554_22: pinctrl-pca95540-22 {
fsl,pins = <
VF610_PAD_PTB28__GPIO_98 0x219d
>;
};
};
/*
* =============================================================
* End of shared part
* =============================================================
*/

View File

@ -0,0 +1,445 @@
/*
* Copyright (C) 2015, 2016 Zodiac Inflight Innovations
*
* Based on an original 'vf610-twr.dts' which is Copyright 2015,
* Freescale Semiconductor, Inc.
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "vf610-zii-dev.dtsi"
/*
* =============================================================
* The following code is shared with Linux kernel and should be
* removed once it trickles down from there eventually
* =============================================================
*/
/ {
model = "ZII VF610 Development Board, Rev C";
compatible = "zii,vf610dev-c", "zii,vf610dev", "fsl,vf610";
mdio-mux {
compatible = "mdio-mux-gpio";
pinctrl-0 = <&pinctrl_mdio_mux>;
pinctrl-names = "default";
gpios = <&gpio0 8 GPIO_ACTIVE_HIGH
&gpio0 9 GPIO_ACTIVE_HIGH
&gpio0 25 GPIO_ACTIVE_HIGH>;
mdio-parent-bus = <&mdio1>;
#address-cells = <1>;
#size-cells = <0>;
mdio_mux_1: mdio@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
switch0: switch0@0 {
compatible = "marvell,mv88e6190";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
dsa,member = <0 0>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@0 {
reg = <0>;
label = "cpu";
ethernet = <&fec1>;
fixed-link {
speed = <100>;
full-duplex;
};
};
port@1 {
reg = <1>;
label = "lan1";
};
port@2 {
reg = <2>;
label = "lan2";
};
port@3 {
reg = <3>;
label = "lan3";
};
port@4 {
reg = <4>;
label = "lan4";
};
switch0port10: port@10 {
reg = <10>;
label = "dsa";
phy-mode = "xgmii";
link = <&switch1port10>;
};
};
};
};
mdio_mux_2: mdio@2 {
reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
switch1: switch1@0 {
compatible = "marvell,mv88e6190";
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
dsa,member = <0 1>;
ports {
#address-cells = <1>;
#size-cells = <0>;
port@1 {
reg = <1>;
label = "lan5";
};
port@2 {
reg = <2>;
label = "lan6";
};
port@3 {
reg = <3>;
label = "lan7";
};
port@4 {
reg = <4>;
label = "lan8";
};
switch1port10: port@10 {
reg = <10>;
label = "dsa";
phy-mode = "xgmii";
link = <&switch0port10>;
};
};
};
};
mdio_mux_4: mdio@4 {
reg = <4>;
#address-cells = <1>;
#size-cells = <0>;
};
};
};
&dspi0 {
bus-num = <0>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dspi0>;
status = "okay";
spi-num-chipselects = <2>;
m25p128@0 {
compatible = "m25p128", "jedec,spi-nor";
#address-cells = <1>;
#size-cells = <1>;
reg = <0>;
spi-max-frequency = <50000000>;
};
atzb-rf-233@1 {
compatible = "atmel,at86rf233";
pinctrl-names = "default";
pinctrl-0 = <&pinctr_atzb_rf_233>;
spi-max-frequency = <7500000>;
reg = <1>;
interrupts = <4 IRQ_TYPE_LEVEL_HIGH>;
interrupt-parent = <&gpio3>;
xtal-trim = /bits/ 8 <0x06>;
sleep-gpio = <&gpio0 24 GPIO_ACTIVE_HIGH>;
reset-gpio = <&gpio6 10 GPIO_ACTIVE_HIGH>;
fsl,spi-cs-sck-delay = <180>;
fsl,spi-sck-cs-delay = <250>;
};
};
&dspi2 {
bus-num = <2>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dspi2>;
status = "okay";
spi-num-chipselects = <2>;
};
&i2c0 {
/*
* U712
*
* Exposed signals:
* P1 - WE2_CMD
* P2 - WE2_CLK
*/
gpio5: pca9557@18 {
compatible = "nxp,pca9557";
reg = <0x18>;
gpio-controller;
#gpio-cells = <2>;
};
/*
* U121
*
* Exposed signals:
* I/O0 - ENET_SWR_EN
* I/O1 - ESW1_RESETn
* I/O2 - ARINC_RESET
* I/O3 - DD1_IO_RESET
* I/O4 - ESW2_RESETn
* I/O5 - ESW3_RESETn
* I/O6 - ESW4_RESETn
* I/O8 - TP909
* I/O9 - FEM_SEL
* I/O10 - WIFI_RESETn
* I/O11 - PHY_RSTn
* I/O12 - OPT1_SD
* I/O13 - OPT2_SD
* I/O14 - OPT1_TX_DIS
* I/O15 - OPT2_TX_DIS
*/
gpio6: sx1503@20 {
compatible = "semtech,sx1503q";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_sx1503_20>;
#gpio-cells = <2>;
#interrupt-cells = <2>;
reg = <0x20>;
interrupt-parent = <&gpio0>;
interrupts = <23 IRQ_TYPE_EDGE_FALLING>;
gpio-controller;
interrupt-controller;
enet_swr_en {
gpio-hog;
gpios = <0 GPIO_ACTIVE_HIGH>;
output-high;
line-name = "enet-swr-en";
};
};
/*
* U715
*
* Exposed signals:
* IO0 - WE1_CLK
* IO1 - WE1_CMD
*/
gpio7: pca9554@22 {
compatible = "nxp,pca9554";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
};
};
&i2c1 {
at24mac602@00 {
compatible = "atmel,24c02";
reg = <0x50>;
read-only;
};
};
&i2c2 {
tca9548@70 {
compatible = "nxp,pca9548";
pinctrl-0 = <&pinctrl_i2c_mux_reset>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
reset-gpios = <&gpio3 23 GPIO_ACTIVE_LOW>;
i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
reg = <0>;
};
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
sfp2: at24c04@50 {
compatible = "atmel,24c02";
reg = <0x50>;
};
};
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
sfp3: at24c04@50 {
compatible = "atmel,24c02";
reg = <0x50>;
};
};
i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
};
};
};
&uart3 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart3>;
status = "okay";
};
&gpio0 {
eth0_intrp {
gpio-hog;
gpios = <23 GPIO_ACTIVE_HIGH>;
input;
line-name = "sx1503-irq";
};
};
&gpio3 {
eth0_intrp {
gpio-hog;
gpios = <2 GPIO_ACTIVE_HIGH>;
input;
line-name = "eth0-intrp";
};
};
&fec0 {
mdio {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
ethernet-phy@0 {
compatible = "ethernet-phy-ieee802.3-c22";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec0_phy_int>;
interrupt-parent = <&gpio3>;
interrupts = <2 IRQ_TYPE_LEVEL_LOW>;
reg = <0>;
};
};
};
&iomuxc {
pinctr_atzb_rf_233: pinctrl-atzb-rf-233 {
fsl,pins = <
VF610_PAD_PTB2__GPIO_24 0x31c2
VF610_PAD_PTE27__GPIO_132 0x33e2
>;
};
pinctrl_sx1503_20: pinctrl-sx1503-20 {
fsl,pins = <
VF610_PAD_PTB1__GPIO_23 0x219d
>;
};
pinctrl_uart3: uart3grp {
fsl,pins = <
VF610_PAD_PTA20__UART3_TX 0x21a2
VF610_PAD_PTA21__UART3_RX 0x21a1
>;
};
pinctrl_mdio_mux: pinctrl-mdio-mux {
fsl,pins = <
VF610_PAD_PTA18__GPIO_8 0x31c2
VF610_PAD_PTA19__GPIO_9 0x31c2
VF610_PAD_PTB3__GPIO_25 0x31c2
>;
};
pinctrl_fec0_phy_int: pinctrl-fec0-phy-int {
fsl,pins = <
VF610_PAD_PTB28__GPIO_98 0x219d
>;
};
};
/*
* =============================================================
* End of shared part
* =============================================================
*/
&dspi0 {
m25p128@0 {
partition@0 {
label = "bootloader";
reg = <0x0 0x100000>;
};
};
};

View File

@ -0,0 +1,436 @@
/*
* Copyright (C) 2015, 2016 Zodiac Inflight Innovations
*
* Based on an original 'vf610-twr.dts' which is Copyright 2015,
* Freescale Semiconductor, Inc.
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use
n * copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* =============================================================
* The following code is shared with Linux kernel and should be
* removed once it trickles down from there eventually
* =============================================================
*/
#include <arm/vf610.dtsi>
/ {
chosen {
stdout-path = "serial0:115200n8";
};
memory {
reg = <0x80000000 0x20000000>;
};
gpio-leds {
compatible = "gpio-leds";
pinctrl-0 = <&pinctrl_leds_debug>;
pinctrl-names = "default";
debug {
label = "zii:green:debug1";
gpios = <&gpio2 10 GPIO_ACTIVE_HIGH>;
linux,default-trigger = "heartbeat";
};
};
reg_vcc_3v3_mcu: regulator-vcc-3v3-mcu {
compatible = "regulator-fixed";
regulator-name = "vcc_3v3_mcu";
regulator-min-microvolt = <3300000>;
regulator-max-microvolt = <3300000>;
};
usb0_vbus: regulator-usb0-vbus {
compatible = "regulator-fixed";
pinctrl-0 = <&pinctrl_usb_vbus>;
regulator-name = "usb_vbus";
regulator-min-microvolt = <5000000>;
regulator-max-microvolt = <5000000>;
enable-active-high;
regulator-always-on;
regulator-boot-on;
gpio = <&gpio0 6 0>;
};
};
&adc0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_adc0_ad5>;
vref-supply = <&reg_vcc_3v3_mcu>;
status = "okay";
};
&edma0 {
status = "okay";
};
&esdhc1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc1>;
bus-width = <4>;
status = "okay";
};
&fec0 {
phy-mode = "rmii";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec0>;
status = "okay";
};
&fec1 {
phy-mode = "rmii";
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_fec1>;
status = "okay";
fixed-link {
speed = <100>;
full-duplex;
};
mdio1: mdio {
#address-cells = <1>;
#size-cells = <0>;
status = "okay";
};
};
&i2c0 {
clock-frequency = <100000>;
pinctrl-names = "default", "gpio";
pinctrl-0 = <&pinctrl_i2c0>;
pinctrl-1 = <&pinctrl_i2c0_gpio>;
scl-gpios = <&gpio1 4 GPIO_ACTIVE_HIGH>;
sda-gpios = <&gpio1 5 GPIO_ACTIVE_HIGH>;
status = "okay";
lm75@48 {
compatible = "national,lm75";
reg = <0x48>;
};
at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
at24c04@52 {
compatible = "atmel,24c04";
reg = <0x52>;
};
ds1682@6b {
compatible = "dallas,ds1682";
reg = <0x6b>;
};
};
&i2c1 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c1>;
status = "okay";
};
&i2c2 {
clock-frequency = <100000>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_i2c2>;
status = "okay";
};
&uart0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart0>;
status = "okay";
};
&uart1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart1>;
status = "okay";
};
&uart2 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_uart2>;
status = "okay";
};
&usbdev0 {
disable-over-current;
vbus-supply = <&usb0_vbus>;
dr_mode = "host";
status = "okay";
};
&usbh1 {
disable-over-current;
status = "okay";
};
&usbmisc0 {
status = "okay";
};
&usbmisc1 {
status = "okay";
};
&usbphy0 {
status = "okay";
};
&usbphy1 {
status = "okay";
};
&iomuxc {
pinctrl_adc0_ad5: adc0ad5grp {
fsl,pins = <
VF610_PAD_PTC30__ADC0_SE5 0x00a1
>;
};
pinctrl_dspi0: dspi0grp {
fsl,pins = <
VF610_PAD_PTB18__DSPI0_CS1 0x1182
VF610_PAD_PTB19__DSPI0_CS0 0x1182
VF610_PAD_PTB20__DSPI0_SIN 0x1181
VF610_PAD_PTB21__DSPI0_SOUT 0x1182
VF610_PAD_PTB22__DSPI0_SCK 0x1182
>;
};
pinctrl_dspi2: dspi2grp {
fsl,pins = <
VF610_PAD_PTD31__DSPI2_CS1 0x1182
VF610_PAD_PTD30__DSPI2_CS0 0x1182
VF610_PAD_PTD29__DSPI2_SIN 0x1181
VF610_PAD_PTD28__DSPI2_SOUT 0x1182
VF610_PAD_PTD27__DSPI2_SCK 0x1182
>;
};
pinctrl_esdhc1: esdhc1grp {
fsl,pins = <
VF610_PAD_PTA24__ESDHC1_CLK 0x31ef
VF610_PAD_PTA25__ESDHC1_CMD 0x31ef
VF610_PAD_PTA26__ESDHC1_DAT0 0x31ef
VF610_PAD_PTA27__ESDHC1_DAT1 0x31ef
VF610_PAD_PTA28__ESDHC1_DATA2 0x31ef
VF610_PAD_PTA29__ESDHC1_DAT3 0x31ef
VF610_PAD_PTA7__GPIO_134 0x219d
>;
};
pinctrl_fec0: fec0grp {
fsl,pins = <
VF610_PAD_PTC0__ENET_RMII0_MDC 0x30d2
VF610_PAD_PTC1__ENET_RMII0_MDIO 0x30d3
VF610_PAD_PTC2__ENET_RMII0_CRS 0x30d1
VF610_PAD_PTC3__ENET_RMII0_RXD1 0x30d1
VF610_PAD_PTC4__ENET_RMII0_RXD0 0x30d1
VF610_PAD_PTC5__ENET_RMII0_RXER 0x30d1
VF610_PAD_PTC6__ENET_RMII0_TXD1 0x30d2
VF610_PAD_PTC7__ENET_RMII0_TXD0 0x30d2
VF610_PAD_PTC8__ENET_RMII0_TXEN 0x30d2
>;
};
pinctrl_fec1: fec1grp {
fsl,pins = <
VF610_PAD_PTA6__RMII_CLKIN 0x30d1
VF610_PAD_PTC9__ENET_RMII1_MDC 0x30d2
VF610_PAD_PTC10__ENET_RMII1_MDIO 0x30d3
VF610_PAD_PTC11__ENET_RMII1_CRS 0x30d1
VF610_PAD_PTC12__ENET_RMII1_RXD1 0x30d1
VF610_PAD_PTC13__ENET_RMII1_RXD0 0x30d1
VF610_PAD_PTC14__ENET_RMII1_RXER 0x30d1
VF610_PAD_PTC15__ENET_RMII1_TXD1 0x30d2
VF610_PAD_PTC16__ENET_RMII1_TXD0 0x30d2
VF610_PAD_PTC17__ENET_RMII1_TXEN 0x30d2
>;
};
pinctrl_gpio_spi0: pinctrl-gpio-spi0 {
fsl,pins = <
VF610_PAD_PTB22__GPIO_44 0x33e2
VF610_PAD_PTB21__GPIO_43 0x33e2
VF610_PAD_PTB20__GPIO_42 0x33e1
VF610_PAD_PTB19__GPIO_41 0x33e2
VF610_PAD_PTB18__GPIO_40 0x33e2
>;
};
pinctrl_i2c_mux_reset: pinctrl-i2c-mux-reset {
fsl,pins = <
VF610_PAD_PTE14__GPIO_119 0x31c2
>;
};
pinctrl_i2c0: i2c0grp {
fsl,pins = <
VF610_PAD_PTB14__I2C0_SCL 0x37ff
VF610_PAD_PTB15__I2C0_SDA 0x37ff
>;
};
pinctrl_i2c0_gpio: i2c0grp-gpio {
fsl,pins = <
VF610_PAD_PTB14__GPIO_36 0x31c2
VF610_PAD_PTB15__GPIO_37 0x31c2
>;
};
pinctrl_i2c1: i2c1grp {
fsl,pins = <
VF610_PAD_PTB16__I2C1_SCL 0x37ff
VF610_PAD_PTB17__I2C1_SDA 0x37ff
>;
};
pinctrl_i2c2: i2c2grp {
fsl,pins = <
VF610_PAD_PTA22__I2C2_SCL 0x37ff
VF610_PAD_PTA23__I2C2_SDA 0x37ff
>;
};
pinctrl_leds_debug: pinctrl-leds-debug {
fsl,pins = <
VF610_PAD_PTD20__GPIO_74 0x31c2
>;
};
pinctrl_qspi0: qspi0grp {
fsl,pins = <
VF610_PAD_PTD7__QSPI0_B_QSCK 0x31c3
VF610_PAD_PTD8__QSPI0_B_CS0 0x31ff
VF610_PAD_PTD9__QSPI0_B_DATA3 0x31c3
VF610_PAD_PTD10__QSPI0_B_DATA2 0x31c3
VF610_PAD_PTD11__QSPI0_B_DATA1 0x31c3
VF610_PAD_PTD12__QSPI0_B_DATA0 0x31c3
>;
};
pinctrl_uart0: uart0grp {
fsl,pins = <
VF610_PAD_PTB10__UART0_TX 0x21a2
VF610_PAD_PTB11__UART0_RX 0x21a1
>;
};
pinctrl_uart1: uart1grp {
fsl,pins = <
VF610_PAD_PTB23__UART1_TX 0x21a2
VF610_PAD_PTB24__UART1_RX 0x21a1
>;
};
pinctrl_uart2: uart2grp {
fsl,pins = <
VF610_PAD_PTD0__UART2_TX 0x21a2
VF610_PAD_PTD1__UART2_RX 0x21a1
>;
};
pinctrl_usb_vbus: pinctrl-usb-vbus {
fsl,pins = <
VF610_PAD_PTA16__GPIO_6 0x31c2
>;
};
pinctrl_usb0_host: usb0-host-grp {
fsl,pins = <
VF610_PAD_PTD6__GPIO_85 0x0062
>;
};
};
/*
* =============================================================
* End of shared part
* =============================================================
*/
/ {
audio_ext: mclk_osc {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <0>;
};
enet_ext: eth_osc {
compatible = "fixed-clock";
clock-output-names = "enet_ext";
#clock-cells = <0>;
clock-frequency = <50000000>;
};
anaclk1: anaclk1 {
compatible = "fixed-clock";
#clock-cells = <0>;
clock-frequency = <0>;
};
};
&clks {
clocks = <&sxosc>, <&fxosc>, <&enet_ext>, <&audio_ext>, <&anaclk1>,
<&clks VF610_CLK_SYS_BUS>, <&clks VF610_CLK_PLATFORM_BUS>,
<&clks VF610_CLK_IPG_BUS>, <&clks VF610_CLK_DDRMC>;
clock-names = "sxosc", "fxosc", "enet_ext", "audio_ext", "anaclk1",
"cpu", "bus", "ipg", "ddr";
assigned-clocks = <&clks VF610_CLK_ENET_SEL>,
<&clks VF610_CLK_ENET_TS_SEL>;
assigned-clock-parents = <&clks VF610_CLK_ENET_EXT>,
<&clks VF610_CLK_ENET_EXT>;
};
&ocotp {
barebox,provide-mac-address = <&fec0 0x620>,
<&fec1 0x640>;
};

View File

@ -0,0 +1,457 @@
/*
* Copyright (C) 2015, 2016 Zodiac Inflight Innovations
*
* Based on an original 'vf610-twr.dts' which is Copyright 2015,
* Freescale Semiconductor, Inc.
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "vf610-zii-dev.dtsi"
/ {
model = "ZII VF610 SCU4 AIB, Rev C";
compatible = "zii,vf610scu4-aib-c", "zii,vf610dev", "fsl,vf610";
chosen {
bootargs = "console=ttyLP0,115200n8";
};
gpio-leds {
debug {
gpios = <&gpio3 0 GPIO_ACTIVE_HIGH>;
};
};
mdio-mux {
compatible = "mdio-mux-gpio";
pinctrl-0 = <&pinctrl_mdio_mux>;
pinctrl-names = "default";
gpios = <&gpio4 4 GPIO_ACTIVE_HIGH
&gpio4 5 GPIO_ACTIVE_HIGH
&gpio3 30 GPIO_ACTIVE_HIGH
&gpio3 31 GPIO_ACTIVE_HIGH>;
mdio-parent-bus = <&mdio1>;
#address-cells = <1>;
#size-cells = <0>;
mdio_mux_1: mdio@1 {
reg = <1>;
#address-cells = <1>;
#size-cells = <0>;
};
mdio_mux_2: mdio@2 {
reg = <2>;
#address-cells = <1>;
#size-cells = <0>;
};
mdio_mux_4: mdio@4 {
reg = <4>;
#address-cells = <1>;
#size-cells = <0>;
};
mdio_mux_8: mdio@8 {
reg = <8>;
#address-cells = <1>;
#size-cells = <0>;
};
};
spi2 {
compatible = "spi-gpio";
pinctrl-0 = <&pinctrl_dspi2>;
pinctrl-names = "default";
#address-cells = <1>;
#size-cells = <0>;
gpio-sck = <&gpio2 3 GPIO_ACTIVE_HIGH>;
gpio-mosi = <&gpio2 2 GPIO_ACTIVE_HIGH>;
gpio-miso = <&gpio2 1 GPIO_ACTIVE_HIGH>;
cs-gpios = <&gpio2 0 GPIO_ACTIVE_HIGH>;
num-chipselects = <1>;
at93c46d@0 {
compatible = "atmel,at93c46d";
#address-cells = <0>;
#size-cells = <0>;
reg = <0>;
spi-max-frequency = <500000>;
spi-cs-high;
data-size = <16>;
select-gpios = <&gpio2 4 GPIO_ACTIVE_HIGH>;
};
};
};
&dspi0 {
pinctrl-0 = <&pinctrl_dspi0>, <&pinctrl_dspi0_cs_4_5>;
pinctrl-names = "default";
status = "okay";
};
&dspi1 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dspi1>;
status = "okay";
m25p128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p128", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
partition@0 {
label = "m25p128-0";
reg = <0x0 0x01000000>;
};
};
m25p128@1 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p128", "jedec,spi-nor";
reg = <1>;
spi-max-frequency = <50000000>;
partition@0 {
label = "m25p128-1";
reg = <0x0 0x01000000>;
};
};
};
&esdhc0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc0>;
bus-width = <8>;
status = "okay";
};
&fec0 {
status = "disabled";
};
&i2c0 {
/* Reset Signals */
gpio5: pca9505@20 {
compatible = "nxp,pca9554";
reg = <0x20>;
gpio-controller;
#gpio-cells = <2>;
};
/* Board Revision */
gpio6: pca9505@22 {
compatible = "nxp,pca9554";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
};
};
&i2c1 {
/* Wireless 2 */
gpio8: pca9554@18 {
compatible = "nxp,pca9557";
reg = <0x18>;
gpio-controller;
#gpio-cells = <2>;
};
/* Wireless 1 */
gpio7: pca9554@24 {
compatible = "nxp,pca9554";
reg = <0x24>;
gpio-controller;
#gpio-cells = <2>;
};
/* AIB voltage monitor */
adt7411@4a {
compatible = "adi,adt7411";
reg = <0x4a>;
};
};
&i2c2 {
/* FIB voltage monitor */
adt7411@4a {
compatible = "adi,adt7411";
reg = <0x4a>;
};
lm75_swb {
compatible = "national,lm75";
reg = <0x4e>;
};
lm75_swa {
compatible = "national,lm75";
reg = <0x4f>;
};
/* FIB Nameplate */
at24c08@57 {
compatible = "atmel,24c08";
reg = <0x57>;
};
tca9548@70 {
compatible = "nxp,pca9548";
#address-cells = <1>;
#size-cells = <0>;
reg = <0x70>;
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
sff0: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
sff1: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
sff2: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
sff3: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@5 {
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
sff4: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
};
tca9548@71 {
compatible = "nxp,pca9548";
reg = <0x71>;
#address-cells = <1>;
#size-cells = <0>;
i2c@1 {
#address-cells = <1>;
#size-cells = <0>;
reg = <1>;
sff5: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@2 {
#address-cells = <1>;
#size-cells = <0>;
reg = <2>;
sff6: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@3 {
#address-cells = <1>;
#size-cells = <0>;
reg = <3>;
sff7: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@4 {
#address-cells = <1>;
#size-cells = <0>;
reg = <4>;
sff8: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
i2c@5 {
#address-cells = <1>;
#size-cells = <0>;
reg = <5>;
sff9: at24c04@50 {
compatible = "atmel,24c04";
reg = <0x50>;
};
};
};
};
&uart1 {
linux,rs485-enabled-at-boot-time;
pinctrl-0 = <&pinctrl_uart1>, <&pinctrl_uart1_rts>;
};
&uart2 {
linux,rs485-enabled-at-boot-time;
pinctrl-0 = <&pinctrl_uart2>, <&pinctrl_uart2_rts>;
};
&iomuxc {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_gpo_public>;
pinctrl_gpo_public: gpopubgrp {
fsl,pins = <
VF610_PAD_PTE2__GPIO_107 0x2062
VF610_PAD_PTE3__GPIO_108 0x2062
VF610_PAD_PTE4__GPIO_109 0x2062
VF610_PAD_PTE5__GPIO_110 0x2062
VF610_PAD_PTE6__GPIO_111 0x2062
>;
};
pinctrl_dspi0_cs_4_5: dspi0grp-cs-4-5 {
fsl,pins = <
VF610_PAD_PTB13__DSPI0_CS4 0x1182
VF610_PAD_PTB12__DSPI0_CS5 0x1182
>;
};
pinctrl_dspi1: dspi1grp {
fsl,pins = <
VF610_PAD_PTD5__DSPI1_CS0 0x1182
VF610_PAD_PTD4__DSPI1_CS1 0x1182
VF610_PAD_PTC6__DSPI1_SIN 0x1181
VF610_PAD_PTC7__DSPI1_SOUT 0x1182
VF610_PAD_PTC8__DSPI1_SCK 0x1182
>;
};
pinctrl_esdhc0: esdhc0grp {
fsl,pins = <
VF610_PAD_PTC0__ESDHC0_CLK 0x31ef
VF610_PAD_PTC1__ESDHC0_CMD 0x31ef
VF610_PAD_PTC2__ESDHC0_DAT0 0x31ef
VF610_PAD_PTC3__ESDHC0_DAT1 0x31ef
VF610_PAD_PTC4__ESDHC0_DAT2 0x31ef
VF610_PAD_PTC5__ESDHC0_DAT3 0x31ef
VF610_PAD_PTD23__ESDHC0_DAT4 0x31ef
VF610_PAD_PTD22__ESDHC0_DAT5 0x31ef
VF610_PAD_PTD21__ESDHC0_DAT6 0x31ef
VF610_PAD_PTD20__ESDHC0_DAT7 0x31ef
>;
};
pinctrl_i2c3: i2c3grp {
fsl,pins = <
VF610_PAD_PTA30__I2C3_SCL 0x37ff
VF610_PAD_PTA31__I2C3_SDA 0x37ff
>;
};
pinctrl_leds_debug: pinctrl-leds-debug {
fsl,pins = <
VF610_PAD_PTB26__GPIO_96 0x31c2
>;
};
pinctrl_uart1_rts: uart1grp-rts {
fsl,pins = <
VF610_PAD_PTB25__UART1_RTS 0x2062
>;
};
pinctrl_uart2_rts: uart2grp-rts {
fsl,pins = <
VF610_PAD_PTD2__UART2_RTS 0x2062
>;
};
pinctrl_mdio_mux: pinctrl-mdio-mux {
fsl,pins = <
VF610_PAD_PTE27__GPIO_132 0x31c2
VF610_PAD_PTE28__GPIO_133 0x31c2
VF610_PAD_PTE21__GPIO_126 0x31c2
VF610_PAD_PTE22__GPIO_127 0x31c2
>;
};
};

View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2015, 2016 Zodiac Inflight Innovations
*
* Based on an original 'vf610-twr.dts' which is Copyright 2015,
* Freescale Semiconductor, Inc.
*
* This file is dual-licensed: you can use it either under the terms
* of the GPL or the X11 license, at your option. Note that this dual
* licensing only applies to this file, and not this project as a
* whole.
*
* a) This file 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 file 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.
*
* Or, alternatively
*
* b) Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use
* copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED , WITHOUT WARRANTY OF ANY KIND
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/dts-v1/;
#include "vf610-zii-dev.dtsi"
/ {
model = "ZII VF610 SPU3 Switch Management Board";
compatible = "zii,vf610spu3-a", "zii,vf610dev", "fsl,vf610";
aliases {
/delete-property/ serial2;
};
gpio-leds {
debug {
gpios = <&gpio2 18 GPIO_ACTIVE_HIGH>;
};
};
};
&dspi1 {
bus-num = <1>;
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_dspi1>;
status = "okay";
m25p128@0 {
#address-cells = <1>;
#size-cells = <1>;
compatible = "m25p128", "jedec,spi-nor";
reg = <0>;
spi-max-frequency = <50000000>;
partition@0 {
label = "m25p128-0";
reg = <0x0 0x01000000>;
};
};
};
&esdhc0 {
pinctrl-names = "default";
pinctrl-0 = <&pinctrl_esdhc0>;
bus-width = <8>;
status = "okay";
};
&fec0 {
status = "disabled";
};
&i2c0 {
/* Board Revision */
gpio6: pca9505@22 {
compatible = "nxp,pca9554";
reg = <0x22>;
gpio-controller;
#gpio-cells = <2>;
};
};
/delete-node/ &i2c1;
/delete-node/ &i2c2;
/delete-node/ &uart2;
&iomuxc {
pinctrl_dspi1: dspi1grp {
fsl,pins = <
VF610_PAD_PTD5__DSPI1_CS0 0x1182
VF610_PAD_PTD4__DSPI1_CS1 0x1182
VF610_PAD_PTC6__DSPI1_SIN 0x1181
VF610_PAD_PTC7__DSPI1_SOUT 0x1182
VF610_PAD_PTC8__DSPI1_SCK 0x1182
>;
};
pinctrl_esdhc0: esdhc0grp {
fsl,pins = <
VF610_PAD_PTC0__ESDHC0_CLK 0x31ef
VF610_PAD_PTC1__ESDHC0_CMD 0x31ef
VF610_PAD_PTC2__ESDHC0_DAT0 0x31ef
VF610_PAD_PTC3__ESDHC0_DAT1 0x31ef
VF610_PAD_PTC4__ESDHC0_DAT2 0x31ef
VF610_PAD_PTC5__ESDHC0_DAT3 0x31ef
VF610_PAD_PTD23__ESDHC0_DAT4 0x31ef
VF610_PAD_PTD22__ESDHC0_DAT5 0x31ef
VF610_PAD_PTD21__ESDHC0_DAT6 0x31ef
VF610_PAD_PTD20__ESDHC0_DAT7 0x31ef
>;
};
pinctrl_leds_debug: pinctrl-leds-debug {
fsl,pins = <
VF610_PAD_PTD3__GPIO_82 0x31c2
>;
};
};

View File

@ -0,0 +1,104 @@
/*
* Copyright (c) 2015, Linaro Limited
*
* This software is licensed under the terms of the GNU General Public
* License version 2, as published by the Free Software Foundation, and
* may be copied, distributed, and modified under those terms.
*
* 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.
*
*/
#ifndef __LINUX_ARM_SMCCC_H
#define __LINUX_ARM_SMCCC_H
#include <linux/linkage.h>
#include <linux/types.h>
/*
* This file provides common defines for ARM SMC Calling Convention as
* specified in
* http://infocenter.arm.com/help/topic/com.arm.doc.den0028a/index.html
*/
#define ARM_SMCCC_STD_CALL 0
#define ARM_SMCCC_FAST_CALL 1
#define ARM_SMCCC_TYPE_SHIFT 31
#define ARM_SMCCC_SMC_32 0
#define ARM_SMCCC_SMC_64 1
#define ARM_SMCCC_CALL_CONV_SHIFT 30
#define ARM_SMCCC_OWNER_MASK 0x3F
#define ARM_SMCCC_OWNER_SHIFT 24
#define ARM_SMCCC_FUNC_MASK 0xFFFF
#define ARM_SMCCC_IS_FAST_CALL(smc_val) \
((smc_val) & (ARM_SMCCC_FAST_CALL << ARM_SMCCC_TYPE_SHIFT))
#define ARM_SMCCC_IS_64(smc_val) \
((smc_val) & (ARM_SMCCC_SMC_64 << ARM_SMCCC_CALL_CONV_SHIFT))
#define ARM_SMCCC_FUNC_NUM(smc_val) ((smc_val) & ARM_SMCCC_FUNC_MASK)
#define ARM_SMCCC_OWNER_NUM(smc_val) \
(((smc_val) >> ARM_SMCCC_OWNER_SHIFT) & ARM_SMCCC_OWNER_MASK)
#define ARM_SMCCC_CALL_VAL(type, calling_convention, owner, func_num) \
(((type) << ARM_SMCCC_TYPE_SHIFT) | \
((calling_convention) << ARM_SMCCC_CALL_CONV_SHIFT) | \
(((owner) & ARM_SMCCC_OWNER_MASK) << ARM_SMCCC_OWNER_SHIFT) | \
((func_num) & ARM_SMCCC_FUNC_MASK))
#define ARM_SMCCC_OWNER_ARCH 0
#define ARM_SMCCC_OWNER_CPU 1
#define ARM_SMCCC_OWNER_SIP 2
#define ARM_SMCCC_OWNER_OEM 3
#define ARM_SMCCC_OWNER_STANDARD 4
#define ARM_SMCCC_OWNER_TRUSTED_APP 48
#define ARM_SMCCC_OWNER_TRUSTED_APP_END 49
#define ARM_SMCCC_OWNER_TRUSTED_OS 50
#define ARM_SMCCC_OWNER_TRUSTED_OS_END 63
/**
* struct arm_smccc_res - Result from SMC/HVC call
* @a0-a3 result values from registers 0 to 3
*/
struct arm_smccc_res {
unsigned long a0;
unsigned long a1;
unsigned long a2;
unsigned long a3;
};
/**
* arm_smccc_smc() - make SMC calls
* @a0-a7: arguments passed in registers 0 to 7
* @res: result values from registers 0 to 3
*
* This function is used to make SMC calls following SMC Calling Convention.
* The content of the supplied param are copied to registers 0 to 7 prior
* to the SMC instruction. The return values are updated with the content
* from register 0 to 3 on return from the SMC instruction.
*/
asmlinkage void arm_smccc_smc(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, unsigned long a6, unsigned long a7,
struct arm_smccc_res *res);
/**
* arm_smccc_hvc() - make HVC calls
* @a0-a7: arguments passed in registers 0 to 7
* @res: result values from registers 0 to 3
*
* This function is used to make HVC calls following SMC Calling
* Convention. The content of the supplied param are copied to registers 0
* to 7 prior to the HVC instruction. The return values are updated with
* the content from register 0 to 3 on return from the HVC instruction.
*/
asmlinkage void arm_smccc_hvc(unsigned long a0, unsigned long a1,
unsigned long a2, unsigned long a3, unsigned long a4,
unsigned long a5, unsigned long a6, unsigned long a7,
struct arm_smccc_res *res);
#endif /*__LINUX_ARM_SMCCC_H*/

View File

@ -3,6 +3,7 @@
#include <asm/memory.h>
#include <asm/setup.h>
#include <asm/secure.h>
#if defined CONFIG_ARM_LINUX
void armlinux_set_bootparams(void *params);
@ -38,6 +39,7 @@ static inline void armlinux_set_atag_appender(struct tag *(*func)(struct tag *))
struct image_data;
void start_linux(void *adr, int swap, unsigned long initrd_address,
unsigned long initrd_size, void *oftree);
unsigned long initrd_size, void *oftree,
enum arm_security_state);
#endif /* __ARCH_ARMLINUX_H */

110
arch/arm/include/asm/gic.h Normal file
View File

@ -0,0 +1,110 @@
#ifndef __GIC_H__
#define __GIC_H__
/* Register offsets for the ARM generic interrupt controller (GIC) */
#define GIC_DIST_OFFSET 0x1000
#define GIC_CPU_OFFSET_A9 0x0100
#define GIC_CPU_OFFSET_A15 0x2000
/* Distributor Registers */
#define GICD_CTLR 0x0000
#define GICD_TYPER 0x0004
#define GICD_IIDR 0x0008
#define GICD_STATUSR 0x0010
#define GICD_SETSPI_NSR 0x0040
#define GICD_CLRSPI_NSR 0x0048
#define GICD_SETSPI_SR 0x0050
#define GICD_CLRSPI_SR 0x0058
#define GICD_SEIR 0x0068
#define GICD_IGROUPRn 0x0080
#define GICD_ISENABLERn 0x0100
#define GICD_ICENABLERn 0x0180
#define GICD_ISPENDRn 0x0200
#define GICD_ICPENDRn 0x0280
#define GICD_ISACTIVERn 0x0300
#define GICD_ICACTIVERn 0x0380
#define GICD_IPRIORITYRn 0x0400
#define GICD_ITARGETSRn 0x0800
#define GICD_ICFGR 0x0c00
#define GICD_IGROUPMODRn 0x0d00
#define GICD_NSACRn 0x0e00
#define GICD_SGIR 0x0f00
#define GICD_CPENDSGIRn 0x0f10
#define GICD_SPENDSGIRn 0x0f20
#define GICD_IROUTERn 0x6000
/* Cpu Interface Memory Mapped Registers */
#define GICC_CTLR 0x0000
#define GICC_PMR 0x0004
#define GICC_BPR 0x0008
#define GICC_IAR 0x000C
#define GICC_EOIR 0x0010
#define GICC_RPR 0x0014
#define GICC_HPPIR 0x0018
#define GICC_ABPR 0x001c
#define GICC_AIAR 0x0020
#define GICC_AEOIR 0x0024
#define GICC_AHPPIR 0x0028
#define GICC_APRn 0x00d0
#define GICC_NSAPRn 0x00e0
#define GICC_IIDR 0x00fc
#define GICC_DIR 0x1000
/* ReDistributor Registers for Control and Physical LPIs */
#define GICR_CTLR 0x0000
#define GICR_IIDR 0x0004
#define GICR_TYPER 0x0008
#define GICR_STATUSR 0x0010
#define GICR_WAKER 0x0014
#define GICR_SETLPIR 0x0040
#define GICR_CLRLPIR 0x0048
#define GICR_SEIR 0x0068
#define GICR_PROPBASER 0x0070
#define GICR_PENDBASER 0x0078
#define GICR_INVLPIR 0x00a0
#define GICR_INVALLR 0x00b0
#define GICR_SYNCR 0x00c0
#define GICR_MOVLPIR 0x0100
#define GICR_MOVALLR 0x0110
/* ReDistributor Registers for SGIs and PPIs */
#define GICR_IGROUPRn 0x0080
#define GICR_ISENABLERn 0x0100
#define GICR_ICENABLERn 0x0180
#define GICR_ISPENDRn 0x0200
#define GICR_ICPENDRn 0x0280
#define GICR_ISACTIVERn 0x0300
#define GICR_ICACTIVERn 0x0380
#define GICR_IPRIORITYRn 0x0400
#define GICR_ICFGR0 0x0c00
#define GICR_ICFGR1 0x0c04
#define GICR_IGROUPMODRn 0x0d00
#define GICR_NSACRn 0x0e00
/* Cpu Interface System Registers */
#define ICC_IAR0_EL1 S3_0_C12_C8_0
#define ICC_IAR1_EL1 S3_0_C12_C12_0
#define ICC_EOIR0_EL1 S3_0_C12_C8_1
#define ICC_EOIR1_EL1 S3_0_C12_C12_1
#define ICC_HPPIR0_EL1 S3_0_C12_C8_2
#define ICC_HPPIR1_EL1 S3_0_C12_C12_2
#define ICC_BPR0_EL1 S3_0_C12_C8_3
#define ICC_BPR1_EL1 S3_0_C12_C12_3
#define ICC_DIR_EL1 S3_0_C12_C11_1
#define ICC_PMR_EL1 S3_0_C4_C6_0
#define ICC_RPR_EL1 S3_0_C12_C11_3
#define ICC_CTLR_EL1 S3_0_C12_C12_4
#define ICC_CTLR_EL3 S3_6_C12_C12_4
#define ICC_SRE_EL1 S3_0_C12_C12_5
#define ICC_SRE_EL2 S3_4_C12_C9_5
#define ICC_SRE_EL3 S3_6_C12_C12_5
#define ICC_IGRPEN0_EL1 S3_0_C12_C12_6
#define ICC_IGRPEN1_EL1 S3_0_C12_C12_7
#define ICC_IGRPEN1_EL3 S3_6_C12_C12_7
#define ICC_SEIEN_EL1 S3_0_C12_C13_0
#define ICC_SGI0R_EL1 S3_0_C12_C11_7
#define ICC_SGI1R_EL1 S3_0_C12_C11_5
#define ICC_ASGI1R_EL1 S3_0_C12_C11_6
#endif /* __GIC_H__ */

140
arch/arm/include/asm/psci.h Normal file
View File

@ -0,0 +1,140 @@
/*
* Copyright (C) 2013 - ARM Ltd
* Author: Marc Zyngier <marc.zyngier@arm.com>
*
* 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.
*
* You should have received a copy of the GNU General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef __ARM_PSCI_H__
#define __ARM_PSCI_H__
#define ARM_PSCI_VER_1_0 (0x00010000)
#define ARM_PSCI_VER_0_2 (0x00000002)
/* PSCI 0.1 interface */
#define ARM_PSCI_FN_BASE 0x95c1ba5e
#define ARM_PSCI_FN(n) (ARM_PSCI_FN_BASE + (n))
#define ARM_PSCI_FN_CPU_SUSPEND ARM_PSCI_FN(0)
#define ARM_PSCI_FN_CPU_OFF ARM_PSCI_FN(1)
#define ARM_PSCI_FN_CPU_ON ARM_PSCI_FN(2)
#define ARM_PSCI_FN_MIGRATE ARM_PSCI_FN(3)
#define ARM_PSCI_RET_SUCCESS 0
#define ARM_PSCI_RET_NOT_SUPPORTED (-1)
#define ARM_PSCI_RET_INVAL (-2)
#define ARM_PSCI_RET_DENIED (-3)
#define ARM_PSCI_RET_ALREADY_ON (-4)
#define ARM_PSCI_RET_ON_PENDING (-5)
#define ARM_PSCI_RET_INTERNAL_FAILURE (-6)
#define ARM_PSCI_RET_NOT_PRESENT (-7)
#define ARM_PSCI_RET_DISABLED (-8)
#define ARM_PSCI_RET_INVALID_ADDRESS (-9)
/* PSCI 0.2 interface */
#define ARM_PSCI_0_2_FN_BASE 0x84000000
#define ARM_PSCI_0_2_FN(n) (ARM_PSCI_0_2_FN_BASE + (n))
#define ARM_PSCI_0_2_FN64_BASE 0xC4000000
#define ARM_PSCI_0_2_FN64(n) (ARM_PSCI_0_2_FN64_BASE + (n))
#define ARM_PSCI_0_2_FN_PSCI_VERSION ARM_PSCI_0_2_FN(0)
#define ARM_PSCI_0_2_FN_CPU_SUSPEND ARM_PSCI_0_2_FN(1)
#define ARM_PSCI_0_2_FN_CPU_OFF ARM_PSCI_0_2_FN(2)
#define ARM_PSCI_0_2_FN_CPU_ON ARM_PSCI_0_2_FN(3)
#define ARM_PSCI_0_2_FN_AFFINITY_INFO ARM_PSCI_0_2_FN(4)
#define ARM_PSCI_0_2_FN_MIGRATE ARM_PSCI_0_2_FN(5)
#define ARM_PSCI_0_2_FN_MIGRATE_INFO_TYPE ARM_PSCI_0_2_FN(6)
#define ARM_PSCI_0_2_FN_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN(7)
#define ARM_PSCI_0_2_FN_SYSTEM_OFF ARM_PSCI_0_2_FN(8)
#define ARM_PSCI_0_2_FN_SYSTEM_RESET ARM_PSCI_0_2_FN(9)
#define ARM_PSCI_0_2_FN64_CPU_SUSPEND ARM_PSCI_0_2_FN64(1)
#define ARM_PSCI_0_2_FN64_CPU_ON ARM_PSCI_0_2_FN64(3)
#define ARM_PSCI_0_2_FN64_AFFINITY_INFO ARM_PSCI_0_2_FN64(4)
#define ARM_PSCI_0_2_FN64_MIGRATE ARM_PSCI_0_2_FN64(5)
#define ARM_PSCI_0_2_FN64_MIGRATE_INFO_UP_CPU ARM_PSCI_0_2_FN64(7)
/* PSCI 1.0 interface */
#define ARM_PSCI_1_0_FN_PSCI_FEATURES ARM_PSCI_0_2_FN(10)
#define ARM_PSCI_1_0_FN_CPU_FREEZE ARM_PSCI_0_2_FN(11)
#define ARM_PSCI_1_0_FN_CPU_DEFAULT_SUSPEND ARM_PSCI_0_2_FN(12)
#define ARM_PSCI_1_0_FN_NODE_HW_STATE ARM_PSCI_0_2_FN(13)
#define ARM_PSCI_1_0_FN_SYSTEM_SUSPEND ARM_PSCI_0_2_FN(14)
#define ARM_PSCI_1_0_FN_SET_SUSPEND_MODE ARM_PSCI_0_2_FN(15)
#define ARM_PSCI_1_0_FN_STAT_RESIDENCY ARM_PSCI_0_2_FN(16)
#define ARM_PSCI_1_0_FN_STAT_COUNT ARM_PSCI_0_2_FN(17)
#define ARM_PSCI_1_0_FN64_CPU_DEFAULT_SUSPEND ARM_PSCI_0_2_FN64(12)
#define ARM_PSCI_1_0_FN64_NODE_HW_STATE ARM_PSCI_0_2_FN64(13)
#define ARM_PSCI_1_0_FN64_SYSTEM_SUSPEND ARM_PSCI_0_2_FN64(14)
#define ARM_PSCI_1_0_FN64_STAT_RESIDENCY ARM_PSCI_0_2_FN64(16)
#define ARM_PSCI_1_0_FN64_STAT_COUNT ARM_PSCI_0_2_FN64(17)
/* PSCI affinity level state returned by AFFINITY_INFO */
#define PSCI_AFFINITY_LEVEL_ON 0
#define PSCI_AFFINITY_LEVEL_OFF 1
#define PSCI_AFFINITY_LEVEL_ON_PENDING 2
struct psci_ops {
int (*cpu_suspend)(u32 power_state, unsigned long entry, u32 context_id);
int (*cpu_off)(void);
int (*cpu_on)(u32 cpu_id);
int (*affinity_info)(u32 affinity, u32 lowest_affinity_level);
int (*migrate)(u32 cpu_id);
int (*migrate_info_type)(void);
int (*migrate_info_up_cpu)(void);
void (*system_off)(void);
void (*system_reset)(void);
};
#ifdef CONFIG_ARM_PSCI
void psci_set_ops(struct psci_ops *ops);
#else
static inline void psci_set_ops(struct psci_ops *ops)
{
}
#endif
void psci_cpu_entry(void);
#ifdef CONFIG_ARM_PSCI_DEBUG
void psci_set_putc(void (*putcf)(void *ctx, int c), void *ctx);
void psci_putc(char c);
int psci_puts(const char *str);
int psci_printf(const char *fmt, ...)
__attribute__ ((format(__printf__, 1, 2)));
#else
static inline void psci_set_putc(void (*putcf)(void *ctx, int c), void *ctx)
{
}
static inline void psci_putc(char c)
{
}
static inline int psci_puts(const char *str)
{
return 0;
}
static inline int psci_printf(const char *fmt, ...)
{
return 0;
}
#endif
int psci_get_cpu_id(void);
#endif /* __ARM_PSCI_H__ */

View File

@ -32,6 +32,7 @@
#define IRQ_MODE 0x00000012
#define SVC_MODE 0x00000013
#define ABT_MODE 0x00000017
#define HYP_MODE 0x0000001a
#define UND_MODE 0x0000001b
#define SYSTEM_MODE 0x0000001f
#define MODE32_BIT 0x00000010

View File

@ -0,0 +1,39 @@
#ifndef __ASM_ARM_SECURE_H
#define __ASM_ARM_SECURE_H
#ifndef __ASSEMBLY__
int armv7_secure_monitor_install(void);
int __armv7_secure_monitor_install(void);
void armv7_switch_to_hyp(void);
extern unsigned char secure_monitor_init_vectors[];
enum arm_security_state {
ARM_STATE_SECURE,
ARM_STATE_NONSECURE,
ARM_STATE_HYP,
};
#ifdef CONFIG_ARM_SECURE_MONITOR
enum arm_security_state bootm_arm_security_state(void);
const char *bootm_arm_security_state_name(enum arm_security_state state);
#else
static inline enum arm_security_state bootm_arm_security_state(void)
{
return ARM_STATE_SECURE;
}
static inline const char *bootm_arm_security_state_name(
enum arm_security_state state)
{
return "secure";
}
#endif
#endif /* __ASSEMBLY__ */
#define ARM_SECURE_STACK_SHIFT 10
#define ARM_SECURE_MAX_CPU 8
#endif /* __ASM_ARM_SECURE_H */

View File

@ -48,4 +48,10 @@ extern void unwind_backtrace(struct pt_regs *regs);
#endif /* !__ASSEMBLY__ */
#ifdef CONFIG_ARM_UNWIND
#define UNWIND(code...) code
#else
#define UNWIND(code...)
#endif
#endif /* __ASM_UNWIND_H */

View File

@ -18,6 +18,7 @@
#include <magicvar.h>
#include <binfmt.h>
#include <restart.h>
#include <globalvar.h>
#include <asm/byteorder.h>
#include <asm/setup.h>
@ -133,6 +134,7 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
{
unsigned long kernel;
unsigned long initrd_start = 0, initrd_size = 0, initrd_end = 0;
enum arm_security_state state = bootm_arm_security_state();
int ret;
kernel = data->os_res->start + data->os_entry;
@ -174,10 +176,20 @@ static int __do_bootm_linux(struct image_data *data, unsigned long free_mem, int
printf("...\n");
}
if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR)) {
if (file_detect_type((void *)data->os_res->start, 0x100) ==
filetype_arm_barebox)
state = ARM_STATE_SECURE;
printf("Starting kernel in %s mode\n",
bootm_arm_security_state_name(state));
}
if (data->dryrun)
return 0;
start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree);
start_linux((void *)kernel, swap, initrd_start, initrd_size, data->oftree,
state);
restart_machine();

View File

@ -26,7 +26,7 @@ static int do_bootu(int argc, char *argv[])
oftree = of_get_fixed_tree(NULL);
#endif
start_linux(kernel, 0, 0, 0, oftree);
start_linux(kernel, 0, 0, 0, oftree, ARM_STATE_SECURE);
return 1;
}

View File

@ -38,6 +38,7 @@
#include <asm/barebox-arm.h>
#include <asm/armlinux.h>
#include <asm/system.h>
#include <asm/secure.h>
static struct tag *params;
static void *armlinux_bootparams = NULL;
@ -258,11 +259,19 @@ static void setup_tags(unsigned long initrd_address,
}
void start_linux(void *adr, int swap, unsigned long initrd_address,
unsigned long initrd_size, void *oftree)
unsigned long initrd_size, void *oftree,
enum arm_security_state state)
{
void (*kernel)(int zero, int arch, void *params) = adr;
void *params = NULL;
int architecture;
int ret;
if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR) && state > ARM_STATE_SECURE) {
ret = armv7_secure_monitor_install();
if (ret)
pr_err("Failed to install secure monitor\n");
}
if (oftree) {
pr_debug("booting kernel with devicetree\n");
@ -274,6 +283,10 @@ void start_linux(void *adr, int swap, unsigned long initrd_address,
architecture = armlinux_get_architecture();
shutdown_barebox();
if (IS_ENABLED(CONFIG_ARM_SECURE_MONITOR) && state == ARM_STATE_HYP)
armv7_switch_to_hyp();
if (swap) {
u32 reg;
__asm__ __volatile__("mrc p15, 0, %0, c1, c0" : "=r" (reg));

View File

@ -19,6 +19,7 @@
*/
#include <asm-generic/barebox.lds.h>
#include <asm/secure.h>
OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
@ -123,6 +124,15 @@ SECTIONS
__bss_start = .;
.bss : { *(.bss*) }
__bss_stop = .;
#ifdef CONFIG_ARM_SECURE_MONITOR
. = ALIGN(16);
__secure_stack_start = .;
. = . + (ARM_SECURE_MAX_CPU << ARM_SECURE_STACK_SHIFT);
__secure_stack_end = .;
__secure_end = .;
#endif
_end = .;
_barebox_image_size = __bss_start - TEXT_BASE;
}

View File

@ -112,7 +112,7 @@ static int do_bootz(int argc, char *argv[])
oftree = of_get_fixed_tree(NULL);
#endif
start_linux(zimage, swap, 0, 0, oftree);
start_linux(zimage, swap, 0, 0, oftree, ARM_STATE_SECURE);
return 0;

View File

@ -40,7 +40,8 @@
#include <asm/system.h>
void start_linux(void *adr, int swap, unsigned long initrd_address,
unsigned long initrd_size, void *oftree)
unsigned long initrd_size, void *oftree,
enum arm_security_state bootm_secure_state)
{
void (*kernel)(void *dtb) = adr;

View File

@ -39,6 +39,7 @@ config ARCH_TEXT_BASE
default 0x4fc00000 if MACH_UDOO
default 0x4fc00000 if MACH_VARISCITE_MX6
default 0x4fc00000 if MACH_PHYTEC_SOM_IMX6
default 0x9fc00000 if MACH_WARP7
config ARCH_IMX_IMXIMAGE
bool
@ -147,6 +148,10 @@ config ARCH_IMX6
select COMMON_CLK_OF_PROVIDER
select HW_HAS_PCI
config ARCH_IMX6SL
bool
select ARCH_IMX6
config ARCH_IMX6SX
bool
select ARCH_IMX6
@ -157,6 +162,12 @@ config ARCH_IMX6UL
bool
select ARCH_IMX6
config ARCH_IMX7
bool
select CPU_V7
select OFTREE
select COMMON_CLK_OF_PROVIDER
config ARCH_VF610
bool
select ARCH_HAS_L2X0
@ -166,6 +177,7 @@ config ARCH_VF610
select OFTREE
select COMMON_CLK
select COMMON_CLK_OF_PROVIDER
select IMX_OCOTP # Needed for clock adjustement
config IMX_MULTI_BOARDS
bool "Allow multiple boards to be selected"
@ -346,10 +358,23 @@ config MACH_CM_FX6
bool "CM FX6"
select ARCH_IMX6
config MACH_WARP7
bool "NXP i.MX7: element 14 WaRP7 Board"
select ARCH_IMX7
config MACH_VF610_TWR
bool "Freescale VF610 Tower Board"
select ARCH_VF610
config MACH_ZII_RDU2
bool "ZII i.MX6Q(+) RDU2"
select ARCH_IMX6
config MACH_ZII_VF610_DEV
bool "Zodiac VF610 Dev Family"
select ARCH_VF610
select CLKDEV_LOOKUP
endif
# ----------------------------------------------------------

View File

@ -13,6 +13,7 @@ obj-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
pbl-$(CONFIG_ARCH_IMX53) += imx53.o imx5.o esdctl-v4.o
obj-$(CONFIG_ARCH_IMX6) += imx6.o usb-imx6.o
lwl-$(CONFIG_ARCH_IMX6) += imx6-mmdc.o
obj-$(CONFIG_ARCH_IMX7) += imx7.o
obj-$(CONFIG_ARCH_IMX_XLOAD) += xload.o
obj-$(CONFIG_IMX_IIM) += iim.o
obj-$(CONFIG_IMX_OCOTP) += ocotp.o

View File

@ -25,6 +25,7 @@
#include <mach/imx51-regs.h>
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
#include <mach/imx7-regs.h>
/* [CTRL][TYPE] */
static const enum bootsource locations[4][4] = {
@ -346,3 +347,72 @@ void imx6_boot_save_loc(void)
bootsource_set(src);
bootsource_set_instance(instance);
}
#define IMX7_SRC_SBMR1 0x58
#define IMX7_SRC_SBMR2 0x70
void imx7_get_boot_source(enum bootsource *src, int *instance)
{
void __iomem *src_base = IOMEM(MX7_SRC_BASE_ADDR);
uint32_t sbmr1 = readl(src_base + IMX7_SRC_SBMR1);
uint32_t sbmr2 = readl(src_base + IMX7_SRC_SBMR2);
int boot_mode;
/* BMOD[1:0] */
boot_mode = (sbmr2 >> 24) & 0x3;
switch (boot_mode) {
case 0: /* Fuses, fall through */
case 2: /* internal boot */
goto internal_boot;
case 1: /* Serial Downloader */
*src = BOOTSOURCE_SERIAL;
break;
case 3: /* reserved */
break;
};
return;
internal_boot:
switch ((sbmr1 >> 12) & 0xf) {
case 1:
case 2:
*src = BOOTSOURCE_MMC;
*instance = (sbmr1 >> 10 & 0x3);
break;
case 3:
*src = BOOTSOURCE_NAND;
break;
case 4:
*src = BOOTSOURCE_SPI_NOR,
*instance = (sbmr1 >> 9 & 0x7);
break;
case 6:
*src = BOOTSOURCE_SPI; /* Really: qspi */
break;
case 5:
*src = BOOTSOURCE_NOR;
break;
default:
break;
}
/* BOOT_CFG1[7:0] */
if (sbmr1 & (1 << 7))
*src = BOOTSOURCE_NAND;
return;
}
void imx7_boot_save_loc(void)
{
enum bootsource src = BOOTSOURCE_UNKNOWN;
int instance = BOOTSOURCE_INSTANCE_UNKNOWN;
imx7_get_boot_source(&src, &instance);
bootsource_set(src);
bootsource_set_instance(instance);
}

View File

@ -154,6 +154,9 @@ static __maybe_unused struct of_device_id imx_gpt_dt_ids[] = {
}, {
.compatible = "fsl,imx6ul-gpt",
.data = &regs_imx31,
}, {
.compatible = "fsl,imx7d-gpt",
.data = &regs_imx31,
}, {
/* sentinel */
}

View File

@ -34,6 +34,11 @@ void imx6_cpu_lowlevel_init(void)
enable_arm_errata_845369_war();
}
void imx7_cpu_lowlevel_init(void)
{
arm_cpu_lowlevel_init();
}
void vf610_cpu_lowlevel_init(void)
{
arm_cpu_lowlevel_init();

View File

@ -432,6 +432,9 @@ static struct platform_device_id imx_esdctl_ids[] = {
static __maybe_unused struct of_device_id imx_esdctl_dt_ids[] = {
{
.compatible = "fsl,imx6sl-mmdc",
.data = &imx6ul_data
}, {
.compatible = "fsl,imx6ul-mmdc",
.data = &imx6ul_data
}, {

View File

@ -61,10 +61,16 @@ static int imx_soc_from_dt(void)
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6sx"))
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6sl"))
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6qp"))
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx6ul"))
return IMX_CPU_IMX6;
if (of_machine_is_compatible("fsl,imx7s"))
return IMX_CPU_IMX7;
if (of_machine_is_compatible("fsl,imx7d"))
return IMX_CPU_IMX7;
if (of_machine_is_compatible("fsl,vf610"))
return IMX_CPU_VF610;
@ -103,6 +109,8 @@ static int imx_init(void)
ret = imx53_init();
else if (cpu_is_mx6())
ret = imx6_init();
else if (cpu_is_mx7())
ret = imx7_init();
else if (cpu_is_vf610())
ret = 0;
else

View File

@ -151,6 +151,9 @@ int imx6_init(void)
case IMX6_CPUTYPE_IMX6S:
cputypestr = "i.MX6 Solo";
break;
case IMX6_CPUTYPE_IMX6SL:
cputypestr = "i.MX6 SoloLite";
break;
case IMX6_CPUTYPE_IMX6SX:
cputypestr = "i.MX6 SoloX";
break;

202
arch/arm/mach-imx/imx7.c Normal file
View File

@ -0,0 +1,202 @@
/*
* 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 <init.h>
#include <common.h>
#include <io.h>
#include <linux/sizes.h>
#include <asm/psci.h>
#include <mach/imx7.h>
#include <mach/generic.h>
#include <mach/revision.h>
#include <mach/imx7-regs.h>
void imx7_init_lowlevel(void)
{
void __iomem *aips1 = IOMEM(MX7_AIPS1_CONFIG_BASE_ADDR);
void __iomem *aips2 = IOMEM(MX7_AIPS2_CONFIG_BASE_ADDR);
/*
* Set all MPROTx to be non-bufferable, trusted for R/W,
* not forced to user-mode.
*/
writel(0x77777777, aips1);
writel(0x77777777, aips1 + 0x4);
writel(0, aips1 + 0x40);
writel(0, aips1 + 0x44);
writel(0, aips1 + 0x48);
writel(0, aips1 + 0x4c);
writel(0, aips1 + 0x50);
writel(0x77777777, aips2);
writel(0x77777777, aips2 + 0x4);
writel(0, aips2 + 0x40);
writel(0, aips2 + 0x44);
writel(0, aips2 + 0x48);
writel(0, aips2 + 0x4c);
writel(0, aips2 + 0x50);
}
#define SC_CNTCR 0x0
#define SC_CNTSR 0x4
#define SC_CNTCV1 0x8
#define SC_CNTCV2 0xc
#define SC_CNTFID0 0x20
#define SC_CNTFID1 0x24
#define SC_CNTFID2 0x28
#define SC_counterid 0xfcc
#define SC_CNTCR_ENABLE (1 << 0)
#define SC_CNTCR_HDBG (1 << 1)
#define SC_CNTCR_FREQ0 (1 << 8)
#define SC_CNTCR_FREQ1 (1 << 9)
static int imx7_timer_init(void)
{
void __iomem *sctr = IOMEM(MX7_SYSCNT_CTRL_BASE_ADDR);
unsigned long val, freq;
freq = 8000000;
asm("mcr p15, 0, %0, c14, c0, 0" : : "r" (freq));
writel(freq, sctr + SC_CNTFID0);
/* Enable system counter */
val = readl(sctr + SC_CNTCR);
val &= ~(SC_CNTCR_FREQ0 | SC_CNTCR_FREQ1);
val |= SC_CNTCR_FREQ0 | SC_CNTCR_ENABLE | SC_CNTCR_HDBG;
writel(val, sctr + SC_CNTCR);
return 0;
}
#define CSU_NUM_REGS 64
#define CSU_INIT_SEC_LEVEL0 0x00FF00FF
static void imx7_init_csu(void)
{
void __iomem *csu = IOMEM(MX7_CSU_BASE_ADDR);
int i = 0;
for (i = 0; i < CSU_NUM_REGS; i++)
writel(CSU_INIT_SEC_LEVEL0, csu + i * 4);
}
#define GPC_CPU_PGC_SW_PDN_REQ 0xfc
#define GPC_CPU_PGC_SW_PUP_REQ 0xf0
#define GPC_PGC_C1 0x840
#define GPC_PGC(n) (0x800 + (n) * 0x40)
#define BM_CPU_PGC_SW_PDN_PUP_REQ_CORE1_A7 0x2
#define PGC_CTRL 0x0
/* below is for i.MX7D */
#define SRC_GPR1_MX7D 0x074
#define SRC_A7RCR1 0x008
static void imx_gpcv2_set_core_power(int core, bool pdn)
{
void __iomem *gpc = IOMEM(MX7_GPC_BASE_ADDR);
void __iomem *pgc = gpc + GPC_PGC(core);
u32 reg = pdn ? GPC_CPU_PGC_SW_PUP_REQ : GPC_CPU_PGC_SW_PDN_REQ;
u32 val;
writel(1, pgc + PGC_CTRL);
val = readl(gpc + reg);
val |= 1 << core;
writel(val, gpc + reg);
while (readl(gpc + reg) & (1 << core));
writel(0, pgc + PGC_CTRL);
}
static int imx7_cpu_on(u32 cpu_id)
{
void __iomem *src = IOMEM(MX7_SRC_BASE_ADDR);
u32 val;
writel(psci_cpu_entry, src + cpu_id * 8 + SRC_GPR1_MX7D);
imx_gpcv2_set_core_power(cpu_id, true);
val = readl(src + SRC_A7RCR1);
val |= 1 << cpu_id;
writel(val, src + SRC_A7RCR1);
return 0;
}
static int imx7_cpu_off(void)
{
void __iomem *src = IOMEM(MX7_SRC_BASE_ADDR);
u32 val;
int cpu_id = psci_get_cpu_id();
val = readl(src + SRC_A7RCR1);
val &= ~(1 << cpu_id);
writel(val, src + SRC_A7RCR1);
/*
* FIXME: This reads nice and symmetrically to cpu_on above,
* but of course this will never be reached as we have just
* put the CPU we are currently running on into reset.
*/
imx_gpcv2_set_core_power(cpu_id, false);
while (1);
return 0;
}
static struct psci_ops imx7_psci_ops = {
.cpu_on = imx7_cpu_on,
.cpu_off = imx7_cpu_off,
};
int imx7_init(void)
{
const char *cputypestr;
u32 imx7_silicon_revision;
imx7_init_lowlevel();
imx7_init_csu();
imx7_timer_init();
imx7_boot_save_loc();
imx7_silicon_revision = imx7_cpu_revision();
psci_set_ops(&imx7_psci_ops);
switch (imx7_cpu_type()) {
case IMX7_CPUTYPE_IMX7D:
cputypestr = "i.MX7d";
break;
case IMX7_CPUTYPE_IMX7S:
cputypestr = "i.MX7s";
break;
default:
cputypestr = "unknown i.MX7";
break;
}
imx_set_silicon_revision(cputypestr, imx7_silicon_revision);
return 0;
}

View File

@ -14,6 +14,7 @@
#include <mach/imx51-regs.h>
#include <mach/imx53-regs.h>
#include <mach/imx6-regs.h>
#include <mach/imx7-regs.h>
#include <mach/vf610-regs.h>
#include <serial/imx-uart.h>
@ -44,6 +45,8 @@
#define IMX_DEBUG_SOC MX53
#elif defined CONFIG_DEBUG_IMX6Q_UART
#define IMX_DEBUG_SOC MX6
#elif defined CONFIG_DEBUG_IMX7D_UART
#define IMX_DEBUG_SOC MX7
#elif defined CONFIG_DEBUG_VF610_UART
#define IMX_DEBUG_SOC VF610
#else

View File

@ -14,12 +14,14 @@ void imx27_boot_save_loc(void);
void imx51_boot_save_loc(void);
void imx53_boot_save_loc(void);
void imx6_boot_save_loc(void);
void imx7_boot_save_loc(void);
void imx25_get_boot_source(enum bootsource *src, int *instance);
void imx35_get_boot_source(enum bootsource *src, int *instance);
void imx51_get_boot_source(enum bootsource *src, int *instance);
void imx53_get_boot_source(enum bootsource *src, int *instance);
void imx6_get_boot_source(enum bootsource *src, int *instance);
void imx7_get_boot_source(enum bootsource *src, int *instance);
int imx1_init(void);
int imx21_init(void);
@ -31,6 +33,7 @@ int imx50_init(void);
int imx51_init(void);
int imx53_init(void);
int imx6_init(void);
int imx7_init(void);
int imx1_devices_init(void);
int imx21_devices_init(void);
@ -45,6 +48,7 @@ int imx6_devices_init(void);
void imx5_cpu_lowlevel_init(void);
void imx6_cpu_lowlevel_init(void);
void imx7_cpu_lowlevel_init(void);
void vf610_cpu_lowlevel_init(void);
/* There's a off-by-one betweem the gpio bank number and the gpiochip */
@ -174,6 +178,18 @@ extern unsigned int __imx_cpu_type;
# define cpu_is_mx6() (0)
#endif
#ifdef CONFIG_ARCH_IMX7
# ifdef imx_cpu_type
# undef imx_cpu_type
# define imx_cpu_type __imx_cpu_type
# else
# define imx_cpu_type IMX_CPU_IMX7
# endif
# define cpu_is_mx7() (imx_cpu_type == IMX_CPU_IMX7)
#else
# define cpu_is_mx7() (0)
#endif
#ifdef CONFIG_ARCH_VF610
# ifdef imx_cpu_type
# undef imx_cpu_type

View File

@ -1,62 +1,22 @@
#ifndef __MACH_IMX_IMX6_OCOTP_H
#define __MACH_IMX_IMX6_OCOTP_H
#include <mach/ocotp.h>
#include <mach/ocotp-fusemap.h>
#define IMX6_OCOTP_TESTER_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(0) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_BOOT_CFG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(2) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_MEM_TRIM_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(4) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_SJC_RESP_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(6) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_MAC_ADDR_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(8) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_GP1_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(10) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_GP2_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(12) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_SRK_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(14) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_ANALOG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(18) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_MISC_CONF_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(22) | OCOTP_WIDTH(1))
/* 0 <= n <= 1 */
#define IMX6_OCOTP_UNIQUE_ID(n) (OCOTP_WORD(0x410 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define IMX6_OCOTP_SI_REV (OCOTP_WORD(0x430) | OCOTP_BIT(16) | OCOTP_WIDTH(4))
#define IMX6_OCOTP_NUM_CORES (OCOTP_WORD(0x430) | OCOTP_BIT(20) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_SATA_RST_SRC (OCOTP_WORD(0x430) | OCOTP_BIT(24) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_MLB_DISABLE (OCOTP_WORD(0x430) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_VPU_DISABLE (OCOTP_WORD(0x440) | OCOTP_BIT(15) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_SPEED_GRADING (OCOTP_WORD(0x440) | OCOTP_BIT(16) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_BOOT_CFG1 (OCOTP_WORD(0x450) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_BOOT_CFG2 (OCOTP_WORD(0x450) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_BOOT_CFG3 (OCOTP_WORD(0x450) | OCOTP_BIT(16) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_BOOT_CFG4 (OCOTP_WORD(0x450) | OCOTP_BIT(24) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_SEC_CONFIG (OCOTP_WORD(0x460) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_DIR_BT_DIS (OCOTP_WORD(0x460) | OCOTP_BIT(3) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_BT_FUSE_SEL (OCOTP_WORD(0x460) | OCOTP_BIT(4) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_DDR3_CONFIG (OCOTP_WORD(0x460) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_HDCP (OCOTP_WORD(0x460) | OCOTP_BIT(16) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_SJC_DISABLE (OCOTP_WORD(0x460) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_WDOG_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(21) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_JTAG_SMODE (OCOTP_WORD(0x460) | OCOTP_BIT(22) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_KTE (OCOTP_WORD(0x460) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_JTAG_HEO (OCOTP_WORD(0x460) | OCOTP_BIT(27) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_TZASC_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(28) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_SDMMC_HYS_EN (OCOTP_WORD(0x460) | OCOTP_BIT(29) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_eMMC_RESET_EN (OCOTP_WORD(0x460) | OCOTP_BIT(30) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_NAND_READ_CMD_CODE1 (OCOTP_WORD(0x470) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_NAND_READ_CMD_CODE2 (OCOTP_WORD(0x470) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
#define IMX6_OCOTP_BT_LPB_POLARITY (OCOTP_WORD(0x470) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_LPB_BOOT (OCOTP_WORD(0x470) | OCOTP_BIT(21) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_MMC_DLL_DLY (OCOTP_WORD(0x470) | OCOTP_BIT(24) | OCOTP_WIDTH(7))
#define IMX6_OCOTP_TEMPERATURE_GRADE (OCOTP_WORD(0x480) | OCOTP_BIT(6) | OCOTP_WIDTH(2))
#define IMX6_OCOTP_POWER_GATE_CORES (OCOTP_WORD(0x4d0) | OCOTP_BIT(31) | OCOTP_WIDTH(1))
#define IMX6_OCOTP_USB_VID (OCOTP_WORD(0x4f0) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
#define IMX6_OCOTP_USB_PID (OCOTP_WORD(0x4f0) | OCOTP_BIT(16) | OCOTP_WIDTH(16))
/* 0 <= n <= 7 */
#define IMX6_OCOTP_SRK_HASH(n) (OCOTP_WORD(0x580 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define IMX6_OCOTP_SJC_RESP_31_0 (OCOTP_WORD(0x600) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define IMX6_OCOTP_SJC_RESP_55_32 (OCOTP_WORD(0x610) | OCOTP_BIT(0) | OCOTP_WIDTH(24))
#define IMX6_OCOTP_MAC_ADDR_31_0 (OCOTP_WORD(0x620) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define IMX6_OCOTP_MAC_ADDR_47_32 (OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
#define IMX6_OCOTP_GP1 (OCOTP_WORD(0x660) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define IMX6_OCOTP_GP2 (OCOTP_WORD(0x670) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define IMX6_OCOTP_PAD_SETTINGS (OCOTP_WORD(0x6d0) | OCOTP_BIT(0) | OCOTP_WIDTH(6))
#define IMX6DQ_OCOTP_TEST_PORT_DISABLE (OCOTP_WORD(0x6e0) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
#define IMX6SDL_OCOTP_FIELD_RETURN (OCOTP_WORD(0x6e0) | OCOTP_BIT(0) | OCOTP_WIDTH(1))

View File

@ -9,7 +9,9 @@
void imx6_init_lowlevel(void);
#define IMX6_ANATOP_SI_REV 0x260
#define IMX6SL_ANATOP_SI_REV 0x280
#define IMX6_CPUTYPE_IMX6SL 0x160
#define IMX6_CPUTYPE_IMX6S 0x161
#define IMX6_CPUTYPE_IMX6DL 0x261
#define IMX6_CPUTYPE_IMX6SX 0x462
@ -36,6 +38,16 @@ static inline int __imx6_cpu_type(void)
val = readl(MX6_ANATOP_BASE_ADDR + IMX6_ANATOP_SI_REV);
val = (val >> 16) & 0xff;
/* non-MX6-standard SI_REV reg offset for MX6SL */
if (IS_ENABLED(CONFIG_ARCH_IMX6SL) &&
val < (IMX6_CPUTYPE_IMX6S & 0xff)) {
uint32_t tmp;
tmp = readl(MX6_ANATOP_BASE_ADDR + IMX6SL_ANATOP_SI_REV);
tmp = (tmp >> 16) & 0xff;
if ((IMX6_CPUTYPE_IMX6SL & 0xff) == tmp)
/* intentionally skip scu_get_core_count() for MX6SL */
return IMX6_CPUTYPE_IMX6SL;
}
val |= scu_get_core_count() << 8;
@ -50,12 +62,37 @@ static inline int imx6_cpu_type(void)
return __imx6_cpu_type();
}
#define DEFINE_MX6_CPU_TYPE(str, type) \
static inline int cpu_mx6_is_##str(void) \
{ \
return __imx6_cpu_type() == type; \
} \
\
static inline int cpu_is_##str(void) \
{ \
if (!cpu_is_mx6()) \
return 0; \
return cpu_mx6_is_##str(); \
}
DEFINE_MX6_CPU_TYPE(mx6s, IMX6_CPUTYPE_IMX6S);
DEFINE_MX6_CPU_TYPE(mx6dl, IMX6_CPUTYPE_IMX6DL);
DEFINE_MX6_CPU_TYPE(mx6q, IMX6_CPUTYPE_IMX6Q);
DEFINE_MX6_CPU_TYPE(mx6d, IMX6_CPUTYPE_IMX6D);
DEFINE_MX6_CPU_TYPE(mx6sx, IMX6_CPUTYPE_IMX6SX);
DEFINE_MX6_CPU_TYPE(mx6sl, IMX6_CPUTYPE_IMX6SL);
DEFINE_MX6_CPU_TYPE(mx6ul, IMX6_CPUTYPE_IMX6UL);
static inline int __imx6_cpu_revision(void)
{
uint32_t rev;
uint32_t si_rev_offset = IMX6_ANATOP_SI_REV;
rev = readl(MX6_ANATOP_BASE_ADDR + IMX6_ANATOP_SI_REV);
if (IS_ENABLED(CONFIG_ARCH_IMX6SL) && cpu_mx6_is_mx6sl())
si_rev_offset = IMX6SL_ANATOP_SI_REV;
rev = readl(MX6_ANATOP_BASE_ADDR + si_rev_offset);
switch (rev & 0xfff) {
case 0x00:
@ -85,24 +122,4 @@ static inline int imx6_cpu_revision(void)
return __imx6_cpu_revision();
}
#define DEFINE_MX6_CPU_TYPE(str, type) \
static inline int cpu_mx6_is_##str(void) \
{ \
return __imx6_cpu_type() == type; \
} \
\
static inline int cpu_is_##str(void) \
{ \
if (!cpu_is_mx6()) \
return 0; \
return cpu_mx6_is_##str(); \
}
DEFINE_MX6_CPU_TYPE(mx6s, IMX6_CPUTYPE_IMX6S);
DEFINE_MX6_CPU_TYPE(mx6dl, IMX6_CPUTYPE_IMX6DL);
DEFINE_MX6_CPU_TYPE(mx6q, IMX6_CPUTYPE_IMX6Q);
DEFINE_MX6_CPU_TYPE(mx6d, IMX6_CPUTYPE_IMX6D);
DEFINE_MX6_CPU_TYPE(mx6sx, IMX6_CPUTYPE_IMX6SX);
DEFINE_MX6_CPU_TYPE(mx6ul, IMX6_CPUTYPE_IMX6UL);
#endif /* __MACH_IMX6_H */

View File

@ -0,0 +1,119 @@
#ifndef __MACH_IMX7_REGS_H
#define __MACH_IMX7_REGS_H
/* Defines for Blocks connected via AIPS */
#define MX7_AIPS1_BASE_ADDR 0x30000000
#define MX7_AIPS2_BASE_ADDR 0x30400000
#define MX7_AIPS3_BASE_ADDR 0x30800000
/* ATZ#1- On Platform */
#define MX7_DAP_BASE_ADDR (MX7_AIPS1_BASE_ADDR)
#define MX7_AIPS1_CONFIG_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x1F0000)
/* ATZ#1- Off Platform */
#define MX7_GPIO1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x200000)
#define MX7_GPIO2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x210000)
#define MX7_GPIO3_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x220000)
#define MX7_GPIO4_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x230000)
#define MX7_GPIO5_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x240000)
#define MX7_GPIO6_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x250000)
#define MX7_GPIO7_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x260000)
#define MX7_IOMUXC_LPSR_GPR_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x270000)
#define MX7_WDOG1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x280000)
#define MX7_WDOG2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x290000)
#define MX7_WDOG3_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2A0000)
#define MX7_WDOG4_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2B0000)
#define MX7_IOMUXC_LPSR_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2C0000)
#define MX7_GPT1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2D0000)
#define MX7_GPT2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2E0000)
#define MX7_GPT3_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x2F0000)
#define MX7_GPT4_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x300000)
#define MX7_ROMCP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x310000)
#define MX7_KPP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x320000)
#define MX7_IOMUXC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x330000)
#define MX7_IOMUXC_GPR_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x340000)
#define MX7_OCOTP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x350000)
#define MX7_ANATOP_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x360000)
#define MX7_SNVS_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x370000)
#define MX7_CCM_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x380000)
#define MX7_SRC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x390000)
#define MX7_GPC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3A0000)
#define MX7_SEMAPHORE1_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3B0000)
#define MX7_SEMAPHORE2_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3C0000)
#define MX7_RDC_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3D0000)
#define MX7_CSU_BASE_ADDR (MX7_AIPS1_BASE_ADDR + 0x3E0000)
/* ATZ#2- On Platform */
#define MX7_AIPS2_CONFIG_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x1F0000)
/* ATZ#2- Off Platform */
#define MX7_ADC1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x230000)
#define MX7_ADC2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x230000)
#define MX7_ECSPI4_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x230000)
#define MX7_FTM1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x240000)
#define MX7_FTM2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x250000)
#define MX7_PWM1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x260000)
#define MX7_PWM2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x270000)
#define MX7_PWM3_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x280000)
#define MX7_PWM4_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x290000)
#define MX7_SYSCNT_RD_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2A0000)
#define MX7_SYSCNT_CMP_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2B0000)
#define MX7_SYSCNT_CTRL_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2C0000)
#define MX7_PCIE_PHY_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2D0000)
#define MX7_EPDC_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x2F0000)
#define MX7_PXP_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x300000)
#define MX7_CSI_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x310000)
#define MX7_LCDIF_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x330000)
#define MX7_MIPI_CSI_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x350000)
#define MX7_MIPI_DSI_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x360000)
#define MX7_TZASC_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x380000)
#define MX7_DDRPHY_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x390000)
#define MX7_DDRC_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3A0000)
#define MX7_IP2APB_PERFMON1_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3C0000)
#define MX7_IP2APB_PERFMON2_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3D0000)
#define MX7_AXI_DEBUG_MON_BASE_ADDR (MX7_AIPS2_BASE_ADDR + 0x3E0000)
/* ATZ#3- On Platform */
#define MX7_ECSPI1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x20000)
#define MX7_ECSPI2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x30000)
#define MX7_ECSPI3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x40000)
#define MX7_UART1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x60000)
#define MX7_UART2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x70000)
#define MX7_UART3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x80000)
#define MX7_SAI1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0xA0000)
#define MX7_SAI2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0xB0000)
#define MX7_SAI3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0xC0000)
#define MX7_SPBA_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x90000)
#define MX7_CAAM_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x100000)
#define MX7_AIPS3_CONFIG_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x1F0000)
/* ATZ#3- Off Platform */
#define MX7_CAN1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x200000)
#define MX7_CAN2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x210000)
#define MX7_I2C1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x220000)
#define MX7_I2C2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x230000)
#define MX7_I2C3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x240000)
#define MX7_I2C4_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x250000)
#define MX7_UART4_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x260000)
#define MX7_UART5_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x270000)
#define MX7_UART6_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x280000)
#define MX7_UART7_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x290000)
#define MX7_MU_A_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2A0000)
#define MX7_MU_B_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2B0000)
#define MX7_SEM_HS_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2C0000)
#define MX7_USBOH2_PL301_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x2D0000)
#define MX7_OTG1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x310000)
#define MX7_OTG2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x320000)
#define MX7_USBOH3_USB_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x330000)
#define MX7_USDHC1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x340000)
#define MX7_USDHC2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x350000)
#define MX7_USDHC3_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x360000)
#define MX7_SIM1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x390000)
#define MX7_SIM2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3A0000)
#define MX7_QSPI_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3B0000)
#define MX7_WEIM_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3C0000)
#define MX7_SDMA_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3D0000)
#define MX7_ENET1_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3E0000)
#define MX7_ENET2_BASE_ADDR (MX7_AIPS3_BASE_ADDR + 0x3F0000)
#endif /* __MACH_IMX7_REGS_H */

View File

@ -0,0 +1,59 @@
#ifndef __MACH_IMX7_H
#define __MACH_IMX7_H
#include <io.h>
#include <mach/generic.h>
#include <mach/imx7-regs.h>
#include <mach/revision.h>
void imx7_init_lowlevel(void);
#define ANADIG_DIGPROG_IMX7 0x800
#define IMX7_CPUTYPE_IMX7S 0x71
#define IMX7_CPUTYPE_IMX7D 0x72
static inline int __imx7_cpu_type(void)
{
void __iomem *ocotp = IOMEM(MX7_OCOTP_BASE_ADDR);
if (readl(ocotp + 0x450) & 1)
return IMX7_CPUTYPE_IMX7S;
else
return IMX7_CPUTYPE_IMX7D;
}
static inline int imx7_cpu_type(void)
{
if (!cpu_is_mx7())
return 0;
return __imx7_cpu_type();
}
static inline int imx7_cpu_revision(void)
{
if (!cpu_is_mx7())
return IMX_CHIP_REV_UNKNOWN;
/* register value has the format of the IMX_CHIP_REV_* macros */
return readl(MX7_ANATOP_BASE_ADDR + ANADIG_DIGPROG_IMX7) & 0xff;
}
#define DEFINE_MX7_CPU_TYPE(str, type) \
static inline int cpu_mx7_is_##str(void) \
{ \
return __imx7_cpu_type() == type; \
} \
\
static inline int cpu_is_##str(void) \
{ \
if (!cpu_is_mx7()) \
return 0; \
return cpu_mx7_is_##str(); \
}
DEFINE_MX7_CPU_TYPE(mx7s, IMX7_CPUTYPE_IMX7S);
DEFINE_MX7_CPU_TYPE(mx7d, IMX7_CPUTYPE_IMX7D);
#endif /* __MACH_IMX7_H */

View File

@ -11,6 +11,7 @@
#define IMX_CPU_IMX51 51
#define IMX_CPU_IMX53 53
#define IMX_CPU_IMX6 6
#define IMX_CPU_IMX7 7
#define IMX_CPU_VF610 610
#endif /* __MACH_IMX_CPU_TYPES_H */

View File

@ -16,6 +16,8 @@
#ifndef __MACH_IOMUX_V3_H__
#define __MACH_IOMUX_V3_H__
#include <io.h>
/*
* build IOMUX_PAD structure
*
@ -76,6 +78,14 @@ typedef u64 iomux_v3_cfg_t;
((iomux_v3_cfg_t)(_sel_input_ofs) << MUX_SEL_INPUT_OFS_SHIFT) | \
((iomux_v3_cfg_t)(_sel_input) << MUX_SEL_INPUT_SHIFT))
#define IOMUX_PAD_FIELD(name, pad) (((pad) & name##_MASK) >> name##_SHIFT)
#define IOMUX_CTRL_OFS(pad) IOMUX_PAD_FIELD(MUX_CTRL_OFS, pad)
#define IOMUX_MODE(pad) IOMUX_PAD_FIELD(MUX_MODE, pad)
#define IOMUX_SEL_INPUT_OFS(pad) IOMUX_PAD_FIELD(MUX_SEL_INPUT_OFS, pad)
#define IOMUX_SEL_INPUT(pad) IOMUX_PAD_FIELD(MUX_SEL_INPUT, pad)
#define IOMUX_PAD_CTRL_OFS(pad) IOMUX_PAD_FIELD(MUX_PAD_CTRL_OFS, pad)
#define IOMUX_PAD_CTRL(pad) IOMUX_PAD_FIELD(MUX_PAD_CTRL, pad)
#define NEW_PAD_CTRL(cfg, pad) (((cfg) & ~MUX_PAD_CTRL_MASK) | MUX_PAD_CTRL(pad))
/*
* Use to set PAD control
@ -104,6 +114,57 @@ typedef u64 iomux_v3_cfg_t;
#define IOMUX_CONFIG_SION (0x1 << 4)
#define SHARE_MUX_CONF_REG 0x1
#define ZERO_OFFSET_VALID 0x2
#define IMX7_PINMUX_LPSR 0x4
static inline void iomux_v3_setup_pad(void __iomem *iomux, unsigned int flags,
u32 mux_reg, u32 conf_reg, u32 input_reg,
u32 mux_val, u32 conf_val, u32 input_val)
{
const bool mux_ok = !!mux_reg || (flags & ZERO_OFFSET_VALID);
const bool conf_ok = !!conf_reg;
const bool input_ok = !!input_reg;
/*
* The sel_input registers for the LPSR controller pins are in the regular pinmux
* controller, so bend the register offset over to the other controller.
*/
if (flags & IMX7_PINMUX_LPSR)
input_reg += 0x70000;
if (flags & SHARE_MUX_CONF_REG) {
mux_val |= conf_val;
} else {
if (conf_ok)
writel(conf_val, iomux + conf_reg);
}
if (mux_ok)
writel(mux_val, iomux + mux_reg);
if (input_ok)
writel(input_val, iomux + input_reg);
}
static inline void imx_setup_pad(void __iomem *iomux, iomux_v3_cfg_t pad)
{
uint32_t pad_ctrl;
pad_ctrl = IOMUX_PAD_CTRL(pad);
pad_ctrl = (pad_ctrl & NO_PAD_CTRL) ? 0 : pad_ctrl,
iomux_v3_setup_pad(iomux, 0,
IOMUX_CTRL_OFS(pad),
IOMUX_PAD_CTRL_OFS(pad),
IOMUX_SEL_INPUT_OFS(pad),
IOMUX_MODE(pad),
pad_ctrl,
IOMUX_SEL_INPUT(pad));
}
/*
* setups a single pad in the iomuxer
*/

View File

@ -163,9 +163,13 @@ enum {
VF610_PAD_PTD22__NF_IO6 = IOMUX_PAD(0x0120, 0x0120, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD21__NF_IO5 = IOMUX_PAD(0x0124, 0x0124, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD20__NF_IO4 = IOMUX_PAD(0x0128, 0x0128, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD19__GPIO_75 = IOMUX_PAD(0x012C, 0x012C, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD19__NF_IO3 = IOMUX_PAD(0x012c, 0x012c, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD18__GPIO_76 = IOMUX_PAD(0x0120, 0x0130, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD18__NF_IO2 = IOMUX_PAD(0x0130, 0x0130, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD17__GPIO_77 = IOMUX_PAD(0x0134, 0x0134, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD17__NF_IO1 = IOMUX_PAD(0x0134, 0x0134, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTD16__GPIO_78 = IOMUX_PAD(0x0138, 0x0138, 0, __NA_, 0, VF610_GPIO_PAD_CTRL),
VF610_PAD_PTD16__NF_IO0 = IOMUX_PAD(0x0138, 0x0138, 2, __NA_, 0, VF610_NFC_IO_PAD_CTRL),
VF610_PAD_PTB24__NF_WE_B = IOMUX_PAD(0x0178, 0x0178, 5, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
VF610_PAD_PTB25__NF_CE0_B = IOMUX_PAD(0x017c, 0x017c, 5, __NA_, 0, VF610_NFC_CN_PAD_CTRL),
@ -223,4 +227,19 @@ enum {
VF610_PAD_DDR_ODT0__DDR_ODT_1 = IOMUX_PAD(0x02d8, 0x02d8, 0, __NA_, 0, VF610_DDR_PAD_CTRL),
};
#define PINCTRL_VF610_MUX_SHIFT 20
static inline void vf610_setup_pad(void __iomem *iomux, iomux_v3_cfg_t pad)
{
iomux_v3_setup_pad(iomux, SHARE_MUX_CONF_REG | ZERO_OFFSET_VALID,
IOMUX_CTRL_OFS(pad),
IOMUX_PAD_CTRL_OFS(pad),
IOMUX_SEL_INPUT_OFS(pad),
IOMUX_MODE(pad) << PINCTRL_VF610_MUX_SHIFT,
IOMUX_PAD_CTRL(pad),
IOMUX_SEL_INPUT(pad));
}
#endif /* __IOMUX_VF610_H__ */

View File

@ -0,0 +1,49 @@
#ifndef __MACH_IMX_OCOTP_FUSEMAP_H
#define __MACH_IMX_OCOTP_FUSEMAP_H
#include <mach/ocotp.h>
#define OCOTP_TESTER_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(0) | OCOTP_WIDTH(2))
#define OCOTP_BOOT_CFG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(2) | OCOTP_WIDTH(2))
#define OCOTP_MEM_TRIM_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(4) | OCOTP_WIDTH(2))
#define OCOTP_SJC_RESP_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(6) | OCOTP_WIDTH(1))
#define OCOTP_MAC_ADDR_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(8) | OCOTP_WIDTH(2))
#define OCOTP_GP1_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(10) | OCOTP_WIDTH(2))
#define OCOTP_GP2_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(12) | OCOTP_WIDTH(2))
#define OCOTP_SRK_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(14) | OCOTP_WIDTH(1))
#define OCOTP_ANALOG_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(18) | OCOTP_WIDTH(2))
#define OCOTP_MISC_CONF_LOCK (OCOTP_WORD(0x400) | OCOTP_BIT(22) | OCOTP_WIDTH(1))
/* 0 <= n <= 1 */
#define OCOTP_UNIQUE_ID(n) (OCOTP_WORD(0x410 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define OCOTP_NUM_CORES (OCOTP_WORD(0x430) | OCOTP_BIT(20) | OCOTP_WIDTH(2))
#define OCOTP_MLB_DISABLE (OCOTP_WORD(0x430) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
#define OCOTP_BOOT_CFG1 (OCOTP_WORD(0x450) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
#define OCOTP_BOOT_CFG2 (OCOTP_WORD(0x450) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
#define OCOTP_BOOT_CFG3 (OCOTP_WORD(0x450) | OCOTP_BIT(16) | OCOTP_WIDTH(8))
#define OCOTP_BOOT_CFG4 (OCOTP_WORD(0x450) | OCOTP_BIT(24) | OCOTP_WIDTH(8))
#define OCOTP_SEC_CONFIG_1 (OCOTP_WORD(0x460) | OCOTP_BIT(1) | OCOTP_WIDTH(1))
#define OCOTP_DIR_BT_DIS (OCOTP_WORD(0x460) | OCOTP_BIT(3) | OCOTP_WIDTH(1))
#define OCOTP_BT_FUSE_SEL (OCOTP_WORD(0x460) | OCOTP_BIT(4) | OCOTP_WIDTH(1))
#define OCOTP_SJC_DISABLE (OCOTP_WORD(0x460) | OCOTP_BIT(20) | OCOTP_WIDTH(1))
#define OCOTP_WDOG_ENABLE (OCOTP_WORD(0x460) | OCOTP_BIT(21) | OCOTP_WIDTH(1))
#define OCOTP_JTAG_SMODE (OCOTP_WORD(0x460) | OCOTP_BIT(22) | OCOTP_WIDTH(2))
#define OCOTP_KTE (OCOTP_WORD(0x460) | OCOTP_BIT(26) | OCOTP_WIDTH(1))
#define OCOTP_JTAG_HEO (OCOTP_WORD(0x460) | OCOTP_BIT(27) | OCOTP_WIDTH(1))
#define OCOTP_NAND_READ_CMD_CODE1 (OCOTP_WORD(0x470) | OCOTP_BIT(0) | OCOTP_WIDTH(8))
#define OCOTP_NAND_READ_CMD_CODE2 (OCOTP_WORD(0x470) | OCOTP_BIT(8) | OCOTP_WIDTH(8))
#define OCOTP_TEMP_SENSE (OCOTP_WORD(0x4e0) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define OCOTP_USB_VID (OCOTP_WORD(0x4f0) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
#define OCOTP_USB_PID (OCOTP_WORD(0x4f0) | OCOTP_BIT(16) | OCOTP_WIDTH(16))
/* 0 <= n <= 7 */
#define OCOTP_SRK_HASH(n) (OCOTP_WORD(0x580 + 0x10 * (n)) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define OCOTP_SJC_RESP_31_0 (OCOTP_WORD(0x600) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define OCOTP_SJC_RESP_55_32 (OCOTP_WORD(0x610) | OCOTP_BIT(0) | OCOTP_WIDTH(24))
#define OCOTP_MAC_ADDR_31_0 (OCOTP_WORD(0x620) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define OCOTP_MAC_ADDR_47_32 (OCOTP_WORD(0x630) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
#define OCOTP_GP1 (OCOTP_WORD(0x660) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define OCOTP_GP2 (OCOTP_WORD(0x670) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define OCOTP_PAD_SETTINGS (OCOTP_WORD(0x6d0) | OCOTP_BIT(0) | OCOTP_WIDTH(6))
#endif /* __MACH_IMX_OCOTP_FUSEMAP_H */

View File

@ -16,5 +16,6 @@
int imx_ocotp_read_field(uint32_t field, unsigned *value);
int imx_ocotp_write_field(uint32_t field, unsigned value);
int imx_ocotp_permanent_write(int enable);
bool imx_ocotp_sense_enable(bool enable);
#endif /* __MACH_IMX_OCOTP_H */

View File

@ -0,0 +1,15 @@
#ifndef __MACH_VF610_OCOTP_H
#define __MACH_VF610_OCOTP_H
#include <mach/ocotp-fusemap.h>
#define VF610_OCOTP_CPU_BUS_FRQ OCOTP_WORD(0x430) | OCOTP_BIT(22) | OCOTP_WIDTH(1)
#define VF610_OCOTP_OVG_DISABLE OCOTP_WORD(0x430) | OCOTP_BIT(30) | OCOTP_WIDTH(1)
#define VF610_OCOTP_SEC_CONFIG_0 OCOTP_WORD(0x440) | OCOTP_BIT(1) | OCOTP_WIDTH(1)
#define VF610_OCOTP_SPEED_GRADING OCOTP_WORD(0x440) | OCOTP_BIT(18) | OCOTP_WIDTH(4)
#define VF610_OCOTP_MAC_ADDR0_31_0 OCOTP_MAC_ADDR_31_0
#define VF610_OCOTP_MAC_ADDR0_47_32 OCOTP_MAC_ADDR_47_32
#define VF610_OCOTP_MAC_ADDR1_31_0 (OCOTP_WORD(0x640) | OCOTP_BIT(0) | OCOTP_WIDTH(32))
#define VF610_OCOTP_MAC_ADDR1_47_32 (OCOTP_WORD(0x650) | OCOTP_BIT(0) | OCOTP_WIDTH(16))
#endif

View File

@ -69,12 +69,22 @@
/* Other definitions */
#define IMX6_OTP_DATA_ERROR_VAL 0xBADABADA
#define DEF_RELAX 20
#define MAC_OFFSET (0x22 * 4)
#define MAC_OFFSET_0 (0x22 * 4)
#define MAC_OFFSET_1 (0x24 * 4)
#define MAX_MAC_OFFSETS 2
#define MAC_BYTES 8
struct imx_ocotp_data {
int num_regs;
u32 (*addr_to_offset)(u32 addr);
u8 mac_offsets[MAX_MAC_OFFSETS];
u8 mac_offsets_num;
};
struct ocotp_priv_ethaddr {
char value[MAC_BYTES];
struct regmap *map;
u8 offset;
};
struct ocotp_priv {
@ -84,9 +94,10 @@ struct ocotp_priv {
struct device_d dev;
int permanent_write_enable;
int sense_enable;
char ethaddr[6];
struct ocotp_priv_ethaddr ethaddr[MAX_MAC_OFFSETS];
struct regmap_config map_config;
const struct imx_ocotp_data *data;
int mac_offset_idx;
};
static struct ocotp_priv *imx_ocotp;
@ -348,6 +359,13 @@ int imx_ocotp_permanent_write(int enable)
return 0;
}
bool imx_ocotp_sense_enable(bool enable)
{
const bool old_value = imx_ocotp->sense_enable;
imx_ocotp->sense_enable = enable;
return old_value;
}
static uint32_t inc_offset(uint32_t offset)
{
if ((offset & 0x3) == 0x3)
@ -397,37 +415,39 @@ static void imx_ocotp_init_dt(struct device_d *dev, void __iomem *base)
}
}
static void memreverse(void *dest, const void *src, size_t n)
{
char *destp = dest;
const char *srcp = src + n - 1;
while(n--)
*destp++ = *srcp--;
}
static int imx_ocotp_get_mac(struct param_d *param, void *priv)
{
struct ocotp_priv *ocotp_priv = priv;
char buf[8];
int i, ret;
char buf[MAC_BYTES];
int ret;
struct ocotp_priv_ethaddr *ethaddr = priv;
ret = regmap_bulk_read(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
ret = regmap_bulk_read(ethaddr->map, ethaddr->offset,
buf, MAC_BYTES);
if (ret < 0)
return ret;
for (i = 0; i < 6; i++)
ocotp_priv->ethaddr[i] = buf[5 - i];
memreverse(ethaddr->value, buf, 6);
return 0;
}
static int imx_ocotp_set_mac(struct param_d *param, void *priv)
{
struct ocotp_priv *ocotp_priv = priv;
char buf[8];
int i, ret;
char buf[MAC_BYTES];
struct ocotp_priv_ethaddr *ethaddr = priv;
for (i = 0; i < 6; i++)
buf[5 - i] = ocotp_priv->ethaddr[i];
buf[6] = 0; buf[7] = 0;
memreverse(buf, ethaddr->value, 6);
ret = regmap_bulk_write(ocotp_priv->map, MAC_OFFSET, buf, MAC_BYTES);
if (ret < 0)
return ret;
return 0;
return regmap_bulk_write(ethaddr->map, ethaddr->offset,
buf, MAC_BYTES);
}
static struct regmap_bus imx_ocotp_regmap_bus = {
@ -486,9 +506,28 @@ static int imx_ocotp_probe(struct device_d *dev)
NULL, NULL, &priv->permanent_write_enable, NULL);
}
if (IS_ENABLED(CONFIG_NET))
dev_add_param_mac(&(priv->dev), "mac_addr", imx_ocotp_set_mac,
imx_ocotp_get_mac, priv->ethaddr, priv);
if (IS_ENABLED(CONFIG_NET)) {
int i;
struct ocotp_priv_ethaddr *ethaddr;
for (i = 0; i < priv->data->mac_offsets_num; i++) {
ethaddr = &priv->ethaddr[i];
ethaddr->map = priv->map;
ethaddr->offset = priv->data->mac_offsets[i];
dev_add_param_mac(&priv->dev, xasprintf("mac_addr%d", i),
imx_ocotp_set_mac, imx_ocotp_get_mac,
ethaddr->value, ethaddr);
}
/*
* Alias to mac_addr0 for backwards compatibility
*/
ethaddr = &priv->ethaddr[0];
dev_add_param_mac(&priv->dev, "mac_addr",
imx_ocotp_set_mac, imx_ocotp_get_mac,
ethaddr->value, ethaddr);
}
dev_add_param_bool(&(priv->dev), "sense_enable", NULL, NULL, &priv->sense_enable, priv);
@ -527,16 +566,22 @@ static u32 vf610_addr_to_offset(u32 addr)
static struct imx_ocotp_data imx6q_ocotp_data = {
.num_regs = 512,
.addr_to_offset = imx6q_addr_to_offset,
.mac_offsets_num = 1,
.mac_offsets = { MAC_OFFSET_0 },
};
static struct imx_ocotp_data imx6sl_ocotp_data = {
.num_regs = 256,
.addr_to_offset = imx6sl_addr_to_offset,
.mac_offsets_num = 1,
.mac_offsets = { MAC_OFFSET_0 },
};
static struct imx_ocotp_data vf610_ocotp_data = {
.num_regs = 512,
.addr_to_offset = vf610_addr_to_offset,
.mac_offsets_num = 2,
.mac_offsets = { MAC_OFFSET_0, MAC_OFFSET_1 },
};
static __maybe_unused struct of_device_id imx_ocotp_dt_ids[] = {
@ -572,4 +617,4 @@ static int imx_ocotp_init(void)
return 0;
}
coredevice_initcall(imx_ocotp_init);
postcore_initcall(imx_ocotp_init);

View File

@ -1074,6 +1074,13 @@ config DEBUG_IMX6Q_UART
Say Y here if you want kernel low-level debugging support
on i.MX6Q.
config DEBUG_IMX7D_UART
bool "i.MX7D Debug UART"
depends on ARCH_IMX7
help
Say Y here if you want barebox low-level debugging support
on i.MX7D.
config DEBUG_VF610_UART
bool "VF610 Debug UART"
depends on ARCH_VF610
@ -1122,6 +1129,7 @@ config DEBUG_IMX_UART_PORT
DEBUG_IMX53_UART || \
DEBUG_IMX6Q_UART || \
DEBUG_IMX6SL_UART || \
DEBUG_IMX7D_UART || \
DEBUG_VF610_UART
default 1
depends on ARCH_IMX

View File

@ -1,6 +1,7 @@
obj-$(CONFIG_COMMON_CLK) += clk.o clk-fixed.o clk-divider.o clk-fixed-factor.o \
clk-mux.o clk-gate.o clk-composite.o \
clk-fractional-divider.o clk-conf.o
clk-fractional-divider.o clk-conf.o \
clk-gate-shared.o
obj-$(CONFIG_CLKDEV_LOOKUP) += clkdev.o
obj-$(CONFIG_ARCH_MVEBU) += mvebu/

View File

@ -0,0 +1,123 @@
/*
* clk-gate-shared.c - generic barebox clock support. Based on Linux clk support
*
* Copyright (c) 2017 Sascha Hauer <s.hauer@pengutronix.de>, 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 <common.h>
#include <io.h>
#include <malloc.h>
#include <linux/clk.h>
#include <linux/err.h>
struct clk_gate_shared {
struct clk clk;
const char *parent;
const char *companion_gate;
struct clk *companion_clk;
};
#define to_clk_gate_shared(_clk) container_of(_clk, struct clk_gate_shared, clk)
static struct clk *lookup_companion(struct clk_gate_shared *g)
{
if (IS_ERR(g->companion_clk))
g->companion_clk = clk_lookup(g->companion_gate);
if (IS_ERR(g->companion_clk))
return NULL;
return g->companion_clk;
}
static int clk_gate_shared_enable(struct clk *clk)
{
struct clk_gate_shared *g = to_clk_gate_shared(clk);
return clk_enable(lookup_companion(g));
}
static void clk_gate_shared_disable(struct clk *clk)
{
struct clk_gate_shared *g = to_clk_gate_shared(clk);
clk_disable(lookup_companion(g));
}
static int clk_gate_shared_is_enabled(struct clk *clk)
{
struct clk_gate_shared *g = to_clk_gate_shared(clk);
return clk_is_enabled(lookup_companion(g));
}
static struct clk_ops clk_gate_shared_ops = {
.set_rate = clk_parent_set_rate,
.round_rate = clk_parent_round_rate,
.enable = clk_gate_shared_enable,
.disable = clk_gate_shared_disable,
.is_enabled = clk_gate_shared_is_enabled,
};
struct clk *clk_gate_shared_alloc(const char *name, const char *parent, const char *companion,
unsigned flags)
{
struct clk_gate_shared *g = xzalloc(sizeof(*g));
g->parent = parent;
g->companion_gate = companion;
g->companion_clk = ERR_PTR(-EINVAL);
g->clk.ops = &clk_gate_shared_ops;
g->clk.name = name;
g->clk.flags = flags;
g->clk.parent_names = &g->parent;
g->clk.num_parents = 1;
return &g->clk;
}
void clk_gate_shared_free(struct clk *clk)
{
struct clk_gate_shared *g = to_clk_gate_shared(clk);
free(g);
}
/*
* clk_gate_shared - register a gate controlled by another gate
* @name: The name of the new clock gate
* @parent: The parent name of the new clock
* companion: The hardware gate this clock is controlled by
* @flags: common CLK_* flags
*
* This gate clock is used when a single software control knob controls multiple
* gates in hardware. The first gate is then registered as the real hardware gate,
* the others are registered with this function. This gate has no hardware control
* itself, but only enables/disabled its companion hardware gate.
*/
struct clk *clk_gate_shared(const char *name, const char *parent, const char *companion,
unsigned flags)
{
struct clk *clk;
int ret;
clk = clk_gate_shared_alloc(name , parent, companion, flags);
ret = clk_register(clk);
if (ret) {
clk_gate_shared_free(clk);
return ERR_PTR(ret);
}
return clk;
}

View File

@ -141,6 +141,7 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
{
struct clk *parent;
unsigned long parent_rate = 0;
int ret;
if (!clk)
return 0;
@ -148,14 +149,26 @@ int clk_set_rate(struct clk *clk, unsigned long rate)
if (IS_ERR(clk))
return PTR_ERR(clk);
if (!clk->ops->set_rate)
return -ENOSYS;
parent = clk_get_parent(clk);
if (parent)
if (parent) {
parent_rate = clk_get_rate(parent);
if (clk->ops->set_rate)
return clk->ops->set_rate(clk, rate, parent_rate);
if (clk->flags & CLK_OPS_PARENT_ENABLE) {
ret = clk_enable(parent);
if (ret)
return ret;
}
}
return -ENOSYS;
ret = clk->ops->set_rate(clk, rate, parent_rate);
if (parent && clk->flags & CLK_OPS_PARENT_ENABLE)
clk_disable(parent);
return ret;
}
struct clk *clk_lookup(const char *name)
@ -173,14 +186,15 @@ struct clk *clk_lookup(const char *name)
return ERR_PTR(-ENODEV);
}
int clk_set_parent(struct clk *clk, struct clk *parent)
int clk_set_parent(struct clk *clk, struct clk *newparent)
{
int i;
int i, ret;
struct clk *curparent = clk_get_parent(clk);
if (IS_ERR(clk))
return PTR_ERR(clk);
if (IS_ERR(parent))
return PTR_ERR(parent);
if (IS_ERR(newparent))
return PTR_ERR(newparent);
if (!clk->num_parents)
return -EINVAL;
@ -192,14 +206,32 @@ int clk_set_parent(struct clk *clk, struct clk *parent)
clk->parents[i] = clk_lookup(clk->parent_names[i]);
if (!IS_ERR_OR_NULL(clk->parents[i]))
if (clk->parents[i] == parent)
if (clk->parents[i] == newparent)
break;
}
if (i == clk->num_parents)
return -EINVAL;
return clk->ops->set_parent(clk, i);
if (clk->enable_count)
clk_enable(newparent);
if (clk->flags & CLK_OPS_PARENT_ENABLE) {
clk_enable(curparent);
clk_enable(newparent);
}
ret = clk->ops->set_parent(clk, i);
if (clk->flags & CLK_OPS_PARENT_ENABLE) {
clk_disable(curparent);
clk_disable(newparent);
}
if (clk->enable_count)
clk_disable(curparent);
return ret;
}
struct clk *clk_get_parent(struct clk *clk)

View File

@ -5,6 +5,7 @@ obj-$(CONFIG_COMMON_CLK) += \
clk-pfd.o \
clk-gate2.o \
clk-gate-exclusive.o \
clk-cpu.o \
clk.o
obj-$(CONFIG_ARCH_IMX1) += clk-imx1.o
@ -18,5 +19,7 @@ obj-$(CONFIG_ARCH_IMX51) += clk-imx5.o
obj-$(CONFIG_ARCH_IMX53) += clk-imx5.o
obj-$(CONFIG_ARCH_IMX6) += clk-imx6.o
obj-$(CONFIG_ARCH_IMX6SX) += clk-imx6sx.o
obj-$(CONFIG_ARCH_IMX6SL) += clk-imx6sl.o
obj-$(CONFIG_ARCH_IMX6UL) += clk-imx6ul.o
obj-$(CONFIG_ARCH_IMX7) += clk-imx7.o
obj-$(CONFIG_ARCH_VF610) += clk-vf610.o

110
drivers/clk/imx/clk-cpu.c Normal file
View File

@ -0,0 +1,110 @@
/*
* Copyright (c) 2014 Lucas Stach <l.stach@pengutronix.de>, Pengutronix
*
* 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.
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <common.h>
#include <init.h>
#include <driver.h>
#include <linux/clk.h>
#include <io.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <malloc.h>
#include <clock.h>
#include "clk.h"
struct clk_cpu {
struct clk clk;
struct clk *div;
struct clk *mux;
struct clk *pll;
struct clk *step;
};
static inline struct clk_cpu *to_clk_cpu(struct clk *clk)
{
return container_of(clk, struct clk_cpu, clk);
}
static unsigned long clk_cpu_recalc_rate(struct clk *clk,
unsigned long parent_rate)
{
struct clk_cpu *cpu = to_clk_cpu(clk);
return clk_get_rate(cpu->div);
}
static long clk_cpu_round_rate(struct clk *clk, unsigned long rate,
unsigned long *prate)
{
struct clk_cpu *cpu = to_clk_cpu(clk);
return clk_round_rate(cpu->pll, rate);
}
static int clk_cpu_set_rate(struct clk *clk, unsigned long rate,
unsigned long parent_rate)
{
struct clk_cpu *cpu = to_clk_cpu(clk);
int ret;
/* switch to PLL bypass clock */
ret = clk_set_parent(cpu->mux, cpu->step);
if (ret)
return ret;
/* reprogram PLL */
ret = clk_set_rate(cpu->pll, rate);
if (ret) {
clk_set_parent(cpu->mux, cpu->pll);
return ret;
}
/* switch back to PLL clock */
clk_set_parent(cpu->mux, cpu->pll);
/* Ensure the divider is what we expect */
clk_set_rate(cpu->div, rate);
return 0;
}
static const struct clk_ops clk_cpu_ops = {
.recalc_rate = clk_cpu_recalc_rate,
.round_rate = clk_cpu_round_rate,
.set_rate = clk_cpu_set_rate,
};
struct clk *imx_clk_cpu(const char *name, const char *parent_name,
struct clk *div, struct clk *mux, struct clk *pll,
struct clk *step)
{
struct clk_cpu *cpu;
int ret;
cpu = xzalloc(sizeof(*cpu));
cpu->div = div;
cpu->mux = mux;
cpu->pll = pll;
cpu->step = step;
cpu->clk.name = name;
cpu->clk.ops = &clk_cpu_ops;
cpu->clk.flags = 0;
cpu->clk.parent_names = &parent_name;
cpu->clk.num_parents = 1;
ret = clk_register(&cpu->clk);
if (ret)
free(cpu);
return &cpu->clk;
}

View File

@ -88,7 +88,8 @@ static struct clk_ops clk_gate2_ops = {
};
struct clk *clk_gate2_alloc(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 cgr_val)
void __iomem *reg, u8 shift, u8 cgr_val,
unsigned long flags)
{
struct clk_gate2 *g = xzalloc(sizeof(*g));
@ -100,7 +101,7 @@ struct clk *clk_gate2_alloc(const char *name, const char *parent,
g->clk.name = name;
g->clk.parent_names = &g->parent;
g->clk.num_parents = 1;
g->clk.flags = CLK_SET_RATE_PARENT;
g->clk.flags = CLK_SET_RATE_PARENT | flags;
return &g->clk;
}
@ -113,12 +114,12 @@ void clk_gate2_free(struct clk *clk)
}
struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
u8 shift, u8 cgr_val)
u8 shift, u8 cgr_val, unsigned long flags)
{
struct clk *g;
int ret;
g = clk_gate2_alloc(name , parent, reg, shift, cgr_val);
g = clk_gate2_alloc(name , parent, reg, shift, cgr_val, flags);
ret = clk_register(g);
if (ret) {
@ -135,7 +136,7 @@ struct clk *clk_gate2_inverted(const char *name, const char *parent,
struct clk *clk;
struct clk_gate2 *g;
clk = clk_gate2(name, parent, reg, shift, 0x3);
clk = clk_gate2(name, parent, reg, shift, 0x3, 0);
if (IS_ERR(clk))
return clk;

View File

@ -63,14 +63,27 @@ enum mx31_clks {
mstick1_gate, mstick2_gate, csi_gate, rtc_gate, wdog_gate, pwm_gate,
sim_gate, ect_gate, usb_gate, kpp_gate, ipu_gate, uart3_gate,
uart4_gate, uart5_gate, owire_gate, ssi2_gate, cspi1_gate, cspi2_gate,
gacc_gate, emi_gate, rtic_gate, firi_gate, clk_max
gacc_gate, emi_gate, rtic_gate, firi_gate, fpm, pll_ref, mpll_byp,
clk_max
};
static struct clk *clks[clk_max];
static const char *pll_ref_sel[] = {
"dummy",
"fpm",
"ckih",
"dummy",
};
static const char *mpll_byp_sel[] = {
"mpll",
"pll_ref",
};
static const char *mcu_main_sel[] = {
"spll",
"mpll",
"mpll_byp",
};
static const char *per_sel[] = {
@ -94,9 +107,14 @@ static int imx31_ccm_probe(struct device_d *dev)
clks[ckih] = clk_fixed("ckih", 26000000);
clks[ckil] = clk_fixed("ckil", 32768);
clks[mpll] = imx_clk_pllv1("mpll", "ckih", base + CCM_MPCTL);
clks[spll] = imx_clk_pllv1("spll", "ckih", base + CCM_SRPCTL);
clks[upll] = imx_clk_pllv1("upll", "ckih", base + CCM_UPCTL);
clks[fpm] = imx_clk_fixed_factor("fpm", "ckil", 1024, 1);
clks[pll_ref] = imx_clk_mux("pll_ref", base + CCM_CCMR, 1, 2,
pll_ref_sel, ARRAY_SIZE(pll_ref_sel));
clks[mpll] = imx_clk_pllv1("mpll", "pll_ref", base + CCM_MPCTL);
clks[spll] = imx_clk_pllv1("spll", "pll_ref", base + CCM_SRPCTL);
clks[upll] = imx_clk_pllv1("upll", "pll_ref", base + CCM_UPCTL);
clks[mpll_byp] = imx_clk_mux("mpll_byp", base + CCM_CCMR, 7, 1,
mpll_byp_sel, ARRAY_SIZE(mpll_byp_sel));
clks[mcu_main] = imx_clk_mux("mcu_main", base + CCM_PMCR0, 31, 1,
mcu_main_sel, ARRAY_SIZE(mcu_main_sel));
clks[hsp] = imx_clk_divider("hsp", "mcu_main", base + CCM_PDR0, 11, 3);

View File

@ -0,0 +1,329 @@
/*
* Copyright (C) 2014 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <dt-bindings/clock/imx6sl-clock.h>
#include <common.h>
#include <init.h>
#include <driver.h>
#include <linux/clk.h>
#include <io.h>
#include <of.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <linux/clk.h>
#include <mach/imx6-regs.h>
#include <mach/revision.h>
#include <mach/imx6.h>
#include "clk.h"
#include "common.h"
static const char *step_sels[] = { "osc", "pll2_pfd2", };
static const char *pll1_sw_sels[] = { "pll1_sys", "step", };
static const char *ocram_alt_sels[] = { "pll2_pfd2", "pll3_pfd1", };
static const char *ocram_sels[] = { "periph", "ocram_alt_sels", };
static const char *pre_periph_sels[] = { "pll2_bus", "pll2_pfd2", "pll2_pfd0", "pll2_198m", };
static const char *periph_clk2_sels[] = { "pll3_usb_otg", "osc", "osc", "dummy", };
static const char *periph2_clk2_sels[] = { "pll3_usb_otg", "pll2_bus", };
static const char *periph_sels[] = { "pre_periph_sel", "periph_clk2_podf", };
static const char *periph2_sels[] = { "pre_periph2_sel", "periph2_clk2_podf", };
static const char *csi_sels[] = { "osc", "pll2_pfd2", "pll3_120m", "pll3_pfd1", };
static const char *lcdif_axi_sels[] = { "pll2_bus", "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", };
static const char *usdhc_sels[] = { "pll2_pfd2", "pll2_pfd0", };
static const char *perclk_sels[] = { "ipg", "osc", };
static const char *pxp_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd3", };
static const char *epdc_axi_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd2", "pll3_pfd2", };
static const char *gpu2d_ovg_sels[] = { "pll3_pfd1", "pll3_usb_otg", "pll2_bus", "pll2_pfd2", };
static const char *gpu2d_sels[] = { "pll2_pfd2", "pll3_usb_otg", "pll3_pfd1", "pll2_bus", };
static const char *lcdif_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll3_pfd0", "pll3_pfd1", };
static const char *epdc_pix_sels[] = { "pll2_bus", "pll3_usb_otg", "pll5_video_div", "pll2_pfd0", "pll2_pfd1", "pll3_pfd1", };
static const char *ecspi_sels[] = { "pll3_60m", "osc", };
static const char *uart_sels[] = { "pll3_80m", "osc", };
static const char *lvds_sels[] = {
"pll1_sys", "pll2_bus", "pll2_pfd0", "pll2_pfd1", "pll2_pfd2", "dummy", "pll4_audio", "pll5_video",
"dummy", "enet_ref", "dummy", "dummy", "pll3_usb_otg", "pll7_usb_host", "pll3_pfd0", "pll3_pfd1",
"pll3_pfd2", "pll3_pfd3", "osc", "dummy", "dummy", "dummy", "dummy", "dummy",
"dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy", "dummy",
};
static const char *pll_bypass_src_sels[] = { "osc", "lvds1_in", };
static const char *pll1_bypass_sels[] = { "pll1", "pll1_bypass_src", };
static const char *pll2_bypass_sels[] = { "pll2", "pll2_bypass_src", };
static const char *pll3_bypass_sels[] = { "pll3", "pll3_bypass_src", };
static const char *pll4_bypass_sels[] = { "pll4", "pll4_bypass_src", };
static const char *pll5_bypass_sels[] = { "pll5", "pll5_bypass_src", };
static const char *pll6_bypass_sels[] = { "pll6", "pll6_bypass_src", };
static const char *pll7_bypass_sels[] = { "pll7", "pll7_bypass_src", };
static struct clk *clks[IMX6SL_CLK_END];
static struct clk_onecell_data clk_data;
static struct clk_div_table clk_enet_ref_table[] = {
{ .val = 0, .div = 20, },
{ .val = 1, .div = 10, },
{ .val = 2, .div = 5, },
{ .val = 3, .div = 4, },
{ }
};
static struct clk_div_table post_div_table[] = {
{ .val = 2, .div = 1, },
{ .val = 1, .div = 2, },
{ .val = 0, .div = 4, },
{ }
};
static struct clk_div_table video_div_table[] = {
{ .val = 0, .div = 1, },
{ .val = 1, .div = 2, },
{ .val = 2, .div = 1, },
{ .val = 3, .div = 4, },
{ }
};
static int imx6sl_ccm_probe(struct device_d *dev)
{
struct resource *iores;
void __iomem *base, *anatop_base, *ccm_base;
struct device_node *ccm_node = dev->device_node;
clks[IMX6SL_CLK_DUMMY] = clk_fixed("dummy", 0);
anatop_base = (void *)MX6_ANATOP_BASE_ADDR;
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
ccm_base = IOMEM(iores->start);
base = anatop_base;
clks[IMX6SL_PLL1_BYPASS_SRC] = imx_clk_mux("pll1_bypass_src", base + 0x00, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clks[IMX6SL_PLL2_BYPASS_SRC] = imx_clk_mux("pll2_bypass_src", base + 0x30, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clks[IMX6SL_PLL3_BYPASS_SRC] = imx_clk_mux("pll3_bypass_src", base + 0x10, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clks[IMX6SL_PLL4_BYPASS_SRC] = imx_clk_mux("pll4_bypass_src", base + 0x70, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clks[IMX6SL_PLL5_BYPASS_SRC] = imx_clk_mux("pll5_bypass_src", base + 0xa0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clks[IMX6SL_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", base + 0xe0, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clks[IMX6SL_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", base + 0x20, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
/* type name parent_name base div_mask */
clks[IMX6SL_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll1", "osc", base + 0x00, 0x7f);
clks[IMX6SL_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "osc", base + 0x30, 0x1);
clks[IMX6SL_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB, "pll3", "osc", base + 0x10, 0x3);
clks[IMX6SL_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "osc", base + 0x70, 0x7f);
clks[IMX6SL_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_AV, "pll5", "osc", base + 0xa0, 0x7f);
clks[IMX6SL_CLK_PLL6] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll6", "osc", base + 0xe0, 0x3);
clks[IMX6SL_CLK_PLL7] = imx_clk_pllv3(IMX_PLLV3_USB, "pll7", "osc", base + 0x20, 0x3);
clks[IMX6SL_PLL1_BYPASS] = imx_clk_mux_p("pll1_bypass", base + 0x00, 16, 1, pll1_bypass_sels, ARRAY_SIZE(pll1_bypass_sels));
clks[IMX6SL_PLL2_BYPASS] = imx_clk_mux_p("pll2_bypass", base + 0x30, 16, 1, pll2_bypass_sels, ARRAY_SIZE(pll2_bypass_sels));
clks[IMX6SL_PLL3_BYPASS] = imx_clk_mux_p("pll3_bypass", base + 0x10, 16, 1, pll3_bypass_sels, ARRAY_SIZE(pll3_bypass_sels));
clks[IMX6SL_PLL4_BYPASS] = imx_clk_mux_p("pll4_bypass", base + 0x70, 16, 1, pll4_bypass_sels, ARRAY_SIZE(pll4_bypass_sels));
clks[IMX6SL_PLL5_BYPASS] = imx_clk_mux_p("pll5_bypass", base + 0xa0, 16, 1, pll5_bypass_sels, ARRAY_SIZE(pll5_bypass_sels));
clks[IMX6SL_PLL6_BYPASS] = imx_clk_mux_p("pll6_bypass", base + 0xe0, 16, 1, pll6_bypass_sels, ARRAY_SIZE(pll6_bypass_sels));
clks[IMX6SL_PLL7_BYPASS] = imx_clk_mux_p("pll7_bypass", base + 0x20, 16, 1, pll7_bypass_sels, ARRAY_SIZE(pll7_bypass_sels));
/* Do not bypass PLLs initially */
clk_set_parent(clks[IMX6SL_PLL1_BYPASS], clks[IMX6SL_CLK_PLL1]);
clk_set_parent(clks[IMX6SL_PLL2_BYPASS], clks[IMX6SL_CLK_PLL2]);
clk_set_parent(clks[IMX6SL_PLL3_BYPASS], clks[IMX6SL_CLK_PLL3]);
clk_set_parent(clks[IMX6SL_PLL4_BYPASS], clks[IMX6SL_CLK_PLL4]);
clk_set_parent(clks[IMX6SL_PLL5_BYPASS], clks[IMX6SL_CLK_PLL5]);
clk_set_parent(clks[IMX6SL_PLL6_BYPASS], clks[IMX6SL_CLK_PLL6]);
clk_set_parent(clks[IMX6SL_PLL7_BYPASS], clks[IMX6SL_CLK_PLL7]);
clks[IMX6SL_CLK_PLL1_SYS] = imx_clk_gate("pll1_sys", "pll1_bypass", base + 0x00, 13);
clks[IMX6SL_CLK_PLL2_BUS] = imx_clk_gate("pll2_bus", "pll2_bypass", base + 0x30, 13);
clks[IMX6SL_CLK_PLL3_USB_OTG] = imx_clk_gate("pll3_usb_otg", "pll3_bypass", base + 0x10, 13);
clks[IMX6SL_CLK_PLL4_AUDIO] = imx_clk_gate("pll4_audio", "pll4_bypass", base + 0x70, 13);
clks[IMX6SL_CLK_PLL5_VIDEO] = imx_clk_gate("pll5_video", "pll5_bypass", base + 0xa0, 13);
clks[IMX6SL_CLK_PLL6_ENET] = imx_clk_gate("pll6_enet", "pll6_bypass", base + 0xe0, 13);
clks[IMX6SL_CLK_PLL7_USB_HOST] = imx_clk_gate("pll7_usb_host", "pll7_bypass", base + 0x20, 13);
clks[IMX6SL_CLK_LVDS1_SEL] = imx_clk_mux("lvds1_sel", base + 0x160, 0, 5, lvds_sels, ARRAY_SIZE(lvds_sels));
clks[IMX6SL_CLK_LVDS1_OUT] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x160, 10, BIT(12));
clks[IMX6SL_CLK_LVDS1_IN] = imx_clk_gate_exclusive("lvds1_in", "anaclk1", base + 0x160, 12, BIT(10));
/*
* usbphy1 and usbphy2 are implemented as dummy gates using reserve
* bit 20. They are used by phy driver to keep the refcount of
* parent PLL correct. usbphy1_gate and usbphy2_gate only needs to be
* turned on during boot, and software will not need to control it
* anymore after that.
*/
clks[IMX6SL_CLK_USBPHY1] = imx_clk_gate("usbphy1", "pll3_usb_otg", base + 0x10, 20);
clks[IMX6SL_CLK_USBPHY2] = imx_clk_gate("usbphy2", "pll7_usb_host", base + 0x20, 20);
clks[IMX6SL_CLK_USBPHY1_GATE] = imx_clk_gate("usbphy1_gate", "dummy", base + 0x10, 6);
clks[IMX6SL_CLK_USBPHY2_GATE] = imx_clk_gate("usbphy2_gate", "dummy", base + 0x20, 6);
/* dev name parent_name flags reg shift width div: flags, div_table lock */
clks[IMX6SL_CLK_PLL4_POST_DIV] = imx_clk_divider_table("pll4_post_div", "pll4_audio",
base + 0x70, 19, 2, post_div_table);
clks[IMX6SL_CLK_PLL4_AUDIO_DIV] = imx_clk_divider("pll4_audio_div", "pll4_post_div",
base + 0x170, 15, 1);
clks[IMX6SL_CLK_PLL5_POST_DIV] = imx_clk_divider_table("pll5_post_div", "pll5_video",
base + 0xa0, 19, 2, post_div_table);
clks[IMX6SL_CLK_PLL5_VIDEO_DIV] = imx_clk_divider_table("pll5_video_div", "pll5_post_div",
base + 0x170, 30, 2, video_div_table);
clks[IMX6SL_CLK_ENET_REF] = imx_clk_divider_table("enet_ref", "pll6_enet",
base + 0xe0, 0, 2, clk_enet_ref_table);
/* name parent_name reg idx */
clks[IMX6SL_CLK_PLL2_PFD0] = imx_clk_pfd("pll2_pfd0", "pll2_bus", base + 0x100, 0);
clks[IMX6SL_CLK_PLL2_PFD1] = imx_clk_pfd("pll2_pfd1", "pll2_bus", base + 0x100, 1);
clks[IMX6SL_CLK_PLL2_PFD2] = imx_clk_pfd("pll2_pfd2", "pll2_bus", base + 0x100, 2);
clks[IMX6SL_CLK_PLL3_PFD0] = imx_clk_pfd("pll3_pfd0", "pll3_usb_otg", base + 0xf0, 0);
clks[IMX6SL_CLK_PLL3_PFD1] = imx_clk_pfd("pll3_pfd1", "pll3_usb_otg", base + 0xf0, 1);
clks[IMX6SL_CLK_PLL3_PFD2] = imx_clk_pfd("pll3_pfd2", "pll3_usb_otg", base + 0xf0, 2);
clks[IMX6SL_CLK_PLL3_PFD3] = imx_clk_pfd("pll3_pfd3", "pll3_usb_otg", base + 0xf0, 3);
/* name parent_name mult div */
clks[IMX6SL_CLK_PLL2_198M] = imx_clk_fixed_factor("pll2_198m", "pll2_pfd2", 1, 2);
clks[IMX6SL_CLK_PLL3_120M] = imx_clk_fixed_factor("pll3_120m", "pll3_usb_otg", 1, 4);
clks[IMX6SL_CLK_PLL3_80M] = imx_clk_fixed_factor("pll3_80m", "pll3_usb_otg", 1, 6);
clks[IMX6SL_CLK_PLL3_60M] = imx_clk_fixed_factor("pll3_60m", "pll3_usb_otg", 1, 8);
base = ccm_base;
/* name reg shift width parent_names num_parents */
clks[IMX6SL_CLK_STEP] = imx_clk_mux("step", base + 0xc, 8, 1, step_sels, ARRAY_SIZE(step_sels));
clks[IMX6SL_CLK_PLL1_SW] = imx_clk_mux("pll1_sw", base + 0xc, 2, 1, pll1_sw_sels, ARRAY_SIZE(pll1_sw_sels));
clks[IMX6SL_CLK_OCRAM_ALT_SEL] = imx_clk_mux("ocram_alt_sel", base + 0x14, 7, 1, ocram_alt_sels, ARRAY_SIZE(ocram_alt_sels));
clks[IMX6SL_CLK_OCRAM_SEL] = imx_clk_mux("ocram_sel", base + 0x14, 6, 1, ocram_sels, ARRAY_SIZE(ocram_sels));
clks[IMX6SL_CLK_PRE_PERIPH2_SEL] = imx_clk_mux("pre_periph2_sel", base + 0x18, 21, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
clks[IMX6SL_CLK_PRE_PERIPH_SEL] = imx_clk_mux("pre_periph_sel", base + 0x18, 18, 2, pre_periph_sels, ARRAY_SIZE(pre_periph_sels));
clks[IMX6SL_CLK_PERIPH2_CLK2_SEL] = imx_clk_mux("periph2_clk2_sel", base + 0x18, 20, 1, periph2_clk2_sels, ARRAY_SIZE(periph2_clk2_sels));
clks[IMX6SL_CLK_PERIPH_CLK2_SEL] = imx_clk_mux("periph_clk2_sel", base + 0x18, 12, 2, periph_clk2_sels, ARRAY_SIZE(periph_clk2_sels));
clks[IMX6SL_CLK_CSI_SEL] = imx_clk_mux("csi_sel", base + 0x3c, 9, 2, csi_sels, ARRAY_SIZE(csi_sels));
clks[IMX6SL_CLK_LCDIF_AXI_SEL] = imx_clk_mux("lcdif_axi_sel", base + 0x3c, 14, 2, lcdif_axi_sels, ARRAY_SIZE(lcdif_axi_sels));
clks[IMX6SL_CLK_USDHC1_SEL] = imx_clk_mux("usdhc1_sel", base + 0x1c, 16, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
clks[IMX6SL_CLK_USDHC2_SEL] = imx_clk_mux("usdhc2_sel", base + 0x1c, 17, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
clks[IMX6SL_CLK_USDHC3_SEL] = imx_clk_mux("usdhc3_sel", base + 0x1c, 18, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
clks[IMX6SL_CLK_USDHC4_SEL] = imx_clk_mux("usdhc4_sel", base + 0x1c, 19, 1, usdhc_sels, ARRAY_SIZE(usdhc_sels));
clks[IMX6SL_CLK_PERCLK_SEL] = imx_clk_mux("perclk_sel", base + 0x1c, 6, 1, perclk_sels, ARRAY_SIZE(perclk_sels));
clks[IMX6SL_CLK_PXP_AXI_SEL] = imx_clk_mux("pxp_axi_sel", base + 0x34, 6, 3, pxp_axi_sels, ARRAY_SIZE(pxp_axi_sels));
clks[IMX6SL_CLK_EPDC_AXI_SEL] = imx_clk_mux("epdc_axi_sel", base + 0x34, 15, 3, epdc_axi_sels, ARRAY_SIZE(epdc_axi_sels));
clks[IMX6SL_CLK_GPU2D_OVG_SEL] = imx_clk_mux("gpu2d_ovg_sel", base + 0x18, 4, 2, gpu2d_ovg_sels, ARRAY_SIZE(gpu2d_ovg_sels));
clks[IMX6SL_CLK_GPU2D_SEL] = imx_clk_mux("gpu2d_sel", base + 0x18, 8, 2, gpu2d_sels, ARRAY_SIZE(gpu2d_sels));
clks[IMX6SL_CLK_LCDIF_PIX_SEL] = imx_clk_mux("lcdif_pix_sel", base + 0x38, 6, 3, lcdif_pix_sels, ARRAY_SIZE(lcdif_pix_sels));
clks[IMX6SL_CLK_EPDC_PIX_SEL] = imx_clk_mux("epdc_pix_sel", base + 0x38, 15, 3, epdc_pix_sels, ARRAY_SIZE(epdc_pix_sels));
clks[IMX6SL_CLK_ECSPI_SEL] = imx_clk_mux("ecspi_sel", base + 0x38, 18, 1, ecspi_sels, ARRAY_SIZE(ecspi_sels));
clks[IMX6SL_CLK_UART_SEL] = imx_clk_mux("uart_sel", base + 0x24, 6, 1, uart_sels, ARRAY_SIZE(uart_sels));
/* name reg shift width busy: reg, shift parent_names num_parents */
clks[IMX6SL_CLK_PERIPH] = imx_clk_busy_mux("periph", base + 0x14, 25, 1, base + 0x48, 5, periph_sels, ARRAY_SIZE(periph_sels));
clks[IMX6SL_CLK_PERIPH2] = imx_clk_busy_mux("periph2", base + 0x14, 26, 1, base + 0x48, 3, periph2_sels, ARRAY_SIZE(periph2_sels));
/* name parent_name reg shift width */
clks[IMX6SL_CLK_OCRAM_PODF] = imx_clk_divider("ocram_podf", "ocram_sel", base + 0x14, 16, 3);
clks[IMX6SL_CLK_PERIPH_CLK2_PODF] = imx_clk_divider("periph_clk2_podf", "periph_clk2_sel", base + 0x14, 27, 3);
clks[IMX6SL_CLK_PERIPH2_CLK2_PODF] = imx_clk_divider("periph2_clk2_podf", "periph2_clk2_sel", base + 0x14, 0, 3);
clks[IMX6SL_CLK_IPG] = imx_clk_divider("ipg", "ahb", base + 0x14, 8, 2);
clks[IMX6SL_CLK_CSI_PODF] = imx_clk_divider("csi_podf", "csi_sel", base + 0x3c, 11, 3);
clks[IMX6SL_CLK_LCDIF_AXI_PODF] = imx_clk_divider("lcdif_axi_podf", "lcdif_axi_sel", base + 0x3c, 16, 3);
clks[IMX6SL_CLK_USDHC1_PODF] = imx_clk_divider("usdhc1_podf", "usdhc1_sel", base + 0x24, 11, 3);
clks[IMX6SL_CLK_USDHC2_PODF] = imx_clk_divider("usdhc2_podf", "usdhc2_sel", base + 0x24, 16, 3);
clks[IMX6SL_CLK_USDHC3_PODF] = imx_clk_divider("usdhc3_podf", "usdhc3_sel", base + 0x24, 19, 3);
clks[IMX6SL_CLK_USDHC4_PODF] = imx_clk_divider("usdhc4_podf", "usdhc4_sel", base + 0x24, 22, 3);
clks[IMX6SL_CLK_PERCLK] = imx_clk_divider("perclk", "perclk_sel", base + 0x1c, 0, 6);
clks[IMX6SL_CLK_PXP_AXI_PODF] = imx_clk_divider("pxp_axi_podf", "pxp_axi_sel", base + 0x34, 3, 3);
clks[IMX6SL_CLK_EPDC_AXI_PODF] = imx_clk_divider("epdc_axi_podf", "epdc_axi_sel", base + 0x34, 12, 3);
clks[IMX6SL_CLK_GPU2D_OVG_PODF] = imx_clk_divider("gpu2d_ovg_podf", "gpu2d_ovg_sel", base + 0x18, 26, 3);
clks[IMX6SL_CLK_GPU2D_PODF] = imx_clk_divider("gpu2d_podf", "gpu2d_sel", base + 0x18, 29, 3);
clks[IMX6SL_CLK_LCDIF_PIX_PRED] = imx_clk_divider("lcdif_pix_pred", "lcdif_pix_sel", base + 0x38, 3, 3);
clks[IMX6SL_CLK_EPDC_PIX_PRED] = imx_clk_divider("epdc_pix_pred", "epdc_pix_sel", base + 0x38, 12, 3);
clks[IMX6SL_CLK_LCDIF_PIX_PODF] = imx_clk_divider("lcdif_pix_podf", "lcdif_pix_pred", base + 0x1c, 20, 3);
clks[IMX6SL_CLK_EPDC_PIX_PODF] = imx_clk_divider("epdc_pix_podf", "epdc_pix_pred", base + 0x18, 23, 3);
clks[IMX6SL_CLK_ECSPI_ROOT] = imx_clk_divider("ecspi_root", "ecspi_sel", base + 0x38, 19, 6);
clks[IMX6SL_CLK_UART_ROOT] = imx_clk_divider("uart_root", "uart_sel", base + 0x24, 0, 6);
/* name parent_name reg shift width busy: reg, shift */
clks[IMX6SL_CLK_AHB] = imx_clk_busy_divider("ahb", "periph", base + 0x14, 10, 3, base + 0x48, 1);
clks[IMX6SL_CLK_MMDC_ROOT] = imx_clk_busy_divider("mmdc", "periph2", base + 0x14, 3, 3, base + 0x48, 2);
clks[IMX6SL_CLK_ARM] = imx_clk_busy_divider("arm", "pll1_sw", base + 0x10, 0, 3, base + 0x48, 16);
/* name parent_name reg shift */
clks[IMX6SL_CLK_ECSPI1] = imx_clk_gate2("ecspi1", "ecspi_root", base + 0x6c, 0);
clks[IMX6SL_CLK_ECSPI2] = imx_clk_gate2("ecspi2", "ecspi_root", base + 0x6c, 2);
clks[IMX6SL_CLK_ECSPI3] = imx_clk_gate2("ecspi3", "ecspi_root", base + 0x6c, 4);
clks[IMX6SL_CLK_ECSPI4] = imx_clk_gate2("ecspi4", "ecspi_root", base + 0x6c, 6);
clks[IMX6SL_CLK_ENET] = imx_clk_gate2("enet", "ipg", base + 0x6c, 10);
clks[IMX6SL_CLK_EPIT1] = imx_clk_gate2("epit1", "perclk", base + 0x6c, 12);
clks[IMX6SL_CLK_EPIT2] = imx_clk_gate2("epit2", "perclk", base + 0x6c, 14);
clks[IMX6SL_CLK_GPT] = imx_clk_gate2("gpt", "perclk", base + 0x6c, 20);
clks[IMX6SL_CLK_GPT_SERIAL] = imx_clk_gate2("gpt_serial", "perclk", base + 0x6c, 22);
clks[IMX6SL_CLK_GPU2D_OVG] = imx_clk_gate2("gpu2d_ovg", "gpu2d_ovg_podf", base + 0x6c, 26);
clks[IMX6SL_CLK_I2C1] = imx_clk_gate2("i2c1", "perclk", base + 0x70, 6);
clks[IMX6SL_CLK_I2C2] = imx_clk_gate2("i2c2", "perclk", base + 0x70, 8);
clks[IMX6SL_CLK_I2C3] = imx_clk_gate2("i2c3", "perclk", base + 0x70, 10);
clks[IMX6SL_CLK_OCOTP] = imx_clk_gate2("ocotp", "ipg", base + 0x70, 12);
clks[IMX6SL_CLK_CSI] = imx_clk_gate2("csi", "csi_podf", base + 0x74, 0);
clks[IMX6SL_CLK_PXP_AXI] = imx_clk_gate2("pxp_axi", "pxp_axi_podf", base + 0x74, 2);
clks[IMX6SL_CLK_EPDC_AXI] = imx_clk_gate2("epdc_axi", "epdc_axi_podf", base + 0x74, 4);
clks[IMX6SL_CLK_LCDIF_AXI] = imx_clk_gate2("lcdif_axi", "lcdif_axi_podf", base + 0x74, 6);
clks[IMX6SL_CLK_LCDIF_PIX] = imx_clk_gate2("lcdif_pix", "lcdif_pix_podf", base + 0x74, 8);
clks[IMX6SL_CLK_EPDC_PIX] = imx_clk_gate2("epdc_pix", "epdc_pix_podf", base + 0x74, 10);
clks[IMX6SL_CLK_OCRAM] = imx_clk_gate2("ocram", "ocram_podf", base + 0x74, 28);
clks[IMX6SL_CLK_PWM1] = imx_clk_gate2("pwm1", "perclk", base + 0x78, 16);
clks[IMX6SL_CLK_PWM2] = imx_clk_gate2("pwm2", "perclk", base + 0x78, 18);
clks[IMX6SL_CLK_PWM3] = imx_clk_gate2("pwm3", "perclk", base + 0x78, 20);
clks[IMX6SL_CLK_PWM4] = imx_clk_gate2("pwm4", "perclk", base + 0x78, 22);
clks[IMX6SL_CLK_SDMA] = imx_clk_gate2("sdma", "ipg", base + 0x7c, 6);
clks[IMX6SL_CLK_SPBA] = imx_clk_gate2("spba", "ipg", base + 0x7c, 12);
clks[IMX6SL_CLK_UART] = imx_clk_gate2("uart", "ipg", base + 0x7c, 24);
clks[IMX6SL_CLK_UART_SERIAL] = imx_clk_gate2("uart_serial", "uart_root", base + 0x7c, 26);
clks[IMX6SL_CLK_USBOH3] = imx_clk_gate2("usboh3", "ipg", base + 0x80, 0);
clks[IMX6SL_CLK_USDHC1] = imx_clk_gate2("usdhc1", "usdhc1_podf", base + 0x80, 2);
clks[IMX6SL_CLK_USDHC2] = imx_clk_gate2("usdhc2", "usdhc2_podf", base + 0x80, 4);
clks[IMX6SL_CLK_USDHC3] = imx_clk_gate2("usdhc3", "usdhc3_podf", base + 0x80, 6);
clks[IMX6SL_CLK_USDHC4] = imx_clk_gate2("usdhc4", "usdhc4_podf", base + 0x80, 8);
clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(ccm_node, of_clk_src_onecell_get, &clk_data);
if (IS_ENABLED(CONFIG_USB_IMX_PHY)) {
clk_enable(clks[IMX6SL_CLK_USBPHY1_GATE]);
clk_enable(clks[IMX6SL_CLK_USBPHY2_GATE]);
}
return 0;
};
static int imx6sl_clocks_init(void)
{
if (!of_machine_is_compatible("fsl,imx6sl"))
return 0;
/* Ensure the AHB clk is at 132MHz. */
clk_set_rate(clks[IMX6SL_CLK_AHB], 132000000);
return 0;
}
coredevice_initcall(imx6sl_clocks_init);
static __maybe_unused struct of_device_id imx6sl_ccm_dt_ids[] = {
{
.compatible = "fsl,imx6sl-ccm",
}, {
/* sentinel */
}
};
static struct driver_d imx6sl_ccm_driver = {
.probe = imx6sl_ccm_probe,
.name = "imx6-ccm",
.of_compatible = DRV_OF_COMPAT(imx6sl_ccm_dt_ids),
};
static int imx6sl_ccm_init(void)
{
return platform_driver_register(&imx6sl_ccm_driver);
}
core_initcall(imx6sl_ccm_init);

880
drivers/clk/imx/clk-imx7.c Normal file
View File

@ -0,0 +1,880 @@
/*
* Copyright (C) 2014-2015 Freescale Semiconductor, Inc.
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
* Version 2 or later at the following locations:
*
* http://www.opensource.org/licenses/gpl-license.html
* http://www.gnu.org/copyleft/gpl.html
*/
#include <common.h>
#include <init.h>
#include <driver.h>
#include <linux/clk.h>
#include <io.h>
#include <of.h>
#include <linux/clkdev.h>
#include <linux/err.h>
#include <mach/imx7-regs.h>
#include <mach/revision.h>
#include <dt-bindings/clock/imx7d-clock.h>
#include "clk.h"
static struct clk *clks[IMX7D_CLK_END];
static const char *arm_a7_sel[] = { "osc", "pll_arm_main",
"pll_enet_500m_clk", "pll_dram_main",
"pll_sys_main", "pll_sys_pfd0_392m_clk", "pll_audio_post_div",
"pll_usb_main_clk", };
static const char *arm_m4_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_250m_clk", "pll_sys_pfd2_270m_clk",
"pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main",
"pll_usb_main_clk", };
static const char *arm_m0_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_125m_clk", "pll_sys_pfd2_135m_clk",
"pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main",
"pll_usb_main_clk", };
static const char *axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
"pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd5_clk",
"pll_audio_post_div", "pll_video_main", "pll_sys_pfd7_clk", };
static const char *disp_axi_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
"pll_dram_533m_clk", "pll_enet_250m_clk", "pll_sys_pfd6_clk",
"pll_sys_pfd7_clk", "pll_audio_post_div", "pll_video_main", };
static const char *enet_axi_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
"pll_dram_533m_clk", "pll_enet_250m_clk",
"pll_sys_main_240m_clk", "pll_audio_post_div", "pll_video_main",
"pll_sys_pfd4_clk", };
static const char *nand_usdhc_bus_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
"pll_dram_533m_clk", "pll_sys_main_240m_clk",
"pll_sys_pfd2_135m_clk", "pll_sys_pfd6_clk", "pll_enet_250m_clk",
"pll_audio_post_div", };
static const char *ahb_channel_sel[] = { "osc", "pll_sys_pfd2_270m_clk",
"pll_dram_533m_clk", "pll_sys_pfd0_392m_clk",
"pll_enet_125m_clk", "pll_usb_main_clk", "pll_audio_post_div",
"pll_video_main", };
static const char *dram_phym_sel[] = { "pll_dram_main",
"dram_phym_alt_clk", };
static const char *dram_sel[] = { "pll_dram_main",
"dram_alt_root_clk", };
static const char *dram_phym_alt_sel[] = { "osc", "pll_dram_533m_clk",
"pll_sys_main", "pll_enet_500m_clk",
"pll_usb_main_clk", "pll_sys_pfd7_clk", "pll_audio_post_div",
"pll_video_main", };
static const char *dram_alt_sel[] = { "osc", "pll_dram_533m_clk",
"pll_sys_main", "pll_enet_500m_clk",
"pll_enet_250m_clk", "pll_sys_pfd0_392m_clk",
"pll_audio_post_div", "pll_sys_pfd2_270m_clk", };
static const char *usb_hsic_sel[] = { "osc", "pll_sys_main",
"pll_usb_main_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
"pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
static const char *pcie_ctrl_sel[] = { "osc", "pll_enet_250m_clk",
"pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk",
"pll_dram_533m_clk", "pll_enet_500m_clk",
"pll_sys_pfd1_332m_clk", "pll_sys_pfd6_clk", };
static const char *pcie_phy_sel[] = { "osc", "pll_enet_100m_clk",
"pll_enet_500m_clk", "ext_clk_1", "ext_clk_2", "ext_clk_3",
"ext_clk_4", "pll_sys_pfd0_392m_clk", };
static const char *epdc_pixel_sel[] = { "osc", "pll_sys_pfd1_332m_clk",
"pll_dram_533m_clk", "pll_sys_main", "pll_sys_pfd5_clk",
"pll_sys_pfd6_clk", "pll_sys_pfd7_clk", "pll_video_main", };
static const char *lcdif_pixel_sel[] = { "osc", "pll_sys_pfd5_clk",
"pll_dram_533m_clk", "ext_clk_3", "pll_sys_pfd4_clk",
"pll_sys_pfd2_270m_clk", "pll_video_main",
"pll_usb_main_clk", };
static const char *mipi_dsi_sel[] = { "osc", "pll_sys_pfd5_clk",
"pll_sys_pfd3_clk", "pll_sys_main", "pll_sys_pfd0_196m_clk",
"pll_dram_533m_clk", "pll_video_main", "pll_audio_post_div", };
static const char *mipi_csi_sel[] = { "osc", "pll_sys_pfd4_clk",
"pll_sys_pfd3_clk", "pll_sys_main", "pll_sys_pfd0_196m_clk",
"pll_dram_533m_clk", "pll_video_main", "pll_audio_post_div", };
static const char *mipi_dphy_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_dram_533m_clk", "pll_sys_pfd5_clk", "ref_1m_clk", "ext_clk_2",
"pll_video_main", "ext_clk_3", };
static const char *sai1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
static const char *sai2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_2", };
static const char *sai3_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_clk_3", };
static const char *spdif_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_audio_post_div", "pll_dram_533m_clk", "pll_video_main",
"pll_sys_pfd4_clk", "pll_enet_125m_clk", "ext_3_clk", };
static const char *enet1_ref_sel[] = { "osc", "pll_enet_125m_clk",
"pll_enet_50m_clk", "pll_enet_25m_clk",
"pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main",
"ext_clk_4", };
static const char *enet1_time_sel[] = { "osc", "pll_enet_100m_clk",
"pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
"ext_clk_4", "pll_video_main", };
static const char *enet2_ref_sel[] = { "osc", "pll_enet_125m_clk",
"pll_enet_50m_clk", "pll_enet_25m_clk",
"pll_sys_main_120m_clk", "pll_audio_post_div", "pll_video_main",
"ext_clk_4", };
static const char *enet2_time_sel[] = { "osc", "pll_enet_100m_clk",
"pll_audio_post_div", "ext_clk_1", "ext_clk_2", "ext_clk_3",
"ext_clk_4", "pll_video_main", };
static const char *enet_phy_ref_sel[] = { "osc", "pll_enet_25m_clk",
"pll_enet_50m_clk", "pll_enet_125m_clk",
"pll_dram_533m_clk", "pll_audio_post_div", "pll_video_main",
"pll_sys_pfd3_clk", };
static const char *eim_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
"pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_enet_125m_clk",
"pll_usb_main_clk", };
static const char *nand_sel[] = { "osc", "pll_sys_main",
"pll_dram_533m_clk", "pll_sys_pfd0_392m_clk", "pll_sys_pfd3_clk",
"pll_enet_500m_clk", "pll_enet_250m_clk",
"pll_video_main", };
static const char *qspi_sel[] = { "osc", "pll_sys_pfd4_clk",
"pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd3_clk",
"pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
static const char *usdhc1_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
"pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
"pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
static const char *usdhc2_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
"pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
"pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
static const char *usdhc3_sel[] = { "osc", "pll_sys_pfd0_392m_clk",
"pll_dram_533m_clk", "pll_enet_500m_clk", "pll_sys_pfd4_clk",
"pll_sys_pfd2_270m_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk", };
static const char *can1_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_dram_533m_clk", "pll_sys_main",
"pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1",
"ext_clk_4", };
static const char *can2_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_dram_533m_clk", "pll_sys_main",
"pll_enet_40m_clk", "pll_usb_main_clk", "ext_clk_1",
"ext_clk_3", };
static const char *i2c1_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
"pll_audio_post_div", "pll_video_main", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *i2c2_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
"pll_audio_post_div", "pll_video_main", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *i2c3_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
"pll_audio_post_div", "pll_video_main", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *i2c4_sel[] = { "osc", "pll_sys_main_120m_clk",
"pll_enet_50m_clk", "pll_dram_533m_clk",
"pll_audio_post_div", "pll_video_main", "pll_usb_main_clk",
"pll_sys_pfd2_135m_clk", };
static const char *uart1_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_enet_100m_clk",
"pll_sys_main", "ext_clk_2", "ext_clk_4",
"pll_usb_main_clk", };
static const char *uart2_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_enet_100m_clk",
"pll_sys_main", "ext_clk_2", "ext_clk_3",
"pll_usb_main_clk", };
static const char *uart3_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_enet_100m_clk",
"pll_sys_main", "ext_clk_2", "ext_clk_4",
"pll_usb_main_clk", };
static const char *uart4_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_enet_100m_clk",
"pll_sys_main", "ext_clk_2", "ext_clk_3",
"pll_usb_main_clk", };
static const char *uart5_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_enet_100m_clk",
"pll_sys_main", "ext_clk_2", "ext_clk_4",
"pll_usb_main_clk", };
static const char *uart6_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_enet_100m_clk",
"pll_sys_main", "ext_clk_2", "ext_clk_3",
"pll_usb_main_clk", };
static const char *uart7_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_enet_100m_clk",
"pll_sys_main", "ext_clk_2", "ext_clk_4",
"pll_usb_main_clk", };
static const char *ecspi1_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_sys_main_120m_clk",
"pll_sys_main", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
"pll_usb_main_clk", };
static const char *ecspi2_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_sys_main_120m_clk",
"pll_sys_main", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
"pll_usb_main_clk", };
static const char *ecspi3_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_sys_main_120m_clk",
"pll_sys_main", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
"pll_usb_main_clk", };
static const char *ecspi4_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_enet_40m_clk", "pll_sys_main_120m_clk",
"pll_sys_main", "pll_sys_pfd4_clk", "pll_enet_250m_clk",
"pll_usb_main_clk", };
static const char *pwm1_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
"ext_clk_1", "ref_1m_clk", "pll_video_main", };
static const char *pwm2_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
"ext_clk_1", "ref_1m_clk", "pll_video_main", };
static const char *pwm3_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
"ext_clk_2", "ref_1m_clk", "pll_video_main", };
static const char *pwm4_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
"ext_clk_2", "ref_1m_clk", "pll_video_main", };
static const char *flextimer1_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
"ext_clk_3", "ref_1m_clk", "pll_video_main", };
static const char *flextimer2_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_main_120m_clk", "pll_enet_40m_clk", "pll_audio_post_div",
"ext_clk_3", "ref_1m_clk", "pll_video_main", };
static const char *sim1_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
"pll_usb_main_clk", "pll_audio_post_div", "pll_enet_125m_clk",
"pll_sys_pfd7_clk", };
static const char *sim2_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
"pll_usb_main_clk", "pll_video_main", "pll_enet_125m_clk",
"pll_sys_pfd7_clk", };
static const char *gpt1_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_1", };
static const char *gpt2_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_2", };
static const char *gpt3_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_3", };
static const char *gpt4_sel[] = { "osc", "pll_enet_100m_clk",
"pll_sys_pfd0_392m_clk", "pll_enet_40m_clk", "pll_video_main",
"ref_1m_clk", "pll_audio_post_div", "ext_clk_4", };
static const char *trace_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
"pll_enet_125m_clk", "pll_usb_main_clk", "ext_clk_2",
"ext_clk_3", };
static const char *wdog_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
"pll_enet_125m_clk", "pll_usb_main_clk", "ref_1m_clk",
"pll_sys_pfd1_166m_clk", };
static const char *csi_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
"pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main",
"pll_usb_main_clk", };
static const char *audio_mclk_sel[] = { "osc", "pll_sys_pfd2_135m_clk",
"pll_sys_main_120m_clk", "pll_dram_533m_clk",
"pll_enet_125m_clk", "pll_audio_post_div", "pll_video_main",
"pll_usb_main_clk", };
static const char *wrclk_sel[] = { "osc", "pll_enet_40m_clk",
"pll_dram_533m_clk", "pll_usb_main_clk",
"pll_sys_main_240m_clk", "pll_sys_pfd2_270m_clk",
"pll_enet_500m_clk", "pll_sys_pfd7_clk", };
static const char *clko1_sel[] = { "osc", "pll_sys_main",
"pll_sys_main_240m_clk", "pll_sys_pfd0_196m_clk", "pll_sys_pfd3_clk",
"pll_enet_500m_clk", "pll_dram_533m_clk", "ref_1m_clk", };
static const char *clko2_sel[] = { "osc", "pll_sys_main_240m_clk",
"pll_sys_pfd0_392m_clk", "pll_sys_pfd1_166m_clk", "pll_sys_pfd4_clk",
"pll_audio_post_div", "pll_video_main", "ckil", };
static const char *lvds1_sel[] = { "pll_arm_main",
"pll_sys_main", "pll_sys_pfd0_392m_clk", "pll_sys_pfd1_332m_clk",
"pll_sys_pfd2_270m_clk", "pll_sys_pfd3_clk", "pll_sys_pfd4_clk",
"pll_sys_pfd5_clk", "pll_sys_pfd6_clk", "pll_sys_pfd7_clk",
"pll_audio_post_div", "pll_video_main", "pll_enet_500m_clk",
"pll_enet_250m_clk", "pll_enet_125m_clk", "pll_enet_100m_clk",
"pll_enet_50m_clk", "pll_enet_40m_clk", "pll_enet_25m_clk",
"pll_dram_main", };
static int const clks_init_on[] __initconst = {
IMX7D_ARM_A7_ROOT_CLK, IMX7D_MAIN_AXI_ROOT_CLK,
IMX7D_PLL_SYS_MAIN_480M_CLK, IMX7D_NAND_USDHC_BUS_ROOT_CLK,
IMX7D_DRAM_PHYM_ROOT_CLK, IMX7D_DRAM_ROOT_CLK,
IMX7D_DRAM_PHYM_ALT_ROOT_CLK, IMX7D_DRAM_ALT_ROOT_CLK,
IMX7D_AHB_CHANNEL_ROOT_CLK,
};
static struct clk_onecell_data clk_data;
static struct clk ** const uart_clks[] __initconst = {
&clks[IMX7D_UART1_ROOT_CLK],
&clks[IMX7D_UART2_ROOT_CLK],
&clks[IMX7D_UART3_ROOT_CLK],
&clks[IMX7D_UART4_ROOT_CLK],
&clks[IMX7D_UART5_ROOT_CLK],
&clks[IMX7D_UART6_ROOT_CLK],
&clks[IMX7D_UART7_ROOT_CLK],
NULL
};
static int imx7_clk_initialized;
static int imx7_ccm_probe(struct device_d *dev)
{
struct resource *iores;
void __iomem *base, *anatop_base, *ccm_base;
anatop_base = IOMEM(MX7_ANATOP_BASE_ADDR);
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
ccm_base = IOMEM(iores->start);
base = anatop_base;
clks[IMX7D_PLL_ARM_MAIN] = imx_clk_pllv3(IMX_PLLV3_SYS, "pll_arm_main", "osc", base + 0x60, 0x7f);
clks[IMX7D_PLL_DRAM_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_dram_main", "osc", base + 0x70, 0x7f);
clks[IMX7D_PLL_SYS_MAIN] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll_sys_main", "osc", base + 0xb0, 0x1);
clks[IMX7D_PLL_ENET_MAIN] = imx_clk_pllv3(IMX_PLLV3_ENET_IMX7, "pll_enet_main", "osc", base + 0xe0, 0x0);
clks[IMX7D_PLL_AUDIO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_audio_main", "osc", base + 0xf0, 0x7f);
clks[IMX7D_PLL_VIDEO_MAIN] = imx_clk_pllv3(IMX_PLLV3_AV, "pll_video_main", "osc", base + 0x130, 0x7f);
clks[IMX7D_PLL_SYS_PFD0_392M_CLK] = imx_clk_pfd("pll_sys_pfd0_392m_clk", "pll_sys_main", base + 0xc0, 0);
clks[IMX7D_PLL_SYS_PFD1_332M_CLK] = imx_clk_pfd("pll_sys_pfd1_332m_clk", "pll_sys_main", base + 0xc0, 1);
clks[IMX7D_PLL_SYS_PFD2_270M_CLK] = imx_clk_pfd("pll_sys_pfd2_270m_clk", "pll_sys_main", base + 0xc0, 2);
clks[IMX7D_PLL_SYS_PFD3_CLK] = imx_clk_pfd("pll_sys_pfd3_clk", "pll_sys_main", base + 0xc0, 3);
clks[IMX7D_PLL_SYS_PFD4_CLK] = imx_clk_pfd("pll_sys_pfd4_clk", "pll_sys_main", base + 0xd0, 0);
clks[IMX7D_PLL_SYS_PFD5_CLK] = imx_clk_pfd("pll_sys_pfd5_clk", "pll_sys_main", base + 0xd0, 1);
clks[IMX7D_PLL_SYS_PFD6_CLK] = imx_clk_pfd("pll_sys_pfd6_clk", "pll_sys_main", base + 0xd0, 2);
clks[IMX7D_PLL_SYS_PFD7_CLK] = imx_clk_pfd("pll_sys_pfd7_clk", "pll_sys_main", base + 0xd0, 3);
clks[IMX7D_PLL_SYS_MAIN_480M] = imx_clk_fixed_factor("pll_sys_main_480m", "pll_sys_main", 1, 1);
clks[IMX7D_PLL_SYS_MAIN_240M] = imx_clk_fixed_factor("pll_sys_main_240m", "pll_sys_main", 1, 2);
clks[IMX7D_PLL_SYS_MAIN_120M] = imx_clk_fixed_factor("pll_sys_main_120m", "pll_sys_main", 1, 4);
clks[IMX7D_PLL_DRAM_MAIN_533M] = imx_clk_fixed_factor("pll_dram_533m", "pll_dram_main", 1, 2);
clks[IMX7D_PLL_SYS_MAIN_480M_CLK] = imx_clk_gate_dis("pll_sys_main_480m_clk", "pll_sys_main_480m", base + 0xb0, 4);
clks[IMX7D_PLL_SYS_MAIN_240M_CLK] = imx_clk_gate_dis("pll_sys_main_240m_clk", "pll_sys_main_240m", base + 0xb0, 5);
clks[IMX7D_PLL_SYS_MAIN_120M_CLK] = imx_clk_gate_dis("pll_sys_main_120m_clk", "pll_sys_main_120m", base + 0xb0, 6);
clks[IMX7D_PLL_DRAM_MAIN_533M_CLK] = imx_clk_gate("pll_dram_533m_clk", "pll_dram_533m", base + 0x70, 12);
clks[IMX7D_PLL_SYS_PFD0_196M] = imx_clk_fixed_factor("pll_sys_pfd0_196m", "pll_sys_pfd0_392m_clk", 1, 2);
clks[IMX7D_PLL_SYS_PFD1_166M] = imx_clk_fixed_factor("pll_sys_pfd1_166m", "pll_sys_pfd1_332m_clk", 1, 2);
clks[IMX7D_PLL_SYS_PFD2_135M] = imx_clk_fixed_factor("pll_sys_pfd2_135m", "pll_sys_pfd2_270m_clk", 1, 2);
clks[IMX7D_PLL_SYS_PFD0_196M_CLK] = imx_clk_gate_dis("pll_sys_pfd0_196m_clk", "pll_sys_pfd0_196m", base + 0xb0, 26);
clks[IMX7D_PLL_SYS_PFD1_166M_CLK] = imx_clk_gate_dis("pll_sys_pfd1_166m_clk", "pll_sys_pfd1_166m", base + 0xb0, 27);
clks[IMX7D_PLL_SYS_PFD2_135M_CLK] = imx_clk_gate_dis("pll_sys_pfd2_135m_clk", "pll_sys_pfd2_135m", base + 0xb0, 28);
clks[IMX7D_PLL_ENET_MAIN_CLK] = imx_clk_fixed_factor("pll_enet_main_clk", "pll_enet_main", 1, 1);
clks[IMX7D_PLL_ENET_MAIN_500M] = imx_clk_fixed_factor("pll_enet_500m", "pll_enet_main_clk", 1, 2);
clks[IMX7D_PLL_ENET_MAIN_250M] = imx_clk_fixed_factor("pll_enet_250m", "pll_enet_main_clk", 1, 4);
clks[IMX7D_PLL_ENET_MAIN_125M] = imx_clk_fixed_factor("pll_enet_125m", "pll_enet_main_clk", 1, 8);
clks[IMX7D_PLL_ENET_MAIN_100M] = imx_clk_fixed_factor("pll_enet_100m", "pll_enet_main_clk", 1, 10);
clks[IMX7D_PLL_ENET_MAIN_50M] = imx_clk_fixed_factor("pll_enet_50m", "pll_enet_main_clk", 1, 20);
clks[IMX7D_PLL_ENET_MAIN_40M] = imx_clk_fixed_factor("pll_enet_40m", "pll_enet_main_clk", 1, 25);
clks[IMX7D_PLL_ENET_MAIN_25M] = imx_clk_fixed_factor("pll_enet_25m", "pll_enet_main_clk", 1, 40);
clks[IMX7D_PLL_ENET_MAIN_500M_CLK] = imx_clk_gate("pll_enet_500m_clk", "pll_enet_500m", base + 0xe0, 12);
clks[IMX7D_PLL_ENET_MAIN_250M_CLK] = imx_clk_gate("pll_enet_250m_clk", "pll_enet_250m", base + 0xe0, 11);
clks[IMX7D_PLL_ENET_MAIN_125M_CLK] = imx_clk_gate("pll_enet_125m_clk", "pll_enet_125m", base + 0xe0, 10);
clks[IMX7D_PLL_ENET_MAIN_100M_CLK] = imx_clk_gate("pll_enet_100m_clk", "pll_enet_100m", base + 0xe0, 9);
clks[IMX7D_PLL_ENET_MAIN_50M_CLK] = imx_clk_gate("pll_enet_50m_clk", "pll_enet_50m", base + 0xe0, 8);
clks[IMX7D_PLL_ENET_MAIN_40M_CLK] = imx_clk_gate("pll_enet_40m_clk", "pll_enet_40m", base + 0xe0, 7);
clks[IMX7D_PLL_ENET_MAIN_25M_CLK] = imx_clk_gate("pll_enet_25m_clk", "pll_enet_25m", base + 0xe0, 6);
clks[IMX7D_LVDS1_OUT_SEL] = imx_clk_mux("lvds1_sel", base + 0x170, 0, 5, lvds1_sel, ARRAY_SIZE(lvds1_sel));
clks[IMX7D_LVDS1_OUT_CLK] = imx_clk_gate_exclusive("lvds1_out", "lvds1_sel", base + 0x170, 5, BIT(6));
base = ccm_base;
clks[IMX7D_ARM_A7_ROOT_SRC] = imx_clk_mux2("arm_a7_src", base + 0x8000, 24, 3, arm_a7_sel, ARRAY_SIZE(arm_a7_sel));
clks[IMX7D_ARM_M4_ROOT_SRC] = imx_clk_mux2("arm_m4_src", base + 0x8080, 24, 3, arm_m4_sel, ARRAY_SIZE(arm_m4_sel));
clks[IMX7D_ARM_M0_ROOT_SRC] = imx_clk_mux2("arm_m0_src", base + 0x8100, 24, 3, arm_m0_sel, ARRAY_SIZE(arm_m0_sel));
clks[IMX7D_MAIN_AXI_ROOT_SRC] = imx_clk_mux2("axi_src", base + 0x8800, 24, 3, axi_sel, ARRAY_SIZE(axi_sel));
clks[IMX7D_DISP_AXI_ROOT_SRC] = imx_clk_mux2("disp_axi_src", base + 0x8880, 24, 3, disp_axi_sel, ARRAY_SIZE(disp_axi_sel));
clks[IMX7D_ENET_AXI_ROOT_SRC] = imx_clk_mux2("enet_axi_src", base + 0x8900, 24, 3, enet_axi_sel, ARRAY_SIZE(enet_axi_sel));
clks[IMX7D_NAND_USDHC_BUS_ROOT_SRC] = imx_clk_mux2("nand_usdhc_src", base + 0x8980, 24, 3, nand_usdhc_bus_sel, ARRAY_SIZE(nand_usdhc_bus_sel));
clks[IMX7D_AHB_CHANNEL_ROOT_SRC] = imx_clk_mux2("ahb_src", base + 0x9000, 24, 3, ahb_channel_sel, ARRAY_SIZE(ahb_channel_sel));
clks[IMX7D_DRAM_PHYM_ROOT_SRC] = imx_clk_mux2("dram_phym_src", base + 0x9800, 24, 1, dram_phym_sel, ARRAY_SIZE(dram_phym_sel));
clks[IMX7D_DRAM_ROOT_SRC] = imx_clk_mux2("dram_src", base + 0x9880, 24, 1, dram_sel, ARRAY_SIZE(dram_sel));
clks[IMX7D_DRAM_PHYM_ALT_ROOT_SRC] = imx_clk_mux2("dram_phym_alt_src", base + 0xa000, 24, 3, dram_phym_alt_sel, ARRAY_SIZE(dram_phym_alt_sel));
clks[IMX7D_DRAM_ALT_ROOT_SRC] = imx_clk_mux2("dram_alt_src", base + 0xa080, 24, 3, dram_alt_sel, ARRAY_SIZE(dram_alt_sel));
clks[IMX7D_USB_HSIC_ROOT_SRC] = imx_clk_mux2("usb_hsic_src", base + 0xa100, 24, 3, usb_hsic_sel, ARRAY_SIZE(usb_hsic_sel));
clks[IMX7D_PCIE_CTRL_ROOT_SRC] = imx_clk_mux2("pcie_ctrl_src", base + 0xa180, 24, 3, pcie_ctrl_sel, ARRAY_SIZE(pcie_ctrl_sel));
clks[IMX7D_PCIE_PHY_ROOT_SRC] = imx_clk_mux2("pcie_phy_src", base + 0xa200, 24, 3, pcie_phy_sel, ARRAY_SIZE(pcie_phy_sel));
clks[IMX7D_EPDC_PIXEL_ROOT_SRC] = imx_clk_mux2("epdc_pixel_src", base + 0xa280, 24, 3, epdc_pixel_sel, ARRAY_SIZE(epdc_pixel_sel));
clks[IMX7D_LCDIF_PIXEL_ROOT_SRC] = imx_clk_mux2("lcdif_pixel_src", base + 0xa300, 24, 3, lcdif_pixel_sel, ARRAY_SIZE(lcdif_pixel_sel));
clks[IMX7D_MIPI_DSI_ROOT_SRC] = imx_clk_mux2("mipi_dsi_src", base + 0xa380, 24, 3, mipi_dsi_sel, ARRAY_SIZE(mipi_dsi_sel));
clks[IMX7D_MIPI_CSI_ROOT_SRC] = imx_clk_mux2("mipi_csi_src", base + 0xa400, 24, 3, mipi_csi_sel, ARRAY_SIZE(mipi_csi_sel));
clks[IMX7D_MIPI_DPHY_ROOT_SRC] = imx_clk_mux2("mipi_dphy_src", base + 0xa480, 24, 3, mipi_dphy_sel, ARRAY_SIZE(mipi_dphy_sel));
clks[IMX7D_SAI1_ROOT_SRC] = imx_clk_mux2("sai1_src", base + 0xa500, 24, 3, sai1_sel, ARRAY_SIZE(sai1_sel));
clks[IMX7D_SAI2_ROOT_SRC] = imx_clk_mux2("sai2_src", base + 0xa580, 24, 3, sai2_sel, ARRAY_SIZE(sai2_sel));
clks[IMX7D_SAI3_ROOT_SRC] = imx_clk_mux2("sai3_src", base + 0xa600, 24, 3, sai3_sel, ARRAY_SIZE(sai3_sel));
clks[IMX7D_SPDIF_ROOT_SRC] = imx_clk_mux2("spdif_src", base + 0xa680, 24, 3, spdif_sel, ARRAY_SIZE(spdif_sel));
clks[IMX7D_ENET1_REF_ROOT_SRC] = imx_clk_mux2("enet1_ref_src", base + 0xa700, 24, 3, enet1_ref_sel, ARRAY_SIZE(enet1_ref_sel));
clks[IMX7D_ENET1_TIME_ROOT_SRC] = imx_clk_mux2("enet1_time_src", base + 0xa780, 24, 3, enet1_time_sel, ARRAY_SIZE(enet1_time_sel));
clks[IMX7D_ENET2_REF_ROOT_SRC] = imx_clk_mux2("enet2_ref_src", base + 0xa800, 24, 3, enet2_ref_sel, ARRAY_SIZE(enet2_ref_sel));
clks[IMX7D_ENET2_TIME_ROOT_SRC] = imx_clk_mux2("enet2_time_src", base + 0xa880, 24, 3, enet2_time_sel, ARRAY_SIZE(enet2_time_sel));
clks[IMX7D_ENET_PHY_REF_ROOT_SRC] = imx_clk_mux2("enet_phy_ref_src", base + 0xa900, 24, 3, enet_phy_ref_sel, ARRAY_SIZE(enet_phy_ref_sel));
clks[IMX7D_EIM_ROOT_SRC] = imx_clk_mux2("eim_src", base + 0xa980, 24, 3, eim_sel, ARRAY_SIZE(eim_sel));
clks[IMX7D_NAND_ROOT_SRC] = imx_clk_mux2("nand_src", base + 0xaa00, 24, 3, nand_sel, ARRAY_SIZE(nand_sel));
clks[IMX7D_QSPI_ROOT_SRC] = imx_clk_mux2("qspi_src", base + 0xaa80, 24, 3, qspi_sel, ARRAY_SIZE(qspi_sel));
clks[IMX7D_USDHC1_ROOT_SRC] = imx_clk_mux2("usdhc1_src", base + 0xab00, 24, 3, usdhc1_sel, ARRAY_SIZE(usdhc1_sel));
clks[IMX7D_USDHC2_ROOT_SRC] = imx_clk_mux2("usdhc2_src", base + 0xab80, 24, 3, usdhc2_sel, ARRAY_SIZE(usdhc2_sel));
clks[IMX7D_USDHC3_ROOT_SRC] = imx_clk_mux2("usdhc3_src", base + 0xac00, 24, 3, usdhc3_sel, ARRAY_SIZE(usdhc3_sel));
clks[IMX7D_CAN1_ROOT_SRC] = imx_clk_mux2("can1_src", base + 0xac80, 24, 3, can1_sel, ARRAY_SIZE(can1_sel));
clks[IMX7D_CAN2_ROOT_SRC] = imx_clk_mux2("can2_src", base + 0xad00, 24, 3, can2_sel, ARRAY_SIZE(can2_sel));
clks[IMX7D_I2C1_ROOT_SRC] = imx_clk_mux2("i2c1_src", base + 0xad80, 24, 3, i2c1_sel, ARRAY_SIZE(i2c1_sel));
clks[IMX7D_I2C2_ROOT_SRC] = imx_clk_mux2("i2c2_src", base + 0xae00, 24, 3, i2c2_sel, ARRAY_SIZE(i2c2_sel));
clks[IMX7D_I2C3_ROOT_SRC] = imx_clk_mux2("i2c3_src", base + 0xae80, 24, 3, i2c3_sel, ARRAY_SIZE(i2c3_sel));
clks[IMX7D_I2C4_ROOT_SRC] = imx_clk_mux2("i2c4_src", base + 0xaf00, 24, 3, i2c4_sel, ARRAY_SIZE(i2c4_sel));
clks[IMX7D_UART1_ROOT_SRC] = imx_clk_mux2("uart1_src", base + 0xaf80, 24, 3, uart1_sel, ARRAY_SIZE(uart1_sel));
clks[IMX7D_UART2_ROOT_SRC] = imx_clk_mux2("uart2_src", base + 0xb000, 24, 3, uart2_sel, ARRAY_SIZE(uart2_sel));
clks[IMX7D_UART3_ROOT_SRC] = imx_clk_mux2("uart3_src", base + 0xb080, 24, 3, uart3_sel, ARRAY_SIZE(uart3_sel));
clks[IMX7D_UART4_ROOT_SRC] = imx_clk_mux2("uart4_src", base + 0xb100, 24, 3, uart4_sel, ARRAY_SIZE(uart4_sel));
clks[IMX7D_UART5_ROOT_SRC] = imx_clk_mux2("uart5_src", base + 0xb180, 24, 3, uart5_sel, ARRAY_SIZE(uart5_sel));
clks[IMX7D_UART6_ROOT_SRC] = imx_clk_mux2("uart6_src", base + 0xb200, 24, 3, uart6_sel, ARRAY_SIZE(uart6_sel));
clks[IMX7D_UART7_ROOT_SRC] = imx_clk_mux2("uart7_src", base + 0xb280, 24, 3, uart7_sel, ARRAY_SIZE(uart7_sel));
clks[IMX7D_ECSPI1_ROOT_SRC] = imx_clk_mux2("ecspi1_src", base + 0xb300, 24, 3, ecspi1_sel, ARRAY_SIZE(ecspi1_sel));
clks[IMX7D_ECSPI2_ROOT_SRC] = imx_clk_mux2("ecspi2_src", base + 0xb380, 24, 3, ecspi2_sel, ARRAY_SIZE(ecspi2_sel));
clks[IMX7D_ECSPI3_ROOT_SRC] = imx_clk_mux2("ecspi3_src", base + 0xb400, 24, 3, ecspi3_sel, ARRAY_SIZE(ecspi3_sel));
clks[IMX7D_ECSPI4_ROOT_SRC] = imx_clk_mux2("ecspi4_src", base + 0xb480, 24, 3, ecspi4_sel, ARRAY_SIZE(ecspi4_sel));
clks[IMX7D_PWM1_ROOT_SRC] = imx_clk_mux2("pwm1_src", base + 0xb500, 24, 3, pwm1_sel, ARRAY_SIZE(pwm1_sel));
clks[IMX7D_PWM2_ROOT_SRC] = imx_clk_mux2("pwm2_src", base + 0xb580, 24, 3, pwm2_sel, ARRAY_SIZE(pwm2_sel));
clks[IMX7D_PWM3_ROOT_SRC] = imx_clk_mux2("pwm3_src", base + 0xb600, 24, 3, pwm3_sel, ARRAY_SIZE(pwm3_sel));
clks[IMX7D_PWM4_ROOT_SRC] = imx_clk_mux2("pwm4_src", base + 0xb680, 24, 3, pwm4_sel, ARRAY_SIZE(pwm4_sel));
clks[IMX7D_FLEXTIMER1_ROOT_SRC] = imx_clk_mux2("flextimer1_src", base + 0xb700, 24, 3, flextimer1_sel, ARRAY_SIZE(flextimer1_sel));
clks[IMX7D_FLEXTIMER2_ROOT_SRC] = imx_clk_mux2("flextimer2_src", base + 0xb780, 24, 3, flextimer2_sel, ARRAY_SIZE(flextimer2_sel));
clks[IMX7D_SIM1_ROOT_SRC] = imx_clk_mux2("sim1_src", base + 0xb800, 24, 3, sim1_sel, ARRAY_SIZE(sim1_sel));
clks[IMX7D_SIM2_ROOT_SRC] = imx_clk_mux2("sim2_src", base + 0xb880, 24, 3, sim2_sel, ARRAY_SIZE(sim2_sel));
clks[IMX7D_GPT1_ROOT_SRC] = imx_clk_mux2("gpt1_src", base + 0xb900, 24, 3, gpt1_sel, ARRAY_SIZE(gpt1_sel));
clks[IMX7D_GPT2_ROOT_SRC] = imx_clk_mux2("gpt2_src", base + 0xb980, 24, 3, gpt2_sel, ARRAY_SIZE(gpt2_sel));
clks[IMX7D_GPT3_ROOT_SRC] = imx_clk_mux2("gpt3_src", base + 0xba00, 24, 3, gpt3_sel, ARRAY_SIZE(gpt3_sel));
clks[IMX7D_GPT4_ROOT_SRC] = imx_clk_mux2("gpt4_src", base + 0xba80, 24, 3, gpt4_sel, ARRAY_SIZE(gpt4_sel));
clks[IMX7D_TRACE_ROOT_SRC] = imx_clk_mux2("trace_src", base + 0xbb00, 24, 3, trace_sel, ARRAY_SIZE(trace_sel));
clks[IMX7D_WDOG_ROOT_SRC] = imx_clk_mux2("wdog_src", base + 0xbb80, 24, 3, wdog_sel, ARRAY_SIZE(wdog_sel));
clks[IMX7D_CSI_MCLK_ROOT_SRC] = imx_clk_mux2("csi_mclk_src", base + 0xbc00, 24, 3, csi_mclk_sel, ARRAY_SIZE(csi_mclk_sel));
clks[IMX7D_AUDIO_MCLK_ROOT_SRC] = imx_clk_mux2("audio_mclk_src", base + 0xbc80, 24, 3, audio_mclk_sel, ARRAY_SIZE(audio_mclk_sel));
clks[IMX7D_WRCLK_ROOT_SRC] = imx_clk_mux2("wrclk_src", base + 0xbd00, 24, 3, wrclk_sel, ARRAY_SIZE(wrclk_sel));
clks[IMX7D_CLKO1_ROOT_SRC] = imx_clk_mux2("clko1_src", base + 0xbd80, 24, 3, clko1_sel, ARRAY_SIZE(clko1_sel));
clks[IMX7D_CLKO2_ROOT_SRC] = imx_clk_mux2("clko2_src", base + 0xbe00, 24, 3, clko2_sel, ARRAY_SIZE(clko2_sel));
clks[IMX7D_ARM_A7_ROOT_CG] = imx_clk_gate3("arm_a7_cg", "arm_a7_src", base + 0x8000, 28);
clks[IMX7D_ARM_M4_ROOT_CG] = imx_clk_gate3("arm_m4_cg", "arm_m4_src", base + 0x8080, 28);
clks[IMX7D_ARM_M0_ROOT_CG] = imx_clk_gate3("arm_m0_cg", "arm_m0_src", base + 0x8100, 28);
clks[IMX7D_MAIN_AXI_ROOT_CG] = imx_clk_gate3("axi_cg", "axi_src", base + 0x8800, 28);
clks[IMX7D_DISP_AXI_ROOT_CG] = imx_clk_gate3("disp_axi_cg", "disp_axi_src", base + 0x8880, 28);
clks[IMX7D_ENET_AXI_ROOT_CG] = imx_clk_gate3("enet_axi_cg", "enet_axi_src", base + 0x8900, 28);
clks[IMX7D_NAND_USDHC_BUS_ROOT_CG] = imx_clk_gate3("nand_usdhc_cg", "nand_usdhc_src", base + 0x8980, 28);
clks[IMX7D_AHB_CHANNEL_ROOT_CG] = imx_clk_gate3("ahb_cg", "ahb_src", base + 0x9000, 28);
clks[IMX7D_DRAM_PHYM_ROOT_CG] = imx_clk_gate3("dram_phym_cg", "dram_phym_src", base + 0x9800, 28);
clks[IMX7D_DRAM_ROOT_CG] = imx_clk_gate3("dram_cg", "dram_src", base + 0x9880, 28);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CG] = imx_clk_gate3("dram_phym_alt_cg", "dram_phym_alt_src", base + 0xa000, 28);
clks[IMX7D_DRAM_ALT_ROOT_CG] = imx_clk_gate3("dram_alt_cg", "dram_alt_src", base + 0xa080, 28);
clks[IMX7D_USB_HSIC_ROOT_CG] = imx_clk_gate3("usb_hsic_cg", "usb_hsic_src", base + 0xa100, 28);
clks[IMX7D_PCIE_CTRL_ROOT_CG] = imx_clk_gate3("pcie_ctrl_cg", "pcie_ctrl_src", base + 0xa180, 28);
clks[IMX7D_PCIE_PHY_ROOT_CG] = imx_clk_gate3("pcie_phy_cg", "pcie_phy_src", base + 0xa200, 28);
clks[IMX7D_EPDC_PIXEL_ROOT_CG] = imx_clk_gate3("epdc_pixel_cg", "epdc_pixel_src", base + 0xa280, 28);
clks[IMX7D_LCDIF_PIXEL_ROOT_CG] = imx_clk_gate3("lcdif_pixel_cg", "lcdif_pixel_src", base + 0xa300, 28);
clks[IMX7D_MIPI_DSI_ROOT_CG] = imx_clk_gate3("mipi_dsi_cg", "mipi_dsi_src", base + 0xa380, 28);
clks[IMX7D_MIPI_CSI_ROOT_CG] = imx_clk_gate3("mipi_csi_cg", "mipi_csi_src", base + 0xa400, 28);
clks[IMX7D_MIPI_DPHY_ROOT_CG] = imx_clk_gate3("mipi_dphy_cg", "mipi_dphy_src", base + 0xa480, 28);
clks[IMX7D_SAI1_ROOT_CG] = imx_clk_gate3("sai1_cg", "sai1_src", base + 0xa500, 28);
clks[IMX7D_SAI2_ROOT_CG] = imx_clk_gate3("sai2_cg", "sai2_src", base + 0xa580, 28);
clks[IMX7D_SAI3_ROOT_CG] = imx_clk_gate3("sai3_cg", "sai3_src", base + 0xa600, 28);
clks[IMX7D_SPDIF_ROOT_CG] = imx_clk_gate3("spdif_cg", "spdif_src", base + 0xa680, 28);
clks[IMX7D_ENET1_REF_ROOT_CG] = imx_clk_gate3("enet1_ref_cg", "enet1_ref_src", base + 0xa700, 28);
clks[IMX7D_ENET1_TIME_ROOT_CG] = imx_clk_gate3("enet1_time_cg", "enet1_time_src", base + 0xa780, 28);
clks[IMX7D_ENET2_REF_ROOT_CG] = imx_clk_gate3("enet2_ref_cg", "enet2_ref_src", base + 0xa800, 28);
clks[IMX7D_ENET2_TIME_ROOT_CG] = imx_clk_gate3("enet2_time_cg", "enet2_time_src", base + 0xa880, 28);
clks[IMX7D_ENET_PHY_REF_ROOT_CG] = imx_clk_gate3("enet_phy_ref_cg", "enet_phy_ref_src", base + 0xa900, 28);
clks[IMX7D_EIM_ROOT_CG] = imx_clk_gate3("eim_cg", "eim_src", base + 0xa980, 28);
clks[IMX7D_NAND_ROOT_CG] = imx_clk_gate3("nand_cg", "nand_src", base + 0xaa00, 28);
clks[IMX7D_QSPI_ROOT_CG] = imx_clk_gate3("qspi_cg", "qspi_src", base + 0xaa80, 28);
clks[IMX7D_USDHC1_ROOT_CG] = imx_clk_gate3("usdhc1_cg", "usdhc1_src", base + 0xab00, 28);
clks[IMX7D_USDHC2_ROOT_CG] = imx_clk_gate3("usdhc2_cg", "usdhc2_src", base + 0xab80, 28);
clks[IMX7D_USDHC3_ROOT_CG] = imx_clk_gate3("usdhc3_cg", "usdhc3_src", base + 0xac00, 28);
clks[IMX7D_CAN1_ROOT_CG] = imx_clk_gate3("can1_cg", "can1_src", base + 0xac80, 28);
clks[IMX7D_CAN2_ROOT_CG] = imx_clk_gate3("can2_cg", "can2_src", base + 0xad00, 28);
clks[IMX7D_I2C1_ROOT_CG] = imx_clk_gate3("i2c1_cg", "i2c1_src", base + 0xad80, 28);
clks[IMX7D_I2C2_ROOT_CG] = imx_clk_gate3("i2c2_cg", "i2c2_src", base + 0xae00, 28);
clks[IMX7D_I2C3_ROOT_CG] = imx_clk_gate3("i2c3_cg", "i2c3_src", base + 0xae80, 28);
clks[IMX7D_I2C4_ROOT_CG] = imx_clk_gate3("i2c4_cg", "i2c4_src", base + 0xaf00, 28);
clks[IMX7D_UART1_ROOT_CG] = imx_clk_gate3("uart1_cg", "uart1_src", base + 0xaf80, 28);
clks[IMX7D_UART2_ROOT_CG] = imx_clk_gate3("uart2_cg", "uart2_src", base + 0xb000, 28);
clks[IMX7D_UART3_ROOT_CG] = imx_clk_gate3("uart3_cg", "uart3_src", base + 0xb080, 28);
clks[IMX7D_UART4_ROOT_CG] = imx_clk_gate3("uart4_cg", "uart4_src", base + 0xb100, 28);
clks[IMX7D_UART5_ROOT_CG] = imx_clk_gate3("uart5_cg", "uart5_src", base + 0xb180, 28);
clks[IMX7D_UART6_ROOT_CG] = imx_clk_gate3("uart6_cg", "uart6_src", base + 0xb200, 28);
clks[IMX7D_UART7_ROOT_CG] = imx_clk_gate3("uart7_cg", "uart7_src", base + 0xb280, 28);
clks[IMX7D_ECSPI1_ROOT_CG] = imx_clk_gate3("ecspi1_cg", "ecspi1_src", base + 0xb300, 28);
clks[IMX7D_ECSPI2_ROOT_CG] = imx_clk_gate3("ecspi2_cg", "ecspi2_src", base + 0xb380, 28);
clks[IMX7D_ECSPI3_ROOT_CG] = imx_clk_gate3("ecspi3_cg", "ecspi3_src", base + 0xb400, 28);
clks[IMX7D_ECSPI4_ROOT_CG] = imx_clk_gate3("ecspi4_cg", "ecspi4_src", base + 0xb480, 28);
clks[IMX7D_PWM1_ROOT_CG] = imx_clk_gate3("pwm1_cg", "pwm1_src", base + 0xb500, 28);
clks[IMX7D_PWM2_ROOT_CG] = imx_clk_gate3("pwm2_cg", "pwm2_src", base + 0xb580, 28);
clks[IMX7D_PWM3_ROOT_CG] = imx_clk_gate3("pwm3_cg", "pwm3_src", base + 0xb600, 28);
clks[IMX7D_PWM4_ROOT_CG] = imx_clk_gate3("pwm4_cg", "pwm4_src", base + 0xb680, 28);
clks[IMX7D_FLEXTIMER1_ROOT_CG] = imx_clk_gate3("flextimer1_cg", "flextimer1_src", base + 0xb700, 28);
clks[IMX7D_FLEXTIMER2_ROOT_CG] = imx_clk_gate3("flextimer2_cg", "flextimer2_src", base + 0xb780, 28);
clks[IMX7D_SIM1_ROOT_CG] = imx_clk_gate3("sim1_cg", "sim1_src", base + 0xb800, 28);
clks[IMX7D_SIM2_ROOT_CG] = imx_clk_gate3("sim2_cg", "sim2_src", base + 0xb880, 28);
clks[IMX7D_GPT1_ROOT_CG] = imx_clk_gate3("gpt1_cg", "gpt1_src", base + 0xb900, 28);
clks[IMX7D_GPT2_ROOT_CG] = imx_clk_gate3("gpt2_cg", "gpt2_src", base + 0xb980, 28);
clks[IMX7D_GPT3_ROOT_CG] = imx_clk_gate3("gpt3_cg", "gpt3_src", base + 0xbA00, 28);
clks[IMX7D_GPT4_ROOT_CG] = imx_clk_gate3("gpt4_cg", "gpt4_src", base + 0xbA80, 28);
clks[IMX7D_TRACE_ROOT_CG] = imx_clk_gate3("trace_cg", "trace_src", base + 0xbb00, 28);
clks[IMX7D_WDOG_ROOT_CG] = imx_clk_gate3("wdog_cg", "wdog_src", base + 0xbb80, 28);
clks[IMX7D_CSI_MCLK_ROOT_CG] = imx_clk_gate3("csi_mclk_cg", "csi_mclk_src", base + 0xbc00, 28);
clks[IMX7D_AUDIO_MCLK_ROOT_CG] = imx_clk_gate3("audio_mclk_cg", "audio_mclk_src", base + 0xbc80, 28);
clks[IMX7D_WRCLK_ROOT_CG] = imx_clk_gate3("wrclk_cg", "wrclk_src", base + 0xbd00, 28);
clks[IMX7D_CLKO1_ROOT_CG] = imx_clk_gate3("clko1_cg", "clko1_src", base + 0xbd80, 28);
clks[IMX7D_CLKO2_ROOT_CG] = imx_clk_gate3("clko2_cg", "clko2_src", base + 0xbe00, 28);
clks[IMX7D_MAIN_AXI_ROOT_PRE_DIV] = imx_clk_divider2("axi_pre_div", "axi_cg", base + 0x8800, 16, 3);
clks[IMX7D_DISP_AXI_ROOT_PRE_DIV] = imx_clk_divider2("disp_axi_pre_div", "disp_axi_cg", base + 0x8880, 16, 3);
clks[IMX7D_ENET_AXI_ROOT_PRE_DIV] = imx_clk_divider2("enet_axi_pre_div", "enet_axi_cg", base + 0x8900, 16, 3);
clks[IMX7D_NAND_USDHC_BUS_ROOT_PRE_DIV] = imx_clk_divider2("nand_usdhc_pre_div", "nand_usdhc_cg", base + 0x8980, 16, 3);
clks[IMX7D_AHB_CHANNEL_ROOT_PRE_DIV] = imx_clk_divider2("ahb_pre_div", "ahb_cg", base + 0x9000, 16, 3);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_PRE_DIV] = imx_clk_divider2("dram_phym_alt_pre_div", "dram_phym_alt_cg", base + 0xa000, 16, 3);
clks[IMX7D_DRAM_ALT_ROOT_PRE_DIV] = imx_clk_divider2("dram_alt_pre_div", "dram_alt_cg", base + 0xa080, 16, 3);
clks[IMX7D_USB_HSIC_ROOT_PRE_DIV] = imx_clk_divider2("usb_hsic_pre_div", "usb_hsic_cg", base + 0xa100, 16, 3);
clks[IMX7D_PCIE_CTRL_ROOT_PRE_DIV] = imx_clk_divider2("pcie_ctrl_pre_div", "pcie_ctrl_cg", base + 0xa180, 16, 3);
clks[IMX7D_PCIE_PHY_ROOT_PRE_DIV] = imx_clk_divider2("pcie_phy_pre_div", "pcie_phy_cg", base + 0xa200, 16, 3);
clks[IMX7D_EPDC_PIXEL_ROOT_PRE_DIV] = imx_clk_divider2("epdc_pixel_pre_div", "epdc_pixel_cg", base + 0xa280, 16, 3);
clks[IMX7D_LCDIF_PIXEL_ROOT_PRE_DIV] = imx_clk_divider2("lcdif_pixel_pre_div", "lcdif_pixel_cg", base + 0xa300, 16, 3);
clks[IMX7D_MIPI_DSI_ROOT_PRE_DIV] = imx_clk_divider2("mipi_dsi_pre_div", "mipi_dsi_cg", base + 0xa380, 16, 3);
clks[IMX7D_MIPI_CSI_ROOT_PRE_DIV] = imx_clk_divider2("mipi_csi_pre_div", "mipi_csi_cg", base + 0xa400, 16, 3);
clks[IMX7D_MIPI_DPHY_ROOT_PRE_DIV] = imx_clk_divider2("mipi_dphy_pre_div", "mipi_dphy_cg", base + 0xa480, 16, 3);
clks[IMX7D_SAI1_ROOT_PRE_DIV] = imx_clk_divider2("sai1_pre_div", "sai1_cg", base + 0xa500, 16, 3);
clks[IMX7D_SAI2_ROOT_PRE_DIV] = imx_clk_divider2("sai2_pre_div", "sai2_cg", base + 0xa580, 16, 3);
clks[IMX7D_SAI3_ROOT_PRE_DIV] = imx_clk_divider2("sai3_pre_div", "sai3_cg", base + 0xa600, 16, 3);
clks[IMX7D_SPDIF_ROOT_PRE_DIV] = imx_clk_divider2("spdif_pre_div", "spdif_cg", base + 0xa680, 16, 3);
clks[IMX7D_ENET1_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet1_ref_pre_div", "enet1_ref_cg", base + 0xa700, 16, 3);
clks[IMX7D_ENET1_TIME_ROOT_PRE_DIV] = imx_clk_divider2("enet1_time_pre_div", "enet1_time_cg", base + 0xa780, 16, 3);
clks[IMX7D_ENET2_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet2_ref_pre_div", "enet2_ref_cg", base + 0xa800, 16, 3);
clks[IMX7D_ENET2_TIME_ROOT_PRE_DIV] = imx_clk_divider2("enet2_time_pre_div", "enet2_time_cg", base + 0xa880, 16, 3);
clks[IMX7D_ENET_PHY_REF_ROOT_PRE_DIV] = imx_clk_divider2("enet_phy_ref_pre_div", "enet_phy_ref_cg", base + 0xa900, 16, 3);
clks[IMX7D_EIM_ROOT_PRE_DIV] = imx_clk_divider2("eim_pre_div", "eim_cg", base + 0xa980, 16, 3);
clks[IMX7D_NAND_ROOT_PRE_DIV] = imx_clk_divider2("nand_pre_div", "nand_cg", base + 0xaa00, 16, 3);
clks[IMX7D_QSPI_ROOT_PRE_DIV] = imx_clk_divider2("qspi_pre_div", "qspi_cg", base + 0xaa80, 16, 3);
clks[IMX7D_USDHC1_ROOT_PRE_DIV] = imx_clk_divider2("usdhc1_pre_div", "usdhc1_cg", base + 0xab00, 16, 3);
clks[IMX7D_USDHC2_ROOT_PRE_DIV] = imx_clk_divider2("usdhc2_pre_div", "usdhc2_cg", base + 0xab80, 16, 3);
clks[IMX7D_USDHC3_ROOT_PRE_DIV] = imx_clk_divider2("usdhc3_pre_div", "usdhc3_cg", base + 0xac00, 16, 3);
clks[IMX7D_CAN1_ROOT_PRE_DIV] = imx_clk_divider2("can1_pre_div", "can1_cg", base + 0xac80, 16, 3);
clks[IMX7D_CAN2_ROOT_PRE_DIV] = imx_clk_divider2("can2_pre_div", "can2_cg", base + 0xad00, 16, 3);
clks[IMX7D_I2C1_ROOT_PRE_DIV] = imx_clk_divider2("i2c1_pre_div", "i2c1_cg", base + 0xad80, 16, 3);
clks[IMX7D_I2C2_ROOT_PRE_DIV] = imx_clk_divider2("i2c2_pre_div", "i2c2_cg", base + 0xae00, 16, 3);
clks[IMX7D_I2C3_ROOT_PRE_DIV] = imx_clk_divider2("i2c3_pre_div", "i2c3_cg", base + 0xae80, 16, 3);
clks[IMX7D_I2C4_ROOT_PRE_DIV] = imx_clk_divider2("i2c4_pre_div", "i2c4_cg", base + 0xaf00, 16, 3);
clks[IMX7D_UART1_ROOT_PRE_DIV] = imx_clk_divider2("uart1_pre_div", "uart1_cg", base + 0xaf80, 16, 3);
clks[IMX7D_UART2_ROOT_PRE_DIV] = imx_clk_divider2("uart2_pre_div", "uart2_cg", base + 0xb000, 16, 3);
clks[IMX7D_UART3_ROOT_PRE_DIV] = imx_clk_divider2("uart3_pre_div", "uart3_cg", base + 0xb080, 16, 3);
clks[IMX7D_UART4_ROOT_PRE_DIV] = imx_clk_divider2("uart4_pre_div", "uart4_cg", base + 0xb100, 16, 3);
clks[IMX7D_UART5_ROOT_PRE_DIV] = imx_clk_divider2("uart5_pre_div", "uart5_cg", base + 0xb180, 16, 3);
clks[IMX7D_UART6_ROOT_PRE_DIV] = imx_clk_divider2("uart6_pre_div", "uart6_cg", base + 0xb200, 16, 3);
clks[IMX7D_UART7_ROOT_PRE_DIV] = imx_clk_divider2("uart7_pre_div", "uart7_cg", base + 0xb280, 16, 3);
clks[IMX7D_ECSPI1_ROOT_PRE_DIV] = imx_clk_divider2("ecspi1_pre_div", "ecspi1_cg", base + 0xb300, 16, 3);
clks[IMX7D_ECSPI2_ROOT_PRE_DIV] = imx_clk_divider2("ecspi2_pre_div", "ecspi2_cg", base + 0xb380, 16, 3);
clks[IMX7D_ECSPI3_ROOT_PRE_DIV] = imx_clk_divider2("ecspi3_pre_div", "ecspi3_cg", base + 0xb400, 16, 3);
clks[IMX7D_ECSPI4_ROOT_PRE_DIV] = imx_clk_divider2("ecspi4_pre_div", "ecspi4_cg", base + 0xb480, 16, 3);
clks[IMX7D_PWM1_ROOT_PRE_DIV] = imx_clk_divider2("pwm1_pre_div", "pwm1_cg", base + 0xb500, 16, 3);
clks[IMX7D_PWM2_ROOT_PRE_DIV] = imx_clk_divider2("pwm2_pre_div", "pwm2_cg", base + 0xb580, 16, 3);
clks[IMX7D_PWM3_ROOT_PRE_DIV] = imx_clk_divider2("pwm3_pre_div", "pwm3_cg", base + 0xb600, 16, 3);
clks[IMX7D_PWM4_ROOT_PRE_DIV] = imx_clk_divider2("pwm4_pre_div", "pwm4_cg", base + 0xb680, 16, 3);
clks[IMX7D_FLEXTIMER1_ROOT_PRE_DIV] = imx_clk_divider2("flextimer1_pre_div", "flextimer1_cg", base + 0xb700, 16, 3);
clks[IMX7D_FLEXTIMER2_ROOT_PRE_DIV] = imx_clk_divider2("flextimer2_pre_div", "flextimer2_cg", base + 0xb780, 16, 3);
clks[IMX7D_SIM1_ROOT_PRE_DIV] = imx_clk_divider2("sim1_pre_div", "sim1_cg", base + 0xb800, 16, 3);
clks[IMX7D_SIM2_ROOT_PRE_DIV] = imx_clk_divider2("sim2_pre_div", "sim2_cg", base + 0xb880, 16, 3);
clks[IMX7D_GPT1_ROOT_PRE_DIV] = imx_clk_divider2("gpt1_pre_div", "gpt1_cg", base + 0xb900, 16, 3);
clks[IMX7D_GPT2_ROOT_PRE_DIV] = imx_clk_divider2("gpt2_pre_div", "gpt2_cg", base + 0xb980, 16, 3);
clks[IMX7D_GPT3_ROOT_PRE_DIV] = imx_clk_divider2("gpt3_pre_div", "gpt3_cg", base + 0xba00, 16, 3);
clks[IMX7D_GPT4_ROOT_PRE_DIV] = imx_clk_divider2("gpt4_pre_div", "gpt4_cg", base + 0xba80, 16, 3);
clks[IMX7D_TRACE_ROOT_PRE_DIV] = imx_clk_divider2("trace_pre_div", "trace_cg", base + 0xbb00, 16, 3);
clks[IMX7D_WDOG_ROOT_PRE_DIV] = imx_clk_divider2("wdog_pre_div", "wdog_cg", base + 0xbb80, 16, 3);
clks[IMX7D_CSI_MCLK_ROOT_PRE_DIV] = imx_clk_divider2("csi_mclk_pre_div", "csi_mclk_cg", base + 0xbc00, 16, 3);
clks[IMX7D_AUDIO_MCLK_ROOT_PRE_DIV] = imx_clk_divider2("audio_mclk_pre_div", "audio_mclk_cg", base + 0xbc80, 16, 3);
clks[IMX7D_WRCLK_ROOT_PRE_DIV] = imx_clk_divider2("wrclk_pre_div", "wrclk_cg", base + 0xbd00, 16, 3);
clks[IMX7D_CLKO1_ROOT_PRE_DIV] = imx_clk_divider2("clko1_pre_div", "clko1_cg", base + 0xbd80, 16, 3);
clks[IMX7D_CLKO2_ROOT_PRE_DIV] = imx_clk_divider2("clko2_pre_div", "clko2_cg", base + 0xbe00, 16, 3);
clks[IMX7D_ARM_A7_ROOT_DIV] = imx_clk_divider2("arm_a7_div", "arm_a7_cg", base + 0x8000, 0, 3);
clks[IMX7D_ARM_M4_ROOT_DIV] = imx_clk_divider2("arm_m4_div", "arm_m4_cg", base + 0x8080, 0, 3);
clks[IMX7D_ARM_M0_ROOT_DIV] = imx_clk_divider2("arm_m0_div", "arm_m0_cg", base + 0x8100, 0, 3);
clks[IMX7D_MAIN_AXI_ROOT_DIV] = imx_clk_divider2("axi_post_div", "axi_pre_div", base + 0x8800, 0, 6);
clks[IMX7D_DISP_AXI_ROOT_DIV] = imx_clk_divider2("disp_axi_post_div", "disp_axi_pre_div", base + 0x8880, 0, 6);
clks[IMX7D_ENET_AXI_ROOT_DIV] = imx_clk_divider2("enet_axi_post_div", "enet_axi_pre_div", base + 0x8900, 0, 6);
clks[IMX7D_NAND_USDHC_BUS_ROOT_DIV] = imx_clk_divider2("nand_usdhc_post_div", "nand_usdhc_pre_div", base + 0x8980, 0, 6);
clks[IMX7D_AHB_CHANNEL_ROOT_DIV] = imx_clk_divider2("ahb_post_div", "ahb_pre_div", base + 0x9000, 0, 6);
clks[IMX7D_DRAM_ROOT_DIV] = imx_clk_divider2("dram_post_div", "dram_cg", base + 0x9880, 0, 3);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_DIV] = imx_clk_divider2("dram_phym_alt_post_div", "dram_phym_alt_pre_div", base + 0xa000, 0, 3);
clks[IMX7D_DRAM_ALT_ROOT_DIV] = imx_clk_divider2("dram_alt_post_div", "dram_alt_pre_div", base + 0xa080, 0, 3);
clks[IMX7D_USB_HSIC_ROOT_DIV] = imx_clk_divider2("usb_hsic_post_div", "usb_hsic_pre_div", base + 0xa100, 0, 6);
clks[IMX7D_PCIE_CTRL_ROOT_DIV] = imx_clk_divider2("pcie_ctrl_post_div", "pcie_ctrl_pre_div", base + 0xa180, 0, 6);
clks[IMX7D_PCIE_PHY_ROOT_DIV] = imx_clk_divider2("pcie_phy_post_div", "pcie_phy_pre_div", base + 0xa200, 0, 6);
clks[IMX7D_EPDC_PIXEL_ROOT_DIV] = imx_clk_divider2("epdc_pixel_post_div", "epdc_pixel_pre_div", base + 0xa280, 0, 6);
clks[IMX7D_LCDIF_PIXEL_ROOT_DIV] = imx_clk_divider2("lcdif_pixel_post_div", "lcdif_pixel_pre_div", base + 0xa300, 0, 6);
clks[IMX7D_MIPI_DSI_ROOT_DIV] = imx_clk_divider2("mipi_dsi_post_div", "mipi_dsi_pre_div", base + 0xa380, 0, 6);
clks[IMX7D_MIPI_CSI_ROOT_DIV] = imx_clk_divider2("mipi_csi_post_div", "mipi_csi_pre_div", base + 0xa400, 0, 6);
clks[IMX7D_MIPI_DPHY_ROOT_DIV] = imx_clk_divider2("mipi_dphy_post_div", "mipi_csi_dphy_div", base + 0xa480, 0, 6);
clks[IMX7D_SAI1_ROOT_DIV] = imx_clk_divider2("sai1_post_div", "sai1_pre_div", base + 0xa500, 0, 6);
clks[IMX7D_SAI2_ROOT_DIV] = imx_clk_divider2("sai2_post_div", "sai2_pre_div", base + 0xa580, 0, 6);
clks[IMX7D_SAI3_ROOT_DIV] = imx_clk_divider2("sai3_post_div", "sai3_pre_div", base + 0xa600, 0, 6);
clks[IMX7D_SPDIF_ROOT_DIV] = imx_clk_divider2("spdif_post_div", "spdif_pre_div", base + 0xa680, 0, 6);
clks[IMX7D_ENET1_REF_ROOT_DIV] = imx_clk_divider2("enet1_ref_post_div", "enet1_ref_pre_div", base + 0xa700, 0, 6);
clks[IMX7D_ENET1_TIME_ROOT_DIV] = imx_clk_divider2("enet1_time_post_div", "enet1_time_pre_div", base + 0xa780, 0, 6);
clks[IMX7D_ENET2_REF_ROOT_DIV] = imx_clk_divider2("enet2_ref_post_div", "enet2_ref_pre_div", base + 0xa800, 0, 6);
clks[IMX7D_ENET2_TIME_ROOT_DIV] = imx_clk_divider2("enet2_time_post_div", "enet2_time_pre_div", base + 0xa880, 0, 6);
clks[IMX7D_ENET_PHY_REF_ROOT_DIV] = imx_clk_divider2("enet_phy_ref_post_div", "enet_phy_ref_pre_div", base + 0xa900, 0, 6);
clks[IMX7D_EIM_ROOT_DIV] = imx_clk_divider2("eim_post_div", "eim_pre_div", base + 0xa980, 0, 6);
clks[IMX7D_NAND_ROOT_DIV] = imx_clk_divider2("nand_post_div", "nand_pre_div", base + 0xaa00, 0, 6);
clks[IMX7D_QSPI_ROOT_DIV] = imx_clk_divider2("qspi_post_div", "qspi_pre_div", base + 0xaa80, 0, 6);
clks[IMX7D_USDHC1_ROOT_DIV] = imx_clk_divider2("usdhc1_post_div", "usdhc1_pre_div", base + 0xab00, 0, 6);
clks[IMX7D_USDHC2_ROOT_DIV] = imx_clk_divider2("usdhc2_post_div", "usdhc2_pre_div", base + 0xab80, 0, 6);
clks[IMX7D_USDHC3_ROOT_DIV] = imx_clk_divider2("usdhc3_post_div", "usdhc3_pre_div", base + 0xac00, 0, 6);
clks[IMX7D_CAN1_ROOT_DIV] = imx_clk_divider2("can1_post_div", "can1_pre_div", base + 0xac80, 0, 6);
clks[IMX7D_CAN2_ROOT_DIV] = imx_clk_divider2("can2_post_div", "can2_pre_div", base + 0xad00, 0, 6);
clks[IMX7D_I2C1_ROOT_DIV] = imx_clk_divider2("i2c1_post_div", "i2c1_pre_div", base + 0xad80, 0, 6);
clks[IMX7D_I2C2_ROOT_DIV] = imx_clk_divider2("i2c2_post_div", "i2c2_pre_div", base + 0xae00, 0, 6);
clks[IMX7D_I2C3_ROOT_DIV] = imx_clk_divider2("i2c3_post_div", "i2c3_pre_div", base + 0xae80, 0, 6);
clks[IMX7D_I2C4_ROOT_DIV] = imx_clk_divider2("i2c4_post_div", "i2c4_pre_div", base + 0xaf00, 0, 6);
clks[IMX7D_UART1_ROOT_DIV] = imx_clk_divider2("uart1_post_div", "uart1_pre_div", base + 0xaf80, 0, 6);
clks[IMX7D_UART2_ROOT_DIV] = imx_clk_divider2("uart2_post_div", "uart2_pre_div", base + 0xb000, 0, 6);
clks[IMX7D_UART3_ROOT_DIV] = imx_clk_divider2("uart3_post_div", "uart3_pre_div", base + 0xb080, 0, 6);
clks[IMX7D_UART4_ROOT_DIV] = imx_clk_divider2("uart4_post_div", "uart4_pre_div", base + 0xb100, 0, 6);
clks[IMX7D_UART5_ROOT_DIV] = imx_clk_divider2("uart5_post_div", "uart5_pre_div", base + 0xb180, 0, 6);
clks[IMX7D_UART6_ROOT_DIV] = imx_clk_divider2("uart6_post_div", "uart6_pre_div", base + 0xb200, 0, 6);
clks[IMX7D_UART7_ROOT_DIV] = imx_clk_divider2("uart7_post_div", "uart7_pre_div", base + 0xb280, 0, 6);
clks[IMX7D_ECSPI1_ROOT_DIV] = imx_clk_divider2("ecspi1_post_div", "ecspi1_pre_div", base + 0xb300, 0, 6);
clks[IMX7D_ECSPI2_ROOT_DIV] = imx_clk_divider2("ecspi2_post_div", "ecspi2_pre_div", base + 0xb380, 0, 6);
clks[IMX7D_ECSPI3_ROOT_DIV] = imx_clk_divider2("ecspi3_post_div", "ecspi3_pre_div", base + 0xb400, 0, 6);
clks[IMX7D_ECSPI4_ROOT_DIV] = imx_clk_divider2("ecspi4_post_div", "ecspi4_pre_div", base + 0xb480, 0, 6);
clks[IMX7D_PWM1_ROOT_DIV] = imx_clk_divider2("pwm1_post_div", "pwm1_pre_div", base + 0xb500, 0, 6);
clks[IMX7D_PWM2_ROOT_DIV] = imx_clk_divider2("pwm2_post_div", "pwm2_pre_div", base + 0xb580, 0, 6);
clks[IMX7D_PWM3_ROOT_DIV] = imx_clk_divider2("pwm3_post_div", "pwm3_pre_div", base + 0xb600, 0, 6);
clks[IMX7D_PWM4_ROOT_DIV] = imx_clk_divider2("pwm4_post_div", "pwm4_pre_div", base + 0xb680, 0, 6);
clks[IMX7D_FLEXTIMER1_ROOT_DIV] = imx_clk_divider2("flextimer1_post_div", "flextimer1_pre_div", base + 0xb700, 0, 6);
clks[IMX7D_FLEXTIMER2_ROOT_DIV] = imx_clk_divider2("flextimer2_post_div", "flextimer2_pre_div", base + 0xb780, 0, 6);
clks[IMX7D_SIM1_ROOT_DIV] = imx_clk_divider2("sim1_post_div", "sim1_pre_div", base + 0xb800, 0, 6);
clks[IMX7D_SIM2_ROOT_DIV] = imx_clk_divider2("sim2_post_div", "sim2_pre_div", base + 0xb880, 0, 6);
clks[IMX7D_GPT1_ROOT_DIV] = imx_clk_divider2("gpt1_post_div", "gpt1_pre_div", base + 0xb900, 0, 6);
clks[IMX7D_GPT2_ROOT_DIV] = imx_clk_divider2("gpt2_post_div", "gpt2_pre_div", base + 0xb980, 0, 6);
clks[IMX7D_GPT3_ROOT_DIV] = imx_clk_divider2("gpt3_post_div", "gpt3_pre_div", base + 0xba00, 0, 6);
clks[IMX7D_GPT4_ROOT_DIV] = imx_clk_divider2("gpt4_post_div", "gpt4_pre_div", base + 0xba80, 0, 6);
clks[IMX7D_TRACE_ROOT_DIV] = imx_clk_divider2("trace_post_div", "trace_pre_div", base + 0xbb00, 0, 6);
clks[IMX7D_WDOG_ROOT_DIV] = imx_clk_divider2("wdog_post_div", "wdog_pre_div", base + 0xbb80, 0, 6);
clks[IMX7D_CSI_MCLK_ROOT_DIV] = imx_clk_divider2("csi_mclk_post_div", "csi_mclk_pre_div", base + 0xbc00, 0, 6);
clks[IMX7D_AUDIO_MCLK_ROOT_DIV] = imx_clk_divider2("audio_mclk_post_div", "audio_mclk_pre_div", base + 0xbc80, 0, 6);
clks[IMX7D_WRCLK_ROOT_DIV] = imx_clk_divider2("wrclk_post_div", "wrclk_pre_div", base + 0xbd00, 0, 6);
clks[IMX7D_CLKO1_ROOT_DIV] = imx_clk_divider2("clko1_post_div", "clko1_pre_div", base + 0xbd80, 0, 6);
clks[IMX7D_CLKO2_ROOT_DIV] = imx_clk_divider2("clko2_post_div", "clko2_pre_div", base + 0xbe00, 0, 6);
clks[IMX7D_ARM_A7_ROOT_CLK] = imx_clk_gate4("arm_a7_root_clk", "arm_a7_div", base + 0x4000, 0);
clks[IMX7D_ARM_M4_ROOT_CLK] = imx_clk_gate4("arm_m4_root_clk", "arm_m4_div", base + 0x4010, 0);
clks[IMX7D_ARM_M0_ROOT_CLK] = imx_clk_gate4("arm_m0_root_clk", "arm_m0_div", base + 0x4020, 0);
clks[IMX7D_MAIN_AXI_ROOT_CLK] = imx_clk_gate4("main_axi_root_clk", "axi_post_div", base + 0x4040, 0);
clks[IMX7D_DISP_AXI_ROOT_CLK] = imx_clk_gate4("disp_axi_root_clk", "disp_axi_post_div", base + 0x4050, 0);
clks[IMX7D_ENET_AXI_ROOT_CLK] = imx_clk_gate4("enet_axi_root_clk", "enet_axi_post_div", base + 0x4060, 0);
clks[IMX7D_OCRAM_CLK] = imx_clk_gate4("ocram_clk", "axi_post_div", base + 0x4110, 0);
clks[IMX7D_OCRAM_S_CLK] = imx_clk_gate4("ocram_s_clk", "ahb_post_div", base + 0x4120, 0);
clks[IMX7D_NAND_USDHC_BUS_ROOT_CLK] = imx_clk_gate4("nand_usdhc_root_clk", "nand_usdhc_post_div", base + 0x4130, 0);
clks[IMX7D_AHB_CHANNEL_ROOT_CLK] = imx_clk_gate4("ahb_root_clk", "ahb_post_div", base + 0x4200, 0);
clks[IMX7D_DRAM_ROOT_CLK] = imx_clk_gate4("dram_root_clk", "dram_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ROOT_CLK] = imx_clk_gate4("dram_phym_root_clk", "dram_phym_cg", base + 0x4130, 0);
clks[IMX7D_DRAM_PHYM_ALT_ROOT_CLK] = imx_clk_gate4("dram_phym_alt_root_clk", "dram_phym_alt_post_div", base + 0x4130, 0);
clks[IMX7D_DRAM_ALT_ROOT_CLK] = imx_clk_gate4("dram_alt_root_clk", "dram_alt_post_div", base + 0x4130, 0);
clks[IMX7D_USB_HSIC_ROOT_CLK] = imx_clk_gate4("usb_hsic_root_clk", "usb_hsic_post_div", base + 0x4420, 0);
clks[IMX7D_SDMA_CORE_CLK] = imx_clk_gate4("sdma_root_clk", "ahb_root_clk", base + 0x4480, 0);
clks[IMX7D_PCIE_CTRL_ROOT_CLK] = imx_clk_gate4("pcie_ctrl_root_clk", "pcie_ctrl_post_div", base + 0x4600, 0);
clks[IMX7D_PCIE_PHY_ROOT_CLK] = imx_clk_gate4("pcie_phy_root_clk", "pcie_phy_post_div", base + 0x4600, 0);
clks[IMX7D_EPDC_PIXEL_ROOT_CLK] = imx_clk_gate4("epdc_pixel_root_clk", "epdc_pixel_post_div", base + 0x44a0, 0);
clks[IMX7D_LCDIF_PIXEL_ROOT_CLK] = imx_clk_gate4("lcdif_pixel_root_clk", "lcdif_pixel_post_div", base + 0x44b0, 0);
/*
* Linux code controls gates at 0x44e0, 0x44f0, 0x4500 and 0x4500. However, these do not seem to
* exist in hardware. According to the reference manual the ethernet clocks are controlled by
* gates at 0x4700 and 0x4710
*/
clks[IMX7D_ENET1_REF_ROOT_CLK] = imx_clk_gate4("enet1_ref_root_clk", "enet1_ref_post_div", base + 0x4700, 0);
clks[IMX7D_ENET1_TIME_ROOT_CLK] = imx_clk_gate_shared("enet1_time_root_clk", "enet1_time_post_div", "enet1_ref_root_clk");
clks[IMX7D_ENET2_REF_ROOT_CLK] = imx_clk_gate4("enet2_ref_root_clk", "enet2_ref_post_div", base + 0x4710, 0);
clks[IMX7D_ENET2_TIME_ROOT_CLK] = imx_clk_gate_shared("enet2_time_root_clk", "enet2_time_post_div", "enet2_ref_root_clk");
clks[IMX7D_ENET_PHY_REF_ROOT_CLK] = imx_clk_gate4("enet_phy_ref_root_clk", "enet_phy_ref_post_div", base + 0x4520, 0);
clks[IMX7D_EIM_ROOT_CLK] = imx_clk_gate4("eim_root_clk", "eim_post_div", base + 0x4160, 0);
clks[IMX7D_NAND_ROOT_CLK] = imx_clk_gate4("nand_root_clk", "nand_post_div", base + 0x4140, 0);
clks[IMX7D_QSPI_ROOT_CLK] = imx_clk_gate4("qspi_root_clk", "qspi_post_div", base + 0x4150, 0);
clks[IMX7D_USB_CTRL_CLK] = imx_clk_gate4("usb_ctrl_clk", "osc", base + 0x4680, 0);
clks[IMX7D_USB_PHY1_CLK] = imx_clk_gate4("usbphy1_clk", "osc", base + 0x46a0, 0);
clks[IMX7D_USB_PHY2_CLK] = imx_clk_gate4("usbphy2_clk", "osc", base + 0x46b0, 0);
clks[IMX7D_USDHC1_ROOT_CLK] = imx_clk_gate4("usdhc1_root_clk", "usdhc1_post_div", base + 0x46c0, 0);
clks[IMX7D_USDHC2_ROOT_CLK] = imx_clk_gate4("usdhc2_root_clk", "usdhc2_post_div", base + 0x46d0, 0);
clks[IMX7D_USDHC3_ROOT_CLK] = imx_clk_gate4("usdhc3_root_clk", "usdhc3_post_div", base + 0x46e0, 0);
clks[IMX7D_CAN1_ROOT_CLK] = imx_clk_gate4("can1_root_clk", "can1_post_div", base + 0x4740, 0);
clks[IMX7D_CAN2_ROOT_CLK] = imx_clk_gate4("can2_root_clk", "can2_post_div", base + 0x4750, 0);
clks[IMX7D_I2C1_ROOT_CLK] = imx_clk_gate4("i2c1_root_clk", "i2c1_post_div", base + 0x4880, 0);
clks[IMX7D_I2C2_ROOT_CLK] = imx_clk_gate4("i2c2_root_clk", "i2c2_post_div", base + 0x4890, 0);
clks[IMX7D_I2C3_ROOT_CLK] = imx_clk_gate4("i2c3_root_clk", "i2c3_post_div", base + 0x48a0, 0);
clks[IMX7D_I2C4_ROOT_CLK] = imx_clk_gate4("i2c4_root_clk", "i2c4_post_div", base + 0x48b0, 0);
clks[IMX7D_UART1_ROOT_CLK] = imx_clk_gate4("uart1_root_clk", "uart1_post_div", base + 0x4940, 0);
clks[IMX7D_UART2_ROOT_CLK] = imx_clk_gate4("uart2_root_clk", "uart2_post_div", base + 0x4950, 0);
clks[IMX7D_UART3_ROOT_CLK] = imx_clk_gate4("uart3_root_clk", "uart3_post_div", base + 0x4960, 0);
clks[IMX7D_UART4_ROOT_CLK] = imx_clk_gate4("uart4_root_clk", "uart4_post_div", base + 0x4970, 0);
clks[IMX7D_UART5_ROOT_CLK] = imx_clk_gate4("uart5_root_clk", "uart5_post_div", base + 0x4980, 0);
clks[IMX7D_UART6_ROOT_CLK] = imx_clk_gate4("uart6_root_clk", "uart6_post_div", base + 0x4990, 0);
clks[IMX7D_UART7_ROOT_CLK] = imx_clk_gate4("uart7_root_clk", "uart7_post_div", base + 0x49a0, 0);
clks[IMX7D_ECSPI1_ROOT_CLK] = imx_clk_gate4("ecspi1_root_clk", "ecspi1_post_div", base + 0x4780, 0);
clks[IMX7D_ECSPI2_ROOT_CLK] = imx_clk_gate4("ecspi2_root_clk", "ecspi2_post_div", base + 0x4790, 0);
clks[IMX7D_ECSPI3_ROOT_CLK] = imx_clk_gate4("ecspi3_root_clk", "ecspi3_post_div", base + 0x47a0, 0);
clks[IMX7D_ECSPI4_ROOT_CLK] = imx_clk_gate4("ecspi4_root_clk", "ecspi4_post_div", base + 0x47b0, 0);
clks[IMX7D_PWM1_ROOT_CLK] = imx_clk_gate4("pwm1_root_clk", "pwm1_post_div", base + 0x4840, 0);
clks[IMX7D_PWM2_ROOT_CLK] = imx_clk_gate4("pwm2_root_clk", "pwm2_post_div", base + 0x4850, 0);
clks[IMX7D_PWM3_ROOT_CLK] = imx_clk_gate4("pwm3_root_clk", "pwm3_post_div", base + 0x4860, 0);
clks[IMX7D_PWM4_ROOT_CLK] = imx_clk_gate4("pwm4_root_clk", "pwm4_post_div", base + 0x4870, 0);
clks[IMX7D_FLEXTIMER1_ROOT_CLK] = imx_clk_gate4("flextimer1_root_clk", "flextimer1_post_div", base + 0x4800, 0);
clks[IMX7D_FLEXTIMER2_ROOT_CLK] = imx_clk_gate4("flextimer2_root_clk", "flextimer2_post_div", base + 0x4810, 0);
clks[IMX7D_SIM1_ROOT_CLK] = imx_clk_gate4("sim1_root_clk", "sim1_post_div", base + 0x4900, 0);
clks[IMX7D_SIM2_ROOT_CLK] = imx_clk_gate4("sim2_root_clk", "sim2_post_div", base + 0x4910, 0);
clks[IMX7D_GPT1_ROOT_CLK] = imx_clk_gate4("gpt1_root_clk", "gpt1_post_div", base + 0x47c0, 0);
clks[IMX7D_GPT2_ROOT_CLK] = imx_clk_gate4("gpt2_root_clk", "gpt2_post_div", base + 0x47d0, 0);
clks[IMX7D_GPT3_ROOT_CLK] = imx_clk_gate4("gpt3_root_clk", "gpt3_post_div", base + 0x47e0, 0);
clks[IMX7D_GPT4_ROOT_CLK] = imx_clk_gate4("gpt4_root_clk", "gpt4_post_div", base + 0x47f0, 0);
clks[IMX7D_TRACE_ROOT_CLK] = imx_clk_gate4("trace_root_clk", "trace_post_div", base + 0x4300, 0);
clks[IMX7D_WDOG1_ROOT_CLK] = imx_clk_gate4("wdog1_root_clk", "wdog_post_div", base + 0x49c0, 0);
clks[IMX7D_WDOG2_ROOT_CLK] = imx_clk_gate4("wdog2_root_clk", "wdog_post_div", base + 0x49d0, 0);
clks[IMX7D_WDOG3_ROOT_CLK] = imx_clk_gate4("wdog3_root_clk", "wdog_post_div", base + 0x49e0, 0);
clks[IMX7D_WDOG4_ROOT_CLK] = imx_clk_gate4("wdog4_root_clk", "wdog_post_div", base + 0x49f0, 0);
clks[IMX7D_CSI_MCLK_ROOT_CLK] = imx_clk_gate4("csi_mclk_root_clk", "csi_mclk_post_div", base + 0x4490, 0);
clks[IMX7D_AUDIO_MCLK_ROOT_CLK] = imx_clk_gate4("audio_mclk_root_clk", "audio_mclk_post_div", base + 0x4790, 0);
clks[IMX7D_WRCLK_ROOT_CLK] = imx_clk_gate4("wrclk_root_clk", "wrclk_post_div", base + 0x47a0, 0);
clks[IMX7D_ADC_ROOT_CLK] = imx_clk_gate4("adc_root_clk", "ipg_root_clk", base + 0x4200, 0);
clks[IMX7D_GPT_3M_CLK] = imx_clk_fixed_factor("gpt_3m", "osc", 1, 8);
clks[IMX7D_CLK_ARM] = imx_clk_cpu("arm", "arm_a7_root_clk",
clks[IMX7D_ARM_A7_ROOT_CLK],
clks[IMX7D_ARM_A7_ROOT_SRC],
clks[IMX7D_PLL_ARM_MAIN_CLK],
clks[IMX7D_PLL_SYS_MAIN_CLK]);
clk_data.clks = clks;
clk_data.clk_num = ARRAY_SIZE(clks);
of_clk_add_provider(dev->device_node, of_clk_src_onecell_get, &clk_data);
imx7_clk_initialized = 1;
return 0;
}
static int imx7_clk_setup(void)
{
int i;
if (!imx7_clk_initialized)
return 0;
clks[IMX7D_OSC_24M_CLK] = clk_lookup("osc");
for (i = 0; i < ARRAY_SIZE(clks_init_on); i++)
clk_enable(clks[clks_init_on[i]]);
/* use old gpt clk setting, gpt1 root clk must be twice as gpt counter freq */
clk_set_parent(clks[IMX7D_GPT1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
/* set uart module clock's parent clock source that must be great then 80MHz */
clk_set_parent(clks[IMX7D_UART1_ROOT_SRC], clks[IMX7D_OSC_24M_CLK]);
clk_set_parent(clks[IMX7D_ENET1_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_125M_CLK]);
clk_set_parent(clks[IMX7D_ENET1_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
clk_set_parent(clks[IMX7D_ENET2_REF_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_125M_CLK]);
clk_set_parent(clks[IMX7D_ENET2_TIME_ROOT_SRC], clks[IMX7D_PLL_ENET_MAIN_100M_CLK]);
clk_set_rate(clks[IMX7D_PLL_SYS_PFD4_CLK], 392000000);
clk_set_parent(clks[IMX7D_ENET_AXI_ROOT_SRC], clks[IMX7D_PLL_SYS_PFD4_CLK]);
clk_set_rate(clks[IMX7D_ENET_AXI_ROOT_CLK], 197000000);
clk_set_rate(clks[IMX7D_ENET1_TIME_ROOT_CLK], 25000000);
clk_set_rate(clks[IMX7D_ENET2_TIME_ROOT_CLK], 25000000);
return 0;
}
postcore_initcall(imx7_clk_setup);
static __maybe_unused struct of_device_id imx7_ccm_dt_ids[] = {
{
.compatible = "fsl,imx7d-ccm",
}, {
/* sentinel */
}
};
static struct driver_d imx7_ccm_driver = {
.probe = imx7_ccm_probe,
.name = "imx6-ccm",
.of_compatible = DRV_OF_COMPAT(imx7_ccm_dt_ids),
};
static int imx7_ccm_init(void)
{
return platform_driver_register(&imx7_ccm_driver);
}
core_initcall(imx7_ccm_init);

View File

@ -26,10 +26,13 @@
#define PLL_NUM_OFFSET 0x10
#define PLL_DENOM_OFFSET 0x20
#define SYS_VF610_PLL_OFFSET 0x10
#define BM_PLL_POWER (0x1 << 12)
#define BM_PLL_ENABLE (0x1 << 13)
#define BM_PLL_BYPASS (0x1 << 16)
#define BM_PLL_LOCK (0x1 << 31)
#define IMX7_ENET_PLL_POWER (0x1 << 5)
struct clk_pllv3 {
struct clk clk;
@ -38,6 +41,10 @@ struct clk_pllv3 {
u32 div_mask;
u32 div_shift;
const char *parent;
void __iomem *lock_reg;
u32 lock_mask;
u32 ref_clock;
u32 power_bit;
};
#define to_clk_pllv3(_clk) container_of(_clk, struct clk_pllv3, clk)
@ -51,9 +58,9 @@ static int clk_pllv3_enable(struct clk *clk)
val = readl(pll->base);
val &= ~BM_PLL_BYPASS;
if (pll->powerup_set)
val |= BM_PLL_POWER;
val |= pll->power_bit;
else
val &= ~BM_PLL_POWER;
val &= ~pll->power_bit;
writel(val, pll->base);
/* Wait for PLL to lock */
@ -83,9 +90,9 @@ static void clk_pllv3_disable(struct clk *clk)
val |= BM_PLL_BYPASS;
if (pll->powerup_set)
val &= ~BM_PLL_POWER;
val &= ~pll->power_bit;
else
val |= BM_PLL_POWER;
val |= pll->power_bit;
writel(val, pll->base);
}
@ -265,7 +272,9 @@ static const struct clk_ops clk_pllv3_av_ops = {
static unsigned long clk_pllv3_enet_recalc_rate(struct clk *clk,
unsigned long parent_rate)
{
return 500000000;
struct clk_pllv3 *pll = to_clk_pllv3(clk);
return pll->ref_clock;
}
static const struct clk_ops clk_pllv3_enet_ops = {
@ -279,6 +288,88 @@ static const struct clk_ops clk_pllv3_mlb_ops = {
.disable = clk_pllv3_disable,
};
static unsigned long clk_pllv3_sys_vf610_recalc_rate(struct clk *clk,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(clk);
u32 mfn = readl(pll->base + SYS_VF610_PLL_OFFSET + PLL_NUM_OFFSET);
u32 mfd = readl(pll->base + SYS_VF610_PLL_OFFSET + PLL_DENOM_OFFSET);
u32 div = (readl(pll->base) & pll->div_mask) ? 22 : 20;
return (parent_rate * div) + ((parent_rate / mfd) * mfn);
}
static long clk_pllv3_sys_vf610_round_rate(struct clk *clk, unsigned long rate,
unsigned long *prate)
{
unsigned long parent_rate = *prate;
unsigned long min_rate = parent_rate * 20;
unsigned long max_rate = 528000000;
u32 mfn, mfd = 1000000;
u64 temp64;
if (rate >= max_rate)
return max_rate;
else if (rate < min_rate)
rate = min_rate;
temp64 = (u64) (rate - 20 * parent_rate);
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;
return parent_rate * 20 + parent_rate / mfd * mfn;
}
static int clk_pllv3_sys_vf610_set_rate(struct clk *clk, unsigned long rate,
unsigned long parent_rate)
{
struct clk_pllv3 *pll = to_clk_pllv3(clk);
unsigned long min_rate = parent_rate * 20;
unsigned long max_rate = 528000000;
u32 val;
u32 mfn, mfd = 1000000;
u64 temp64;
if (rate < min_rate || rate > max_rate)
return -EINVAL;
val = readl(pll->base);
if (rate == max_rate) {
writel(0, pll->base + SYS_VF610_PLL_OFFSET + PLL_NUM_OFFSET);
val |= pll->div_mask;
writel(val, pll->base);
return 0;
} else {
val &= ~pll->div_mask;
}
temp64 = (u64) (rate - 20 * parent_rate);
temp64 *= mfd;
do_div(temp64, parent_rate);
mfn = temp64;
writel(val, pll->base);
writel(mfn, pll->base + SYS_VF610_PLL_OFFSET + PLL_NUM_OFFSET);
writel(mfd, pll->base + SYS_VF610_PLL_OFFSET + PLL_DENOM_OFFSET);
while (!(readl(pll->lock_reg) & pll->lock_mask))
;
return 0;
}
static const struct clk_ops clk_pllv3_sys_vf610_ops = {
.enable = clk_pllv3_enable,
.disable = clk_pllv3_disable,
.recalc_rate = clk_pllv3_sys_vf610_recalc_rate,
.round_rate = clk_pllv3_sys_vf610_round_rate,
.set_rate = clk_pllv3_sys_vf610_set_rate,
};
struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent, void __iomem *base,
u32 div_mask)
@ -289,7 +380,12 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
pll = xzalloc(sizeof(*pll));
pll->power_bit = BM_PLL_POWER;
switch (type) {
case IMX_PLLV3_SYS_VF610:
ops = &clk_pllv3_sys_vf610_ops;
break;
case IMX_PLLV3_SYS:
ops = &clk_pllv3_sys_ops;
break;
@ -302,7 +398,13 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
case IMX_PLLV3_AV:
ops = &clk_pllv3_av_ops;
break;
case IMX_PLLV3_ENET_IMX7:
pll->power_bit = IMX7_ENET_PLL_POWER;
pll->ref_clock = 1000000000;
ops = &clk_pllv3_enet_ops;
break;
case IMX_PLLV3_ENET:
pll->ref_clock = 500000000;
ops = &clk_pllv3_enet_ops;
break;
case IMX_PLLV3_MLB:
@ -327,3 +429,22 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
return &pll->clk;
}
struct clk *imx_clk_pllv3_locked(enum imx_pllv3_type type, const char *name,
const char *parent, void __iomem *base,
u32 div_mask, void __iomem *lock_reg, u32 lock_mask)
{
struct clk *clk;
struct clk_pllv3 *pll;
clk = imx_clk_pllv3(type, name, parent, base, div_mask);
if (IS_ERR(clk))
return clk;
pll = to_clk_pllv3(clk);
pll->lock_reg = lock_reg;
pll->lock_mask = lock_mask;
return clk;
}

View File

@ -16,7 +16,10 @@
#include <of_address.h>
#include <linux/clkdev.h>
#include <linux/clk.h>
#include <notifier.h>
#include <dt-bindings/clock/vf610-clock.h>
#include <mach/vf610-regs.h>
#include <mach/vf610-fusemap.h>
#include "clk.h"
@ -76,6 +79,7 @@
#define PLL6_CTRL (anatop_base + 0xa0)
#define PLL7_CTRL (anatop_base + 0x20)
#define ANA_MISC1 (anatop_base + 0x160)
#define PLL_LOCK (anatop_base + 0x2c0)
static void __iomem *anatop_base;
static void __iomem *ccm_base;
@ -188,8 +192,9 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
clk[VF610_CLK_PLL6_BYPASS_SRC] = imx_clk_mux("pll6_bypass_src", PLL6_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clk[VF610_CLK_PLL7_BYPASS_SRC] = imx_clk_mux("pll7_bypass_src", PLL7_CTRL, 14, 1, pll_bypass_src_sels, ARRAY_SIZE(pll_bypass_src_sels));
clk[VF610_CLK_PLL1] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1);
clk[VF610_CLK_PLL2] = imx_clk_pllv3(IMX_PLLV3_GENERIC, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1);
clk[VF610_CLK_PLL1] = imx_clk_pllv3_locked(IMX_PLLV3_SYS_VF610, "pll1", "pll1_bypass_src", PLL1_CTRL, 0x1, PLL_LOCK, BIT(6));
clk[VF610_CLK_PLL2] = imx_clk_pllv3_locked(IMX_PLLV3_SYS_VF610, "pll2", "pll2_bypass_src", PLL2_CTRL, 0x1, PLL_LOCK, BIT(5));
clk[VF610_CLK_PLL3] = imx_clk_pllv3(IMX_PLLV3_USB_VF610, "pll3", "pll3_bypass_src", PLL3_CTRL, 0x2);
clk[VF610_CLK_PLL4] = imx_clk_pllv3(IMX_PLLV3_AV, "pll4", "pll4_bypass_src", PLL4_CTRL, 0x7f);
clk[VF610_CLK_PLL5] = imx_clk_pllv3(IMX_PLLV3_ENET, "pll5", "pll5_bypass_src", PLL5_CTRL, 0x3);
@ -444,3 +449,157 @@ static void __init vf610_clocks_init(struct device_node *ccm_node)
of_clk_add_provider(np, of_clk_src_onecell_get, &clk_data);
}
CLK_OF_DECLARE(vf610, "fsl,vf610-ccm", vf610_clocks_init);
enum {
VF610_SPEED_500 = 0b1110,
VF610_SPEED_400 = 0b1001,
VF610_SPEED_266 = 0b0001,
DDRMC_CR117 = 0x01d4,
DDRMC_CR117_AXI0_FITYPEREG_SYNC = 0b01 << 16,
};
static int vf610_switch_cpu_clock_to_500mhz(void)
{
int ret;
/*
* When switching A5 CPU to 500Mhz we expect DDRC to be
* clocked by PLL2_PFD2 and the system to be configured in
* asynchronous mode.
*
* We also can't just use default PFD1 output of PLL1 due to
* Errata e6235, so we have to re-clock the PLL itself and use
* its output to clock the CPU directly.
*/
if (clk_get_parent(clk[VF610_CLK_DDR_SEL]) != clk[VF610_CLK_PLL2_PFD2]) {
pr_warn("DDRC is clocked by PLL1, can't switch CPU clock");
return -EINVAL;
}
ret = clk_set_parent(clk[VF610_CLK_SYS_SEL], clk[VF610_CLK_PLL2_BUS]);
if (ret < 0) {
pr_crit("Unable to re-parent '%s'\n",
clk[VF610_CLK_SYS_SEL]->name);
return ret;
}
ret = clk_set_rate(clk[VF610_CLK_PLL1], 500000000);
if (ret < 0) {
pr_crit("Unable to set %s to 500Mhz %d\n",
clk[VF610_CLK_PLL1]->name, ret);
return ret;
}
ret = clk_set_parent(clk[VF610_CLK_PLL1_PFD_SEL], clk[VF610_CLK_PLL1_SYS]);
if (ret < 0) {
pr_crit("Unable to re-parent '%s'\n",
clk[VF610_CLK_PLL1_PFD_SEL]->name);
return ret;
}
ret = clk_set_parent(clk[VF610_CLK_SYS_SEL], clk[VF610_CLK_PLL1_PFD_SEL]);
if (ret < 0) {
pr_crit("Unable to re-parent '%s'\n",
clk[VF610_CLK_SYS_SEL]->name);
return ret;
}
/*
* imx_clk_divider has no error path in its set_rate hook
*/
clk_set_rate(clk[VF610_CLK_SYS_BUS], clk_get_rate(clk[VF610_CLK_SYS_SEL]));
clk_set_rate(clk[VF610_CLK_PLATFORM_BUS], clk_get_rate(clk[VF610_CLK_SYS_BUS]) / 3);
return ret;
}
static int vf610_switch_cpu_clock_to_400mhz(void)
{
int ret;
uint32_t cr117;
void * __iomem ddrmc = IOMEM(VF610_DDR_BASE_ADDR);
if (clk_get_parent(clk[VF610_CLK_DDR_SEL]) != clk[VF610_CLK_PLL2_PFD2]) {
pr_warn("DDRC is clocked by PLL1, can't switch CPU clock");
return -EINVAL;
}
ret = clk_set_parent(clk[VF610_CLK_PLL2_PFD_SEL], clk[VF610_CLK_PLL2_PFD2]);
if (ret < 0) {
pr_crit("Unable to re-parent '%s'\n",
clk[VF610_CLK_PLL2_PFD_SEL]->name);
return ret;
}
ret = clk_set_parent(clk[VF610_CLK_SYS_SEL], clk[VF610_CLK_PLL2_PFD_SEL]);
if (ret < 0) {
pr_crit("Unable to re-parent '%s'\n",
clk[VF610_CLK_SYS_SEL]->name);
return ret;
}
/*
* imx_clk_divider has no error path in its set_rate hook
*/
clk_set_rate(clk[VF610_CLK_SYS_BUS], clk_get_rate(clk[VF610_CLK_SYS_SEL]));
clk_set_rate(clk[VF610_CLK_PLATFORM_BUS], clk_get_rate(clk[VF610_CLK_SYS_BUS]) / 3);
/*
* Now that we are running off of the same clock as DDRMC we
* shouldn't need to use clock domain crossing FIFO and
* asynchronous mode and instead can swithch to sychronous
* mode for AXI0 accesses
*/
cr117 = readl(ddrmc + DDRMC_CR117);
cr117 |= DDRMC_CR117_AXI0_FITYPEREG_SYNC;
writel(cr117, ddrmc + DDRMC_CR117);
return 0;
}
static int vf610_switch_cpu_clock(void)
{
int ret;
bool sense_enable;
uint32_t speed_grading;
if (!of_machine_is_compatible("fsl,vf610"))
return 0;
sense_enable = imx_ocotp_sense_enable(true);
ret = imx_ocotp_read_field(VF610_OCOTP_SPEED_GRADING, &speed_grading);
imx_ocotp_sense_enable(sense_enable);
if (ret < 0)
return ret;
switch (speed_grading) {
default:
pr_err("Unknown CPU speed grading %x\n", speed_grading);
return -EINVAL;
case VF610_SPEED_266:
return 0;
case VF610_SPEED_500:
ret = vf610_switch_cpu_clock_to_500mhz();
break;
case VF610_SPEED_400:
ret = vf610_switch_cpu_clock_to_400mhz();
break;
}
clock_notifier_call_chain();
return ret;
}
/*
* We can probably gain a bit of a boot speed if we switch CPU clock
* earlier, but if we do this we'd need to figure out a way how to
* re-adjust the baud rate settings of the UART for DEBUG_LL
* functionality, or, accept the fact that it will be unavailable
* after this hook is executed. Both are far from ideal, so a bit
* slower boot it is.
*/
postconsole_initcall(vf610_switch_cpu_clock);

View File

@ -2,7 +2,7 @@
#define __IMX_CLK_H
struct clk *clk_gate2(const char *name, const char *parent, void __iomem *reg,
u8 shift, u8 cgr_val);
u8 shift, u8 cgr_val, unsigned long flags);
static inline struct clk *imx_clk_divider(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width)
@ -16,6 +16,12 @@ static inline struct clk *imx_clk_divider_np(const char *name, const char *paren
return clk_divider(name, parent, reg, shift, width, 0);
}
static inline struct clk *imx_clk_divider2(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 width)
{
return clk_divider(name, parent, reg, shift, width, CLK_OPS_PARENT_ENABLE);
}
static inline struct clk *imx_clk_divider_table(const char *name,
const char *parent, void __iomem *reg, u8 shift, u8 width,
const struct clk_div_table *table)
@ -44,6 +50,12 @@ static inline struct clk *imx_clk_mux(const char *name, void __iomem *reg,
return clk_mux(name, reg, shift, width, parents, num_parents, 0);
}
static inline struct clk *imx_clk_mux2(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, u8 num_parents)
{
return clk_mux(name, reg, shift, width, parents, num_parents, CLK_OPS_PARENT_ENABLE);
}
static inline struct clk *imx_clk_mux_p(const char *name, void __iomem *reg,
u8 shift, u8 width, const char **parents, u8 num_parents)
{
@ -56,18 +68,41 @@ static inline struct clk *imx_clk_gate(const char *name, const char *parent,
return clk_gate(name, parent, reg, shift, CLK_SET_RATE_PARENT, 0);
}
static inline struct clk *imx_clk_gate_dis(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_gate_inverted(name, parent, reg, shift, CLK_SET_RATE_PARENT);
}
static inline struct clk *imx_clk_gate2(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_gate2(name, parent, reg, shift, 0x3);
return clk_gate2(name, parent, reg, shift, 0x3, 0);
}
static inline struct clk *imx_clk_gate2_cgr(const char *name, const char *parent,
void __iomem *reg, u8 shift, u8 cgr_val)
{
return clk_gate2(name, parent, reg, shift, cgr_val);
return clk_gate2(name, parent, reg, shift, cgr_val, 0);
}
static inline struct clk *imx_clk_gate3(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_gate(name, parent, reg, shift, CLK_SET_RATE_PARENT | CLK_OPS_PARENT_ENABLE, 0);
}
static inline struct clk *imx_clk_gate4(const char *name, const char *parent,
void __iomem *reg, u8 shift)
{
return clk_gate2(name, parent, reg, shift, 0x3, CLK_OPS_PARENT_ENABLE);
}
static inline struct clk *imx_clk_gate_shared(const char *name, const char *parent,
const char *shared)
{
return clk_gate_shared(name, parent, shared, CLK_SET_RATE_PARENT);
}
struct clk *imx_clk_pllv1(const char *name, const char *parent,
void __iomem *base);
@ -78,10 +113,12 @@ struct clk *imx_clk_pllv2(const char *name, const char *parent,
enum imx_pllv3_type {
IMX_PLLV3_GENERIC,
IMX_PLLV3_SYS,
IMX_PLLV3_SYS_VF610,
IMX_PLLV3_USB,
IMX_PLLV3_USB_VF610,
IMX_PLLV3_AV,
IMX_PLLV3_ENET,
IMX_PLLV3_ENET_IMX7,
IMX_PLLV3_MLB,
};
@ -89,6 +126,10 @@ struct clk *imx_clk_pllv3(enum imx_pllv3_type type, const char *name,
const char *parent, void __iomem *base,
u32 div_mask);
struct clk *imx_clk_pllv3_locked(enum imx_pllv3_type type, const char *name,
const char *parent, void __iomem *base,
u32 div_mask, void __iomem *lock_reg, u32 lock_mask);
struct clk *imx_clk_pfd(const char *name, const char *parent,
void __iomem *reg, u8 idx);
@ -119,5 +160,8 @@ struct clk *imx_clk_gate_exclusive(const char *name, const char *parent,
void imx_check_clocks(struct clk *clks[], unsigned int count);
struct clk *imx_clk_cpu(const char *name, const char *parent_name,
struct clk *div, struct clk *mux, struct clk *pll,
struct clk *step);
#endif /* __IMX_CLK_H */

View File

@ -673,6 +673,7 @@ static int __init i2c_fsl_probe(struct device_d *pdev)
ret = PTR_ERR(i2c_fsl->clk);
goto fail;
}
clk_enable(i2c_fsl->clk);
#endif
i2c_fsl->hwdata = of_device_get_match_data(pdev);

View File

@ -218,13 +218,10 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
u32 wml_value;
if (IS_ENABLED(CONFIG_MCI_IMX_ESDHC_PIO)) {
if (!(data->flags & MMC_DATA_READ)) {
if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0)
goto err_locked;
if (!(data->flags & MMC_DATA_READ))
esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->src);
} else {
else
esdhc_write32(regs + SDHCI_DMA_ADDRESS, (u32)data->dest);
}
} else {
wml_value = data->blocksize/4;
@ -237,8 +234,6 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
} else {
if (wml_value > 0x80)
wml_value = 0x80;
if ((esdhc_read32(regs + SDHCI_PRESENT_STATE) & PRSSTAT_WPSPL) == 0)
goto err_locked;
esdhc_clrsetbits32(regs + IMX_SDHCI_WML, WML_WR_WML_MASK,
wml_value << 16);
@ -249,11 +244,6 @@ static int esdhc_setup_data(struct mci_host *mci, struct mci_data *data)
esdhc_write32(regs + SDHCI_BLOCK_SIZE__BLOCK_COUNT, data->blocks << 16 | data->blocksize);
return 0;
err_locked:
dev_err(host->dev, "Can not write to locked card.\n\n");
return -ETIMEDOUT;
}
static int esdhc_do_data(struct mci_host *mci, struct mci_data *data)
@ -630,6 +620,14 @@ static int fsl_esdhc_probe(struct device_d *dev)
host->clk = clk_get(dev, "per");
if (IS_ERR(host->clk))
return PTR_ERR(host->clk);
clk_enable(host->clk);
ret = clk_enable(host->clk);
if (ret) {
dev_err(dev, "Failed to enable clock: %s\n",
strerror(ret));
return ret;
}
host->dev = dev;
iores = dev_request_mem_resource(dev, 0);

View File

@ -436,6 +436,7 @@ static void mci_part_add(struct mci *mci, uint64_t size,
part->blk.num_blocks = mci_calc_blk_cnt(size, part->blk.blockbits);
part->area_type = area_type;
part->part_cfg = part_cfg;
part->idx = idx;
if (area_type == MMC_BLK_DATA_AREA_MAIN)
part->blk.cdev.device_node = mci->host->hw_dev->device_node;
@ -1573,6 +1574,59 @@ static const char *mci_boot_names[] = {
"user",
};
static int mci_register_partition(struct mci_part *part)
{
struct mci *mci = part->mci;
struct mci_host *host = mci->host;
const char *partnodename = NULL;
struct device_node *np;
int rc;
/*
* An MMC/SD card acts like an ordinary disk.
* So, re-use the disk driver to gain access to this media
*/
part->blk.dev = &mci->dev;
part->blk.ops = &mci_ops;
rc = blockdevice_register(&part->blk);
if (rc != 0) {
dev_err(&mci->dev, "Failed to register MCI/SD blockdevice\n");
return rc;
}
dev_info(&mci->dev, "registered %s\n", part->blk.cdev.name);
np = host->hw_dev->device_node;
/* create partitions on demand */
switch (part->area_type) {
case MMC_BLK_DATA_AREA_BOOT:
if (part->idx == 0)
partnodename = "boot0-partitions";
else
partnodename = "boot1-partitions";
np = of_get_child_by_name(host->hw_dev->device_node,
partnodename);
break;
case MMC_BLK_DATA_AREA_MAIN:
break;
default:
return 0;
}
rc = parse_partition_table(&part->blk);
if (rc != 0) {
dev_warn(&mci->dev, "No partition table found\n");
rc = 0; /* it's not a failure */
}
if (np)
of_parse_partitions(&part->blk.cdev, np);
return 0;
}
/**
* Probe an MCI card at the given host interface
* @param mci MCI device instance
@ -1647,29 +1701,7 @@ static int mci_card_probe(struct mci *mci)
for (i = 0; i < mci->nr_parts; i++) {
struct mci_part *part = &mci->part[i];
/*
* An MMC/SD card acts like an ordinary disk.
* So, re-use the disk driver to gain access to this media
*/
part->blk.dev = &mci->dev;
part->blk.ops = &mci_ops;
rc = blockdevice_register(&part->blk);
if (rc != 0) {
dev_err(&mci->dev, "Failed to register MCI/SD blockdevice\n");
goto on_error;
}
dev_info(&mci->dev, "registered %s\n", part->blk.cdev.name);
/* create partitions on demand */
if (part->area_type == MMC_BLK_DATA_AREA_MAIN) {
rc = parse_partition_table(&part->blk);
if (rc != 0) {
dev_warn(&mci->dev, "No partition table found\n");
rc = 0; /* it's not a failure */
}
of_parse_partitions(&part->blk.cdev, host->hw_dev->device_node);
}
rc = mci_register_partition(part);
if (IS_ENABLED(CONFIG_MCI_MMC_BOOT_PARTITIONS) &&
part->area_type == MMC_BLK_DATA_AREA_BOOT &&

View File

@ -74,16 +74,16 @@ struct cdev *of_parse_partition(struct cdev *cdev, struct device_node *node)
int of_parse_partitions(struct cdev *cdev, struct device_node *node)
{
struct device_node *n;
struct device_node *n, *subnode;
if (!node)
return -EINVAL;
for_each_child_of_node(node, n) {
if (of_device_is_compatible(n, "fixed-partitions")) {
node = n;
break;
}
subnode = of_get_child_by_name(node, "partitions");
if (subnode) {
if (!of_device_is_compatible(subnode, "fixed-partitions"))
return -EINVAL;
node = subnode;
}
for_each_child_of_node(node, n) {

View File

@ -27,6 +27,7 @@ struct nop_usbphy {
struct usb_phy usb_phy;
struct phy *phy;
struct phy_provider *provider;
struct clk *clk;
};
static struct phy *nop_usbphy_xlate(struct device_d *dev,
@ -37,6 +38,13 @@ static struct phy *nop_usbphy_xlate(struct device_d *dev,
return nopphy->phy;
}
static int nop_usbphy_init(struct phy *phy)
{
struct nop_usbphy *nopphy = phy_get_drvdata(phy);
return clk_enable(nopphy->clk);
}
static struct usb_phy *nop_usbphy_to_usbphy(struct phy *phy)
{
struct nop_usbphy *nopphy = phy_get_drvdata(phy);
@ -46,6 +54,7 @@ static struct usb_phy *nop_usbphy_to_usbphy(struct phy *phy)
static const struct phy_ops nop_phy_ops = {
.to_usbphy = nop_usbphy_to_usbphy,
.init = nop_usbphy_init,
};
static int nop_usbphy_probe(struct device_d *dev)
@ -57,7 +66,10 @@ static int nop_usbphy_probe(struct device_d *dev)
dev->priv = nopphy;
/* FIXME: Add clk support */
nopphy->clk = clk_get(dev, "main_clk");
if (IS_ERR(nopphy->clk))
nopphy->clk = NULL;
/* FIXME: Add vbus regulator support */
/* FIXME: Add vbus-detect-gpio support */
@ -97,8 +109,8 @@ static struct driver_d nop_usbphy_driver = {
.of_compatible = DRV_OF_COMPAT(nop_usbphy_dt_ids),
};
static int nop_usbphy_init(void)
static int nop_usbphy_driver_init(void)
{
return platform_driver_register(&nop_usbphy_driver);
}
fs_initcall(nop_usbphy_init);
fs_initcall(nop_usbphy_driver_init);

View File

@ -24,53 +24,29 @@
#include <pinctrl.h>
#include <malloc.h>
#include <mach/iomux-v3.h>
#include <mach/generic.h>
struct imx_iomux_v3 {
void __iomem *base;
struct pinctrl_device pinctrl;
unsigned int flags;
};
struct imx_iomux_v3_data {
unsigned int flags;
};
static void __iomem *iomuxv3_base;
static struct device_d *iomuxv3_dev;
static void imx_iomuxv3_setup_single(void __iomem *base, struct device_d *dev,
u32 mux_reg, u32 conf_reg, u32 input_reg,
u32 mux_val, u32 conf_val, u32 input_val)
{
dev_dbg(dev,
"mux: 0x%08x -> 0x%04x, conf: 0x%08x -> 0x%04x input: 0x%08x -> 0x%04x\n",
mux_val, mux_reg, conf_val, conf_reg, input_val, input_reg);
if (mux_reg)
writel(mux_val, base + mux_reg);
if (conf_reg)
writel(conf_val, base + conf_reg);
if (input_reg)
writel(input_val, base + input_reg);
}
/*
* configures a single pad in the iomuxer
*/
int mxc_iomux_v3_setup_pad(iomux_v3_cfg_t pad)
{
u32 mux_reg = (pad & MUX_CTRL_OFS_MASK) >> MUX_CTRL_OFS_SHIFT;
u32 mux_val = (pad & MUX_MODE_MASK) >> MUX_MODE_SHIFT;
u32 input_reg = (pad & MUX_SEL_INPUT_OFS_MASK) >> MUX_SEL_INPUT_OFS_SHIFT;
u32 input_val = (pad & MUX_SEL_INPUT_MASK) >> MUX_SEL_INPUT_SHIFT;
u32 conf_reg = (pad & MUX_PAD_CTRL_OFS_MASK) >> MUX_PAD_CTRL_OFS_SHIFT;
u32 conf_val = (pad & MUX_PAD_CTRL_MASK) >> MUX_PAD_CTRL_SHIFT;
if (!iomuxv3_base)
return -EINVAL;
if (conf_val & NO_PAD_CTRL)
conf_reg = 0;
imx_iomuxv3_setup_single(iomuxv3_base, iomuxv3_dev,
mux_reg, conf_reg, input_reg,
mux_val, conf_val, input_val);
imx_setup_pad(iomuxv3_base, pad);
return 0;
}
EXPORT_SYMBOL(mxc_iomux_v3_setup_pad);
@ -140,9 +116,9 @@ static int imx_iomux_v3_set_state(struct pinctrl_device *pdev, struct device_nod
if (conf_val & IMX_DT_NO_PAD_CTL)
conf_reg = 0;
imx_iomuxv3_setup_single(iomux->base, iomux->pinctrl.dev,
mux_reg, conf_reg, input_reg,
mux_val, conf_val, input_val);
iomux_v3_setup_pad(iomux->base, iomux->flags,
mux_reg, conf_reg, input_reg,
mux_val, conf_val, input_val);
}
return 0;
@ -155,14 +131,18 @@ static struct pinctrl_ops imx_iomux_v3_ops = {
static int imx_pinctrl_dt(struct device_d *dev, void __iomem *base)
{
struct imx_iomux_v3 *iomux;
struct imx_iomux_v3_data *drvdata = NULL;
int ret;
dev_get_drvdata(dev, (const void **)&drvdata);
iomux = xzalloc(sizeof(*iomux));
iomux->base = base;
iomux->pinctrl.dev = dev;
iomux->pinctrl.ops = &imx_iomux_v3_ops;
if (drvdata)
iomux->flags = drvdata->flags;
ret = pinctrl_register(&iomux->pinctrl);
if (ret)
@ -173,24 +153,33 @@ static int imx_pinctrl_dt(struct device_d *dev, void __iomem *base)
static int imx_iomux_v3_probe(struct device_d *dev)
{
void __iomem *base;
struct resource *iores;
int ret = 0;
if (iomuxv3_base)
return -EBUSY;
iores = dev_request_mem_resource(dev, 0);
if (IS_ERR(iores))
return PTR_ERR(iores);
iomuxv3_base = IOMEM(iores->start);
iomuxv3_dev = dev;
base = IOMEM(iores->start);
if (!iomuxv3_base)
/*
* Uh, this works only for the older controllers, not for
* i.MX7 which has two iomux controllers. i.MX7 based boards
* should not use mxc_iomux_v3_setup_pad anyway.
*/
iomuxv3_base = base;
if (IS_ENABLED(CONFIG_PINCTRL) && dev->device_node)
ret = imx_pinctrl_dt(dev, iomuxv3_base);
ret = imx_pinctrl_dt(dev, base);
return ret;
}
static struct imx_iomux_v3_data imx_iomux_imx7_lpsr_data = {
.flags = ZERO_OFFSET_VALID | IMX7_PINMUX_LPSR,
};
static __maybe_unused struct of_device_id imx_iomux_v3_dt_ids[] = {
{
.compatible = "fsl,imx25-iomuxc",
@ -202,12 +191,19 @@ static __maybe_unused struct of_device_id imx_iomux_v3_dt_ids[] = {
.compatible = "fsl,imx53-iomuxc",
}, {
.compatible = "fsl,imx6q-iomuxc",
}, {
}, {
.compatible = "fsl,imx6dl-iomuxc",
}, {
.compatible = "fsl,imx6sx-iomuxc",
}, {
.compatible = "fsl,imx6ul-iomuxc",
}, {
.compatible = "fsl,imx6sl-iomuxc",
}, {
.compatible = "fsl,imx7d-iomuxc",
}, {
.compatible = "fsl,imx7d-iomuxc-lpsr",
.data = &imx_iomux_imx7_lpsr_data,
}, {
/* sentinel */
}

View File

@ -24,9 +24,10 @@
#include <malloc.h>
#include <gpio.h>
#include <mach/iomux-vf610.h>
enum {
PINCTRL_VF610_MUX_LINE_SIZE = 20,
PINCTRL_VF610_MUX_SHIFT = 20,
PINCTRL_VF610_IBE = 1 << 0,
PINCTRL_VF610_OBE = 1 << 1,
@ -60,17 +61,17 @@ static int pinctrl_vf610_set_state(struct pinctrl_device *pdev,
npins = size / PINCTRL_VF610_MUX_LINE_SIZE;
for (i = 0; i < npins; i++) {
iomux_v3_cfg_t pad;
u32 mux_reg = be32_to_cpu(*list++);
u32 input_reg = be32_to_cpu(*list++);
u32 mux_val = be32_to_cpu(*list++);
u32 input_val = be32_to_cpu(*list++);
u32 conf_val = be32_to_cpu(*list++);
writel(mux_val << PINCTRL_VF610_MUX_SHIFT | conf_val,
iomux->base + mux_reg);
pad = IOMUX_PAD(mux_reg, mux_reg, mux_val,
input_reg, input_val, conf_val);
if (input_reg)
writel(input_val, iomux->base + input_reg);
vf610_setup_pad(iomux->base, pad);
}
return 0;

View File

@ -16,4 +16,8 @@ config REGULATOR_BCM283X
depends on ARCH_BCM283X
default y
config REGULATOR_PFUZE
bool "Freescale PFUZE100/200/3000 regulator driver"
depends on I2C
endif

View File

@ -1,3 +1,4 @@
obj-$(CONFIG_REGULATOR) += core.o
obj-$(CONFIG_REGULATOR_FIXED) += fixed.o
obj-$(CONFIG_REGULATOR_BCM283X) += bcm2835.o
obj-$(CONFIG_REGULATOR_PFUZE) += pfuze.o

Some files were not shown because too many files have changed in this diff Show More