diff options
Diffstat (limited to 'arch/arm')
46 files changed, 4933 insertions, 15 deletions
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index e16fe03887..ded8cfee09 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -767,6 +767,17 @@ config ARCH_INTEGRATOR select PL01X_SERIAL imply CMD_DM +config ARCH_IPQ40XX + bool "Qualcomm IPQ40xx SoCs" + select CPU_V7A + select DM + select DM_GPIO + select DM_SERIAL + select PINCTRL + select CLK + select OF_CONTROL + imply CMD_DM + config ARCH_KEYSTONE bool "TI Keystone" select CMD_POWEROFF @@ -905,6 +916,11 @@ config ARCH_MX5 select CPU_V7A imply MXC_GPIO +config ARCH_NEXELL + bool "Nexell S5P4418/S5P6818 SoC" + select ENABLE_ARM_SOC_BOOT0_HOOK + select DM + config ARCH_OWL bool "Actions Semi OWL SoCs" select DM @@ -1793,6 +1809,8 @@ source "arch/arm/mach-highbank/Kconfig" source "arch/arm/mach-integrator/Kconfig" +source "arch/arm/mach-ipq40xx/Kconfig" + source "arch/arm/mach-k3/Kconfig" source "arch/arm/mach-keystone/Kconfig" @@ -1879,6 +1897,8 @@ source "arch/arm/cpu/armv8/Kconfig" source "arch/arm/mach-imx/Kconfig" +source "arch/arm/mach-nexell/Kconfig" + source "board/bosch/shc/Kconfig" source "board/bosch/guardian/Kconfig" source "board/CarMediaLab/flea3/Kconfig" diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 94eb50bf72..bf3890e99b 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -58,6 +58,7 @@ machine-$(CONFIG_ARCH_BCMSTB) += bcmstb machine-$(CONFIG_ARCH_DAVINCI) += davinci machine-$(CONFIG_ARCH_EXYNOS) += exynos machine-$(CONFIG_ARCH_HIGHBANK) += highbank +machine-$(CONFIG_ARCH_IPQ40XX) += ipq40xx machine-$(CONFIG_ARCH_K3) += k3 machine-$(CONFIG_ARCH_KEYSTONE) += keystone machine-$(CONFIG_ARCH_KIRKWOOD) += kirkwood @@ -65,6 +66,7 @@ machine-$(CONFIG_ARCH_LPC32XX) += lpc32xx machine-$(CONFIG_ARCH_MEDIATEK) += mediatek machine-$(CONFIG_ARCH_MESON) += meson machine-$(CONFIG_ARCH_MVEBU) += mvebu +machine-$(CONFIG_ARCH_NEXELL) += nexell machine-$(CONFIG_ARCH_OMAP2PLUS) += omap2 machine-$(CONFIG_ARCH_ORION5X) += orion5x machine-$(CONFIG_ARCH_OWL) += owl diff --git a/arch/arm/cpu/armv7/Makefile b/arch/arm/cpu/armv7/Makefile index 8c955d0d52..0e83e394d5 100644 --- a/arch/arm/cpu/armv7/Makefile +++ b/arch/arm/cpu/armv7/Makefile @@ -42,3 +42,5 @@ obj-$(CONFIG_RMOBILE) += rmobile/ obj-$(if $(filter stv0991,$(SOC)),y) += stv0991/ obj-$(CONFIG_ARCH_SUNXI) += sunxi/ obj-$(CONFIG_VF610) += vf610/ +obj-$(CONFIG_ARCH_S5P4418) += s5p4418/ +obj-$(CONFIG_ARCH_NEXELL) += s5p-common/ diff --git a/arch/arm/cpu/armv7/s5p-common/Makefile b/arch/arm/cpu/armv7/s5p-common/Makefile index 12cf804e88..bfe02389cd 100644 --- a/arch/arm/cpu/armv7/s5p-common/Makefile +++ b/arch/arm/cpu/armv7/s5p-common/Makefile @@ -3,9 +3,14 @@ # Copyright (C) 2009 Samsung Electronics # Minkyu Kang <mk7.kang@samsung.com> -obj-y += cpu_info.o +ifdef CONFIG_ARCH_NEXELL +obj-$(CONFIG_PWM_NX) += pwm.o +obj-$(CONFIG_S5P4418_ONEWIRE) += pwm.o +else +obj-y += cpu_info.o ifndef CONFIG_SPL_BUILD -obj-y += timer.o -obj-y += sromc.o -obj-$(CONFIG_PWM) += pwm.o +obj-y += timer.o +obj-y += sromc.o +obj-$(CONFIG_PWM) += pwm.o +endif endif diff --git a/arch/arm/cpu/armv7/s5p-common/pwm.c b/arch/arm/cpu/armv7/s5p-common/pwm.c index 6b9e865803..aef2e5574b 100644 --- a/arch/arm/cpu/armv7/s5p-common/pwm.c +++ b/arch/arm/cpu/armv7/s5p-common/pwm.c @@ -15,7 +15,11 @@ int pwm_enable(int pwm_id) { const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned long tcon; tcon = readl(&pwm->tcon); @@ -29,7 +33,11 @@ int pwm_enable(int pwm_id) void pwm_disable(int pwm_id) { const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned long tcon; tcon = readl(&pwm->tcon); @@ -43,14 +51,43 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq) unsigned long tin_parent_rate; unsigned int div; +#if defined(CONFIG_ARCH_NEXELL) + unsigned int pre_div; + const struct s5p_timer *pwm = + (struct s5p_timer *)PHY_BASEADDR_PWM; + unsigned int val; + struct clk *clk = clk_get(CORECLK_NAME_PCLK); + + tin_parent_rate = clk_get_rate(clk); +#else tin_parent_rate = get_pwm_clk(); +#endif + +#if defined(CONFIG_ARCH_NEXELL) + writel(0, &pwm->tcfg0); + val = readl(&pwm->tcfg0); + + if (pwm_id < 2) + div = ((val >> 0) & 0xff) + 1; + else + div = ((val >> 8) & 0xff) + 1; + writel(0, &pwm->tcfg1); + val = readl(&pwm->tcfg1); + val = (val >> MUX_DIV_SHIFT(pwm_id)) & 0xF; + pre_div = (1UL << val); + + freq = tin_parent_rate / div / pre_div; + + return freq; +#else for (div = 2; div <= 16; div *= 2) { if ((tin_parent_rate / (div << 16)) < freq) return tin_parent_rate / div; } return tin_parent_rate / 16; +#endif } #define NS_IN_SEC 1000000000UL @@ -58,7 +95,11 @@ static unsigned long pwm_calc_tin(int pwm_id, unsigned long freq) int pwm_config(int pwm_id, int duty_ns, int period_ns) { const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned int offset; unsigned long tin_rate; unsigned long tin_ns; @@ -84,7 +125,12 @@ int pwm_config(int pwm_id, int duty_ns, int period_ns) tin_rate = pwm_calc_tin(pwm_id, frequency); tin_ns = NS_IN_SEC / tin_rate; - tcnt = period_ns / tin_ns; + + if (IS_ENABLED(CONFIG_ARCH_NEXELL)) + /* The counter starts at zero. */ + tcnt = (period_ns / tin_ns) - 1; + else + tcnt = period_ns / tin_ns; /* Note, counters count down */ tcmp = duty_ns / tin_ns; @@ -115,7 +161,11 @@ int pwm_init(int pwm_id, int div, int invert) { u32 val; const struct s5p_timer *pwm = +#if defined(CONFIG_ARCH_NEXELL) + (struct s5p_timer *)PHY_BASEADDR_PWM; +#else (struct s5p_timer *)samsung_get_base_timer(); +#endif unsigned long ticks_per_period; unsigned int offset, prescaler; @@ -148,7 +198,12 @@ int pwm_init(int pwm_id, int div, int invert) ticks_per_period = -1UL; } else { const unsigned long pwm_hz = 1000; +#if defined(CONFIG_ARCH_NEXELL) + struct clk *clk = clk_get(CORECLK_NAME_PCLK); + unsigned long timer_rate_hz = clk_get_rate(clk) / +#else unsigned long timer_rate_hz = get_pwm_clk() / +#endif ((prescaler + 1) * (1 << div)); ticks_per_period = timer_rate_hz / pwm_hz; diff --git a/arch/arm/cpu/armv7/s5p4418/Makefile b/arch/arm/cpu/armv7/s5p4418/Makefile new file mode 100644 index 0000000000..321b257b6d --- /dev/null +++ b/arch/arm/cpu/armv7/s5p4418/Makefile @@ -0,0 +1,6 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2016 Nexell +# Hyunseok, Jung <hsjung@nexell.co.kr> + +obj-y += cpu.o diff --git a/arch/arm/cpu/armv7/s5p4418/cpu.c b/arch/arm/cpu/armv7/s5p4418/cpu.c new file mode 100644 index 0000000000..8add9474ad --- /dev/null +++ b/arch/arm/cpu/armv7/s5p4418/cpu.c @@ -0,0 +1,121 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Hyunseok, Jung <hsjung@nexell.co.kr> + */ + +#include <common.h> +#include <command.h> +#include <asm/system.h> +#include <asm/cache.h> +#include <asm/sections.h> +#include <asm/io.h> +#include <asm/arch/nexell.h> +#include <asm/arch/clk.h> +#include <asm/arch/reset.h> +#include <asm/arch/tieoff.h> +#include <cpu_func.h> +#include <linux/delay.h> + +DECLARE_GLOBAL_DATA_PTR; + +#ifndef CONFIG_ARCH_CPU_INIT +#error must be define the macro "CONFIG_ARCH_CPU_INIT" +#endif + +void s_init(void) +{ +} + +static void cpu_soc_init(void) +{ + /* + * NOTE> ALIVE Power Gate must enable for Alive register access. + * must be clear wfi jump address + */ + writel(1, ALIVEPWRGATEREG); + writel(0xFFFFFFFF, SCR_ARM_SECOND_BOOT); + + /* write 0xf0 on alive scratchpad reg for boot success check */ + writel(readl(SCR_SIGNAGURE_READ) | 0xF0, (SCR_SIGNAGURE_SET)); + + /* set l2 cache tieoff */ + nx_tieoff_set(NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_0, 1); + nx_tieoff_set(NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_1, 1); +} + +#ifdef CONFIG_PL011_SERIAL +static void serial_device_init(void) +{ + char dev[10]; + int id; + + sprintf(dev, "nx-uart.%d", CONFIG_CONS_INDEX); + id = RESET_ID_UART0 + CONFIG_CONS_INDEX; + + struct clk *clk = clk_get((const char *)dev); + + /* reset control: Low active ___|--- */ + nx_rstcon_setrst(id, RSTCON_ASSERT); + udelay(10); + nx_rstcon_setrst(id, RSTCON_NEGATE); + udelay(10); + + /* set clock */ + clk_disable(clk); + clk_set_rate(clk, CONFIG_PL011_CLOCK); + clk_enable(clk); +} +#endif + +int arch_cpu_init(void) +{ + flush_dcache_all(); + cpu_soc_init(); + clk_init(); + + if (IS_ENABLED(CONFIG_PL011_SERIAL)) + serial_device_init(); + + return 0; +} + +#if defined(CONFIG_DISPLAY_CPUINFO) +int print_cpuinfo(void) +{ + return 0; +} +#endif + +void reset_cpu(ulong ignored) +{ + void *clkpwr_reg = (void *)PHY_BASEADDR_CLKPWR; + const u32 sw_rst_enb_bitpos = 3; + const u32 sw_rst_enb_mask = 1 << sw_rst_enb_bitpos; + const u32 sw_rst_bitpos = 12; + const u32 sw_rst_mask = 1 << sw_rst_bitpos; + int pwrcont = 0x224; + int pwrmode = 0x228; + u32 read_value; + + read_value = readl((void *)(clkpwr_reg + pwrcont)); + + read_value &= ~sw_rst_enb_mask; + read_value |= 1 << sw_rst_enb_bitpos; + + writel(read_value, (void *)(clkpwr_reg + pwrcont)); + writel(sw_rst_mask, (void *)(clkpwr_reg + pwrmode)); +} + +void enable_caches(void) +{ + /* Enable D-cache. I-cache is already enabled in start.S */ + dcache_enable(); +} + +#if defined(CONFIG_ARCH_MISC_INIT) +int arch_misc_init(void) +{ + return 0; +} +#endif /* CONFIG_ARCH_MISC_INIT */ diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index f01eb7bf5f..caa7756c5d 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -147,6 +147,9 @@ dtb-$(CONFIG_ROCKCHIP_RV1108) += \ rv1108-elgin-r1.dtb \ rv1108-evb.dtb +dtb-$(CONFIG_ARCH_S5P4418) += \ + s5p4418-nanopi2.dtb + dtb-$(CONFIG_ARCH_MESON) += \ meson-gxbb-nanopi-k2.dtb \ meson-gxbb-odroidc2.dtb \ @@ -946,6 +949,7 @@ dtb-$(CONFIG_SOC_K3_J721E) += k3-j721e-common-proc-board.dtb \ dtb-$(CONFIG_ARCH_MEDIATEK) += \ mt7622-rfb.dtb \ + mt7623a-unielec-u7623-02-emmc.dtb \ mt7623n-bananapi-bpi-r2.dtb \ mt7629-rfb.dtb \ mt8512-bm1-emmc.dtb \ diff --git a/arch/arm/dts/mt7623a-unielec-u7623-02-emmc.dts b/arch/arm/dts/mt7623a-unielec-u7623-02-emmc.dts new file mode 100644 index 0000000000..fdeec75b05 --- /dev/null +++ b/arch/arm/dts/mt7623a-unielec-u7623-02-emmc.dts @@ -0,0 +1,211 @@ +/* + * Copyright (C) 2018 MediaTek Inc. + * Author: Ryder Lee <ryder.lee@mediatek.com> + * + * SPDX-License-Identifier: (GPL-2.0 OR MIT) + */ + +/dts-v1/; +#include "mt7623.dtsi" +#include "mt7623-u-boot.dtsi" + +/ { + model = "UniElec U7623-02 eMMC"; + compatible = "unielec,u7623-02-emmc", "mediatek,mt7623"; + + memory@80000000 { + device_type = "memory"; + reg = <0 0x80000000 0 0x20000000>; + }; + + chosen { + stdout-path = &uart2; + tick-timer = &timer0; + }; + + reg_1p8v: regulator-1p8v { + compatible = "regulator-fixed"; + regulator-name = "fixed-1.8V"; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_3p3v: regulator-3p3v { + compatible = "regulator-fixed"; + regulator-name = "fixed-3.3V"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + regulator-boot-on; + regulator-always-on; + }; + + reg_5v: regulator-5v { + compatible = "regulator-fixed"; + regulator-name = "fixed-5V"; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + regulator-boot-on; + regulator-always-on; + }; + + leds { + compatible = "gpio-leds"; + + led3 { + label = "u7623-01:green:led3"; + gpios = <&gpio 14 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + + led4 { + label = "u7623-01:green:led4"; + gpios = <&gpio 15 GPIO_ACTIVE_LOW>; + default-state = "off"; + }; + }; +}; + +ð { + status = "okay"; + mediatek,gmac-id = <0>; + phy-mode = "rgmii"; + mediatek,switch = "mt7530"; + mediatek,mcm; + + fixed-link { + speed = <1000>; + full-duplex; + }; +}; + +&mmc0 { + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_pins_default>; + status = "okay"; + bus-width = <8>; + max-frequency = <50000000>; + cap-mmc-highspeed; + vmmc-supply = <®_3p3v>; + vqmmc-supply = <®_1p8v>; + non-removable; +}; + +&pinctrl { + ephy_default: ephy_default { + mux { + function = "eth"; + groups = "mdc_mdio", "ephy"; + }; + + conf { + pins = "G2_TXEN", "G2_TXD0", "G2_TXD1", "G2_TXD2", + "G2_TXD3", "G2_TXC", "G2_RXC", "G2_RXD0", + "G2_RXD1", "G2_RXD2", "G2_RXD3", "G2_RXDV", + "MDC", "MDIO"; + drive-strength = <12>; + mediatek,tdsel = <5>; + }; + }; + + mmc0_pins_default: mmc0default { + mux { + function = "msdc"; + groups = "msdc0"; + }; + + conf-cmd-data { + pins = "MSDC0_CMD", "MSDC0_DAT0", "MSDC0_DAT1", + "MSDC0_DAT2", "MSDC0_DAT3", "MSDC0_DAT4", + "MSDC0_DAT5", "MSDC0_DAT6", "MSDC0_DAT7"; + input-enable; + bias-pull-up; + }; + + conf-clk { + pins = "MSDC0_CLK"; + bias-pull-down; + }; + + conf-rst { + pins = "MSDC0_RSTB"; + bias-pull-up; + }; + }; + + pcie_default: pcie-default { + mux { + function = "pcie"; + groups = "pcie0_0_perst", "pcie1_0_perst"; + }; + }; + + uart0_pins_a: uart0-default { + mux { + function = "uart"; + groups = "uart0_0_txd_rxd"; + }; + }; + + uart1_pins_a: uart1-default { + mux { + function = "uart"; + groups = "uart1_0_txd_rxd"; + }; + }; + + uart2_pins_a: uart2-default { + mux { + function = "uart"; + groups = "uart2_0_txd_rxd"; + }; + }; + + uart2_pins_b: uart2-alt { + mux { + function = "uart"; + groups = "uart2_1_txd_rxd"; + }; + }; +}; + +&pcie { + pinctrl-names = "default"; + pinctrl-0 = <&pcie_default>; + status = "okay"; + + pcie@0,0 { + status = "okay"; + }; + + pcie@1,0 { + status = "okay"; + }; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + +&uart0 { + pinctrl-names = "default"; + pinctrl-0 = <&uart0_pins_a>; + status = "okay"; +}; + +&uart1 { + pinctrl-names = "default"; + pinctrl-0 = <&uart1_pins_a>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&uart2_pins_b>; + status = "okay"; +}; diff --git a/arch/arm/dts/mt7629-rfb.dts b/arch/arm/dts/mt7629-rfb.dts index bf84f76344..5cc7294de6 100644 --- a/arch/arm/dts/mt7629-rfb.dts +++ b/arch/arm/dts/mt7629-rfb.dts @@ -24,12 +24,14 @@ ð { status = "okay"; - mediatek,gmac-id = <1>; - phy-mode = "gmii"; - phy-handle = <&phy0>; - - phy0: ethernet-phy@0 { - reg = <0>; + mediatek,gmac-id = <0>; + phy-mode = "sgmii"; + mediatek,switch = "mt7531"; + reset-gpios = <&gpio 28 GPIO_ACTIVE_HIGH>; + + fixed-link { + speed = <1000>; + full-duplex; }; }; diff --git a/arch/arm/dts/qcom-ipq4019.dtsi b/arch/arm/dts/qcom-ipq4019.dtsi new file mode 100644 index 0000000000..5f78bc5ab9 --- /dev/null +++ b/arch/arm/dts/qcom-ipq4019.dtsi @@ -0,0 +1,79 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Copyright (c) 2019 Sartura Ltd. + * + * Author: Robert Marko <robert.marko@sartura.hr> + */ + + /dts-v1/; + +#include "skeleton.dtsi" +#include <dt-bindings/gpio/gpio.h> +#include <dt-bindings/pinctrl/pinctrl-snapdragon.h> + +/ { + #address-cells = <1>; + #size-cells = <1>; + + model = "Qualcomm Technologies, Inc. IPQ4019"; + compatible = "qcom,ipq4019"; + + aliases { + serial0 = &blsp1_uart1; + }; + + reserved-memory { + #address-cells = <0x1>; + #size-cells = <0x1>; + ranges; + + smem_mem: smem_region: smem@87e00000 { + reg = <0x87e00000 0x080000>; + no-map; + }; + + tz@87e80000 { + reg = <0x87e80000 0x180000>; + no-map; + }; + }; + + soc: soc { + #address-cells = <1>; + #size-cells = <1>; + ranges; + compatible = "simple-bus"; + + gcc: clock-controller@1800000 { + compatible = "qcom,gcc-ipq4019"; + reg = <0x1800000 0x60000>; + #clock-cells = <1>; + #reset-cells = <1>; + u-boot,dm-pre-reloc; + }; + + pinctrl: qcom,tlmm@1000000 { + compatible = "qcom,tlmm-ipq4019"; + reg = <0x1000000 0x300000>; + u-boot,dm-pre-reloc; + }; + + blsp1_uart1: serial@78af000 { + compatible = "qcom,msm-uartdm-v1.4", "qcom,msm-uartdm"; + reg = <0x78af000 0x200>; + clock = <&gcc 26>; + bit-rate = <0xFF>; + status = "disabled"; + u-boot,dm-pre-reloc; + }; + + soc_gpios: pinctrl@1000000 { + compatible = "qcom,ipq4019-pinctrl"; + reg = <0x1000000 0x300000>; + gpio-controller; + gpio-count = <100>; + gpio-bank-name="soc"; + #gpio-cells = <2>; + }; + }; +}; diff --git a/arch/arm/dts/s5p4418-nanopi2.dts b/arch/arm/dts/s5p4418-nanopi2.dts new file mode 100644 index 0000000000..4deaf10a1c --- /dev/null +++ b/arch/arm/dts/s5p4418-nanopi2.dts @@ -0,0 +1,110 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2020 Stefan Bosch <stefan_b@posteo.net> + * + * (C) Copyright 2017 FriendlyElec Computer Tech. Co., Ltd. + * (http://www.friendlyarm.com) + * + * (C) Copyright 2016 Nexell + * Youngbok, Park <park@nexell.co.kr> + */ + +/dts-v1/; +#include "s5p4418.dtsi" + +/ { + model = "FriendlyElec boards based on Nexell s5p4418"; + cpu-model = "S5p4418"; + + compatible = "friendlyelec,nanopi2", + "nexell,s5p4418"; + + aliases { + mmc0 = "/mmc@c0069000"; + mmc1 = "/mmc@c0062000"; + i2c0 = "/i2c@c00a4000"; + i2c1 = "/i2c@c00a5000"; + i2c2 = "/i2c@c00a6000"; + }; + + mmc0:mmc@c0062000 { + frequency = <50000000>; + drive_dly = <0x0>; + drive_shift = <0x03>; + sample_dly = <0x00>; + sample_shift = <0x02>; + mmcboost = <0>; + status = "okay"; + }; + + mmc2:mmc@c0069000 { + frequency = <50000000>; + drive_dly = <0x0>; + drive_shift = <0x03>; + sample_dly = <0x00>; + sample_shift = <0x02>; + mmcboost = <0>; + status = "okay"; + }; + + /* NanoPi2: Header "CON2", NanoPC-T2: EEPROM (MAC-Addr.) and Audio */ + i2c0:i2c@c00a4000 { + status ="okay"; + }; + + /* NanoPi2: Header "CON2" and HDMI, NanoPC-T2: HDMI */ + i2c1:i2c@c00a5000 { + status ="okay"; + }; + + /* NanoPi2: LCD interface, NanoPC-T2: LCD, LVDS and MIPI interfaces */ + i2c2:i2c@c00a6000 { + status ="okay"; + }; + + dp0:dp@c0102800 { + status = "okay"; + module = <0>; + lcd-type = "lvds"; + + dp-device { + format = <0>; /* 0:VESA, 1:JEIDA */ + }; + + dp-sync { + h_active_len = <1024>; + h_front_porch = <84>; + h_back_porch = <84>; + h_sync_width = <88>; + h_sync_invert = <0>; + v_active_len = <600>; + v_front_porch = <10>; + v_back_porch = <10>; + v_sync_width = <20>; + v_sync_invert = <0>; + }; + + dp-ctrl { + clk_src_lv0 = <3>; + clk_div_lv0 = <16>; + clk_src_lv1 = <7>; + clk_div_lv1 = <1>; + out_format = <2>; + }; + + dp-planes { + layer_top { + screen_width = <1024>; + screen_height = <600>; + back_color = <0x0>; + }; + + layer_1 { /* RGB 1 */ + width = <1024>; + height = <600>; + format = <0x06530000>; + pixel_byte = <4>; + }; + }; + }; +}; diff --git a/arch/arm/dts/s5p4418-pinctrl.dtsi b/arch/arm/dts/s5p4418-pinctrl.dtsi new file mode 100644 index 0000000000..a7e1c2c381 --- /dev/null +++ b/arch/arm/dts/s5p4418-pinctrl.dtsi @@ -0,0 +1,135 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Nexell's s5p6818 SoC pin-mux and pin-config device tree source + * + * (C) Copyright 2020 Stefan Bosch <stefan_b@posteo.net> + * + * Copyright (C) 2016 Nexell Co., Ltd. + * http://www.nexell.co.kr + * + * Nexell's s5p6818 SoC pin-mux and pin-config options are listed as + * device tree nodes in this file. + */ + +pinctrl@C0010000 { + /* + * values for "pin-pull": + * pulldown resistor = 0 + * pullup = 1 + * no pullup/down = 2 + */ + + /* MMC */ + mmc0_clk: mmc0-clk { + pins = "gpioa-29"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <2>; + }; + + mmc0_cmd: mmc0-cmd { + pins = "gpioa-31"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <1>; + }; + + mmc0_bus4: mmc0-bus-width4 { + pins = "gpiob-1, gpiob-3, gpiob-5, gpiob-7"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <1>; + }; + + mmc1_clk: mmc1-clk { + pins = "gpiod-22"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <2>; + }; + + mmc1_cmd: mmc1-cmd { + pins = "gpiod-23"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <1>; + }; + + mmc1_bus4: mmc1-bus-width4 { + pins = "gpiod-24, gpiod-25, gpiod-26, gpiod-27"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <1>; + }; + + mmc2_clk: mmc2-clk { + pins = "gpioc-18"; + pin-function = <2>; + pin-pull = <2>; + pin-strength = <2>; + }; + + mmc2_cmd: mmc2-cmd { + pins = "gpioc-19"; + pin-function = <2>; + pin-pull = <2>; + pin-strength = <1>; + }; + + mmc2_bus4: mmc2-bus-width4 { + pins = "gpioc-20, gpioc-21, gpioc-22, gpioc-23"; + pin-function = <2>; + pin-pull = <2>; + pin-strength = <1>; + }; + + mmc2_bus8: mmc2-bus-width8 { + nexell,pins = "gpioe-21", "gpioe-22", "gpioe-23", "gpioe-24"; + pin-function = <2>; + pin-pull = <2>; + pin-strength = <1>; + }; + + /* I2C */ + i2c0_sda:i2c0-sda { + pins = "gpiod-3"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + i2c0_scl:i2c0-scl { + pins = "gpiod-2"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + i2c1_sda:i2c1-sda { + pins = "gpiod-5"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + i2c1_scl:i2c1-scl { + pins = "gpiod-4"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + i2c2_sda:i2c2-sda { + pins = "gpiod-7"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; + + i2c2_scl:i2c2-scl { + pins = "gpiod-6"; + pin-function = <1>; + pin-pull = <2>; + pin-strength = <0>; + }; +}; diff --git a/arch/arm/dts/s5p4418.dtsi b/arch/arm/dts/s5p4418.dtsi new file mode 100644 index 0000000000..a4d1a1bd03 --- /dev/null +++ b/arch/arm/dts/s5p4418.dtsi @@ -0,0 +1,170 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2020 Stefan Bosch <stefan_b@posteo.net> + * + * (C) Copyright 2016 Nexell + * Youngbok, Park <park@nexell.co.kr> + * + */ + +#include "skeleton.dtsi" + +/ { + #include "s5p4418-pinctrl.dtsi" + + aliases { + mmc0 = &mmc0; + mmc1 = &mmc1; + mmc2 = &mmc2; + gmac = "/ethernet@c0060000"; + }; + + mmc2:mmc@c0069000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nexell,nexell-dwmmc"; + reg = <0xc0069000 0x1000>; + bus-width = <4>; + index = <2>; + max-frequency = <50000000>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc2_clk>, <&mmc2_cmd>, <&mmc2_bus4>; + status = "disabled"; + }; + + mmc1:mmc@c0068000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nexell,nexell-dwmmc"; + reg = <0xc0068000 0x1000>; + bus-width = <4>; + index = <1>; + max-frequency = <50000000>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc1_clk>, <&mmc1_cmd>, <&mmc1_bus4>; + status = "disabled"; + }; + + mmc0:mmc@c0062000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nexell,nexell-dwmmc"; + reg = <0xc0062000 0x1000>; + bus-width = <4>; + index = <0>; + max-frequency = <50000000>; + pinctrl-names = "default"; + pinctrl-0 = <&mmc0_clk>, <&mmc0_cmd>, <&mmc0_bus4>; + status = "disabled"; + }; + + i2c0:i2c@c00a4000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nexell,s5pxx18-i2c"; + reg = <0xc00a4000 0x100>; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c0_sda>, <&i2c0_scl>; + status ="disabled"; + }; + + i2c1:i2c@c00a5000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nexell,s5pxx18-i2c"; + reg = <0xc00a5000 0x100>; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c1_sda>, <&i2c1_scl>; + status ="disabled"; + }; + + i2c2:i2c@c00a6000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nexell,s5pxx18-i2c"; + reg = <0xc00a6000 0x100>; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&i2c2_sda>, <&i2c2_scl>; + status ="disabled"; + }; + + dp0:dp@c0102800 { + compatible = "nexell,nexell-display"; + reg = <0xc0102800 0x100>; + index = <0>; + u-boot,dm-pre-reloc; + status = "disabled"; + }; + + dp1:dp@c0102c00 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "nexell,nexell-display"; + reg = <0xc0102c00 0x100>; + index = <1>; + status = "disabled"; + }; + + gpio_a:gpio@c001a000 { + compatible = "nexell,nexell-gpio"; + reg = <0xc001a000 0x00000010>; + altr,gpio-bank-width = <32>; + gpio-bank-name = "gpio_a"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio_b:gpio@c001b000 { + compatible = "nexell,nexell-gpio"; + reg = <0xc001b000 0x00000010>; + altr,gpio-bank-width = <32>; + gpio-bank-name = "gpio_b"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio_c:gpio@c001c000 { + compatible = "nexell,nexell-gpio"; + reg = <0xc001c000 0x00000010>; + nexell,gpio-bank-width = <32>; + gpio-bank-name = "gpio_c"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio_d:gpio@c001d000 { + compatible = "nexell,nexell-gpio"; + reg = <0xc001d000 0x00000010>; + nexell,gpio-bank-width = <32>; + gpio-bank-name = "gpio_d"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio_e:gpio@c001e000 { + compatible = "nexell,nexell-gpio"; + reg = <0xc001e000 0x00000010>; + nexell,gpio-bank-width = <32>; + gpio-bank-name = "gpio_e"; + gpio-controller; + #gpio-cells = <2>; + }; + + gpio_alv:gpio@c0010800 { + compatible = "nexell,nexell-gpio"; + reg = <0xc0010800 0x00000010>; + nexell,gpio-bank-width = <32>; + gpio-bank-name = "gpio_alv"; + gpio-controller; + #gpio-cells = <2>; + }; + + pinctrl@C0010000 { + compatible = "nexell,s5pxx18-pinctrl"; + reg = <0xc0010000 0xf000>; + u-boot,dm-pre-reloc; + }; +}; diff --git a/arch/arm/include/asm/system.h b/arch/arm/include/asm/system.h index 37c1bfd726..ce552944b7 100644 --- a/arch/arm/include/asm/system.h +++ b/arch/arm/include/asm/system.h @@ -445,10 +445,16 @@ static inline void set_dacr(unsigned int val) #define TTBCR_EPD0 (0 << 7) /* - * Memory types + * VMSAv8-32 Long-descriptor format memory region attributes + * (ARM Architecture Reference Manual section G5.7.4 [DDI0487E.a]) + * + * MAIR0[ 7: 0] 0x00 Device-nGnRnE (aka Strongly-Ordered) + * MAIR0[15: 8] 0xaa Outer/Inner Write-Through, Read-Allocate No Write-Allocate + * MAIR0[23:16] 0xee Outer/Inner Write-Back, Read-Allocate No Write-Allocate + * MAIR0[31:24] 0xff Outer/Inner Write-Back, Read-Allocate Write-Allocate */ -#define MEMORY_ATTRIBUTES ((0x00 << (0 * 8)) | (0x88 << (1 * 8)) | \ - (0xcc << (2 * 8)) | (0xff << (3 * 8))) +#define MEMORY_ATTRIBUTES ((0x00 << (0 * 8)) | (0xaa << (1 * 8)) | \ + (0xee << (2 * 8)) | (0xff << (3 * 8))) /* options available for data cache on each page */ enum dcache_option { @@ -471,7 +477,16 @@ enum dcache_option { #define TTB_SECT_B_MASK (1 << 2) #define TTB_SECT (2 << 0) -/* options available for data cache on each page */ +/* + * Short-descriptor format memory region attributes, without TEX remap + * (ARM Architecture Reference Manual section G5.7.2 [DDI0487E.a]) + * + * TEX[0] C B + * 0 0 0 Device-nGnRnE (aka Strongly-Ordered) + * 0 1 0 Outer/Inner Write-Through, Read-Allocate No Write-Allocate + * 0 1 1 Outer/Inner Write-Back, Read-Allocate No Write-Allocate + * 1 1 1 Outer/Inner Write-Back, Read-Allocate Write-Allocate + */ enum dcache_option { DCACHE_OFF = TTB_SECT_DOMAIN(0) | TTB_SECT_XN_MASK | TTB_SECT, DCACHE_WRITETHROUGH = DCACHE_OFF | TTB_SECT_C_MASK, diff --git a/arch/arm/mach-ipq40xx/Kconfig b/arch/arm/mach-ipq40xx/Kconfig new file mode 100644 index 0000000000..4eef80e935 --- /dev/null +++ b/arch/arm/mach-ipq40xx/Kconfig @@ -0,0 +1,15 @@ +if ARCH_IPQ40XX + +config SYS_SOC + default "ipq40xx" + +config SYS_MALLOC_F_LEN + default 0x2000 + +config SYS_TEXT_BASE + default 0x87300000 + +config NR_DRAM_BANKS + default 1 + +endif diff --git a/arch/arm/mach-ipq40xx/Makefile b/arch/arm/mach-ipq40xx/Makefile new file mode 100644 index 0000000000..08a65b8854 --- /dev/null +++ b/arch/arm/mach-ipq40xx/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# Copyright (c) 2019 Sartura Ltd. +# +# Author: Robert Marko <robert.marko@sartura.hr> + +obj-y += clock-ipq4019.o +obj-y += pinctrl-snapdragon.o +obj-y += pinctrl-ipq4019.o diff --git a/arch/arm/mach-ipq40xx/clock-ipq4019.c b/arch/arm/mach-ipq40xx/clock-ipq4019.c new file mode 100644 index 0000000000..7cf98a203c --- /dev/null +++ b/arch/arm/mach-ipq40xx/clock-ipq4019.c @@ -0,0 +1,64 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Clock drivers for Qualcomm IPQ40xx + * + * Copyright (c) 2019 Sartura Ltd. + * + * Author: Robert Marko <robert.marko@sartura.hr> + * + */ + +#include <common.h> +#include <clk-uclass.h> +#include <dm.h> +#include <errno.h> + +struct msm_clk_priv { + phys_addr_t base; +}; + +ulong msm_set_rate(struct clk *clk, ulong rate) +{ + switch (clk->id) { + case 26: /*UART1*/ + /* This clock is already initialized by SBL1 */ + return 0; + break; + default: + return 0; + } +} + +static int msm_clk_probe(struct udevice *dev) +{ + struct msm_clk_priv *priv = dev_get_priv(dev); + + priv->base = devfdt_get_addr(dev); + if (priv->base == FDT_ADDR_T_NONE) + return -EINVAL; + + return 0; +} + +static ulong msm_clk_set_rate(struct clk *clk, ulong rate) +{ + return msm_set_rate(clk, rate); +} + +static struct clk_ops msm_clk_ops = { + .set_rate = msm_clk_set_rate, +}; + +static const struct udevice_id msm_clk_ids[] = { + { .compatible = "qcom,gcc-ipq4019" }, + { } +}; + +U_BOOT_DRIVER(clk_msm) = { + .name = "clk_msm", + .id = UCLASS_CLK, + .of_match = msm_clk_ids, + .ops = &msm_clk_ops, + .priv_auto_alloc_size = sizeof(struct msm_clk_priv), + .probe = msm_clk_probe, +}; diff --git a/arch/arm/mach-ipq40xx/include/mach/gpio.h b/arch/arm/mach-ipq40xx/include/mach/gpio.h new file mode 100644 index 0000000000..a45747c0fe --- /dev/null +++ b/arch/arm/mach-ipq40xx/include/mach/gpio.h @@ -0,0 +1,10 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Empty gpio.h + * + * This file must stay as arch/arm/include/asm/gpio.h requires it. + * + * Copyright (c) 2019 Sartura Ltd. + * + * Author: Robert Marko <robert.marko@sartura.hr> + */ diff --git a/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c b/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c new file mode 100644 index 0000000000..06a57f2e5e --- /dev/null +++ b/arch/arm/mach-ipq40xx/pinctrl-ipq4019.c @@ -0,0 +1,47 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Qualcomm IPQ40xx pinctrl + * + * Copyright (c) 2019 Sartura Ltd. + * + * Author: Robert Marko <robert.marko@sartura.hr> + */ + +#include "pinctrl-snapdragon.h" +#include <common.h> + +#define MAX_PIN_NAME_LEN 32 +static char pin_name[MAX_PIN_NAME_LEN]; + +static const struct pinctrl_function msm_pinctrl_functions[] = { + {"gpio", 0}, + {"blsp_uart0_0", 1}, /* Only for GPIO:16,17 */ + {"blsp_uart0_1", 2}, /* Only for GPIO:60,61 */ + {"blsp_uart1", 1}, +}; + +static const char *ipq4019_get_function_name(struct udevice *dev, + unsigned int selector) +{ + return msm_pinctrl_functions[selector].name; +} + +static const char *ipq4019_get_pin_name(struct udevice *dev, + unsigned int selector) +{ + snprintf(pin_name, MAX_PIN_NAME_LEN, "GPIO_%u", selector); + return pin_name; +} + +static unsigned int ipq4019_get_function_mux(unsigned int selector) +{ + return msm_pinctrl_functions[selector].val; +} + +struct msm_pinctrl_data ipq4019_data = { + .pin_count = 100, + .functions_count = ARRAY_SIZE(msm_pinctrl_functions), + .get_function_name = ipq4019_get_function_name, + .get_function_mux = ipq4019_get_function_mux, + .get_pin_name = ipq4019_get_pin_name, +}; diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c new file mode 100644 index 0000000000..64b8b049fa --- /dev/null +++ b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.c @@ -0,0 +1,137 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * TLMM driver for Qualcomm IPQ40xx + * + * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com> + * + * Copyright (c) 2020 Sartura Ltd. + * + * Author: Robert Marko <robert.marko@sartura.hr> + * + */ + +#include <common.h> +#include <dm.h> +#include <errno.h> +#include <asm/io.h> +#include <dm/pinctrl.h> +#include <linux/bitops.h> +#include "pinctrl-snapdragon.h" + +struct msm_pinctrl_priv { + phys_addr_t base; + struct msm_pinctrl_data *data; +}; + +#define GPIO_CONFIG_OFFSET(x) ((x) * 0x1000) +#define TLMM_GPIO_PULL_MASK GENMASK(1, 0) +#define TLMM_FUNC_SEL_MASK GENMASK(5, 2) +#define TLMM_DRV_STRENGTH_MASK GENMASK(8, 6) +#define TLMM_GPIO_DISABLE BIT(9) + +static const struct pinconf_param msm_conf_params[] = { + { "drive-strength", PIN_CONFIG_DRIVE_STRENGTH, 2 }, + { "bias-disable", PIN_CONFIG_BIAS_DISABLE, 0 }, + { "bias-pull-up", PIN_CONFIG_BIAS_PULL_UP, 2 }, +}; + +static int msm_get_functions_count(struct udevice *dev) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->functions_count; +} + +static int msm_get_pins_count(struct udevice *dev) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->pin_count; +} + +static const char *msm_get_function_name(struct udevice *dev, + unsigned int selector) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->get_function_name(dev, selector); +} + +static int msm_pinctrl_probe(struct udevice *dev) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + priv->base = devfdt_get_addr(dev); + priv->data = (struct msm_pinctrl_data *)dev->driver_data; + + return priv->base == FDT_ADDR_T_NONE ? -EINVAL : 0; +} + +static const char *msm_get_pin_name(struct udevice *dev, unsigned int selector) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + return priv->data->get_pin_name(dev, selector); +} + +static int msm_pinmux_set(struct udevice *dev, unsigned int pin_selector, + unsigned int func_selector) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + TLMM_FUNC_SEL_MASK | TLMM_GPIO_DISABLE, + priv->data->get_function_mux(func_selector) << 2); + return 0; +} + +static int msm_pinconf_set(struct udevice *dev, unsigned int pin_selector, + unsigned int param, unsigned int argument) +{ + struct msm_pinctrl_priv *priv = dev_get_priv(dev); + + switch (param) { + case PIN_CONFIG_DRIVE_STRENGTH: + clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + TLMM_DRV_STRENGTH_MASK, argument << 6); + break; + case PIN_CONFIG_BIAS_DISABLE: + clrbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + TLMM_GPIO_PULL_MASK); + break; + case PIN_CONFIG_BIAS_PULL_UP: + clrsetbits_le32(priv->base + GPIO_CONFIG_OFFSET(pin_selector), + TLMM_GPIO_PULL_MASK, argument); + break; + default: + return 0; + } + + return 0; +} + +static struct pinctrl_ops msm_pinctrl_ops = { + .get_pins_count = msm_get_pins_count, + .get_pin_name = msm_get_pin_name, + .set_state = pinctrl_generic_set_state, + .pinmux_set = msm_pinmux_set, + .pinconf_num_params = ARRAY_SIZE(msm_conf_params), + .pinconf_params = msm_conf_params, + .pinconf_set = msm_pinconf_set, + .get_functions_count = msm_get_functions_count, + .get_function_name = msm_get_function_name, +}; + +static const struct udevice_id msm_pinctrl_ids[] = { + { .compatible = "qcom,tlmm-ipq4019", .data = (ulong)&ipq4019_data }, + { } +}; + +U_BOOT_DRIVER(pinctrl_snapdraon) = { + .name = "pinctrl_msm", + .id = UCLASS_PINCTRL, + .of_match = msm_pinctrl_ids, + .priv_auto_alloc_size = sizeof(struct msm_pinctrl_priv), + .ops = &msm_pinctrl_ops, + .probe = msm_pinctrl_probe, +}; diff --git a/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h new file mode 100644 index 0000000000..2341a71349 --- /dev/null +++ b/arch/arm/mach-ipq40xx/pinctrl-snapdragon.h @@ -0,0 +1,30 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Qualcomm Pin control + * + * (C) Copyright 2018 Ramon Fried <ramon.fried@gmail.com> + * + */ +#ifndef _PINCTRL_SNAPDRAGON_H +#define _PINCTRL_SNAPDRAGON_H + +#include <common.h> + +struct msm_pinctrl_data { + int pin_count; + int functions_count; + const char *(*get_function_name)(struct udevice *dev, + unsigned int selector); + unsigned int (*get_function_mux)(unsigned int selector); + const char *(*get_pin_name)(struct udevice *dev, + unsigned int selector); +}; + +struct pinctrl_function { + const char *name; + int val; +}; + +extern struct msm_pinctrl_data ipq4019_data; + +#endif diff --git a/arch/arm/mach-nexell/Kconfig b/arch/arm/mach-nexell/Kconfig new file mode 100644 index 0000000000..ffa4d4865a --- /dev/null +++ b/arch/arm/mach-nexell/Kconfig @@ -0,0 +1,58 @@ +if ARCH_NEXELL + +config ARCH_S5P4418 + bool "Nexell S5P4418 SoC" + select CPU_V7A + select OF_CONTROL + select OF_SEPARATE + select NX_GPIO + select PL011_SERIAL + select PL011_SERIAL_FLUSH_ON_INIT + help + Enable support for Nexell S5P4418 SoC. + +config ARCH_S5P6818 + bool "Nexell S5P6818 SoC" + select ARM64 + select ARMV8_MULTIENTRY + help + Enable support for Nexell S5P6818 SoC. + +menu "Nexell S5P4418/S5P6818" + depends on ARCH_NEXELL + +choice + prompt "Nexell S5P4418/S5P6818 board select" + optional + +config TARGET_NANOPI2 + bool "FriendlyARM NanoPi2 / NanoPC-T2 Board" + select ARCH_S5P4418 + help + Enable support for FriendlyARM NanoPi2 and NanoPC-T2 Boards. + +endchoice + +config SYS_BOARD + default "nanopi2" + +config SYS_VENDOR + default "friendlyarm" + +config SYS_SOC + default "nexell" + +config SYS_CONFIG_NAME + default "s5p4418_nanopi2" + +endmenu + +config SYS_PLLFIN + int + +config TIMER_SYS_TICK_CH + int + +source "board/friendlyarm/Kconfig" + +endif diff --git a/arch/arm/mach-nexell/Makefile b/arch/arm/mach-nexell/Makefile new file mode 100644 index 0000000000..10b3963ed1 --- /dev/null +++ b/arch/arm/mach-nexell/Makefile @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: GPL-2.0+ +# +# (C) Copyright 2016 Nexell +# Hyunseok, Jung <hsjung@nexell.co.kr> + +obj-y += clock.o +obj-y += timer.o +obj-y += reset.o +obj-y += nx_gpio.o +obj-y += tieoff.o +obj-$(CONFIG_ARCH_S5P4418) += reg-call.o +obj-$(CONFIG_ARCH_S5P4418) += nx_sec_reg.o +obj-$(CONFIG_CMD_BOOTL) += cmd_boot_linux.o diff --git a/arch/arm/mach-nexell/clock.c b/arch/arm/mach-nexell/clock.c new file mode 100644 index 0000000000..a0ba2d8e0c --- /dev/null +++ b/arch/arm/mach-nexell/clock.c @@ -0,0 +1,869 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Hyunseok, Jung <hsjung@nexell.co.kr> + */ + +#include <common.h> +#include <command.h> +#include <linux/err.h> +#include <asm/io.h> +#include <asm/arch/nexell.h> +#include <asm/arch/clk.h> + +/* + * clock generator macros + */ +#define I_PLL0_BIT (0) +#define I_PLL1_BIT (1) +#define I_PLL2_BIT (2) +#define I_PLL3_BIT (3) +#define I_EXT1_BIT (4) +#define I_EXT2_BIT (5) +#define I_CLKn_BIT (7) +#define I_EXT1_BIT_FORCE (8) +#define I_EXT2_BIT_FORCE (9) + +#define I_CLOCK_NUM 6 /* PLL0, PLL1, PLL2, PLL3, EXT1, EXT2 */ + +#define I_EXECEPT_CLK (0) +#define I_CLOCK_MASK (((1 << I_CLOCK_NUM) - 1) & ~I_EXECEPT_CLK) + +#define I_PLL0 (1 << I_PLL0_BIT) +#define I_PLL1 (1 << I_PLL1_BIT) +#define I_PLL2 (1 << I_PLL2_BIT) +#define I_PLL3 (1 << I_PLL3_BIT) +#define I_EXTCLK1 (1 << I_EXT1_BIT) +#define I_EXTCLK2 (1 << I_EXT2_BIT) +#define I_EXTCLK1_FORCE (1 << I_EXT1_BIT_FORCE) +#define I_EXTCLK2_FORCE (1 << I_EXT2_BIT_FORCE) + +#define I_PLL_0_1 (I_PLL0 | I_PLL1) +#define I_PLL_0_2 (I_PLL_0_1 | I_PLL2) +#define I_PLL_0_3 (I_PLL_0_2 | I_PLL3) +#define I_CLKnOUT (0) + +#define I_PCLK (1 << 16) +#define I_BCLK (1 << 17) +#define I_GATE_PCLK (1 << 20) +#define I_GATE_BCLK (1 << 21) +#define I_PCLK_MASK (I_GATE_PCLK | I_PCLK) +#define I_BCLK_MASK (I_GATE_BCLK | I_BCLK) + +struct clk_dev_peri { + const char *dev_name; + void __iomem *base; + int dev_id; + int periph_id; + int clk_step; + u32 in_mask; + u32 in_mask1; + int div_src_0; + int div_val_0; + int invert_0; + int div_src_1; + int div_val_1; + int invert_1; + int in_extclk_1; + int in_extclk_2; +}; + +struct clk_dev { + struct clk clk; + struct clk *link; + const char *name; + struct clk_dev_peri *peri; +}; + +struct clk_dev_map { + unsigned int con_enb; + unsigned int con_gen[4]; +}; + +#define CLK_PERI_1S(name, devid, id, addr, mk)[id] = \ + { .dev_name = name, .dev_id = devid, .periph_id = id, .clk_step = 1, \ + .base = (void *)addr, .in_mask = mk, } + +#define CLK_PERI_2S(name, devid, id, addr, mk, mk2)[id] = \ + { .dev_name = name, .dev_id = devid, .periph_id = id, .clk_step = 2, \ + .base = (void *)addr, .in_mask = mk, .in_mask1 = mk2, } + +static const char * const clk_core[] = { + CORECLK_NAME_PLL0, CORECLK_NAME_PLL1, CORECLK_NAME_PLL2, + CORECLK_NAME_PLL3, CORECLK_NAME_FCLK, CORECLK_NAME_MCLK, + CORECLK_NAME_BCLK, CORECLK_NAME_PCLK, CORECLK_NAME_HCLK, +}; + +/* + * Section ".data" must be used because BSS is not available before relocation, + * in board_init_f(), respectively! I.e. global variables can not be used! + */ +static struct clk_dev_peri clk_periphs[] + __attribute__((section(".data"))) = { + CLK_PERI_1S(DEV_NAME_TIMER, 0, CLK_ID_TIMER_0, + PHY_BASEADDR_CLKGEN14, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_TIMER, 1, CLK_ID_TIMER_1, + PHY_BASEADDR_CLKGEN0, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_TIMER, 2, CLK_ID_TIMER_2, + PHY_BASEADDR_CLKGEN1, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_TIMER, 3, CLK_ID_TIMER_3, + PHY_BASEADDR_CLKGEN2, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_UART, 0, CLK_ID_UART_0, + PHY_BASEADDR_CLKGEN22, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_UART, 1, CLK_ID_UART_1, + PHY_BASEADDR_CLKGEN24, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_UART, 2, CLK_ID_UART_2, + PHY_BASEADDR_CLKGEN23, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_UART, 3, CLK_ID_UART_3, + PHY_BASEADDR_CLKGEN25, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_UART, 4, CLK_ID_UART_4, + PHY_BASEADDR_CLKGEN26, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_UART, 5, CLK_ID_UART_5, + PHY_BASEADDR_CLKGEN27, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_PWM, 0, CLK_ID_PWM_0, + PHY_BASEADDR_CLKGEN13, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_PWM, 1, CLK_ID_PWM_1, + PHY_BASEADDR_CLKGEN3, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_PWM, 2, CLK_ID_PWM_2, + PHY_BASEADDR_CLKGEN4, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_PWM, 3, CLK_ID_PWM_3, + PHY_BASEADDR_CLKGEN5, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_I2C, 0, CLK_ID_I2C_0, + PHY_BASEADDR_CLKGEN6, (I_GATE_PCLK)), + CLK_PERI_1S(DEV_NAME_I2C, 1, CLK_ID_I2C_1, + PHY_BASEADDR_CLKGEN7, (I_GATE_PCLK)), + CLK_PERI_1S(DEV_NAME_I2C, 2, CLK_ID_I2C_2, + PHY_BASEADDR_CLKGEN8, (I_GATE_PCLK)), + CLK_PERI_2S(DEV_NAME_GMAC, 0, CLK_ID_GMAC, + PHY_BASEADDR_CLKGEN10, + (I_PLL_0_3 | I_EXTCLK1 | I_EXTCLK1_FORCE), + (I_CLKnOUT)), + CLK_PERI_2S(DEV_NAME_I2S, 0, CLK_ID_I2S_0, + PHY_BASEADDR_CLKGEN15, (I_PLL_0_3 | I_EXTCLK1), + (I_CLKnOUT)), + CLK_PERI_2S(DEV_NAME_I2S, 1, CLK_ID_I2S_1, + PHY_BASEADDR_CLKGEN16, (I_PLL_0_3 | I_EXTCLK1), + (I_CLKnOUT)), + CLK_PERI_2S(DEV_NAME_I2S, 2, CLK_ID_I2S_2, + PHY_BASEADDR_CLKGEN17, (I_PLL_0_3 | I_EXTCLK1), + (I_CLKnOUT)), + CLK_PERI_1S(DEV_NAME_SDHC, 0, CLK_ID_SDHC_0, + PHY_BASEADDR_CLKGEN18, (I_PLL_0_2 | I_GATE_PCLK)), + CLK_PERI_1S(DEV_NAME_SDHC, 1, CLK_ID_SDHC_1, + PHY_BASEADDR_CLKGEN19, (I_PLL_0_2 | I_GATE_PCLK)), + CLK_PERI_1S(DEV_NAME_SDHC, 2, CLK_ID_SDHC_2, + PHY_BASEADDR_CLKGEN20, (I_PLL_0_2 | I_GATE_PCLK)), + CLK_PERI_1S(DEV_NAME_SPI, 0, CLK_ID_SPI_0, + PHY_BASEADDR_CLKGEN37, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_SPI, 1, CLK_ID_SPI_1, + PHY_BASEADDR_CLKGEN38, (I_PLL_0_2)), + CLK_PERI_1S(DEV_NAME_SPI, 2, CLK_ID_SPI_2, + PHY_BASEADDR_CLKGEN39, (I_PLL_0_2)), +}; + +#define CLK_PERI_NUM ((int)ARRAY_SIZE(clk_periphs)) +#define CLK_CORE_NUM ((int)ARRAY_SIZE(clk_core)) +#define CLK_DEVS_NUM (CLK_CORE_NUM + CLK_PERI_NUM) +#define MAX_DIVIDER ((1 << 8) - 1) /* 256, align 2 */ + +static struct clk_dev st_clk_devs[CLK_DEVS_NUM] + __attribute__((section(".data"))); +#define clk_dev_get(n) ((struct clk_dev *)&st_clk_devs[n]) +#define clk_container(p) (container_of(p, struct clk_dev, clk)) + +/* + * Core frequencys + */ +struct _core_hz_ { + unsigned long pll[4]; /* PLL */ + unsigned long cpu_fclk, cpu_bclk; /* cpu */ + unsigned long mem_fclk, mem_dclk, mem_bclk, mem_pclk; /* ddr */ + unsigned long bus_bclk, bus_pclk; /* bus */ +#if defined(CONFIG_ARCH_S5P6818) + unsigned long cci4_bclk, cci4_pclk; /* cci */ +#endif + /* ip */ + unsigned long g3d_bclk; + unsigned long coda_bclk, coda_pclk; +#if defined(CONFIG_ARCH_S5P6818) + unsigned long disp_bclk, disp_pclk; + unsigned long hdmi_pclk; +#endif +}; + +/* + * Section ".data" must be used because BSS is not available before relocation, + * in board_init_f(), respectively! I.e. global variables can not be used! + */ +/* core clock */ +static struct _core_hz_ core_hz __attribute__((section(".data"))); + +#define CORE_HZ_SIZE (sizeof(core_hz) / 4) + +/* + * CLKGEN HW + */ +static inline void clk_dev_bclk(void *base, int on) +{ + struct clk_dev_map *reg = base; + unsigned int val = readl(®->con_enb) & ~(0x3); + + val |= (on ? 3 : 0) & 0x3; /* always BCLK */ + writel(val, ®->con_enb); +} + +static inline void clk_dev_pclk(void *base, int on) +{ + struct clk_dev_map *reg = base; + unsigned int val = 0; + + if (!on) + return; + + val = readl(®->con_enb) & ~(1 << 3); + val |= (1 << 3); + writel(val, ®->con_enb); +} + +static inline void clk_dev_rate(void *base, int step, int src, int div) +{ + struct clk_dev_map *reg = base; + unsigned int val = 0; + + val = readl(®->con_gen[step << 1]); + val &= ~(0x07 << 2); + val |= (src << 2); /* source */ + val &= ~(0xFF << 5); + val |= (div - 1) << 5; /* divider */ + writel(val, ®->con_gen[step << 1]); +} + +static inline void clk_dev_inv(void *base, int step, int inv) +{ + struct clk_dev_map *reg = base; + unsigned int val = readl(®->con_gen[step << 1]) & ~(1 << 1); + + val |= (inv << 1); + writel(val, ®->con_gen[step << 1]); +} + +static inline void clk_dev_enb(void *base, int on) +{ + struct clk_dev_map *reg = base; + unsigned int val = readl(®->con_enb) & ~(1 << 2); + + val |= ((on ? 1 : 0) << 2); + writel(val, ®->con_enb); +} + +/* + * CORE FREQUENCY + * + * PLL0 [P,M,S] ------- | | ----- [DIV0] --- CPU-G0 + * |M| ----- [DIV1] --- BCLK/PCLK + * PLL1 [P,M,S] ------- | | ----- [DIV2] --- DDR + * |U| ----- [DIV3] --- 3D + * PLL2 [P,M,S,K]-------| | ----- [DIV4] --- CODA + * |X| ----- [DIV5] --- DISPLAY + * PLL3 [P,M,S,K]-------| | ----- [DIV6] --- HDMI + * | | ----- [DIV7] --- CPU-G1 + * | | ----- [DIV8] --- CCI-400(FASTBUS) + * + */ + +struct nx_clkpwr_registerset { + u32 clkmodereg0; /* 0x000 : Clock Mode Register0 */ + u32 __reserved0; /* 0x004 */ + u32 pllsetreg[4]; /* 0x008 ~ 0x014 : PLL Setting Register */ + u32 __reserved1[2]; /* 0x018 ~ 0x01C */ + u32 dvoreg[9]; /* 0x020 ~ 0x040 : Divider Setting Register */ + u32 __Reserved2; /* 0x044 */ + u32 pllsetreg_sscg[6]; /* 0x048 ~ 0x05C */ + u32 __reserved3[8]; /* 0x060 ~ 0x07C */ + u8 __reserved4[0x200 - 0x80]; /* padding (0x80 ~ 0x1FF) */ + u32 gpiowakeupriseenb; /* 0x200 : GPIO Rising Edge Detect En. Reg. */ + u32 gpiowakeupfallenb; /* 0x204 : GPIO Falling Edge Detect En. Reg. */ + u32 gpiorstenb; /* 0x208 : GPIO Reset Enable Register */ + u32 gpiowakeupenb; /* 0x20C : GPIO Wakeup Source Enable */ + u32 gpiointenb; /* 0x210 : Interrupt Enable Register */ + u32 gpiointpend; /* 0x214 : Interrupt Pend Register */ + u32 resetstatus; /* 0x218 : Reset Status Register */ + u32 intenable; /* 0x21C : Interrupt Enable Register */ + u32 intpend; /* 0x220 : Interrupt Pend Register */ + u32 pwrcont; /* 0x224 : Power Control Register */ + u32 pwrmode; /* 0x228 : Power Mode Register */ + u32 __reserved5; /* 0x22C : Reserved Region */ + u32 scratch[3]; /* 0x230 ~ 0x238 : Scratch Register */ + u32 sysrstconfig; /* 0x23C : System Reset Configuration Reg. */ + u8 __reserved6[0x2A0 - 0x240]; /* padding (0x240 ~ 0x29F) */ + u32 cpupowerdownreq; /* 0x2A0 : CPU Power Down Request Register */ + u32 cpupoweronreq; /* 0x2A4 : CPU Power On Request Register */ + u32 cpuresetmode; /* 0x2A8 : CPU Reset Mode Register */ + u32 cpuwarmresetreq; /* 0x2AC : CPU Warm Reset Request Register */ + u32 __reserved7; /* 0x2B0 */ + u32 cpustatus; /* 0x2B4 : CPU Status Register */ + u8 __reserved8[0x400 - 0x2B8]; /* padding (0x2B8 ~ 0x33F) */ +}; + +static struct nx_clkpwr_registerset * const clkpwr = + (struct nx_clkpwr_registerset *)PHY_BASEADDR_CLKPWR; + +#define getquotient(v, d) ((v) / (d)) + +#define DIV_CPUG0 0 +#define DIV_BUS 1 +#define DIV_MEM 2 +#define DIV_G3D 3 +#define DIV_CODA 4 +#if defined(CONFIG_ARCH_S5P6818) +#define DIV_DISP 5 +#define DIV_HDMI 6 +#define DIV_CPUG1 7 +#define DIV_CCI4 8 +#endif + +#define DVO0 3 +#define DVO1 9 +#define DVO2 15 +#define DVO3 21 + +static unsigned int pll_rate(unsigned int plln, unsigned int xtal) +{ + unsigned int val, val1, nP, nM, nS, nK; + unsigned int temp = 0; + + val = clkpwr->pllsetreg[plln]; + val1 = clkpwr->pllsetreg_sscg[plln]; + xtal /= 1000; /* Unit Khz */ + + nP = (val >> 18) & 0x03F; + nM = (val >> 8) & 0x3FF; + nS = (val >> 0) & 0x0FF; + nK = (val1 >> 16) & 0xFFFF; + + if (plln > 1 && nK) { + temp = (unsigned int)(getquotient((getquotient((nK * 1000), + 65536) * xtal), nP) >> nS); + } + + temp = (unsigned int)((getquotient((nM * xtal), nP) >> nS) * 1000) + + temp; + return temp; +} + +static unsigned int pll_dvo(int dvo) +{ + unsigned int val; + + val = (clkpwr->dvoreg[dvo] & 0x7); + return val; +} + +static unsigned int pll_div(int dvo) +{ + unsigned int val = clkpwr->dvoreg[dvo]; + + return ((((val >> DVO3) & 0x3F) + 1) << 24) | + ((((val >> DVO2) & 0x3F) + 1) << 16) | + ((((val >> DVO1) & 0x3F) + 1) << 8) | + ((((val >> DVO0) & 0x3F) + 1) << 0); +} + +#define PLLN_RATE(n) (pll_rate(n, CONFIG_SYS_PLLFIN)) /* 0~ 3 */ +#define CPU_FCLK_RATE(n) (pll_rate(pll_dvo(n), CONFIG_SYS_PLLFIN) / \ + ((pll_div(n) >> 0) & 0x3F)) +#define CPU_BCLK_RATE(n) (pll_rate(pll_dvo(n), CONFIG_SYS_PLLFIN) / \ + ((pll_div(n) >> 0) & 0x3F) / \ + ((pll_div(n) >> 8) & 0x3F)) + +#define MEM_FCLK_RATE() (pll_rate(pll_dvo(DIV_MEM), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_MEM) >> 0) & 0x3F) / \ + ((pll_div(DIV_MEM) >> 8) & 0x3F)) + +#define MEM_DCLK_RATE() (pll_rate(pll_dvo(DIV_MEM), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_MEM) >> 0) & 0x3F)) + +#define MEM_BCLK_RATE() (pll_rate(pll_dvo(DIV_MEM), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_MEM) >> 0) & 0x3F) / \ + ((pll_div(DIV_MEM) >> 8) & 0x3F) / \ + ((pll_div(DIV_MEM) >> 16) & 0x3F)) +#define MEM_PCLK_RATE() (pll_rate(pll_dvo(DIV_MEM), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_MEM) >> 0) & 0x3F) / \ + ((pll_div(DIV_MEM) >> 8) & 0x3F) / \ + ((pll_div(DIV_MEM) >> 16) & 0x3F) / \ + ((pll_div(DIV_MEM) >> 24) & 0x3F)) + +#define BUS_BCLK_RATE() (pll_rate(pll_dvo(DIV_BUS), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_BUS) >> 0) & 0x3F)) +#define BUS_PCLK_RATE() (pll_rate(pll_dvo(DIV_BUS), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_BUS) >> 0) & 0x3F) / \ + ((pll_div(DIV_BUS) >> 8) & 0x3F)) + +#define G3D_BCLK_RATE() (pll_rate(pll_dvo(DIV_G3D), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_G3D) >> 0) & 0x3F)) + +#define MPG_BCLK_RATE() (pll_rate(pll_dvo(DIV_CODA), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_CODA) >> 0) & 0x3F)) +#define MPG_PCLK_RATE() (pll_rate(pll_dvo(DIV_CODA), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_CODA) >> 0) & 0x3F) / \ + ((pll_div(DIV_CODA) >> 8) & 0x3F)) + +#if defined(CONFIG_ARCH_S5P6818) +#define DISP_BCLK_RATE() (pll_rate(pll_dvo(DIV_DISP), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_DISP) >> 0) & 0x3F)) +#define DISP_PCLK_RATE() (pll_rate(pll_dvo(DIV_DISP), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_DISP) >> 0) & 0x3F) / \ + ((pll_div(DIV_DISP) >> 8) & 0x3F)) + +#define HDMI_PCLK_RATE() (pll_rate(pll_dvo(DIV_HDMI), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_HDMI) >> 0) & 0x3F)) + +#define CCI4_BCLK_RATE() (pll_rate(pll_dvo(DIV_CCI4), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_CCI4) >> 0) & 0x3F)) +#define CCI4_PCLK_RATE() (pll_rate(pll_dvo(DIV_CCI4), CONFIG_SYS_PLLFIN) / \ + ((pll_div(DIV_CCI4) >> 0) & 0x3F) / \ + ((pll_div(DIV_CCI4) >> 8) & 0x3F)) +#endif + +static void core_update_rate(int type) +{ + switch (type) { + case 0: + core_hz.pll[0] = PLLN_RATE(0); break; + case 1: + core_hz.pll[1] = PLLN_RATE(1); break; + case 2: + core_hz.pll[2] = PLLN_RATE(2); break; + case 3: + core_hz.pll[3] = PLLN_RATE(3); break; + case 4: + core_hz.cpu_fclk = CPU_FCLK_RATE(DIV_CPUG0); break; + case 5: + core_hz.mem_fclk = MEM_FCLK_RATE(); break; + case 6: + core_hz.bus_bclk = BUS_BCLK_RATE(); break; + case 7: + core_hz.bus_pclk = BUS_PCLK_RATE(); break; + case 8: + core_hz.cpu_bclk = CPU_BCLK_RATE(DIV_CPUG0); break; + case 9: + core_hz.mem_dclk = MEM_DCLK_RATE(); break; + case 10: + core_hz.mem_bclk = MEM_BCLK_RATE(); break; + case 11: + core_hz.mem_pclk = MEM_PCLK_RATE(); break; + case 12: + core_hz.g3d_bclk = G3D_BCLK_RATE(); break; + case 13: + core_hz.coda_bclk = MPG_BCLK_RATE(); break; + case 14: + core_hz.coda_pclk = MPG_PCLK_RATE(); break; +#if defined(CONFIG_ARCH_S5P6818) + case 15: + core_hz.disp_bclk = DISP_BCLK_RATE(); break; + case 16: + core_hz.disp_pclk = DISP_PCLK_RATE(); break; + case 17: + core_hz.hdmi_pclk = HDMI_PCLK_RATE(); break; + case 18: + core_hz.cci4_bclk = CCI4_BCLK_RATE(); break; + case 19: + core_hz.cci4_pclk = CCI4_PCLK_RATE(); break; +#endif + }; +} + +static unsigned long core_get_rate(int type) +{ + unsigned long rate = 0; + + switch (type) { + case 0: + rate = core_hz.pll[0]; break; + case 1: + rate = core_hz.pll[1]; break; + case 2: + rate = core_hz.pll[2]; break; + case 3: + rate = core_hz.pll[3]; break; + case 4: + rate = core_hz.cpu_fclk; break; + case 5: + rate = core_hz.mem_fclk; break; + case 6: + rate = core_hz.bus_bclk; break; + case 7: + rate = core_hz.bus_pclk; break; + case 8: + rate = core_hz.cpu_bclk; break; + case 9: + rate = core_hz.mem_dclk; break; + case 10: + rate = core_hz.mem_bclk; break; + case 11: + rate = core_hz.mem_pclk; break; + case 12: + rate = core_hz.g3d_bclk; break; + case 13: + rate = core_hz.coda_bclk; break; + case 14: + rate = core_hz.coda_pclk; break; +#if defined(CONFIG_ARCH_S5P6818) + case 15: + rate = core_hz.disp_bclk; break; + case 16: + rate = core_hz.disp_pclk; break; + case 17: + rate = core_hz.hdmi_pclk; break; + case 18: + rate = core_hz.cci4_bclk; break; + case 19: + rate = core_hz.cci4_pclk; break; +#endif + default: + printf("unknown core clock type %d ...\n", type); + break; + }; + return rate; +} + +static long core_set_rate(struct clk *clk, long rate) +{ + return clk->rate; +} + +static void core_rate_init(void) +{ + int i; + + for (i = 0; i < CORE_HZ_SIZE; i++) + core_update_rate(i); +} + +/* + * Clock Interfaces + */ +static inline long clk_divide(long rate, long request, + int align, int *divide) +{ + int div = (rate / request); + int max = MAX_DIVIDER & ~(align - 1); + int adv = (div & ~(align - 1)) + align; + long ret; + + if (!div) { + if (divide) + *divide = 1; + return rate; + } + + if (div != 1) + div &= ~(align - 1); + + if (div != adv && abs(request - rate / div) > abs(request - rate / adv)) + div = adv; + + div = (div > max ? max : div); + if (divide) + *divide = div; + + ret = rate / div; + return ret; +} + +void clk_put(struct clk *clk) +{ +} + +struct clk *clk_get(const char *id) +{ + struct clk_dev *cdev = clk_dev_get(0); + struct clk *clk = NULL; + const char *str = NULL, *c = NULL; + int i, devid; + + if (id) + str = id; + + for (i = 0; i < CLK_DEVS_NUM; i++, cdev++) { + if (!cdev->name) + continue; + if (!strncmp(cdev->name, str, strlen(cdev->name))) { + c = strrchr((const char *)str, (int)'.'); + if (!c || !cdev->peri) + break; + devid = simple_strtoul(++c, NULL, 10); + if (cdev->peri->dev_id == devid) + break; + } + } + if (i < CLK_DEVS_NUM) + clk = &cdev->clk; + else + clk = &(clk_dev_get(7))->clk; /* pclk */ + + return clk ? clk : ERR_PTR(-ENOENT); +} + +long clk_round_rate(struct clk *clk, unsigned long rate) +{ + struct clk_dev *pll = NULL, *cdev = clk_container(clk); + struct clk_dev_peri *peri = cdev->peri; + unsigned long request = rate, rate_hz = 0; + unsigned int mask; + int step, div[2] = { 0, }; + int i, n, clk2 = 0; + int start_src = 0, max_src = I_CLOCK_NUM; + short s1 = 0, s2 = 0, d1 = 0, d2 = 0; + + if (!peri) + return core_set_rate(clk, rate); + + step = peri->clk_step; + mask = peri->in_mask; + debug("clk: %s.%d request = %ld [input=0x%x]\n", peri->dev_name, + peri->dev_id, rate, mask); + + if (!(I_CLOCK_MASK & mask)) { + if (I_PCLK_MASK & mask) + return core_get_rate(CORECLK_ID_PCLK); + else if (I_BCLK_MASK & mask) + return core_get_rate(CORECLK_ID_BCLK); + else + return clk->rate; + } + +next: + if (peri->in_mask & I_EXTCLK1_FORCE) { + start_src = 4; max_src = 5; + } + for (n = start_src ; max_src > n; n++) { + if (!(((mask & I_CLOCK_MASK) >> n) & 0x1)) + continue; + + if (n == I_EXT1_BIT) { + rate = peri->in_extclk_1; + } else if (n == I_EXT2_BIT) { + rate = peri->in_extclk_2; + } else { + pll = clk_dev_get(n); + rate = pll->clk.rate; + } + + if (!rate) + continue; + + for (i = 0; step > i ; i++) + rate = clk_divide(rate, request, 2, &div[i]); + + if (rate_hz && (abs(rate - request) > abs(rate_hz - request))) + continue; + + debug("clk: %s.%d, pll.%d[%lu] request[%ld] calc[%ld]\n", + peri->dev_name, peri->dev_id, n, pll->clk.rate, + request, rate); + + if (clk2) { + s1 = -1, d1 = -1; /* not use */ + s2 = n, d2 = div[0]; + } else { + s1 = n, d1 = div[0]; + s2 = I_CLKn_BIT, d2 = div[1]; + } + rate_hz = rate; + } + + /* search 2th clock from input */ + if (!clk2 && abs(rate_hz - request) && + peri->in_mask1 & ((1 << I_CLOCK_NUM) - 1)) { + clk2 = 1; + mask = peri->in_mask1; + step = 1; + goto next; + } + if (peri->in_mask & I_EXTCLK1_FORCE) { + if (s1 == 0) { + s1 = 4; s2 = 7; + d1 = 1; d2 = 1; + } + } + + peri->div_src_0 = s1, peri->div_val_0 = d1; + peri->div_src_1 = s2, peri->div_val_1 = d2; + clk->rate = rate_hz; + + debug("clk: %s.%d, step[%d] src[%d,%d] %ld", peri->dev_name, + peri->dev_id, peri->clk_step, peri->div_src_0, peri->div_src_1, + rate); + debug("/(div0: %d * div1: %d) = %ld, %ld diff (%ld)\n", + peri->div_val_0, peri->div_val_1, rate_hz, request, + abs(rate_hz - request)); + + return clk->rate; +} + +unsigned long clk_get_rate(struct clk *clk) +{ + struct clk_dev *cdev = clk_container(clk); + + if (cdev->link) + clk = cdev->link; + return clk->rate; +} + +int clk_set_rate(struct clk *clk, unsigned long rate) +{ + struct clk_dev *cdev = clk_container(clk); + struct clk_dev_peri *peri = cdev->peri; + int i; + + if (!peri) + return core_set_rate(clk, rate); + + clk_round_rate(clk, rate); + + for (i = 0; peri->clk_step > i ; i++) { + int s = (i == 0 ? peri->div_src_0 : peri->div_src_1); + int d = (i == 0 ? peri->div_val_0 : peri->div_val_1); + + if (-1 == s) + continue; + + clk_dev_rate(peri->base, i, s, d); + + debug("clk: %s.%d (%p) set_rate [%d] src[%d] div[%d]\n", + peri->dev_name, peri->dev_id, peri->base, i, s, d); + } + + return clk->rate; +} + +int clk_enable(struct clk *clk) +{ + struct clk_dev *cdev = clk_container(clk); + struct clk_dev_peri *peri = cdev->peri; + int i = 0, inv = 0; + + if (!peri) + return 0; + + debug("clk: %s.%d enable (BCLK=%s, PCLK=%s)\n", peri->dev_name, + peri->dev_id, I_GATE_BCLK & peri->in_mask ? "ON" : "PASS", + I_GATE_PCLK & peri->in_mask ? "ON" : "PASS"); + + if (!(I_CLOCK_MASK & peri->in_mask)) { + /* Gated BCLK/PCLK enable */ + if (I_GATE_BCLK & peri->in_mask) + clk_dev_bclk(peri->base, 1); + + if (I_GATE_PCLK & peri->in_mask) + clk_dev_pclk(peri->base, 1); + + return 0; + } + + /* invert */ + inv = peri->invert_0; + for (; peri->clk_step > i; i++, inv = peri->invert_1) + clk_dev_inv(peri->base, i, inv); + + /* Gated BCLK/PCLK enable */ + if (I_GATE_BCLK & peri->in_mask) + clk_dev_bclk(peri->base, 1); + + if (I_GATE_PCLK & peri->in_mask) + clk_dev_pclk(peri->base, 1); + + /* restore clock rate */ + for (i = 0; peri->clk_step > i ; i++) { + int s = (i == 0 ? peri->div_src_0 : peri->div_src_1); + int d = (i == 0 ? peri->div_val_0 : peri->div_val_1); + + if (s == -1) + continue; + clk_dev_rate(peri->base, i, s, d); + } + + clk_dev_enb(peri->base, 1); + + return 0; +} + +void clk_disable(struct clk *clk) +{ + struct clk_dev *cdev = clk_container(clk); + struct clk_dev_peri *peri = cdev->peri; + + if (!peri) + return; + + debug("clk: %s.%d disable\n", peri->dev_name, peri->dev_id); + + if (!(I_CLOCK_MASK & peri->in_mask)) { + /* Gated BCLK/PCLK disable */ + if (I_GATE_BCLK & peri->in_mask) + clk_dev_bclk(peri->base, 0); + + if (I_GATE_PCLK & peri->in_mask) + clk_dev_pclk(peri->base, 0); + + return; + } + + clk_dev_rate(peri->base, 0, 7, 256); /* for power save */ + clk_dev_enb(peri->base, 0); + + /* Gated BCLK/PCLK disable */ + if (I_GATE_BCLK & peri->in_mask) + clk_dev_bclk(peri->base, 0); + + if (I_GATE_PCLK & peri->in_mask) + clk_dev_pclk(peri->base, 0); +} + +/* + * Core clocks APIs + */ +void __init clk_init(void) +{ + struct clk_dev *cdev = st_clk_devs; + struct clk_dev_peri *peri = clk_periphs; + struct clk *clk = NULL; + int i = 0; + + memset(cdev, 0, sizeof(st_clk_devs)); + core_rate_init(); + + for (i = 0; (CLK_CORE_NUM + CLK_PERI_NUM) > i; i++, cdev++) { + if (i < CLK_CORE_NUM) { + cdev->name = clk_core[i]; + clk = &cdev->clk; + clk->rate = core_get_rate(i); + continue; + } + + peri = &clk_periphs[i - CLK_CORE_NUM]; + peri->base = (void *)peri->base; + + cdev->peri = peri; + cdev->name = peri->dev_name; + + if (!(I_CLOCK_MASK & peri->in_mask)) { + if (I_BCLK_MASK & peri->in_mask) + cdev->clk.rate = core_get_rate(CORECLK_ID_BCLK); + if (I_PCLK_MASK & peri->in_mask) + cdev->clk.rate = core_get_rate(CORECLK_ID_PCLK); + } + + /* prevent uart clock disable for low step debug message */ + #ifndef CONFIG_DEBUG_NX_UART + if (peri->dev_name) { + #ifdef CONFIG_BACKLIGHT_PWM + if (!strcmp(peri->dev_name, DEV_NAME_PWM)) + continue; + #endif + } + #endif + } + debug("CPU : Clock Generator= %d EA, ", CLK_DEVS_NUM); +} diff --git a/arch/arm/mach-nexell/cmd_boot_linux.c b/arch/arm/mach-nexell/cmd_boot_linux.c new file mode 100644 index 0000000000..f2dedfe162 --- /dev/null +++ b/arch/arm/mach-nexell/cmd_boot_linux.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 nexell + * jhkim <jhkim@nexell.co.kr> + */ + +#include <common.h> +#include <bootm.h> +#include <command.h> +#include <environment.h> +#include <errno.h> +#include <image.h> +#include <fdt_support.h> + +#if !defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_CLI_FRAMEWORK) + +DECLARE_GLOBAL_DATA_PTR; + +static bootm_headers_t linux_images; + +static void boot_go_set_os(cmd_tbl_t *cmdtp, int flag, int argc, + char * const argv[], + bootm_headers_t *images) +{ + char * const img_addr = argv[0]; + + images->os.type = IH_TYPE_KERNEL; + images->os.comp = IH_COMP_NONE; + images->os.os = IH_OS_LINUX; + images->os.load = simple_strtoul(img_addr, NULL, 16); + images->ep = images->os.load; +#if defined(CONFIG_ARM) + images->os.arch = IH_ARCH_ARM; +#elif defined(CONFIG_ARM64) + images->os.arch = IH_ARCH_ARM64; +#else + #error "Not support architecture ..." +#endif + if (!IS_ENABLED(CONFIG_OF_LIBFDT) && !IS_ENABLED(CONFIG_SPL_BUILD)) { + /* set DTB address for linux kernel */ + if (argc > 2) { + unsigned long ft_addr; + + ft_addr = simple_strtol(argv[2], NULL, 16); + images->ft_addr = (char *)ft_addr; + + /* + * if not defined IMAGE_ENABLE_OF_LIBFDT, + * must be set to fdt address + */ + if (!IMAGE_ENABLE_OF_LIBFDT) + gd->bd->bi_boot_params = ft_addr; + + debug("## set ft:%08lx and boot params:%08lx [control of:%s]" + "...\n", ft_addr, gd->bd->bi_boot_params, + IMAGE_ENABLE_OF_LIBFDT ? "on" : "off"); + } + } +} + +#if defined(CONFIG_OF_LIBFDT) && defined(CONFIG_LMB) +static void boot_start_lmb(bootm_headers_t *images) +{ + ulong mem_start; + phys_size_t mem_size; + + lmb_init(&images->lmb); + + mem_start = getenv_bootm_low(); + mem_size = getenv_bootm_size(); + + lmb_add(&images->lmb, (phys_addr_t)mem_start, mem_size); + + arch_lmb_reserve(&images->lmb); + board_lmb_reserve(&images->lmb); +} +#else +#define lmb_reserve(lmb, base, size) +static inline void boot_start_lmb(bootm_headers_t *images) { } +#endif + +int do_boot_linux(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + boot_os_fn *boot_fn; + bootm_headers_t *images = &linux_images; + int flags; + int ret; + + boot_start_lmb(images); + + flags = BOOTM_STATE_START; + + argc--; argv++; + boot_go_set_os(cmdtp, flag, argc, argv, images); + + if (IS_ENABLED(CONFIG_OF_LIBFDT)) { + /* find flattened device tree */ + ret = boot_get_fdt(flag, argc, argv, IH_ARCH_DEFAULT, images, + &images->ft_addr, &images->ft_len); + if (ret) { + puts("Could not find a valid device tree\n"); + return 1; + } + set_working_fdt_addr((ulong)images->ft_addr); + } + + if (!IS_ENABLED(CONFIG_OF_LIBFDT)) + flags |= BOOTM_STATE_OS_GO; + + boot_fn = do_bootm_linux; + ret = boot_fn(flags, argc, argv, images); + + if (ret == BOOTM_ERR_UNIMPLEMENTED) + show_boot_progress(BOOTSTAGE_ID_DECOMP_UNIMPL); + else if (ret == BOOTM_ERR_RESET) + do_reset(cmdtp, flag, argc, argv); + + return ret; +} + +U_BOOT_CMD(bootl, CONFIG_SYS_MAXARGS, 1, do_boot_linux, + "boot linux image from memory", + "[addr [arg ...]]\n - boot linux image stored in memory\n" + "\tuse a '-' for the DTB address\n" +); +#endif + +#if defined(CONFIG_CMD_BOOTD) && !defined(CONFIG_CMD_BOOTM) +int do_bootd(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[]) +{ + return run_command(env_get("bootcmd"), flag); +} + +U_BOOT_CMD(boot, 1, 1, do_bootd, + "boot default, i.e., run 'bootcmd'", + "" +); + +/* keep old command name "bootd" for backward compatibility */ +U_BOOT_CMD(bootd, 1, 1, do_bootd, + "boot default, i.e., run 'bootcmd'", + "" +); +#endif diff --git a/arch/arm/mach-nexell/config.mk b/arch/arm/mach-nexell/config.mk new file mode 100644 index 0000000000..7b0662699c --- /dev/null +++ b/arch/arm/mach-nexell/config.mk @@ -0,0 +1,11 @@ +# +# (C) Copyright 2016 Nexell +# junghyun kim<jhkim@nexell.co.kr> +# +# SPDX-License-Identifier: GPL-2.0+ +# + +SOCDIR=CPUDIR/$(VENDOR) +MACHDIR=$(patsubst %,arch/arm/mach-%,$(machine-y)) + +LDPPFLAGS += -DMACHDIR=$(MACHDIR) -DSOCDIR=$(SOCDIR) diff --git a/arch/arm/mach-nexell/include/mach/boot0.h b/arch/arm/mach-nexell/include/mach/boot0.h new file mode 100644 index 0000000000..e05c07ece6 --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/boot0.h @@ -0,0 +1,40 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * NSIH (Nexell System Information Header) for FriendlyArm nanopi2 board + * + * The NSIH (first 512 Bytes of u-boot.bin) is necessary for the + * 2nd-Bootloader to get information like load address of U-Boot. + * + * 0x400 must be added to CONFIG_SYS_TEXT_BASE to have the actual load and + * start address because 2nd-Bootloader loads with an offset of 0x400 + * (NSIH + 0x200 bytes are not loaded into RAM). + * + * It has been tested / is working with the following 2nd-Bootloader: + * "BL1 by Nexell V1.0.0-gd551e13 [Built on 2018-01-25 16:58:29]" + * + * (C) Copyright 2020 Stefan Bosch <stefan_b@posteo.net> + */ + +#ifndef __BOOT0_H +#define __BOOT0_H + + ARM_VECTORS + .space 0x30 + .word (_end - _start) + 20 * 1024 /* 0x50: load size + * (bin + 20k for DTB) */ + .space 0x4 + .word CONFIG_SYS_TEXT_BASE + 0x400 /* 0x58: load address */ + .word 0x00000000 + .word CONFIG_SYS_TEXT_BASE + 0x400 /* 0x60: start address */ + .space 0x198 + .byte 'N' /* 0x1FC: "NSIH" signature */ + .byte 'S' + .byte 'I' + .byte 'H' + + /* The NSIH + 0x200 bytes are omitted by the 2nd-Bootloader */ + .space 0x200 +_start: + ARM_VECTORS + +#endif /* __BOOT0_H */ diff --git a/arch/arm/mach-nexell/include/mach/clk.h b/arch/arm/mach-nexell/include/mach/clk.h new file mode 100644 index 0000000000..cc5589adea --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/clk.h @@ -0,0 +1,24 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2016 Nexell + * Hyunseok, Jung <hsjung@nexell.co.kr> + */ + +#ifndef __ASM_ARM_ARCH_CLK_H_ +#define __ASM_ARM_ARCH_CLK_H_ + +struct clk { + unsigned long rate; +}; + +void clk_init(void); + +struct clk *clk_get(const char *id); +void clk_put(struct clk *clk); +unsigned long clk_get_rate(struct clk *clk); +long clk_round_rate(struct clk *clk, unsigned long rate); +int clk_set_rate(struct clk *clk, unsigned long rate); +int clk_enable(struct clk *clk); +void clk_disable(struct clk *clk); + +#endif diff --git a/arch/arm/mach-nexell/include/mach/display.h b/arch/arm/mach-nexell/include/mach/display.h new file mode 100644 index 0000000000..b167e63a5a --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/display.h @@ -0,0 +1,273 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * Copyright (C) 2016 Nexell Co., Ltd. + * + * Author: junghyun, kim <jhkim@nexell.co.kr> + */ + +#ifndef _NX__DISPLAY_H_ +#define _NX__DISPLAY_H_ + +#define DP_PLANS_NUM 3 + +/* the display output format. */ +#define DPC_FORMAT_RGB555 0 /* RGB555 Format */ +#define DPC_FORMAT_RGB565 1 /* RGB565 Format */ +#define DPC_FORMAT_RGB666 2 /* RGB666 Format */ +#define DPC_FORMAT_RGB888 3 /* RGB888 Format */ +#define DPC_FORMAT_MRGB555A 4 /* MRGB555A Format */ +#define DPC_FORMAT_MRGB555B 5 /* MRGB555B Format */ +#define DPC_FORMAT_MRGB565 6 /* MRGB565 Format */ +#define DPC_FORMAT_MRGB666 7 /* MRGB666 Format */ +#define DPC_FORMAT_MRGB888A 8 /* MRGB888A Format */ +#define DPC_FORMAT_MRGB888B 9 /* MRGB888B Format */ +#define DPC_FORMAT_CCIR656 10 /* ITU-R BT.656 / 601(8-bit) */ +#define DPC_FORMAT_CCIR601A 12 /* ITU-R BT.601A */ +#define DPC_FORMAT_CCIR601B 13 /* ITU-R BT.601B */ +#define DPC_FORMAT_4096COLOR 1 /* 4096 Color Format */ +#define DPC_FORMAT_16GRAY 3 /* 16 Level Gray Format */ + +/* layer pixel format. */ +#define MLC_RGBFMT_R5G6B5 0x44320000 /* {R5,G6,B5 }. */ +#define MLC_RGBFMT_B5G6R5 0xC4320000 /* {B5,G6,R5 }. */ +#define MLC_RGBFMT_X1R5G5B5 0x43420000 /* {X1,R5,G5,B5}. */ +#define MLC_RGBFMT_X1B5G5R5 0xC3420000 /* {X1,B5,G5,R5}. */ +#define MLC_RGBFMT_X4R4G4B4 0x42110000 /* {X4,R4,G4,B4}. */ +#define MLC_RGBFMT_X4B4G4R4 0xC2110000 /* {X4,B4,G4,R4}. */ +#define MLC_RGBFMT_X8R3G3B2 0x41200000 /* {X8,R3,G3,B2}. */ +#define MLC_RGBFMT_X8B3G3R2 0xC1200000 /* {X8,B3,G3,R2}. */ +#define MLC_RGBFMT_A1R5G5B5 0x33420000 /* {A1,R5,G5,B5}. */ +#define MLC_RGBFMT_A1B5G5R5 0xB3420000 /* {A1,B5,G5,R5}. */ +#define MLC_RGBFMT_A4R4G4B4 0x22110000 /* {A4,R4,G4,B4}. */ +#define MLC_RGBFMT_A4B4G4R4 0xA2110000 /* {A4,B4,G4,R4}. */ +#define MLC_RGBFMT_A8R3G3B2 0x11200000 /* {A8,R3,G3,B2}. */ +#define MLC_RGBFMT_A8B3G3R2 0x91200000 /* {A8,B3,G3,R2}. */ +#define MLC_RGBFMT_R8G8B8 0x46530000 /* {R8,G8,B8 }. */ +#define MLC_RGBFMT_B8G8R8 0xC6530000 /* {B8,G8,R8 }. */ +#define MLC_RGBFMT_X8R8G8B8 0x46530000 /* {X8,R8,G8,B8}. */ +#define MLC_RGBFMT_X8B8G8R8 0xC6530000 /* {X8,B8,G8,R8}. */ +#define MLC_RGBFMT_A8R8G8B8 0x06530000 /* {A8,R8,G8,B8}. */ +#define MLC_RGBFMT_A8B8G8R8 0x86530000 /* {A8,B8,G8,R8}. */ + +/* the data output order in case of ITU-R BT.656 / 601. */ +#define DPC_YCORDER_CBYCRY 0 +#define DPC_YCORDER_CRYCBY 1 +#define DPC_YCORDER_YCBYCR 2 +#define DPC_YCORDER_YCRYCB 3 + +/* the PAD output clock. */ +#define DPC_PADCLKSEL_VCLK 0 /* VCLK */ +#define DPC_PADCLKSEL_VCLK2 1 /* VCLK2 */ + +/* display sync info for DPC */ +struct dp_sync_info { + int interlace; + int h_active_len; + int h_sync_width; + int h_back_porch; + int h_front_porch; + int h_sync_invert; /* default active low */ + int v_active_len; + int v_sync_width; + int v_back_porch; + int v_front_porch; + int v_sync_invert; /* default active low */ + int pixel_clock_hz; /* HZ */ +}; + +/* syncgen control (DPC) */ +#define DP_SYNC_DELAY_RGB_PVD (1 << 0) +#define DP_SYNC_DELAY_HSYNC_CP1 (1 << 1) +#define DP_SYNC_DELAY_VSYNC_FRAM (1 << 2) +#define DP_SYNC_DELAY_DE_CP (1 << 3) + +struct dp_ctrl_info { + /* clock gen */ + int clk_src_lv0; + int clk_div_lv0; + int clk_src_lv1; + int clk_div_lv1; + /* scan format */ + int interlace; + /* syncgen format */ + unsigned int out_format; + int invert_field; /* 0:normal(Low odd), 1:invert (low even) */ + int swap_RB; + unsigned int yc_order; /* for CCIR output */ + /* extern sync delay */ + int delay_mask; /* if 0, set defalut delays */ + int d_rgb_pvd; /* delay for RGB/PVD, 0~16, default 0 */ + int d_hsync_cp1; /* delay for HSYNC/CP1, 0~63, default 12 */ + int d_vsync_fram; /* delay for VSYNC/FRAM, 0~63, default 12 */ + int d_de_cp2; /* delay for DE/CP2, 0~63, default 12 */ + /* sync offset */ + int vs_start_offset; /* start vsync offset, defatult 0 */ + int vs_end_offset; /* end vsync offset, default 0 */ + int ev_start_offset; /* start even vsync offset, default 0 */ + int ev_end_offset; /* end even vsync offset , default 0 */ + /* pad clock seletor */ + int vck_select; /* 0=vclk0, 1=vclk2 */ + int clk_inv_lv0; /* OUTCLKINVn */ + int clk_delay_lv0; /* OUTCLKDELAYn */ + int clk_inv_lv1; /* OUTCLKINVn */ + int clk_delay_lv1; /* OUTCLKDELAYn */ + int clk_sel_div1; /* 0=clk1_inv, 1=clk1_div_2_ns */ +}; + +/* multi layer control (MLC) */ +struct dp_plane_top { + int screen_width; + int screen_height; + int video_prior; /* 0: video>RGBn, 1: RGB0>video>RGB1, + * 2: RGB0 > RGB1 > video .. */ + int interlace; + int plane_num; + unsigned int back_color; +}; + +struct dp_plane_info { + int layer; + unsigned int fb_base; + int left; + int top; + int width; + int height; + int pixel_byte; + unsigned int format; + int alpha_on; + int alpha_depth; + int tp_on; /* transparency color enable */ + unsigned int tp_color; + unsigned int mem_lock_size; /* memory burst access (4,8,16) */ + int video_layer; + int enable; +}; + +/* + * LCD device dependency struct + * RGB, LVDS, MiPi, HDMI + */ +enum { + DP_DEVICE_RESCONV = 0, + DP_DEVICE_RGBLCD = 1, + DP_DEVICE_HDMI = 2, + DP_DEVICE_MIPI = 3, + DP_DEVICE_LVDS = 4, + DP_DEVICE_CVBS = 5, + DP_DEVICE_DP0 = 6, + DP_DEVICE_DP1 = 7, + DP_DEVICE_END, +}; + +enum { + DP_CLOCK_RESCONV = 0, + DP_CLOCK_LCDIF = 1, + DP_CLOCK_MIPI = 2, + DP_CLOCK_LVDS = 3, + DP_CLOCK_HDMI = 4, + DP_CLOCK_END, +}; + +enum dp_lvds_format { + DP_LVDS_FORMAT_VESA = 0, + DP_LVDS_FORMAT_JEIDA = 1, + DP_LVDS_FORMAT_LOC = 2, +}; + +#define DEF_VOLTAGE_LEVEL (0x20) + +struct dp_lvds_dev { + enum dp_lvds_format lvds_format; /* 0:VESA, 1:JEIDA, 2: Location */ + int pol_inv_hs; /* hsync polarity invert for VESA, JEIDA */ + int pol_inv_vs; /* bsync polarity invert for VESA, JEIDA */ + int pol_inv_de; /* de polarity invert for VESA, JEIDA */ + int pol_inv_ck; /* input clock(pixel clock) polarity invert */ + int voltage_level; + /* Location setting */ + unsigned int loc_map[9]; /* Location Setting */ + unsigned int loc_mask[2]; /* Location Setting, 0 ~ 34 */ + unsigned int loc_pol[2]; /* Location Setting, 0 ~ 34 */ +}; + +#include "mipi_display.h" + +struct dp_mipi_dev { + int lp_bitrate; /* to lcd setup, low power bitrate (150, 100, 80 Mhz) */ + int hs_bitrate; /* to lcd data, high speed bitrate (1000, ... Mhz) */ + int lpm_trans; + int command_mode; + unsigned int hs_pllpms; + unsigned int hs_bandctl; + unsigned int lp_pllpms; + unsigned int lp_bandctl; + struct mipi_dsi_device dsi; +}; + +struct dp_rgb_dev { + int lcd_mpu_type; +}; + +struct dp_hdmi_dev { + int preset; +}; + +/* platform data for the driver model */ +struct nx_display_platdata { + int module; + struct dp_sync_info sync; + struct dp_ctrl_info ctrl; + struct dp_plane_top top; + struct dp_plane_info plane[DP_PLANS_NUM]; + int dev_type; + void *device; +}; + +/* Lcd api */ +void nx_lvds_display(int module, + struct dp_sync_info *sync, struct dp_ctrl_info *ctrl, + struct dp_plane_top *top, + struct dp_plane_info *planes, + struct dp_lvds_dev *dev); + +void nx_rgb_display(int module, + struct dp_sync_info *sync, struct dp_ctrl_info *ctrl, + struct dp_plane_top *top, struct dp_plane_info *planes, + struct dp_rgb_dev *dev); + +void nx_hdmi_display(int module, + struct dp_sync_info *sync, struct dp_ctrl_info *ctrl, + struct dp_plane_top *top, + struct dp_plane_info *planes, + struct dp_hdmi_dev *dev); + +void nx_mipi_display(int module, + struct dp_sync_info *sync, struct dp_ctrl_info *ctrl, + struct dp_plane_top *top, + struct dp_plane_info *planes, + struct dp_mipi_dev *dev); + +int nx_mipi_dsi_lcd_bind(struct mipi_dsi_device *dsi); + +/* disaply api */ +void dp_control_init(int module); +int dp_control_setup(int module, struct dp_sync_info *sync, + struct dp_ctrl_info *ctrl); +void dp_control_enable(int module, int on); + +void dp_plane_init(int module); +int dp_plane_screen_setup(int module, struct dp_plane_top *top); +void dp_plane_screen_enable(int module, int on); + +int dp_plane_layer_setup(int module, struct dp_plane_info *plane); +void dp_plane_layer_enable(int module, struct dp_plane_info *plane, int on); + +int dp_plane_set_enable(int module, int layer, int on); +int dp_plane_set_address(int module, int layer, unsigned int address); +int dp_plane_wait_vsync(int module, int layer, int fps); + +#if defined CONFIG_SPL_BUILD || \ + (!defined(CONFIG_DM) && !defined(CONFIG_OF_CONTROL)) +int nx_display_probe(struct nx_display_platdata *plat); +#endif + +#endif diff --git a/arch/arm/mach-nexell/include/mach/display_dev.h b/arch/arm/mach-nexell/include/mach/display_dev.h new file mode 100644 index 0000000000..77eb614768 --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/display_dev.h @@ -0,0 +1,37 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * Copyright (C) 2016 Nexell Co., Ltd. + * + * Author: junghyun, kim <jhkim@nexell.co.kr> + */ + +#ifndef _NX__DISPLAY_DEV_H_ +#define _NX__DISPLAY_DEV_H_ + +#if defined CONFIG_VIDEO || defined CONFIG_DM_VIDEO +#include <video_fb.h> +#elif defined CONFIG_LCD +#include <lcd.h> +#endif + +struct nx_display_dev { +#if defined CONFIG_VIDEO || defined CONFIG_DM_VIDEO + GraphicDevice graphic_device; +#elif defined CONFIG_LCD + vidinfo_t *panel_info; +#endif + unsigned long base; + int module; + struct dp_sync_info sync; + struct dp_ctrl_info ctrl; + struct dp_plane_top top; + struct dp_plane_info planes[DP_PLANS_NUM]; + int dev_type; + void *device; + struct dp_plane_info *fb_plane; + unsigned int depth; /* byte per pixel */ + unsigned int fb_addr; + unsigned int fb_size; +}; + +#endif diff --git a/arch/arm/mach-nexell/include/mach/ehci.h b/arch/arm/mach-nexell/include/mach/ehci.h new file mode 100644 index 0000000000..545153b145 --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/ehci.h @@ -0,0 +1,106 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * NEXELL USB HOST EHCI Controller + * + * (C) Copyright 2016 Nexell + * Hyunseok, Jung <hsjung@nexell.co.kr> + */ + +#ifndef __ASM_ARM_ARCH_EHCI_H__ +#define __ASM_ARM_ARCH_EHCI_H__ + +/* Nexell USBHOST PHY registers */ + +/* USBHOST Configuration 0 Register */ +#define NX_HOST_CON0 0x14 +#define NX_HOST_CON0_SS_WORD_IF BIT(26) +#define NX_HOST_CON0_SS_WORD_IF_ENB BIT(25) +#define NX_HOST_CON0_SS_WORD_IF_16 ( \ + NX_HOST_CON0_SS_WORD_IF | \ + NX_HOST_CON0_SS_WORD_IF_ENB) + +#define NX_HOST_CON0_HSIC_480M_FROM_OTG_PHY BIT(24) +#define NX_HOST_CON0_HSIC_FREE_CLOCK_ENB BIT(23) +#define NX_HOST_CON0_HSIC_CLK_MASK (0x3 << 23) + +#define NX_HOST_CON0_N_HOST_HSIC_RESET_SYNC BIT(22) +#define NX_HOST_CON0_N_HOST_UTMI_RESET_SYNC BIT(21) +#define NX_HOST_CON0_N_HOST_PHY_RESET_SYNC BIT(20) +#define NX_HOST_CON0_UTMI_RESET_SYNC ( \ + NX_HOST_CON0_N_HOST_HSIC_RESET_SYNC | \ + NX_HOST_CON0_N_HOST_UTMI_RESET_SYNC | \ + NX_HOST_CON0_N_HOST_PHY_RESET_SYNC) + +#define NX_HOST_CON0_N_AUXWELL_RESET_SYNC BIT(19) +#define NX_HOST_CON0_N_OHCI_RESET_SYNC BIT(18) +#define NX_HOST_CON0_N_RESET_SYNC BIT(17) +#define NX_HOST_CON0_AHB_RESET_SYNC ( \ + NX_HOST_CON0_N_AUXWELL_RESET_SYNC | \ + NX_HOST_CON0_N_OHCI_RESET_SYNC | \ + NX_HOST_CON0_N_RESET_SYNC) + +#define NX_HOST_CON0_HSIC_EN_PORT1 (0x2 << 14) +#define NX_HOST_CON0_HSIC_EN_MASK (0x7 << 14) + +/* USBHOST Configuration 1 Register */ +#define NX_HOST_CON1 0x18 + +/* USBHOST Configuration 2 Register */ +#define NX_HOST_CON2 0x1C +#define NX_HOST_CON2_SS_ENA_INCRX_ALIGN (0x1 << 28) +#define NX_HOST_CON2_SS_ENA_INCR4 (0x1 << 27) +#define NX_HOST_CON2_SS_ENA_INCR8 (0x1 << 26) +#define NX_HOST_CON2_SS_ENA_INCR16 (0x1 << 25) +#define NX_HOST_CON2_SS_DMA_BURST_MASK \ + (NX_HOST_CON2_SS_ENA_INCR16 | NX_HOST_CON2_SS_ENA_INCR8 | \ + NX_HOST_CON2_SS_ENA_INCR4 | NX_HOST_CON2_SS_ENA_INCRX_ALIGN) + +#define NX_HOST_CON2_EHCI_SS_ENABLE_DMA_BURST \ + (NX_HOST_CON2_SS_ENA_INCR16 | NX_HOST_CON2_SS_ENA_INCR8 | \ + NX_HOST_CON2_SS_ENA_INCR4 | NX_HOST_CON2_SS_ENA_INCRX_ALIGN) + +#define NX_HOST_CON2_OHCI_SS_ENABLE_DMA_BURST \ + (NX_HOST_CON2_SS_ENA_INCR4 | NX_HOST_CON2_SS_ENA_INCRX_ALIGN) + +#define NX_HOST_CON2_SS_FLADJ_VAL_0_OFFSET (21) +#define NX_HOST_CON2_SS_FLADJ_VAL_OFFSET (3) +#define NX_HOST_CON2_SS_FLADJ_VAL_NUM (6) +#define NX_HOST_CON2_SS_FLADJ_VAL_0_SEL BIT(5) +#define NX_HOST_CON2_SS_FLADJ_VAL_MAX 0x7 + +/* USBHOST Configuration 3 Register */ +#define NX_HOST_CON3 0x20 +#define NX_HOST_CON3_POR BIT(8) +#define NX_HOST_CON3_POR_ENB BIT(7) +#define NX_HOST_CON3_POR_MASK (0x3 << 7) + +/* USBHOST Configuration 4 Register */ +#define NX_HOST_CON4 0x24 +#define NX_HOST_CON4_WORDINTERFACE BIT(9) +#define NX_HOST_CON4_WORDINTERFACE_ENB BIT(8) +#define NX_HOST_CON4_WORDINTERFACE_16 ( \ + NX_HOST_CON4_WORDINTERFACE | \ + NX_HOST_CON4_WORDINTERFACE_ENB) + +/* USBHOST Configuration 5 Register */ +#define NX_HOST_CON5 0x28 +#define NX_HOST_CON5_HSIC_POR BIT(19) +#define NX_HOST_CON5_HSIC_POR_ENB BIT(18) +#define NX_HOST_CON5_HSIC_POR_MASK (0x3 << 18) + +/* USBHOST Configuration 6 Register */ +#define NX_HOST_CON6 0x2C +#define NX_HOST_CON6_HSIC_WORDINTERFACE BIT(13) +#define NX_HOST_CON6_HSIC_WORDINTERFACE_ENB BIT(12) +#define NX_HOST_CON6_HSIC_WORDINTERFACE_16 ( \ + NX_HOST_CON6_HSIC_WORDINTERFACE | \ + NX_HOST_CON6_HSIC_WORDINTERFACE_ENB) + +/* Register map for PHY control */ +struct nx_usb_phy { + unsigned int reserved; + unsigned int others[4]; + unsigned int usbhost_con[7]; +}; + +#endif /* __ASM_ARM_ARCH_EHCI_H__ */ diff --git a/arch/arm/mach-nexell/include/mach/gpio.h b/arch/arm/mach-nexell/include/mach/gpio.h new file mode 100644 index 0000000000..7167d3cf5b --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/gpio.h @@ -0,0 +1,17 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2016 Nexell + * DeokJin, Lee <truevirtue@nexell.co.kr> + */ + +#ifndef __ASM_ARCH_NEXELL_GPIO_H +#define __ASM_ARCH_NEXELL_GPIO_H + +#include <asm/io.h> +#include <linux/errno.h> + +#define PIN_BASE 0 + +#define MAX_GPIO_BANKS 5 + +#endif /* __ASM_ARCH_NEXELL_GPIO_H */ diff --git a/arch/arm/mach-nexell/include/mach/mipi_display.h b/arch/arm/mach-nexell/include/mach/mipi_display.h new file mode 100644 index 0000000000..f3fdec6464 --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/mipi_display.h @@ -0,0 +1,215 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * Defines for Mobile Industry Processor Interface (MIPI(R)) + * Display Working Group standards: DSI, DCS, DBI, DPI + * + * Copyright (C) 2010 Guennadi Liakhovetski <g.liakhovetski@gmx.de> + * Copyright (C) 2006 Nokia Corporation + * Author: Imre Deak <imre.deak@nokia.com> + */ + +#ifndef MIPI_DISPLAY_H +#define MIPI_DISPLAY_H + +/* MIPI DSI Processor-to-Peripheral transaction types */ +enum { + MIPI_DSI_V_SYNC_START = 0x01, + MIPI_DSI_V_SYNC_END = 0x11, + MIPI_DSI_H_SYNC_START = 0x21, + MIPI_DSI_H_SYNC_END = 0x31, + + MIPI_DSI_COLOR_MODE_OFF = 0x02, + MIPI_DSI_COLOR_MODE_ON = 0x12, + MIPI_DSI_SHUTDOWN_PERIPHERAL = 0x22, + MIPI_DSI_TURN_ON_PERIPHERAL = 0x32, + + MIPI_DSI_GENERIC_SHORT_WRITE_0_PARAM = 0x03, + MIPI_DSI_GENERIC_SHORT_WRITE_1_PARAM = 0x13, + MIPI_DSI_GENERIC_SHORT_WRITE_2_PARAM = 0x23, + + MIPI_DSI_GENERIC_READ_REQUEST_0_PARAM = 0x04, + MIPI_DSI_GENERIC_READ_REQUEST_1_PARAM = 0x14, + MIPI_DSI_GENERIC_READ_REQUEST_2_PARAM = 0x24, + + MIPI_DSI_DCS_SHORT_WRITE = 0x05, + MIPI_DSI_DCS_SHORT_WRITE_PARAM = 0x15, + + MIPI_DSI_DCS_READ = 0x06, + + MIPI_DSI_SET_MAXIMUM_RETURN_PACKET_SIZE = 0x37, + + MIPI_DSI_END_OF_TRANSMISSION = 0x08, + + MIPI_DSI_NULL_PACKET = 0x09, + MIPI_DSI_BLANKING_PACKET = 0x19, + MIPI_DSI_GENERIC_LONG_WRITE = 0x29, + MIPI_DSI_DCS_LONG_WRITE = 0x39, + + MIPI_DSI_LOOSELY_PACKED_PIXEL_STREAM_YCBCR20 = 0x0c, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR24 = 0x1c, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR16 = 0x2c, + + MIPI_DSI_PACKED_PIXEL_STREAM_30 = 0x0d, + MIPI_DSI_PACKED_PIXEL_STREAM_36 = 0x1d, + MIPI_DSI_PACKED_PIXEL_STREAM_YCBCR12 = 0x3d, + + MIPI_DSI_PACKED_PIXEL_STREAM_16 = 0x0e, + MIPI_DSI_PACKED_PIXEL_STREAM_18 = 0x1e, + MIPI_DSI_PIXEL_STREAM_3BYTE_18 = 0x2e, + MIPI_DSI_PACKED_PIXEL_STREAM_24 = 0x3e, +}; + +/* MIPI DSI Peripheral-to-Processor transaction types */ +enum { + MIPI_DSI_RX_ACKNOWLEDGE_AND_ERROR_REPORT = 0x02, + MIPI_DSI_RX_END_OF_TRANSMISSION = 0x08, + MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_1BYTE = 0x11, + MIPI_DSI_RX_GENERIC_SHORT_READ_RESPONSE_2BYTE = 0x12, + MIPI_DSI_RX_GENERIC_LONG_READ_RESPONSE = 0x1a, + MIPI_DSI_RX_DCS_LONG_READ_RESPONSE = 0x1c, + MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_1BYTE = 0x21, + MIPI_DSI_RX_DCS_SHORT_READ_RESPONSE_2BYTE = 0x22, +}; + +/* MIPI DCS commands */ +enum { + MIPI_DCS_NOP = 0x00, + MIPI_DCS_SOFT_RESET = 0x01, + MIPI_DCS_GET_DISPLAY_ID = 0x04, + MIPI_DCS_GET_RED_CHANNEL = 0x06, + MIPI_DCS_GET_GREEN_CHANNEL = 0x07, + MIPI_DCS_GET_BLUE_CHANNEL = 0x08, + MIPI_DCS_GET_DISPLAY_STATUS = 0x09, + MIPI_DCS_GET_POWER_MODE = 0x0A, + MIPI_DCS_GET_ADDRESS_MODE = 0x0B, + MIPI_DCS_GET_PIXEL_FORMAT = 0x0C, + MIPI_DCS_GET_DISPLAY_MODE = 0x0D, + MIPI_DCS_GET_SIGNAL_MODE = 0x0E, + MIPI_DCS_GET_DIAGNOSTIC_RESULT = 0x0F, + MIPI_DCS_ENTER_SLEEP_MODE = 0x10, + MIPI_DCS_EXIT_SLEEP_MODE = 0x11, + MIPI_DCS_ENTER_PARTIAL_MODE = 0x12, + MIPI_DCS_ENTER_NORMAL_MODE = 0x13, + MIPI_DCS_EXIT_INVERT_MODE = 0x20, + MIPI_DCS_ENTER_INVERT_MODE = 0x21, + MIPI_DCS_SET_GAMMA_CURVE = 0x26, + MIPI_DCS_SET_DISPLAY_OFF = 0x28, + MIPI_DCS_SET_DISPLAY_ON = 0x29, + MIPI_DCS_SET_COLUMN_ADDRESS = 0x2A, + MIPI_DCS_SET_PAGE_ADDRESS = 0x2B, + MIPI_DCS_WRITE_MEMORY_START = 0x2C, + MIPI_DCS_WRITE_LUT = 0x2D, + MIPI_DCS_READ_MEMORY_START = 0x2E, + MIPI_DCS_SET_PARTIAL_AREA = 0x30, + MIPI_DCS_SET_SCROLL_AREA = 0x33, + MIPI_DCS_SET_TEAR_OFF = 0x34, + MIPI_DCS_SET_TEAR_ON = 0x35, + MIPI_DCS_SET_ADDRESS_MODE = 0x36, + MIPI_DCS_SET_SCROLL_START = 0x37, + MIPI_DCS_EXIT_IDLE_MODE = 0x38, + MIPI_DCS_ENTER_IDLE_MODE = 0x39, + MIPI_DCS_SET_PIXEL_FORMAT = 0x3A, + MIPI_DCS_WRITE_MEMORY_CONTINUE = 0x3C, + MIPI_DCS_READ_MEMORY_CONTINUE = 0x3E, + MIPI_DCS_SET_TEAR_SCANLINE = 0x44, + MIPI_DCS_GET_SCANLINE = 0x45, + MIPI_DCS_READ_DDB_START = 0xA1, + MIPI_DCS_READ_DDB_CONTINUE = 0xA8, +}; + +/* MIPI DCS pixel formats */ +#define MIPI_DCS_PIXEL_FMT_24BIT 7 +#define MIPI_DCS_PIXEL_FMT_18BIT 6 +#define MIPI_DCS_PIXEL_FMT_16BIT 5 +#define MIPI_DCS_PIXEL_FMT_12BIT 3 +#define MIPI_DCS_PIXEL_FMT_8BIT 2 +#define MIPI_DCS_PIXEL_FMT_3BIT 1 + +/* request ACK from peripheral */ +#define MIPI_DSI_MSG_REQ_ACK BIT(0) +/* use Low Power Mode to transmit message */ +#define MIPI_DSI_MSG_USE_LPM BIT(1) + +/** + * struct mipi_dsi_msg - read/write DSI buffer + * @channel: virtual channel id + * @type: payload data type + * @flags: flags controlling this message transmission + * @tx_len: length of @tx_buf + * @tx_buf: data to be written + * @rx_len: length of @rx_buf + * @rx_buf: data to be read, or NULL + */ +struct mipi_dsi_msg { + u8 channel; /* virtual channel id */ + u8 type; /* payload data type */ + u16 flags; /* flags controlling this message transmission */ + size_t tx_len; + const void *tx_buf; + size_t rx_len; + void *rx_buf; +}; + +/* DSI mode flags */ + +/* video mode */ +#define MIPI_DSI_MODE_VIDEO BIT(0) +/* video burst mode */ +#define MIPI_DSI_MODE_VIDEO_BURST BIT(1) +/* video pulse mode */ +#define MIPI_DSI_MODE_VIDEO_SYNC_PULSE BIT(2) +/* enable auto vertical count mode */ +#define MIPI_DSI_MODE_VIDEO_AUTO_VERT BIT(3) +/* enable hsync-end packets in vsync-pulse and v-porch area */ +#define MIPI_DSI_MODE_VIDEO_HSE BIT(4) +/* disable hfront-porch area */ +#define MIPI_DSI_MODE_VIDEO_HFP BIT(5) +/* disable hback-porch area */ +#define MIPI_DSI_MODE_VIDEO_HBP BIT(6) +/* disable hsync-active area */ +#define MIPI_DSI_MODE_VIDEO_HSA BIT(7) +/* flush display FIFO on vsync pulse */ +#define MIPI_DSI_MODE_VSYNC_FLUSH BIT(8) +/* disable EoT packets in HS mode */ +#define MIPI_DSI_MODE_EOT_PACKET BIT(9) +/* device supports non-continuous clock behavior (DSI spec 5.6.1) */ +#define MIPI_DSI_CLOCK_NON_CONTINUOUS BIT(10) +/* transmit data in low power */ +#define MIPI_DSI_MODE_LPM BIT(11) /* DSI mode flags */ + +enum mipi_dsi_pixel_format { + MIPI_DSI_FMT_RGB888, + MIPI_DSI_FMT_RGB666, + MIPI_DSI_FMT_RGB666_PACKED, + MIPI_DSI_FMT_RGB565, +}; + +/** + * struct mipi_dsi_device - DSI peripheral device + * @host: DSI host for this peripheral + * @dev: driver model device node for this peripheral + * @channel: virtual channel assigned to the peripheral + * @format: pixel format for video mode + * @lanes: number of active data lanes + * @mode_flags: DSI operation mode related flags + */ +struct mipi_dsi_device { + unsigned int channel; + unsigned int lanes; + enum mipi_dsi_pixel_format format; + unsigned long mode_flags; + struct mipi_panel_ops *ops; + ssize_t (*write_buffer)(struct mipi_dsi_device *dsi, + const void *data, size_t len); +}; + +struct mipi_panel_ops { + int (*init)(struct mipi_dsi_device *dsi, int width, int height); + int (*prepare)(struct mipi_dsi_device *dsi); + int (*unprepare)(struct mipi_dsi_device *dsi); + int (*enable)(struct mipi_dsi_device *dsi); + int (*disable)(struct mipi_dsi_device *dsi); + void *private_data; +}; + +#endif diff --git a/arch/arm/mach-nexell/include/mach/nexell.h b/arch/arm/mach-nexell/include/mach/nexell.h new file mode 100644 index 0000000000..e42805fa01 --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/nexell.h @@ -0,0 +1,352 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2016 Nexell + * Hyunseok, Jung <hsjung@nexell.co.kr> + */ + +#ifndef __NEXELL_H__ +#define __NEXELL_H__ + +#define PHY_BASEADDR_DMA0 (0xC0000000) +#define PHY_BASEADDR_DMA1 (0xC0001000) +#if defined(CONFIG_ARCH_S5P4418) +#define PHY_BASEADDR_INTC0 (0xC0002000) +#define PHY_BASEADDR_INTC1 (0xC0003000) +#elif defined(CONFIG_ARCH_S5P6818) +#define PHY_BASEADDR_INTC (0xC0008000) +#endif +#define PHY_BASEADDR_CLKPWR (0xC0010000) +#define PHY_BASEADDR_RTC (0xC0010C00) +#define PHY_BASEADDR_ALIVE (0xC0010800) +#define PHY_BASEADDR_RSTCON (0xC0012000) +#define PHY_BASEADDR_TIEOFF (0xC0011000) +#define PHY_BASEADDR_PDM (0xC0014000) +#define PHY_BASEADDR_CRYPTO (0xC0015000) +#define PHY_BASEADDR_TIMER (0xC0017000) +#define PHY_BASEADDR_PWM (0xC0018000) +#define PHY_BASEADDR_WDT (0xC0019000) +#define PHY_BASEADDR_GPIOA (0xC001A000) +#define PHY_BASEADDR_GPIOB (0xC001B000) +#define PHY_BASEADDR_GPIOC (0xC001C000) +#define PHY_BASEADDR_GPIOD (0xC001D000) +#define PHY_BASEADDR_GPIOE (0xC001E000) +#define PHY_BASEADDR_OHCI (0xC0020000) +#define PHY_BASEADDR_EHCI (0xC0030000) +#define PHY_BASEADDR_HSOTG (0xC0040000) +#define PHY_BASEADDR_ADC (0xC0053000) +#define PHY_BASEADDR_PPM (0xC0054000) +#define PHY_BASEADDR_I2S0 (0xC0055000) +#define PHY_BASEADDR_I2S1 (0xC0056000) +#define PHY_BASEADDR_I2S2 (0xC0057000) +#define PHY_BASEADDR_AC97 (0xC0058000) +#define PHY_BASEADDR_SPDIF_TX (0xC0059000) +#define PHY_BASEADDR_SPDIF_RX (0xC005A000) +#define PHY_BASEADDR_SSP0 (0xC005B000) +#define PHY_BASEADDR_SSP1 (0xC005C000) +#define PHY_BASEADDR_SSP2 (0xC005F000) +#define PHY_BASEADDR_MPEGTSI (0xC005D000) +#define PHY_BASEADDR_GMAC (0xC0060000) +#define PHY_BASEADDR_VIP0 (0xC0063000) +#define PHY_BASEADDR_VIP1 (0xC0064000) +#if defined(CONFIG_ARCH_S5P6818) +#define PHY_BASEADDR_VIP2 (0xC0099000) +#endif +#define PHY_BASEADDR_DEINTERLACE (0xC0065000) +#define PHY_BASEADDR_SCALER (0xC0066000) +#define PHY_BASEADDR_ECID (0xC0067000) +#define PHY_BASEADDR_SDMMC0 (0xC0062000) +#define PHY_BASEADDR_SDMMC1 (0xC0068000) +#define PHY_BASEADDR_SDMMC2 (0xC0069000) +#define PHY_BASEADDR_MALI400 (0xC0070000) +#define PHY_BASEADDR_CODA_APB0 (0xC0080000) +#define PHY_BASEADDR_CODA_APB1 (0xC0081000) +#define PHY_BASEADDR_CODA_APB2 (0xC0082000) +#define PHY_BASEADDR_CODA_APB3 (0xC0083000) +/* dma (O), modem(X), UART0_MODULE */ +#define PHY_BASEADDR_UART0 (0xC00A1000) +/* dma (O), modem(O), pl01115_Uart_modem_MODULE */ +#define PHY_BASEADDR_UART1 (0xC00A0000) +/* dma (O), modem(X), UART1_MODULE */ +#define PHY_BASEADDR_UART2 (0xC00A2000) +/* dma (X), modem(X), pl01115_Uart_nodma0_MODULE */ +#define PHY_BASEADDR_UART3 (0xC00A3000) +/* dma (X), modem(X), pl01115_Uart_nodma1_MODULE */ +#define PHY_BASEADDR_UART4 (0xC006D000) +/* dma (X), modem(X), pl01115_Uart_nodma2_MODULE */ +#define PHY_BASEADDR_UART5 (0xC006F000) +#define PHY_BASEADDR_I2C0 (0xC00A4000) +#define PHY_BASEADDR_I2C1 (0xC00A5000) +#define PHY_BASEADDR_I2C2 (0xC00A6000) +#define PHY_BASEADDR_CAN0 (0xC00CE000) +#define PHY_BASEADDR_CAN1 (0xC00CF000) +#define PHY_BASEADDR_MIPI (0xC00D0000) +#define PHY_BASEADDR_DISPLAYTOP (0xC0100000) + +#define PHY_BASEADDR_CLKGEN0 (0xC00BB000) /* TIMER_1 */ +#define PHY_BASEADDR_CLKGEN1 (0xC00BC000) /* TIMER_2 */ +#define PHY_BASEADDR_CLKGEN2 (0xC00BD000) /* TIMER_3 */ +#define PHY_BASEADDR_CLKGEN3 (0xC00BE000) /* PWM_1 */ +#define PHY_BASEADDR_CLKGEN4 (0xC00BF000) /* PWM_2 */ +#define PHY_BASEADDR_CLKGEN5 (0xC00C0000) /* PWM_3 */ +#define PHY_BASEADDR_CLKGEN6 (0xC00AE000) /* I2C_0 */ +#define PHY_BASEADDR_CLKGEN7 (0xC00AF000) /* I2C_1 */ +#define PHY_BASEADDR_CLKGEN8 (0xC00B0000) /* I2C_2 */ +#define PHY_BASEADDR_CLKGEN9 (0xC00CA000) /* MIPI */ +#define PHY_BASEADDR_CLKGEN10 (0xC00C8000) /* GMAC */ +#define PHY_BASEADDR_CLKGEN11 (0xC00B8000) /* SPDIF_TX */ +#define PHY_BASEADDR_CLKGEN12 (0xC00B7000) /* MPEGTSI */ +#define PHY_BASEADDR_CLKGEN13 (0xC00BA000) /* PWM_0 */ +#define PHY_BASEADDR_CLKGEN14 (0xC00B9000) /* TIMER_0 */ +#define PHY_BASEADDR_CLKGEN15 (0xC00B2000) /* I2S_0 */ +#define PHY_BASEADDR_CLKGEN16 (0xC00B3000) /* I2S_1 */ +#define PHY_BASEADDR_CLKGEN17 (0xC00B4000) /* I2S_2 */ +#define PHY_BASEADDR_CLKGEN18 (0xC00C5000) /* SDHC_0 */ +#define PHY_BASEADDR_CLKGEN19 (0xC00CC000) /* SDHC_1 */ +#define PHY_BASEADDR_CLKGEN20 (0xC00CD000) /* SDHC_2 */ +#define PHY_BASEADDR_CLKGEN21 (0xC00C3000) /* MALI */ +#define PHY_BASEADDR_CLKGEN22 (0xC00A9000) /* UART_0 */ +#define PHY_BASEADDR_CLKGEN23 (0xC00AA000) /* UART_2 */ +#define PHY_BASEADDR_CLKGEN24 (0xC00A8000) /* UART_1 */ +#define PHY_BASEADDR_CLKGEN25 (0xC00AB000) /* UART_3 */ +#define PHY_BASEADDR_CLKGEN26 (0xC006E000) /* UART_4 */ +#define PHY_BASEADDR_CLKGEN27 (0xC00B1000) /* UART_5 */ +#define PHY_BASEADDR_CLKGEN28 (0xC00B5000) /* DEINTERLACE */ +#define PHY_BASEADDR_CLKGEN29 (0xC00C4000) /* PPM */ +#define PHY_BASEADDR_CLKGEN30 (0xC00C1000) /* VIP_0 */ +#define PHY_BASEADDR_CLKGEN31 (0xC00C2000) /* VIP_1 */ +#define PHY_BASEADDR_CLKGEN32 (0xC006B000) /* USB2HOST */ +#define PHY_BASEADDR_CLKGEN33 (0xC00C7000) /* CODA */ +#define PHY_BASEADDR_CLKGEN34 (0xC00C6000) /* CRYPTO */ +#define PHY_BASEADDR_CLKGEN35 (0xC00B6000) /* SCALER */ +#define PHY_BASEADDR_CLKGEN36 (0xC00CB000) /* PDM */ +#define PHY_BASEADDR_CLKGEN37 (0xC00AC000) /* SPI0 */ +#define PHY_BASEADDR_CLKGEN38 (0xC00AD000) /* SPI1 */ +#define PHY_BASEADDR_CLKGEN39 (0xC00A7000) /* SPI2 */ +#if defined(CONFIG_ARCH_S5P6818) +#define PHY_BASEADDR_CLKGEN40 (0xC009A000) +#endif +#define PHY_BASEADDR_DREX (0xC00E0000) + +#define PHY_BASEADDR_CS_NAND (0x2C000000) + +#define PHY_BASEADDR_SRAM (0xFFFF0000) + +/* + * Nexell clock generator + */ +#define CLK_ID_TIMER_1 0 +#define CLK_ID_TIMER_2 1 +#define CLK_ID_TIMER_3 2 +#define CLK_ID_PWM_1 3 +#define CLK_ID_PWM_2 4 +#define CLK_ID_PWM_3 5 +#define CLK_ID_I2C_0 6 +#define CLK_ID_I2C_1 7 +#define CLK_ID_I2C_2 8 +#define CLK_ID_MIPI 9 +#define CLK_ID_GMAC 10 /* External Clock 1 */ +#define CLK_ID_SPDIF_TX 11 +#define CLK_ID_MPEGTSI 12 +#define CLK_ID_PWM_0 13 +#define CLK_ID_TIMER_0 14 +#define CLK_ID_I2S_0 15 /* External Clock 1 */ +#define CLK_ID_I2S_1 16 /* External Clock 1 */ +#define CLK_ID_I2S_2 17 /* External Clock 1 */ +#define CLK_ID_SDHC_0 18 +#define CLK_ID_SDHC_1 19 +#define CLK_ID_SDHC_2 20 +#define CLK_ID_MALI 21 +#define CLK_ID_UART_0 22 /* UART0_MODULE */ +#define CLK_ID_UART_2 23 /* UART1_MODULE */ +#define CLK_ID_UART_1 24 /* pl01115_Uart_modem_MODULE */ +#define CLK_ID_UART_3 25 /* pl01115_Uart_nodma0_MODULE */ +#define CLK_ID_UART_4 26 /* pl01115_Uart_nodma1_MODULE */ +#define CLK_ID_UART_5 27 /* pl01115_Uart_nodma2_MODULE */ +#define CLK_ID_DIT 28 +#define CLK_ID_PPM 29 +#define CLK_ID_VIP_0 30 /* External Clock 1 */ +#define CLK_ID_VIP_1 31 /* External Clock 1, 2 */ +#define CLK_ID_USB2HOST 32 /* External Clock 2 */ +#define CLK_ID_CODA 33 +#define CLK_ID_CRYPTO 34 +#define CLK_ID_SCALER 35 +#define CLK_ID_PDM 36 +#define CLK_ID_SPI_0 37 +#define CLK_ID_SPI_1 38 +#define CLK_ID_SPI_2 39 +#define CLK_ID_MAX 39 + +/* + * Nexell Reset control + */ +#define RESET_ID_AC97 0 +#define RESET_ID_CPU1 1 +#define RESET_ID_CPU2 2 +#define RESET_ID_CPU3 3 +#define RESET_ID_WD1 4 +#define RESET_ID_WD2 5 +#define RESET_ID_WD3 6 +#define RESET_ID_CRYPTO 7 +#define RESET_ID_DEINTERLACE 8 +#define RESET_ID_DISP_TOP 9 +#define RESET_ID_DISPLAY 10 +#define RESET_ID_RESCONV 11 +#define RESET_ID_LCDIF 12 +#define RESET_ID_HDMI 13 +#define RESET_ID_HDMI_VIDEO 14 +#define RESET_ID_HDMI_SPDIF 15 +#define RESET_ID_HDMI_TMDS 16 +#define RESET_ID_HDMI_PHY 17 +#define RESET_ID_LVDS 18 +#define RESET_ID_ECID 19 +#define RESET_ID_I2C0 20 +#define RESET_ID_I2C1 21 +#define RESET_ID_I2C2 22 +#define RESET_ID_I2S0 23 +#define RESET_ID_I2S1 24 +#define RESET_ID_I2S2 25 +#define RESET_ID_DREX_C 26 +#define RESET_ID_DREX_A 27 +#define RESET_ID_DREX 28 +#define RESET_ID_MIPI 29 +#define RESET_ID_MIPI_DSI 30 +#define RESET_ID_MIPI_CSI 31 +#define RESET_ID_MIPI_PHY_S 32 +#define RESET_ID_MIPI_PHY_M 33 +#define RESET_ID_MPEGTSI 34 +#define RESET_ID_PDM 35 +#define RESET_ID_TIMER 36 +#define RESET_ID_PWM 37 +#define RESET_ID_SCALER 38 +#define RESET_ID_SDMMC0 39 +#define RESET_ID_SDMMC1 40 +#define RESET_ID_SDMMC2 41 +#define RESET_ID_SPDIFRX 42 +#define RESET_ID_SPDIFTX 43 +#define RESET_ID_SSP0_P 44 +#define RESET_ID_SSP0 45 +#define RESET_ID_SSP1_P 46 +#define RESET_ID_SSP1 47 +#define RESET_ID_SSP2_P 48 +#define RESET_ID_SSP2 49 +#define RESET_ID_UART0 50 /* UART1 */ +#define RESET_ID_UART1 51 /* pl01115_Uart_modem */ +#define RESET_ID_UART2 52 /* UART1 */ +#define RESET_ID_UART3 53 /* pl01115_Uart_nodma0 */ +#define RESET_ID_UART4 54 /* pl01115_Uart_nodma1 */ +#define RESET_ID_UART5 55 /* pl01115_Uart_nodma2 */ +#define RESET_ID_USB20HOST 56 +#define RESET_ID_USB20OTG 57 +#define RESET_ID_WDT 58 +#define RESET_ID_WDT_POR 59 +#define RESET_ID_ADC 60 +#define RESET_ID_CODA_A 61 +#define RESET_ID_CODA_P 62 +#define RESET_ID_CODA_C 63 +#define RESET_ID_DWC_GMAC 64 +#define RESET_ID_MALI400 65 +#define RESET_ID_PPM 66 +#define RESET_ID_VIP1 67 +#define RESET_ID_VIP0 68 +#if defined(CONFIG_ARCH_S5P6818) +#define RESET_ID_VIP2 69 +#endif + +/* + * device name + */ +#define DEV_NAME_UART "nx-uart" /* pl0115 (amba-pl011.c) */ +#define DEV_NAME_FB "nx-fb" +#define DEV_NAME_DISP "nx-disp" +#define DEV_NAME_LCD "nx-lcd" +#define DEV_NAME_LVDS "nx-lvds" +#define DEV_NAME_HDMI "nx-hdmi" +#define DEV_NAME_RESCONV "nx-resconv" +#define DEV_NAME_MIPI "nx-mipi" +#define DEV_NAME_PCM "nx-pcm" +#define DEV_NAME_I2S "nx-i2s" +#define DEV_NAME_SPDIF_TX "nx-spdif-tx" +#define DEV_NAME_SPDIF_RX "nx-spdif-rx" +#define DEV_NAME_I2C "nx-i2c" +#define DEV_NAME_NAND "nx-nand" +#define DEV_NAME_KEYPAD "nx-keypad" +#define DEV_NAME_SDHC "nx-sdhc" +#define DEV_NAME_PWM "nx-pwm" +#define DEV_NAME_TIMER "nx-timer" +#define DEV_NAME_SOC_PWM "nx-soc-pwm" +#define DEV_NAME_GPIO "nx-gpio" +#define DEV_NAME_RTC "nx-rtc" +#define DEV_NAME_GMAC "nx-gmac" +#define DEV_NAME_MPEGTSI "nx-mpegtsi" +#define DEV_NAME_MALI "nx-mali" +#define DEV_NAME_DIT "nx-deinterlace" +#define DEV_NAME_PPM "nx-ppm" +#define DEV_NAME_VIP "nx-vip" +#define DEV_NAME_CODA "nx-coda" +#define DEV_NAME_USB2HOST "nx-usb2h" +#define DEV_NAME_CRYPTO "nx-crypto" +#define DEV_NAME_SCALER "nx-scaler" +#define DEV_NAME_PDM "nx-pdm" +#define DEV_NAME_SPI "nx-spi" +#define DEV_NAME_CPUFREQ "nx-cpufreq" + +/* + * clock generator + */ +#define CORECLK_NAME_PLL0 "pll0" /* cpu clock */ +#define CORECLK_NAME_PLL1 "pll1" +#define CORECLK_NAME_PLL2 "pll2" +#define CORECLK_NAME_PLL3 "pll3" +#define CORECLK_NAME_FCLK "fclk" +#define CORECLK_NAME_MCLK "mclk" +#define CORECLK_NAME_BCLK "bclk" +#define CORECLK_NAME_PCLK "pclk" +#define CORECLK_NAME_HCLK "hclk" + +#define CORECLK_ID_PLL0 0 +#define CORECLK_ID_PLL1 1 +#define CORECLK_ID_PLL2 2 +#define CORECLK_ID_PLL3 3 +#define CORECLK_ID_FCLK 4 +#define CORECLK_ID_MCLK 5 +#define CORECLK_ID_BCLK 6 +#define CORECLK_ID_PCLK 7 +#define CORECLK_ID_HCLK 8 + +#define ALIVEPWRGATEREG (PHY_BASEADDR_ALIVE + 0x0) + +#if defined(CONFIG_ARCH_S5P4418) +#define SCR_ARM_SECOND_BOOT (0xC0010C1C) /* PWR scratch */ +#define SCR_ARM_SECOND_BOOT_REG1 (0xc0010234) /* ToDo : Check Address */ +#elif defined(CONFIG_ARCH_S5P6818) +#define SCR_ARM_SECOND_BOOT (0xc0010230) /* PWR scratch */ +#define SCR_ARM_SECOND_BOOT_REG1 (0xc0010234) /* PWR scratch */ +#define SCR_ARM_SECOND_BOOT_REG2 (0xc0010238) /* PWR scratch */ +#endif + +#define SCR_ALIVE_BASE (PHY_BASEADDR_ALIVE) +#define SCR_SIGNAGURE_RESET (SCR_ALIVE_BASE + 0x068) +#define SCR_SIGNAGURE_SET (SCR_ALIVE_BASE + 0x06C) +#define SCR_SIGNAGURE_READ (SCR_ALIVE_BASE + 0x070) + +#define SYSRSTCONFIG (0x23C) +#define DEVICEBOOTINFO (0x50) +#define BOOTMODE_MASK (0x7) +#define BOOTMODE_SDMMC 5 +#define BOOTMODE_USB 6 +#define BOOTMODE_SDMMC_PORT_VAL(x) ((((x) >> 3) & 1) | \ + (((x) >> 19 & 1) << 1)) +#define EMMC_PORT_NUM 2 +#define SD_PORT_NUM 0 +#define ID_REG_EC0 (0x54) +#define WIRE0_MASK (0x1) + +#ifndef __ASSEMBLY__ + +#define NS_IN_HZ (1000000000UL) +#define TO_PERIOD_NS(freq) (NS_IN_HZ / (freq)) +#define TO_DUTY_NS(duty, freq) (duty ? TO_PERIOD_NS(freq) / (100 / duty) : 0) + +#endif /* __ASSEMBLY__ */ + +#endif /* __NEXELL_H__ */ diff --git a/arch/arm/mach-nexell/include/mach/nx_gpio.h b/arch/arm/mach-nexell/include/mach/nx_gpio.h new file mode 100644 index 0000000000..91803d28cb --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/nx_gpio.h @@ -0,0 +1,103 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2016 Nexell + * Youngbok, Park <ybpark@nexell.co.kr> + */ + +#include <linux/types.h> +#include <asm/io.h> + +#ifndef __nx_gpio_h__ +#define __nx_gpio_h__ + +struct nx_gpio_register_set { + u32 gpioxout; + u32 gpioxoutenb; + u32 gpioxdetmode[2]; + u32 gpioxintenb; + u32 gpioxdet; + u32 gpioxpad; + u32 gpioxpuenb; + u32 gpioxaltfn[2]; + u32 gpioxdetmodeex; + u32 __reserved[4]; + u32 gpioxdetenb; + u32 gpiox_slew; + u32 gpiox_slew_disable_default; + u32 gpiox_drv1; + u32 gpiox_drv1_disable_default; + u32 gpiox_drv0; + u32 gpiox_drv0_disable_default; + u32 gpiox_pullsel; + u32 gpiox_pullsel_disable_default; + u32 gpiox_pullenb; + u32 gpiox_pullenb_disable_default; + u32 gpiox_input_mux_select0; + u32 gpiox_input_mux_select1; + u8 __reserved1[0x1000 - 0x70]; +}; + +enum { + nx_gpio_padfunc_0 = 0ul, + nx_gpio_padfunc_1 = 1ul, + nx_gpio_padfunc_2 = 2ul, + nx_gpio_padfunc_3 = 3ul +}; + +enum { + nx_gpio_drvstrength_0 = 0ul, + nx_gpio_drvstrength_1 = 1ul, + nx_gpio_drvstrength_2 = 2ul, + nx_gpio_drvstrength_3 = 3ul +}; + +enum { + nx_gpio_pull_down = 0ul, + nx_gpio_pull_up = 1ul, + nx_gpio_pull_off = 2ul +}; + +int nx_gpio_initialize(void); +u32 nx_gpio_get_number_of_module(void); +u32 nx_gpio_get_size_of_register_set(void); +void nx_gpio_set_base_address(u32 module_index, void *base_address); +void *nx_gpio_get_base_address(u32 module_index); +int nx_gpio_open_module(u32 module_index); +int nx_gpio_close_module(u32 module_index); +int nx_gpio_check_busy(u32 module_index); +void nx_gpio_set_detect_enable(u32 module_index, u32 bit_number, + int detect_enb); +void nx_gpio_set_pad_function(u32 module_index, u32 bit_number, u32 padfunc); +void nx_gpio_set_pad_function32(u32 module_index, u32 msbvalue, u32 lsbvalue); +int nx_gpio_get_pad_function(u32 module_index, u32 bit_number); +void nx_gpio_set_output_enable(u32 module_index, u32 bit_number, + int output_enb); +int nx_gpio_get_detect_enable(u32 module_index, u32 bit_number); +u32 nx_gpio_get_detect_enable32(u32 module_index); +void nx_gpio_set_detect_enable(u32 module_index, u32 bit_number, + int detect_enb); +void nx_gpio_set_detect_enable32(u32 module_index, u32 enable_flag); +int nx_gpio_get_output_enable(u32 module_index, u32 bit_number); +void nx_gpio_set_output_enable32(u32 module_index, int output_enb); +u32 nx_gpio_get_output_enable32(u32 module_index); +void nx_gpio_set_output_value(u32 module_index, u32 bit_number, int value); +int nx_gpio_get_output_value(u32 module_index, u32 bit_number); +void nx_gpio_set_output_value32(u32 module_index, u32 value); +u32 nx_gpio_get_output_value32(u32 module_index); +int nx_gpio_get_input_value(u32 module_index, u32 bit_number); +void nx_gpio_set_pull_select(u32 module_index, u32 bit_number, int enable); +void nx_gpio_set_pull_select32(u32 module_index, u32 value); +int nx_gpio_get_pull_select(u32 module_index, u32 bit_number); +u32 nx_gpio_get_pull_select32(u32 module_index); +void nx_gpio_set_pull_mode(u32 module_index, u32 bit_number, u32 mode); +void nx_gpio_set_fast_slew(u32 module_index, u32 bit_number, int enable); +void nx_gpio_set_drive_strength_disable_default(u32 module_index, + u32 bit_number, int enable); +void nx_gpio_set_drive_strength_disable_default(u32 module_index, + u32 bit_number, int enable); +void nx_gpio_set_drive_strength(u32 module_index, u32 bit_number, + u32 drvstrength); +void nx_gpio_set_drive_strength_disable_default(u32 module_index, + u32 bit_number, int enable); +u32 nx_gpio_get_drive_strength(u32 module_index, u32 bit_number); +#endif diff --git a/arch/arm/mach-nexell/include/mach/pwm.h b/arch/arm/mach-nexell/include/mach/pwm.h new file mode 100644 index 0000000000..08a287d308 --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/pwm.h @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0+ */ +/* + * Copyright (C) 2009 Samsung Electronics + * Kyungmin Park <kyungmin.park@samsung.com> + * Minkyu Kang <mk7.kang@samsung.com> + */ + +#ifndef __ASM_ARM_ARCH_PWM_H_ +#define __ASM_ARM_ARCH_PWM_H_ + +#define PRESCALER_0 (8 - 1) /* prescaler of timer 0, 1 */ +#define PRESCALER_1 (16 - 1) /* prescaler of timer 2, 3, 4 */ + +/* Divider MUX */ +#define MUX_DIV_1 0 /* 1/1 period */ +#define MUX_DIV_2 1 /* 1/2 period */ +#define MUX_DIV_4 2 /* 1/4 period */ +#define MUX_DIV_8 3 /* 1/8 period */ +#define MUX_DIV_16 4 /* 1/16 period */ + +#define MUX_DIV_SHIFT(x) ((x) * 4) + +#define TCON_OFFSET(x) (((x) + 1) * (!!(x)) << 2) + +#define TCON_START(x) (1 << TCON_OFFSET(x)) +#define TCON_UPDATE(x) (1 << (TCON_OFFSET(x) + 1)) +#define TCON_INVERTER(x) (1 << (TCON_OFFSET(x) + 2)) +#define TCON_AUTO_RELOAD(x) (1 << (TCON_OFFSET(x) + 3)) +#define TCON4_AUTO_RELOAD (1 << 22) + +#ifndef __ASSEMBLY__ +struct s5p_timer { + unsigned int tcfg0; + unsigned int tcfg1; + unsigned int tcon; + unsigned int tcntb0; + unsigned int tcmpb0; + unsigned int tcnto0; + unsigned int tcntb1; + unsigned int tcmpb1; + unsigned int tcnto1; + unsigned int tcntb2; + unsigned int tcmpb2; + unsigned int tcnto2; + unsigned int tcntb3; + unsigned int res1; + unsigned int tcnto3; + unsigned int tcntb4; + unsigned int tcnto4; + unsigned int tintcstat; +}; +#endif /* __ASSEMBLY__ */ + +#endif diff --git a/arch/arm/mach-nexell/include/mach/reset.h b/arch/arm/mach-nexell/include/mach/reset.h new file mode 100644 index 0000000000..e1301d4e53 --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/reset.h @@ -0,0 +1,19 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2016 Nexell + * Youngbok, Park <ybpark@nexell.co.kr> + */ + +#ifndef __NEXELL_RESET__ +#define __NEXELL_RESET__ + +#define NUMBER_OF_RESET_MODULE_PIN 69 + +enum rstcon { + RSTCON_ASSERT = 0UL, + RSTCON_NEGATE = 1UL +}; + +void nx_rstcon_setrst(u32 rstindex, enum rstcon status); + +#endif /* __NEXELL_RESET__ */ diff --git a/arch/arm/mach-nexell/include/mach/sec_reg.h b/arch/arm/mach-nexell/include/mach/sec_reg.h new file mode 100644 index 0000000000..e3ae5ac1bb --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/sec_reg.h @@ -0,0 +1,15 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2016 Nexell + * Youngbok, Park <park@nexell.co.kr> + */ + +#define NEXELL_L2C_SEC_ID 0 +#define NEXELL_MALI_SEC_ID 2 +#define NEXELL_MIPI_SEC_ID 4 +#define NEXELL_TOFF_SEC_ID 6 + +int write_sec_reg_by_id(void __iomem *reg, int val, int id); +int read_sec_reg_by_id(void __iomem *reg, int id); +int read_sec_reg(void __iomem *reg); +int write_sec_reg(void __iomem *reg, int val); diff --git a/arch/arm/mach-nexell/include/mach/tieoff.h b/arch/arm/mach-nexell/include/mach/tieoff.h new file mode 100644 index 0000000000..70e9652b6d --- /dev/null +++ b/arch/arm/mach-nexell/include/mach/tieoff.h @@ -0,0 +1,423 @@ +/* SPDX-License-Identifier: GPL-2.0+ + * + * (C) Copyright 2016 Nexell + * Youngbok, Park <park@nexell.co.kr> + */ + +#ifndef _NEXELL_TIEOFF_H +#define _NEXELL_TIEOFF_H + +void nx_tieoff_set(u32 tieoff_index, u32 tieoff_value); +u32 nx_tieoff_get(u32 tieoff_index); + +#if defined(CONFIG_ARCH_S5P4418) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CLAMPCOREOUT ((1 << 16) | 0) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CLAMPCPU0 ((1 << 16) | 1) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CLAMPCPU1 ((1 << 16) | 2) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CLAMPCPU2 ((1 << 16) | 3) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CLAMPCPU3 ((1 << 16) | 4) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_COREPWRDOWN ((1 << 16) | 5) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CPU0PWRDOWN ((1 << 16) | 6) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CPU1PWRDOWN ((1 << 16) | 7) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CPU2PWRDOWN ((1 << 16) | 8) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CPU3PWRDOWN ((1 << 16) | 9) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2_CFGENDIAN ((1 << 16) | 10) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L1EMAS ((1 << 16) | 11) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_0 ((1 << 16) | 12) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2RET1N_1 ((1 << 16) | 13) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2PGEN_0 ((1 << 16) | 14) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2PGEN_1 ((1 << 16) | 15) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CLAMPL2_0 ((1 << 16) | 16) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CLAMPL2_1 ((1 << 16) | 17) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_VINITHI ((4 << 16) | 18) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2EMA ((3 << 16) | 22) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_TEINIT ((4 << 16) | 25) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L1EMAW ((2 << 16) | 29) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L2EMAW ((2 << 16) | 32) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_L1EMA ((3 << 16) | 34) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_CPUCLKOFF ((4 << 16) | 37) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_PWRCTLI0 ((2 << 16) | 41) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_PWRCTLI1 ((2 << 16) | 43) +#define NX_TIEOFF_CORTEXA9MP_TOP_QUADL2C_PWRCTLI2 ((2 << 16) | 45) +#elif defined(CONFIG_ARCH_S5P6818) +#define NX_TIEOFF_MMC_8BIT ((1 << 16) | 5) +#endif +#define NX_TIEOFF_AXISRAM0_i_TIE_ra2w_EMAA ((3 << 16) | 47) +#define NX_TIEOFF_AXISRAM0_i_TIE_ra2w_EMAB ((3 << 16) | 50) +#define NX_TIEOFF_AXISRAM0_i_TIE_ra2w_EMAWA ((2 << 16) | 53) +#define NX_TIEOFF_AXISRAM0_i_TIE_ra2w_EMAWB ((2 << 16) | 55) +#define NX_TIEOFF_AXISRAM0_i_nPowerDown ((1 << 16) | 57) +#define NX_TIEOFF_AXISRAM0_i_nSleep ((1 << 16) | 58) +#define NX_TIEOFF_CAN0_i_TIE_rf1_EMA ((3 << 16) | 59) +#define NX_TIEOFF_CAN0_i_TIE_rf1_EMAW ((2 << 16) | 62) +#define NX_TIEOFF_CAN0_i_nPowerDown ((1 << 16) | 64) +#define NX_TIEOFF_CAN0_i_nSleep ((1 << 16) | 65) +#define NX_TIEOFF_CAN1_i_TIE_rf1_EMA ((3 << 16) | 66) +#define NX_TIEOFF_CAN1_i_TIE_rf1_EMAW ((2 << 16) | 69) +#define NX_TIEOFF_CAN1_i_nPowerDown ((1 << 16) | 71) +#define NX_TIEOFF_CAN1_i_nSleep ((1 << 16) | 72) +#define NX_TIEOFF_DEINTERLACE0_i_NX_RF1_EMA ((3 << 16) | 73) +#define NX_TIEOFF_DEINTERLACE0_i_NX_RF1_EMAW ((2 << 16) | 76) +#define NX_TIEOFF_DEINTERLACE0_i_NX_RF2_EMAA ((3 << 16) | 78) +#define NX_TIEOFF_DEINTERLACE0_i_NX_RF2_EMAB ((3 << 16) | 81) +#define NX_TIEOFF_DEINTERLACE0_i_NX_RF2W_EMAA ((3 << 16) | 84) +#define NX_TIEOFF_DEINTERLACE0_i_NX_RF2W_EMAB ((3 << 16) | 87) +#define NX_TIEOFF_DISPLAYTOP0_i_ResConv_nPowerDown ((1 << 16) | 90) +#define NX_TIEOFF_DISPLAYTOP0_i_ResConv_nSleep ((1 << 16) | 91) +#define NX_TIEOFF_DISPLAYTOP0_i_HDMI_nPowerDown ((2 << 16) | 92) +#define NX_TIEOFF_DISPLAYTOP0_i_HDMI_nSleep ((2 << 16) | 94) +#define NX_TIEOFF_DISPLAYTOP0_i_HDMI_PHY_REFCLK_SEL ((1 << 16) | 96) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_SPSRAM_EMA ((3 << 16) | 97) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_SPSRAM_EMAW ((2 << 16) | 100) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_DPSRAM_1R1W_EMAA ((3 << 16) | 102) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_DPSRAM_1R1W_EMAB ((3 << 16) | 105) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_DPSRAM_EMAA ((3 << 16) | 108) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_DPSRAM_EMAB ((3 << 16) | 111) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_DPSRAM_EMAWA ((2 << 16) | 114) +#define NX_TIEOFF_DISPLAYTOP0_i_TIEOFF_DPSRAM_EMAWB ((2 << 16) | 116) +#define NX_TIEOFF_MCUSTOP0_i_vrom_EMA ((3 << 16) | 118) +#define NX_TIEOFF_DREX0_CKE_INIT ((1 << 16) | 121) +#define NX_TIEOFF_DREX0_CA_SWAP ((1 << 16) | 122) +#define NX_TIEOFF_DREX0_CSYSREQ ((1 << 16) | 123) +#define NX_TIEOFF_DREX0_PAUSE_REQ ((1 << 16) | 124) +#define NX_TIEOFF_DREX0_PEREV_TRIGGER ((1 << 16) | 125) +#define NX_TIEOFF_DREX0_CTRL_HCKE ((1 << 16) | 126) +#define NX_TIEOFF_DREX0_DFI_RESET_N_P0 ((1 << 16) | 127) +#define NX_TIEOFF_DREX0_DFI_RESET_N_P1 ((1 << 16) | 128) +#define NX_TIEOFF_MIPI0_NX_DPSRAM_1R1W_EMAA ((3 << 16) | 129) +#define NX_TIEOFF_MIPI0_NX_DPSRAM_1R1W_EMAB ((3 << 16) | 132) +#define NX_TIEOFF_MIPI0_i_NX_NPOWERDOWN ((4 << 16) | 135) +#define NX_TIEOFF_MIPI0_i_NX_NSLEEP ((4 << 16) | 139) +#define NX_TIEOFF_SCALER0_i_NX_EMA ((3 << 16) | 143) +#define NX_TIEOFF_SCALER0_i_NX_EMAW ((2 << 16) | 146) +#define NX_TIEOFF_UART0_USESMC ((1 << 16) | 148) +#define NX_TIEOFF_UART0_SMCTXENB ((1 << 16) | 149) +#define NX_TIEOFF_UART0_SMCRXENB ((1 << 16) | 150) +#define NX_TIEOFF_UART1_USESMC ((1 << 16) | 151) +#define NX_TIEOFF_UART1_SMCTXENB ((1 << 16) | 152) +#define NX_TIEOFF_UART1_SMCRXENB ((1 << 16) | 153) +#define NX_TIEOFF_UART2_USESMC ((1 << 16) | 154) +#define NX_TIEOFF_UART2_SMCTXENB ((1 << 16) | 155) +#define NX_TIEOFF_UART2_SMCRXENB ((1 << 16) | 156) +#define NX_TIEOFF_UART3_USESMC ((1 << 16) | 157) +#define NX_TIEOFF_UART3_SMCTXENB ((1 << 16) | 158) +#define NX_TIEOFF_UART3_SMCRXENB ((1 << 16) | 159) +#define NX_TIEOFF_UART4_USESMC ((1 << 16) | 160) +#define NX_TIEOFF_UART4_SMCTXENB ((1 << 16) | 161) +#define NX_TIEOFF_UART4_SMCRXENB ((1 << 16) | 162) +#define NX_TIEOFF_UART5_USESMC ((1 << 16) | 163) +#define NX_TIEOFF_UART5_SMCTXENB ((1 << 16) | 164) +#define NX_TIEOFF_UART5_SMCRXENB ((1 << 16) | 165) +#define NX_TIEOFF_USB20HOST0_i_nPowerDown ((1 << 16) | 166) +#define NX_TIEOFF_USB20HOST0_i_nSleep ((1 << 16) | 167) +#define NX_TIEOFF_USB20HOST0_i_NX_RF1_EMA ((3 << 16) | 168) +#define NX_TIEOFF_USB20HOST0_i_NX_RF1_EMAW ((2 << 16) | 171) +#define NX_TIEOFF_USB20HOST0_sys_interrupt_i ((1 << 16) | 173) +#define NX_TIEOFF_USB20HOST0_i_hsic_en ((3 << 16) | 174) +#define NX_TIEOFF_USB20HOST0_i_nResetSync ((1 << 16) | 177) +#define NX_TIEOFF_USB20HOST0_i_nResetSync_ohci ((1 << 16) | 178) +#define NX_TIEOFF_USB20HOST0_i_nAuxWellResetSync ((1 << 16) | 179) +#define NX_TIEOFF_USB20HOST0_i_nHostPhyResetSync ((1 << 16) | 180) +#define NX_TIEOFF_USB20HOST0_i_nHostUtmiResetSync ((1 << 16) | 181) +#define NX_TIEOFF_USB20HOST0_i_nHostHsicResetSync ((1 << 16) | 182) +#define NX_TIEOFF_USB20HOST0_i_HSIC_FREE_CLOCK_ENB ((1 << 16) | 183) +#define NX_TIEOFF_USB20HOST0_i_HSIC_480M_FROM_OTG_PHY ((1 << 16) | 184) +#define NX_TIEOFF_USB20HOST0_ss_word_if_enb_i ((1 << 16) | 185) +#define NX_TIEOFF_USB20HOST0_ss_word_if_i ((1 << 16) | 186) +#define NX_TIEOFF_USB20HOST0_ss_utmi_backward_enb_i ((1 << 16) | 187) +#define NX_TIEOFF_USB20HOST0_ss_resume_utmi_pls_dis_i ((1 << 16) | 188) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_0_i ((3 << 16) | 189) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_1_i ((3 << 16) | 192) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_2_i ((3 << 16) | 195) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_3_i ((3 << 16) | 198) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_4_i ((3 << 16) | 201) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_5_i ((3 << 16) | 204) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_6_i ((3 << 16) | 207) +#define NX_TIEOFF_USB20HOST0_phy_vstatus_7_i ((3 << 16) | 210) +#define NX_TIEOFF_USB20HOST0_ss_power_state_valid_i ((1 << 16) | 213) +#define NX_TIEOFF_USB20HOST0_ss_nxt_power_state_valid_i ((1 << 16) | 214) +#define NX_TIEOFF_USB20HOST0_ss_power_state_i ((2 << 16) | 215) +#define NX_TIEOFF_USB20HOST0_ss_next_power_state_i ((2 << 16) | 217) +#define NX_TIEOFF_USB20HOST0_app_prt_ovrcur_i ((3 << 16) | 219) +#define NX_TIEOFF_USB20HOST0_ss_simulation_mode_i ((1 << 16) | 222) +#define NX_TIEOFF_USB20HOST0_ss_fladj_val_host_i ((6 << 16) | 224) +#define NX_TIEOFF_USB20HOST0_ss_fladj_val_5_i ((3 << 16) | 230) +#define NX_TIEOFF_USB20HOST0_ss_fladj_val_4_i ((3 << 16) | 233) +#define NX_TIEOFF_USB20HOST0_ss_fladj_val_3_i ((3 << 16) | 236) +#define NX_TIEOFF_USB20HOST0_ss_fladj_val_2_i ((3 << 16) | 239) +#define NX_TIEOFF_USB20HOST0_ss_fladj_val_1_i ((3 << 16) | 242) +#define NX_TIEOFF_USB20HOST0_ss_fladj_val_0_i ((3 << 16) | 245) +#define NX_TIEOFF_USB20HOST0_ss_autoppd_on_overcur_en_i ((1 << 16) | 248) +#define NX_TIEOFF_USB20HOST0_ss_ena_incr16_i ((1 << 16) | 249) +#define NX_TIEOFF_USB20HOST0_ss_ena_incr8_i ((1 << 16) | 250) +#define NX_TIEOFF_USB20HOST0_ss_ena_incr4_i ((1 << 16) | 251) +#define NX_TIEOFF_USB20HOST0_ss_ena_incrx_align_i ((1 << 16) | 252) +#define NX_TIEOFF_USB20HOST0_i_ohci_0_cntsel_n ((1 << 16) | 253) +#define NX_TIEOFF_USB20HOST0_ohci_0_app_irq1_i ((1 << 16) | 254) +#define NX_TIEOFF_USB20HOST0_ohci_0_app_irq12_i ((1 << 16) | 255) +#define NX_TIEOFF_USB20HOST0_ohci_0_app_io_hit_i ((1 << 16) | 256) +#define NX_TIEOFF_USB20HOST0_ss_hubsetup_min_i ((1 << 16) | 257) +#define NX_TIEOFF_USB20HOST0_app_start_clk_i ((1 << 16) | 258) +#define NX_TIEOFF_USB20HOST0_ohci_susp_lgcy_i ((1 << 16) | 259) +#define NX_TIEOFF_USB20HOST0_i_SIDDQ ((1 << 16) | 260) +#define NX_TIEOFF_USB20HOST0_i_VATESTENB ((2 << 16) | 261) +#define NX_TIEOFF_USB20HOST0_i_POR_ENB ((1 << 16) | 263) +#define NX_TIEOFF_USB20HOST0_i_POR ((1 << 16) | 264) +#define NX_TIEOFF_USB20HOST0_i_REFCLKSEL ((2 << 16) | 265) +#define NX_TIEOFF_USB20HOST0_i_FSEL ((3 << 16) | 267) +#define NX_TIEOFF_USB20HOST0_i_COMMONONN ((1 << 16) | 270) +#define NX_TIEOFF_USB20HOST0_i_RESREQIN ((1 << 16) | 271) +#define NX_TIEOFF_USB20HOST0_i_PORTRESET ((1 << 16) | 272) +#define NX_TIEOFF_USB20HOST0_i_OTGDISABLE ((1 << 16) | 273) +#define NX_TIEOFF_USB20HOST0_i_LOOPBACKENB ((1 << 16) | 274) +#define NX_TIEOFF_USB20HOST0_i_IDPULLUPi ((1 << 16) | 275) +#define NX_TIEOFF_USB20HOST0_i_DRVVBUS ((1 << 16) | 276) +#define NX_TIEOFF_USB20HOST0_i_ADPCHRG ((1 << 16) | 277) +#define NX_TIEOFF_USB20HOST0_i_ADPDISCHRG ((1 << 16) | 278) +#define NX_TIEOFF_USB20HOST0_i_ADPPRBENB ((1 << 16) | 279) +#define NX_TIEOFF_USB20HOST0_i_VBUSVLDEXT ((1 << 16) | 280) +#define NX_TIEOFF_USB20HOST0_i_VBUSVLDEXTSEL ((1 << 16) | 281) +#define NX_TIEOFF_USB20HOST0_i_DPPULLDOWN ((1 << 16) | 282) +#define NX_TIEOFF_USB20HOST0_i_DMPULLDOWN ((1 << 16) | 283) +#define NX_TIEOFF_USB20HOST0_i_SUSPENDM_ENB ((1 << 16) | 284) +#define NX_TIEOFF_USB20HOST0_i_SUSPENDM ((1 << 16) | 285) +#define NX_TIEOFF_USB20HOST0_i_SLEEPM_ENB ((1 << 16) | 286) +#define NX_TIEOFF_USB20HOST0_i_SLEEPM ((1 << 16) | 287) +#define NX_TIEOFF_USB20HOST0_i_OPMODE_ENB ((1 << 16) | 288) +#define NX_TIEOFF_USB20HOST0_i_OPMODE ((2 << 16) | 289) +#define NX_TIEOFF_USB20HOST0_i_TERMSEL_ENB ((1 << 16) | 291) +#define NX_TIEOFF_USB20HOST0_i_TERMSEL ((1 << 16) | 292) +#define NX_TIEOFF_USB20HOST0_i_XCVRSEL_ENB ((1 << 16) | 293) +#define NX_TIEOFF_USB20HOST0_i_XCVRSEL ((2 << 16) | 294) +#define NX_TIEOFF_USB20HOST0_i_WORDINTERFACE_ENB ((1 << 16) | 296) +#define NX_TIEOFF_USB20HOST0_i_WORDINTERFACE ((1 << 16) | 297) +#define NX_TIEOFF_USB20HOST0_i_TXBITSTUFFEN ((1 << 16) | 298) +#define NX_TIEOFF_USB20HOST0_i_TXBITSTUFFENH ((1 << 16) | 299) +#define NX_TIEOFF_USB20HOST0_i_BYPASSDPDATA ((1 << 16) | 300) +#define NX_TIEOFF_USB20HOST0_i_BYPASSDMDATA ((1 << 16) | 301) +#define NX_TIEOFF_USB20HOST0_i_BYPASSDPEN ((1 << 16) | 302) +#define NX_TIEOFF_USB20HOST0_i_BYPASSDMEN ((1 << 16) | 303) +#define NX_TIEOFF_USB20HOST0_i_BYPASSSEL ((1 << 16) | 304) +#define NX_TIEOFF_USB20HOST0_i_COMPDISTUNE ((3 << 16) | 305) +#define NX_TIEOFF_USB20HOST0_i_SQRXTUNE ((3 << 16) | 308) +#define NX_TIEOFF_USB20HOST0_i_OTGTUNE ((3 << 16) | 311) +#define NX_TIEOFF_USB20HOST0_i_TXHSXVTUNE ((2 << 16) | 314) +#define NX_TIEOFF_USB20HOST0_i_TXFSLSTUNE ((4 << 16) | 316) +#define NX_TIEOFF_USB20HOST0_i_TXVREFTUNE ((4 << 16) | 320) +#define NX_TIEOFF_USB20HOST0_i_TXRISETUNE ((2 << 16) | 324) +#define NX_TIEOFF_USB20HOST0_i_TXRESTUNE ((2 << 16) | 326) +#define NX_TIEOFF_USB20HOST0_i_TXPREEMPAMPTUNE ((2 << 16) | 328) +#define NX_TIEOFF_USB20HOST0_i_TXPREEMPPULSETUNE ((1 << 16) | 330) +#define NX_TIEOFF_USB20HOST0_i_CHRGSEL ((1 << 16) | 331) +#define NX_TIEOFF_USB20HOST0_i_VDATDETENB ((1 << 16) | 332) +#define NX_TIEOFF_USB20HOST0_i_VDATSRCENB ((1 << 16) | 333) +#define NX_TIEOFF_USB20HOST0_i_DCDENB ((1 << 16) | 334) +#define NX_TIEOFF_USB20HOST0_i_ACAENB ((1 << 16) | 335) +#define NX_TIEOFF_USB20HOST0_i_HSIC_MSTRXCVR ((1 << 16) | 336) +#define NX_TIEOFF_USB20HOST0_i_HSIC_SIDDQ ((1 << 16) | 337) +#define NX_TIEOFF_USB20HOST0_i_HSIC_POR_ENB ((1 << 16) | 338) +#define NX_TIEOFF_USB20HOST0_i_HSIC_POR ((1 << 16) | 339) +#define NX_TIEOFF_USB20HOST0_i_HSIC_REFCLKDIV ((7 << 16) | 340) +#define NX_TIEOFF_USB20HOST0_i_HSIC_REFCLKSEL ((2 << 16) | 347) +#define NX_TIEOFF_USB20HOST0_i_HSIC_COMMONONN ((1 << 16) | 349) +#define NX_TIEOFF_USB20HOST0_i_HSIC_PORTRESET ((1 << 16) | 350) +#define NX_TIEOFF_USB20HOST0_i_HSIC_LOOPBACKENB ((1 << 16) | 351) +#define NX_TIEOFF_USB20HOST0_i_HSIC_DPPULLDOWN ((1 << 16) | 352) +#define NX_TIEOFF_USB20HOST0_i_HSIC_DMPULLDOWN ((1 << 16) | 353) +#define NX_TIEOFF_USB20HOST0_i_HSIC_SUSPENDM_ENB ((1 << 16) | 354) +#define NX_TIEOFF_USB20HOST0_i_HSIC_SUSPENDM ((1 << 16) | 355) +#define NX_TIEOFF_USB20HOST0_i_HSIC_SLEEPM_ENB ((1 << 16) | 356) +#define NX_TIEOFF_USB20HOST0_i_HSIC_SLEEPM ((1 << 16) | 357) +#define NX_TIEOFF_USB20HOST0_i_HSIC_MSTRXOPU ((1 << 16) | 358) +#define NX_TIEOFF_USB20HOST0_i_HSIC_OPMODE_ENB ((1 << 16) | 359) +#define NX_TIEOFF_USB20HOST0_i_HSIC_OPMODE ((2 << 16) | 360) +#define NX_TIEOFF_USB20HOST0_i_HSIC_XCVRSELECT_ENB ((1 << 16) | 362) +#define NX_TIEOFF_USB20HOST0_i_HSIC_XCVRSELECT ((1 << 16) | 363) +#define NX_TIEOFF_USB20HOST0_i_HSIC_WORDINTERFACE_ENB ((1 << 16) | 364) +#define NX_TIEOFF_USB20HOST0_i_HSIC_WORDINTERFACE ((1 << 16) | 365) +#define NX_TIEOFF_USB20HOST0_i_HSIC_TXBITSTUFFEN ((1 << 16) | 366) +#define NX_TIEOFF_USB20HOST0_i_HSIC_TXBITSTUFFENH ((1 << 16) | 367) +#define NX_TIEOFF_USB20HOST0_i_HSIC_TXRPUTUNE ((2 << 16) | 368) +#define NX_TIEOFF_USB20HOST0_i_HSIC_TXRPDTUNE ((2 << 16) | 370) +#define NX_TIEOFF_USB20HOST0_i_HSIC_TXSRTUNE ((4 << 16) | 372) +#define NX_TIEOFF_USB20OTG0_i_nPowerDown ((1 << 16) | 376) +#define NX_TIEOFF_USB20OTG0_i_nSleep ((1 << 16) | 377) +#define NX_TIEOFF_USB20OTG0_i_NX_RF1_EMA ((3 << 16) | 378) +#define NX_TIEOFF_USB20OTG0_i_NX_RF1_EMAW ((2 << 16) | 381) +#define NX_TIEOFF_USB20OTG0_i_ss_scaledown_mode ((2 << 16) | 384) +#define NX_TIEOFF_USB20OTG0_i_gp_in ((16 << 16) | 386) +#define NX_TIEOFF_USB20OTG0_i_sof_count ((14 << 16) | 402) +#define NX_TIEOFF_USB20OTG0_i_sys_dma_done ((1 << 16) | 416) +#define NX_TIEOFF_USB20OTG0_i_if_select_hsic ((1 << 16) | 417) +#define NX_TIEOFF_USB20OTG0_i_nResetSync ((1 << 16) | 418) +#define NX_TIEOFF_USB20OTG0_i_nUtmiResetSync ((1 << 16) | 419) +#define NX_TIEOFF_USB20OTG0_i_SIDDQ ((1 << 16) | 420) +#define NX_TIEOFF_USB20OTG0_i_VATESTENB ((2 << 16) | 421) +#define NX_TIEOFF_USB20OTG0_i_POR_ENB ((1 << 16) | 423) +#define NX_TIEOFF_USB20OTG0_i_POR ((1 << 16) | 424) +#define NX_TIEOFF_USB20OTG0_i_REFCLKSEL ((2 << 16) | 425) +#define NX_TIEOFF_USB20OTG0_i_FSEL ((3 << 16) | 427) +#define NX_TIEOFF_USB20OTG0_i_COMMONONN ((1 << 16) | 430) +#define NX_TIEOFF_USB20OTG0_i_RESREQIN ((1 << 16) | 431) +#define NX_TIEOFF_USB20OTG0_i_PORTRESET ((1 << 16) | 432) +#define NX_TIEOFF_USB20OTG0_i_OTGDISABLE ((1 << 16) | 433) +#define NX_TIEOFF_USB20OTG0_i_LOOPBACKENB ((1 << 16) | 434) +#define NX_TIEOFF_USB20OTG0_i_IDPULLUP ((1 << 16) | 435) +#define NX_TIEOFF_USB20OTG0_i_DRVVBUS ((1 << 16) | 436) +#define NX_TIEOFF_USB20OTG0_i_ADPCHRG ((1 << 16) | 437) +#define NX_TIEOFF_USB20OTG0_i_ADPDISCHRG ((1 << 16) | 438) +#define NX_TIEOFF_USB20OTG0_i_ADPPRBENB ((1 << 16) | 439) +#define NX_TIEOFF_USB20OTG0_i_VBUSVLDEXT ((1 << 16) | 440) +#define NX_TIEOFF_USB20OTG0_i_VBUSVLDEXTSEL ((1 << 16) | 441) +#define NX_TIEOFF_USB20OTG0_i_DPPULLDOWN ((1 << 16) | 442) +#define NX_TIEOFF_USB20OTG0_i_DMPULLDOWN ((1 << 16) | 443) +#define NX_TIEOFF_USB20OTG0_i_SUSPENDM_ENB ((1 << 16) | 444) +#define NX_TIEOFF_USB20OTG0_i_SUSPENDM ((1 << 16) | 445) +#define NX_TIEOFF_USB20OTG0_i_SLEEPM_ENB ((1 << 16) | 446) +#define NX_TIEOFF_USB20OTG0_i_SLEEPM ((1 << 16) | 447) +#define NX_TIEOFF_USB20OTG0_i_OPMODE_ENB ((1 << 16) | 448) +#define NX_TIEOFF_USB20OTG0_i_OPMODE ((2 << 16) | 449) +#define NX_TIEOFF_USB20OTG0_i_TERMSEL_ENB ((1 << 16) | 451) +#define NX_TIEOFF_USB20OTG0_i_TERMSEL ((1 << 16) | 452) +#define NX_TIEOFF_USB20OTG0_i_XCVRSEL_ENB ((1 << 16) | 453) +#define NX_TIEOFF_USB20OTG0_i_XCVRSEL ((2 << 16) | 454) +#define NX_TIEOFF_USB20OTG0_i_WORDINTERFACE_ENB ((1 << 16) | 456) +#define NX_TIEOFF_USB20OTG0_i_WORDINTERFACE ((1 << 16) | 457) +#define NX_TIEOFF_USB20OTG0_i_TXBITSTUFFEN ((1 << 16) | 458) +#define NX_TIEOFF_USB20OTG0_i_TXBITSTUFFENH ((1 << 16) | 459) +#define NX_TIEOFF_USB20OTG0_i_BYPASSDPDATA ((1 << 16) | 460) +#define NX_TIEOFF_USB20OTG0_i_BYPASSDMDATA ((1 << 16) | 461) +#define NX_TIEOFF_USB20OTG0_i_BYPASSDPEN ((1 << 16) | 462) +#define NX_TIEOFF_USB20OTG0_i_BYPASSDMEN ((1 << 16) | 463) +#define NX_TIEOFF_USB20OTG0_i_BYPASSSEL ((1 << 16) | 464) +#define NX_TIEOFF_USB20OTG0_i_COMPDISTUNE ((3 << 16) | 465) +#define NX_TIEOFF_USB20OTG0_i_SQRXTUNE ((3 << 16) | 468) +#define NX_TIEOFF_USB20OTG0_i_OTGTUNE ((3 << 16) | 471) +#define NX_TIEOFF_USB20OTG0_i_TXHSXVTUNE ((2 << 16) | 474) +#define NX_TIEOFF_USB20OTG0_i_TXFSLSTUNE ((4 << 16) | 476) +#define NX_TIEOFF_USB20OTG0_i_TXVREFTUNE ((4 << 16) | 480) +#define NX_TIEOFF_USB20OTG0_i_TXRISETUNE ((2 << 16) | 484) +#define NX_TIEOFF_USB20OTG0_i_TXRESTUNE ((2 << 16) | 486) +#define NX_TIEOFF_USB20OTG0_i_TXPREEMPAMPTUNE ((2 << 16) | 488) +#define NX_TIEOFF_USB20OTG0_i_TXPREEMPPULSETUNE ((1 << 16) | 490) +#define NX_TIEOFF_USB20OTG0_i_CHRGSEL ((1 << 16) | 491) +#define NX_TIEOFF_USB20OTG0_i_VDATDETENB ((1 << 16) | 492) +#define NX_TIEOFF_USB20OTG0_i_VDATSRCENB ((1 << 16) | 493) +#define NX_TIEOFF_USB20OTG0_i_DCDENB ((1 << 16) | 494) +#define NX_TIEOFF_USB20OTG0_i_ACAENB ((1 << 16) | 495) +#define NX_TIEOFF_USB20OTG0_i_IDPULLUP_ENB ((1 << 16) | 496) +#define NX_TIEOFF_USB20OTG0_i_DPPULLDOWN_ENB ((1 << 16) | 497) +#define NX_TIEOFF_USB20OTG0_i_DMPULLDOWN_ENB ((1 << 16) | 498) +#define NX_TIEOFF_USB20OTG0_i_DRVVBUS_ENB ((1 << 16) | 499) +#define NX_TIEOFF_USB20OTG0_i_LPMClkMuxCntrl ((1 << 16) | 500) +#define NX_TIEOFF_USB20OTG0_i_GLITCHLESSMUXCntrl ((1 << 16) | 501) +#define NX_TIEOFF_CODA9600_i_nPWRDN00 ((4 << 16) | 502) +#define NX_TIEOFF_CODA9600_i_nSLEEP00 ((4 << 16) | 506) +#define NX_TIEOFF_CODA9600_i_nPWRDN01 ((8 << 16) | 512) +#define NX_TIEOFF_CODA9600_i_nSLEEP01 ((8 << 16) | 520) +#define NX_TIEOFF_CODA9600_i_nPWRDN02 ((10 << 16) | 528) +#define NX_TIEOFF_CODA9600_i_nSLEEP02 ((10 << 16) | 544) +#define NX_TIEOFF_CODA9600_i_nPWRDN03 ((2 << 16) | 554) +#define NX_TIEOFF_CODA9600_i_nSLEEP03 ((2 << 16) | 556) +#define NX_TIEOFF_CODA9600_i_nPWRDN04 ((8 << 16) | 558) +#define NX_TIEOFF_CODA9600_i_nSLEEP04 ((8 << 16) | 566) +#define NX_TIEOFF_CODA9600_i_nPWRDN05 ((3 << 16) | 576) +#define NX_TIEOFF_CODA9600_i_nSLEEP05 ((3 << 16) | 579) +#define NX_TIEOFF_CODA9600_i_nPWRDN06 ((7 << 16) | 582) +#define NX_TIEOFF_CODA9600_i_nSLEEP06 ((7 << 16) | 589) +#define NX_TIEOFF_CODA9600_i_nPWRDN07 ((12 << 16) | 596) +#define NX_TIEOFF_CODA9600_i_nSLEEP07 ((12 << 16) | 608) +#define NX_TIEOFF_CODA9600_i_nPWRDN08 ((1 << 16) | 620) +#define NX_TIEOFF_CODA9600_i_nSLEEP08 ((1 << 16) | 621) +#define NX_TIEOFF_CODA9600_i_nPWRDN09 ((2 << 16) | 622) +#define NX_TIEOFF_CODA9600_i_nSLEEP09 ((2 << 16) | 624) +#define NX_TIEOFF_CODA9600_i_nPWRDN10 ((10 << 16) | 626) +#define NX_TIEOFF_CODA9600_i_nSLEEP10 ((10 << 16) | 640) +#define NX_TIEOFF_CODA9600_i_nPWRDN11 ((1 << 16) | 650) +#define NX_TIEOFF_CODA9600_i_nSLEEP11 ((1 << 16) | 651) +#define NX_TIEOFF_CODA9600_i_TIE_rf2_EMAA ((3 << 16) | 652) +#define NX_TIEOFF_CODA9600_i_TIE_rf2_EMAB ((3 << 16) | 655) +#define NX_TIEOFF_CODA9600_i_TIE_rf2w_EMAA ((3 << 16) | 658) +#define NX_TIEOFF_CODA9600_i_TIE_rf2w_EMAB ((3 << 16) | 661) +#define NX_TIEOFF_CODA9600_i_TIE_ra2_EMAA ((3 << 16) | 664) +#define NX_TIEOFF_CODA9600_i_TIE_ra2_EMAB ((3 << 16) | 667) +#define NX_TIEOFF_CODA9600_i_TIE_ra2_EMAWA ((2 << 16) | 670) +#define NX_TIEOFF_CODA9600_i_TIE_ra2_EMAWB ((2 << 16) | 672) +#define NX_TIEOFF_CODA9600_i_TIE_ra2w_EMAA ((3 << 16) | 674) +#define NX_TIEOFF_CODA9600_i_TIE_ra2w_EMAB ((3 << 16) | 677) +#define NX_TIEOFF_CODA9600_i_TIE_ra2w_EMAWA ((2 << 16) | 680) +#define NX_TIEOFF_CODA9600_i_TIE_ra2w_EMAWB ((2 << 16) | 682) +#define NX_TIEOFF_CODA9600_i_TIE_rf1_EMA ((3 << 16) | 684) +#define NX_TIEOFF_CODA9600_i_TIE_rf1_EMAW ((2 << 16) | 687) +#define NX_TIEOFF_CODA9600_i_TIE_rf1w_EMA ((3 << 16) | 689) +#define NX_TIEOFF_CODA9600_i_TIE_rf1w_EMAW ((2 << 16) | 692) +#define NX_TIEOFF_DWC_GMAC0_sbd_flowctrl_i ((1 << 16) | 694) +#define NX_TIEOFF_DWC_GMAC0_phy_intf_sel_i ((3 << 16) | 695) +#define NX_TIEOFF_DWC_GMAC0_i_NX_RF2_EMAA ((3 << 16) | 698) +#define NX_TIEOFF_DWC_GMAC0_i_NX_RF2_EMAB ((3 << 16) | 701) +#define NX_TIEOFF_MALI4000_NX_DPSRAM_1R1W_EMAA ((3 << 16) | 704) +#define NX_TIEOFF_MALI4000_NX_DPSRAM_1R1W_EMAB ((3 << 16) | 707) +#define NX_TIEOFF_MALI4000_NX_SPSRAM_EMA ((3 << 16) | 710) +#define NX_TIEOFF_MALI4000_NX_SPSRAM_EMAW ((2 << 16) | 713) +#define NX_TIEOFF_MALI4000_NX_SPSRAM_BW_EMA ((3 << 16) | 715) +#define NX_TIEOFF_MALI4000_NX_SPSRAM_BW_EMAW ((2 << 16) | 718) +#define NX_TIEOFF_MALI4000_PWRDNBYPASS ((1 << 16) | 720) +#define NX_TIEOFF_MALI4000_GP_NX_NPOWERDOWN ((15 << 16) | 721) +#define NX_TIEOFF_MALI4000_GP_NX_NSLEEP ((15 << 16) | 736) +#define NX_TIEOFF_MALI4000_L2_NX_NPOWERDOWN ((3 << 16) | 751) +#define NX_TIEOFF_MALI4000_L2_NX_NSLEEP ((3 << 16) | 754) +#define NX_TIEOFF_MALI4000_PP0_NX_NPOWERDOWN ((32 << 16) | 768) +#define NX_TIEOFF_MALI4000_PP0_NX_NSLEEP ((32 << 16) | 800) +#define NX_TIEOFF_MALI4000_PP1_NX_NPOWERDOWN ((32 << 16) | 832) +#define NX_TIEOFF_MALI4000_PP1_NX_NSLEEP ((32 << 16) | 864) +#define NX_TIEOFF_MALI4000_PP2_NX_NPOWERDOWN ((32 << 16) | 896) +#define NX_TIEOFF_MALI4000_PP2_NX_NSLEEP ((32 << 16) | 928) +#define NX_TIEOFF_MALI4000_PP3_NX_NPOWERDOWN ((32 << 16) | 960) +#define NX_TIEOFF_MALI4000_PP3_NX_NSLEEP ((32 << 16) | 992) +#define NX_TIEOFF_A3BM_AXI_PERI_BUS0_SYNCMODEREQm9 ((1 << 16) | 1024) +#define NX_TIEOFF_A3BM_AXI_PERI_BUS0_SYNCMODEREQm10 ((1 << 16) | 1025) +#define NX_TIEOFF_A3BM_AXI_PERI_BUS0_SYNCMODEREQm16 ((1 << 16) | 1026) +#define NX_TIEOFF_A3BM_AXI_TOP_MASTER_BUS0_REMAP ((2 << 16) | 1027) +#if defined(CONFIG_ARCH_S5P6818) +#define NX_TIEOFF_Inst_ARMTOP_SMPEN ((4 << 16) | 2816) +#define NX_TIEOFF_Inst_ARMTOP_STANBYWFI ((4 << 16) | 2880) +#define NX_TIEOFF_Inst_ARMTOP_STANBYWFIL2 ((1 << 16) | 2884) +#define NX_TIEOFF_Inst_ARMTOP_DBGNOPWRDWN ((4 << 16) | 2889) +#define NX_TIEOFF_Inst_ARMTOP_DBGPWRUPREQ ((4 << 16) | 2893) +#define NX_TIEOFF_Inst_ARMTOP_COREPWRDOWNPRE ((1 << 16) | 2901) +#define NX_TIEOFF_Inst_ARMTOP_CPU0PWRDOWNPRE ((1 << 16) | 2902) +#define NX_TIEOFF_Inst_ARMTOP_CPU1PWRDOWNPRE ((1 << 16) | 2903) +#define NX_TIEOFF_Inst_ARMTOP_CPU2PWRDOWNPRE ((1 << 16) | 2904) +#define NX_TIEOFF_Inst_ARMTOP_CPU3PWRDOWNPRE ((1 << 16) | 2905) +#define NX_TIEOFF_Inst_ARMTOP_COREPWRDOWNALL ((1 << 16) | 2906) +#define NX_TIEOFF_Inst_ARMTOP_CPU0PWRDOWNALL ((1 << 16) | 2907) +#define NX_TIEOFF_Inst_ARMTOP_CPU1PWRDOWNALL ((1 << 16) | 2908) +#define NX_TIEOFF_Inst_ARMTOP_CPU2PWRDOWNALL ((1 << 16) | 2909) +#define NX_TIEOFF_Inst_ARMTOP_CPU3PWRDOWNALL ((1 << 16) | 2910) +#define NX_TIEOFF_Inst_ARMTOP_CLAMPL2 ((1 << 16) | 2920) +#define NX_TIEOFF_Inst_ARMTOP_L2FLUSHREQ ((1 << 16) | 3018) +#define NX_TIEOFF_Inst_ARMTOP_L2FLUSHDONE ((1 << 16) | 3019) +#define NX_TIEOFF_Inst_ARMTOP_ACINACTM ((1 << 16) | 3023) +#define NX_TIEOFF_Inst_ARMTOP_P1_SMPEN ((4 << 16) | 3360) +#define NX_TIEOFF_Inst_ARMTOP_P1_STANBYWFI ((4 << 16) | 3424) +#define NX_TIEOFF_Inst_ARMTOP_P1_STANBYWFIL2 ((1 << 16) | 3428) +#define NX_TIEOFF_Inst_ARMTOP_P1_DBGNOPWRDWN ((4 << 16) | 3442) +#define NX_TIEOFF_Inst_ARMTOP_P1_DBGPWRUPREQ ((4 << 16) | 3443) +#define NX_TIEOFF_Inst_ARMTOP_P1_DBGPWRDUP ((4 << 16) | 3444) +#define NX_TIEOFF_Inst_ARMTOP_P1_COREPWRDOWNPRE ((1 << 16) | 3445) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU0PWRDOWNPRE ((1 << 16) | 3446) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU1PWRDOWNPRE ((1 << 16) | 3447) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU2PWRDOWNPRE ((1 << 16) | 3448) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU3PWRDOWNPRE ((1 << 16) | 3449) +#define NX_TIEOFF_Inst_ARMTOP_P1_COREPWRDOWNALL ((1 << 16) | 3450) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU0PWRDOWNALL ((1 << 16) | 3451) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU1PWRDOWNALL ((1 << 16) | 3452) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU2PWRDOWNALL ((1 << 16) | 3453) +#define NX_TIEOFF_Inst_ARMTOP_P1_CPU3PWRDOWNALL ((1 << 16) | 3454) +#define NX_TIEOFF_Inst_ARMTOP_P1_CLAMPL2 ((1 << 16) | 3464) +#define NX_TIEOFF_Inst_ARMTOP_P1_L2FLUSHREQ ((1 << 16) | 3562) +#define NX_TIEOFF_Inst_ARMTOP_P1_L2FLUSHDONE ((1 << 16) | 3563) +#define NX_TIEOFF_Inst_ARMTOP_P1_ACINACTM ((1 << 16) | 3567) +#endif + +#endif /* _NEXELL_TIEOFF_H */ diff --git a/arch/arm/mach-nexell/nx_gpio.c b/arch/arm/mach-nexell/nx_gpio.c new file mode 100644 index 0000000000..dfba3a2374 --- /dev/null +++ b/arch/arm/mach-nexell/nx_gpio.c @@ -0,0 +1,352 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Youngbok, Park <ybpark@nexell.co.kr> + */ + +/* + * FIXME : will be remove after support pinctrl + */ +#include <linux/types.h> +#include <asm/io.h> +#include <asm/arch/nexell.h> +#include "asm/arch/nx_gpio.h" +#define NUMBER_OF_GPIO_MODULE 5 +u32 __g_nx_gpio_valid_bit[NUMBER_OF_GPIO_MODULE] = { + 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF, 0xFFFFFFFF}; + +static struct { + struct nx_gpio_register_set *pregister; +} __g_module_variables[NUMBER_OF_GPIO_MODULE] = { + { (struct nx_gpio_register_set *)PHY_BASEADDR_GPIOA }, + { (struct nx_gpio_register_set *)PHY_BASEADDR_GPIOB }, + { (struct nx_gpio_register_set *)PHY_BASEADDR_GPIOC }, + { (struct nx_gpio_register_set *)PHY_BASEADDR_GPIOD }, + { (struct nx_gpio_register_set *)PHY_BASEADDR_GPIOE }, +}; + +enum { nx_gpio_max_bit = 32 }; + +void nx_gpio_set_bit(u32 *value, u32 bit, int enable) +{ + register u32 newvalue; + + newvalue = *value; + newvalue &= ~(1ul << bit); + newvalue |= (u32)enable << bit; + writel(newvalue, value); +} + +int nx_gpio_get_bit(u32 value, u32 bit) +{ + return (int)((value >> bit) & (1ul)); +} + +void nx_gpio_set_bit2(u32 *value, u32 bit, u32 bit_value) +{ + register u32 newvalue = *value; + + newvalue = (u32)(newvalue & ~(3ul << (bit * 2))); + newvalue = (u32)(newvalue | (bit_value << (bit * 2))); + + writel(newvalue, value); +} + +u32 nx_gpio_get_bit2(u32 value, u32 bit) +{ + return (u32)((u32)(value >> (bit * 2)) & 3ul); +} + +int nx_gpio_initialize(void) +{ + static int binit; + u32 i; + + binit = 0; + + if (binit == 0) { + for (i = 0; i < NUMBER_OF_GPIO_MODULE; i++) + __g_module_variables[i].pregister = NULL; + binit = true; + } + for (i = 0; i < NUMBER_OF_GPIO_MODULE; i++) { + __g_nx_gpio_valid_bit[i] = 0xFFFFFFFF; + }; + return true; +} + +u32 nx_gpio_get_number_of_module(void) +{ + return NUMBER_OF_GPIO_MODULE; +} + +u32 nx_gpio_get_size_of_register_set(void) +{ + return sizeof(struct nx_gpio_register_set); +} + +void nx_gpio_set_base_address(u32 module_index, void *base_address) +{ + __g_module_variables[module_index].pregister = + (struct nx_gpio_register_set *)base_address; +} + +void *nx_gpio_get_base_address(u32 module_index) +{ + return (void *)__g_module_variables[module_index].pregister; +} + +int nx_gpio_open_module(u32 module_index) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + writel(0xFFFFFFFF, &pregister->gpiox_slew_disable_default); + writel(0xFFFFFFFF, &pregister->gpiox_drv1_disable_default); + writel(0xFFFFFFFF, &pregister->gpiox_drv0_disable_default); + writel(0xFFFFFFFF, &pregister->gpiox_pullsel_disable_default); + writel(0xFFFFFFFF, &pregister->gpiox_pullenb_disable_default); + return true; +} + +int nx_gpio_close_module(u32 module_index) { return true; } + +int nx_gpio_check_busy(u32 module_index) { return false; } + +void nx_gpio_set_pad_function(u32 module_index, u32 bit_number, + u32 padfunc) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + nx_gpio_set_bit2(&pregister->gpioxaltfn[bit_number / 16], + bit_number % 16, padfunc); +} + +void nx_gpio_set_pad_function32(u32 module_index, u32 msbvalue, u32 lsbvalue) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + writel(lsbvalue, &pregister->gpioxaltfn[0]); + writel(msbvalue, &pregister->gpioxaltfn[1]); +} + +int nx_gpio_get_pad_function(u32 module_index, u32 bit_number) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return (int)nx_gpio_get_bit2 + (readl(&pregister->gpioxaltfn[bit_number / 16]), + bit_number % 16); +} + +void nx_gpio_set_output_enable(u32 module_index, u32 bit_number, + int output_enb) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + nx_gpio_set_bit(&pregister->gpioxoutenb, bit_number, output_enb); +} + +int nx_gpio_get_detect_enable(u32 module_index, u32 bit_number) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return nx_gpio_get_bit(readl(&pregister->gpioxdetenb), bit_number); +} + +u32 nx_gpio_get_detect_enable32(u32 module_index) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return readl(&pregister->gpioxdetenb); +} + +void nx_gpio_set_detect_enable(u32 module_index, u32 bit_number, + int detect_enb) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + nx_gpio_set_bit(&pregister->gpioxdetenb, bit_number, detect_enb); +} + +void nx_gpio_set_detect_enable32(u32 module_index, u32 enable_flag) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + writel(enable_flag, &pregister->gpioxdetenb); +} + +int nx_gpio_get_output_enable(u32 module_index, u32 bit_number) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return nx_gpio_get_bit(readl(&pregister->gpioxoutenb), bit_number); +} + +void nx_gpio_set_output_enable32(u32 module_index, int output_enb) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + if (output_enb) + writel(0xFFFFFFFF, &pregister->gpioxoutenb); + else + writel(0x0, &pregister->gpioxoutenb); +} + +u32 nx_gpio_get_output_enable32(u32 module_index) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return readl(&pregister->gpioxoutenb); +} + +void nx_gpio_set_output_value(u32 module_index, u32 bit_number, int value) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + nx_gpio_set_bit(&pregister->gpioxout, bit_number, value); +} + +int nx_gpio_get_output_value(u32 module_index, u32 bit_number) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return nx_gpio_get_bit(readl(&pregister->gpioxout), bit_number); +} + +void nx_gpio_set_output_value32(u32 module_index, u32 value) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + writel(value, &pregister->gpioxout); +} + +u32 nx_gpio_get_output_value32(u32 module_index) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return readl(&pregister->gpioxout); +} + +int nx_gpio_get_input_value(u32 module_index, u32 bit_number) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + return nx_gpio_get_bit(readl(&pregister->gpioxpad), bit_number); +} + +void nx_gpio_set_pull_select(u32 module_index, u32 bit_number, int enable) +{ + nx_gpio_set_bit(&__g_module_variables[module_index] + .pregister->gpiox_pullsel_disable_default, + bit_number, true); + nx_gpio_set_bit + (&__g_module_variables[module_index].pregister->gpiox_pullsel, + bit_number, enable); +} + +void nx_gpio_set_pull_select32(u32 module_index, u32 value) +{ + writel(value, + &__g_module_variables[module_index].pregister->gpiox_pullsel); +} + +int nx_gpio_get_pull_select(u32 module_index, u32 bit_number) +{ + return nx_gpio_get_bit + (__g_module_variables[module_index].pregister->gpiox_pullsel, + bit_number); +} + +u32 nx_gpio_get_pull_select32(u32 module_index) +{ + return __g_module_variables[module_index].pregister->gpiox_pullsel; +} + +void nx_gpio_set_pull_mode(u32 module_index, u32 bit_number, u32 mode) +{ + nx_gpio_set_bit(&__g_module_variables[module_index] + .pregister->gpiox_pullsel_disable_default, + bit_number, true); + nx_gpio_set_bit(&__g_module_variables[module_index] + .pregister->gpiox_pullenb_disable_default, + bit_number, true); + if (mode == nx_gpio_pull_off) { + nx_gpio_set_bit + (&__g_module_variables[module_index].pregister->gpiox_pullenb, + bit_number, false); + nx_gpio_set_bit + (&__g_module_variables[module_index].pregister->gpiox_pullsel, + bit_number, false); + } else { + nx_gpio_set_bit + (&__g_module_variables[module_index].pregister->gpiox_pullsel, + bit_number, (mode & 1 ? true : false)); + nx_gpio_set_bit + (&__g_module_variables[module_index].pregister->gpiox_pullenb, + bit_number, true); + } +} + +void nx_gpio_set_fast_slew(u32 module_index, u32 bit_number, + int enable) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + nx_gpio_set_bit(&pregister->gpiox_slew, bit_number, + (int)(!enable)); +} + +void nx_gpio_set_drive_strength(u32 module_index, u32 bit_number, + u32 drvstrength) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + nx_gpio_set_bit(&pregister->gpiox_drv1, bit_number, + (int)(((u32)drvstrength >> 0) & 0x1)); + nx_gpio_set_bit(&pregister->gpiox_drv0, bit_number, + (int)(((u32)drvstrength >> 1) & 0x1)); +} + +void nx_gpio_set_drive_strength_disable_default(u32 module_index, + u32 bit_number, int enable) +{ + register struct nx_gpio_register_set *pregister; + + pregister = __g_module_variables[module_index].pregister; + nx_gpio_set_bit(&pregister->gpiox_drv1_disable_default, bit_number, + (int)(enable)); + nx_gpio_set_bit(&pregister->gpiox_drv0_disable_default, bit_number, + (int)(enable)); +} + +u32 nx_gpio_get_drive_strength(u32 module_index, u32 bit_number) +{ + register struct nx_gpio_register_set *pregister; + register u32 retvalue; + + pregister = __g_module_variables[module_index].pregister; + retvalue = + nx_gpio_get_bit(readl(&pregister->gpiox_drv0), bit_number) << 1; + retvalue |= + nx_gpio_get_bit(readl(&pregister->gpiox_drv1), bit_number) << 0; + return retvalue; +} diff --git a/arch/arm/mach-nexell/nx_sec_reg.c b/arch/arm/mach-nexell/nx_sec_reg.c new file mode 100644 index 0000000000..3d3dd9fd8b --- /dev/null +++ b/arch/arm/mach-nexell/nx_sec_reg.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Youngbok, Park <park@nexell.co.kr> + */ + +#include <linux/types.h> +#include <asm/io.h> +#include <asm/arch/nexell.h> +#include <asm/arch/sec_reg.h> +#include <linux/linkage.h> + +#define NEXELL_SMC_BASE 0x82000000 + +#define NEXELL_SMC_FN(n) (NEXELL_SMC_BASE + (n)) + +#define NEXELL_SMC_SEC_REG_WRITE NEXELL_SMC_FN(0x0) +#define NEXELL_SMC_SEC_REG_READ NEXELL_SMC_FN(0x1) + +#define SECURE_ID_SHIFT 8 + +#define SEC_4K_OFFSET ((4 * 1024) - 1) +#define SEC_64K_OFFSET ((64 * 1024) - 1) + +asmlinkage int __invoke_nexell_fn_smc(u32, u32, u32, u32); + +int write_sec_reg_by_id(void __iomem *reg, int val, int id) +{ + int ret = 0; + u32 off = 0; + + switch (id) { + case NEXELL_L2C_SEC_ID: + case NEXELL_MIPI_SEC_ID: + case NEXELL_TOFF_SEC_ID: + off = (u32)reg & SEC_4K_OFFSET; + break; + case NEXELL_MALI_SEC_ID: + off = (u32)reg & SEC_64K_OFFSET; + break; + } + ret = __invoke_nexell_fn_smc(NEXELL_SMC_SEC_REG_WRITE | + ((1 << SECURE_ID_SHIFT) + id), off, val, 0); + return ret; +} + +int read_sec_reg_by_id(void __iomem *reg, int id) +{ + int ret = 0; + u32 off = 0; + + switch (id) { + case NEXELL_L2C_SEC_ID: + case NEXELL_MIPI_SEC_ID: + case NEXELL_TOFF_SEC_ID: + off = (u32)reg & SEC_4K_OFFSET; + break; + case NEXELL_MALI_SEC_ID: + off = (u32)reg & SEC_64K_OFFSET; + break; + } + ret = __invoke_nexell_fn_smc(NEXELL_SMC_SEC_REG_READ | + ((1 << SECURE_ID_SHIFT) + id), off, 0, 0); + return ret; +} + +int write_sec_reg(void __iomem *reg, int val) +{ + int ret = 0; + + ret = __invoke_nexell_fn_smc(NEXELL_SMC_SEC_REG_WRITE, + (u32)reg, val, 0); + return ret; +} + +int read_sec_reg(void __iomem *reg) +{ + int ret = 0; + + ret = __invoke_nexell_fn_smc(NEXELL_SMC_SEC_REG_READ, (u32)reg, 0, 0); + return ret; +} diff --git a/arch/arm/mach-nexell/reg-call.S b/arch/arm/mach-nexell/reg-call.S new file mode 100644 index 0000000000..5fdf51520d --- /dev/null +++ b/arch/arm/mach-nexell/reg-call.S @@ -0,0 +1,23 @@ +#include <asm-offsets.h> +#include <config.h> +#include <linux/linkage.h> + +#define ___asm_opcode_identity32(x) ((x) & 0xFFFFFFFF) +#define __opcode_to_mem_arm(x) ___opcode_identity32(x) +#define ___asm_opcode_to_mem_arm(x) ___asm_opcode_identity32(x) + +#define ___opcode_identity32(x) ((u32)(x)) +#define ___inst_arm(x) .long x +#define __inst_arm(x) ___inst_arm(___asm_opcode_to_mem_arm(x)) + +#define __inst_arm_thumb32(arm_opcode, thumb_opcode) __inst_arm(arm_opcode) + +#define __SMC(imm4) __inst_arm_thumb32( \ + 0xE1600070 | (((imm4) & 0xF) << 0), \ + 0xF7F08000 | (((imm4) & 0xF) << 16) \ +) + +ENTRY(__invoke_nexell_fn_smc) + __SMC(0) + bx lr +ENDPROC(__invoke_nexell_fn_smc) diff --git a/arch/arm/mach-nexell/reset.c b/arch/arm/mach-nexell/reset.c new file mode 100644 index 0000000000..1f732a3d37 --- /dev/null +++ b/arch/arm/mach-nexell/reset.c @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Youngbok, Park <park@nexell.co.kr> + */ + +/* + *FIXME : Not support device tree & reset control driver. + * will remove after support device tree & reset control driver. + */ +#include <common.h> +#include <asm/io.h> +#include <asm/arch/nexell.h> +#include <asm/arch/reset.h> + +struct nx_rstcon_registerset { + u32 regrst[(NUMBER_OF_RESET_MODULE_PIN + 31) >> 5]; +}; + +static struct nx_rstcon_registerset *nx_rstcon = + (struct nx_rstcon_registerset *)PHY_BASEADDR_RSTCON; + +void nx_rstcon_setrst(u32 rstindex, enum rstcon status) +{ + u32 regnum, bitpos, curstat; + + regnum = rstindex >> 5; + curstat = (u32)readl(&nx_rstcon->regrst[regnum]); + bitpos = rstindex & 0x1f; + curstat &= ~(1UL << bitpos); + curstat |= (status & 0x01) << bitpos; + writel(curstat, &nx_rstcon->regrst[regnum]); +} diff --git a/arch/arm/mach-nexell/tieoff.c b/arch/arm/mach-nexell/tieoff.c new file mode 100644 index 0000000000..5a4744c296 --- /dev/null +++ b/arch/arm/mach-nexell/tieoff.c @@ -0,0 +1,107 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Youngbok, Park <park@nexell.co.kr> + */ + +#include <common.h> +#include <asm/arch/nexell.h> +#include <asm/arch/clk.h> +#include <asm/arch/reset.h> +#include <asm/arch/nx_gpio.h> +#include <asm/arch/tieoff.h> +#include <asm/arch/sec_reg.h> + +#define NX_PIN_FN_SIZE 4 +#define TIEOFF_REG_NUM 33 + +struct nx_tieoff_registerset { + u32 tieoffreg[TIEOFF_REG_NUM]; +}; + +static struct nx_tieoff_registerset *nx_tieoff = (void *)PHY_BASEADDR_TIEOFF; + +static int tieoff_readl(void __iomem *reg) +{ + if (IS_ENABLED(CONFIG_ARCH_S5P4418)) + return read_sec_reg_by_id(reg, NEXELL_TOFF_SEC_ID); + else + return readl(reg); +} + +static int tieoff_writetl(void __iomem *reg, int val) +{ + if (IS_ENABLED(CONFIG_ARCH_S5P4418)) + return write_sec_reg_by_id(reg, val, NEXELL_TOFF_SEC_ID); + else + return writel(val, reg); +} + +void nx_tieoff_set(u32 tieoff_index, u32 tieoff_value) +{ + u32 regindex, mask; + u32 lsb, msb; + u32 regval; + + u32 position; + u32 bitwidth; + + position = tieoff_index & 0xffff; + bitwidth = (tieoff_index >> 16) & 0xffff; + + regindex = position >> 5; + + lsb = position & 0x1F; + msb = lsb + bitwidth; + + if (msb > 32) { + msb &= 0x1F; + mask = ~(0xffffffff << lsb); + regval = tieoff_readl(&nx_tieoff->tieoffreg[regindex]) & mask; + regval |= ((tieoff_value & ((1UL << bitwidth) - 1)) << lsb); + tieoff_writetl(&nx_tieoff->tieoffreg[regindex], regval); + + mask = (0xffffffff << msb); + regval = tieoff_readl(&nx_tieoff->tieoffreg[regindex]) & mask; + regval |= ((tieoff_value & ((1UL << bitwidth) - 1)) >> msb); + tieoff_writetl(&nx_tieoff->tieoffreg[regindex + 1], regval); + } else { + mask = (0xffffffff << msb) | (~(0xffffffff << lsb)); + regval = tieoff_readl(&nx_tieoff->tieoffreg[regindex]) & mask; + regval |= ((tieoff_value & ((1UL << bitwidth) - 1)) << lsb); + tieoff_writetl(&nx_tieoff->tieoffreg[regindex], regval); + } +} + +u32 nx_tieoff_get(u32 tieoff_index) +{ + u32 regindex, mask; + u32 lsb, msb; + u32 regval; + + u32 position; + u32 bitwidth; + + position = tieoff_index & 0xffff; + bitwidth = (tieoff_index >> 16) & 0xffff; + + regindex = position / 32; + lsb = position % 32; + msb = lsb + bitwidth; + + if (msb > 32) { + msb &= 0x1F; + mask = 0xffffffff << lsb; + regval = tieoff_readl(&nx_tieoff->tieoffreg[regindex]) & mask; + regval >>= lsb; + + mask = ~(0xffffffff << msb); + regval |= ((tieoff_readl(&nx_tieoff->tieoffreg[regindex + 1]) + & mask) << (32 - lsb)); + } else { + mask = ~(0xffffffff << msb) & (0xffffffff << lsb); + regval = tieoff_readl(&nx_tieoff->tieoffreg[regindex]) & mask; + regval >>= lsb; + } + return regval; +} diff --git a/arch/arm/mach-nexell/timer.c b/arch/arm/mach-nexell/timer.c new file mode 100644 index 0000000000..fecee67265 --- /dev/null +++ b/arch/arm/mach-nexell/timer.c @@ -0,0 +1,299 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * (C) Copyright 2016 Nexell + * Hyunseok, Jung <hsjung@nexell.co.kr> + */ + +#include <common.h> +#include <log.h> + +#include <asm/io.h> +#include <asm/arch/nexell.h> +#include <asm/arch/clk.h> +#if defined(CONFIG_ARCH_S5P4418) +#include <asm/arch/reset.h> +#endif + +#if (CONFIG_TIMER_SYS_TICK_CH > 3) +#error Not support timer channel. Please use "0~3" channels. +#endif + +/* global variables to save timer count + * + * Section ".data" must be used because BSS is not available before relocation, + * in board_init_f(), respectively! I.e. global variables can not be used! + */ +static unsigned long timestamp __attribute__ ((section(".data"))); +static unsigned long lastdec __attribute__ ((section(".data"))); +static int timerinit __attribute__ ((section(".data"))); + +/* macro to hw timer tick config */ +static long TIMER_FREQ = 1000000; +static long TIMER_HZ = 1000000 / CONFIG_SYS_HZ; +static long TIMER_COUNT = 0xFFFFFFFF; + +#define REG_TCFG0 (0x00) +#define REG_TCFG1 (0x04) +#define REG_TCON (0x08) +#define REG_TCNTB0 (0x0C) +#define REG_TCMPB0 (0x10) +#define REG_TCNT0 (0x14) +#define REG_CSTAT (0x44) + +#define TCON_BIT_AUTO (1 << 3) +#define TCON_BIT_INVT (1 << 2) +#define TCON_BIT_UP (1 << 1) +#define TCON_BIT_RUN (1 << 0) +#define TCFG0_BIT_CH(ch) ((ch) == 0 || (ch) == 1 ? 0 : 8) +#define TCFG1_BIT_CH(ch) ((ch) * 4) +#define TCON_BIT_CH(ch) ((ch) ? (ch) * 4 + 4 : 0) +#define TINT_CH(ch) (ch) +#define TINT_CSTAT_BIT_CH(ch) ((ch) + 5) +#define TINT_CSTAT_MASK (0x1F) +#define TIMER_TCNT_OFFS (0xC) + +void reset_timer_masked(void); +unsigned long get_timer_masked(void); + +/* + * Timer HW + */ +static inline void timer_clock(void __iomem *base, int ch, int mux, int scl) +{ + u32 val = readl(base + REG_TCFG0) & ~(0xFF << TCFG0_BIT_CH(ch)); + + writel(val | ((scl - 1) << TCFG0_BIT_CH(ch)), base + REG_TCFG0); + val = readl(base + REG_TCFG1) & ~(0xF << TCFG1_BIT_CH(ch)); + writel(val | (mux << TCFG1_BIT_CH(ch)), base + REG_TCFG1); +} + +static inline void timer_count(void __iomem *base, int ch, unsigned int cnt) +{ + writel((cnt - 1), base + REG_TCNTB0 + (TIMER_TCNT_OFFS * ch)); + writel((cnt - 1), base + REG_TCMPB0 + (TIMER_TCNT_OFFS * ch)); +} + +static inline void timer_start(void __iomem *base, int ch) +{ + int on = 0; + u32 val = readl(base + REG_CSTAT) & ~(TINT_CSTAT_MASK << 5 | 0x1 << ch); + + writel(val | (0x1 << TINT_CSTAT_BIT_CH(ch) | on << ch), + base + REG_CSTAT); + val = readl(base + REG_TCON) & ~(0xE << TCON_BIT_CH(ch)); + writel(val | (TCON_BIT_UP << TCON_BIT_CH(ch)), base + REG_TCON); + + val &= ~(TCON_BIT_UP << TCON_BIT_CH(ch)); + val |= ((TCON_BIT_AUTO | TCON_BIT_RUN) << TCON_BIT_CH(ch)); + writel(val, base + REG_TCON); + dmb(); +} + +static inline void timer_stop(void __iomem *base, int ch) +{ + int on = 0; + u32 val = readl(base + REG_CSTAT) & ~(TINT_CSTAT_MASK << 5 | 0x1 << ch); + + writel(val | (0x1 << TINT_CSTAT_BIT_CH(ch) | on << ch), + base + REG_CSTAT); + val = readl(base + REG_TCON) & ~(TCON_BIT_RUN << TCON_BIT_CH(ch)); + writel(val, base + REG_TCON); +} + +static inline unsigned long timer_read(void __iomem *base, int ch) +{ + unsigned long ret; + + ret = TIMER_COUNT - readl(base + REG_TCNT0 + (TIMER_TCNT_OFFS * ch)); + return ret; +} + +int timer_init(void) +{ + struct clk *clk = NULL; + char name[16] = "pclk"; + int ch = CONFIG_TIMER_SYS_TICK_CH; + unsigned long rate, tclk = 0; + unsigned long mout, thz, cmp = -1UL; + int tcnt, tscl = 0, tmux = 0; + int mux = 0, scl = 0; + void __iomem *base = (void __iomem *)PHY_BASEADDR_TIMER; + + if (timerinit) + return 0; + + /* get with PCLK */ + clk = clk_get(name); + rate = clk_get_rate(clk); + for (mux = 0; mux < 5; mux++) { + mout = rate / (1 << mux), scl = mout / TIMER_FREQ, + thz = mout / scl; + if (!(mout % TIMER_FREQ) && 256 > scl) { + tclk = thz, tmux = mux, tscl = scl; + break; + } + if (scl > 256) + continue; + if (abs(thz - TIMER_FREQ) >= cmp) + continue; + tclk = thz, tmux = mux, tscl = scl; + cmp = abs(thz - TIMER_FREQ); + } + tcnt = tclk; /* Timer Count := 1 Mhz counting */ + + TIMER_FREQ = tcnt; /* Timer Count := 1 Mhz counting */ + TIMER_HZ = TIMER_FREQ / CONFIG_SYS_HZ; + tcnt = TIMER_COUNT == 0xFFFFFFFF ? TIMER_COUNT + 1 : tcnt; + + timer_stop(base, ch); + timer_clock(base, ch, tmux, tscl); + timer_count(base, ch, tcnt); + timer_start(base, ch); + + reset_timer_masked(); + timerinit = 1; + + return 0; +} + +void reset_timer(void) +{ + reset_timer_masked(); +} + +unsigned long get_timer(unsigned long base) +{ + long ret; + unsigned long time = get_timer_masked(); + unsigned long hz = TIMER_HZ; + + ret = time / hz - base; + return ret; +} + +void set_timer(unsigned long t) +{ + timestamp = (unsigned long)t; +} + +void reset_timer_masked(void) +{ + void __iomem *base = (void __iomem *)PHY_BASEADDR_TIMER; + int ch = CONFIG_TIMER_SYS_TICK_CH; + + /* reset time */ + /* capure current decrementer value time */ + lastdec = timer_read(base, ch); + /* start "advancing" time stamp from 0 */ + timestamp = 0; +} + +unsigned long get_timer_masked(void) +{ + void __iomem *base = (void __iomem *)PHY_BASEADDR_TIMER; + int ch = CONFIG_TIMER_SYS_TICK_CH; + + unsigned long now = timer_read(base, ch); /* current tick value */ + + if (now >= lastdec) { /* normal mode (non roll) */ + /* move stamp fordward with absolute diff ticks */ + timestamp += now - lastdec; + } else { + /* we have overflow of the count down timer */ + /* nts = ts + ld + (TLV - now) + * ts=old stamp, ld=time that passed before passing through -1 + * (TLV-now) amount of time after passing though -1 + * nts = new "advancing time stamp"... + * it could also roll and cause problems. + */ + timestamp += now + TIMER_COUNT - lastdec; + } + /* save last */ + lastdec = now; + + debug("now=%lu, last=%lu, timestamp=%lu\n", now, lastdec, timestamp); + return (unsigned long)timestamp; +} + +void __udelay(unsigned long usec) +{ + unsigned long tmo, tmp; + + debug("+udelay=%ld\n", usec); + + if (!timerinit) + timer_init(); + + /* if "big" number, spread normalization to seconds */ + if (usec >= 1000) { + /* start to normalize for usec to ticks per sec */ + tmo = usec / 1000; + /* find number of "ticks" to wait to achieve target */ + tmo *= TIMER_FREQ; + /* finish normalize. */ + tmo /= 1000; + /* else small number, don't kill it prior to HZ multiply */ + } else { + tmo = usec * TIMER_FREQ; + tmo /= (1000 * 1000); + } + + tmp = get_timer_masked(); /* get current timestamp */ + debug("A. tmo=%ld, tmp=%ld\n", tmo, tmp); + + /* if setting this fordward will roll time stamp */ + if (tmp > (tmo + tmp + 1)) + /* reset "advancing" timestamp to 0, set lastdec value */ + reset_timer_masked(); + else + /* set advancing stamp wake up time */ + tmo += tmp; + + debug("B. tmo=%ld, tmp=%ld\n", tmo, tmp); + + /* loop till event */ + do { + tmp = get_timer_masked(); + } while (tmo > tmp); + debug("-udelay=%ld\n", usec); +} + +void udelay_masked(unsigned long usec) +{ + unsigned long tmo, endtime; + signed long diff; + + /* if "big" number, spread normalization to seconds */ + if (usec >= 1000) { + /* start to normalize for usec to ticks per sec */ + tmo = usec / 1000; + /* find number of "ticks" to wait to achieve target */ + tmo *= TIMER_FREQ; + /* finish normalize. */ + tmo /= 1000; + } else { /* else small number, don't kill it prior to HZ multiply */ + tmo = usec * TIMER_FREQ; + tmo /= (1000 * 1000); + } + + endtime = get_timer_masked() + tmo; + + do { + unsigned long now = get_timer_masked(); + + diff = endtime - now; + } while (diff >= 0); +} + +unsigned long long get_ticks(void) +{ + return get_timer_masked(); +} + +#if defined(CONFIG_ARCH_S5P4418) +ulong get_tbclk(void) +{ + ulong tbclk = TIMER_FREQ; + return tbclk; +} +#endif |