diff --git a/LICENSES/preferred/BSD-1-Clause b/LICENSES/preferred/BSD-1-Clause new file mode 100644 index 0000000..a6d78dd --- /dev/null +++ b/LICENSES/preferred/BSD-1-Clause @@ -0,0 +1,26 @@ +Valid-License-Identifier: BSD-1-Clause +SPDX-URL: https://spdx.org/licenses/BSD-1-Clause.html +Usage-Guide: + To use the BSD 1-clause License put the following SPDX tag/value pair + into a comment according to the placement guidelines in the licensing + rules documentation: + SPDX-License-Identifier: BSD-1-Clause +License-Text: + +Copyright (c) All rights reserved. + +Redistribution and use in source and binary forms, with or without modification, +are permitted provided that the following conditions are met: + +1. Redistributions of source code must retain the above copyright notice, this +list of conditions and the following disclaimer. +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS. "AS IS" AND ANY EXPRESS OR +IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. +IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE FOR ANY DIRECT, INDIRECT, +INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, +OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF +LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index 349ad33..1445f61 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -34,7 +34,6 @@ select CLKDEV_LOOKUP select HAS_DEBUG_LL select HAVE_CLK - select PINCTRL_AT91 select COMMON_CLK_AT91 if COMMON_CLK_OF_PROVIDER diff --git a/arch/arm/boards/Makefile b/arch/arm/boards/Makefile index 8c0e5e5..e862db4 100644 --- a/arch/arm/boards/Makefile +++ b/arch/arm/boards/Makefile @@ -111,6 +111,7 @@ obj-$(CONFIG_MACH_SABRELITE) += freescale-mx6-sabrelite/ obj-$(CONFIG_MACH_SABRESD) += freescale-mx6-sabresd/ obj-$(CONFIG_MACH_FREESCALE_IMX6SX_SABRESDB) += freescale-mx6sx-sabresdb/ +obj-$(CONFIG_MACH_SAMA5D27_SOM1) += sama5d27-som1/ obj-$(CONFIG_MACH_SAMA5D3XEK) += sama5d3xek/ obj-$(CONFIG_MACH_SAMA5D3_XPLAINED) += sama5d3_xplained/ obj-$(CONFIG_MACH_MICROCHIP_KSZ9477_EVB) += microchip-ksz9477-evb/ diff --git a/arch/arm/boards/at91sam9263ek/lowlevel_init.c b/arch/arm/boards/at91sam9263ek/lowlevel_init.c index ba0ae39..0bf0e0f 100644 --- a/arch/arm/boards/at91sam9263ek/lowlevel_init.c +++ b/arch/arm/boards/at91sam9263ek/lowlevel_init.c @@ -115,7 +115,7 @@ fdt); } -extern char __dtb_at91sam9263ek_start[]; +extern char __dtb_z_at91sam9263ek_start[]; ENTRY_FUNCTION(start_at91sam9263ek, r0, r1, r2) { @@ -126,7 +126,7 @@ arm_setup_stack(AT91SAM9263_SRAM0_BASE + AT91SAM9263_SRAM0_SIZE); if (IS_ENABLED(CONFIG_MACH_AT91SAM9263EK_DT)) - fdt = __dtb_at91sam9263ek_start + get_runtime_offset(); + fdt = __dtb_z_at91sam9263ek_start + get_runtime_offset(); else fdt = NULL; diff --git a/arch/arm/boards/at91sam9x5ek/lowlevel.c b/arch/arm/boards/at91sam9x5ek/lowlevel.c index 9033597..c1433c8 100644 --- a/arch/arm/boards/at91sam9x5ek/lowlevel.c +++ b/arch/arm/boards/at91sam9x5ek/lowlevel.c @@ -7,7 +7,7 @@ #include #include -extern char __dtb_at91sam9x5ek_start[]; +extern char __dtb_z_at91sam9x5ek_start[]; ENTRY_FUNCTION(start_at91sam9x5ek, r0, r1, r2) { @@ -16,7 +16,7 @@ arm_cpu_lowlevel_init(); arm_setup_stack(AT91SAM9X5_SRAM_BASE + AT91SAM9X5_SRAM_SIZE); - fdt = __dtb_at91sam9x5ek_start + get_runtime_offset(); + fdt = __dtb_z_at91sam9x5ek_start + get_runtime_offset(); barebox_arm_entry(AT91_CHIPSELECT_1, at91sam9x5_get_ddram_size(), fdt); } diff --git a/arch/arm/boards/microchip-ksz9477-evb/lowlevel.c b/arch/arm/boards/microchip-ksz9477-evb/lowlevel.c index 0ce2b29..30a5760 100644 --- a/arch/arm/boards/microchip-ksz9477-evb/lowlevel.c +++ b/arch/arm/boards/microchip-ksz9477-evb/lowlevel.c @@ -1,7 +1,7 @@ +// SPDX-License-Identifier: GPL-2.0-only AND BSD-1-Clause /* + * Copyright (C) 2014, Atmel Corporation * Copyright (C) 2018 Ahmad Fatoum, Pengutronix - * - * Under GPLv2 */ #include @@ -9,10 +9,34 @@ #include #include +#include #include +#include +#include +#include -extern char __dtb_at91_microchip_ksz9477_evb_start[]; +/* PCK = 528MHz, MCK = 132MHz */ +#define MASTER_CLOCK 132000000 + +#define sama5d3_pmc_enable_periph_clock(clk) \ + at91_pmc_enable_periph_clock(IOMEM(SAMA5D3_BASE_PMC), clk) + +static void dbgu_init(void) +{ + void __iomem *pio = IOMEM(SAMA5D3_BASE_PIOB); + + sama5d3_pmc_enable_periph_clock(SAMA5D3_ID_PIOB); + + at91_mux_pio3_pin(pio, pin_to_mask(AT91_PIN_PB31), AT91_MUX_PERIPH_A, 0); + + sama5d3_pmc_enable_periph_clock(SAMA5D3_ID_DBGU); + at91_dbgu_setup_ll(IOMEM(AT91_BASE_DBGU1), MASTER_CLOCK, 115200); + + putc_ll('>'); +} + +extern char __dtb_z_at91_microchip_ksz9477_evb_start[]; ENTRY_FUNCTION(start_sama5d3_xplained_ung8071, r0, r1, r2) { @@ -22,7 +46,10 @@ arm_setup_stack(SAMA5D3_SRAM_BASE + SAMA5D3_SRAM_SIZE); - fdt = __dtb_at91_microchip_ksz9477_evb_start + get_runtime_offset(); + if (IS_ENABLED(CONFIG_DEBUG_LL)) + dbgu_init(); + + fdt = __dtb_z_at91_microchip_ksz9477_evb_start + get_runtime_offset(); barebox_arm_entry(SAMA5_DDRCS, SZ_256M, fdt); } diff --git a/arch/arm/boards/sama5d27-som1/Makefile b/arch/arm/boards/sama5d27-som1/Makefile new file mode 100644 index 0000000..b08c4a9 --- /dev/null +++ b/arch/arm/boards/sama5d27-som1/Makefile @@ -0,0 +1 @@ +lwl-y += lowlevel.o diff --git a/arch/arm/boards/sama5d27-som1/lowlevel.c b/arch/arm/boards/sama5d27-som1/lowlevel.c new file mode 100644 index 0000000..7df5a47 --- /dev/null +++ b/arch/arm/boards/sama5d27-som1/lowlevel.c @@ -0,0 +1,81 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2019 Ahmad Fatoum, Pengutronix + */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include + +#define RGB_LED_GREEN (1 << 0) +#define RGB_LED_RED (1 << 1) +#define RGB_LED_BLUE (1 << 2) + +/* PCK = 492MHz, MCK = 164MHz */ +#define MASTER_CLOCK 164000000 + +#define sama5d2_pmc_enable_periph_clock(clk) \ + at91_pmc_sam9x5_enable_periph_clock(IOMEM(SAMA5D2_BASE_PMC), clk) + +static void ek_turn_led(unsigned color) +{ + struct { + unsigned long pio; + unsigned bit; + unsigned color; + } *led, leds[] = { + { .pio = SAMA5D2_BASE_PIOA, .bit = 10, .color = color & RGB_LED_RED }, + { .pio = SAMA5D2_BASE_PIOB, .bit = 1, .color = color & RGB_LED_GREEN }, + { .pio = SAMA5D2_BASE_PIOA, .bit = 31, .color = color & RGB_LED_BLUE }, + { /* sentinel */ }, + }; + + for (led = leds; led->pio; led++) { + at91_mux_gpio4_enable(IOMEM(led->pio), BIT(led->bit)); + at91_mux_gpio4_input(IOMEM(led->pio), BIT(led->bit), false); + at91_mux_gpio4_set(IOMEM(led->pio), BIT(led->bit), led->color); + } +} + +static void ek_dbgu_init(void) +{ + unsigned mck = MASTER_CLOCK / 2; + + sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_PIOD); + + at91_mux_pio4_set_A_periph(IOMEM(SAMA5D2_BASE_PIOD), + pin_to_mask(AT91_PIN_PD3)); /* DBGU TXD */ + + sama5d2_pmc_enable_periph_clock(SAMA5D2_ID_UART1); + + at91_dbgu_setup_ll(IOMEM(SAMA5D2_BASE_UART1), mck, 115200); + + putc_ll('>'); +} + +extern char __dtb_z_at91_sama5d27_som1_ek_start[]; + +ENTRY_FUNCTION(start_sama5d27_som1_ek, r0, r1, r2) +{ + void *fdt; + + arm_cpu_lowlevel_init(); + + arm_setup_stack(SAMA5D2_SRAM_BASE + SAMA5D2_SRAM_SIZE - 16); + + if (IS_ENABLED(CONFIG_DEBUG_LL)) + ek_dbgu_init(); + + fdt = __dtb_z_at91_sama5d27_som1_ek_start + get_runtime_offset(); + + ek_turn_led(RGB_LED_GREEN); + barebox_arm_entry(SAMA5_DDRCS, SZ_128M, fdt); +} diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 8cb8467..bffcfad 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -134,6 +134,7 @@ vf610-zii-ssmb-dtu.dtb.o lwl-dtb-$(CONFIG_MACH_AT91SAM9263EK_DT) += at91sam9263ek.dtb.o lwl-dtb-$(CONFIG_MACH_MICROCHIP_KSZ9477_EVB) += at91-microchip-ksz9477-evb.dtb.o +lwl-dtb-$(CONFIG_MACH_SAMA5D27_SOM1) += at91-sama5d27_som1_ek.dtb.o lwl-dtb-$(CONFIG_MACH_AT91SAM9X5EK) += at91sam9x5ek.dtb.o lwl-dtb-$(CONFIG_MACH_XILINX_ZCU104) += zynqmp-zcu104-revA.dtb.o diff --git a/arch/arm/dts/at91-sama5d27_som1_ek.dts b/arch/arm/dts/at91-sama5d27_som1_ek.dts new file mode 100644 index 0000000..936f07e --- /dev/null +++ b/arch/arm/dts/at91-sama5d27_som1_ek.dts @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: GPL-2.0 OR X11 +/* + * Copyright (C) 2019 Oleksij Rempel - Pengutronix + */ + +#include + +/ { + chosen { + environment { + compatible = "barebox,environment"; + device-path = &barebox_env; + }; + }; + + memory { + reg = <0x20000000 0x8000000>; + }; +}; + +&qspi1 { + flash@0 { + #address-cells = <1>; + #size-cells = <1>; + + partition@0 { + label = "barebox"; + reg = <0x0 0x80000>; + }; + + barebox_env: partition@80000 { + label = "barebox-environment"; + reg = <0x80000 0x80000>; + }; + }; +}; diff --git a/arch/arm/dts/at91sam9x5ek.dts b/arch/arm/dts/at91sam9x5ek.dts index d5c7a8f..bc2a279 100644 --- a/arch/arm/dts/at91sam9x5ek.dts +++ b/arch/arm/dts/at91sam9x5ek.dts @@ -19,18 +19,6 @@ status = "okay"; }; - ahb { - apb { - pinctrl@fffff400 { - spi { - pinctrl_board_spi: spi-board { - atmel,pins = ; - }; - }; - }; - }; - }; - leds { /* * PB18 has a resource conflict since it is both used @@ -68,3 +56,10 @@ phy-mode = "rmii"; }; +&{/ahb/apb/pinctrl@fffff400} { + spi0 { + pinctrl_board_spi: spi-board { + atmel,pins = ; + }; + }; +}; diff --git a/arch/arm/dts/sama5d2.dtsi b/arch/arm/dts/sama5d2.dtsi new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/arch/arm/dts/sama5d2.dtsi diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig index 8e1bf06..ef00e32 100644 --- a/arch/arm/mach-at91/Kconfig +++ b/arch/arm/mach-at91/Kconfig @@ -6,6 +6,9 @@ config HAVE_AT91_USB_CLK bool +config HAVE_AT91_PIO4 + bool + config COMMON_CLK_AT91 bool select COMMON_CLK @@ -47,6 +50,7 @@ select HAVE_AT91_SMD select HAVE_AT91_USB_CLK select HAVE_AT91_UTMI + select PINCTRL_AT91 config SOC_SAMA5 bool @@ -57,6 +61,13 @@ select SOC_SAMA5 select AT91SAM9_SMC select CLOCKSOURCE_ATMEL_PIT + select HAVE_AT91_H32MX + select HAVE_AT91_UTMI + select HAVE_AT91_USB_CLK + select HAVE_AT91_GENERATED_CLK + select PINCTRL_AT91PIO4 + select HAS_MACB + select HAVE_MACH_ARM_HEAD config SOC_SAMA5D3 bool @@ -66,6 +77,9 @@ select HAVE_AT91_SMD select HAVE_AT91_USB_CLK select HAVE_AT91_UTMI + select PINCTRL_AT91 + select HAS_MACB + select HAVE_MACH_ARM_HEAD config SOC_SAMA5D4 bool @@ -76,12 +90,15 @@ select HAVE_AT91_SMD select HAVE_AT91_USB_CLK select HAVE_AT91_UTMI + select PINCTRL_AT91 + select HAS_MACB + select HAVE_MACH_ARM_HEAD config ARCH_TEXT_BASE hex - default 0x73f00000 if ARCH_AT91SAM9G45 - default 0x26f00000 if ARCH_AT91SAM9X5 - default 0x20f00000 if ARCH_AT91RM9200 + default 0x73f00000 if SOC_AT91SAM9G45 + default 0x26f00000 if SOC_AT91SAM9X5 + default 0x20f00000 if SOC_AT91RM9200 default 0x21f00000 if MACH_ANIMEO_IP default 0x23f00000 @@ -102,11 +119,14 @@ select HAS_AT91_ETHER select HAVE_AT91_DBGU0 select HAVE_AT91_USB_CLK + select PINCTRL_AT91 config SOC_AT91SAM9260 bool select SOC_AT91SAM9 select HAS_MACB + select PINCTRL_AT91 + select HAVE_MACH_ARM_HEAD help Select this if you are using one of Atmel's AT91SAM9260, AT91SAM9XE or AT91SAM9G20 SoC. @@ -114,6 +134,9 @@ config SOC_AT91SAM9261 bool select SOC_AT91SAM9 + select PINCTRL_AT91 + select HAVE_AT91_LOAD_BAREBOX_SRAM + select HAVE_MACH_ARM_HEAD help Select this if you are using one of Atmel's AT91SAM9261 or AT91SAM9G10 SoC. @@ -122,11 +145,15 @@ select SOC_AT91SAM9 select HAS_MACB select HAVE_AT91_LOAD_BAREBOX_SRAM + select HAVE_MACH_ARM_HEAD + select PINCTRL_AT91 config SOC_AT91SAM9G45 bool select SOC_AT91SAM9 select HAS_MACB + select PINCTRL_AT91 + select HAVE_MACH_ARM_HEAD help Select this if you are using one of Atmel's AT91SAM9G45 family SoC. This support covers AT91SAM9G45, AT91SAM9G46, AT91SAM9M10 and AT91SAM9M11. @@ -136,6 +163,8 @@ select SOC_AT91SAM9 select HAS_MACB select COMMON_CLK_OF_PROVIDER + select PINCTRL_AT91 + select OFDEVICE help Select this if you are using one of Atmel's AT91SAM9x5 family SoC. This means that your SAM9 name finishes with a '5' (except if it is @@ -146,11 +175,25 @@ config SOC_AT91SAM9N12 bool select SOC_AT91SAM9 + select PINCTRL_AT91 + select HAVE_MACH_ARM_HEAD help Select this if you are using Atmel's AT91SAM9N12 SoC. +config SUPPORT_CALAO_DAB_MMX + bool + +config SUPPORT_CALAO_MOB_TNY_MD2 + bool + +if !AT91_MULTI_BOARDS + +# ---------------------------------------------------------- + choice prompt "Atmel AT91 Processor" + help + Select here which SoC to support in non-multi-image configurations config ARCH_AT91RM9200 bool "AT91RM9200" @@ -163,49 +206,38 @@ config ARCH_AT91SAM9261 bool "AT91SAM9261" select SOC_AT91SAM9261 - select HAVE_AT91_LOAD_BAREBOX_SRAM config ARCH_AT91SAM9263 bool "AT91SAM9263" select SOC_AT91SAM9263 - select HAVE_MACH_ARM_HEAD config ARCH_AT91SAM9G10 bool "AT91SAM9G10" select SOC_AT91SAM9261 - select HAVE_MACH_ARM_HEAD config ARCH_AT91SAM9G20 bool "AT91SAM9G20" select SOC_AT91SAM9260 - select HAVE_MACH_ARM_HEAD config ARCH_AT91SAM9G45 bool "AT91SAM9G45 or AT91SAM9M10" select SOC_AT91SAM9G45 - select HAVE_MACH_ARM_HEAD config ARCH_AT91SAM9X5 bool "AT91SAM9X5" select SOC_AT91SAM9X5 - select OFDEVICE config ARCH_AT91SAM9N12 bool "AT91SAM9N12" select SOC_AT91SAM9N12 - select HAVE_MACH_ARM_HEAD config ARCH_SAMA5D3 bool "SAMA5D3x" select SOC_SAMA5D3 - select HAS_MACB - select HAVE_MACH_ARM_HEAD config ARCH_SAMA5D4 bool "SAMA5D4" select SOC_SAMA5D4 - select HAS_MACB - select HAVE_MACH_ARM_HEAD endchoice @@ -213,25 +245,15 @@ hex default 0x1000 if ARCH_AT91SAM9260 default 0x27000 if ARCH_AT91SAM9261 - default 0x12000 if ARCH_AT91SAM9263 default 0x4000 if ARCH_AT91SAM9G20 default 0x3000 if ARCH_AT91SAM9G10 default 0xF000 if ARCH_AT91SAM9G45 - default 0x6000 if ARCH_AT91SAM9X5 default 0x6000 if ARCH_AT91SAM9N12 - default 0x6000 if ARCH_SAMA5D3 + default 0x12000 if SOC_AT91SAM9263 + default 0x6000 if SOC_AT91SAM9X5 + default 0x6000 if SOC_SAMA5D3 default 0xffffffff -config SUPPORT_CALAO_DAB_MMX - bool - -config SUPPORT_CALAO_MOB_TNY_MD2 - bool - -if !AT91_MULTI_BOARDS - -# ---------------------------------------------------------- - if ARCH_AT91RM9200 choice @@ -521,12 +543,13 @@ config AT91_MULTI_BOARDS bool "Allow multiple boards to be selected" select HAVE_PBL_MULTI_IMAGES + select ARM_USE_COMPRESSED_DTB if AT91_MULTI_BOARDS config MACH_AT91SAM9263EK bool "Atmel AT91SAM9263-EK" - depends on ARCH_AT91SAM9263 + select SOC_AT91SAM9263 select OFDEVICE select COMMON_CLK_OF_PROVIDER select HAVE_NAND_ATMEL_BUSWIDTH_16 @@ -537,19 +560,27 @@ config MACH_AT91SAM9X5EK bool "Atmel AT91SAM9x5 Series Evaluation Kit" - depends on ARCH_AT91SAM9X5 + select SOC_AT91SAM9X5 help Select this if you re using Atmel's AT91SAM9x5-EK Evaluation Kit. Supported chips are sam9g15, sam9g25, sam9x25, sam9g35 and sam9x35. config MACH_MICROCHIP_KSZ9477_EVB bool "Microchip EVB-KSZ9477 Evaluation Kit" - depends on ARCH_SAMA5D3 + select SOC_SAMA5D3 select OFDEVICE select COMMON_CLK_OF_PROVIDER help Select this if you are using Microchip's EVB-KSZ9477 Evaluation Kit. +config MACH_SAMA5D27_SOM1 + bool "Microchip SAMA5D27 SoM-1 Evaluation Kit" + select SOC_SAMA5D2 + select OFDEVICE + select COMMON_CLK_OF_PROVIDER + help + Select this if you are using Microchip's sama5d27 SoM evaluation kit + endif comment "AT91 Board Options" diff --git a/arch/arm/mach-at91/Makefile b/arch/arm/mach-at91/Makefile index d81683a..66d0b70 100644 --- a/arch/arm/mach-at91/Makefile +++ b/arch/arm/mach-at91/Makefile @@ -1,4 +1,5 @@ obj-y += setup.o +lwl-y += at91_pmc_ll.o ifeq ($(CONFIG_COMMON_CLK_OF_PROVIDER),) obj-y += clock.o @@ -14,16 +15,16 @@ obj-$(CONFIG_AT91SAM9_SMC) += sam9_smc.o # CPU-specific support -obj-$(CONFIG_ARCH_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o -obj-$(CONFIG_ARCH_AT91SAM9260) += at91sam9260.o at91sam9260_devices.o -obj-$(CONFIG_ARCH_AT91SAM9261) += at91sam9261.o at91sam9261_devices.o -obj-$(CONFIG_ARCH_AT91SAM9G10) += at91sam9261.o at91sam9261_devices.o +obj-$(CONFIG_SOC_AT91RM9200) += at91rm9200.o at91rm9200_time.o at91rm9200_devices.o +obj-$(CONFIG_SOC_AT91SAM9260) += at91sam9260.o at91sam9260_devices.o +obj-$(CONFIG_SOC_AT91SAM9261) += at91sam9261.o at91sam9261_devices.o +obj-$(CONFIG_SOC_AT91SAM9G10) += at91sam9261.o at91sam9261_devices.o ifeq ($(CONFIG_OFDEVICE),) -obj-$(CONFIG_ARCH_AT91SAM9263) += at91sam9263.o at91sam9263_devices.o -obj-$(CONFIG_ARCH_SAMA5D3) += sama5d3.o sama5d3_devices.o +obj-$(CONFIG_SOC_AT91SAM9263) += at91sam9263.o at91sam9263_devices.o +obj-$(CONFIG_SOC_SAMA5D3) += sama5d3.o sama5d3_devices.o endif -obj-$(CONFIG_ARCH_AT91SAM9G20) += at91sam9260.o at91sam9260_devices.o -obj-$(CONFIG_ARCH_AT91SAM9G45) += at91sam9g45.o at91sam9g45_devices.o -obj-$(CONFIG_ARCH_AT91SAM9X5) += at91sam9x5.o at91sam9x5_devices.o -obj-$(CONFIG_ARCH_AT91SAM9N12) += at91sam9n12.o at91sam9n12_devices.o -obj-$(CONFIG_ARCH_SAMA5D4) += sama5d4.o sama5d4_devices.o +obj-$(CONFIG_SOC_AT91SAM9G20) += at91sam9260.o at91sam9260_devices.o +obj-$(CONFIG_SOC_AT91SAM9G45) += at91sam9g45.o at91sam9g45_devices.o +obj-$(CONFIG_SOC_AT91SAM9X5) += at91sam9x5.o at91sam9x5_devices.o +obj-$(CONFIG_SOC_AT91SAM9N12) += at91sam9n12.o at91sam9n12_devices.o +obj-$(CONFIG_SOC_SAMA5D4) += sama5d4.o sama5d4_devices.o diff --git a/arch/arm/mach-at91/at91_pmc_ll.c b/arch/arm/mach-at91/at91_pmc_ll.c new file mode 100644 index 0000000..4d39f57 --- /dev/null +++ b/arch/arm/mach-at91/at91_pmc_ll.c @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: BSD-1-Clause +/* + * Copyright (c) 2006, Atmel Corporation + * + * Atmel's name may not be used to endorse or promote products + * derived from this software without specific prior written permission. + */ + +#include +#include + +#define at91_pmc_write(off, val) writel(val, pmc_base + off) +#define at91_pmc_read(off) readl(pmc_base + off) + +void at91_pmc_init(void __iomem *pmc_base, unsigned int flags) +{ + u32 tmp; + + /* + * Switch the master clock to the slow clock without modifying other + * parameters. It is assumed that ROM code set H32MXDIV, PLLADIV2, + * PCK_DIV3. + */ + tmp = at91_pmc_read(AT91_PMC_MCKR); + tmp &= ~AT91_PMC_ALT_PCKR_CSS; + tmp |= AT91_PMC_CSS_SLOW; + at91_pmc_write(AT91_PMC_MCKR, tmp); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MCKRDY)) + ; + + if (flags & AT91_PMC_LL_FLAG_SAM9X5_PMC) { + /* + * Enable the Main Crystal Oscillator + * tST_max = 2ms + * Startup Time: 32768 * 2ms / 8 = 8 + */ + tmp = at91_pmc_read(AT91_CKGR_MOR); + tmp &= ~AT91_PMC_OSCOUNT; + tmp &= ~AT91_PMC_KEY_MASK; + tmp |= AT91_PMC_MOSCEN; + tmp |= AT91_PMC_OSCOUNT_(8); + tmp |= AT91_PMC_KEY; + at91_pmc_write(AT91_CKGR_MOR, tmp); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MOSCS)) + ; + + if (flags & AT91_PMC_LL_FLAG_MEASURE_XTAL) { + /* Enable a measurement of the Main Crystal Oscillator */ + tmp = at91_pmc_read(AT91_CKGR_MCFR); + tmp |= AT91_PMC_CCSS_XTAL_OSC; + tmp |= AT91_PMC_RCMEAS; + at91_pmc_write(AT91_CKGR_MCFR, tmp); + + while (!(at91_pmc_read(AT91_CKGR_MCFR) & AT91_PMC_MAINRDY)) + ; + } + + /* Switch from internal 12MHz RC to the Main Crystal Oscillator */ + tmp = at91_pmc_read(AT91_CKGR_MOR); + tmp &= ~AT91_PMC_OSCBYPASS; + tmp &= ~AT91_PMC_KEY_MASK; + tmp |= AT91_PMC_KEY; + at91_pmc_write(AT91_CKGR_MOR, tmp); + + tmp = at91_pmc_read(AT91_CKGR_MOR); + tmp |= AT91_PMC_MOSCSEL; + tmp &= ~AT91_PMC_KEY_MASK; + tmp |= AT91_PMC_KEY; + at91_pmc_write(AT91_CKGR_MOR, tmp); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MOSCSELS)) + ; + + if (flags & AT91_PMC_LL_FLAG_DISABLE_RC) { + /* Disable the 12MHz RC Oscillator */ + tmp = at91_pmc_read(AT91_CKGR_MOR); + tmp &= ~AT91_PMC_MOSCRCEN; + tmp &= ~AT91_PMC_KEY_MASK; + tmp |= AT91_PMC_KEY; + at91_pmc_write(AT91_CKGR_MOR, tmp); + } + + } else { + /* + * Enable the Main Crystal Oscillator + * tST_max = 2ms + * Startup Time: 32768 * 2ms / 8 = 8 + */ + tmp = at91_pmc_read(AT91_CKGR_MOR); + tmp &= ~AT91_PMC_OSCOUNT; + tmp |= AT91_PMC_MOSCEN; + tmp |= AT91_PMC_OSCOUNT_(8); + at91_pmc_write(AT91_CKGR_MOR, tmp); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MOSCS)) + ; + } + + /* After stablization, switch to Main Clock */ + if ((at91_pmc_read(AT91_PMC_MCKR) & AT91_PMC_ALT_PCKR_CSS) == AT91_PMC_CSS_SLOW) { + tmp = at91_pmc_read(AT91_PMC_MCKR); + tmp &= ~(0x1 << 13); + tmp &= ~AT91_PMC_ALT_PCKR_CSS; + tmp |= AT91_PMC_CSS_MAIN; + at91_pmc_write(AT91_PMC_MCKR, tmp); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MCKRDY)) + ; + + tmp &= ~AT91_PMC_PRES; + tmp |= AT91_PMC_PRES_1; + at91_pmc_write(AT91_PMC_MCKR, tmp); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MCKRDY)) + ; + } +} + +void at91_pmc_cfg_plla(void __iomem *pmc_base, u32 pmc_pllar, + unsigned int __always_unused flags) +{ + /* Always disable PLL before configuring it */ + at91_pmc_write(AT91_CKGR_PLLAR, AT91_PMC_PLLA_WR_ERRATA); + at91_pmc_write(AT91_CKGR_PLLAR, AT91_PMC_PLLA_WR_ERRATA | pmc_pllar); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_LOCKA)) + ; +} + +void at91_pmc_cfg_mck(void __iomem *pmc_base, u32 pmc_mckr, unsigned int flags) +{ + u32 tmp; + + /* + * Program the PRES field in the AT91_PMC_MCKR register + */ + tmp = at91_pmc_read(AT91_PMC_MCKR); + tmp &= ~(0x1 << 13); + + if (flags & AT91_PMC_LL_FLAG_SAM9X5_PMC) { + tmp &= ~AT91_PMC_ALT_PRES; + tmp |= pmc_mckr & AT91_PMC_ALT_PRES; + } else { + tmp &= ~AT91_PMC_PRES; + tmp |= pmc_mckr & AT91_PMC_PRES; + } + at91_pmc_write(AT91_PMC_MCKR, tmp); + + /* + * Program the MDIV field in the AT91_PMC_MCKR register + */ + tmp = at91_pmc_read(AT91_PMC_MCKR); + tmp &= ~AT91_PMC_MDIV; + tmp |= pmc_mckr & AT91_PMC_MDIV; + at91_pmc_write(AT91_PMC_MCKR, tmp); + + /* + * Program the PLLADIV2 field in the AT91_PMC_MCKR register + */ + tmp = at91_pmc_read(AT91_PMC_MCKR); + tmp &= ~AT91_PMC_PLLADIV2; + tmp |= pmc_mckr & AT91_PMC_PLLADIV2; + at91_pmc_write(AT91_PMC_MCKR, tmp); + + /* + * Program the H32MXDIV field in the AT91_PMC_MCKR register + */ + tmp = at91_pmc_read(AT91_PMC_MCKR); + tmp &= ~AT91_PMC_H32MXDIV; + tmp |= pmc_mckr & AT91_PMC_H32MXDIV; + at91_pmc_write(AT91_PMC_MCKR, tmp); + + /* + * Program the CSS field in the AT91_PMC_MCKR register, + * wait for MCKRDY bit to be set in the PMC_SR register + */ + tmp = at91_pmc_read(AT91_PMC_MCKR); + tmp &= ~AT91_PMC_ALT_PCKR_CSS; + tmp |= pmc_mckr & AT91_PMC_ALT_PCKR_CSS; + at91_pmc_write(AT91_PMC_MCKR, tmp); + + while (!(at91_pmc_read(AT91_PMC_SR) & AT91_PMC_MCKRDY)) + ; +} diff --git a/arch/arm/mach-at91/clock.c b/arch/arm/mach-at91/clock.c index d2691ac..9a58b24 100644 --- a/arch/arm/mach-at91/clock.c +++ b/arch/arm/mach-at91/clock.c @@ -46,6 +46,7 @@ #define cpu_has_utmi() ( cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ + || cpu_is_sama5d2() \ || cpu_is_sama5d3() \ || cpu_is_sama5d4()) @@ -69,11 +70,13 @@ #define cpu_has_pllb() (!(cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ + || cpu_is_sama5d2() \ || cpu_is_sama5d3() \ || cpu_is_sama5d4())) #define cpu_has_upll() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ + || cpu_is_sama5d2() \ || cpu_is_sama5d3() \ || cpu_is_sama5d4()) @@ -84,30 +87,36 @@ #define cpu_has_udpfs() (!(cpu_is_at91sam9rl() \ || cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ + || cpu_is_sama5d2() \ || cpu_is_sama5d3() \ || cpu_is_sama5d4())) #define cpu_has_plladiv2() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ || cpu_is_at91sam9n12() \ + || cpu_is_sama5d2() \ || cpu_is_sama5d3() \ || cpu_is_sama5d4()) #define cpu_has_mdiv3() (cpu_is_at91sam9g45() \ || cpu_is_at91sam9x5() \ || cpu_is_at91sam9n12() \ + || cpu_is_sama5d2() \ || cpu_is_sama5d3() \ || cpu_is_sama5d4()) #define cpu_has_alt_prescaler() (cpu_is_at91sam9x5() \ || cpu_is_at91sam9n12() \ + || cpu_is_sama5d2() \ || cpu_is_sama5d3() \ || cpu_is_sama5d4()) -#define cpu_has_pcr() (cpu_is_sama5d3() \ +#define cpu_has_pcr() (cpu_is_sama5d2() \ + || cpu_is_sama5d3() \ || cpu_is_sama5d4()) -#define cpu_has_dual_matrix() (cpu_is_sama5d4()) +#define cpu_has_dual_matrix() (cpu_is_sama5d2() \ + || cpu_is_sama5d4()) static void *pmc; @@ -663,6 +672,8 @@ if (cpu_is_sama5d4()) pmc = IOMEM(0xf0018000); + else if (cpu_is_sama5d2()) + pmc = IOMEM(0xf0014000); else pmc = IOMEM(0xfffffc00); /* * All other supported SoCs use this diff --git a/arch/arm/mach-at91/include/mach/at91_dbgu.h b/arch/arm/mach-at91/include/mach/at91_dbgu.h index e33a358..0ba9cda 100644 --- a/arch/arm/mach-at91/include/mach/at91_dbgu.h +++ b/arch/arm/mach-at91/include/mach/at91_dbgu.h @@ -5,7 +5,7 @@ * Copyright (C) SAN People * * Debug Unit (DBGU) - System peripherals registers. - * Based on AT91RM9200 datasheet revision E. + * Based on AT91RM9200 datasheet revision E and SAMA5D3 datasheet revision B. * * 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 @@ -17,7 +17,33 @@ #define AT91_DBGU_H #define AT91_DBGU_CR (0x00) /* Control Register */ +#define AT91_DBGU_RSTRX (1 << 2) /* Reset Receiver */ +#define AT91_DBGU_RSTTX (1 << 3) /* Reset Transmitter */ +#define AT91_DBGU_RXEN (1 << 4) /* Receiver Enable */ +#define AT91_DBGU_RXDIS (1 << 5) /* Receiver Disable */ +#define AT91_DBGU_TXEN (1 << 6) /* Transmitter Enable */ +#define AT91_DBGU_TXDIS (1 << 7) /* Transmitter Disable */ +#define AT91_DBGU_RSTSTA (1 << 8) /* Reset Status Bits */ #define AT91_DBGU_MR (0x04) /* Mode Register */ +#define AT91_DBGU_NBSTOP_1BIT (0 << 12) /* 1 stop bit */ +#define AT91_DBGU_NBSTOP_1_5BIT (1 << 12) /* 1.5 stop bits */ +#define AT91_DBGU_NBSTOP_2BIT (2 << 12) /* 2 stop bits */ + +#define AT91_DBGU_CHRL_5BIT (0 << 6) /* 5 bit character length */ +#define AT91_DBGU_CHRL_6BIT (1 << 6) /* 6 bit character length */ +#define AT91_DBGU_CHRL_7BIT (2 << 6) /* 7 bit character length */ +#define AT91_DBGU_CHRL_8BIT (3 << 6) /* 8 bit character length */ + +#define AT91_DBGU_PAR_EVEN (0 << 9) /* Even Parity */ +#define AT91_DBGU_PAR_ODD (1 << 9) /* Odd Parity */ +#define AT91_DBGU_PAR_SPACE (2 << 9) /* Space: Force Parity to 0 */ +#define AT91_DBGU_PAR_MARK (3 << 9) /* Mark: Force Parity to 1 */ +#define AT91_DBGU_PAR_NONE (4 << 9) /* No Parity */ + +#define AT91_DBGU_CHMODE_NORMAL (0 << 14) /* Normal mode */ +#define AT91_DBGU_CHMODE_AUTO (1 << 14) /* Automatic Echo */ +#define AT91_DBGU_CHMODE_LOCAL (2 << 14) /* Local Loopback */ +#define AT91_DBGU_CHMODE_REMOTE (3 << 14) /* Remote Loopback */ #define AT91_DBGU_IER (0x08) /* Interrupt Enable Register */ #define AT91_DBGU_TXRDY (1 << 1) /* Transmitter Ready */ #define AT91_DBGU_TXEMPTY (1 << 9) /* Transmitter Empty */ @@ -61,4 +87,39 @@ #define AT91_CIDR_NVPTYP (7 << 28) /* Nonvolatile Program Memory Type */ #define AT91_CIDR_EXT (1 << 31) /* Extension Flag */ +#ifndef __ASSEMBLY__ + +#include +static inline void at91_dbgu_setup_ll(void __iomem *dbgu_base, + unsigned mck, + unsigned baudrate) +{ + if (IS_ENABLED(CONFIG_DEBUG_LL)) { + u32 brgr = mck / (baudrate * 16); + + if ((mck / (baudrate * 16)) % 10 >= 5) + brgr++; + + writel(~0, dbgu_base + AT91_DBGU_IDR); + + writel(AT91_DBGU_RSTRX + | AT91_DBGU_RSTTX + | AT91_DBGU_RXDIS + | AT91_DBGU_TXDIS, + dbgu_base + AT91_DBGU_CR); + + writel(brgr, dbgu_base + AT91_DBGU_BRGR); + + writel(AT91_DBGU_PAR_NONE + | AT91_DBGU_CHMODE_NORMAL + | AT91_DBGU_CHRL_8BIT + | AT91_DBGU_NBSTOP_1BIT, + dbgu_base + AT91_DBGU_MR); + + writel(AT91_DBGU_RXEN | AT91_DBGU_TXEN, dbgu_base + AT91_DBGU_CR); + } +} + +#endif + #endif diff --git a/arch/arm/mach-at91/include/mach/at91_pio.h b/arch/arm/mach-at91/include/mach/at91_pio.h index 2d80dfc..0f129c9 100644 --- a/arch/arm/mach-at91/include/mach/at91_pio.h +++ b/arch/arm/mach-at91/include/mach/at91_pio.h @@ -3,6 +3,8 @@ * * Copyright (C) 2005 Ivan Kokshaysky * Copyright (C) SAN People + * Copyright (C) 2015 Atmel, + * 2015 Ludovic Desroches * * Parallel I/O Controller (PIO) - System peripherals registers. * Based on AT91RM9200 datasheet revision E. @@ -16,6 +18,8 @@ #ifndef AT91_PIO_H #define AT91_PIO_H +#include + #define PIO_PER 0x00 /* Enable Register */ #define PIO_PDR 0x04 /* Disable Register */ #define PIO_PSR 0x08 /* Status Register */ @@ -71,4 +75,33 @@ #define ABCDSR_PERIPH_C 0x2 #define ABCDSR_PERIPH_D 0x3 +#define PIO4_MSKR 0x0000 /* Mask Register */ +#define PIO4_CFGR 0x0004 /* Configuration Register */ +#define PIO4_CFGR_FUNC_MASK GENMASK(2, 0) +#define PIO4_DIR_MASK BIT(8) +#define PIO4_PUEN_MASK BIT(9) +#define PIO4_PDEN_MASK BIT(10) +#define PIO4_IFEN_MASK BIT(12) +#define PIO4_IFSCEN_MASK BIT(13) +#define PIO4_OPD_MASK BIT(14) +#define PIO4_SCHMITT_MASK BIT(15) +#define PIO4_DRVSTR_MASK GENMASK(17, 16) +#define PIO4_DRVSTR_OFFSET 16 +#define PIO4_CFGR_EVTSEL_MASK GENMASK(26, 24) +#define PIO4_CFGR_EVTSEL_FALLING (0 << 24) +#define PIO4_CFGR_EVTSEL_RISING (1 << 24) +#define PIO4_CFGR_EVTSEL_BOTH (2 << 24) +#define PIO4_CFGR_EVTSEL_LOW (3 << 24) +#define PIO4_CFGR_EVTSEL_HIGH (4 << 24) +#define PIO4_PDSR 0x0008 /* Data Status Register */ +#define PIO4_LOCKSR 0x000C /* Lock Status Register */ +#define PIO4_SODR 0x0010 /* Set Output Data Register */ +#define PIO4_CODR 0x0014 /* Clear Output Data Register */ +#define PIO4_ODSR 0x0018 /* Output Data Status Register */ +#define PIO4_IER 0x0020 /* Interrupt Enable Register */ +#define PIO4_IDR 0x0024 /* Interrupt Disable Register */ +#define PIO4_IMR 0x0028 /* Interrupt Mask Register */ +#define PIO4_ISR 0x002C /* Interrupt Status Register */ +#define PIO4_IOFR 0x003C /* I/O Freeze Configuration Register */ + #endif diff --git a/arch/arm/mach-at91/include/mach/at91_pmc.h b/arch/arm/mach-at91/include/mach/at91_pmc.h index bbbd497..4d60bec 100644 --- a/arch/arm/mach-at91/include/mach/at91_pmc.h +++ b/arch/arm/mach-at91/include/mach/at91_pmc.h @@ -50,14 +50,19 @@ #define AT91_PMC_OSCBYPASS (1 << 1) /* Oscillator Bypass */ #define AT91_PMC_MOSCRCEN (1 << 3) /* Main On-Chip RC Oscillator Enable [some SAM9] */ #define AT91_PMC_OSCOUNT (0xff << 8) /* Main Oscillator Start-up Time */ -#define AT91_PMC_KEY (0x37 << 16) /* MOR Writing Key */ +#define AT91_PMC_OSCOUNT_(x) ((x) << 8) +#define AT91_PMC_KEY_MASK (0xff << 16) /* MOR Writing Key */ +#define AT91_PMC_KEY (0x37 << 16) #define AT91_PMC_MOSCSEL (1 << 24) /* Main Oscillator Selection [some SAM9] */ #define AT91_PMC_CFDEN (1 << 25) /* Clock Failure Detector Enable [some SAM9] */ #define AT91_CKGR_MCFR 0x24 /* Main Clock Frequency Register */ #define AT91_PMC_MAINF (0xffff << 0) /* Main Clock Frequency */ -#define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Ready */ - +#define AT91_PMC_MAINRDY (1 << 16) /* Main Clock Frequency Measure Ready */ +#define AT91_PMC_RCMEAS (1 << 20) /* RC Oscillator Frequency Measure (write-only) */ +#define AT91_PMC_CCSS (1 << 24) /* Counter Clock Source Selection */ +#define AT91_PMC_CCSS_RC_OSC (0 << 24) /* MAINF counter clock is the RC oscillator. */ +#define AT91_PMC_CCSS_XTAL_OSC (1 << 24) /* MAINF counter clock is the crystal oscillator. */ #define AT91_CKGR_PLLAR 0x28 /* PLL A Register */ #define AT91_CKGR_PLLBR 0x2c /* PLL B Register */ #define AT91_PMC_DIV (0xff << 0) /* Divider */ @@ -133,6 +138,7 @@ #define AT91_PMC_CSSMCK_MCK (1 << 8) #define AT91_PMC_IER 0x60 /* Interrupt Enable Register */ +#define AT91_PMC_MOSCXTS (1 << 0) /* Oscillator Startup Time */ #define AT91_PMC_IDR 0x64 /* Interrupt Disable Register */ #define AT91_PMC_SR 0x68 /* Status Register */ #define AT91_PMC_MOSCS (1 << 0) /* MOSCS Flag */ @@ -148,6 +154,17 @@ #define AT91_PMC_MOSCRCS (1 << 17) /* Main On-Chip RC [some SAM9] */ #define AT91_PMC_CFDEV (1 << 18) /* Clock Failure Detector Event [some SAM9] */ #define AT91_PMC_IMR 0x6c /* Interrupt Mask Register */ +#define AT91_PMC_PLLICPR 0x80 /* PLL Charge Pump Current Register */ +#define AT91_PMC_ICPPLLA (0xf << 0) +#define AT91_PMC_ICPPLLA_0 (0 << 0) +#define AT91_PMC_ICPPLLA_1 (1 << 0) +#define AT91_PMC_REALLOCK (0x1 << 7) +#define AT91_PMC_IPLLA (0xf << 8) +#define AT91_PMC_IPLLA_0 (0 << 8) +#define AT91_PMC_IPLLA_1 (1 << 8) +#define AT91_PMC_IPLLA_2 (2 << 8) +#define AT91_PMC_IPLLA_3 (3 << 8) + #define AT91_PMC_PROT 0xe4 /* Write Protect Mode Register [some SAM9] */ #define AT91_PMC_WPEN (0x1 << 0) /* Write Protect Enable */ @@ -163,6 +180,7 @@ #define AT91_PMC_PCR 0x10c /* Peripheral Control Register [some SAM9] */ #define AT91_PMC_PCR_PID (0x3f << 0) /* Peripheral ID */ #define AT91_PMC_PCR_CMD (0x1 << 12) /* Command */ +#define AT91_PMC_PCR_DIV_MASK (0x3 << 16) #define AT91_PMC_PCR_DIV(n) ((n) << 16) /* Divisor value */ #define AT91_PMC_PCR_DIV0 0x0 /* Peripheral clock is MCK */ #define AT91_PMC_PCR_DIV2 0x1 /* Peripheral clock is MCK/2 */ diff --git a/arch/arm/mach-at91/include/mach/at91_pmc_ll.h b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h new file mode 100644 index 0000000..eda40e8 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/at91_pmc_ll.h @@ -0,0 +1,78 @@ +// SPDX-License-Identifier: BSD-1-Clause +/* + * Copyright (c) 2006, Atmel Corporation + */ + +#ifndef AT91_PMC_LL_H +#define AT91_PMC_LL_H + +#include +#include +#include + +#define AT91_PMC_LL_FLAG_SAM9X5_PMC (1 << 0) +#define AT91_PMC_LL_FLAG_MEASURE_XTAL (1 << 1) +#define AT91_PMC_LL_FLAG_DISABLE_RC (1 << 2) + +#define AT91_PMC_LL_AT91RM9200 (0) +#define AT91_PMC_LL_AT91SAM9260 (0) +#define AT91_PMC_LL_AT91SAM9261 (0) +#define AT91_PMC_LL_AT91SAM9263 (0) +#define AT91_PMC_LL_AT91SAM9G45 (0) +#define AT91_PMC_LL_AT91SAM9X5 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \ + AT91_PMC_LL_FLAG_DISABLE_RC) +#define AT91_PMC_LL_AT91SAM9N12 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \ + AT91_PMC_LL_FLAG_DISABLE_RC) +#define AT91_PMC_LL_SAMA5D2 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \ + AT91_PMC_LL_FLAG_MEASURE_XTAL) +#define AT91_PMC_LL_SAMA5D3 (AT91_PMC_LL_FLAG_SAM9X5_PMC | \ + AT91_PMC_LL_FLAG_DISABLE_RC) +#define AT91_PMC_LL_SAMA5D4 (AT91_PMC_LL_FLAG_SAM9X5_PMC) + +void at91_pmc_init(void __iomem *pmc_base, unsigned int flags); +void at91_pmc_cfg_mck(void __iomem *pmc_base, u32 pmc_mckr, unsigned int flags); +void at91_pmc_cfg_plla(void __iomem *pmc_base, u32 pmc_pllar, unsigned int flags); + +static inline void at91_pmc_init_pll(void __iomem *pmc_base, u32 pmc_pllicpr) +{ + writel(pmc_pllicpr, pmc_base + AT91_PMC_PLLICPR); +} + +static inline void at91_pmc_enable_system_clock(void __iomem *pmc_base, + unsigned clock_id) +{ + writel(clock_id, pmc_base + AT91_PMC_SCER); +} + +static inline int at91_pmc_enable_periph_clock(void __iomem *pmc_base, + unsigned periph_id) +{ + u32 mask = 0x01 << (periph_id % 32); + + if ((periph_id / 32) == 1) + writel(mask, pmc_base + AT91_PMC_PCER1); + else if ((periph_id / 32) == 0) + writel(mask, pmc_base + AT91_PMC_PCER); + else + return -EINVAL; + + return 0; +} + +static inline int at91_pmc_sam9x5_enable_periph_clock(void __iomem *pmc_base, + unsigned periph_id) +{ + u32 pcr = periph_id; + + if (periph_id >= 0x80) /* 7 bits only */ + return -EINVAL; + + writel(pcr, pmc_base + AT91_PMC_PCR); + pcr |= readl(pmc_base + AT91_PMC_PCR) & AT91_PMC_PCR_DIV_MASK; + pcr |= AT91_PMC_PCR_CMD | AT91_PMC_PCR_EN; + writel(pcr, pmc_base + AT91_PMC_PCR); + + return 0; +} + +#endif diff --git a/arch/arm/mach-at91/include/mach/at91sam926x_board_init.h b/arch/arm/mach-at91/include/mach/at91sam926x_board_init.h index d52a29e..3dab64b 100644 --- a/arch/arm/mach-at91/include/mach/at91sam926x_board_init.h +++ b/arch/arm/mach-at91/include/mach/at91sam926x_board_init.h @@ -183,28 +183,22 @@ writel(0xffffffff, pmc + AT91_PMC_PCER); } -#if defined CONFIG_ARCH_AT91SAM9260 #include static void __always_inline at91sam9260_board_init(struct at91sam926x_board_cfg *cfg) { at91sam926x_board_init(IOMEM(AT91SAM9260_BASE_SMC), cfg); } -#endif -#if defined CONFIG_ARCH_AT91SAM9261 || defined CONFIG_ARCH_AT91SAM9G10 #include static void __always_inline at91sam9261_board_init(struct at91sam926x_board_cfg *cfg) { at91sam926x_board_init(IOMEM(AT91SAM9261_BASE_SMC), cfg); } -#endif -#if defined CONFIG_ARCH_AT91SAM9263 #include static void __always_inline at91sam9263_board_init(struct at91sam926x_board_cfg *cfg) { at91sam926x_board_init(IOMEM(AT91SAM9263_BASE_SMC0), cfg); } -#endif #endif /* __AT91SAM926X_BOARD_INIT_H__ */ diff --git a/arch/arm/mach-at91/include/mach/cpu.h b/arch/arm/mach-at91/include/mach/cpu.h index def49dc..6e0f25f 100644 --- a/arch/arm/mach-at91/include/mach/cpu.h +++ b/arch/arm/mach-at91/include/mach/cpu.h @@ -52,6 +52,22 @@ #define ARCH_EXID_AT91SAM9CN11 0x00000009 #define ARCH_EXID_AT91SAM9CN12 0x00000005 +#define ARCH_EXID_SAMA5D21CU 0x0000005a +#define ARCH_EXID_SAMA5D225C_D1M 0x00000053 +#define ARCH_EXID_SAMA5D22CU 0x00000059 +#define ARCH_EXID_SAMA5D22CN 0x00000069 +#define ARCH_EXID_SAMA5D23CU 0x00000058 +#define ARCH_EXID_SAMA5D24CX 0x00000004 +#define ARCH_EXID_SAMA5D24CU 0x00000014 +#define ARCH_EXID_SAMA5D26CU 0x00000012 +#define ARCH_EXID_SAMA5D27C_D1G 0x00000033 +#define ARCH_EXID_SAMA5D27C_D5M 0x00000032 +#define ARCH_EXID_SAMA5D27CU 0x00000011 +#define ARCH_EXID_SAMA5D27CN 0x00000021 +#define ARCH_EXID_SAMA5D28C_D1G 0x00000013 +#define ARCH_EXID_SAMA5D28CU 0x00000010 +#define ARCH_EXID_SAMA5D28CN 0x00000020 + #define ARCH_EXID_SAMA5D3 0x00004300 #define ARCH_EXID_SAMA5D31 0x00444300 #define ARCH_EXID_SAMA5D33 0x00414300 @@ -93,6 +109,9 @@ /* SAM9N12 */ AT91_SOC_SAM9N12, + /* SAMA5D2 */ + AT91_SOC_SAMA5D2, + /* SAMA5D3 */ AT91_SOC_SAMA5D3, @@ -120,6 +139,14 @@ /* SAM9N12 */ AT91_SOC_SAM9CN11, AT91_SOC_SAM9CN12, + /* SAMA5D2 */ + AT91_SOC_SAMA5D21CU, + AT91_SOC_SAMA5D225C_D1M, AT91_SOC_SAMA5D22CU, AT91_SOC_SAMA5D22CN, + AT91_SOC_SAMA5D23CU, AT91_SOC_SAMA5D24CX, AT91_SOC_SAMA5D24CU, + AT91_SOC_SAMA5D26CU, AT91_SOC_SAMA5D27C_D1G, AT91_SOC_SAMA5D27C_D5M, + AT91_SOC_SAMA5D27CU, AT91_SOC_SAMA5D27CN, AT91_SOC_SAMA5D28C_D1G, + AT91_SOC_SAMA5D28CU, AT91_SOC_SAMA5D28CN, + /* SAMA5D3 */ AT91_SOC_SAMA5D31, AT91_SOC_SAMA5D33, AT91_SOC_SAMA5D34, AT91_SOC_SAMA5D35, AT91_SOC_SAMA5D36, @@ -222,7 +249,36 @@ #define cpu_is_at91sam9n12() (0) #endif -#ifdef CONFIG_ARCH_SAMA5D3 +#ifdef CONFIG_SOC_SAMA5D2 +#define cpu_is_sama5d2() (at91_soc_initdata.type == AT91_SOC_SAMA5D2) +#define cpu_is_sama5d21() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D21CU) +#define cpu_is_sama5d22() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D225C_D1M \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D225C_D1M \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D22CU \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D22CN) +#define cpu_is_sama5d23() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D23CU) +#define cpu_is_sama5d24() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D24CX \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D24CU) +#define cpu_is_sama5d26() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D26CU) +#define cpu_is_sama5d27() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D27C_D1G \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D27C_D5M \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D27CU \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D27CN) +#define cpu_is_sama5d28() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D28C_D1G \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D28CU \ + || at91_soc_initdata.subtype == AT91_SOC_SAMA5D28CN) +#else +#define cpu_is_sama5d2() (0) +#define cpu_is_sama5d21() (0) +#define cpu_is_sama5d22() (0) +#define cpu_is_sama5d23() (0) +#define cpu_is_sama5d24() (0) +#define cpu_is_sama5d26() (0) +#define cpu_is_sama5d27() (0) +#define cpu_is_sama5d28() (0) +#endif + +#ifdef CONFIG_SOC_SAMA5D3 #define cpu_is_sama5d3() (at91_soc_initdata.type == AT91_SOC_SAMA5D3) #define cpu_is_sama5d31() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D31) #define cpu_is_sama5d33() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D33) @@ -238,7 +294,7 @@ #define cpu_is_sama5d36() (0) #endif -#ifdef CONFIG_ARCH_SAMA5D4 +#ifdef CONFIG_SOC_SAMA5D4 #define cpu_is_sama5d4() (at91_soc_initdata.type == AT91_SOC_SAMA5D4) #define cpu_is_sama5d41() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D41) #define cpu_is_sama5d42() (at91_soc_initdata.subtype == AT91_SOC_SAMA5D42) diff --git a/arch/arm/mach-at91/include/mach/gpio.h b/arch/arm/mach-at91/include/mach/gpio.h index f5ab47c..ddd6971 100644 --- a/arch/arm/mach-at91/include/mach/gpio.h +++ b/arch/arm/mach-at91/include/mach/gpio.h @@ -7,8 +7,23 @@ #ifndef __AT91_GPIO_H__ #define __AT91_GPIO_H__ +#include +#include +#include + #define MAX_NB_GPIO_PER_BANK 32 +enum at91_mux { + AT91_MUX_GPIO = 0, + AT91_MUX_PERIPH_A = 1, + AT91_MUX_PERIPH_B = 2, + AT91_MUX_PERIPH_C = 3, + AT91_MUX_PERIPH_D = 4, + AT91_MUX_PERIPH_E = 5, + AT91_MUX_PERIPH_F = 6, + AT91_MUX_PERIPH_G = 7, +}; + static inline unsigned pin_to_bank(unsigned pin) { return pin / MAX_NB_GPIO_PER_BANK; @@ -130,10 +145,162 @@ static inline int at91_mux_gpio_get(void __iomem *pio, unsigned mask) { - u32 pdsr; + u32 pdsr; - pdsr = readl(pio + PIO_PDSR); - return (pdsr & mask) != 0; + pdsr = readl(pio + PIO_PDSR); + return (pdsr & mask) != 0; +} + +static inline void at91_mux_pio3_pin(void __iomem *pio, unsigned mask, + enum at91_mux mux, int gpio_state) +{ + at91_mux_disable_interrupt(pio, mask); + + switch(mux) { + case AT91_MUX_GPIO: + at91_mux_gpio_enable(pio, mask); + break; + case AT91_MUX_PERIPH_A: + at91_mux_pio3_set_A_periph(pio, mask); + break; + case AT91_MUX_PERIPH_B: + at91_mux_pio3_set_B_periph(pio, mask); + break; + case AT91_MUX_PERIPH_C: + at91_mux_pio3_set_C_periph(pio, mask); + break; + case AT91_MUX_PERIPH_D: + at91_mux_pio3_set_D_periph(pio, mask); + break; + default: + /* ignore everything else */ + break; + } + if (mux != AT91_MUX_GPIO) + at91_mux_gpio_disable(pio, mask); + + at91_mux_set_pullup(pio, mask, gpio_state & GPIO_PULL_UP); + at91_mux_pio3_set_pulldown(pio, mask, gpio_state & GPIO_PULL_DOWN); +} + +/* helpers for PIO4 pinctrl (>= sama5d2) */ + +static inline void at91_mux_pio4_set_periph(void __iomem *pio, unsigned mask, u32 func) +{ + writel(mask, pio + PIO4_MSKR); + writel(func, pio + PIO4_CFGR); +} + +static inline void at91_mux_pio4_set_A_periph(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_periph(pio, mask, AT91_MUX_PERIPH_A); +} + +static inline void at91_mux_pio4_set_B_periph(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_periph(pio, mask, AT91_MUX_PERIPH_B); +} + +static inline void at91_mux_pio4_set_C_periph(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_periph(pio, mask, AT91_MUX_PERIPH_C); +} + +static inline void at91_mux_pio4_set_D_periph(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_periph(pio, mask, AT91_MUX_PERIPH_D); +} + +static inline void at91_mux_pio4_set_E_periph(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_periph(pio, mask, AT91_MUX_PERIPH_E); +} + +static inline void at91_mux_pio4_set_F_periph(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_periph(pio, mask, AT91_MUX_PERIPH_F); +} + +static inline void at91_mux_pio4_set_G_periph(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_periph(pio, mask, AT91_MUX_PERIPH_G); +} + +static inline void at91_mux_pio4_set_func(void __iomem *pio, + unsigned pin_mask, + unsigned cfgr_and_mask, + unsigned cfgr_or_mask) +{ + u32 reg; + writel(pin_mask, pio + PIO4_MSKR); + reg = readl(pio + PIO4_CFGR); + reg &= cfgr_and_mask; + reg |= cfgr_or_mask; + writel(reg, pio + PIO4_CFGR); +} + +static inline void at91_mux_pio4_set_bistate(void __iomem *pio, + unsigned pin_mask, + unsigned func_mask, + bool is_on) +{ + at91_mux_pio4_set_func(pio, pin_mask, ~func_mask, + is_on ? func_mask : 0); +} + +static inline void at91_mux_pio4_set_deglitch(void __iomem *pio, unsigned mask, bool is_on) +{ + at91_mux_pio4_set_bistate(pio, mask, PIO4_IFEN_MASK, is_on); +} + +static inline void at91_mux_pio4_set_debounce(void __iomem *pio, unsigned mask, + bool is_on, u32 div) +{ + at91_mux_pio4_set_bistate(pio, mask, PIO4_IFEN_MASK, is_on); + at91_mux_pio4_set_bistate(pio, mask, PIO4_IFSCEN_MASK, is_on); +} + +static inline void at91_mux_pio4_set_pulldown(void __iomem *pio, unsigned mask, bool is_on) +{ + at91_mux_pio4_set_bistate(pio, mask, PIO4_PDEN_MASK, is_on); +} + +static inline void at91_mux_pio4_disable_schmitt_trig(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_bistate(pio, mask, PIO4_SCHMITT_MASK, false); +} + +static inline void at91_mux_gpio4_enable(void __iomem *pio, unsigned mask) +{ + at91_mux_pio4_set_func(pio, mask, ~PIO4_CFGR_FUNC_MASK, AT91_MUX_GPIO); +} + +static inline void at91_mux_gpio4_input(void __iomem *pio, unsigned mask, bool input) +{ + u32 cfgr; + + writel(mask, pio + PIO4_MSKR); + + cfgr = readl(pio + PIO4_CFGR); + if (input) + cfgr &= ~PIO4_DIR_MASK; + else + cfgr |= PIO4_DIR_MASK; + writel(cfgr, pio + PIO4_CFGR); +} + +static inline void at91_mux_gpio4_set(void __iomem *pio, unsigned mask, + int value) +{ + writel(mask, pio + (value ? PIO4_SODR : PIO4_CODR)); +} + +static inline int at91_mux_gpio4_get(void __iomem *pio, unsigned mask) +{ + u32 pdsr; + + pdsr = readl(pio + PIO4_PDSR); + return (pdsr & mask) != 0; } #endif /* __AT91_GPIO_H__ */ diff --git a/arch/arm/mach-at91/include/mach/hardware.h b/arch/arm/mach-at91/include/mach/hardware.h index 2146203..3ae5424 100644 --- a/arch/arm/mach-at91/include/mach/hardware.h +++ b/arch/arm/mach-at91/include/mach/hardware.h @@ -29,6 +29,7 @@ #include #include #include +#include #include #include diff --git a/arch/arm/mach-at91/include/mach/iomux.h b/arch/arm/mach-at91/include/mach/iomux.h index bac7ef6..0c91b22 100644 --- a/arch/arm/mach-at91/include/mach/iomux.h +++ b/arch/arm/mach-at91/include/mach/iomux.h @@ -17,6 +17,7 @@ #include #include #include +#include #define AT91_PIN_PA0 (0x00 + 0) #define AT91_PIN_PA1 (0x00 + 1) @@ -183,14 +184,6 @@ #define AT91_PIN_PE30 (0x80 + 30) #define AT91_PIN_PE31 (0x80 + 31) -enum at91_mux { - AT91_MUX_GPIO = 0, - AT91_MUX_PERIPH_A = 1, - AT91_MUX_PERIPH_B = 2, - AT91_MUX_PERIPH_C = 3, - AT91_MUX_PERIPH_D = 4, -}; - /* * mux the pin */ diff --git a/arch/arm/mach-at91/include/mach/sama5d2.h b/arch/arm/mach-at91/include/mach/sama5d2.h new file mode 100644 index 0000000..3dad7d9 --- /dev/null +++ b/arch/arm/mach-at91/include/mach/sama5d2.h @@ -0,0 +1,261 @@ +// SPDX-License-Identifier: BSD-1-Clause +/* + * Chip-specific header file for the SAMA5D2 family + * + * Copyright (c) 2015, Atmel Corporation + * Copyright (c) 2019 Ahmad Fatoum, Pengutronix + * + * Common definitions. + * Based on SAMA5D2 datasheet: + * http://ww1.microchip.com/downloads/en/DeviceDoc/SAMA5D2-Series-Data-Sheet-DS60001476C.pdf + * + */ + +#ifndef SAMA5D2_H +#define SAMA5D2_H + +/* + * Peripheral identifiers/interrupts. (Table 18-9) + */ +#define SAMA5D2_ID_FIQ 0 /* FIQ Interrupt ID */ +/* 1 */ +#define SAMA5D2_ID_ARM 2 /* Performance Monitor Unit */ +#define SAMA5D2_ID_PIT 3 /* Periodic Interval Timer Interrupt */ +#define SAMA5D2_ID_WDT 4 /* Watchdog Timer Interrupt */ +#define SAMA5D2_ID_GMAC 5 /* Ethernet MAC */ +#define SAMA5D2_ID_XDMAC0 6 /* DMA Controller 0 */ +#define SAMA5D2_ID_XDMAC1 7 /* DMA Controller 1 */ +#define SAMA5D2_ID_ICM 8 /* Integrity Check Monitor */ +#define SAMA5D2_ID_AES 9 /* Advanced Encryption Standard */ +#define SAMA5D2_ID_AESB 10 /* AES bridge */ +#define SAMA5D2_ID_TDES 11 /* Triple Data Encryption Standard */ +#define SAMA5D2_ID_SHA 12 /* SHA Signature */ +#define SAMA5D2_ID_MPDDRC 13 /* MPDDR Controller */ +#define SAMA5D2_ID_MATRIX1 14 /* H32MX, 32-bit AHB Matrix */ +#define SAMA5D2_ID_MATRIX0 15 /* H64MX, 64-bit AHB Matrix */ +#define SAMA5D2_ID_SECUMOD 16 /* Secure Module */ +#define SAMA5D2_ID_HSMC 17 /* Multi-bit ECC interrupt */ +#define SAMA5D2_ID_PIOA 18 /* Parallel I/O Controller A */ +#define SAMA5D2_ID_FLEXCOM0 19 /* FLEXCOM0 */ +#define SAMA5D2_ID_FLEXCOM1 20 /* FLEXCOM1 */ +#define SAMA5D2_ID_FLEXCOM2 21 /* FLEXCOM2 */ +#define SAMA5D2_ID_FLEXCOM3 22 /* FLEXCOM3 */ +#define SAMA5D2_ID_FLEXCOM4 23 /* FLEXCOM4 */ +#define SAMA5D2_ID_UART0 24 /* UART0 */ +#define SAMA5D2_ID_UART1 25 /* UART1 */ +#define SAMA5D2_ID_UART2 26 /* UART2 */ +#define SAMA5D2_ID_UART3 27 /* UART3 */ +#define SAMA5D2_ID_UART4 28 /* UART4 */ +#define SAMA5D2_ID_TWI0 29 /* Two-wire Interface 0 */ +#define SAMA5D2_ID_TWI1 30 /* Two-wire Interface 1 */ +#define SAMA5D2_ID_SDMMC0 31 /* Secure Data Memory Card Controller 0 */ +#define SAMA5D2_ID_SDMMC1 32 /* Secure Data Memory Card Controller 1 */ +#define SAMA5D2_ID_SPI0 33 /* Serial Peripheral Interface 0 */ +#define SAMA5D2_ID_SPI1 34 /* Serial Peripheral Interface 1 */ +#define SAMA5D2_ID_TC0 35 /* Timer Counter 0 (ch.0,1,2) */ +#define SAMA5D2_ID_TC1 36 /* Timer Counter 1 (ch.3,4,5) */ +/* 37 */ +#define SAMA5D2_ID_PWM 38 /* Pulse Width Modulation Controller0 (ch. 0,1,2,3) */ +/* 39 */ +#define SAMA5D2_ID_ADC 40 /* Touch Screen ADC Controller */ +#define SAMA5D2_ID_UHPHS 41 /* USB Host High Speed */ +#define SAMA5D2_ID_UDPHS 42 /* USB Device High Speed */ +#define SAMA5D2_ID_SSC0 43 /* Serial Synchronous Controller 0 */ +#define SAMA5D2_ID_SSC1 44 /* Serial Synchronous Controller 1 */ +#define SAMA5D2_ID_LCDC 45 /* LCD Controller */ +#define SAMA5D2_ID_ISI 46 /* Image Sensor Interface */ +#define SAMA5D2_ID_TRNG 47 /* True Random Number Generator */ +#define SAMA5D2_ID_PDMIC 48 /* Pulse Density Modulation Interface Controller */ +#define SAMA5D2_ID_IRQ 49 /* IRQ Interrupt ID */ +#define SAMA5D2_ID_SFC 50 /* Fuse Controller */ +#define SAMA5D2_ID_SECURAM 51 /* Secure RAM */ +#define SAMA5D2_ID_QSPI0 52 /* QSPI0 */ +#define SAMA5D2_ID_QSPI1 53 /* QSPI1 */ +#define SAMA5D2_ID_I2SC0 54 /* Inter-IC Sound Controller 0 */ +#define SAMA5D2_ID_I2SC1 55 /* Inter-IC Sound Controller 1 */ +#define SAMA5D2_ID_CAN0_INT0 56 /* MCAN 0 Interrupt0 */ +#define SAMA5D2_ID_CAN1_INT0 57 /* MCAN 1 Interrupt0 */ +#define SAMA5D2_ID_PTC 58 /* Peripheral Touch Controller */ +#define SAMA5D2_ID_CLASSD 59 /* Audio Class D Amplifier */ +#define SAMA5D2_ID_SFR 60 /* Special Function Register */ +#define SAMA5D2_ID_SAIC 61 /* Secured Advanced Interrupt Controller */ +#define SAMA5D2_ID_AIC 62 /* Advanced Interrupt Controller */ +#define SAMA5D2_ID_L2CC 63 /* L2 Cache Controller */ +#define SAMA5D2_ID_CAN0_INT1 64 /* MCAN 0 Interrupt1 */ +#define SAMA5D2_ID_CAN1_INT1 65 /* MCAN 1 Interrupt1 */ +#define SAMA5D2_ID_GMAC_Q1 66 /* GMAC Queue 1 Interrupt */ +#define SAMA5D2_ID_GMAC_Q2 67 /* GMAC Queue 2 Interrupt */ +#define SAMA5D2_ID_PIOB 68 /* Parallel I/O Controller B */ +#define SAMA5D2_ID_PIOC 69 /* Parallel I/O Controller C */ +#define SAMA5D2_ID_PIOD 70 /* Parallel I/O Controller D */ +#define SAMA5D2_ID_SDMMC0_TIMER 71 /* Secure Data Memory Card Controller 0 */ +#define SAMA5D2_ID_SDMMC1_TIMER 72 /* Secure Data Memory Card Controller 1 */ +/* 73 */ +#define SAMA5D2_ID_SYS 74 /* System Controller Interrupt */ +#define SAMA5D2_ID_ACC 75 /* Analog Comparator */ +#define SAMA5D2_ID_RXLP 76 /* UART Low-Power */ +#define SAMA5D2_ID_SFRBU 77 /* Special Function Register BackUp */ +#define SAMA5D2_ID_CHIPID 78 /* Chip ID */ + +/* + * User Peripheral physical base addresses. + */ + +#define SAMA5D2_BASE_LCDC 0xf0000000 +#define SAMA5D2_BASE_XDMAC1 0xf0004000 +#define SAMA5D2_BASE_HXISI 0xf0008000 +#define SAMA5D2_BASE_MPDDRC 0xf000c000 +#define SAMA5D2_BASE_XDMAC0 0xf0010000 +#define SAMA5D2_BASE_PMC 0xf0014000 +#define SAMA5D2_BASE_MATRIX64 0xf0018000 /* MATRIX0 */ +#define SAMA5D2_BASE_AESB 0xf001c000 +#define SAMA5D2_BASE_QSPI0 0xf0020000 +#define SAMA5D2_BASE_QSPI1 0xf0024000 +#define SAMA5D2_BASE_SHA 0xf0028000 +#define SAMA5D2_BASE_AES 0xf002c000 + +#define SAMA5D2_BASE_SPI0 0xf8000000 +#define SAMA5D2_BASE_SSC0 0xf8004000 +#define SAMA5D2_BASE_GMAC 0xf8008000 +#define SAMA5D2_BASE_TC0 0xf800c000 +#define SAMA5D2_BASE_TC1 0xf8010000 +#define SAMA5D2_BASE_HSMC 0xf8014000 +#define SAMA5D2_BASE_PDMIC 0xf8018000 +#define SAMA5D2_BASE_UART0 0xf801c000 +#define SAMA5D2_BASE_UART1 0xf8020000 +#define SAMA5D2_BASE_UART2 0xf8024000 +#define SAMA5D2_BASE_TWI0 0xf8028000 +#define SAMA5D2_BASE_PWMC 0xf802c000 +#define SAMA5D2_BASE_SFR 0xf8030000 +#define SAMA5D2_BASE_FLEXCOM0 0xf8034000 +#define SAMA5D2_BASE_FLEXCOM1 0xf8038000 +#define SAMA5D2_BASE_SAIC 0xf803c000 +#define SAMA5D2_BASE_ICM 0xf8040000 +#define SAMA5D2_BASE_SECURAM 0xf8044000 +#define SAMA5D2_BASE_SYSC 0xf8048000 +#define SAMA5D2_BASE_ACC 0xf804a000 +#define SAMA5D2_BASE_SFC 0xf804c000 +#define SAMA5D2_BASE_I2SC0 0xf8050000 +#define SAMA5D2_BASE_CAN0 0xf8054000 + +#define SAMA5D2_BASE_SPI1 0xfc000000 +#define SAMA5D2_BASE_SSC1 0xfc004000 +#define SAMA5D2_BASE_UART3 0xfc008000 +#define SAMA5D2_BASE_UART4 0xfc00c000 +#define SAMA5D2_BASE_FLEXCOM2 0xfc010000 +#define SAMA5D2_BASE_FLEXCOM3 0xfc014000 +#define SAMA5D2_BASE_FLEXCOM4 0xfc018000 +#define SAMA5D2_BASE_TRNG 0xfc01c000 +#define SAMA5D2_BASE_AIC 0xfc020000 +#define SAMA5D2_BASE_TWI1 0xfc028000 +#define SAMA5D2_BASE_UDPHS 0xfc02c000 +#define SAMA5D2_BASE_ADC 0xfc030000 + +#define SAMA5D2_BASE_PIOA 0xfc038000 +#define SAMA5D2_BASE_MATRIX32 0xfc03c000 /* MATRIX1 */ +#define SAMA5D2_BASE_SECUMOD 0xfc040000 +#define SAMA5D2_BASE_TDES 0xfc044000 +#define SAMA5D2_BASE_CLASSD 0xfc048000 +#define SAMA5D2_BASE_I2SC1 0xfc04c000 +#define SAMA5D2_BASE_CAN1 0xfc050000 +#define SAMA5D2_BASE_SFRBU 0xfc05c000 +#define SAMA5D2_BASE_CHIPID 0xfc069000 + +/* + * Address Memory Space + */ +#define SAMA5D2_BASE_INTERNAL_MEM 0x00000000 +#define SAMA5D2_BASE_CS0 0x10000000 +#define SAMA5D2_BASE_DDRCS 0x20000000 +#define SAMA5D2_BASE_DDRCS_AES 0x40000000 +#define SAMA5D2_BASE_CS1 0x60000000 +#define SAMA5D2_BASE_CS2 0x70000000 +#define SAMA5D2_BASE_CS3 0x80000000 +#define SAMA5D2_BASE_QSPI0_AES_MEM 0x90000000 +#define SAMA5D2_BASE_QSPI1_AES_MEM 0x98000000 +#define SAMA5D2_BASE_SDHC0 0xa0000000 +#define SAMA5D2_BASE_SDHC1 0xb0000000 +#define SAMA5D2_BASE_NFC_CMD_REG 0xc0000000 +#define SAMA5D2_BASE_QSPI0_MEM 0xd0000000 +#define SAMA5D2_BASE_QSPI1_MEM 0xd8000000 +#define SAMA5D2_BASE_PERIPH 0xf0000000 + +/* + * Internal Memories + */ +#define SAMA5D2_BASE_ROM 0x00000000 /* ROM */ +#define SAMA5D2_BASE_ECC_ROM 0x00060000 /* ECC ROM */ +#define SAMA5D2_BASE_NFC_SRAM 0x00100000 /* NFC SRAM */ +#define SAMA5D2_BASE_SRAM0 0x00200000 /* SRAM0 */ +#define SAMA5D2_BASE_SRAM1 0x00220000 /* SRAM1 */ +#define SAMA5D2_BASE_UDPHS_SRAM 0x00300000 /* UDPHS RAM */ +#define SAMA5D2_BASE_UHP_OHCI 0x00400000 /* UHP OHCI */ +#define SAMA5D2_BASE_UHP_EHCI 0x00500000 /* UHP EHCI */ +#define SAMA5D2_BASE_AXI_MATRIX 0x00600000 /* AXI Maxtrix */ +#define SAMA5D2_BASE_DAP 0x00700000 /* DAP */ +#define SAMA5D2_BASE_PTC 0x00800000 /* PTC */ +#define SAMA5D2_BASE_L2CC 0x00A00000 /* L2CC */ + +/* + * Other misc defines + */ +#define SAMA5D2_BASE_PMECC (SAMA5D2_BASE_HSMC + 0x70) +#define SAMA5D2_BASE_PMERRLOC (SAMA5D2_BASE_HSMC + 0x500) + +#define SAMA5D2_PMECC (SAMA5D2_BASE_PMECC - SAMA5D2_BASE_SYS) +#define SAMA5D2_PMERRLOC (SAMA5D2_BASE_PMERRLOC - SAMA5D2_BASE_SYS) + +#define SAMA5D2_BASE_PIOB (SAMA5D2_BASE_PIOA + 0x40) +#define SAMA5D2_BASE_PIOC (SAMA5D2_BASE_PIOB + 0x40) +#define SAMA5D2_BASE_PIOD (SAMA5D2_BASE_PIOC + 0x40) + +/* SYSC spawns */ +#define SAMA5D2_BASE_RSTC SAMA5D2_BASE_SYSC +#define SAMA5D2_BASE_SHDC (SAMA5D2_BASE_SYSC + 0x10) +#define SAMA5D2_BASE_PITC (SAMA5D2_BASE_SYSC + 0x30) +#define SAMA5D2_BASE_WDT (SAMA5D2_BASE_SYSC + 0x40) +#define SAMA5D2_BASE_SCKCR (SAMA5D2_BASE_SYSC + 0x50) +#define SAMA5D2_BASE_RTCC (SAMA5D2_BASE_SYSC + 0xb0) + +#define SAMA5D2_BASE_SMC (SAMA5D2_BASE_HSMC + 0x700) + +#define SAMA5D2_NUM_PIO 4 +#define SAMA5D2_NUM_TWI 2 + +/* AICREDIR Unlock Key */ +#define SAMA5D2_AICREDIR_KEY 0xB6D81C4D + +/* + * Matrix Slaves ID + */ +/* MATRIX0(H64MX) Matrix Slaves */ +/* Bridge from H64MX to AXIMX (Internal ROM, Cryto Library, PKCC RAM) */ +#define SAMA5D2_H64MX_SLAVE_BRIDGE_TO_AXIMX 0 +#define SAMA5D2_H64MX_SLAVE_PERI_BRIDGE 1 /* H64MX Peripheral Bridge */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_0 2 /* DDR2 Port0-AESOTF */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_1 3 /* DDR2 Port1 */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_2 4 /* DDR2 Port2 */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_3 5 /* DDR2 Port3 */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_4 6 /* DDR2 Port4 */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_5 7 /* DDR2 Port5 */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_6 8 /* DDR2 Port6 */ +#define SAMA5D2_H64MX_SLAVE_DDR2_PORT_7 9 /* DDR2 Port7 */ +#define SAMA5D2_H64MX_SLAVE_INTERNAL_SRAM 10 /* Internal SRAM 128K */ +#define SAMA5D2_H64MX_SLAVE_CACHE_L2 11 /* Internal SRAM 128K (Cache L2) */ +#define SAMA5D2_H64MX_SLAVE_QSPI0 12 /* QSPI0 */ +#define SAMA5D2_H64MX_SLAVE_QSPI1 13 /* QSPI1 */ +#define SAMA5D2_H64MX_SLAVE_AESB 14 /* AESB */ + +/* MATRIX1(H32MX) Matrix Slaves */ +#define SAMA5D2_H32MX_BRIDGE_TO_H64MX 0 /* Bridge from H32MX to H64MX */ +#define SAMA5D2_H32MX_PERI_BRIDGE_0 1 /* H32MX Peripheral Bridge 0 */ +#define SAMA5D2_H32MX_PERI_BRIDGE_1 2 /* H32MX Peripheral Bridge 1 */ +#define SAMA5D2_H32MX_EXTERNAL_EBI 3 /* External Bus Interface */ +#define SAMA5D2_H32MX_NFC_CMD_REG 3 /* NFC command Register */ +#define SAMA5D2_H32MX_NFC_SRAM 4 /* NFC SRAM */ +#define SAMA5D2_H32MX_USB 5 + +#define SAMA5D2_SRAM_BASE SAMA5D2_BASE_SRAM0 +#define SAMA5D2_SRAM_SIZE (128 * SZ_1K) + +#endif diff --git a/arch/arm/mach-at91/include/mach/sama5d3.h b/arch/arm/mach-at91/include/mach/sama5d3.h index f0e5361..cd2102c 100644 --- a/arch/arm/mach-at91/include/mach/sama5d3.h +++ b/arch/arm/mach-at91/include/mach/sama5d3.h @@ -92,7 +92,7 @@ #define SAMA5D3_BASE_RSTC 0xfffffe00 #define SAMA5D3_BASE_PIT 0xfffffe30 #define SAMA5D3_BASE_WDT 0xfffffe40 - +#define SAMA5D3_BASE_PMC 0xfffffc00 #define SAMA5D3_BASE_PMECC 0xffffc070 #define SAMA5D3_BASE_PMERRLOC 0xffffc500 diff --git a/arch/arm/mach-at91/sam9_smc.c b/arch/arm/mach-at91/sam9_smc.c index a4d441f..05584c0 100644 --- a/arch/arm/mach-at91/sam9_smc.c +++ b/arch/arm/mach-at91/sam9_smc.c @@ -19,7 +19,8 @@ #define AT91_SAM9_SMC_CS_STRIDE 0x10 #define AT91_SAMA5_SMC_CS_STRIDE 0x14 -#define AT91_SMC_CS_STRIDE ((at91_soc_initdata.type == AT91_SOC_SAMA5D3 \ +#define AT91_SMC_CS_STRIDE ((at91_soc_initdata.type == AT91_SOC_SAMA5D2 \ + || at91_soc_initdata.type == AT91_SOC_SAMA5D3 \ || at91_soc_initdata.type == AT91_SOC_SAMA5D4) \ ? AT91_SAMA5_SMC_CS_STRIDE : AT91_SAM9_SMC_CS_STRIDE) #define AT91_SMC_CS(id, n) (smc_base_addr[id] + ((n) * AT91_SMC_CS_STRIDE)) @@ -32,6 +33,7 @@ void __iomem *mode_reg; switch (at91_soc_initdata.type) { + case AT91_SOC_SAMA5D2: case AT91_SOC_SAMA5D3: case AT91_SOC_SAMA5D4: mode_reg = base + AT91_SAMA5_SMC_MODE; @@ -106,6 +108,7 @@ void __iomem *mode_reg; switch (at91_soc_initdata.type) { + case AT91_SOC_SAMA5D2: case AT91_SOC_SAMA5D3: case AT91_SOC_SAMA5D4: mode_reg = base + AT91_SAMA5_SMC_MODE; diff --git a/arch/arm/mach-at91/setup.c b/arch/arm/mach-at91/setup.c index 4e30c78..b7a66aa 100644 --- a/arch/arm/mach-at91/setup.c +++ b/arch/arm/mach-at91/setup.c @@ -25,7 +25,7 @@ struct at91_socinfo at91_soc_initdata; EXPORT_SYMBOL(at91_soc_initdata); -static void __init soc_detect(u32 dbgu_base) +static void __init dbgu_soc_detect(u32 dbgu_base) { u32 cidr, socid; @@ -188,6 +188,84 @@ } } +static void __init chipid_soc_detect(u32 chipid_base) +{ + u32 cidr, socid; + + cidr = readl(chipid_base); + socid = cidr & AT91_CIDR_ARCH; + + if (!(cidr & AT91_CIDR_EXT)) + return; + + if (socid == (ARCH_ID_SAMA5 & AT91_CIDR_ARCH)) { + at91_soc_initdata.exid = readl(chipid_base + 4); + + switch (at91_soc_initdata.exid) { + case ARCH_EXID_SAMA5D21CU: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D21CU; + break; + case ARCH_EXID_SAMA5D225C_D1M: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D225C_D1M; + break; + case ARCH_EXID_SAMA5D22CU: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D22CU; + break; + case ARCH_EXID_SAMA5D22CN: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D22CN; + break; + case ARCH_EXID_SAMA5D23CU: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D23CU; + break; + case ARCH_EXID_SAMA5D24CX: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D24CX; + break; + case ARCH_EXID_SAMA5D24CU: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D24CU; + break; + case ARCH_EXID_SAMA5D26CU: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D26CU; + break; + case ARCH_EXID_SAMA5D27C_D1G: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D27C_D1G; + break; + case ARCH_EXID_SAMA5D27C_D5M: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D27C_D5M; + break; + case ARCH_EXID_SAMA5D27CU: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D27CU; + break; + case ARCH_EXID_SAMA5D27CN: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D27CN; + break; + case ARCH_EXID_SAMA5D28C_D1G: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D28C_D1G; + break; + case ARCH_EXID_SAMA5D28CU: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D28CU; + break; + case ARCH_EXID_SAMA5D28CN: + at91_soc_initdata.type = AT91_SOC_SAMA5D2; + at91_soc_initdata.subtype = AT91_SOC_SAMA5D28CN; + break; + } + } +} + static const char *soc_name[] = { [AT91_SOC_RM9200] = "at91rm9200", [AT91_SOC_SAM9260] = "at91sam9260", @@ -199,6 +277,7 @@ [AT91_SOC_SAM9RL] = "at91sam9rl", [AT91_SOC_SAM9X5] = "at91sam9x5", [AT91_SOC_SAM9N12] = "at91sam9n12", + [AT91_SOC_SAMA5D2] = "sama5d2", [AT91_SOC_SAMA5D3] = "sama5d3", [AT91_SOC_SAMA5D4] = "sama5d4", [AT91_SOC_NONE] = "Unknown" @@ -226,6 +305,21 @@ [AT91_SOC_SAM9N12] = "at91sam9n12", [AT91_SOC_SAM9CN11] = "at91sam9cn11", [AT91_SOC_SAM9CN12] = "at91sam9cn12", + [AT91_SOC_SAMA5D21CU] = "sama5d21cu", + [AT91_SOC_SAMA5D225C_D1M] = "sama5d225c_d1m", + [AT91_SOC_SAMA5D22CU] = "sama5d22cu", + [AT91_SOC_SAMA5D22CN] = "sama5d22cn", + [AT91_SOC_SAMA5D23CU] = "sama5d23cu", + [AT91_SOC_SAMA5D24CX] = "sama5d24cx", + [AT91_SOC_SAMA5D24CU] = "sama5d24cu", + [AT91_SOC_SAMA5D26CU] = "sama5d26cu", + [AT91_SOC_SAMA5D27C_D1G] = "sama5d27c_d1g", + [AT91_SOC_SAMA5D27C_D5M] = "sama5d27c_d5m", + [AT91_SOC_SAMA5D27CU] = "sama5d27cu", + [AT91_SOC_SAMA5D27CN] = "sama5d27cn", + [AT91_SOC_SAMA5D28C_D1G] = "sama5d28c_d1g", + [AT91_SOC_SAMA5D28CU] = "sama5d28cu", + [AT91_SOC_SAMA5D28CN] = "sama5d28cn", [AT91_SOC_SAMA5D31] = "sama5d31", [AT91_SOC_SAMA5D33] = "sama5d33", [AT91_SOC_SAMA5D34] = "sama5d34", @@ -249,11 +343,13 @@ at91_soc_initdata.type = AT91_SOC_NONE; at91_soc_initdata.subtype = AT91_SOC_SUBTYPE_NONE; - soc_detect(AT91_BASE_DBGU0); + dbgu_soc_detect(AT91_BASE_DBGU0); if (!at91_soc_is_detected()) - soc_detect(AT91_BASE_DBGU1); + dbgu_soc_detect(AT91_BASE_DBGU1); if (!at91_soc_is_detected()) - soc_detect(AT91_BASE_DBGU2); + dbgu_soc_detect(AT91_BASE_DBGU2); + if (!at91_soc_is_detected()) + chipid_soc_detect(0xfc069000); if (!at91_soc_is_detected()) panic("AT91: Impossible to detect the SOC type"); diff --git a/common/Kconfig b/common/Kconfig index cafaadb..d98ea50 100644 --- a/common/Kconfig +++ b/common/Kconfig @@ -1274,8 +1274,9 @@ default 0xfffff200 if SOC_AT91RM9200 || SOC_AT91SAM9260 \ || SOC_AT91SAM9261 || SOC_AT91SAM9X5 \ || SOC_AT91SAM9N12 - default 0xffffee00 if SOC_AT91SAM9263 || SOC_AT91SAM9G45 || ARCH_SAMA5D3 - default 0xfc069000 if ARCH_SAMA5D4 + default 0xffffee00 if SOC_AT91SAM9263 || SOC_AT91SAM9G45 || SOC_SAMA5D3 + default 0xfc069000 if SOC_SAMA5D4 + default 0xf8020000 if SOC_SAMA5D2 default 0xfffff200 depends on ARCH_AT91 help diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig index e2fb0af..95c6708 100644 --- a/drivers/pinctrl/Kconfig +++ b/drivers/pinctrl/Kconfig @@ -17,6 +17,16 @@ help The pinmux controller found on AT91 SoCs. +config PINCTRL_AT91PIO4 + bool "AT91 PIO4 pinctrl driver" + depends on OFDEVICE + depends on ARCH_AT91 + select GPIOLIB + select OF_GPIO + help + Say Y here to enable the at91 pinctrl/gpio driver for Atmel PIO4 + controller available on sama5d2 SoC. + config PINCTRL_BCM283X bool "GPIO and pinmux support for BCM283X" depends on ARCH_BCM283X diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile index e311df7..e7d8ad8 100644 --- a/drivers/pinctrl/Makefile +++ b/drivers/pinctrl/Makefile @@ -1,5 +1,6 @@ obj-$(CONFIG_PINCTRL) += pinctrl.o obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o +obj-$(CONFIG_PINCTRL_AT91PIO4) += pinctrl-at91-pio4.o obj-$(CONFIG_PINCTRL_BCM283X) += pinctrl-bcm2835.o obj-pbl-$(CONFIG_PINCTRL_IMX_IOMUX_V1) += imx-iomux-v1.o obj-$(CONFIG_PINCTRL_IMX_IOMUX_V2) += imx-iomux-v2.o diff --git a/drivers/pinctrl/pinctrl-at91-pio4.c b/drivers/pinctrl/pinctrl-at91-pio4.c new file mode 100644 index 0000000..9bc259f --- /dev/null +++ b/drivers/pinctrl/pinctrl-at91-pio4.c @@ -0,0 +1,320 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * sama5d2 pin control and GPIO chip driver + * Copyright (c) 2019 Ahmad Fatoum, Pengutronix + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#define ATMEL_GET_PIN_NO(pinfunc) ((pinfunc) & 0xff) +#define ATMEL_GET_PIN_FUNC(pinfunc) ((pinfunc >> 16) & 0xf) +#define ATMEL_GET_PIN_IOSET(pinfunc) ((pinfunc >> 20) & 0xf) + +struct pinctrl_at91_pio4 { + void __iomem *base; + struct pinctrl_device pinctrl; + struct gpio_chip gpiochip; +}; + +struct at91_pinctrl_data { + unsigned nbanks; +}; + +static inline void __iomem *pin_to_pio4(struct pinctrl_device *pdev, + unsigned int *pin) +{ + void __iomem *pio; + struct pinctrl_at91_pio4 *pinctrl = + container_of(pdev, struct pinctrl_at91_pio4, pinctrl); + + pio = pinctrl->base + (*pin / 32) * 0x40; + *pin %= 32; + + return pio; +} + +static int __pinctrl_at91_pio4_set_state(struct pinctrl_device *pdev, + struct device_node *np) +{ + u32 drive_strength, enable = 0, disable = ~0; + int output = -1; + + int npins, i; + int ret; + + ret = of_property_read_u32(np, "drive-strength", &drive_strength); + if (!ret && ATMEL_PIO_DRVSTR_LO <= drive_strength + && drive_strength <= ATMEL_PIO_DRVSTR_HI) { + disable &= ~PIO4_DRVSTR_MASK; + enable |= drive_strength << PIO4_DRVSTR_OFFSET; + } + + if (of_get_property(np, "bias-disable", NULL)) { + disable &= ~PIO4_PUEN_MASK; + disable &= ~PIO4_PDEN_MASK; + } + + if (of_get_property(np, "bias-pull-up", NULL)) { + enable |= PIO4_PUEN_MASK; + disable &= ~PIO4_PDEN_MASK; + } + + if (of_get_property(np, "bias-pull-down", NULL)) { + enable |= PIO4_PDEN_MASK; + disable &= ~PIO4_PUEN_MASK; + } + + if (of_get_property(np, "drive-open-drain", NULL)) + enable |= PIO4_OPD_MASK; + + if (of_get_property(np, "input-schmitt-enable", NULL)) + enable |= PIO4_SCHMITT_MASK; + + if (of_get_property(np, "input-enable", NULL)) + disable &= ~PIO4_DIR_MASK; + + if (of_get_property(np, "output-enable", NULL)) + enable |= PIO4_DIR_MASK; + + if (of_get_property(np, "output-low", NULL)) + output = GPIOF_OUT_INIT_LOW; + + if (of_get_property(np, "output-high", NULL)) + output = GPIOF_OUT_INIT_HIGH; + + of_get_property(np, "pinmux", &npins); + npins /= sizeof(__be32); + + if (!npins) { + dev_err(pdev->dev, "Invalid pinmux property in %s\n", + np->full_name); + return -EINVAL; + } + + for (i = 0; i < npins; i++) { + void __iomem *pio; + u32 conf, no, func, cfgr; + + ret = of_property_read_u32_index(np, "pinmux", i, &conf); + if (ret) + return ret; + + no = ATMEL_GET_PIN_NO(conf); + func = ATMEL_GET_PIN_FUNC(conf); + + pio = pin_to_pio4(pdev, &no); + + if (output == GPIOF_OUT_INIT_HIGH) + at91_mux_gpio4_set(pio, BIT(no), true); + + if (output == GPIOF_OUT_INIT_LOW) + at91_mux_gpio4_set(pio, BIT(no), false); + + writel(BIT(no), pio + PIO4_MSKR); + cfgr = readl(pio + PIO4_CFGR); + cfgr &= disable; + cfgr |= enable; + writel(func | cfgr, pio + PIO4_CFGR); + } + + return 0; +} + +static int pinctrl_at91_pio4_set_state(struct pinctrl_device *pdev, + struct device_node *np) +{ + struct device_node *child; + void *prop; + int ret; + + prop = of_find_property(np, "pinmux", NULL); + if (prop) + return __pinctrl_at91_pio4_set_state(pdev, np); + + for_each_child_of_node(np, child) { + ret = __pinctrl_at91_pio4_set_state(pdev, child); + if (ret) + return ret; + } + + return 0; +} + +static inline void __iomem *pin_to_gpio4(struct gpio_chip *chip, unsigned int *pin) +{ + void __iomem *gpio; + struct pinctrl_at91_pio4 *pinctrl = + container_of(chip, struct pinctrl_at91_pio4, gpiochip); + + gpio = pinctrl->base + (*pin / 32) * 0x40; + *pin %= 32; + + return gpio; +} + +static int at91_gpio4_direction_input(struct gpio_chip *chip, unsigned offset) +{ + void __iomem *gpio = pin_to_gpio4(chip, &offset); + + at91_mux_gpio4_input(gpio, BIT(offset), true); + + return 0; +} + +static int at91_gpio4_direction_output(struct gpio_chip *chip, unsigned offset, + int value) +{ + void __iomem *gpio = pin_to_gpio4(chip, &offset); + + at91_mux_gpio4_set(gpio, BIT(offset), value); + at91_mux_gpio4_input(gpio, BIT(offset), false); + + return 0; +} + +static int at91_gpio4_request(struct gpio_chip *chip, unsigned offset) +{ + void __iomem *gpio = pin_to_gpio4(chip, &offset); + + at91_mux_gpio4_enable(gpio, BIT(offset)); + + return 0; +} + +static int at91_gpio4_get_direction(struct gpio_chip *chip, + unsigned int offset) +{ + u32 cfgr; + void __iomem *gpio = pin_to_gpio4(chip, &offset); + + writel(BIT(offset), gpio + PIO4_MSKR); + cfgr = readl(gpio + PIO4_CFGR); + + return cfgr & PIO4_DIR_MASK ? GPIOF_DIR_OUT : GPIOF_DIR_IN; +} + +static void at91_gpio4_set(struct gpio_chip *chip, unsigned offset, int value) +{ + void __iomem *gpio = pin_to_gpio4(chip, &offset); + + at91_mux_gpio4_set(gpio, BIT(offset), value); +} + +static int at91_gpio4_get(struct gpio_chip *chip, unsigned offset) +{ + void __iomem *gpio = pin_to_gpio4(chip, &offset); + + return at91_mux_gpio4_get(gpio, BIT(offset)); +} + +static struct gpio_ops at91_gpio4_ops = { + .request = at91_gpio4_request, + .direction_input = at91_gpio4_direction_input, + .direction_output = at91_gpio4_direction_output, + .get_direction = at91_gpio4_get_direction, + .get = at91_gpio4_get, + .set = at91_gpio4_set, +}; + +static int pinctrl_at91_pio4_gpiochip_add(struct device_d *dev, + struct pinctrl_at91_pio4 *pinctrl) +{ + struct at91_pinctrl_data *drvdata; + struct clk *clk; + int ret; + + clk = clk_get(dev, NULL); + if (IS_ERR(clk)) { + ret = PTR_ERR(clk); + dev_err(dev, "clock not found: %d\n", ret); + return ret; + } + + ret = clk_enable(clk); + if (ret < 0) { + dev_err(dev, "clock failed to enable: %d\n", ret); + clk_put(clk); + return ret; + } + + dev_get_drvdata(dev, (const void **)&drvdata); + + pinctrl->gpiochip.ops = &at91_gpio4_ops; + pinctrl->gpiochip.base = 0; + pinctrl->gpiochip.ngpio = drvdata->nbanks * MAX_NB_GPIO_PER_BANK; + pinctrl->gpiochip.dev = dev; + + ret = gpiochip_add(&pinctrl->gpiochip); + if (ret) { + dev_err(dev, "couldn't add gpiochip, ret = %d\n", ret); + return ret; + } + + dev_info(dev, "gpio driver registered\n"); + + return 0; +} + +static struct pinctrl_ops pinctrl_at91_pio4_ops = { + .set_state = pinctrl_at91_pio4_set_state, +}; + +static int pinctrl_at91_pio4_probe(struct device_d *dev) +{ + struct device_node *np = dev->device_node; + struct pinctrl_at91_pio4 *pinctrl; + struct resource *io; + int ret; + + pinctrl = xzalloc(sizeof(*pinctrl)); + + io = dev_request_mem_resource(dev, 0); + if (IS_ERR(io)) + return PTR_ERR(io); + + pinctrl->base = IOMEM(io->start); + pinctrl->pinctrl.dev = dev; + pinctrl->pinctrl.ops = &pinctrl_at91_pio4_ops; + + ret = pinctrl_register(&pinctrl->pinctrl); + if (ret) + return ret; + + dev_info(dev, "pinctrl driver registered\n"); + + if (of_get_property(np, "gpio-controller", NULL)) + return pinctrl_at91_pio4_gpiochip_add(dev, pinctrl); + + return 0; +} + +static const struct at91_pinctrl_data sama5d2_pinctrl_data = { + .nbanks = 4, +}; + +static __maybe_unused struct of_device_id pinctrl_at91_pio4_dt_ids[] = { + { .compatible = "atmel,sama5d2-pinctrl", .data = &sama5d2_pinctrl_data }, + { /* sentinel */ } +}; + +static struct driver_d pinctrl_at91_pio4_driver = { + .name = "pinctrl-at91-pio4", + .probe = pinctrl_at91_pio4_probe, + .of_compatible = DRV_OF_COMPAT(pinctrl_at91_pio4_dt_ids), +}; + +static int pinctrl_at91_pio4_init(void) +{ + return platform_driver_register(&pinctrl_at91_pio4_driver); +} +core_initcall(pinctrl_at91_pio4_init); diff --git a/drivers/pinctrl/pinctrl-at91.c b/drivers/pinctrl/pinctrl-at91.c index 9b366e4..0da6332 100644 --- a/drivers/pinctrl/pinctrl-at91.c +++ b/drivers/pinctrl/pinctrl-at91.c @@ -152,6 +152,8 @@ return -EINVAL; at91_gpio->ops->mux_D_periph(pio, mask); break; + default: + return -EINVAL; } if (mux) at91_mux_gpio_disable(pio, mask); diff --git a/drivers/usb/gadget/Kconfig b/drivers/usb/gadget/Kconfig index ca1bfc1..9d6a262 100644 --- a/drivers/usb/gadget/Kconfig +++ b/drivers/usb/gadget/Kconfig @@ -19,7 +19,6 @@ bool prompt "at91 gadget driver" depends on ARCH_AT91 - depends on !ARCH_SAMA5D4 default y select USB_GADGET_DUALSPEED diff --git a/drivers/usb/gadget/at91_udc.c b/drivers/usb/gadget/at91_udc.c index efbc574..4114646 100644 --- a/drivers/usb/gadget/at91_udc.c +++ b/drivers/usb/gadget/at91_udc.c @@ -31,9 +31,7 @@ #include #include -#if defined CONFIG_ARCH_AT91SAM9261 || defined CONFIG_ARCH_AT91SAM9G10 #include -#endif #include #include #include @@ -693,12 +691,10 @@ txvc |= AT91_UDP_TXVC_PUON; at91_udp_write(udc, AT91_UDP_TXVC, txvc); } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { -#if defined CONFIG_ARCH_AT91SAM9261 || defined CONFIG_ARCH_AT91SAM9G10 u32 usbpucr; usbpucr = readl(AT91SAM9261_BASE_MATRIX + AT91SAM9261_MATRIX_USBPUCR); usbpucr |= AT91SAM9261_MATRIX_USBPUCR_PUON; writel(usbpucr, AT91SAM9261_BASE_MATRIX + AT91SAM9261_MATRIX_USBPUCR); -#endif } } else { stop_activity(udc); @@ -712,12 +708,10 @@ txvc &= ~AT91_UDP_TXVC_PUON; at91_udp_write(udc, AT91_UDP_TXVC, txvc); } else if (cpu_is_at91sam9261() || cpu_is_at91sam9g10()) { -#if defined CONFIG_ARCH_AT91SAM9261 || defined CONFIG_ARCH_AT91SAM9G10 u32 usbpucr; usbpucr = readl(AT91SAM9261_BASE_MATRIX + AT91SAM9261_MATRIX_USBPUCR); usbpucr &= ~AT91SAM9261_MATRIX_USBPUCR_PUON; writel(usbpucr, AT91SAM9261_BASE_MATRIX + AT91SAM9261_MATRIX_USBPUCR); -#endif } clk_off(udc); } diff --git a/images/Makefile.at91 b/images/Makefile.at91 index acdb591..f321bde 100644 --- a/images/Makefile.at91 +++ b/images/Makefile.at91 @@ -13,3 +13,7 @@ pblb-$(CONFIG_MACH_MICROCHIP_KSZ9477_EVB) += start_sama5d3_xplained_ung8071 FILE_barebox-microchip-ksz9477-evb.img = start_sama5d3_xplained_ung8071.pblb image-$(CONFIG_MACH_MICROCHIP_KSZ9477_EVB) += barebox-microchip-ksz9477-evb.img + +pblb-$(CONFIG_MACH_SAMA5D27_SOM1) += start_sama5d27_som1_ek +FILE_barebox-sama5d27-som1-ek.img = start_sama5d27_som1_ek.pblb +image-$(CONFIG_MACH_SAMA5D27_SOM1) += barebox-sama5d27-som1-ek.img