Merge branch '2020-07-28-misc-soc-improvements'
- Assorted MediaTek improvements - s5p4418 support - QEMU ARM platform improvements - Qualcomm IPQ40xx support
This commit is contained in:
commit
423e08cb77
24
MAINTAINERS
24
MAINTAINERS
|
@ -218,6 +218,13 @@ F: arch/arm/cpu/armv8/hisilicon
|
|||
F: arch/arm/include/asm/arch-hi6220/
|
||||
F: arch/arm/include/asm/arch-hi3660/
|
||||
|
||||
ARM IPQ40XX
|
||||
M: Robert Marko <robert.marko@sartura.hr>
|
||||
M: Luka Kovacic <luka.kovacic@sartura.hr>
|
||||
M: Luka Perkov <luka.perkov@sartura.hr>
|
||||
S: Maintained
|
||||
F: arch/arm/mach-ipq40xx/
|
||||
|
||||
ARM MARVELL KIRKWOOD ARMADA-XP ARMADA-38X ARMADA-37XX ARMADA-7K/8K
|
||||
M: Stefan Roese <sr@denx.de>
|
||||
S: Maintained
|
||||
|
@ -273,6 +280,23 @@ F: arch/arm/mach-at91/
|
|||
F: board/atmel/
|
||||
F: drivers/misc/microchip_flexcom.c
|
||||
|
||||
ARM NEXELL S5P4418
|
||||
M: Stefan Bosch <stefan_b@posteo.net>
|
||||
S: Maintained
|
||||
F: arch/arm/cpu/armv7/s5p4418/
|
||||
F: arch/arm/dts/s5p4418*
|
||||
F: arch/arm/mach-nexell/
|
||||
F: board/friendlyarm/
|
||||
F: configs/s5p4418_nanopi2_defconfig
|
||||
F: doc/README.s5p4418
|
||||
F: drivers/gpio/nx_gpio.c
|
||||
F: drivers/i2c/nx_i2c.c
|
||||
F: drivers/mmc/nexell_dw_mmc_dm.c
|
||||
F: drivers/pinctrl/nexell/
|
||||
F: drivers/video/nexell/
|
||||
F: drivers/video/nexell_display.c
|
||||
F: include/configs/s5p4418_nanopi2.h
|
||||
|
||||
ARM OWL
|
||||
M: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
|
||||
S: Maintained
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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/
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
||||
tin_parent_rate = get_pwm_clk();
|
||||
#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;
|
||||
|
|
6
arch/arm/cpu/armv7/s5p4418/Makefile
Normal file
6
arch/arm/cpu/armv7/s5p4418/Makefile
Normal file
|
@ -0,0 +1,6 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2016 Nexell
|
||||
# Hyunseok, Jung <hsjung@nexell.co.kr>
|
||||
|
||||
obj-y += cpu.o
|
121
arch/arm/cpu/armv7/s5p4418/cpu.c
Normal file
121
arch/arm/cpu/armv7/s5p4418/cpu.c
Normal file
|
@ -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 */
|
|
@ -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 \
|
||||
|
|
211
arch/arm/dts/mt7623a-unielec-u7623-02-emmc.dts
Normal file
211
arch/arm/dts/mt7623a-unielec-u7623-02-emmc.dts
Normal file
|
@ -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";
|
||||
};
|
|
@ -24,12 +24,14 @@
|
|||
|
||||
ð {
|
||||
status = "okay";
|
||||
mediatek,gmac-id = <1>;
|
||||
phy-mode = "gmii";
|
||||
phy-handle = <&phy0>;
|
||||
mediatek,gmac-id = <0>;
|
||||
phy-mode = "sgmii";
|
||||
mediatek,switch = "mt7531";
|
||||
reset-gpios = <&gpio 28 GPIO_ACTIVE_HIGH>;
|
||||
|
||||
phy0: ethernet-phy@0 {
|
||||
reg = <0>;
|
||||
fixed-link {
|
||||
speed = <1000>;
|
||||
full-duplex;
|
||||
};
|
||||
};
|
||||
|
||||
|
|
79
arch/arm/dts/qcom-ipq4019.dtsi
Normal file
79
arch/arm/dts/qcom-ipq4019.dtsi
Normal file
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
110
arch/arm/dts/s5p4418-nanopi2.dts
Normal file
110
arch/arm/dts/s5p4418-nanopi2.dts
Normal file
|
@ -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>;
|
||||
};
|
||||
};
|
||||
};
|
||||
};
|
135
arch/arm/dts/s5p4418-pinctrl.dtsi
Normal file
135
arch/arm/dts/s5p4418-pinctrl.dtsi
Normal file
|
@ -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>;
|
||||
};
|
||||
};
|
170
arch/arm/dts/s5p4418.dtsi
Normal file
170
arch/arm/dts/s5p4418.dtsi
Normal file
|
@ -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;
|
||||
};
|
||||
};
|
|
@ -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,
|
||||
|
|
15
arch/arm/mach-ipq40xx/Kconfig
Normal file
15
arch/arm/mach-ipq40xx/Kconfig
Normal file
|
@ -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
|
9
arch/arm/mach-ipq40xx/Makefile
Normal file
9
arch/arm/mach-ipq40xx/Makefile
Normal file
|
@ -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
|
64
arch/arm/mach-ipq40xx/clock-ipq4019.c
Normal file
64
arch/arm/mach-ipq40xx/clock-ipq4019.c
Normal file
|
@ -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,
|
||||
};
|
10
arch/arm/mach-ipq40xx/include/mach/gpio.h
Normal file
10
arch/arm/mach-ipq40xx/include/mach/gpio.h
Normal file
|
@ -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>
|
||||
*/
|
47
arch/arm/mach-ipq40xx/pinctrl-ipq4019.c
Normal file
47
arch/arm/mach-ipq40xx/pinctrl-ipq4019.c
Normal file
|
@ -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,
|
||||
};
|
137
arch/arm/mach-ipq40xx/pinctrl-snapdragon.c
Normal file
137
arch/arm/mach-ipq40xx/pinctrl-snapdragon.c
Normal file
|
@ -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,
|
||||
};
|
30
arch/arm/mach-ipq40xx/pinctrl-snapdragon.h
Normal file
30
arch/arm/mach-ipq40xx/pinctrl-snapdragon.h
Normal file
|
@ -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
|
58
arch/arm/mach-nexell/Kconfig
Normal file
58
arch/arm/mach-nexell/Kconfig
Normal file
|
@ -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
|
13
arch/arm/mach-nexell/Makefile
Normal file
13
arch/arm/mach-nexell/Makefile
Normal file
|
@ -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
|
869
arch/arm/mach-nexell/clock.c
Normal file
869
arch/arm/mach-nexell/clock.c
Normal file
|
@ -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);
|
||||
}
|
144
arch/arm/mach-nexell/cmd_boot_linux.c
Normal file
144
arch/arm/mach-nexell/cmd_boot_linux.c
Normal file
|
@ -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
|
11
arch/arm/mach-nexell/config.mk
Normal file
11
arch/arm/mach-nexell/config.mk
Normal file
|
@ -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)
|
40
arch/arm/mach-nexell/include/mach/boot0.h
Normal file
40
arch/arm/mach-nexell/include/mach/boot0.h
Normal file
|
@ -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 */
|
24
arch/arm/mach-nexell/include/mach/clk.h
Normal file
24
arch/arm/mach-nexell/include/mach/clk.h
Normal file
|
@ -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
|
273
arch/arm/mach-nexell/include/mach/display.h
Normal file
273
arch/arm/mach-nexell/include/mach/display.h
Normal file
|
@ -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
|
37
arch/arm/mach-nexell/include/mach/display_dev.h
Normal file
37
arch/arm/mach-nexell/include/mach/display_dev.h
Normal file
|
@ -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
|
106
arch/arm/mach-nexell/include/mach/ehci.h
Normal file
106
arch/arm/mach-nexell/include/mach/ehci.h
Normal file
|
@ -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__ */
|
17
arch/arm/mach-nexell/include/mach/gpio.h
Normal file
17
arch/arm/mach-nexell/include/mach/gpio.h
Normal file
|
@ -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 */
|
215
arch/arm/mach-nexell/include/mach/mipi_display.h
Normal file
215
arch/arm/mach-nexell/include/mach/mipi_display.h
Normal file
|
@ -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
|
352
arch/arm/mach-nexell/include/mach/nexell.h
Normal file
352
arch/arm/mach-nexell/include/mach/nexell.h
Normal file
|
@ -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__ */
|
103
arch/arm/mach-nexell/include/mach/nx_gpio.h
Normal file
103
arch/arm/mach-nexell/include/mach/nx_gpio.h
Normal file
|
@ -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
|
54
arch/arm/mach-nexell/include/mach/pwm.h
Normal file
54
arch/arm/mach-nexell/include/mach/pwm.h
Normal file
|
@ -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
|
19
arch/arm/mach-nexell/include/mach/reset.h
Normal file
19
arch/arm/mach-nexell/include/mach/reset.h
Normal file
|
@ -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__ */
|
15
arch/arm/mach-nexell/include/mach/sec_reg.h
Normal file
15
arch/arm/mach-nexell/include/mach/sec_reg.h
Normal file
|
@ -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);
|
423
arch/arm/mach-nexell/include/mach/tieoff.h
Normal file
423
arch/arm/mach-nexell/include/mach/tieoff.h
Normal file
|
@ -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 */
|
352
arch/arm/mach-nexell/nx_gpio.c
Normal file
352
arch/arm/mach-nexell/nx_gpio.c
Normal file
|
@ -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;
|
||||
}
|
82
arch/arm/mach-nexell/nx_sec_reg.c
Normal file
82
arch/arm/mach-nexell/nx_sec_reg.c
Normal file
|
@ -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;
|
||||
}
|
23
arch/arm/mach-nexell/reg-call.S
Normal file
23
arch/arm/mach-nexell/reg-call.S
Normal file
|
@ -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)
|
33
arch/arm/mach-nexell/reset.c
Normal file
33
arch/arm/mach-nexell/reset.c
Normal file
|
@ -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]);
|
||||
}
|
107
arch/arm/mach-nexell/tieoff.c
Normal file
107
arch/arm/mach-nexell/tieoff.c
Normal file
|
@ -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;
|
||||
}
|
299
arch/arm/mach-nexell/timer.c
Normal file
299
arch/arm/mach-nexell/timer.c
Normal file
|
@ -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
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <cpu_func.h>
|
||||
#include <dm.h>
|
||||
#include <fdtdec.h>
|
||||
#include <init.h>
|
||||
|
@ -94,6 +95,12 @@ void *board_fdt_blob_setup(void)
|
|||
return (void *)CONFIG_SYS_SDRAM_BASE;
|
||||
}
|
||||
|
||||
void enable_caches(void)
|
||||
{
|
||||
icache_enable();
|
||||
dcache_enable();
|
||||
}
|
||||
|
||||
#if defined(CONFIG_EFI_RNG_PROTOCOL)
|
||||
#include <efi_loader.h>
|
||||
#include <efi_rng.h>
|
||||
|
@ -135,3 +142,48 @@ efi_status_t platform_get_rng_device(struct udevice **dev)
|
|||
return EFI_SUCCESS;
|
||||
}
|
||||
#endif /* CONFIG_EFI_RNG_PROTOCOL */
|
||||
|
||||
#ifdef CONFIG_ARM64
|
||||
#define __W "w"
|
||||
#else
|
||||
#define __W
|
||||
#endif
|
||||
|
||||
u8 flash_read8(void *addr)
|
||||
{
|
||||
u8 ret;
|
||||
|
||||
asm("ldrb %" __W "0, %1" : "=r"(ret) : "m"(*(u8 *)addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
u16 flash_read16(void *addr)
|
||||
{
|
||||
u16 ret;
|
||||
|
||||
asm("ldrh %" __W "0, %1" : "=r"(ret) : "m"(*(u16 *)addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
u32 flash_read32(void *addr)
|
||||
{
|
||||
u32 ret;
|
||||
|
||||
asm("ldr %" __W "0, %1" : "=r"(ret) : "m"(*(u32 *)addr));
|
||||
return ret;
|
||||
}
|
||||
|
||||
void flash_write8(u8 value, void *addr)
|
||||
{
|
||||
asm("strb %" __W "1, %0" : "=m"(*(u8 *)addr) : "r"(value));
|
||||
}
|
||||
|
||||
void flash_write16(u16 value, void *addr)
|
||||
{
|
||||
asm("strh %" __W "1, %0" : "=m"(*(u16 *)addr) : "r"(value));
|
||||
}
|
||||
|
||||
void flash_write32(u32 value, void *addr)
|
||||
{
|
||||
asm("str %" __W "1, %0" : "=m"(*(u32 *)addr) : "r"(value));
|
||||
}
|
||||
|
|
37
board/friendlyarm/Kconfig
Normal file
37
board/friendlyarm/Kconfig
Normal file
|
@ -0,0 +1,37 @@
|
|||
choice
|
||||
prompt "LCD backlight control"
|
||||
optional
|
||||
default S5P4418_ONEWIRE
|
||||
|
||||
config S5P4418_ONEWIRE
|
||||
bool "I2C / 1-Wire"
|
||||
help
|
||||
This enables LCD-Backlight control for FriendlyARM LCD-panels.
|
||||
I2C is used if available, otherwise 1-Wire is used.
|
||||
|
||||
config PWM_NX
|
||||
bool "PWM"
|
||||
help
|
||||
This enables LCD-Backlight control via PWM.
|
||||
endchoice
|
||||
|
||||
config ROOT_DEV
|
||||
int "ROOT_DEV"
|
||||
help
|
||||
Environment variable rootdev is set to this value if env. var. firstboot
|
||||
does not exist. Otherwise rootdev is set to the MMC boot device. rootdev
|
||||
determines (together with env. var. bootpart) where the OS (linux) is
|
||||
booted from.
|
||||
|
||||
config BOOT_PART
|
||||
int "BOOT_PART"
|
||||
help
|
||||
Environment variable bootpart is set to this value. bootpart determines
|
||||
(together with env. var. rootdev) where the OS (linux) is booted from.
|
||||
|
||||
config ROOT_PART
|
||||
int "ROOT_PART"
|
||||
help
|
||||
Environment variable rootpart is set to this value.
|
||||
|
||||
source "board/friendlyarm/nanopi2/Kconfig"
|
12
board/friendlyarm/nanopi2/Kconfig
Normal file
12
board/friendlyarm/nanopi2/Kconfig
Normal file
|
@ -0,0 +1,12 @@
|
|||
if TARGET_NANOPI2
|
||||
|
||||
config SYS_BOARD
|
||||
default "nanopi2"
|
||||
|
||||
config SYS_VENDOR
|
||||
default "friendlyarm"
|
||||
|
||||
config SYS_CONFIG_NAME
|
||||
default "s5p4418_nanopi2"
|
||||
|
||||
endif
|
7
board/friendlyarm/nanopi2/MAINTAINERS
Normal file
7
board/friendlyarm/nanopi2/MAINTAINERS
Normal file
|
@ -0,0 +1,7 @@
|
|||
NANOPI2 BOARD
|
||||
NANOPC-T2 BOARD
|
||||
M: Stefan Bosch <stefan_b@posteo.net>
|
||||
S: Maintained
|
||||
F: board/s5p4418/nanopi2/
|
||||
F: include/configs/s5p4418_nanopi2.h
|
||||
F: configs/s5p4418_nanopi2_defconfig
|
7
board/friendlyarm/nanopi2/Makefile
Normal file
7
board/friendlyarm/nanopi2/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2016 Nexell
|
||||
# Hyunseok, Jung <hsjung@nexell.co.kr>
|
||||
|
||||
obj-y := board.o hwrev.o lcds.o
|
||||
obj-$(CONFIG_S5P4418_ONEWIRE) += onewire.o
|
575
board/friendlyarm/nanopi2/board.c
Normal file
575
board/friendlyarm/nanopi2/board.c
Normal file
|
@ -0,0 +1,575 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
|
||||
* (http://www.friendlyarm.com)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <command.h>
|
||||
#include <fdt_support.h>
|
||||
#include <log.h>
|
||||
#ifdef CONFIG_PWM_NX
|
||||
#include <pwm.h>
|
||||
#endif
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/nexell.h>
|
||||
#include <asm/arch/nx_gpio.h>
|
||||
#include <asm/arch/display.h>
|
||||
#include <asm/arch/display_dev.h>
|
||||
|
||||
#include <u-boot/md5.h>
|
||||
|
||||
#include <linux/stringify.h>
|
||||
|
||||
#include "hwrev.h"
|
||||
#include "onewire.h"
|
||||
#include "nxp-fb.h"
|
||||
|
||||
#include <env_internal.h> /* for env_save() */
|
||||
#include <asm/mach-types.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
enum gpio_group {
|
||||
gpio_a, gpio_b, gpio_c, gpio_d, gpio_e,
|
||||
};
|
||||
|
||||
#ifdef CONFIG_PWM_NX
|
||||
struct pwm_device {
|
||||
int grp;
|
||||
int bit;
|
||||
int io_fn;
|
||||
};
|
||||
|
||||
static inline void bd_pwm_config_gpio(int ch)
|
||||
{
|
||||
struct pwm_device pwm_dev[] = {
|
||||
[0] = { .grp = gpio_d, .bit = 1, .io_fn = 0 },
|
||||
[1] = { .grp = gpio_c, .bit = 13, .io_fn = 1 },
|
||||
[2] = { .grp = gpio_c, .bit = 14, .io_fn = 1 },
|
||||
[3] = { .grp = gpio_d, .bit = 0, .io_fn = 0 },
|
||||
};
|
||||
|
||||
int gp = pwm_dev[ch].grp;
|
||||
int io = pwm_dev[ch].bit;
|
||||
|
||||
/* pwm backlight OFF: HIGH, ON: LOW */
|
||||
nx_gpio_set_pad_function(gp, io, pwm_dev[ch].io_fn);
|
||||
nx_gpio_set_output_value(gp, io, 1);
|
||||
nx_gpio_set_output_enable(gp, io, 1);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bd_backlight_off(void)
|
||||
{
|
||||
#ifdef CONFIG_S5P4418_ONEWIRE
|
||||
onewire_set_backlight(0);
|
||||
|
||||
#elif defined(BACKLIGHT_CH)
|
||||
bd_pwm_config_gpio(BACKLIGHT_CH);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void bd_backlight_on(void)
|
||||
{
|
||||
#ifdef CONFIG_S5P4418_ONEWIRE
|
||||
onewire_set_backlight(127);
|
||||
|
||||
#elif defined(BACKLIGHT_CH)
|
||||
/* pwm backlight ON: HIGH, ON: LOW */
|
||||
pwm_init(BACKLIGHT_CH,
|
||||
BACKLIGHT_DIV, BACKLIGHT_INV);
|
||||
pwm_config(BACKLIGHT_CH,
|
||||
TO_DUTY_NS(BACKLIGHT_DUTY, BACKLIGHT_HZ),
|
||||
TO_PERIOD_NS(BACKLIGHT_HZ));
|
||||
#endif
|
||||
}
|
||||
|
||||
static void bd_lcd_config_gpio(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 28; i++) {
|
||||
nx_gpio_set_pad_function(gpio_a, i, 1);
|
||||
nx_gpio_set_drive_strength(gpio_a, i, 0);
|
||||
nx_gpio_set_pull_mode(gpio_a, i, 2);
|
||||
}
|
||||
|
||||
nx_gpio_set_drive_strength(gpio_a, 0, 1);
|
||||
}
|
||||
|
||||
/* DEFAULT mmc dev for eMMC boot (dwmmc.2) */
|
||||
static int mmc_boot_dev;
|
||||
|
||||
int board_mmc_bootdev(void)
|
||||
{
|
||||
return mmc_boot_dev;
|
||||
}
|
||||
|
||||
/* call from common/env_mmc.c */
|
||||
int mmc_get_env_dev(void)
|
||||
{
|
||||
return mmc_boot_dev;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_DISPLAY_BOARDINFO
|
||||
int checkboard(void)
|
||||
{
|
||||
printf("Board: %s\n", get_board_name());
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
int nx_display_fixup_dp(struct nx_display_dev *dp)
|
||||
{
|
||||
struct nxp_lcd *lcd = bd_get_lcd();
|
||||
enum lcd_format fmt = bd_get_lcd_format();
|
||||
struct nxp_lcd_timing *timing = &lcd->timing;
|
||||
struct dp_sync_info *sync = &dp->sync;
|
||||
struct dp_plane_info *plane = &dp->planes[0];
|
||||
int i;
|
||||
u32 clk = 800000000;
|
||||
u32 div;
|
||||
|
||||
sync->h_active_len = lcd->width;
|
||||
sync->h_sync_width = timing->h_sw;
|
||||
sync->h_back_porch = timing->h_bp;
|
||||
sync->h_front_porch = timing->h_fp;
|
||||
sync->h_sync_invert = !lcd->polarity.inv_hsync;
|
||||
|
||||
sync->v_active_len = lcd->height;
|
||||
sync->v_sync_width = timing->v_sw;
|
||||
sync->v_back_porch = timing->v_bp;
|
||||
sync->v_front_porch = timing->v_fp;
|
||||
sync->v_sync_invert = !lcd->polarity.inv_vsync;
|
||||
|
||||
/* calculates pixel clock */
|
||||
div = timing->h_sw + timing->h_bp + timing->h_fp + lcd->width;
|
||||
div *= timing->v_sw + timing->v_bp + timing->v_fp + lcd->height;
|
||||
div *= lcd->freq ? : 60;
|
||||
clk /= div;
|
||||
|
||||
dp->ctrl.clk_div_lv0 = clk;
|
||||
dp->ctrl.clk_inv_lv0 = lcd->polarity.rise_vclk;
|
||||
|
||||
dp->top.screen_width = lcd->width;
|
||||
dp->top.screen_height = lcd->height;
|
||||
|
||||
for (i = 0; i < dp->top.plane_num; i++, plane++) {
|
||||
if (plane->enable) {
|
||||
plane->width = lcd->width;
|
||||
plane->height = lcd->height;
|
||||
}
|
||||
}
|
||||
|
||||
/* initialize display device type */
|
||||
if (fmt == LCD_RGB) {
|
||||
dp->dev_type = DP_DEVICE_RGBLCD;
|
||||
|
||||
} else if (fmt == LCD_HDMI) {
|
||||
struct dp_hdmi_dev *dev = (struct dp_hdmi_dev *)dp->device;
|
||||
|
||||
dp->dev_type = DP_DEVICE_HDMI;
|
||||
if (lcd->width == 1920 && lcd->height == 1080)
|
||||
dev->preset = 1;
|
||||
else
|
||||
dev->preset = 0;
|
||||
|
||||
} else {
|
||||
struct dp_lvds_dev *dev = (struct dp_lvds_dev *)dp->device;
|
||||
|
||||
dp->dev_type = DP_DEVICE_LVDS;
|
||||
dev->lvds_format = (fmt & 0x3);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* initialize board status.
|
||||
*/
|
||||
|
||||
#define MMC_BOOT_CH0 (0)
|
||||
#define MMC_BOOT_CH1 (1 << 3)
|
||||
#define MMC_BOOT_CH2 (1 << 19)
|
||||
|
||||
static void bd_bootdev_init(void)
|
||||
{
|
||||
unsigned int rst = readl(PHY_BASEADDR_CLKPWR + SYSRSTCONFIG);
|
||||
|
||||
rst &= (1 << 19) | (1 << 3);
|
||||
if (rst == MMC_BOOT_CH0) {
|
||||
/* mmc dev 1 for SD boot */
|
||||
mmc_boot_dev = 1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef CONFIG_S5P4418_ONEWIRE
|
||||
static void bd_onewire_init(void)
|
||||
{
|
||||
unsigned char lcd;
|
||||
unsigned short fw_ver;
|
||||
|
||||
onewire_init();
|
||||
onewire_get_info(&lcd, &fw_ver);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void bd_lcd_init(void)
|
||||
{
|
||||
struct nxp_lcd *cfg;
|
||||
int id = -1;
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_S5P4418_ONEWIRE
|
||||
id = onewire_get_lcd_id();
|
||||
/* -1: onwire probe failed
|
||||
* 0: bad
|
||||
* >0: identified
|
||||
*/
|
||||
#endif
|
||||
ret = bd_setup_lcd_by_id(id);
|
||||
if (id <= 0 || ret != id) {
|
||||
printf("Panel: N/A (%d)\n", id);
|
||||
bd_setup_lcd_by_name("HDMI720P60");
|
||||
|
||||
} else {
|
||||
printf("Panel: %s\n", bd_get_lcd_name());
|
||||
|
||||
cfg = bd_get_lcd();
|
||||
if (cfg->gpio_init)
|
||||
cfg->gpio_init();
|
||||
}
|
||||
}
|
||||
|
||||
static int mac_read_from_generic_eeprom(u8 *addr)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void make_ether_addr(u8 *addr)
|
||||
{
|
||||
u32 hash[20];
|
||||
|
||||
#define ETHER_MAC_TAG "ethmac"
|
||||
memset(hash, 0, sizeof(hash));
|
||||
memcpy(hash + 12, ETHER_MAC_TAG, sizeof(ETHER_MAC_TAG));
|
||||
|
||||
hash[4] = readl(PHY_BASEADDR_ECID + 0x00);
|
||||
hash[5] = readl(PHY_BASEADDR_ECID + 0x04);
|
||||
hash[6] = readl(PHY_BASEADDR_ECID + 0x08);
|
||||
hash[7] = readl(PHY_BASEADDR_ECID + 0x0c);
|
||||
|
||||
md5((unsigned char *)&hash[4], 64, (unsigned char *)hash);
|
||||
|
||||
hash[0] ^= hash[2];
|
||||
hash[1] ^= hash[3];
|
||||
|
||||
memcpy(addr, (char *)hash, 6);
|
||||
addr[0] &= 0xfe; /* clear multicast bit */
|
||||
addr[0] |= 0x02;
|
||||
}
|
||||
|
||||
static void set_ether_addr(void)
|
||||
{
|
||||
unsigned char mac[6];
|
||||
char ethaddr[20];
|
||||
int ret;
|
||||
|
||||
if (env_get("ethaddr"))
|
||||
return;
|
||||
|
||||
ret = mac_read_from_generic_eeprom(mac);
|
||||
if (ret < 0)
|
||||
make_ether_addr(mac);
|
||||
|
||||
sprintf(ethaddr, "%02x:%02x:%02x:%02x:%02x:%02x",
|
||||
mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
|
||||
if (!ret)
|
||||
printf("MAC: [%s]\n", ethaddr);
|
||||
|
||||
env_set("ethaddr", ethaddr);
|
||||
}
|
||||
|
||||
#ifdef CONFIG_REVISION_TAG
|
||||
static void set_board_rev(void)
|
||||
{
|
||||
char info[64] = {0, };
|
||||
|
||||
snprintf(info, ARRAY_SIZE(info), "%02x", get_board_rev());
|
||||
env_set("board_rev", info);
|
||||
}
|
||||
#endif
|
||||
|
||||
static void set_dtb_name(void)
|
||||
{
|
||||
char info[64] = {0, };
|
||||
|
||||
snprintf(info, ARRAY_SIZE(info),
|
||||
"s5p4418-nanopi2-rev%02x.dtb", get_board_rev());
|
||||
env_set("dtb_name", info);
|
||||
}
|
||||
|
||||
static void bd_update_env(void)
|
||||
{
|
||||
char *lcdtype = env_get("lcdtype");
|
||||
char *lcddpi = env_get("lcddpi");
|
||||
char *bootargs = env_get("bootargs");
|
||||
const char *name;
|
||||
char *p = NULL;
|
||||
int rootdev = board_mmc_bootdev();
|
||||
int need_save = 0;
|
||||
|
||||
#define CMDLINE_LCD " lcd="
|
||||
char cmdline[CONFIG_SYS_CBSIZE];
|
||||
int n = 1;
|
||||
|
||||
if (rootdev != CONFIG_ROOT_DEV && !env_get("firstboot")) {
|
||||
env_set_ulong("rootdev", rootdev);
|
||||
env_set("firstboot", "0");
|
||||
need_save = 1;
|
||||
}
|
||||
|
||||
if (lcdtype) {
|
||||
/* Setup again as user specified LCD in env */
|
||||
bd_setup_lcd_by_name(lcdtype);
|
||||
}
|
||||
|
||||
name = bd_get_lcd_name();
|
||||
|
||||
if (bootargs)
|
||||
n = strlen(bootargs); /* isn't 0 for NULL */
|
||||
else
|
||||
cmdline[0] = '\0';
|
||||
|
||||
if ((n + strlen(name) + sizeof(CMDLINE_LCD)) > sizeof(cmdline)) {
|
||||
printf("Error: `bootargs' is too large (%d)\n", n);
|
||||
goto __exit;
|
||||
}
|
||||
|
||||
if (bootargs) {
|
||||
p = strstr(bootargs, CMDLINE_LCD);
|
||||
if (p) {
|
||||
n = (p - bootargs);
|
||||
p += strlen(CMDLINE_LCD);
|
||||
}
|
||||
strncpy(cmdline, bootargs, n);
|
||||
}
|
||||
|
||||
/* add `lcd=NAME,NUMdpi' */
|
||||
strncpy(cmdline + n, CMDLINE_LCD, strlen(CMDLINE_LCD));
|
||||
n += strlen(CMDLINE_LCD);
|
||||
|
||||
strcpy(cmdline + n, name);
|
||||
n += strlen(name);
|
||||
|
||||
if (lcddpi) {
|
||||
n += sprintf(cmdline + n, ",%sdpi", lcddpi);
|
||||
} else {
|
||||
int dpi = bd_get_lcd_density();
|
||||
|
||||
if (dpi > 0 && dpi < 600)
|
||||
n += sprintf(cmdline + n, ",%ddpi", dpi);
|
||||
}
|
||||
|
||||
/* copy remaining of bootargs */
|
||||
if (p) {
|
||||
p = strstr(p, " ");
|
||||
if (p) {
|
||||
strcpy(cmdline + n, p);
|
||||
n += strlen(p);
|
||||
}
|
||||
}
|
||||
|
||||
/* append `bootdev=2' */
|
||||
#define CMDLINE_BDEV " bootdev="
|
||||
if (rootdev > 0 && !strstr(cmdline, CMDLINE_BDEV))
|
||||
n += sprintf(cmdline + n, "%s2", CMDLINE_BDEV);
|
||||
|
||||
/* finally, let's update uboot env & save it */
|
||||
if (bootargs && strncmp(cmdline, bootargs, sizeof(cmdline))) {
|
||||
env_set("bootargs", cmdline);
|
||||
need_save = 1;
|
||||
}
|
||||
|
||||
__exit:
|
||||
if (need_save)
|
||||
env_save();
|
||||
}
|
||||
|
||||
/* --------------------------------------------------------------------------
|
||||
* call from u-boot
|
||||
*/
|
||||
|
||||
int board_early_init_f(void)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
int board_init(void)
|
||||
{
|
||||
bd_hwrev_init();
|
||||
bd_base_rev_init();
|
||||
|
||||
bd_bootdev_init();
|
||||
#ifdef CONFIG_S5P4418_ONEWIRE
|
||||
bd_onewire_init();
|
||||
#endif
|
||||
|
||||
bd_backlight_off();
|
||||
|
||||
bd_lcd_config_gpio();
|
||||
bd_lcd_init();
|
||||
|
||||
if (IS_ENABLED(CONFIG_SILENT_CONSOLE))
|
||||
gd->flags |= GD_FLG_SILENT;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_BOARD_LATE_INIT
|
||||
int board_late_init(void)
|
||||
{
|
||||
bd_update_env();
|
||||
|
||||
#ifdef CONFIG_REVISION_TAG
|
||||
set_board_rev();
|
||||
#endif
|
||||
set_dtb_name();
|
||||
|
||||
set_ether_addr();
|
||||
|
||||
if (IS_ENABLED(CONFIG_SILENT_CONSOLE))
|
||||
gd->flags &= ~GD_FLG_SILENT;
|
||||
|
||||
bd_backlight_on();
|
||||
printf("\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef CONFIG_SPLASH_SOURCE
|
||||
#include <splash.h>
|
||||
static struct splash_location splash_locations[] = {
|
||||
{
|
||||
.name = "mmc_fs",
|
||||
.storage = SPLASH_STORAGE_MMC,
|
||||
.flags = SPLASH_STORAGE_FS,
|
||||
.devpart = __stringify(CONFIG_ROOT_DEV) ":"
|
||||
__stringify(CONFIG_BOOT_PART),
|
||||
},
|
||||
};
|
||||
|
||||
int splash_screen_prepare(void)
|
||||
{
|
||||
int err;
|
||||
char *env_cmd = env_get("load_splash");
|
||||
|
||||
debug("%s()\n", __func__);
|
||||
|
||||
if (env_cmd) {
|
||||
err = run_command(env_cmd, 0);
|
||||
|
||||
} else {
|
||||
char devpart[64] = { 0, };
|
||||
int bootpart = env_get_ulong("bootpart", 0, CONFIG_BOOT_PART);
|
||||
int rootdev;
|
||||
|
||||
if (env_get("firstboot"))
|
||||
rootdev = env_get_ulong("rootdev", 0, CONFIG_ROOT_DEV);
|
||||
else
|
||||
rootdev = board_mmc_bootdev();
|
||||
|
||||
snprintf(devpart, ARRAY_SIZE(devpart), "%d:%d", rootdev,
|
||||
bootpart);
|
||||
splash_locations[0].devpart = devpart;
|
||||
|
||||
err = splash_source_load(splash_locations,
|
||||
ARRAY_SIZE(splash_locations));
|
||||
}
|
||||
|
||||
if (!err) {
|
||||
char addr[64];
|
||||
|
||||
sprintf(addr, "0x%lx", gd->fb_base);
|
||||
env_set("fb_addr", addr);
|
||||
}
|
||||
|
||||
return err;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* u-boot dram initialize */
|
||||
int dram_init(void)
|
||||
{
|
||||
gd->ram_size = CONFIG_SYS_SDRAM_SIZE;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* u-boot dram board specific */
|
||||
int dram_init_banksize(void)
|
||||
{
|
||||
#define SCR_USER_SIG6_READ (SCR_ALIVE_BASE + 0x0F0)
|
||||
unsigned int reg_val = readl(SCR_USER_SIG6_READ);
|
||||
|
||||
/* set global data memory */
|
||||
gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x00000100;
|
||||
|
||||
gd->bd->bi_dram[0].start = CONFIG_SYS_SDRAM_BASE;
|
||||
gd->bd->bi_dram[0].size = CONFIG_SYS_SDRAM_SIZE;
|
||||
|
||||
/* Number of Row: 14 bits */
|
||||
if ((reg_val >> 28) == 14)
|
||||
gd->bd->bi_dram[0].size -= 0x20000000;
|
||||
|
||||
/* Number of Memory Chips */
|
||||
if ((reg_val & 0x3) > 1) {
|
||||
gd->bd->bi_dram[1].start = 0x80000000;
|
||||
gd->bd->bi_dram[1].size = 0x40000000;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(CONFIG_OF_BOARD_SETUP)
|
||||
int ft_board_setup(void *blob, struct bd_info *bd)
|
||||
{
|
||||
int nodeoff;
|
||||
unsigned int rootdev;
|
||||
unsigned int fb_addr;
|
||||
|
||||
if (board_mmc_bootdev() > 0) {
|
||||
rootdev = fdt_getprop_u32_default(blob, "/board", "sdidx", 2);
|
||||
if (rootdev) {
|
||||
/* find or create "/chosen" node. */
|
||||
nodeoff = fdt_find_or_add_subnode(blob, 0, "chosen");
|
||||
if (nodeoff >= 0)
|
||||
fdt_setprop_u32(blob, nodeoff, "linux,rootdev",
|
||||
rootdev);
|
||||
}
|
||||
}
|
||||
|
||||
fb_addr = env_get_ulong("fb_addr", 0, 0);
|
||||
if (fb_addr) {
|
||||
nodeoff = fdt_path_offset(blob, "/reserved-memory");
|
||||
if (nodeoff < 0)
|
||||
return nodeoff;
|
||||
|
||||
nodeoff = fdt_add_subnode(blob, nodeoff, "display_reserved");
|
||||
if (nodeoff >= 0) {
|
||||
fdt32_t cells[2];
|
||||
|
||||
cells[0] = cpu_to_fdt32(fb_addr);
|
||||
cells[1] = cpu_to_fdt32(0x800000);
|
||||
|
||||
fdt_setprop(blob, nodeoff, "reg", cells,
|
||||
sizeof(cells[0]) * 2);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
108
board/friendlyarm/nanopi2/hwrev.c
Normal file
108
board/friendlyarm/nanopi2/hwrev.c
Normal file
|
@ -0,0 +1,108 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
|
||||
* (http://www.friendlyarm.com)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <i2c.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/nexell.h>
|
||||
#include <asm/arch/nx_gpio.h>
|
||||
|
||||
/* Board revision list: <PCB3 | PCB2 | PCB1>
|
||||
* 0b000 - NanoPi 2
|
||||
* 0b001 - NanoPC-T2
|
||||
* 0b010 - NanoPi S2
|
||||
* 0b011 - Smart4418
|
||||
* 0b100 - NanoPi Fire 2A
|
||||
* 0b111 - NanoPi M2A
|
||||
*
|
||||
* Extented revision:
|
||||
* 0b001 - Smart4418-SDK
|
||||
*/
|
||||
#define __IO_GRP 2 /* GPIO_C */
|
||||
#define __IO_PCB1 26
|
||||
#define __IO_PCB2 27
|
||||
#define __IO_PCB3 25
|
||||
|
||||
static int pcb_rev = -1;
|
||||
static int base_rev;
|
||||
|
||||
static void bd_hwrev_config_gpio(void)
|
||||
{
|
||||
int gpios[3][2] = {
|
||||
{ __IO_PCB1, 1 },
|
||||
{ __IO_PCB2, 1 },
|
||||
{ __IO_PCB3, 1 },
|
||||
};
|
||||
int i;
|
||||
|
||||
/* gpio input mode, pull-down */
|
||||
for (i = 0; i < 3; i++) {
|
||||
nx_gpio_set_pad_function(__IO_GRP, gpios[i][0], gpios[i][1]);
|
||||
nx_gpio_set_output_enable(__IO_GRP, gpios[i][0], 0);
|
||||
nx_gpio_set_pull_mode(__IO_GRP, gpios[i][0], 0);
|
||||
}
|
||||
}
|
||||
|
||||
void bd_hwrev_init(void)
|
||||
{
|
||||
if (pcb_rev >= 0)
|
||||
return;
|
||||
|
||||
bd_hwrev_config_gpio();
|
||||
|
||||
pcb_rev = nx_gpio_get_input_value(__IO_GRP, __IO_PCB1);
|
||||
pcb_rev |= nx_gpio_get_input_value(__IO_GRP, __IO_PCB2) << 1;
|
||||
pcb_rev |= nx_gpio_get_input_value(__IO_GRP, __IO_PCB3) << 2;
|
||||
}
|
||||
|
||||
/* Get extended revision for SmartXX18 */
|
||||
void bd_base_rev_init(void)
|
||||
{
|
||||
struct udevice *dev;
|
||||
u8 val = 0;
|
||||
|
||||
if (pcb_rev != 0x3)
|
||||
return;
|
||||
|
||||
#define PCA9536_I2C_BUS 2
|
||||
#define PCA9636_I2C_ADDR 0x41
|
||||
if (i2c_get_chip_for_busnum
|
||||
(PCA9536_I2C_BUS, PCA9636_I2C_ADDR, 1, &dev))
|
||||
return;
|
||||
|
||||
if (!dm_i2c_read(dev, 0, &val, 1))
|
||||
base_rev = (val & 0xf);
|
||||
}
|
||||
|
||||
/* To override __weak symbols */
|
||||
u32 get_board_rev(void)
|
||||
{
|
||||
return (base_rev << 8) | pcb_rev;
|
||||
}
|
||||
|
||||
const char *get_board_name(void)
|
||||
{
|
||||
bd_hwrev_init();
|
||||
|
||||
switch (pcb_rev) {
|
||||
case 0:
|
||||
return "NanoPi 2";
|
||||
case 1:
|
||||
return "NanoPC-T2";
|
||||
case 2:
|
||||
return "NanoPi S2";
|
||||
case 3:
|
||||
return "Smart4418";
|
||||
case 4:
|
||||
return "NanoPi Fire 2A";
|
||||
case 7:
|
||||
return "NanoPi M2A";
|
||||
default:
|
||||
return "s5p4418-X";
|
||||
}
|
||||
}
|
15
board/friendlyarm/nanopi2/hwrev.h
Normal file
15
board/friendlyarm/nanopi2/hwrev.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
|
||||
* (http://www.friendlyarm.com)
|
||||
*/
|
||||
|
||||
#ifndef __BD_HW_REV_H__
|
||||
#define __BD_HW_REV_H__
|
||||
|
||||
extern void bd_hwrev_init(void);
|
||||
extern void bd_base_rev_init(void);
|
||||
extern u32 get_board_rev(void);
|
||||
extern const char *get_board_name(void);
|
||||
|
||||
#endif /* __BD_HW_REV_H__ */
|
697
board/friendlyarm/nanopi2/lcds.c
Normal file
697
board/friendlyarm/nanopi2/lcds.c
Normal file
|
@ -0,0 +1,697 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (c) 2017 FriendlyARM (www.arm9.net)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <fdtdec.h>
|
||||
#include <fdt_support.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#include <asm/arch/nexell.h>
|
||||
#include <asm/arch/display.h>
|
||||
#include <asm/arch/nx_gpio.h>
|
||||
|
||||
#include "nxp-fb.h"
|
||||
|
||||
/*
|
||||
* param @module_index for nx_gpio APIs and will be removed
|
||||
* after support pinctrl
|
||||
*/
|
||||
#ifndef PAD_GPIO_A
|
||||
#define PAD_GPIO_A 0
|
||||
#endif
|
||||
|
||||
static inline void common_gpio_init(void)
|
||||
{
|
||||
/* PVCLK */
|
||||
nx_gpio_set_fast_slew(PAD_GPIO_A, 0, 1);
|
||||
}
|
||||
|
||||
static void s70_gpio_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
/* PVCLK */
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, 0, 1);
|
||||
|
||||
/* RGB24 */
|
||||
for (i = 1; i < 25; i++)
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, i, 2);
|
||||
|
||||
/* HS/VS/DE */
|
||||
for (; i < 28; i++)
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
|
||||
}
|
||||
|
||||
static void s702_gpio_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
common_gpio_init();
|
||||
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, 0, 2);
|
||||
|
||||
for (i = 1; i < 25; i++)
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, i, 0);
|
||||
|
||||
for (; i < 28; i++)
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
|
||||
}
|
||||
|
||||
static void s430_gpio_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 28; i++)
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
|
||||
}
|
||||
|
||||
static void hd101_gpio_init(void)
|
||||
{
|
||||
int i;
|
||||
|
||||
common_gpio_init();
|
||||
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, 0, 2);
|
||||
|
||||
for (i = 1; i < 25; i++)
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, i, 1);
|
||||
|
||||
nx_gpio_set_drive_strength(PAD_GPIO_A, 27, 1);
|
||||
}
|
||||
|
||||
static void hd700_gpio_init(void)
|
||||
{
|
||||
hd101_gpio_init();
|
||||
}
|
||||
|
||||
/* NXP display configs for supported LCD */
|
||||
|
||||
static struct nxp_lcd wxga_hd700 = {
|
||||
.width = 800,
|
||||
.height = 1280,
|
||||
.p_width = 94,
|
||||
.p_height = 151,
|
||||
.bpp = 24,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 20,
|
||||
.h_bp = 20,
|
||||
.h_sw = 24,
|
||||
.v_fp = 4,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 4,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 8,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 0,
|
||||
.inv_vsync = 0,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = hd700_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd wvga_s70 = {
|
||||
.width = 800,
|
||||
.height = 480,
|
||||
.p_width = 155,
|
||||
.p_height = 93,
|
||||
.bpp = 24,
|
||||
.freq = 61,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 48,
|
||||
.h_bp = 36,
|
||||
.h_sw = 10,
|
||||
.v_fp = 22,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 15,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 8,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = s70_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd wvga_s702 = {
|
||||
.width = 800,
|
||||
.height = 480,
|
||||
.p_width = 155,
|
||||
.p_height = 93,
|
||||
.bpp = 24,
|
||||
.freq = 61,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 44,
|
||||
.h_bp = 26,
|
||||
.h_sw = 20,
|
||||
.v_fp = 22,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 15,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 8,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 1,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = s702_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd wvga_s70d = {
|
||||
.width = 800,
|
||||
.height = 480,
|
||||
.p_width = 155,
|
||||
.p_height = 93,
|
||||
.bpp = 24,
|
||||
.freq = 61,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 80,
|
||||
.h_bp = 78,
|
||||
.h_sw = 10,
|
||||
.v_fp = 22,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 24,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 8,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = s702_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd wvga_w50 = {
|
||||
.width = 800,
|
||||
.height = 480,
|
||||
.p_width = 108,
|
||||
.p_height = 64,
|
||||
.bpp = 24,
|
||||
.freq = 61,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 40,
|
||||
.h_bp = 40,
|
||||
.h_sw = 48,
|
||||
.v_fp = 20,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 20,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 12,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = s70_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd wvga_s430 = {
|
||||
.width = 480,
|
||||
.height = 800,
|
||||
.p_width = 108,
|
||||
.p_height = 64,
|
||||
.bpp = 24,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 64,
|
||||
.h_bp = 0,
|
||||
.h_sw = 16,
|
||||
.v_fp = 32,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 0,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 16,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 1,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = s430_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd wsvga_w101 = {
|
||||
.width = 1024,
|
||||
.height = 600,
|
||||
.p_width = 204,
|
||||
.p_height = 120,
|
||||
.bpp = 24,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 40,
|
||||
.h_bp = 40,
|
||||
.h_sw = 200,
|
||||
.v_fp = 8,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 8,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 16,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 1,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nxp_lcd wsvga_x710 = {
|
||||
.width = 1024,
|
||||
.height = 600,
|
||||
.p_width = 154,
|
||||
.p_height = 90,
|
||||
.bpp = 24,
|
||||
.freq = 61,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 84,
|
||||
.h_bp = 84,
|
||||
.h_sw = 88,
|
||||
.v_fp = 10,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 10,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 20,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = hd101_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd xga_a97 = {
|
||||
.width = 1024,
|
||||
.height = 768,
|
||||
.p_width = 200,
|
||||
.p_height = 150,
|
||||
.bpp = 24,
|
||||
.freq = 61,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 12,
|
||||
.h_bp = 12,
|
||||
.h_sw = 4,
|
||||
.v_fp = 8,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 8,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 4,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nxp_lcd xga_lq150 = {
|
||||
.width = 1024,
|
||||
.height = 768,
|
||||
.p_width = 304,
|
||||
.p_height = 228,
|
||||
.bpp = 24,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 12,
|
||||
.h_bp = 12,
|
||||
.h_sw = 40,
|
||||
.v_fp = 8,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 8,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 40,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nxp_lcd vga_l80 = {
|
||||
.width = 640,
|
||||
.height = 480,
|
||||
.p_width = 160,
|
||||
.p_height = 120,
|
||||
.bpp = 32,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 35,
|
||||
.h_bp = 53,
|
||||
.h_sw = 73,
|
||||
.v_fp = 3,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 29,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 6,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nxp_lcd wxga_bp101 = {
|
||||
.width = 1280,
|
||||
.height = 800,
|
||||
.p_width = 218,
|
||||
.p_height = 136,
|
||||
.bpp = 24,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 20,
|
||||
.h_bp = 20,
|
||||
.h_sw = 24,
|
||||
.v_fp = 4,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 4,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 8,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 1,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nxp_lcd wxga_hd101 = {
|
||||
.width = 1280,
|
||||
.height = 800,
|
||||
.p_width = 218,
|
||||
.p_height = 136,
|
||||
.bpp = 24,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 16,
|
||||
.h_bp = 16,
|
||||
.h_sw = 30,
|
||||
.v_fp = 8,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 8,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 12,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 1,
|
||||
.inv_hsync = 0,
|
||||
.inv_vsync = 0,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
.gpio_init = hd101_gpio_init,
|
||||
};
|
||||
|
||||
static struct nxp_lcd hvga_h43 = {
|
||||
.width = 480,
|
||||
.height = 272,
|
||||
.p_width = 96,
|
||||
.p_height = 54,
|
||||
.bpp = 32,
|
||||
.freq = 65,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 5,
|
||||
.h_bp = 40,
|
||||
.h_sw = 2,
|
||||
.v_fp = 8,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 8,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 2,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nxp_lcd hvga_p43 = {
|
||||
.width = 480,
|
||||
.height = 272,
|
||||
.p_width = 96,
|
||||
.p_height = 54,
|
||||
.bpp = 32,
|
||||
.freq = 65,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 5,
|
||||
.h_bp = 40,
|
||||
.h_sw = 2,
|
||||
.v_fp = 8,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 9,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 2,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 1,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct nxp_lcd qvga_w35 = {
|
||||
.width = 320,
|
||||
.height = 240,
|
||||
.p_width = 70,
|
||||
.p_height = 52,
|
||||
.bpp = 16,
|
||||
.freq = 65,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 4,
|
||||
.h_bp = 70,
|
||||
.h_sw = 4,
|
||||
.v_fp = 4,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 12,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 4,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 1,
|
||||
.inv_hsync = 0,
|
||||
.inv_vsync = 0,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
/* HDMI */
|
||||
static struct nxp_lcd hdmi_def = {
|
||||
.width = 1920,
|
||||
.height = 1080,
|
||||
.p_width = 480,
|
||||
.p_height = 320,
|
||||
.bpp = 24,
|
||||
.freq = 60,
|
||||
|
||||
.timing = {
|
||||
.h_fp = 12,
|
||||
.h_bp = 12,
|
||||
.h_sw = 4,
|
||||
.v_fp = 8,
|
||||
.v_fpe = 1,
|
||||
.v_bp = 8,
|
||||
.v_bpe = 1,
|
||||
.v_sw = 4,
|
||||
},
|
||||
.polarity = {
|
||||
.rise_vclk = 0,
|
||||
.inv_hsync = 1,
|
||||
.inv_vsync = 1,
|
||||
.inv_vden = 0,
|
||||
},
|
||||
};
|
||||
|
||||
static struct hdmi_config {
|
||||
char *name;
|
||||
int width;
|
||||
int height;
|
||||
} bd_hdmi_config[] = {
|
||||
{ "HDMI1080P60", 1920, 1080 },
|
||||
{ "HDMI1080I60", 1920, 1080 },
|
||||
{ "HDMI1080P30", 1920, 1080 },
|
||||
{ "HDMI1080P50", 1920, 1080 },
|
||||
{ "HDMI1080I50", 1920, 1080 },
|
||||
|
||||
{ "HDMI1080P60D", 960, 536 },
|
||||
{ "HDMI1080I60D", 960, 536 },
|
||||
{ "HDMI1080P30D", 960, 536 },
|
||||
{ "HDMI1080P50D", 960, 536 },
|
||||
{ "HDMI1080I50D", 960, 536 },
|
||||
|
||||
{ "HDMI720P60", 1280, 720 },
|
||||
{ "HDMI720P60D", 640, 360 },
|
||||
{ "HDMI720P50", 1280, 720 },
|
||||
{ "HDMI720P50D", 640, 360 },
|
||||
|
||||
{ "HDMI576P16X9", 720, 576 },
|
||||
{ "HDMI576P16X9D", 720, 576 },
|
||||
{ "HDMI576P4X3", 720, 576 },
|
||||
{ "HDMI576P4X3D", 720, 576 },
|
||||
|
||||
{ "HDMI480P16X9", 720, 480 },
|
||||
{ "HDMI480P16X9D", 720, 480 },
|
||||
{ "HDMI480P4X3", 720, 480 },
|
||||
{ "HDMI480P4X3D", 720, 480 },
|
||||
};
|
||||
|
||||
/* Try to guess LCD panel by kernel command line, or
|
||||
* using *HD101* as default
|
||||
*/
|
||||
static struct {
|
||||
int id;
|
||||
char *name;
|
||||
struct nxp_lcd *lcd;
|
||||
int dpi;
|
||||
int ctp;
|
||||
enum lcd_format fmt;
|
||||
} bd_lcd_config[] = {
|
||||
{ 25, "HD101", &wxga_hd101, 0, 1, LCD_RGB },
|
||||
{ 32, "HD101B", &wxga_hd101, 0, 1, LCD_RGB },
|
||||
{ 18, "HD700", &wxga_hd700, 213, 1, LCD_RGB },
|
||||
{ 30, "HD702", &wxga_hd700, 213, 1, LCD_RGB },
|
||||
{ 33, "H70", &wxga_hd700, 213, 0, LCD_VESA },
|
||||
{ 3, "S70", &wvga_s70, 128, 1, LCD_RGB },
|
||||
{ 36, "S701", &wvga_s70, 128, 1, LCD_RGB },
|
||||
{ 24, "S702", &wvga_s702, 128, 3, LCD_RGB },
|
||||
{ 26, "S70D", &wvga_s70d, 128, 0, LCD_RGB },
|
||||
{ 14, "H43", &hvga_h43, 0, 0, LCD_RGB },
|
||||
{ 19, "P43", &hvga_p43, 0, 0, LCD_RGB },
|
||||
{ 8, "W35", &qvga_w35, 0, 0, LCD_RGB },
|
||||
{ 28, "X710", &wsvga_x710, 0, 1, LCD_RGB },
|
||||
{ 31, "S430", &wvga_s430, 180, 1, LCD_RGB },
|
||||
{ 4, "W50", &wvga_w50, 0, 0, LCD_RGB },
|
||||
|
||||
/* TODO: Testing */
|
||||
{ 15, "W101", &wsvga_w101, 0, 1, LCD_RGB },
|
||||
{ 5, "L80", &vga_l80, 0, 1, LCD_RGB },
|
||||
{ -1, "A97", &xga_a97, 0, 0, LCD_RGB },
|
||||
{ -1, "LQ150", &xga_lq150, 0, 1, LCD_RGB },
|
||||
{ -1, "BP101", &wxga_bp101, 0, 1, LCD_RGB },
|
||||
/* Pls keep it at last */
|
||||
{ 128, "HDMI", &hdmi_def, 0, 0, LCD_HDMI },
|
||||
};
|
||||
|
||||
static int lcd_idx;
|
||||
|
||||
int bd_setup_lcd_by_id(int id)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bd_lcd_config); i++) {
|
||||
if (bd_lcd_config[i].id == id) {
|
||||
lcd_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (i >= ARRAY_SIZE(bd_lcd_config)) {
|
||||
/* NOT found */
|
||||
return -19;
|
||||
}
|
||||
|
||||
return bd_lcd_config[i].id;
|
||||
}
|
||||
|
||||
int bd_setup_lcd_by_name(char *str)
|
||||
{
|
||||
char *delim;
|
||||
int i;
|
||||
|
||||
delim = strchr(str, ',');
|
||||
if (delim)
|
||||
*delim++ = '\0';
|
||||
|
||||
if (!strncasecmp("HDMI", str, 4)) {
|
||||
struct hdmi_config *cfg = &bd_hdmi_config[0];
|
||||
struct nxp_lcd *lcd;
|
||||
|
||||
lcd_idx = ARRAY_SIZE(bd_lcd_config) - 1;
|
||||
lcd = bd_lcd_config[lcd_idx].lcd;
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bd_hdmi_config); i++, cfg++) {
|
||||
if (!strcasecmp(cfg->name, str)) {
|
||||
lcd->width = cfg->width;
|
||||
lcd->height = cfg->height;
|
||||
bd_lcd_config[lcd_idx].name = cfg->name;
|
||||
goto __ret;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (i = 0; i < ARRAY_SIZE(bd_lcd_config); i++) {
|
||||
if (!strcasecmp(bd_lcd_config[i].name, str)) {
|
||||
lcd_idx = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
__ret:
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct nxp_lcd *bd_get_lcd(void)
|
||||
{
|
||||
return bd_lcd_config[lcd_idx].lcd;
|
||||
}
|
||||
|
||||
const char *bd_get_lcd_name(void)
|
||||
{
|
||||
return bd_lcd_config[lcd_idx].name;
|
||||
}
|
||||
|
||||
enum lcd_format bd_get_lcd_format(void)
|
||||
{
|
||||
return bd_lcd_config[lcd_idx].fmt;
|
||||
}
|
||||
|
||||
int bd_get_lcd_density(void)
|
||||
{
|
||||
return bd_lcd_config[lcd_idx].dpi;
|
||||
}
|
||||
|
||||
#if CONFIG_IS_ENABLED(OF_CONTROL)
|
||||
int bd_fixup_lcd_fdt(void *blob, struct nxp_lcd *lcd)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
94
board/friendlyarm/nanopi2/nxp-fb.h
Normal file
94
board/friendlyarm/nanopi2/nxp-fb.h
Normal file
|
@ -0,0 +1,94 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Copyright (c) 2017 FriendlyARM (www.arm9.net)
|
||||
*
|
||||
* Copyright (c) 2010 Samsung Electronics Co., Ltd.
|
||||
* http://www.samsung.com/
|
||||
*
|
||||
* Header file for NXP Display Driver
|
||||
*/
|
||||
|
||||
#ifndef __MACH_NXP_FB_H__
|
||||
#define __MACH_NXP_FB_H__
|
||||
|
||||
/*
|
||||
* struct nxp_lcd_polarity
|
||||
* @rise_vclk: if 1, video data is fetched at rising edge
|
||||
* @inv_hsync: if HSYNC polarity is inversed
|
||||
* @inv_vsync: if VSYNC polarity is inversed
|
||||
* @inv_vden: if VDEN polarity is inversed
|
||||
*/
|
||||
struct nxp_lcd_polarity {
|
||||
int rise_vclk;
|
||||
int inv_hsync;
|
||||
int inv_vsync;
|
||||
int inv_vden;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct nxp_lcd_timing
|
||||
* @h_fp: horizontal front porch
|
||||
* @h_bp: horizontal back porch
|
||||
* @h_sw: horizontal sync width
|
||||
* @v_fp: vertical front porch
|
||||
* @v_fpe: vertical front porch for even field
|
||||
* @v_bp: vertical back porch
|
||||
* @v_bpe: vertical back porch for even field
|
||||
*/
|
||||
struct nxp_lcd_timing {
|
||||
int h_fp;
|
||||
int h_bp;
|
||||
int h_sw;
|
||||
int v_fp;
|
||||
int v_fpe;
|
||||
int v_bp;
|
||||
int v_bpe;
|
||||
int v_sw;
|
||||
};
|
||||
|
||||
/*
|
||||
* struct nxp_lcd
|
||||
* @width: horizontal resolution
|
||||
* @height: vertical resolution
|
||||
* @p_width: width of lcd in mm
|
||||
* @p_height: height of lcd in mm
|
||||
* @bpp: bits per pixel
|
||||
* @freq: vframe frequency
|
||||
* @timing: timing values
|
||||
* @polarity: polarity settings
|
||||
* @gpio_init: pointer to GPIO init function
|
||||
*
|
||||
*/
|
||||
struct nxp_lcd {
|
||||
int width;
|
||||
int height;
|
||||
int p_width;
|
||||
int p_height;
|
||||
int bpp;
|
||||
int freq;
|
||||
struct nxp_lcd_timing timing;
|
||||
struct nxp_lcd_polarity polarity;
|
||||
void (*gpio_init)(void);
|
||||
};
|
||||
|
||||
/**
|
||||
* Public interfaces
|
||||
*/
|
||||
enum lcd_format {
|
||||
LCD_VESA = 0,
|
||||
LCD_JEIDA = 1,
|
||||
LCD_LOC = 2,
|
||||
|
||||
LCD_RGB = 4,
|
||||
LCD_HDMI = 5,
|
||||
};
|
||||
|
||||
extern int bd_setup_lcd_by_id(int id);
|
||||
extern int bd_setup_lcd_by_name(char *name);
|
||||
extern struct nxp_lcd *bd_get_lcd(void);
|
||||
extern const char *bd_get_lcd_name(void);
|
||||
extern int bd_get_lcd_density(void);
|
||||
extern enum lcd_format bd_get_lcd_format(void);
|
||||
extern int bd_fixup_lcd_fdt(void *blob, struct nxp_lcd *cfg);
|
||||
|
||||
#endif /* __MACH_NXP_FB_H__ */
|
307
board/friendlyarm/nanopi2/onewire.c
Normal file
307
board/friendlyarm/nanopi2/onewire.c
Normal file
|
@ -0,0 +1,307 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
|
||||
* (http://www.friendlyarm.com)
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/arch/clk.h>
|
||||
#include <i2c.h>
|
||||
#include <pwm.h>
|
||||
|
||||
#include <irq_func.h>
|
||||
|
||||
#include <asm/arch/nexell.h>
|
||||
#include <asm/arch/nx_gpio.h>
|
||||
|
||||
#ifndef NSEC_PER_SEC
|
||||
#define NSEC_PER_SEC 1000000000L
|
||||
#endif
|
||||
|
||||
#define SAMPLE_BPS 9600
|
||||
#define SAMPLE_IN_US 101 /* (1000000 / BPS) */
|
||||
|
||||
#define REQ_INFO 0x60U
|
||||
#define REQ_BL 0x80U
|
||||
|
||||
#define BUS_I2C 0x18
|
||||
#define ONEWIRE_I2C_BUS 2
|
||||
#define ONEWIRE_I2C_ADDR 0x2f
|
||||
|
||||
static int bus_type = -1;
|
||||
static int lcd_id = -1;
|
||||
static unsigned short lcd_fwrev;
|
||||
static int current_brightness = -1;
|
||||
#ifdef CONFIG_DM_I2C
|
||||
static struct udevice *i2c_dev;
|
||||
#endif
|
||||
|
||||
/* debug */
|
||||
#if (0)
|
||||
#define DBGOUT(msg...) do { printf("onewire: " msg); } while (0)
|
||||
#else
|
||||
#define DBGOUT(msg...) do {} while (0)
|
||||
#endif
|
||||
|
||||
/* based on web page from http://lfh1986.blogspot.com */
|
||||
static unsigned char crc8_ow(unsigned int v, unsigned int len)
|
||||
{
|
||||
unsigned char crc = 0xACU;
|
||||
|
||||
while (len--) {
|
||||
if ((crc & 0x80U) != 0) {
|
||||
crc <<= 1;
|
||||
crc ^= 0x7U;
|
||||
} else {
|
||||
crc <<= 1;
|
||||
}
|
||||
if ((v & (1U << 31)) != 0)
|
||||
crc ^= 0x7U;
|
||||
v <<= 1;
|
||||
}
|
||||
return crc;
|
||||
}
|
||||
|
||||
/* GPIO helpers */
|
||||
#define __IO_GRP 2 /* GPIOC15 */
|
||||
#define __IO_IDX 15
|
||||
|
||||
static inline void set_pin_as_input(void)
|
||||
{
|
||||
nx_gpio_set_output_enable(__IO_GRP, __IO_IDX, 0);
|
||||
}
|
||||
|
||||
static inline void set_pin_as_output(void)
|
||||
{
|
||||
nx_gpio_set_output_enable(__IO_GRP, __IO_IDX, 1);
|
||||
}
|
||||
|
||||
static inline void set_pin_value(int v)
|
||||
{
|
||||
nx_gpio_set_output_value(__IO_GRP, __IO_IDX, !!v);
|
||||
}
|
||||
|
||||
static inline int get_pin_value(void)
|
||||
{
|
||||
return nx_gpio_get_input_value(__IO_GRP, __IO_IDX);
|
||||
}
|
||||
|
||||
/* Timer helpers */
|
||||
#define PWM_CH 3
|
||||
#define PWM_TCON (PHY_BASEADDR_PWM + 0x08)
|
||||
#define PWM_TCON_START (1 << 16)
|
||||
#define PWM_TINT_CSTAT (PHY_BASEADDR_PWM + 0x44)
|
||||
|
||||
static int onewire_init_timer(void)
|
||||
{
|
||||
int period_ns = NSEC_PER_SEC / SAMPLE_BPS;
|
||||
|
||||
/* range: 1080~1970 */
|
||||
period_ns -= 1525;
|
||||
|
||||
return pwm_config(PWM_CH, period_ns >> 1, period_ns);
|
||||
}
|
||||
|
||||
static void wait_one_tick(void)
|
||||
{
|
||||
unsigned int tcon;
|
||||
|
||||
tcon = readl(PWM_TCON);
|
||||
tcon |= PWM_TCON_START;
|
||||
writel(tcon, PWM_TCON);
|
||||
|
||||
while (1) {
|
||||
if (readl(PWM_TINT_CSTAT) & (1 << (5 + PWM_CH)))
|
||||
break;
|
||||
}
|
||||
|
||||
writel((1 << (5 + PWM_CH)), PWM_TINT_CSTAT);
|
||||
|
||||
tcon &= ~PWM_TCON_START;
|
||||
writel(tcon, PWM_TCON);
|
||||
}
|
||||
|
||||
/* Session handler */
|
||||
static int onewire_session(unsigned char req, unsigned char res[])
|
||||
{
|
||||
unsigned int Req;
|
||||
unsigned int *Res;
|
||||
int ints = disable_interrupts();
|
||||
int i;
|
||||
int ret;
|
||||
|
||||
Req = (req << 24) | (crc8_ow(req << 24, 8) << 16);
|
||||
Res = (unsigned int *)res;
|
||||
|
||||
set_pin_value(1);
|
||||
set_pin_as_output();
|
||||
for (i = 0; i < 60; i++)
|
||||
wait_one_tick();
|
||||
|
||||
set_pin_value(0);
|
||||
for (i = 0; i < 2; i++)
|
||||
wait_one_tick();
|
||||
|
||||
for (i = 0; i < 16; i++) {
|
||||
int v = !!(Req & (1U << 31));
|
||||
|
||||
Req <<= 1;
|
||||
set_pin_value(v);
|
||||
wait_one_tick();
|
||||
}
|
||||
|
||||
wait_one_tick();
|
||||
set_pin_as_input();
|
||||
wait_one_tick();
|
||||
for (i = 0; i < 32; i++) {
|
||||
(*Res) <<= 1;
|
||||
(*Res) |= get_pin_value();
|
||||
wait_one_tick();
|
||||
}
|
||||
set_pin_value(1);
|
||||
set_pin_as_output();
|
||||
|
||||
if (ints)
|
||||
enable_interrupts();
|
||||
|
||||
ret = crc8_ow(*Res, 24) == res[0];
|
||||
DBGOUT("req = %02X, res = %02X%02X%02X%02X, ret = %d\n",
|
||||
req, res[3], res[2], res[1], res[0], ret);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int onewire_i2c_do_request(unsigned char req, unsigned char *buf)
|
||||
{
|
||||
unsigned char tx[4];
|
||||
int ret;
|
||||
|
||||
tx[0] = req;
|
||||
tx[1] = crc8_ow(req << 24, 8);
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
if (dm_i2c_write(i2c_dev, 0, tx, 2))
|
||||
return -EIO;
|
||||
|
||||
if (!buf)
|
||||
return 0;
|
||||
|
||||
if (dm_i2c_read(i2c_dev, 0, buf, 4))
|
||||
return -EIO;
|
||||
#else
|
||||
if (i2c_write(ONEWIRE_I2C_ADDR, 0, 0, tx, 2))
|
||||
return -EIO;
|
||||
|
||||
if (!buf) /* NO READ */
|
||||
return 0;
|
||||
|
||||
if (i2c_read(ONEWIRE_I2C_ADDR, 0, 0, buf, 4))
|
||||
return -EIO;
|
||||
#endif
|
||||
|
||||
ret = crc8_ow((buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8), 24);
|
||||
DBGOUT("req = %02X, res = %02X%02X%02X%02X, ret = %02x\n",
|
||||
req, buf[0], buf[1], buf[2], buf[3], ret);
|
||||
|
||||
return (ret == buf[3]) ? 0 : -EIO;
|
||||
}
|
||||
|
||||
static void onewire_i2c_init(void)
|
||||
{
|
||||
unsigned char buf[4];
|
||||
int ret;
|
||||
|
||||
#ifdef CONFIG_DM_I2C
|
||||
ret = i2c_get_chip_for_busnum(ONEWIRE_I2C_BUS,
|
||||
ONEWIRE_I2C_ADDR, 0, &i2c_dev);
|
||||
#else
|
||||
i2c_init(CONFIG_SYS_I2C_SPEED, CONFIG_SYS_I2C_SLAVE);
|
||||
i2c_set_bus_num(ONEWIRE_I2C_BUS);
|
||||
|
||||
ret = i2c_probe(ONEWIRE_I2C_ADDR);
|
||||
#endif
|
||||
if (ret)
|
||||
return;
|
||||
|
||||
ret = onewire_i2c_do_request(REQ_INFO, buf);
|
||||
if (!ret) {
|
||||
lcd_id = buf[0];
|
||||
lcd_fwrev = buf[1] * 0x100 + buf[2];
|
||||
bus_type = BUS_I2C;
|
||||
}
|
||||
}
|
||||
|
||||
void onewire_init(void)
|
||||
{
|
||||
/* GPIO, Pull-off */
|
||||
nx_gpio_set_pad_function(__IO_GRP, __IO_IDX, 1);
|
||||
nx_gpio_set_pull_mode(__IO_GRP, __IO_IDX, 2);
|
||||
|
||||
onewire_init_timer();
|
||||
onewire_i2c_init();
|
||||
}
|
||||
|
||||
int onewire_get_info(unsigned char *lcd, unsigned short *fw_ver)
|
||||
{
|
||||
unsigned char res[4];
|
||||
int i;
|
||||
|
||||
if (bus_type == BUS_I2C && lcd_id > 0) {
|
||||
*lcd = lcd_id;
|
||||
*fw_ver = lcd_fwrev;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (onewire_session(REQ_INFO, res)) {
|
||||
*lcd = res[3];
|
||||
*fw_ver = res[2] * 0x100 + res[1];
|
||||
lcd_id = *lcd;
|
||||
DBGOUT("lcd = %d, fw_ver = %x\n", *lcd, *fw_ver);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
/* LCD unknown or not connected */
|
||||
*lcd = 0;
|
||||
*fw_ver = -1;
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
int onewire_get_lcd_id(void)
|
||||
{
|
||||
return lcd_id;
|
||||
}
|
||||
|
||||
int onewire_set_backlight(int brightness)
|
||||
{
|
||||
unsigned char res[4];
|
||||
int i;
|
||||
|
||||
if (brightness == current_brightness)
|
||||
return 0;
|
||||
|
||||
if (brightness > 127)
|
||||
brightness = 127;
|
||||
else if (brightness < 0)
|
||||
brightness = 0;
|
||||
|
||||
if (bus_type == BUS_I2C) {
|
||||
onewire_i2c_do_request((REQ_BL | brightness), NULL);
|
||||
current_brightness = brightness;
|
||||
return 0;
|
||||
}
|
||||
|
||||
for (i = 0; i < 3; i++) {
|
||||
if (onewire_session((REQ_BL | brightness), res)) {
|
||||
current_brightness = brightness;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
15
board/friendlyarm/nanopi2/onewire.h
Normal file
15
board/friendlyarm/nanopi2/onewire.h
Normal file
|
@ -0,0 +1,15 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Copyright (C) Guangzhou FriendlyARM Computer Tech. Co., Ltd.
|
||||
* (http://www.friendlyarm.com)
|
||||
*/
|
||||
|
||||
#ifndef __ONE_WIRE_H__
|
||||
#define __ONE_WIRE_H__
|
||||
|
||||
extern void onewire_init(void);
|
||||
extern int onewire_get_info(unsigned char *lcd, unsigned short *fw_ver);
|
||||
extern int onewire_get_lcd_id(void);
|
||||
extern int onewire_set_backlight(int brightness);
|
||||
|
||||
#endif /* __ONE_WIRE_H__ */
|
|
@ -5,3 +5,10 @@ S: Maintained
|
|||
F: board/mediatek/mt7623
|
||||
F: include/configs/mt7623.h
|
||||
F: configs/mt7623n_bpir2_defconfig
|
||||
|
||||
UNIELEC U7623
|
||||
M: Ryder Lee <ryder.lee@mediatek.com>
|
||||
M: David Woodhouse <dwmw2@infradead.org>
|
||||
S: Maintained
|
||||
F: arch/arm/dts/mt7623a-unielec-u7623-02-emmc.dts
|
||||
F: configs/mt7623a_unielec_u7623_02_defconfig
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <mmc.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
|
@ -15,10 +16,15 @@ int board_init(void)
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_MMC
|
||||
int mmc_get_boot_dev(void)
|
||||
{
|
||||
int g_mmc_devid = -1;
|
||||
char *uflag = (char *)0x81DFFFF0;
|
||||
|
||||
if (!find_mmc_device(1))
|
||||
return 0;
|
||||
|
||||
if (strncmp(uflag,"eMMC",4)==0) {
|
||||
g_mmc_devid = 0;
|
||||
printf("Boot From Emmc(id:%d)\n\n", g_mmc_devid);
|
||||
|
@ -33,3 +39,4 @@ int mmc_get_env_dev(void)
|
|||
{
|
||||
return mmc_get_boot_dev();
|
||||
}
|
||||
#endif
|
||||
|
|
54
configs/mt7623a_unielec_u7623_02_defconfig
Normal file
54
configs/mt7623a_unielec_u7623_02_defconfig
Normal file
|
@ -0,0 +1,54 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_SYS_THUMB_BUILD=y
|
||||
CONFIG_ARCH_MEDIATEK=y
|
||||
CONFIG_SYS_TEXT_BASE=0x81e00000
|
||||
CONFIG_SYS_MALLOC_F_LEN=0x4000
|
||||
CONFIG_ENV_SIZE=0x1000
|
||||
CONFIG_ENV_OFFSET=0x100000
|
||||
CONFIG_TARGET_MT7623=y
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_DISTRO_DEFAULTS=y
|
||||
CONFIG_FIT=y
|
||||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTDELAY=3
|
||||
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7623a-unielec-u7623-02-emmc.dtb"
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_SYS_PROMPT="U-Boot> "
|
||||
CONFIG_CMD_BOOTMENU=y
|
||||
# CONFIG_CMD_ELF is not set
|
||||
# CONFIG_CMD_XIMG is not set
|
||||
CONFIG_CMD_GPIO=y
|
||||
CONFIG_CMD_GPT=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_CMD_READ=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_DEFAULT_DEVICE_TREE="mt7623a-unielec-u7623-02-emmc"
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_SYS_RELOC_GD_ENV_ADDR=y
|
||||
CONFIG_NET_RANDOM_ETHADDR=y
|
||||
CONFIG_REGMAP=y
|
||||
CONFIG_SYSCON=y
|
||||
CONFIG_CLK=y
|
||||
CONFIG_DM_MMC=y
|
||||
# CONFIG_MMC_QUIRKS is not set
|
||||
CONFIG_SUPPORT_EMMC_BOOT=y
|
||||
CONFIG_MMC_HS400_SUPPORT=y
|
||||
CONFIG_MMC_MTK=y
|
||||
CONFIG_PHY_FIXED=y
|
||||
CONFIG_DM_ETH=y
|
||||
CONFIG_MEDIATEK_ETH=y
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_PINCONF=y
|
||||
CONFIG_PINCTRL_MT7623=y
|
||||
CONFIG_POWER_DOMAIN=y
|
||||
CONFIG_MTK_POWER_DOMAIN=y
|
||||
CONFIG_DM_SERIAL=y
|
||||
CONFIG_MTK_SERIAL=y
|
||||
CONFIG_SYSRESET=y
|
||||
CONFIG_SYSRESET_WATCHDOG=y
|
||||
CONFIG_TIMER=y
|
||||
CONFIG_MTK_TIMER=y
|
||||
CONFIG_WDT_MTK=y
|
||||
CONFIG_LZMA=y
|
|
@ -13,7 +13,7 @@ CONFIG_FIT=y
|
|||
CONFIG_FIT_VERBOSE=y
|
||||
CONFIG_BOOTDELAY=3
|
||||
CONFIG_SYS_CONSOLE_IS_IN_ENV=y
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2"
|
||||
CONFIG_DEFAULT_FDT_FILE="mt7623n-bananapi-bpi-r2.dtb"
|
||||
# CONFIG_DISPLAY_BOARDINFO is not set
|
||||
CONFIG_SYS_PROMPT="U-Boot> "
|
||||
CONFIG_CMD_BOOTMENU=y
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARM_SMCCC=y
|
||||
CONFIG_ARMV7_LPAE=y
|
||||
CONFIG_ARCH_QEMU=y
|
||||
CONFIG_ENV_SIZE=0x40000
|
||||
CONFIG_ENV_SECT_SIZE=0x40000
|
||||
|
@ -46,3 +47,4 @@ CONFIG_USB=y
|
|||
CONFIG_DM_USB=y
|
||||
CONFIG_USB_EHCI_HCD=y
|
||||
CONFIG_USB_EHCI_PCI=y
|
||||
# CONFIG_EFI_GRUB_ARM32_WORKAROUND is not set
|
||||
|
|
147
configs/s5p4418_nanopi2_defconfig
Normal file
147
configs/s5p4418_nanopi2_defconfig
Normal file
|
@ -0,0 +1,147 @@
|
|||
CONFIG_ARM=y
|
||||
CONFIG_ARCH_NEXELL=y
|
||||
CONFIG_ARCH_S5P4418=y
|
||||
CONFIG_TARGET_NANOPI2=y
|
||||
CONFIG_DEFAULT_DEVICE_TREE="s5p4418-nanopi2"
|
||||
CONFIG_FIT=y
|
||||
|
||||
CONFIG_SYS_MEMTEST_START=0x71000000
|
||||
CONFIG_SYS_MEMTEST_END=0xb0000000
|
||||
|
||||
CONFIG_CMD_MEMTEST=y
|
||||
# CONFIG_CMD_IMLS is not set
|
||||
# CONFIG_CMD_FLASH is not set
|
||||
CONFIG_CMD_I2C=y
|
||||
# CONFIG_CMD_FPGA is not set
|
||||
CONFIG_CMD_GPIO=y
|
||||
# CONFIG_CMD_SETEXPR is not set
|
||||
# CONFIG_CMD_NET is not set
|
||||
|
||||
# Default is CONFIG_NET=y, in this case:
|
||||
# Loading Environment from MMC... ## Warning: Unknown environment variable type 'm'
|
||||
# OK
|
||||
# CONFIG_CMD_NET=y must be set to avoid this Warning. But then:
|
||||
# Net: Net Initialization Skipped
|
||||
# No ethernet found.
|
||||
# If CONFIG_NET=n is set additionally warning at "make s5p4418_nanopi2_defconfig":
|
||||
# arch/../configs/s5p4418_nanopi2_defconfig:24:warning: override: reassigning to symbol CMD_NET
|
||||
#
|
||||
# --> CONFIG_NET=n set only
|
||||
CONFIG_NET=n
|
||||
|
||||
# CONFIG_CMD_NFS is not set
|
||||
CONFIG_CMD_FDISK=y
|
||||
CONFIG_CMD_EXT4_IMG_WRITE=y
|
||||
CONFIG_CMD_SD_RECOVERY=y
|
||||
CONFIG_CMD_PMIC=y
|
||||
CONFIG_CMD_REGULATOR=y
|
||||
|
||||
CONFIG_PINCTRL=y
|
||||
CONFIG_DM_GPIO=y
|
||||
CONFIG_DM_I2C=y
|
||||
CONFIG_SYS_I2C_NEXELL=y
|
||||
CONFIG_DM_PMIC=y
|
||||
CONFIG_DM_PMIC_AXP228=y
|
||||
CONFIG_DM_REGULATOR=y
|
||||
CONFIG_DM_REGULATOR_AXP228=y
|
||||
CONFIG_DM_PWM=n
|
||||
|
||||
CONFIG_DISPLAY=y
|
||||
CONFIG_DM_VIDEO=y
|
||||
CONFIG_SYS_CONSOLE_BG_COL=0xff
|
||||
CONFIG_SYS_CONSOLE_FG_COL=0x00
|
||||
CONFIG_VIDEO_NX=y
|
||||
CONFIG_VIDEO_NX_RGB=y
|
||||
CONFIG_VIDEO_NX_LVDS=y
|
||||
CONFIG_VIDEO_NX_HDMI=y
|
||||
CONFIG_CMD_BMP=y
|
||||
|
||||
## LCD backlight control
|
||||
CONFIG_S5P4418_ONEWIRE=y
|
||||
CONFIG_PWM_NX is not set
|
||||
|
||||
CONFIG_REGEX=y
|
||||
CONFIG_ERRNO_STR=y
|
||||
|
||||
CONFIG_SYS_TEXT_BASE=0x74C00000
|
||||
CONFIG_NR_DRAM_BANKS=1
|
||||
CONFIG_SYS_CACHELINE_SIZE=64
|
||||
|
||||
## System initialize options (board_init_f)
|
||||
# board_init_f->init_sequence, call board_early_init_f
|
||||
CONFIG_BOARD_LATE_INIT=y
|
||||
# board_init_f->init_sequence, call print_cpuinfo
|
||||
CONFIG_DISPLAY_CPUINFO=y
|
||||
# board_init_f->init_sequence, call show_board_info
|
||||
CONFIG_DISPLAY_BOARDINFO=y
|
||||
# board_init_f, CONFIG_SYS_ICACHE_OFF
|
||||
CONFIG_SYS_DCACHE_OFF=y
|
||||
# board_init_r, call arch_misc_init
|
||||
CONFIG_ARCH_MISC_INIT=y
|
||||
|
||||
CONFIG_BOOTDELAY=1
|
||||
CONFIG_ZERO_BOOTDELAY_CHECK=y
|
||||
|
||||
## U-Boot Environments
|
||||
## refer to common/env_common.c
|
||||
|
||||
# CONFIG_ENV_IS_IN_MMC must be set here and not in s5p4418_nanopi2.h
|
||||
# otherwise CONFIG_ENV_IS_NOWHERE is set by env/Kconfig and environment
|
||||
# (bootargs) are not loaded
|
||||
CONFIG_ENV_IS_IN_MMC=y
|
||||
CONFIG_ENV_OFFSET=0x2E0200
|
||||
CONFIG_ENV_SIZE=0x4000
|
||||
CONFIG_CMD_SAVEENV=y
|
||||
|
||||
## Etc Command definition
|
||||
# image info
|
||||
CONFIG_CMD_IMI=y
|
||||
# add command line history
|
||||
CONFIG_CMDLINE_EDITING=y
|
||||
CONFIG_CMDLINE_TAG=y
|
||||
CONFIG_INITRD_TAG=y
|
||||
CONFIG_SUPPORT_RAW_INITRD=y
|
||||
CONFIG_REVISION_TAG=y
|
||||
CONFIG_CMD_BOOTZ=y
|
||||
|
||||
## serial console configuration
|
||||
CONFIG_CONS_INDEX=0
|
||||
CONFIG_BAUDRATE=115200
|
||||
|
||||
## SD/MMC
|
||||
CONFIG_BOUNCE_BUFFER=y
|
||||
CONFIG_GENERIC_MMC=y
|
||||
CONFIG_MMC=y
|
||||
CONFIG_MMC_DW=y
|
||||
CONFIG_NEXELL_DWMMC=y
|
||||
CONFIG_CMD_MMC=y
|
||||
CONFIG_DM_MMC=y
|
||||
|
||||
CONFIG_DOS_PARTITION=y
|
||||
CONFIG_CMD_FAT=y
|
||||
CONFIG_FS_FAT=y
|
||||
CONFIG_FAT_WRITE=y
|
||||
|
||||
CONFIG_CMD_EXT4=y
|
||||
CONFIG_CMD_EXT4_WRITE=y
|
||||
CONFIG_FS_EXT4=y
|
||||
CONFIG_EXT4_WRITE=y
|
||||
|
||||
## OF_CONTROL
|
||||
CONFIG_FIT_BEST_MATCH=y
|
||||
CONFIG_OF_LIBFDT=y
|
||||
CONFIG_OF_BOARD_SETUP=y
|
||||
|
||||
## BOOTCOMMAND
|
||||
CONFIG_ROOT_DEV=1
|
||||
CONFIG_BOOT_PART=1
|
||||
CONFIG_ROOT_PART=2
|
||||
|
||||
# necessary for if-cmd
|
||||
CONFIG_HUSH_PARSER=y
|
||||
|
||||
# set to 'n' to save memory
|
||||
CONFIG_SYS_LONGHELP=y
|
||||
|
||||
# For debugging (trace) of MMC-CMDs
|
||||
CONFIG_MMC_TRACE=n
|
63
doc/README.s5p4418
Normal file
63
doc/README.s5p4418
Normal file
|
@ -0,0 +1,63 @@
|
|||
|
||||
Summary
|
||||
=======
|
||||
|
||||
This README is about U-Boot support for SAMSUNG's/NEXELL's ARM Cortex-A9 based
|
||||
S5P4418 SoC. It is based on FriendlyARM's U-Boot v2016.01 for the NanoPi2
|
||||
(and other) boards [1].
|
||||
|
||||
Currently the following boards are supported:
|
||||
|
||||
* FriendlyArm NanoPi2 [2]
|
||||
* FriendlyArm NanoPC-T2 [3]
|
||||
|
||||
|
||||
Build
|
||||
=====
|
||||
|
||||
* NanoPi2 and NanoPC-T2
|
||||
|
||||
make s5p4418_nanopi2_defconfig
|
||||
make
|
||||
|
||||
|
||||
Installation
|
||||
============
|
||||
|
||||
- Download Official-ROMs-SDCard-20190718.7z from [4] (images files for android,
|
||||
friendlyCore and LUbuntu)
|
||||
- Use s5p4418-sd-lubuntu-desktop-xenial-4.4-armhf-20190718.img to make a SD-card
|
||||
- Use dd in the directory where U-Boot has been built to update U-Boot:
|
||||
(replace <SD-card> with the device used for the SD-card, e.g. sdc)
|
||||
sudo dd seek=3841 if=u-boot.bin of=/dev/<SD-card>
|
||||
- Boot the board from this SD-card
|
||||
|
||||
The source code for (the used?) LUbuntu 16.04 can be found at [5].
|
||||
|
||||
|
||||
Links
|
||||
=====
|
||||
|
||||
[1] FriendlyArm U-boot v2016.01:
|
||||
|
||||
https://github.com/friendlyarm/u-boot/tree/nanopi2-v2016.01
|
||||
|
||||
|
||||
[2] NanoPi2:
|
||||
|
||||
http://wiki.friendlyarm.com/wiki/index.php/NanoPi_2
|
||||
|
||||
|
||||
[3] NanoPC-T2:
|
||||
|
||||
http://wiki.friendlyarm.com/wiki/index.php/NanoPC-T2
|
||||
|
||||
|
||||
[4] FriendlyArm image files for NanoPi2:
|
||||
|
||||
http://download.friendlyarm.com//NanoPi2
|
||||
|
||||
|
||||
[5] FriendlyArm LUbuntu 16.04 Source Code for NanoPi2:
|
||||
|
||||
https://github.com/friendlyarm/linux/tree/nanopi2-v4.4.y
|
|
@ -1,7 +1,8 @@
|
|||
Qualcomm Snapdragon GPIO controller
|
||||
|
||||
Required properties:
|
||||
- compatible : "qcom,msm8916-pinctrl" or "qcom,apq8016-pinctrl"
|
||||
- compatible : "qcom,msm8916-pinctrl", "qcom,apq8016-pinctrl" or
|
||||
"qcom,ipq4019-pinctrl"
|
||||
- reg : Physical base address and length of the controller's registers.
|
||||
This controller is called "Top Level Mode Multiplexing" in
|
||||
Qualcomm documentation.
|
||||
|
|
28
doc/device-tree-bindings/i2c/nx_i2c.txt
Normal file
28
doc/device-tree-bindings/i2c/nx_i2c.txt
Normal file
|
@ -0,0 +1,28 @@
|
|||
I2C controller embedded in Nexell's/Samsung's SoC S5P4418 and S5P6818
|
||||
|
||||
Driver:
|
||||
- drivers/i2c/nx_i2c.c
|
||||
|
||||
Required properties:
|
||||
- #address-cells = <1>;
|
||||
- #size-cells = <0>;
|
||||
- compatible = "nexell,s5pxx18-i2c";
|
||||
- reg = <i2c_base 0x100>;
|
||||
Where i2c_base has to be the base address of the i2c-register set.
|
||||
I2C0: 0xc00a4000
|
||||
I2C1: 0xc00a5000
|
||||
I2C2: 0xc00a6000
|
||||
|
||||
Optional properties:
|
||||
- clock-frequency: Desired I2C bus frequency in Hz, default value is 100000.
|
||||
- i2c-sda-delay-ns (S5P6818 only): SDA delay in ns, default value is 0.
|
||||
- Child nodes conforming to i2c bus binding.
|
||||
|
||||
Example:
|
||||
i2c0:i2c@c00a4000 {
|
||||
#address-cells = <1>;
|
||||
#size-cells = <0>;
|
||||
compatible = "nexell,s5pxx18-i2c";
|
||||
reg = <0xc00a4000 0x100>;
|
||||
clock-frequency = <400000>;
|
||||
};
|
78
doc/device-tree-bindings/pinctrl/nexell,s5pxx18-pinctrl.txt
Normal file
78
doc/device-tree-bindings/pinctrl/nexell,s5pxx18-pinctrl.txt
Normal file
|
@ -0,0 +1,78 @@
|
|||
Binding for Nexell s5pxx18 pin cotroller
|
||||
========================================
|
||||
|
||||
Nexell's ARM bases SoC's integrates a GPIO and Pin mux/config hardware
|
||||
controller. It controls the input/output settings on the available pads/pins
|
||||
and also provides ability to multiplex and configure the output of various
|
||||
on-chip controllers onto these pads.
|
||||
|
||||
Please refer to pinctrl-bindings.txt in this directory for details of the
|
||||
common pinctrl bindings used by client devices, including the meaning of the
|
||||
phrase "pin configuration node".
|
||||
|
||||
|
||||
Required properties:
|
||||
- compatible: "nexell,s5pxx18-pinctrl"
|
||||
- reg: should be register base and length as documented in the datasheet
|
||||
- interrupts: interrupt specifier for the controller over gpio and alive pins
|
||||
|
||||
Example:
|
||||
pinctrl_0: pinctrl@c0010000 {
|
||||
compatible = "nexell,s5pxx18-pinctrl";
|
||||
reg = <0xc0010000 0xf000>;
|
||||
u-boot,dm-pre-reloc;
|
||||
};
|
||||
|
||||
Nexell's pin configuration nodes act as a container for an arbitrary number of
|
||||
subnodes. Each of these subnodes represents some desired configuration for a
|
||||
pin, a group, or a list of pins or groups. This configuration can include the
|
||||
mux function to select on those pin(s)/group(s), and various pin configuration
|
||||
parameters.
|
||||
|
||||
Child nodes must be set at least one of the following settings:
|
||||
- pins = Select pins for using this function.
|
||||
- pin-function = Select the function for use in a selected pin.
|
||||
- pin-pull = Pull up/down configuration.
|
||||
- pin-strength = Drive strength configuration.
|
||||
|
||||
Valid values for nexell,pins are:
|
||||
"gpioX-N" : X in {A,B,C,D,E}, N in {0-31}
|
||||
Valid values for nexell,pin-function are:
|
||||
"N" : N in {0-3}.
|
||||
This setting means that the value is different for each pin.
|
||||
Please refer to datasheet.
|
||||
Valid values for nexell,pin-pull are:
|
||||
"N" : 0 - Down, 1 - Up, 2 - Off
|
||||
Valid values for nexell,pin-strength are:
|
||||
"N" : 0,1,2,3
|
||||
|
||||
|
||||
Example:
|
||||
- pin settings
|
||||
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>;
|
||||
};
|
||||
|
||||
- used by client devices
|
||||
mmc0:mmc@... {
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&mmc0_clk>, <&mmc0_cmd>, <&mmc0_bus4>;
|
||||
...
|
||||
};
|
|
@ -4,3 +4,7 @@ Required properties:
|
|||
- compatible: must be "qcom,msm-uartdm-v1.4"
|
||||
- reg: start address and size of the registers
|
||||
- clock: interface clock (must accept baudrate as a frequency)
|
||||
|
||||
Optional properties:
|
||||
- bit-rate: Data Mover bit rate register value
|
||||
(If not defined then 0xCC is used as default)
|
||||
|
|
|
@ -457,4 +457,13 @@ config MT7621_GPIO
|
|||
help
|
||||
Say yes here to support MediaTek MT7621 compatible GPIOs.
|
||||
|
||||
config NX_GPIO
|
||||
bool "Nexell GPIO driver"
|
||||
depends on DM_GPIO
|
||||
help
|
||||
Support GPIO access on Nexell SoCs. The GPIOs are arranged into
|
||||
a number of banks (different for each SoC type) each with 32 GPIOs.
|
||||
The GPIOs for a device are defined in the device tree with one node
|
||||
for each bank.
|
||||
|
||||
endmenu
|
||||
|
|
|
@ -64,4 +64,5 @@ obj-$(CONFIG_$(SPL_)PCF8575_GPIO) += pcf8575_gpio.o
|
|||
obj-$(CONFIG_PM8916_GPIO) += pm8916_gpio.o
|
||||
obj-$(CONFIG_MT7621_GPIO) += mt7621_gpio.o
|
||||
obj-$(CONFIG_MSCC_SGPIO) += mscc_sgpio.o
|
||||
obj-$(CONFIG_NX_GPIO) += nx_gpio.o
|
||||
obj-$(CONFIG_SIFIVE_GPIO) += sifive-gpio.o
|
||||
|
|
|
@ -118,6 +118,7 @@ static int msm_gpio_ofdata_to_platdata(struct udevice *dev)
|
|||
static const struct udevice_id msm_gpio_ids[] = {
|
||||
{ .compatible = "qcom,msm8916-pinctrl" },
|
||||
{ .compatible = "qcom,apq8016-pinctrl" },
|
||||
{ .compatible = "qcom,ipq4019-pinctrl" },
|
||||
{ }
|
||||
};
|
||||
|
||||
|
|
250
drivers/gpio/nx_gpio.c
Normal file
250
drivers/gpio/nx_gpio.c
Normal file
|
@ -0,0 +1,250 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2016 Nexell
|
||||
* DeokJin, Lee <truevirtue@nexell.co.kr>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <asm/io.h>
|
||||
#include <asm/gpio.h>
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct nx_gpio_regs {
|
||||
u32 data; /* Data register */
|
||||
u32 outputenb; /* Output Enable register */
|
||||
u32 detmode[2]; /* Detect Mode Register */
|
||||
u32 intenb; /* Interrupt Enable Register */
|
||||
u32 det; /* Event Detect Register */
|
||||
u32 pad; /* Pad Status Register */
|
||||
};
|
||||
|
||||
struct nx_alive_gpio_regs {
|
||||
u32 pwrgate; /* Power Gating Register */
|
||||
u32 reserved0[28]; /* Reserved0 */
|
||||
u32 outputenb_reset;/* Alive GPIO Output Enable Reset Register */
|
||||
u32 outputenb; /* Alive GPIO Output Enable Register */
|
||||
u32 outputenb_read; /* Alive GPIO Output Read Register */
|
||||
u32 reserved1[3]; /* Reserved1 */
|
||||
u32 pad_reset; /* Alive GPIO Output Reset Register */
|
||||
u32 data; /* Alive GPIO Output Register */
|
||||
u32 pad_read; /* Alive GPIO Pad Read Register */
|
||||
u32 reserved2[33]; /* Reserved2 */
|
||||
u32 pad; /* Alive GPIO Input Value Register */
|
||||
};
|
||||
|
||||
struct nx_gpio_platdata {
|
||||
void *regs;
|
||||
int gpio_count;
|
||||
const char *bank_name;
|
||||
};
|
||||
|
||||
static int nx_alive_gpio_is_check(struct udevice *dev)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
const char *bank_name = plat->bank_name;
|
||||
|
||||
if (!strcmp(bank_name, "gpio_alv"))
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_alive_gpio_direction_input(struct udevice *dev, unsigned int pin)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_alive_gpio_regs *const regs = plat->regs;
|
||||
|
||||
setbits_le32(®s->outputenb_reset, 1 << pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_alive_gpio_direction_output(struct udevice *dev, unsigned int pin,
|
||||
int val)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_alive_gpio_regs *const regs = plat->regs;
|
||||
|
||||
if (val)
|
||||
setbits_le32(®s->data, 1 << pin);
|
||||
else
|
||||
setbits_le32(®s->pad_reset, 1 << pin);
|
||||
|
||||
setbits_le32(®s->outputenb, 1 << pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_alive_gpio_get_value(struct udevice *dev, unsigned int pin)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_alive_gpio_regs *const regs = plat->regs;
|
||||
unsigned int mask = 1UL << pin;
|
||||
unsigned int value;
|
||||
|
||||
value = (readl(®s->pad_read) & mask) >> pin;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static int nx_alive_gpio_set_value(struct udevice *dev, unsigned int pin,
|
||||
int val)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_alive_gpio_regs *const regs = plat->regs;
|
||||
|
||||
if (val)
|
||||
setbits_le32(®s->data, 1 << pin);
|
||||
else
|
||||
clrbits_le32(®s->pad_reset, 1 << pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_alive_gpio_get_function(struct udevice *dev, unsigned int pin)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_alive_gpio_regs *const regs = plat->regs;
|
||||
unsigned int mask = (1UL << pin);
|
||||
unsigned int output;
|
||||
|
||||
output = readl(®s->outputenb_read) & mask;
|
||||
|
||||
if (output)
|
||||
return GPIOF_OUTPUT;
|
||||
else
|
||||
return GPIOF_INPUT;
|
||||
}
|
||||
|
||||
static int nx_gpio_direction_input(struct udevice *dev, unsigned int pin)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_gpio_regs *const regs = plat->regs;
|
||||
|
||||
if (nx_alive_gpio_is_check(dev))
|
||||
return nx_alive_gpio_direction_input(dev, pin);
|
||||
|
||||
clrbits_le32(®s->outputenb, 1 << pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_gpio_direction_output(struct udevice *dev, unsigned int pin,
|
||||
int val)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_gpio_regs *const regs = plat->regs;
|
||||
|
||||
if (nx_alive_gpio_is_check(dev))
|
||||
return nx_alive_gpio_direction_output(dev, pin, val);
|
||||
|
||||
if (val)
|
||||
setbits_le32(®s->data, 1 << pin);
|
||||
else
|
||||
clrbits_le32(®s->data, 1 << pin);
|
||||
|
||||
setbits_le32(®s->outputenb, 1 << pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_gpio_get_value(struct udevice *dev, unsigned int pin)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_gpio_regs *const regs = plat->regs;
|
||||
unsigned int mask = 1UL << pin;
|
||||
unsigned int value;
|
||||
|
||||
if (nx_alive_gpio_is_check(dev))
|
||||
return nx_alive_gpio_get_value(dev, pin);
|
||||
|
||||
value = (readl(®s->pad) & mask) >> pin;
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
static int nx_gpio_set_value(struct udevice *dev, unsigned int pin, int val)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_gpio_regs *const regs = plat->regs;
|
||||
|
||||
if (nx_alive_gpio_is_check(dev))
|
||||
return nx_alive_gpio_set_value(dev, pin, val);
|
||||
|
||||
if (val)
|
||||
setbits_le32(®s->data, 1 << pin);
|
||||
else
|
||||
clrbits_le32(®s->data, 1 << pin);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_gpio_get_function(struct udevice *dev, unsigned int pin)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
struct nx_gpio_regs *const regs = plat->regs;
|
||||
unsigned int mask = (1UL << pin);
|
||||
unsigned int output;
|
||||
|
||||
if (nx_alive_gpio_is_check(dev))
|
||||
return nx_alive_gpio_get_function(dev, pin);
|
||||
|
||||
output = readl(®s->outputenb) & mask;
|
||||
|
||||
if (output)
|
||||
return GPIOF_OUTPUT;
|
||||
else
|
||||
return GPIOF_INPUT;
|
||||
}
|
||||
|
||||
static int nx_gpio_probe(struct udevice *dev)
|
||||
{
|
||||
struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
|
||||
uc_priv->gpio_count = plat->gpio_count;
|
||||
uc_priv->bank_name = plat->bank_name;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_gpio_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct nx_gpio_platdata *plat = dev_get_platdata(dev);
|
||||
|
||||
plat->regs = map_physmem(devfdt_get_addr(dev),
|
||||
sizeof(struct nx_gpio_regs),
|
||||
MAP_NOCACHE);
|
||||
plat->gpio_count = dev_read_s32_default(dev, "nexell,gpio-bank-width",
|
||||
32);
|
||||
plat->bank_name = dev_read_string(dev, "gpio-bank-name");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const struct dm_gpio_ops nx_gpio_ops = {
|
||||
.direction_input = nx_gpio_direction_input,
|
||||
.direction_output = nx_gpio_direction_output,
|
||||
.get_value = nx_gpio_get_value,
|
||||
.set_value = nx_gpio_set_value,
|
||||
.get_function = nx_gpio_get_function,
|
||||
};
|
||||
|
||||
static const struct udevice_id nx_gpio_ids[] = {
|
||||
{ .compatible = "nexell,nexell-gpio" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(nx_gpio) = {
|
||||
.name = "nx_gpio",
|
||||
.id = UCLASS_GPIO,
|
||||
.of_match = nx_gpio_ids,
|
||||
.ops = &nx_gpio_ops,
|
||||
.ofdata_to_platdata = nx_gpio_ofdata_to_platdata,
|
||||
.platdata_auto_alloc_size = sizeof(struct nx_gpio_platdata),
|
||||
.probe = nx_gpio_probe,
|
||||
};
|
|
@ -333,6 +333,15 @@ config SYS_MXC_I2C8_SLAVE
|
|||
MXC I2C8 Slave
|
||||
endif
|
||||
|
||||
config SYS_I2C_NEXELL
|
||||
bool "Nexell I2C driver"
|
||||
depends on DM_I2C
|
||||
help
|
||||
Add support for the Nexell I2C driver. This is used with various
|
||||
Nexell parts such as S5Pxx18 series SoCs. All chips
|
||||
have several I2C ports and all are provided, controlled by the
|
||||
device tree.
|
||||
|
||||
config SYS_I2C_OMAP24XX
|
||||
bool "TI OMAP2+ I2C driver"
|
||||
depends on ARCH_OMAP2PLUS || ARCH_K3
|
||||
|
|
|
@ -28,6 +28,7 @@ obj-$(CONFIG_SYS_I2C_LPC32XX) += lpc32xx_i2c.o
|
|||
obj-$(CONFIG_SYS_I2C_MESON) += meson_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_MVTWSI) += mvtwsi.o
|
||||
obj-$(CONFIG_SYS_I2C_MXC) += mxc_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_NEXELL) += nx_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_OCTEON) += octeon_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_OMAP24XX) += omap24xx_i2c.o
|
||||
obj-$(CONFIG_SYS_I2C_RCAR_I2C) += rcar_i2c.o
|
||||
|
|
626
drivers/i2c/nx_i2c.c
Normal file
626
drivers/i2c/nx_i2c.c
Normal file
|
@ -0,0 +1,626 @@
|
|||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <dm.h>
|
||||
#include <i2c.h>
|
||||
#include <log.h>
|
||||
#include <asm/arch/nexell.h>
|
||||
#include <asm/arch/reset.h>
|
||||
#include <asm/arch/clk.h>
|
||||
#include <asm/arch/nx_gpio.h>
|
||||
#include <linux/delay.h>
|
||||
|
||||
#define I2C_WRITE 0
|
||||
#define I2C_READ 1
|
||||
|
||||
#define I2CSTAT_MTM 0xC0 /* Master Transmit Mode */
|
||||
#define I2CSTAT_MRM 0x80 /* Master Receive Mode */
|
||||
#define I2CSTAT_BSY 0x20 /* Read: Bus Busy */
|
||||
#define I2CSTAT_SS 0x20 /* Write: START (1) / STOP (0) */
|
||||
#define I2CSTAT_RXTXEN 0x10 /* Rx/Tx enable */
|
||||
#define I2CSTAT_ABT 0x08 /* Arbitration bit */
|
||||
#define I2CSTAT_NACK 0x01 /* Nack bit */
|
||||
#define I2CCON_IRCLR 0x100 /* Interrupt Clear bit */
|
||||
#define I2CCON_ACKGEN 0x80 /* Acknowledge generation */
|
||||
#define I2CCON_TCP256 0x40 /* Tx-clock prescaler: 16 (0) / 256 (1) */
|
||||
#define I2CCON_IRENB 0x20 /* Interrupt Enable bit */
|
||||
#define I2CCON_IRPND 0x10 /* Interrupt pending bit */
|
||||
#define I2CCON_TCDMSK 0x0F /* I2C-bus transmit clock divider bit mask */
|
||||
|
||||
#ifdef CONFIG_ARCH_S5P6818
|
||||
#define SDADLY_CLKSTEP 5 /* SDA delay: Reg. val. is multiple of 5 clks */
|
||||
#define SDADLY_MAX 3 /* SDA delay: Max. reg. value is 3 */
|
||||
#define I2CLC_FILTER 0x04 /* SDA filter on */
|
||||
#else
|
||||
#define STOPCON_CLR 0x01 /* Clock Line Release */
|
||||
#define STOPCON_DLR 0x02 /* Data Line Release */
|
||||
#define STOPCON_NAG 0x04 /* not-ackn. generation and data shift cont. */
|
||||
#endif
|
||||
|
||||
#define I2C_TIMEOUT_MS 10 /* 10 ms */
|
||||
|
||||
#define I2C_M_NOSTOP 0x100
|
||||
|
||||
#define MAX_I2C_NUM 3
|
||||
|
||||
#define DEFAULT_SPEED 100000 /* default I2C speed [Hz] */
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
struct nx_i2c_regs {
|
||||
uint iiccon;
|
||||
uint iicstat;
|
||||
uint iicadd;
|
||||
uint iicds;
|
||||
#ifdef CONFIG_ARCH_S5P6818
|
||||
/* S5P6818: Offset 0x10 is Line Control Register (SDA-delay, Filter) */
|
||||
uint iiclc;
|
||||
#else
|
||||
/* S5P4418: Offset 0x10 is Stop Control Register */
|
||||
uint iicstopcon;
|
||||
#endif
|
||||
};
|
||||
|
||||
struct nx_i2c_bus {
|
||||
uint bus_num;
|
||||
struct nx_i2c_regs *regs;
|
||||
uint speed;
|
||||
uint target_speed;
|
||||
#ifdef CONFIG_ARCH_S5P6818
|
||||
uint sda_delay;
|
||||
#else
|
||||
/* setup time for Stop condition [us] */
|
||||
uint tsu_stop;
|
||||
#endif
|
||||
};
|
||||
|
||||
/* s5pxx18 i2c must be reset before enabled */
|
||||
static void i2c_reset(int ch)
|
||||
{
|
||||
int rst_id = RESET_ID_I2C0 + ch;
|
||||
|
||||
nx_rstcon_setrst(rst_id, 0);
|
||||
nx_rstcon_setrst(rst_id, 1);
|
||||
}
|
||||
|
||||
static uint i2c_get_clkrate(struct nx_i2c_bus *bus)
|
||||
{
|
||||
struct clk *clk;
|
||||
int index = bus->bus_num;
|
||||
char name[50] = {0, };
|
||||
|
||||
sprintf(name, "%s.%d", DEV_NAME_I2C, index);
|
||||
clk = clk_get((const char *)name);
|
||||
if (!clk)
|
||||
return -1;
|
||||
|
||||
return clk_get_rate(clk);
|
||||
}
|
||||
|
||||
static uint i2c_set_clk(struct nx_i2c_bus *bus, uint enb)
|
||||
{
|
||||
struct clk *clk;
|
||||
char name[50];
|
||||
|
||||
sprintf(name, "%s.%d", DEV_NAME_I2C, bus->bus_num);
|
||||
clk = clk_get((const char *)name);
|
||||
if (!clk) {
|
||||
debug("%s(): clk_get(%s) error!\n",
|
||||
__func__, (const char *)name);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
clk_disable(clk);
|
||||
if (enb)
|
||||
clk_enable(clk);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_ARCH_S5P6818
|
||||
/* Set SDA line delay, not available at S5P4418 */
|
||||
static int nx_i2c_set_sda_delay(struct nx_i2c_bus *bus)
|
||||
{
|
||||
struct nx_i2c_regs *i2c = bus->regs;
|
||||
uint pclk = 0;
|
||||
uint t_pclk = 0;
|
||||
uint delay = 0;
|
||||
|
||||
/* get input clock of the I2C-controller */
|
||||
pclk = i2c_get_clkrate(bus);
|
||||
|
||||
if (bus->sda_delay) {
|
||||
/* t_pclk = period time of one pclk [ns] */
|
||||
t_pclk = DIV_ROUND_UP(1000, pclk / 1000000);
|
||||
/* delay = number of pclks required for sda_delay [ns] */
|
||||
delay = DIV_ROUND_UP(bus->sda_delay, t_pclk);
|
||||
/* delay = register value (step of 5 clocks) */
|
||||
delay = DIV_ROUND_UP(delay, SDADLY_CLKSTEP);
|
||||
/* max. possible register value = 3 */
|
||||
if (delay > SDADLY_MAX) {
|
||||
delay = SDADLY_MAX;
|
||||
debug("%s(): sda-delay des.: %dns, sat. to max.: %dns (granularity: %dns)\n",
|
||||
__func__, bus->sda_delay, t_pclk * delay * SDADLY_CLKSTEP,
|
||||
t_pclk * SDADLY_CLKSTEP);
|
||||
} else {
|
||||
debug("%s(): sda-delay des.: %dns, act.: %dns (granularity: %dns)\n",
|
||||
__func__, bus->sda_delay, t_pclk * delay * SDADLY_CLKSTEP,
|
||||
t_pclk * SDADLY_CLKSTEP);
|
||||
}
|
||||
|
||||
delay |= I2CLC_FILTER;
|
||||
} else {
|
||||
delay = 0;
|
||||
debug("%s(): sda-delay = 0\n", __func__);
|
||||
}
|
||||
|
||||
delay &= 0x7;
|
||||
writel(delay, &i2c->iiclc);
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int nx_i2c_set_bus_speed(struct udevice *dev, uint speed)
|
||||
{
|
||||
struct nx_i2c_bus *bus = dev_get_priv(dev);
|
||||
struct nx_i2c_regs *i2c = bus->regs;
|
||||
unsigned long pclk, pres = 16, div;
|
||||
|
||||
if (i2c_set_clk(bus, 1))
|
||||
return -EINVAL;
|
||||
|
||||
/* get input clock of the I2C-controller */
|
||||
pclk = i2c_get_clkrate(bus);
|
||||
|
||||
/* calculate prescaler and divisor values */
|
||||
if ((pclk / pres / (16 + 1)) > speed)
|
||||
/* prescaler value 16 is too less --> set to 256 */
|
||||
pres = 256;
|
||||
|
||||
div = 0;
|
||||
/* actual divider = div + 1 */
|
||||
while ((pclk / pres / (div + 1)) > speed)
|
||||
div++;
|
||||
|
||||
if (div > 0xF) {
|
||||
debug("%s(): pres==%ld, div==0x%lx is saturated to 0xF !)\n",
|
||||
__func__, pres, div);
|
||||
div = 0xF;
|
||||
} else {
|
||||
debug("%s(): pres==%ld, div==0x%lx)\n", __func__, pres, div);
|
||||
}
|
||||
|
||||
/* set Tx-clock divisor and prescaler values */
|
||||
writel((div & I2CCON_TCDMSK) | ((pres == 256) ? I2CCON_TCP256 : 0),
|
||||
&i2c->iiccon);
|
||||
|
||||
/* init to SLAVE REVEIVE and set slaveaddr */
|
||||
writel(0, &i2c->iicstat);
|
||||
writel(0x00, &i2c->iicadd);
|
||||
|
||||
/* program Master Transmit (and implicit STOP) */
|
||||
writel(I2CSTAT_MTM | I2CSTAT_RXTXEN, &i2c->iicstat);
|
||||
|
||||
/* calculate actual I2C speed [Hz] */
|
||||
bus->speed = pclk / ((div + 1) * pres);
|
||||
debug("%s(): speed des.: %dHz, act.: %dHz\n",
|
||||
__func__, speed, bus->speed);
|
||||
|
||||
#ifdef CONFIG_ARCH_S5P6818
|
||||
nx_i2c_set_sda_delay(bus);
|
||||
#else
|
||||
/* setup time for Stop condition [us], min. 4us @ 100kHz I2C-clock */
|
||||
bus->tsu_stop = DIV_ROUND_UP(400, bus->speed / 1000);
|
||||
#endif
|
||||
|
||||
if (i2c_set_clk(bus, 0))
|
||||
return -EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void i2c_process_node(struct udevice *dev)
|
||||
{
|
||||
struct nx_i2c_bus *bus = dev_get_priv(dev);
|
||||
|
||||
bus->target_speed = dev_read_s32_default(dev, "clock-frequency",
|
||||
DEFAULT_SPEED);
|
||||
#ifdef CONFIG_ARCH_S5P6818
|
||||
bus->sda_delay = dev_read_s32_default(dev, "i2c-sda-delay-ns", 0);
|
||||
#endif
|
||||
}
|
||||
|
||||
static int nx_i2c_probe(struct udevice *dev)
|
||||
{
|
||||
struct nx_i2c_bus *bus = dev_get_priv(dev);
|
||||
fdt_addr_t addr;
|
||||
|
||||
/* get regs = i2c base address */
|
||||
addr = devfdt_get_addr(dev);
|
||||
if (addr == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
bus->regs = (struct nx_i2c_regs *)addr;
|
||||
|
||||
bus->bus_num = dev->seq;
|
||||
|
||||
/* i2c node parsing */
|
||||
i2c_process_node(dev);
|
||||
if (!bus->target_speed)
|
||||
return -ENODEV;
|
||||
|
||||
/* reset */
|
||||
i2c_reset(bus->bus_num);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* i2c bus busy check */
|
||||
static int i2c_is_busy(struct nx_i2c_regs *i2c)
|
||||
{
|
||||
ulong start_time;
|
||||
|
||||
start_time = get_timer(0);
|
||||
while (readl(&i2c->iicstat) & I2CSTAT_BSY) {
|
||||
if (get_timer(start_time) > I2C_TIMEOUT_MS) {
|
||||
debug("Timeout\n");
|
||||
return -EBUSY;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* irq enable/disable functions */
|
||||
static void i2c_enable_irq(struct nx_i2c_regs *i2c)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl(&i2c->iiccon);
|
||||
reg |= I2CCON_IRENB;
|
||||
writel(reg, &i2c->iiccon);
|
||||
}
|
||||
|
||||
/* irq clear function */
|
||||
static void i2c_clear_irq(struct nx_i2c_regs *i2c)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl(&i2c->iiccon);
|
||||
/* reset interrupt pending flag */
|
||||
reg &= ~(I2CCON_IRPND);
|
||||
/*
|
||||
* Interrupt must also be cleared!
|
||||
* Otherwise linux boot may hang after:
|
||||
* [ 0.436000] NetLabel: unlabeled traffic allowed by default
|
||||
* Next would be:
|
||||
* [ 0.442000] clocksource: Switched to clocksource source timer
|
||||
*/
|
||||
reg |= I2CCON_IRCLR;
|
||||
writel(reg, &i2c->iiccon);
|
||||
}
|
||||
|
||||
/* ack enable functions */
|
||||
static void i2c_enable_ack(struct nx_i2c_regs *i2c)
|
||||
{
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl(&i2c->iiccon);
|
||||
reg |= I2CCON_ACKGEN;
|
||||
writel(reg, &i2c->iiccon);
|
||||
}
|
||||
|
||||
static void i2c_send_stop(struct nx_i2c_bus *bus)
|
||||
{
|
||||
struct nx_i2c_regs *i2c = bus->regs;
|
||||
|
||||
if (IS_ENABLED(CONFIG_ARCH_S5P6818)) {
|
||||
unsigned int reg;
|
||||
|
||||
reg = readl(&i2c->iicstat);
|
||||
reg |= I2CSTAT_MRM | I2CSTAT_RXTXEN;
|
||||
reg &= (~I2CSTAT_SS);
|
||||
|
||||
writel(reg, &i2c->iicstat);
|
||||
i2c_clear_irq(i2c);
|
||||
} else { /* S5P4418 */
|
||||
writel(STOPCON_NAG, &i2c->iicstopcon);
|
||||
|
||||
i2c_clear_irq(i2c);
|
||||
|
||||
/*
|
||||
* Clock Line Release --> SDC changes from Low to High and
|
||||
* SDA from High to Low
|
||||
*/
|
||||
writel(STOPCON_CLR, &i2c->iicstopcon);
|
||||
|
||||
/* Hold SDA Low (Setup Time for Stop condition) */
|
||||
udelay(bus->tsu_stop);
|
||||
|
||||
i2c_clear_irq(i2c);
|
||||
|
||||
/* Master Receive Mode Stop --> SDA becomes High */
|
||||
writel(I2CSTAT_MRM, &i2c->iicstat);
|
||||
}
|
||||
}
|
||||
|
||||
static int wait_for_xfer(struct nx_i2c_regs *i2c)
|
||||
{
|
||||
unsigned long start_time = get_timer(0);
|
||||
|
||||
do {
|
||||
if (readl(&i2c->iiccon) & I2CCON_IRPND)
|
||||
/* return -EREMOTEIO if not Acknowledged, otherwise 0 */
|
||||
return (readl(&i2c->iicstat) & I2CSTAT_NACK) ?
|
||||
-EREMOTEIO : 0;
|
||||
} while (get_timer(start_time) < I2C_TIMEOUT_MS);
|
||||
|
||||
return -ETIMEDOUT;
|
||||
}
|
||||
|
||||
static int i2c_transfer(struct nx_i2c_regs *i2c,
|
||||
uchar cmd_type,
|
||||
uchar chip_addr,
|
||||
uchar addr[],
|
||||
uchar addr_len,
|
||||
uchar data[],
|
||||
unsigned short data_len,
|
||||
uint seq)
|
||||
{
|
||||
uint status;
|
||||
int i = 0, result;
|
||||
|
||||
/* Note: data_len = 0 is supported for "probe_chip" */
|
||||
|
||||
i2c_enable_irq(i2c);
|
||||
i2c_enable_ack(i2c);
|
||||
|
||||
/* Get the slave chip address going */
|
||||
/* Enable Rx/Tx */
|
||||
writel(I2CSTAT_RXTXEN, &i2c->iicstat);
|
||||
|
||||
writel(chip_addr, &i2c->iicds);
|
||||
status = I2CSTAT_RXTXEN | I2CSTAT_SS;
|
||||
if (cmd_type == I2C_WRITE || (addr && addr_len))
|
||||
status |= I2CSTAT_MTM;
|
||||
else
|
||||
status |= I2CSTAT_MRM;
|
||||
|
||||
writel(status, &i2c->iicstat);
|
||||
if (seq)
|
||||
i2c_clear_irq(i2c);
|
||||
|
||||
/* Wait for chip address to transmit. */
|
||||
result = wait_for_xfer(i2c);
|
||||
if (result) {
|
||||
debug("%s: transmitting chip address failed\n", __func__);
|
||||
goto bailout;
|
||||
}
|
||||
|
||||
/* If register address needs to be transmitted - do it now. */
|
||||
if (addr && addr_len) { /* register addr */
|
||||
while ((i < addr_len) && !result) {
|
||||
writel(addr[i++], &i2c->iicds);
|
||||
i2c_clear_irq(i2c);
|
||||
result = wait_for_xfer(i2c);
|
||||
}
|
||||
|
||||
i = 0;
|
||||
if (result) {
|
||||
debug("%s: transmitting register address failed\n",
|
||||
__func__);
|
||||
goto bailout;
|
||||
}
|
||||
}
|
||||
|
||||
switch (cmd_type) {
|
||||
case I2C_WRITE:
|
||||
while ((i < data_len) && !result) {
|
||||
writel(data[i++], &i2c->iicds);
|
||||
i2c_clear_irq(i2c);
|
||||
result = wait_for_xfer(i2c);
|
||||
}
|
||||
break;
|
||||
case I2C_READ:
|
||||
if (addr && addr_len) {
|
||||
/*
|
||||
* Register address has been sent, now send slave chip
|
||||
* address again to start the actual read transaction.
|
||||
*/
|
||||
writel(chip_addr, &i2c->iicds);
|
||||
|
||||
/* Generate a re-START. */
|
||||
writel(I2CSTAT_MRM | I2CSTAT_RXTXEN |
|
||||
I2CSTAT_SS, &i2c->iicstat);
|
||||
i2c_clear_irq(i2c);
|
||||
result = wait_for_xfer(i2c);
|
||||
if (result) {
|
||||
debug("%s: I2C_READ: sending chip addr. failed\n",
|
||||
__func__);
|
||||
goto bailout;
|
||||
}
|
||||
}
|
||||
|
||||
while ((i < data_len) && !result) {
|
||||
/* disable ACK for final READ */
|
||||
if (i == data_len - 1)
|
||||
clrbits_le32(&i2c->iiccon, I2CCON_ACKGEN);
|
||||
|
||||
i2c_clear_irq(i2c);
|
||||
result = wait_for_xfer(i2c);
|
||||
data[i++] = readb(&i2c->iicds);
|
||||
}
|
||||
|
||||
if (result == -EREMOTEIO)
|
||||
/* Not Acknowledged --> normal terminated read. */
|
||||
result = 0;
|
||||
else if (result == -ETIMEDOUT)
|
||||
debug("%s: I2C_READ: time out\n", __func__);
|
||||
else
|
||||
debug("%s: I2C_READ: read not terminated with NACK\n",
|
||||
__func__);
|
||||
break;
|
||||
|
||||
default:
|
||||
debug("%s: bad call\n", __func__);
|
||||
result = -EINVAL;
|
||||
break;
|
||||
}
|
||||
|
||||
bailout:
|
||||
return result;
|
||||
}
|
||||
|
||||
static int nx_i2c_read(struct udevice *dev, uchar chip_addr, uint addr,
|
||||
uint alen, uchar *buffer, uint len, uint seq)
|
||||
{
|
||||
struct nx_i2c_bus *i2c;
|
||||
uchar xaddr[4];
|
||||
int ret;
|
||||
|
||||
i2c = dev_get_priv(dev);
|
||||
if (!i2c)
|
||||
return -EFAULT;
|
||||
|
||||
if (alen > 4) {
|
||||
debug("I2C read: addr len %d not supported\n", alen);
|
||||
return -EADDRNOTAVAIL;
|
||||
}
|
||||
|
||||
if (alen > 0)
|
||||
xaddr[0] = (addr >> 24) & 0xFF;
|
||||
|
||||
if (alen > 0) {
|
||||
xaddr[0] = (addr >> 24) & 0xFF;
|
||||
xaddr[1] = (addr >> 16) & 0xFF;
|
||||
xaddr[2] = (addr >> 8) & 0xFF;
|
||||
xaddr[3] = addr & 0xFF;
|
||||
}
|
||||
|
||||
ret = i2c_transfer(i2c->regs, I2C_READ, chip_addr << 1,
|
||||
&xaddr[4 - alen], alen, buffer, len, seq);
|
||||
|
||||
if (ret) {
|
||||
debug("I2C read failed %d\n", ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_i2c_write(struct udevice *dev, uchar chip_addr, uint addr,
|
||||
uint alen, uchar *buffer, uint len, uint seq)
|
||||
{
|
||||
struct nx_i2c_bus *i2c;
|
||||
uchar xaddr[4];
|
||||
int ret;
|
||||
|
||||
i2c = dev_get_priv(dev);
|
||||
if (!i2c)
|
||||
return -EFAULT;
|
||||
|
||||
if (alen > 4) {
|
||||
debug("I2C write: addr len %d not supported\n", alen);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (alen > 0) {
|
||||
xaddr[0] = (addr >> 24) & 0xFF;
|
||||
xaddr[1] = (addr >> 16) & 0xFF;
|
||||
xaddr[2] = (addr >> 8) & 0xFF;
|
||||
xaddr[3] = addr & 0xFF;
|
||||
}
|
||||
|
||||
ret = i2c_transfer(i2c->regs, I2C_WRITE, chip_addr << 1,
|
||||
&xaddr[4 - alen], alen, buffer, len, seq);
|
||||
if (ret) {
|
||||
debug("I2C write failed %d\n", ret);
|
||||
return -EIO;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nx_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
|
||||
{
|
||||
struct nx_i2c_bus *bus = dev_get_priv(dev);
|
||||
struct nx_i2c_regs *i2c = bus->regs;
|
||||
int ret;
|
||||
int i;
|
||||
|
||||
/* The power loss by the clock, only during on/off. */
|
||||
ret = i2c_set_clk(bus, 1);
|
||||
|
||||
if (!ret)
|
||||
/* Bus State(Busy) check */
|
||||
ret = i2c_is_busy(i2c);
|
||||
if (!ret) {
|
||||
for (i = 0; i < nmsgs; msg++, i++) {
|
||||
if (msg->flags & I2C_M_RD) {
|
||||
ret = nx_i2c_read(dev, msg->addr, 0, 0,
|
||||
msg->buf, msg->len, i);
|
||||
} else {
|
||||
ret = nx_i2c_write(dev, msg->addr, 0, 0,
|
||||
msg->buf, msg->len, i);
|
||||
}
|
||||
|
||||
if (ret) {
|
||||
debug("i2c_xfer: error sending\n");
|
||||
ret = -EREMOTEIO;
|
||||
}
|
||||
}
|
||||
|
||||
i2c_send_stop(bus);
|
||||
if (i2c_set_clk(bus, 0))
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
};
|
||||
|
||||
static int nx_i2c_probe_chip(struct udevice *dev, u32 chip_addr,
|
||||
u32 chip_flags)
|
||||
{
|
||||
int ret;
|
||||
struct nx_i2c_bus *bus = dev_get_priv(dev);
|
||||
|
||||
ret = i2c_set_clk(bus, 1);
|
||||
|
||||
if (!ret) {
|
||||
/*
|
||||
* Send Chip Address only
|
||||
* --> I2C transfer with data length and address length = 0.
|
||||
* If there is a Slave, i2c_transfer() returns 0 (acknowledge
|
||||
* transfer).
|
||||
* I2C_WRITE must be used in order Master Transmit Mode is
|
||||
* selected. Otherwise (in Master Receive Mode, I2C_READ)
|
||||
* sending the stop condition below is not working (SDA does
|
||||
* not transit to High).
|
||||
*/
|
||||
ret = i2c_transfer(bus->regs, I2C_WRITE, (uchar)chip_addr << 1,
|
||||
NULL, 0, NULL, 0, 0);
|
||||
|
||||
i2c_send_stop(bus);
|
||||
if (i2c_set_clk(bus, 0))
|
||||
ret = -EINVAL;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static const struct dm_i2c_ops nx_i2c_ops = {
|
||||
.xfer = nx_i2c_xfer,
|
||||
.probe_chip = nx_i2c_probe_chip,
|
||||
.set_bus_speed = nx_i2c_set_bus_speed,
|
||||
};
|
||||
|
||||
static const struct udevice_id nx_i2c_ids[] = {
|
||||
{ .compatible = "nexell,s5pxx18-i2c" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(i2c_nexell) = {
|
||||
.name = "i2c_nexell",
|
||||
.id = UCLASS_I2C,
|
||||
.of_match = nx_i2c_ids,
|
||||
.probe = nx_i2c_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct nx_i2c_bus),
|
||||
.ops = &nx_i2c_ops,
|
||||
};
|
|
@ -263,6 +263,14 @@ config MMC_DW_SNPS
|
|||
This selects support for Synopsys DesignWare Memory Card Interface driver
|
||||
extensions used in various Synopsys ARC devboards.
|
||||
|
||||
config NEXELL_DWMMC
|
||||
bool "Nexell SD/MMC controller support"
|
||||
depends on ARCH_NEXELL
|
||||
depends on MMC_DW
|
||||
depends on DM_MMC
|
||||
depends on PINCTRL_NEXELL
|
||||
default y
|
||||
|
||||
config MMC_MESON_GX
|
||||
bool "Meson GX EMMC controller support"
|
||||
depends on DM_MMC && BLK && ARCH_MESON
|
||||
|
|
|
@ -44,6 +44,7 @@ obj-$(CONFIG_SH_MMCIF) += sh_mmcif.o
|
|||
obj-$(CONFIG_SH_SDHI) += sh_sdhi.o
|
||||
obj-$(CONFIG_STM32_SDMMC2) += stm32_sdmmc2.o
|
||||
obj-$(CONFIG_JZ47XX_MMC) += jz_mmc.o
|
||||
obj-$(CONFIG_NEXELL_DWMMC) += nexell_dw_mmc.o
|
||||
|
||||
# SDHCI
|
||||
obj-$(CONFIG_MMC_SDHCI) += sdhci.o
|
||||
|
|
237
drivers/mmc/nexell_dw_mmc.c
Normal file
237
drivers/mmc/nexell_dw_mmc.c
Normal file
|
@ -0,0 +1,237 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* (C) Copyright 2016 Nexell
|
||||
* Youngbok, Park <park@nexell.co.kr>
|
||||
*
|
||||
* (C) Copyright 2019 Stefan Bosch <stefan_b@posteo.net>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <dt-structs.h>
|
||||
#include <dwmmc.h>
|
||||
#include <log.h>
|
||||
#include <syscon.h>
|
||||
#include <asm/arch/reset.h>
|
||||
#include <asm/arch/clk.h>
|
||||
|
||||
#define DWMCI_CLKSEL 0x09C
|
||||
#define DWMCI_SHIFT_0 0x0
|
||||
#define DWMCI_SHIFT_1 0x1
|
||||
#define DWMCI_SHIFT_2 0x2
|
||||
#define DWMCI_SHIFT_3 0x3
|
||||
#define DWMCI_SET_SAMPLE_CLK(x) (x)
|
||||
#define DWMCI_SET_DRV_CLK(x) ((x) << 16)
|
||||
#define DWMCI_SET_DIV_RATIO(x) ((x) << 24)
|
||||
#define DWMCI_CLKCTRL 0x114
|
||||
#define NX_MMC_CLK_DELAY(x, y, a, b) ((((x) & 0xFF) << 0) |\
|
||||
(((y) & 0x03) << 16) |\
|
||||
(((a) & 0xFF) << 8) |\
|
||||
(((b) & 0x03) << 24))
|
||||
|
||||
struct nexell_mmc_plat {
|
||||
struct mmc_config cfg;
|
||||
struct mmc mmc;
|
||||
};
|
||||
|
||||
struct nexell_dwmmc_priv {
|
||||
struct clk *clk;
|
||||
struct dwmci_host host;
|
||||
int fifo_size;
|
||||
bool fifo_mode;
|
||||
int frequency;
|
||||
u32 min_freq;
|
||||
u32 max_freq;
|
||||
int d_delay;
|
||||
int d_shift;
|
||||
int s_delay;
|
||||
int s_shift;
|
||||
bool mmcboost;
|
||||
};
|
||||
|
||||
struct clk *clk_get(const char *id);
|
||||
|
||||
static void nx_dw_mmc_clksel(struct dwmci_host *host)
|
||||
{
|
||||
/* host->priv is pointer to "struct udevice" */
|
||||
struct nexell_dwmmc_priv *priv = dev_get_priv(host->priv);
|
||||
u32 val;
|
||||
|
||||
if (priv->mmcboost)
|
||||
val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
|
||||
DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(1);
|
||||
else
|
||||
val = DWMCI_SET_SAMPLE_CLK(DWMCI_SHIFT_0) |
|
||||
DWMCI_SET_DRV_CLK(DWMCI_SHIFT_0) | DWMCI_SET_DIV_RATIO(3);
|
||||
|
||||
dwmci_writel(host, DWMCI_CLKSEL, val);
|
||||
}
|
||||
|
||||
static void nx_dw_mmc_reset(int ch)
|
||||
{
|
||||
int rst_id = RESET_ID_SDMMC0 + ch;
|
||||
|
||||
nx_rstcon_setrst(rst_id, 0);
|
||||
nx_rstcon_setrst(rst_id, 1);
|
||||
}
|
||||
|
||||
static void nx_dw_mmc_clk_delay(struct udevice *dev)
|
||||
{
|
||||
unsigned int delay;
|
||||
struct nexell_dwmmc_priv *priv = dev_get_priv(dev);
|
||||
struct dwmci_host *host = &priv->host;
|
||||
|
||||
delay = NX_MMC_CLK_DELAY(priv->d_delay,
|
||||
priv->d_shift, priv->s_delay, priv->s_shift);
|
||||
|
||||
writel(delay, (host->ioaddr + DWMCI_CLKCTRL));
|
||||
debug("%s: Values set: d_delay==%d, d_shift==%d, s_delay==%d, "
|
||||
"s_shift==%d\n", __func__, priv->d_delay, priv->d_shift,
|
||||
priv->s_delay, priv->s_shift);
|
||||
}
|
||||
|
||||
static unsigned int nx_dw_mmc_get_clk(struct dwmci_host *host, uint freq)
|
||||
{
|
||||
struct clk *clk;
|
||||
struct udevice *dev = host->priv;
|
||||
struct nexell_dwmmc_priv *priv = dev_get_priv(dev);
|
||||
|
||||
int index = host->dev_index;
|
||||
char name[50] = { 0, };
|
||||
|
||||
clk = priv->clk;
|
||||
if (!clk) {
|
||||
sprintf(name, "%s.%d", DEV_NAME_SDHC, index);
|
||||
clk = clk_get((const char *)name);
|
||||
if (!clk)
|
||||
return 0;
|
||||
priv->clk = clk;
|
||||
}
|
||||
|
||||
return clk_get_rate(clk) / 2;
|
||||
}
|
||||
|
||||
static unsigned long nx_dw_mmc_set_clk(struct dwmci_host *host,
|
||||
unsigned int rate)
|
||||
{
|
||||
struct clk *clk;
|
||||
char name[50] = { 0, };
|
||||
struct udevice *dev = host->priv;
|
||||
struct nexell_dwmmc_priv *priv = dev_get_priv(dev);
|
||||
|
||||
int index = host->dev_index;
|
||||
|
||||
clk = priv->clk;
|
||||
if (!clk) {
|
||||
sprintf(name, "%s.%d", DEV_NAME_SDHC, index);
|
||||
clk = clk_get((const char *)name);
|
||||
if (!clk) {
|
||||
debug("%s: clk_get(\"%s\") failed!\n", __func__, name);
|
||||
return 0;
|
||||
}
|
||||
priv->clk = clk;
|
||||
}
|
||||
|
||||
clk_disable(clk);
|
||||
rate = clk_set_rate(clk, rate);
|
||||
clk_enable(clk);
|
||||
|
||||
return rate;
|
||||
}
|
||||
|
||||
static int nexell_dwmmc_ofdata_to_platdata(struct udevice *dev)
|
||||
{
|
||||
struct nexell_dwmmc_priv *priv = dev_get_priv(dev);
|
||||
struct dwmci_host *host = &priv->host;
|
||||
int val = -1;
|
||||
|
||||
debug("%s\n", __func__);
|
||||
|
||||
host->name = dev->name;
|
||||
host->ioaddr = dev_read_addr_ptr(dev);
|
||||
host->buswidth = dev_read_u32_default(dev, "bus-width", 4);
|
||||
host->get_mmc_clk = nx_dw_mmc_get_clk;
|
||||
host->clksel = nx_dw_mmc_clksel;
|
||||
host->priv = dev;
|
||||
|
||||
val = dev_read_u32_default(dev, "index", -1);
|
||||
if (val < 0 || val > 2) {
|
||||
debug(" 'index' missing/invalid!\n");
|
||||
return -EINVAL;
|
||||
}
|
||||
host->dev_index = val;
|
||||
|
||||
priv->fifo_size = dev_read_u32_default(dev, "fifo-size", 0x20);
|
||||
priv->fifo_mode = dev_read_bool(dev, "fifo-mode");
|
||||
priv->frequency = dev_read_u32_default(dev, "frequency", 50000000);
|
||||
priv->max_freq = dev_read_u32_default(dev, "max-frequency", 50000000);
|
||||
priv->min_freq = 400000; /* 400 kHz */
|
||||
priv->d_delay = dev_read_u32_default(dev, "drive_dly", 0);
|
||||
priv->d_shift = dev_read_u32_default(dev, "drive_shift", 3);
|
||||
priv->s_delay = dev_read_u32_default(dev, "sample_dly", 0);
|
||||
priv->s_shift = dev_read_u32_default(dev, "sample_shift", 2);
|
||||
priv->mmcboost = dev_read_u32_default(dev, "mmcboost", 0);
|
||||
|
||||
debug(" index==%d, name==%s, ioaddr==0x%08x\n",
|
||||
host->dev_index, host->name, (u32)host->ioaddr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int nexell_dwmmc_probe(struct udevice *dev)
|
||||
{
|
||||
struct nexell_mmc_plat *plat = dev_get_platdata(dev);
|
||||
struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
|
||||
struct nexell_dwmmc_priv *priv = dev_get_priv(dev);
|
||||
struct dwmci_host *host = &priv->host;
|
||||
struct udevice *pwr_dev __maybe_unused;
|
||||
|
||||
host->fifoth_val = MSIZE(0x2) |
|
||||
RX_WMARK(priv->fifo_size / 2 - 1) |
|
||||
TX_WMARK(priv->fifo_size / 2);
|
||||
|
||||
host->fifo_mode = priv->fifo_mode;
|
||||
|
||||
dwmci_setup_cfg(&plat->cfg, host, priv->max_freq, priv->min_freq);
|
||||
host->mmc = &plat->mmc;
|
||||
host->mmc->priv = &priv->host;
|
||||
host->mmc->dev = dev;
|
||||
upriv->mmc = host->mmc;
|
||||
|
||||
if (nx_dw_mmc_set_clk(host, priv->frequency * 4) !=
|
||||
priv->frequency * 4) {
|
||||
debug("%s: nx_dw_mmc_set_clk(host, %d) failed!\n",
|
||||
__func__, priv->frequency * 4);
|
||||
return -EIO;
|
||||
}
|
||||
debug("%s: nx_dw_mmc_set_clk(host, %d) OK\n",
|
||||
__func__, priv->frequency * 4);
|
||||
|
||||
nx_dw_mmc_reset(host->dev_index);
|
||||
nx_dw_mmc_clk_delay(dev);
|
||||
|
||||
return dwmci_probe(dev);
|
||||
}
|
||||
|
||||
static int nexell_dwmmc_bind(struct udevice *dev)
|
||||
{
|
||||
struct nexell_mmc_plat *plat = dev_get_platdata(dev);
|
||||
|
||||
return dwmci_bind(dev, &plat->mmc, &plat->cfg);
|
||||
}
|
||||
|
||||
static const struct udevice_id nexell_dwmmc_ids[] = {
|
||||
{ .compatible = "nexell,nexell-dwmmc" },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(nexell_dwmmc_drv) = {
|
||||
.name = "nexell_dwmmc",
|
||||
.id = UCLASS_MMC,
|
||||
.of_match = nexell_dwmmc_ids,
|
||||
.ofdata_to_platdata = nexell_dwmmc_ofdata_to_platdata,
|
||||
.ops = &dm_dwmci_ops,
|
||||
.bind = nexell_dwmmc_bind,
|
||||
.probe = nexell_dwmmc_probe,
|
||||
.priv_auto_alloc_size = sizeof(struct nexell_dwmmc_priv),
|
||||
.platdata_auto_alloc_size = sizeof(struct nexell_mmc_plat),
|
||||
};
|
|
@ -1094,7 +1094,8 @@ static int mtk_phy_probe(struct udevice *dev)
|
|||
static void mtk_sgmii_init(struct mtk_eth_priv *priv)
|
||||
{
|
||||
/* Set SGMII GEN2 speed(2.5G) */
|
||||
clrsetbits_le32(priv->sgmii_base + SGMSYS_GEN2_SPEED,
|
||||
clrsetbits_le32(priv->sgmii_base + ((priv->soc == SOC_MT7622) ?
|
||||
SGMSYS_GEN2_SPEED : SGMSYS_GEN2_SPEED_V2),
|
||||
SGMSYS_SPEED_2500, SGMSYS_SPEED_2500);
|
||||
|
||||
/* Disable SGMII AN */
|
||||
|
|
|
@ -46,6 +46,7 @@
|
|||
#define SGMII_PHYA_PWD BIT(4)
|
||||
|
||||
#define SGMSYS_GEN2_SPEED 0x2028
|
||||
#define SGMSYS_GEN2_SPEED_V2 0x128
|
||||
#define SGMSYS_SPEED_2500 BIT(2)
|
||||
|
||||
/* Frame Engine Registers */
|
||||
|
|
|
@ -294,6 +294,7 @@ source "drivers/pinctrl/meson/Kconfig"
|
|||
source "drivers/pinctrl/mscc/Kconfig"
|
||||
source "drivers/pinctrl/mtmips/Kconfig"
|
||||
source "drivers/pinctrl/mvebu/Kconfig"
|
||||
source "drivers/pinctrl/nexell/Kconfig"
|
||||
source "drivers/pinctrl/nxp/Kconfig"
|
||||
source "drivers/pinctrl/renesas/Kconfig"
|
||||
source "drivers/pinctrl/rockchip/Kconfig"
|
||||
|
|
|
@ -21,6 +21,7 @@ obj-$(CONFIG_PINCTRL_MESON) += meson/
|
|||
obj-$(CONFIG_PINCTRL_MTK) += mediatek/
|
||||
obj-$(CONFIG_PINCTRL_MSCC) += mscc/
|
||||
obj-$(CONFIG_ARCH_MVEBU) += mvebu/
|
||||
obj-$(CONFIG_ARCH_NEXELL) += nexell/
|
||||
obj-$(CONFIG_PINCTRL_SINGLE) += pinctrl-single.o
|
||||
obj-$(CONFIG_PINCTRL_STI) += pinctrl-sti.o
|
||||
obj-$(CONFIG_PINCTRL_STM32) += pinctrl_stm32.o
|
||||
|
|
|
@ -262,6 +262,132 @@ static const struct mtk_pin_field_calc mt7623_pin_drv_range[] = {
|
|||
PIN_FIELD16(278, 278, 0xf70, 0x10, 8, 4),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7623_pin_pupd_range[] = {
|
||||
/* MSDC0 */
|
||||
PIN_FIELD16(111, 111, 0xd00, 0x10, 12, 1),
|
||||
PIN_FIELD16(112, 112, 0xd00, 0x10, 8, 1),
|
||||
PIN_FIELD16(113, 113, 0xd00, 0x10, 4, 1),
|
||||
PIN_FIELD16(114, 114, 0xd00, 0x10, 0, 1),
|
||||
PIN_FIELD16(115, 115, 0xd10, 0x10, 0, 1),
|
||||
PIN_FIELD16(116, 116, 0xcd0, 0x10, 8, 1),
|
||||
PIN_FIELD16(117, 117, 0xcc0, 0x10, 8, 1),
|
||||
PIN_FIELD16(118, 118, 0xcf0, 0x10, 12, 1),
|
||||
PIN_FIELD16(119, 119, 0xcf0, 0x10, 8, 1),
|
||||
PIN_FIELD16(120, 120, 0xcf0, 0x10, 4, 1),
|
||||
PIN_FIELD16(121, 121, 0xcf0, 0x10, 0, 1),
|
||||
/* MSDC1 */
|
||||
PIN_FIELD16(105, 105, 0xd40, 0x10, 8, 1),
|
||||
PIN_FIELD16(106, 106, 0xd30, 0x10, 8, 1),
|
||||
PIN_FIELD16(107, 107, 0xd60, 0x10, 0, 1),
|
||||
PIN_FIELD16(108, 108, 0xd60, 0x10, 10, 1),
|
||||
PIN_FIELD16(109, 109, 0xd60, 0x10, 4, 1),
|
||||
PIN_FIELD16(110, 110, 0xc60, 0x10, 12, 1),
|
||||
/* MSDC1 */
|
||||
PIN_FIELD16(85, 85, 0xda0, 0x10, 8, 1),
|
||||
PIN_FIELD16(86, 86, 0xd90, 0x10, 8, 1),
|
||||
PIN_FIELD16(87, 87, 0xdc0, 0x10, 0, 1),
|
||||
PIN_FIELD16(88, 88, 0xdc0, 0x10, 10, 1),
|
||||
PIN_FIELD16(89, 89, 0xdc0, 0x10, 4, 1),
|
||||
PIN_FIELD16(90, 90, 0xdc0, 0x10, 12, 1),
|
||||
/* MSDC0E */
|
||||
PIN_FIELD16(249, 249, 0x140, 0x10, 0, 1),
|
||||
PIN_FIELD16(250, 250, 0x130, 0x10, 12, 1),
|
||||
PIN_FIELD16(251, 251, 0x130, 0x10, 8, 1),
|
||||
PIN_FIELD16(252, 252, 0x130, 0x10, 4, 1),
|
||||
PIN_FIELD16(253, 253, 0x130, 0x10, 0, 1),
|
||||
PIN_FIELD16(254, 254, 0xf40, 0x10, 12, 1),
|
||||
PIN_FIELD16(255, 255, 0xf40, 0x10, 8, 1),
|
||||
PIN_FIELD16(256, 256, 0xf40, 0x10, 4, 1),
|
||||
PIN_FIELD16(257, 257, 0xf40, 0x10, 0, 1),
|
||||
PIN_FIELD16(258, 258, 0xcb0, 0x10, 8, 1),
|
||||
PIN_FIELD16(259, 259, 0xc90, 0x10, 8, 1),
|
||||
PIN_FIELD16(261, 261, 0x140, 0x10, 8, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7623_pin_r1_range[] = {
|
||||
/* MSDC0 */
|
||||
PIN_FIELD16(111, 111, 0xd00, 0x10, 13, 1),
|
||||
PIN_FIELD16(112, 112, 0xd00, 0x10, 9, 1),
|
||||
PIN_FIELD16(113, 113, 0xd00, 0x10, 5, 1),
|
||||
PIN_FIELD16(114, 114, 0xd00, 0x10, 1, 1),
|
||||
PIN_FIELD16(115, 115, 0xd10, 0x10, 1, 1),
|
||||
PIN_FIELD16(116, 116, 0xcd0, 0x10, 9, 1),
|
||||
PIN_FIELD16(117, 117, 0xcc0, 0x10, 9, 1),
|
||||
PIN_FIELD16(118, 118, 0xcf0, 0x10, 13, 1),
|
||||
PIN_FIELD16(119, 119, 0xcf0, 0x10, 9, 1),
|
||||
PIN_FIELD16(120, 120, 0xcf0, 0x10, 5, 1),
|
||||
PIN_FIELD16(121, 121, 0xcf0, 0x10, 1, 1),
|
||||
/* MSDC1 */
|
||||
PIN_FIELD16(105, 105, 0xd40, 0x10, 9, 1),
|
||||
PIN_FIELD16(106, 106, 0xd30, 0x10, 9, 1),
|
||||
PIN_FIELD16(107, 107, 0xd60, 0x10, 1, 1),
|
||||
PIN_FIELD16(108, 108, 0xd60, 0x10, 9, 1),
|
||||
PIN_FIELD16(109, 109, 0xd60, 0x10, 5, 1),
|
||||
PIN_FIELD16(110, 110, 0xc60, 0x10, 13, 1),
|
||||
/* MSDC2 */
|
||||
PIN_FIELD16(85, 85, 0xda0, 0x10, 9, 1),
|
||||
PIN_FIELD16(86, 86, 0xd90, 0x10, 9, 1),
|
||||
PIN_FIELD16(87, 87, 0xdc0, 0x10, 1, 1),
|
||||
PIN_FIELD16(88, 88, 0xdc0, 0x10, 9, 1),
|
||||
PIN_FIELD16(89, 89, 0xdc0, 0x10, 5, 1),
|
||||
PIN_FIELD16(90, 90, 0xdc0, 0x10, 13, 1),
|
||||
/* MSDC0E */
|
||||
PIN_FIELD16(249, 249, 0x140, 0x10, 1, 1),
|
||||
PIN_FIELD16(250, 250, 0x130, 0x10, 13, 1),
|
||||
PIN_FIELD16(251, 251, 0x130, 0x10, 9, 1),
|
||||
PIN_FIELD16(252, 252, 0x130, 0x10, 5, 1),
|
||||
PIN_FIELD16(253, 253, 0x130, 0x10, 1, 1),
|
||||
PIN_FIELD16(254, 254, 0xf40, 0x10, 13, 1),
|
||||
PIN_FIELD16(255, 255, 0xf40, 0x10, 9, 1),
|
||||
PIN_FIELD16(256, 256, 0xf40, 0x10, 5, 1),
|
||||
PIN_FIELD16(257, 257, 0xf40, 0x10, 1, 1),
|
||||
PIN_FIELD16(258, 258, 0xcb0, 0x10, 9, 1),
|
||||
PIN_FIELD16(259, 259, 0xc90, 0x10, 9, 1),
|
||||
PIN_FIELD16(261, 261, 0x140, 0x10, 9, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_field_calc mt7623_pin_r0_range[] = {
|
||||
/* MSDC0 */
|
||||
PIN_FIELD16(111, 111, 0xd00, 0x10, 14, 1),
|
||||
PIN_FIELD16(112, 112, 0xd00, 0x10, 10, 1),
|
||||
PIN_FIELD16(113, 113, 0xd00, 0x10, 6, 1),
|
||||
PIN_FIELD16(114, 114, 0xd00, 0x10, 2, 1),
|
||||
PIN_FIELD16(115, 115, 0xd10, 0x10, 2, 1),
|
||||
PIN_FIELD16(116, 116, 0xcd0, 0x10, 10, 1),
|
||||
PIN_FIELD16(117, 117, 0xcc0, 0x10, 10, 1),
|
||||
PIN_FIELD16(118, 118, 0xcf0, 0x10, 14, 1),
|
||||
PIN_FIELD16(119, 119, 0xcf0, 0x10, 10, 1),
|
||||
PIN_FIELD16(120, 120, 0xcf0, 0x10, 6, 1),
|
||||
PIN_FIELD16(121, 121, 0xcf0, 0x10, 2, 1),
|
||||
/* MSDC1 */
|
||||
PIN_FIELD16(105, 105, 0xd40, 0x10, 10, 1),
|
||||
PIN_FIELD16(106, 106, 0xd30, 0x10, 10, 1),
|
||||
PIN_FIELD16(107, 107, 0xd60, 0x10, 2, 1),
|
||||
PIN_FIELD16(108, 108, 0xd60, 0x10, 8, 1),
|
||||
PIN_FIELD16(109, 109, 0xd60, 0x10, 6, 1),
|
||||
PIN_FIELD16(110, 110, 0xc60, 0x10, 14, 1),
|
||||
/* MSDC2 */
|
||||
PIN_FIELD16(85, 85, 0xda0, 0x10, 10, 1),
|
||||
PIN_FIELD16(86, 86, 0xd90, 0x10, 10, 1),
|
||||
PIN_FIELD16(87, 87, 0xdc0, 0x10, 2, 1),
|
||||
PIN_FIELD16(88, 88, 0xdc0, 0x10, 8, 1),
|
||||
PIN_FIELD16(89, 89, 0xdc0, 0x10, 6, 1),
|
||||
PIN_FIELD16(90, 90, 0xdc0, 0x10, 14, 1),
|
||||
/* MSDC0E */
|
||||
PIN_FIELD16(249, 249, 0x140, 0x10, 2, 1),
|
||||
PIN_FIELD16(250, 250, 0x130, 0x10, 14, 1),
|
||||
PIN_FIELD16(251, 251, 0x130, 0x10, 10, 1),
|
||||
PIN_FIELD16(252, 252, 0x130, 0x10, 6, 1),
|
||||
PIN_FIELD16(253, 253, 0x130, 0x10, 2, 1),
|
||||
PIN_FIELD16(254, 254, 0xf40, 0x10, 14, 1),
|
||||
PIN_FIELD16(255, 255, 0xf40, 0x10, 10, 1),
|
||||
PIN_FIELD16(256, 256, 0xf40, 0x10, 6, 1),
|
||||
PIN_FIELD16(257, 257, 0xf40, 0x10, 5, 1),
|
||||
PIN_FIELD16(258, 258, 0xcb0, 0x10, 10, 1),
|
||||
PIN_FIELD16(259, 259, 0xc90, 0x10, 10, 1),
|
||||
PIN_FIELD16(261, 261, 0x140, 0x10, 10, 1),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_reg_calc mt7623_reg_cals[] = {
|
||||
[PINCTRL_PIN_REG_MODE] = MTK_RANGE(mt7623_pin_mode_range),
|
||||
[PINCTRL_PIN_REG_DIR] = MTK_RANGE(mt7623_pin_dir_range),
|
||||
|
@ -272,6 +398,9 @@ static const struct mtk_pin_reg_calc mt7623_reg_cals[] = {
|
|||
[PINCTRL_PIN_REG_PULLSEL] = MTK_RANGE(mt7623_pin_pullsel_range),
|
||||
[PINCTRL_PIN_REG_PULLEN] = MTK_RANGE(mt7623_pin_pullen_range),
|
||||
[PINCTRL_PIN_REG_DRV] = MTK_RANGE(mt7623_pin_drv_range),
|
||||
[PINCTRL_PIN_REG_PUPD] = MTK_RANGE(mt7623_pin_pupd_range),
|
||||
[PINCTRL_PIN_REG_R0] = MTK_RANGE(mt7623_pin_r0_range),
|
||||
[PINCTRL_PIN_REG_R1] = MTK_RANGE(mt7623_pin_r1_range),
|
||||
};
|
||||
|
||||
static const struct mtk_pin_desc mt7623_pins[] = {
|
||||
|
|
|
@ -296,7 +296,7 @@ static const struct pinconf_param mtk_conf_params[] = {
|
|||
};
|
||||
|
||||
|
||||
int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg)
|
||||
int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
||||
{
|
||||
int err, disable, pullup;
|
||||
|
||||
|
@ -323,12 +323,14 @@ int mtk_pinconf_bias_set_v0(struct udevice *dev, u32 pin, u32 arg)
|
|||
return 0;
|
||||
}
|
||||
|
||||
int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, u32 arg)
|
||||
int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, u32 arg, u32 val)
|
||||
{
|
||||
int err, disable, pullup;
|
||||
int err, disable, pullup, r0, r1;
|
||||
|
||||
disable = (arg == PIN_CONFIG_BIAS_DISABLE);
|
||||
pullup = (arg == PIN_CONFIG_BIAS_PULL_UP);
|
||||
r0 = !!(val & 1);
|
||||
r1 = !!(val & 2);
|
||||
|
||||
if (disable) {
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PULLEN, 0);
|
||||
|
@ -344,6 +346,13 @@ int mtk_pinconf_bias_set_v1(struct udevice *dev, u32 pin, u32 arg)
|
|||
return err;
|
||||
}
|
||||
|
||||
/* Also set PUPD/R0/R1 if the pin has them */
|
||||
err = mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_PUPD, !pullup);
|
||||
if (err != -EINVAL) {
|
||||
mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R0, r0);
|
||||
mtk_hw_set_value(dev, pin, PINCTRL_PIN_REG_R1, r1);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -419,9 +428,9 @@ static int mtk_pinconf_set(struct udevice *dev, unsigned int pin,
|
|||
case PIN_CONFIG_BIAS_PULL_UP:
|
||||
case PIN_CONFIG_BIAS_PULL_DOWN:
|
||||
if (rev == MTK_PINCTRL_V0)
|
||||
err = mtk_pinconf_bias_set_v0(dev, pin, param);
|
||||
err = mtk_pinconf_bias_set_v0(dev, pin, param, arg);
|
||||
else
|
||||
err = mtk_pinconf_bias_set_v1(dev, pin, param);
|
||||
err = mtk_pinconf_bias_set_v1(dev, pin, param, arg);
|
||||
if (err)
|
||||
goto err;
|
||||
break;
|
||||
|
|
|
@ -51,6 +51,9 @@ enum {
|
|||
PINCTRL_PIN_REG_PULLEN,
|
||||
PINCTRL_PIN_REG_PULLSEL,
|
||||
PINCTRL_PIN_REG_DRV,
|
||||
PINCTRL_PIN_REG_PUPD,
|
||||
PINCTRL_PIN_REG_R0,
|
||||
PINCTRL_PIN_REG_R1,
|
||||
PINCTRL_PIN_REG_MAX,
|
||||
};
|
||||
|
||||
|
|
18
drivers/pinctrl/nexell/Kconfig
Normal file
18
drivers/pinctrl/nexell/Kconfig
Normal file
|
@ -0,0 +1,18 @@
|
|||
if ARCH_NEXELL
|
||||
|
||||
config PINCTRL_NEXELL
|
||||
bool "Nexell pinctrl driver"
|
||||
help
|
||||
Support of pin multiplexing and pin configuration for Nexell
|
||||
SoCs.
|
||||
|
||||
config PINCTRL_NEXELL_S5PXX18
|
||||
bool "Nexell s5pxx18 SoC pinctrl driver"
|
||||
default y if ARCH_S5P4418 || ARCH_S5P6818
|
||||
depends on ARCH_NEXELL && PINCTRL_FULL
|
||||
select PINCTRL_NEXELL
|
||||
help
|
||||
Support of pin multiplexing and pin configuration for S5P4418
|
||||
and S5P6818 SoC.
|
||||
|
||||
endif
|
7
drivers/pinctrl/nexell/Makefile
Normal file
7
drivers/pinctrl/nexell/Makefile
Normal file
|
@ -0,0 +1,7 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2016 Nexell
|
||||
# Bongyu, KOO <freestyle@nexell.co.kr>
|
||||
|
||||
obj-$(CONFIG_PINCTRL_NEXELL) += pinctrl-nexell.o
|
||||
obj-$(CONFIG_PINCTRL_NEXELL_S5PXX18) += pinctrl-s5pxx18.o
|
66
drivers/pinctrl/nexell/pinctrl-nexell.c
Normal file
66
drivers/pinctrl/nexell/pinctrl-nexell.c
Normal file
|
@ -0,0 +1,66 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Pinctrl driver for Nexell SoCs
|
||||
* (C) Copyright 2016 Nexell
|
||||
* Bongyu, KOO <freestyle@nexell.co.kr>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include "pinctrl-nexell.h"
|
||||
#include "pinctrl-s5pxx18.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
/* given a pin-name, return the address of pin config registers */
|
||||
unsigned long pin_to_bank_base(struct udevice *dev, const char *pin_name,
|
||||
u32 *pin)
|
||||
{
|
||||
struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct nexell_pin_ctrl *pin_ctrl = priv->pin_ctrl;
|
||||
const struct nexell_pin_bank_data *bank_data = pin_ctrl->pin_banks;
|
||||
u32 nr_banks = pin_ctrl->nr_banks, idx = 0;
|
||||
char bank[10];
|
||||
|
||||
/*
|
||||
* The format of the pin name is <bank name>-<pin_number>.
|
||||
* Example: gpioa-4 (gpioa is the bank name and 4 is the pin number)
|
||||
*/
|
||||
while (pin_name[idx] != '-') {
|
||||
bank[idx] = pin_name[idx];
|
||||
idx++;
|
||||
}
|
||||
bank[idx] = '\0';
|
||||
*pin = (u32)simple_strtoul(&pin_name[++idx], NULL, 10);
|
||||
|
||||
/* lookup the pin bank data using the pin bank name */
|
||||
for (idx = 0; idx < nr_banks; idx++)
|
||||
if (!strcmp(bank, bank_data[idx].name))
|
||||
break;
|
||||
|
||||
return priv->base + bank_data[idx].offset;
|
||||
}
|
||||
|
||||
int nexell_pinctrl_probe(struct udevice *dev)
|
||||
{
|
||||
struct nexell_pinctrl_priv *priv;
|
||||
fdt_addr_t base;
|
||||
|
||||
priv = dev_get_priv(dev);
|
||||
if (!priv)
|
||||
return -EINVAL;
|
||||
|
||||
base = devfdt_get_addr(dev);
|
||||
if (base == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->base = base;
|
||||
|
||||
priv->pin_ctrl = (struct nexell_pin_ctrl *)dev_get_driver_data(dev);
|
||||
|
||||
s5pxx18_pinctrl_init(dev);
|
||||
|
||||
return 0;
|
||||
}
|
68
drivers/pinctrl/nexell/pinctrl-nexell.h
Normal file
68
drivers/pinctrl/nexell/pinctrl-nexell.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Pinctrl driver for Nexell SoCs
|
||||
* (C) Copyright 2016 Nexell
|
||||
* Bongyu, KOO <freestyle@nexell.co.kr>
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef __PINCTRL_NEXELL_H_
|
||||
#define __PINCTRL_NEXELL_H_
|
||||
|
||||
/**
|
||||
* struct nexell_pin_bank_data: represent a controller pin-bank data.
|
||||
* @offset: starting offset of the pin-bank registers.
|
||||
* @nr_pins: number of pins included in this bank.
|
||||
* @name: name to be prefixed for each pin in this pin bank.
|
||||
*/
|
||||
struct nexell_pin_bank_data {
|
||||
u32 offset;
|
||||
u8 nr_pins;
|
||||
const char *name;
|
||||
u8 type;
|
||||
};
|
||||
|
||||
#define NEXELL_PIN_BANK(pins, reg, id) \
|
||||
{ \
|
||||
.offset = reg, \
|
||||
.nr_pins = pins, \
|
||||
.name = id \
|
||||
}
|
||||
|
||||
/**
|
||||
* struct nexell_pin_ctrl: represent a pin controller.
|
||||
* @pin_banks: list of pin banks included in this controller.
|
||||
* @nr_banks: number of pin banks.
|
||||
*/
|
||||
struct nexell_pin_ctrl {
|
||||
const struct nexell_pin_bank_data *pin_banks;
|
||||
u32 nr_banks;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nexell_pinctrl_priv: nexell pin controller driver private data
|
||||
* @pin_ctrl: pin controller bank information.
|
||||
* @base: base address of the pin controller instance.
|
||||
*/
|
||||
struct nexell_pinctrl_priv {
|
||||
const struct nexell_pin_ctrl *pin_ctrl;
|
||||
unsigned long base;
|
||||
};
|
||||
|
||||
/**
|
||||
* struct nexell_pinctrl_config_data: configuration for a peripheral.
|
||||
* @offset: offset of the config registers in the controller.
|
||||
* @mask: value of the register to be masked with.
|
||||
* @value: new value to be programmed.
|
||||
*/
|
||||
struct nexell_pinctrl_config_data {
|
||||
const unsigned int offset;
|
||||
const unsigned int mask;
|
||||
const unsigned int value;
|
||||
};
|
||||
|
||||
unsigned long pin_to_bank_base(struct udevice *dev, const char *pin_name,
|
||||
u32 *pin);
|
||||
int nexell_pinctrl_probe(struct udevice *dev);
|
||||
|
||||
#endif /* __PINCTRL_NEXELL_H_ */
|
220
drivers/pinctrl/nexell/pinctrl-s5pxx18.c
Normal file
220
drivers/pinctrl/nexell/pinctrl-s5pxx18.c
Normal file
|
@ -0,0 +1,220 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Pinctrl driver for Nexell SoCs
|
||||
* (C) Copyright 2016 Nexell
|
||||
* Bongyu, KOO <freestyle@nexell.co.kr>
|
||||
*
|
||||
* (C) Copyright 2019 Stefan Bosch <stefan_b@posteo.net>
|
||||
*/
|
||||
|
||||
#include <common.h>
|
||||
#include <dm.h>
|
||||
#include <errno.h>
|
||||
#include <asm/io.h>
|
||||
#include <dm/pinctrl.h>
|
||||
#include <dm/root.h>
|
||||
#include "pinctrl-nexell.h"
|
||||
#include "pinctrl-s5pxx18.h"
|
||||
|
||||
DECLARE_GLOBAL_DATA_PTR;
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static 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);
|
||||
}
|
||||
|
||||
static int nx_gpio_open_module(void *base)
|
||||
{
|
||||
writel(0xFFFFFFFF, base + GPIOX_SLEW_DISABLE_DEFAULT);
|
||||
writel(0xFFFFFFFF, base + GPIOX_DRV1_DISABLE_DEFAULT);
|
||||
writel(0xFFFFFFFF, base + GPIOX_DRV0_DISABLE_DEFAULT);
|
||||
writel(0xFFFFFFFF, base + GPIOX_PULLSEL_DISABLE_DEFAULT);
|
||||
writel(0xFFFFFFFF, base + GPIOX_PULLENB_DISABLE_DEFAULT);
|
||||
return true;
|
||||
}
|
||||
|
||||
static void nx_gpio_set_pad_function(void *base, u32 pin, u32 padfunc)
|
||||
{
|
||||
u32 reg = (pin / 16) ? GPIOX_ALTFN1 : GPIOX_ALTFN0;
|
||||
|
||||
nx_gpio_set_bit2(base + reg, pin % 16, padfunc);
|
||||
}
|
||||
|
||||
static void nx_gpio_set_drive_strength(void *base, u32 pin, u32 drv)
|
||||
{
|
||||
nx_gpio_set_bit(base + GPIOX_DRV1, pin, (int)(((u32)drv >> 0) & 0x1));
|
||||
nx_gpio_set_bit(base + GPIOX_DRV0, pin, (int)(((u32)drv >> 1) & 0x1));
|
||||
}
|
||||
|
||||
static void nx_gpio_set_pull_mode(void *base, u32 pin, u32 mode)
|
||||
{
|
||||
if (mode == nx_gpio_pull_off) {
|
||||
nx_gpio_set_bit(base + GPIOX_PULLENB, pin, false);
|
||||
nx_gpio_set_bit(base + GPIOX_PULLSEL, pin, false);
|
||||
} else {
|
||||
nx_gpio_set_bit(base + GPIOX_PULLSEL,
|
||||
pin, (mode & 1 ? true : false));
|
||||
nx_gpio_set_bit(base + GPIOX_PULLENB, pin, true);
|
||||
}
|
||||
}
|
||||
|
||||
static void nx_alive_set_pullup(void *base, u32 pin, bool enable)
|
||||
{
|
||||
u32 PULLUP_MASK;
|
||||
|
||||
PULLUP_MASK = (1UL << pin);
|
||||
if (enable)
|
||||
writel(PULLUP_MASK, base + ALIVE_PADPULLUPSET);
|
||||
else
|
||||
writel(PULLUP_MASK, base + ALIVE_PADPULLUPRST);
|
||||
}
|
||||
|
||||
static int s5pxx18_pinctrl_gpio_init(struct udevice *dev)
|
||||
{
|
||||
struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
|
||||
unsigned long reg = priv->base;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < ctrl->nr_banks - 1; i++) /* except alive bank */
|
||||
nx_gpio_open_module((void *)(reg + ctrl->pin_banks[i].offset));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int s5pxx18_pinctrl_alive_init(struct udevice *dev)
|
||||
{
|
||||
struct nexell_pinctrl_priv *priv = dev_get_priv(dev);
|
||||
const struct nexell_pin_ctrl *ctrl = priv->pin_ctrl;
|
||||
unsigned long reg = priv->base;
|
||||
|
||||
reg += ctrl->pin_banks[ctrl->nr_banks - 1].offset;
|
||||
|
||||
writel(1, reg + ALIVE_PWRGATE);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int s5pxx18_pinctrl_init(struct udevice *dev)
|
||||
{
|
||||
s5pxx18_pinctrl_gpio_init(dev);
|
||||
s5pxx18_pinctrl_alive_init(dev);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int is_pin_alive(const char *name)
|
||||
{
|
||||
return !strncmp(name, "alive", 5);
|
||||
}
|
||||
|
||||
/**
|
||||
* s5pxx18_pinctrl_set_state: configure a pin state.
|
||||
* dev: the pinctrl device to be configured.
|
||||
* config: the state to be configured.
|
||||
*/
|
||||
static int s5pxx18_pinctrl_set_state(struct udevice *dev,
|
||||
struct udevice *config)
|
||||
{
|
||||
unsigned int count, idx, pin;
|
||||
unsigned int pinfunc, pinpud, pindrv;
|
||||
unsigned long reg;
|
||||
const char *name;
|
||||
int ret;
|
||||
|
||||
/*
|
||||
* refer to the following document for the pinctrl bindings
|
||||
* doc/device-tree-bindings/pinctrl/nexell,s5pxx18-pinctrl.txt
|
||||
*/
|
||||
count = dev_read_string_count(config, "pins");
|
||||
|
||||
if (count <= 0)
|
||||
return -EINVAL;
|
||||
|
||||
pinfunc = dev_read_s32_default(config, "pin-function", -1);
|
||||
pinpud = dev_read_s32_default(config, "pin-pull", -1);
|
||||
pindrv = dev_read_s32_default(config, "pin-strength", -1);
|
||||
|
||||
for (idx = 0; idx < count; idx++) {
|
||||
ret = dev_read_string_index(config, "pins", idx, &name);
|
||||
if (ret)
|
||||
return ret;
|
||||
if (!name)
|
||||
continue;
|
||||
reg = pin_to_bank_base(dev, name, &pin);
|
||||
|
||||
if (is_pin_alive(name)) {
|
||||
/* pin pull up/down */
|
||||
if (pinpud != -1)
|
||||
nx_alive_set_pullup((void *)reg, pin,
|
||||
pinpud & 1);
|
||||
continue;
|
||||
}
|
||||
|
||||
/* pin function */
|
||||
if (pinfunc != -1)
|
||||
nx_gpio_set_pad_function((void *)reg, pin, pinfunc);
|
||||
|
||||
/* pin pull up/down/off */
|
||||
if (pinpud != -1)
|
||||
nx_gpio_set_pull_mode((void *)reg, pin, pinpud);
|
||||
|
||||
/* pin drive strength */
|
||||
if (pindrv != -1)
|
||||
nx_gpio_set_drive_strength((void *)reg, pin, pindrv);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pinctrl_ops s5pxx18_pinctrl_ops = {
|
||||
.set_state = s5pxx18_pinctrl_set_state,
|
||||
};
|
||||
|
||||
/* pin banks of s5pxx18 pin-controller */
|
||||
static const struct nexell_pin_bank_data s5pxx18_pin_banks[] = {
|
||||
NEXELL_PIN_BANK(32, 0xA000, "gpioa"),
|
||||
NEXELL_PIN_BANK(32, 0xB000, "gpiob"),
|
||||
NEXELL_PIN_BANK(32, 0xC000, "gpioc"),
|
||||
NEXELL_PIN_BANK(32, 0xD000, "gpiod"),
|
||||
NEXELL_PIN_BANK(32, 0xE000, "gpioe"),
|
||||
NEXELL_PIN_BANK(6, 0x0800, "alive"),
|
||||
};
|
||||
|
||||
const struct nexell_pin_ctrl s5pxx18_pin_ctrl[] = {
|
||||
{
|
||||
/* pin-controller data */
|
||||
.pin_banks = s5pxx18_pin_banks,
|
||||
.nr_banks = ARRAY_SIZE(s5pxx18_pin_banks),
|
||||
},
|
||||
};
|
||||
|
||||
static const struct udevice_id s5pxx18_pinctrl_ids[] = {
|
||||
{ .compatible = "nexell,s5pxx18-pinctrl",
|
||||
.data = (ulong)s5pxx18_pin_ctrl },
|
||||
{ }
|
||||
};
|
||||
|
||||
U_BOOT_DRIVER(pinctrl_s5pxx18) = {
|
||||
.name = "pinctrl_s5pxx18",
|
||||
.id = UCLASS_PINCTRL,
|
||||
.of_match = s5pxx18_pinctrl_ids,
|
||||
.priv_auto_alloc_size = sizeof(struct nexell_pinctrl_priv),
|
||||
.ops = &s5pxx18_pinctrl_ops,
|
||||
.probe = nexell_pinctrl_probe,
|
||||
.flags = DM_FLAG_PRE_RELOC
|
||||
};
|
53
drivers/pinctrl/nexell/pinctrl-s5pxx18.h
Normal file
53
drivers/pinctrl/nexell/pinctrl-s5pxx18.h
Normal file
|
@ -0,0 +1,53 @@
|
|||
/* SPDX-License-Identifier: GPL-2.0+
|
||||
*
|
||||
* Pinctrl driver for Nexell SoCs
|
||||
* (C) Copyright 2016 Nexell
|
||||
* Bongyu, KOO <freestyle@nexell.co.kr>
|
||||
*/
|
||||
|
||||
#ifndef __PINCTRL_S5PXX18_H_
|
||||
#define __PINCTRL_S5PXX18_H_
|
||||
|
||||
#include <linux/types.h>
|
||||
#include <asm/io.h>
|
||||
|
||||
#define GPIOX_ALTFN0 0x20
|
||||
#define GPIOX_ALTFN1 0x24
|
||||
#define GPIOX_DRV1 0x48
|
||||
#define GPIOX_DRV0 0x50
|
||||
#define GPIOX_PULLSEL 0x58
|
||||
#define GPIOX_PULLENB 0x60
|
||||
|
||||
#define GPIOX_SLEW_DISABLE_DEFAULT 0x44
|
||||
#define GPIOX_DRV1_DISABLE_DEFAULT 0x4C
|
||||
#define GPIOX_DRV0_DISABLE_DEFAULT 0x54
|
||||
#define GPIOX_PULLSEL_DISABLE_DEFAULT 0x5C
|
||||
#define GPIOX_PULLENB_DISABLE_DEFAULT 0x64
|
||||
|
||||
#define ALIVE_PWRGATE 0x0
|
||||
#define ALIVE_PADPULLUPRST 0x80
|
||||
#define ALIVE_PADPULLUPSET 0x84
|
||||
#define ALIVE_PADPULLUPREAD 0x88
|
||||
|
||||
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 s5pxx18_pinctrl_init(struct udevice *dev);
|
||||
#endif /* __PINCTRL_S5PXX18_H_ */
|
|
@ -61,6 +61,7 @@ struct msm_serial_data {
|
|||
phys_addr_t base;
|
||||
unsigned chars_cnt; /* number of buffered chars */
|
||||
uint32_t chars_buf; /* buffered chars */
|
||||
uint32_t clk_bit_rate; /* data mover mode bit rate register value */
|
||||
};
|
||||
|
||||
static int msm_serial_fetch(struct udevice *dev)
|
||||
|
@ -190,7 +191,7 @@ static int msm_uart_clk_init(struct udevice *dev)
|
|||
|
||||
static void uart_dm_init(struct msm_serial_data *priv)
|
||||
{
|
||||
writel(UART_DM_CLK_RX_TX_BIT_RATE, priv->base + UARTDM_CSR);
|
||||
writel(priv->clk_bit_rate, priv->base + UARTDM_CSR);
|
||||
writel(0x0, priv->base + UARTDM_MR1);
|
||||
writel(MSM_BOOT_UART_DM_8_N_1_MODE, priv->base + UARTDM_MR2);
|
||||
writel(MSM_BOOT_UART_DM_CMD_RESET_RX, priv->base + UARTDM_CR);
|
||||
|
@ -223,6 +224,9 @@ static int msm_serial_ofdata_to_platdata(struct udevice *dev)
|
|||
if (priv->base == FDT_ADDR_T_NONE)
|
||||
return -EINVAL;
|
||||
|
||||
priv->clk_bit_rate = fdtdec_get_int(gd->fdt_blob, dev_of_offset(dev),
|
||||
"bit-rate", UART_DM_CLK_RX_TX_BIT_RATE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -644,6 +644,16 @@ source "drivers/video/bridge/Kconfig"
|
|||
|
||||
source "drivers/video/imx/Kconfig"
|
||||
|
||||
config VIDEO_NX
|
||||
bool "Enable video support on Nexell SoC"
|
||||
depends on ARCH_S5P6818 || ARCH_S5P4418
|
||||
help
|
||||
Nexell SoC supports many video output options including eDP and
|
||||
HDMI. This option enables this support which can be used on devices
|
||||
which have an eDP display connected.
|
||||
|
||||
source "drivers/video/nexell/Kconfig"
|
||||
|
||||
config VIDEO
|
||||
bool "Enable legacy video support"
|
||||
depends on !DM_VIDEO
|
||||
|
|
|
@ -62,6 +62,7 @@ obj-${CONFIG_VIDEO_MIPI_DSI} += mipi_dsi.o
|
|||
obj-$(CONFIG_VIDEO_MVEBU) += mvebu_lcd.o
|
||||
obj-$(CONFIG_VIDEO_MX3) += mx3fb.o videomodes.o
|
||||
obj-$(CONFIG_VIDEO_MXS) += mxsfb.o videomodes.o
|
||||
obj-$(CONFIG_VIDEO_NX) += nexell_display.o videomodes.o nexell/
|
||||
obj-$(CONFIG_VIDEO_OMAP3) += omap3_dss.o
|
||||
obj-$(CONFIG_VIDEO_DSI_HOST_SANDBOX) += sandbox_dsi_host.o
|
||||
obj-$(CONFIG_VIDEO_SANDBOX_SDL) += sandbox_sdl.o
|
||||
|
|
27
drivers/video/nexell/Kconfig
Normal file
27
drivers/video/nexell/Kconfig
Normal file
|
@ -0,0 +1,27 @@
|
|||
if VIDEO_NX
|
||||
|
||||
menu "LCD select"
|
||||
|
||||
config VIDEO_NX_RGB
|
||||
bool "RGB LCD"
|
||||
help
|
||||
Support for RGB lcd output.
|
||||
|
||||
config VIDEO_NX_LVDS
|
||||
bool "LVDS LCD"
|
||||
help
|
||||
Support for LVDS lcd output.
|
||||
|
||||
config VIDEO_NX_MIPI
|
||||
bool "MiPi"
|
||||
help
|
||||
Support for MiPi lcd output.
|
||||
|
||||
config VIDEO_NX_HDMI
|
||||
bool "HDMI"
|
||||
help
|
||||
Support for hdmi output.
|
||||
|
||||
endmenu
|
||||
|
||||
endif
|
12
drivers/video/nexell/Makefile
Normal file
12
drivers/video/nexell/Makefile
Normal file
|
@ -0,0 +1,12 @@
|
|||
# SPDX-License-Identifier: GPL-2.0+
|
||||
#
|
||||
# (C) Copyright 2016 Nexell
|
||||
# Junghyun, kim<jhkim@nexell.co.kr>
|
||||
|
||||
obj-$(CONFIG_VIDEO_NX) += s5pxx18_dp.o
|
||||
obj-$(CONFIG_VIDEO_NX) += soc/
|
||||
|
||||
obj-$(CONFIG_VIDEO_NX_RGB) += s5pxx18_dp_rgb.o
|
||||
obj-$(CONFIG_VIDEO_NX_LVDS) += s5pxx18_dp_lvds.o
|
||||
obj-$(CONFIG_VIDEO_NX_MIPI) += s5pxx18_dp_mipi.o
|
||||
obj-$(CONFIG_VIDEO_NX_HDMI) += s5pxx18_dp_hdmi.o
|
341
drivers/video/nexell/s5pxx18_dp.c
Normal file
341
drivers/video/nexell/s5pxx18_dp.c
Normal file
|
@ -0,0 +1,341 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2016 Nexell Co., Ltd.
|
||||
*
|
||||
* Author: junghyun, kim <jhkim@nexell.co.kr>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <log.h>
|
||||
#include <asm/arch/reset.h>
|
||||
#include <asm/arch/nexell.h>
|
||||
#include <asm/arch/display.h>
|
||||
|
||||
#include "soc/s5pxx18_soc_disptop.h"
|
||||
#include "soc/s5pxx18_soc_dpc.h"
|
||||
#include "soc/s5pxx18_soc_mlc.h"
|
||||
|
||||
#define MLC_LAYER_RGB_0 0 /* number of RGB layer 0 */
|
||||
#define MLC_LAYER_RGB_1 1 /* number of RGB layer 1 */
|
||||
#define MLC_LAYER_VIDEO 3 /* number of Video layer: 3 = VIDEO */
|
||||
|
||||
#define __io_address(a) (void *)(uintptr_t)(a)
|
||||
|
||||
void dp_control_init(int module)
|
||||
{
|
||||
void *base;
|
||||
|
||||
/* top */
|
||||
base = __io_address(nx_disp_top_get_physical_address());
|
||||
nx_disp_top_set_base_address(base);
|
||||
|
||||
/* control */
|
||||
base = __io_address(nx_dpc_get_physical_address(module));
|
||||
nx_dpc_set_base_address(module, base);
|
||||
|
||||
/* top controller */
|
||||
nx_rstcon_setrst(RESET_ID_DISP_TOP, RSTCON_ASSERT);
|
||||
nx_rstcon_setrst(RESET_ID_DISP_TOP, RSTCON_NEGATE);
|
||||
|
||||
/* display controller */
|
||||
nx_rstcon_setrst(RESET_ID_DISPLAY, RSTCON_ASSERT);
|
||||
nx_rstcon_setrst(RESET_ID_DISPLAY, RSTCON_NEGATE);
|
||||
|
||||
nx_dpc_set_clock_pclk_mode(module, nx_pclkmode_always);
|
||||
}
|
||||
|
||||
int dp_control_setup(int module,
|
||||
struct dp_sync_info *sync, struct dp_ctrl_info *ctrl)
|
||||
{
|
||||
unsigned int out_format;
|
||||
unsigned int delay_mask;
|
||||
int rgb_pvd = 0, hsync_cp1 = 7, vsync_fram = 7, de_cp2 = 7;
|
||||
int v_vso = 1, v_veo = 1, e_vso = 1, e_veo = 1;
|
||||
|
||||
int interlace = 0;
|
||||
int invert_field;
|
||||
int swap_rb;
|
||||
unsigned int yc_order;
|
||||
int vck_select;
|
||||
int vclk_invert;
|
||||
int emb_sync;
|
||||
|
||||
enum nx_dpc_dither r_dither, g_dither, b_dither;
|
||||
int rgb_mode = 0;
|
||||
|
||||
if (NULL == sync || NULL == ctrl) {
|
||||
debug("error, dp.%d not set sync or pad clock info !!!\n",
|
||||
module);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
out_format = ctrl->out_format;
|
||||
delay_mask = ctrl->delay_mask;
|
||||
interlace = sync->interlace;
|
||||
invert_field = ctrl->invert_field;
|
||||
swap_rb = ctrl->swap_RB;
|
||||
yc_order = ctrl->yc_order;
|
||||
vck_select = ctrl->vck_select;
|
||||
vclk_invert = ctrl->clk_inv_lv0 | ctrl->clk_inv_lv1;
|
||||
emb_sync = (out_format == DPC_FORMAT_CCIR656 ? 1 : 0);
|
||||
|
||||
/* set delay mask */
|
||||
if (delay_mask & DP_SYNC_DELAY_RGB_PVD)
|
||||
rgb_pvd = ctrl->d_rgb_pvd;
|
||||
if (delay_mask & DP_SYNC_DELAY_HSYNC_CP1)
|
||||
hsync_cp1 = ctrl->d_hsync_cp1;
|
||||
if (delay_mask & DP_SYNC_DELAY_VSYNC_FRAM)
|
||||
vsync_fram = ctrl->d_vsync_fram;
|
||||
if (delay_mask & DP_SYNC_DELAY_DE_CP)
|
||||
de_cp2 = ctrl->d_de_cp2;
|
||||
|
||||
if (ctrl->vs_start_offset != 0 ||
|
||||
ctrl->vs_end_offset != 0 ||
|
||||
ctrl->ev_start_offset != 0 || ctrl->ev_end_offset != 0) {
|
||||
v_vso = ctrl->vs_start_offset;
|
||||
v_veo = ctrl->vs_end_offset;
|
||||
e_vso = ctrl->ev_start_offset;
|
||||
e_veo = ctrl->ev_end_offset;
|
||||
}
|
||||
|
||||
if (nx_dpc_format_rgb555 == out_format ||
|
||||
nx_dpc_format_mrgb555a == out_format ||
|
||||
nx_dpc_format_mrgb555b == out_format) {
|
||||
r_dither = nx_dpc_dither_5bit;
|
||||
g_dither = nx_dpc_dither_5bit;
|
||||
b_dither = nx_dpc_dither_5bit;
|
||||
rgb_mode = 1;
|
||||
} else if (nx_dpc_format_rgb565 == out_format ||
|
||||
nx_dpc_format_mrgb565 == out_format) {
|
||||
r_dither = nx_dpc_dither_5bit;
|
||||
b_dither = nx_dpc_dither_5bit;
|
||||
g_dither = nx_dpc_dither_6bit, rgb_mode = 1;
|
||||
} else if ((nx_dpc_format_rgb666 == out_format) ||
|
||||
(nx_dpc_format_mrgb666 == out_format)) {
|
||||
r_dither = nx_dpc_dither_6bit;
|
||||
g_dither = nx_dpc_dither_6bit;
|
||||
b_dither = nx_dpc_dither_6bit;
|
||||
rgb_mode = 1;
|
||||
} else {
|
||||
r_dither = nx_dpc_dither_bypass;
|
||||
g_dither = nx_dpc_dither_bypass;
|
||||
b_dither = nx_dpc_dither_bypass;
|
||||
rgb_mode = 1;
|
||||
}
|
||||
|
||||
/* CLKGEN0/1 */
|
||||
nx_dpc_set_clock_source(module, 0, ctrl->clk_src_lv0 == 3 ?
|
||||
6 : ctrl->clk_src_lv0);
|
||||
nx_dpc_set_clock_divisor(module, 0, ctrl->clk_div_lv0);
|
||||
nx_dpc_set_clock_source(module, 1, ctrl->clk_src_lv1);
|
||||
nx_dpc_set_clock_divisor(module, 1, ctrl->clk_div_lv1);
|
||||
nx_dpc_set_clock_out_delay(module, 0, ctrl->clk_delay_lv0);
|
||||
nx_dpc_set_clock_out_delay(module, 1, ctrl->clk_delay_lv1);
|
||||
|
||||
/* LCD out */
|
||||
nx_dpc_set_mode(module, out_format, interlace, invert_field,
|
||||
rgb_mode, swap_rb, yc_order, emb_sync, emb_sync,
|
||||
vck_select, vclk_invert, 0);
|
||||
nx_dpc_set_hsync(module, sync->h_active_len, sync->h_sync_width,
|
||||
sync->h_front_porch, sync->h_back_porch,
|
||||
sync->h_sync_invert);
|
||||
nx_dpc_set_vsync(module, sync->v_active_len, sync->v_sync_width,
|
||||
sync->v_front_porch, sync->v_back_porch,
|
||||
sync->v_sync_invert, sync->v_active_len,
|
||||
sync->v_sync_width, sync->v_front_porch,
|
||||
sync->v_back_porch);
|
||||
nx_dpc_set_vsync_offset(module, v_vso, v_veo, e_vso, e_veo);
|
||||
nx_dpc_set_delay(module, rgb_pvd, hsync_cp1, vsync_fram, de_cp2);
|
||||
nx_dpc_set_dither(module, r_dither, g_dither, b_dither);
|
||||
|
||||
if (IS_ENABLED(CONFIG_MACH_S5P6818)) {
|
||||
/* Set TFT_CLKCTRL (offset : 1030h)
|
||||
* Field name : DPC0_CLKCTRL, DPC1_CLKCRL
|
||||
* Default value : clk_inv_lv0/1 = 0 : PADCLK_InvCLK
|
||||
* Invert case : clk_inv_lv0/1 = 1 : PADCLK_CLK
|
||||
*/
|
||||
if (module == 0 && ctrl->clk_inv_lv0)
|
||||
nx_disp_top_set_padclock(padmux_primary_mlc,
|
||||
padclk_clk);
|
||||
if (module == 1 && ctrl->clk_inv_lv1)
|
||||
nx_disp_top_set_padclock(padmux_secondary_mlc,
|
||||
padclk_clk);
|
||||
}
|
||||
|
||||
debug("%s: dp.%d x:%4d, hf:%3d, hb:%3d, hs:%3d, hi=%d\n",
|
||||
__func__, module, sync->h_active_len, sync->h_front_porch,
|
||||
sync->h_back_porch, sync->h_sync_width, sync->h_sync_invert);
|
||||
debug("%s: dp.%d y:%4d, vf:%3d, vb:%3d, vs:%3d, vi=%d\n",
|
||||
__func__, module, sync->v_active_len, sync->v_front_porch,
|
||||
sync->v_back_porch, sync->v_sync_width, sync->h_sync_invert);
|
||||
debug("%s: dp.%d ck.0:%d:%d:%d, ck.1:%d:%d:%d\n",
|
||||
__func__, module,
|
||||
ctrl->clk_src_lv0, ctrl->clk_div_lv0, ctrl->clk_inv_lv0,
|
||||
ctrl->clk_src_lv1, ctrl->clk_div_lv1, ctrl->clk_inv_lv1);
|
||||
debug("%s: dp.%d vs:%d, ve:%d, es:%d, ee:%d\n",
|
||||
__func__, module, v_vso, v_veo, e_vso, e_veo);
|
||||
debug("%s: dp.%d delay RGB:%d, hs:%d, vs:%d, de:%d, fmt:0x%x\n",
|
||||
__func__, module, rgb_pvd, hsync_cp1, vsync_fram, de_cp2,
|
||||
out_format);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dp_control_enable(int module, int on)
|
||||
{
|
||||
debug("%s: dp.%d top %s\n", __func__, module, on ? "ON" : "OFF");
|
||||
|
||||
nx_dpc_set_dpc_enable(module, on);
|
||||
nx_dpc_set_clock_divisor_enable(module, on);
|
||||
}
|
||||
|
||||
void dp_plane_init(int module)
|
||||
{
|
||||
void *base = __io_address(nx_mlc_get_physical_address(module));
|
||||
|
||||
nx_mlc_set_base_address(module, base);
|
||||
nx_mlc_set_clock_pclk_mode(module, nx_pclkmode_always);
|
||||
nx_mlc_set_clock_bclk_mode(module, nx_bclkmode_always);
|
||||
}
|
||||
|
||||
int dp_plane_screen_setup(int module, struct dp_plane_top *top)
|
||||
{
|
||||
int width = top->screen_width;
|
||||
int height = top->screen_height;
|
||||
int interlace = top->interlace;
|
||||
int video_prior = top->video_prior;
|
||||
unsigned int bg_color = top->back_color;
|
||||
|
||||
/* MLC TOP layer */
|
||||
nx_mlc_set_screen_size(module, width, height);
|
||||
nx_mlc_set_layer_priority(module, video_prior);
|
||||
nx_mlc_set_background(module, bg_color);
|
||||
nx_mlc_set_field_enable(module, interlace);
|
||||
nx_mlc_set_rgblayer_gama_table_power_mode(module, 0, 0, 0);
|
||||
nx_mlc_set_rgblayer_gama_table_sleep_mode(module, 1, 1, 1);
|
||||
nx_mlc_set_rgblayer_gamma_enable(module, 0);
|
||||
nx_mlc_set_dither_enable_when_using_gamma(module, 0);
|
||||
nx_mlc_set_gamma_priority(module, 0);
|
||||
nx_mlc_set_top_power_mode(module, 1);
|
||||
nx_mlc_set_top_sleep_mode(module, 0);
|
||||
|
||||
debug("%s: dp.%d screen %dx%d, %s, priority:%d, bg:0x%x\n",
|
||||
__func__, module, width, height,
|
||||
interlace ? "Interlace" : "Progressive",
|
||||
video_prior, bg_color);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dp_plane_screen_enable(int module, int on)
|
||||
{
|
||||
/* enable top screen */
|
||||
nx_mlc_set_mlc_enable(module, on);
|
||||
nx_mlc_set_top_dirty_flag(module);
|
||||
debug("%s: dp.%d top %s\n", __func__, module, on ? "ON" : "OFF");
|
||||
}
|
||||
|
||||
int dp_plane_layer_setup(int module, struct dp_plane_info *plane)
|
||||
{
|
||||
int sx = plane->left;
|
||||
int sy = plane->top;
|
||||
int ex = sx + plane->width - 1;
|
||||
int ey = sy + plane->height - 1;
|
||||
int pixel_byte = plane->pixel_byte;
|
||||
int mem_lock_size = 16; /* fix mem lock size */
|
||||
int layer = plane->layer;
|
||||
unsigned int format = plane->format;
|
||||
|
||||
if (!plane->enable)
|
||||
return -EINVAL;
|
||||
|
||||
/* MLC layer */
|
||||
nx_mlc_set_lock_size(module, layer, mem_lock_size);
|
||||
nx_mlc_set_alpha_blending(module, layer, 0, 15);
|
||||
nx_mlc_set_transparency(module, layer, 0, 0);
|
||||
nx_mlc_set_color_inversion(module, layer, 0, 0);
|
||||
nx_mlc_set_rgblayer_invalid_position(module, layer, 0, 0, 0, 0, 0, 0);
|
||||
nx_mlc_set_rgblayer_invalid_position(module, layer, 1, 0, 0, 0, 0, 0);
|
||||
nx_mlc_set_format_rgb(module, layer, format);
|
||||
nx_mlc_set_position(module, layer, sx, sy, ex, ey);
|
||||
nx_mlc_set_rgblayer_stride(module, layer, pixel_byte,
|
||||
plane->width * pixel_byte);
|
||||
nx_mlc_set_rgblayer_address(module, layer, plane->fb_base);
|
||||
|
||||
debug("%s: dp.%d.%d %d * %d, %dbpp, fmt:0x%x\n",
|
||||
__func__, module, layer, plane->width, plane->height,
|
||||
pixel_byte * 8, format);
|
||||
debug("%s: b:0x%x, l:%d, t:%d, r:%d, b:%d, hs:%d, vs:%d\n",
|
||||
__func__, plane->fb_base, sx, sy, ex, ey,
|
||||
plane->width * pixel_byte, pixel_byte);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dp_plane_set_enable(int module, int layer, int on)
|
||||
{
|
||||
int hl, hc;
|
||||
int vl, vc;
|
||||
|
||||
debug("%s: dp.%d.%d %s:%s\n",
|
||||
__func__, module, layer,
|
||||
layer == MLC_LAYER_VIDEO ? "Video" : "RGB",
|
||||
on ? "ON" : "OFF");
|
||||
|
||||
if (layer != MLC_LAYER_VIDEO) {
|
||||
nx_mlc_set_layer_enable(module, layer, on);
|
||||
nx_mlc_set_dirty_flag(module, layer);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* video layer */
|
||||
if (on) {
|
||||
nx_mlc_set_video_layer_line_buffer_power_mode(module, 1);
|
||||
nx_mlc_set_video_layer_line_buffer_sleep_mode(module, 0);
|
||||
nx_mlc_set_layer_enable(module, layer, 1);
|
||||
nx_mlc_set_dirty_flag(module, layer);
|
||||
} else {
|
||||
nx_mlc_set_layer_enable(module, layer, 0);
|
||||
nx_mlc_set_dirty_flag(module, layer);
|
||||
nx_mlc_get_video_layer_scale_filter(module,
|
||||
&hl, &hc, &vl, &vc);
|
||||
if (hl || hc || vl || vc)
|
||||
nx_mlc_set_video_layer_scale_filter(module, 0, 0, 0, 0);
|
||||
nx_mlc_set_video_layer_line_buffer_power_mode(module, 0);
|
||||
nx_mlc_set_video_layer_line_buffer_sleep_mode(module, 1);
|
||||
nx_mlc_set_dirty_flag(module, layer);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void dp_plane_layer_enable(int module,
|
||||
struct dp_plane_info *plane, int on)
|
||||
{
|
||||
dp_plane_set_enable(module, plane->layer, on);
|
||||
}
|
||||
|
||||
int dp_plane_set_address(int module, int layer, unsigned int address)
|
||||
{
|
||||
nx_mlc_set_rgblayer_address(module, layer, address);
|
||||
nx_mlc_set_dirty_flag(module, layer);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int dp_plane_wait_vsync(int module, int layer, int fps)
|
||||
{
|
||||
int cnt = 0;
|
||||
|
||||
if (fps == 0)
|
||||
return (int)nx_mlc_get_dirty_flag(module, layer);
|
||||
|
||||
while (fps > cnt++) {
|
||||
while (nx_mlc_get_dirty_flag(module, layer))
|
||||
;
|
||||
nx_mlc_set_dirty_flag(module, layer);
|
||||
}
|
||||
return 0;
|
||||
}
|
545
drivers/video/nexell/s5pxx18_dp_hdmi.c
Normal file
545
drivers/video/nexell/s5pxx18_dp_hdmi.c
Normal file
|
@ -0,0 +1,545 @@
|
|||
// SPDX-License-Identifier: GPL-2.0+
|
||||
/*
|
||||
* Copyright (C) 2016 Nexell Co., Ltd.
|
||||
*
|
||||
* Author: junghyun, kim <jhkim@nexell.co.kr>
|
||||
*/
|
||||
|
||||
#include <config.h>
|
||||
#include <common.h>
|
||||
#include <errno.h>
|
||||
#include <log.h>
|
||||
|
||||
#include <asm/arch/nexell.h>
|
||||
#include <asm/arch/tieoff.h>
|
||||
#include <asm/arch/reset.h>
|
||||
#include <asm/arch/display.h>
|
||||
|
||||
#include <linux/delay.h>
|
||||
|
||||
#include "soc/s5pxx18_soc_dpc.h"
|
||||
#include "soc/s5pxx18_soc_hdmi.h"
|
||||
#include "soc/s5pxx18_soc_disptop.h"
|
||||
#include "soc/s5pxx18_soc_disptop_clk.h"
|
||||
|
||||
#define __io_address(a) (void *)(uintptr_t)(a)
|
||||
|
||||
static const u8 hdmiphy_preset74_25[32] = {
|
||||
0xd1, 0x1f, 0x10, 0x40, 0x40, 0xf8, 0xc8, 0x81,
|
||||
0xe8, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0a,
|
||||
0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x86, 0x54,
|
||||
0xa5, 0x24, 0x01, 0x00, 0x00, 0x01, 0x10, 0x80,
|
||||
};
|
||||
|
||||
static const u8 hdmiphy_preset148_5[32] = {
|
||||
0xd1, 0x1f, 0x00, 0x40, 0x40, 0xf8, 0xc8, 0x81,
|
||||
0xe8, 0xba, 0xd8, 0x45, 0xa0, 0xac, 0x80, 0x0a,
|
||||
0x80, 0x09, 0x84, 0x05, 0x22, 0x24, 0x86, 0x54,
|
||||
0x4b, 0x25, 0x03, 0x00, 0x00, 0x01, 0x80,
|
||||
};
|
||||
|
||||
#define HDMIPHY_PRESET_TABLE_SIZE (32)
|
||||
|
||||
enum NXP_HDMI_PRESET {
|
||||
NXP_HDMI_PRESET_720P = 0, /* 1280 x 720 */
|
||||
NXP_HDMI_PRESET_1080P, /* 1920 x 1080 */
|
||||
NXP_HDMI_PRESET_MAX
|
||||
};
|
||||
|
||||
static void hdmi_reset(void)
|
||||
{
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_VIDEO, RSTCON_ASSERT);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_SPDIF, RSTCON_ASSERT);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_TMDS, RSTCON_ASSERT);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_VIDEO, RSTCON_NEGATE);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_SPDIF, RSTCON_NEGATE);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_TMDS, RSTCON_NEGATE);
|
||||
}
|
||||
|
||||
static int hdmi_phy_enable(int preset, int enable)
|
||||
{
|
||||
const u8 *table = NULL;
|
||||
int size = 0;
|
||||
u32 addr, i = 0;
|
||||
|
||||
if (!enable)
|
||||
return 0;
|
||||
|
||||
switch (preset) {
|
||||
case NXP_HDMI_PRESET_720P:
|
||||
table = hdmiphy_preset74_25;
|
||||
size = 32;
|
||||
break;
|
||||
case NXP_HDMI_PRESET_1080P:
|
||||
table = hdmiphy_preset148_5;
|
||||
size = 31;
|
||||
break;
|
||||
default:
|
||||
printf("hdmi: phy not support preset %d\n", preset);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (0 << 7));
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (0 << 7));
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG04, (0 << 4));
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG04, (0 << 4));
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG24, (1 << 7));
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG24, (1 << 7));
|
||||
|
||||
for (i = 0, addr = HDMI_PHY_REG04; size > i; i++, addr += 4) {
|
||||
nx_hdmi_set_reg(0, addr, table[i]);
|
||||
nx_hdmi_set_reg(0, addr, table[i]);
|
||||
}
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG7C, 0x80);
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG7C, 0x80);
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (1 << 7));
|
||||
nx_hdmi_set_reg(0, HDMI_PHY_REG7C, (1 << 7));
|
||||
debug("%s: preset = %d\n", __func__, preset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int hdmi_wait_phy_ready(void)
|
||||
{
|
||||
int count = 500;
|
||||
|
||||
do {
|
||||
u32 val = nx_hdmi_get_reg(0, HDMI_LINK_PHY_STATUS_0);
|
||||
|
||||
if (val & 0x01) {
|
||||
printf("HDMI: phy ready...\n");
|
||||
return 1;
|
||||
}
|
||||
mdelay(10);
|
||||
} while (count--);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int hdmi_get_vsync(int preset,
|
||||
struct dp_sync_info *sync,
|
||||
struct dp_ctrl_info *ctrl)
|
||||
{
|
||||
switch (preset) {
|
||||
case NXP_HDMI_PRESET_720P: /* 720p: 1280x720 */
|
||||
sync->h_active_len = 1280;
|
||||
sync->h_sync_width = 40;
|
||||
sync->h_back_porch = 220;
|
||||
sync->h_front_porch = 110;
|
||||
sync->h_sync_invert = 0;
|
||||
sync->v_active_len = 720;
|
||||
sync->v_sync_width = 5;
|
||||
sync->v_back_porch = 20;
|
||||
sync->v_front_porch = 5;
|
||||
sync->v_sync_invert = 0;
|
||||
break;
|
||||
|
||||
case NXP_HDMI_PRESET_1080P: /* 1080p: 1920x1080 */
|
||||
sync->h_active_len = 1920;
|
||||
sync->h_sync_width = 44;
|
||||
sync->h_back_porch = 148;
|
||||
sync->h_front_porch = 88;
|
||||
sync->h_sync_invert = 0;
|
||||
sync->v_active_len = 1080;
|
||||
sync->v_sync_width = 5;
|
||||
sync->v_back_porch = 36;
|
||||
sync->v_front_porch = 4;
|
||||
sync->v_sync_invert = 0;
|
||||
break;
|
||||
default:
|
||||
printf("HDMI: not support preset sync %d\n", preset);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
ctrl->clk_src_lv0 = 4;
|
||||
ctrl->clk_div_lv0 = 1;
|
||||
ctrl->clk_src_lv1 = 7;
|
||||
ctrl->clk_div_lv1 = 1;
|
||||
|
||||
ctrl->out_format = outputformat_rgb888;
|
||||
ctrl->delay_mask = (DP_SYNC_DELAY_RGB_PVD | DP_SYNC_DELAY_HSYNC_CP1 |
|
||||
DP_SYNC_DELAY_VSYNC_FRAM | DP_SYNC_DELAY_DE_CP);
|
||||
ctrl->d_rgb_pvd = 0;
|
||||
ctrl->d_hsync_cp1 = 0;
|
||||
ctrl->d_vsync_fram = 0;
|
||||
ctrl->d_de_cp2 = 7;
|
||||
|
||||
/* HFP + HSW + HBP + AVWidth-VSCLRPIXEL- 1; */
|
||||
ctrl->vs_start_offset = (sync->h_front_porch + sync->h_sync_width +
|
||||
sync->h_back_porch + sync->h_active_len - 1);
|
||||
ctrl->vs_end_offset = 0;
|
||||
|
||||
/* HFP + HSW + HBP + AVWidth-EVENVSCLRPIXEL- 1 */
|
||||
ctrl->ev_start_offset = (sync->h_front_porch + sync->h_sync_width +
|
||||
sync->h_back_porch + sync->h_active_len - 1);
|
||||
ctrl->ev_end_offset = 0;
|
||||
debug("%s: preset: %d\n", __func__, preset);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_clock(void)
|
||||
{
|
||||
void *base =
|
||||
__io_address(nx_disp_top_clkgen_get_physical_address
|
||||
(to_mipi_clkgen));
|
||||
|
||||
nx_disp_top_clkgen_set_base_address(to_mipi_clkgen, base);
|
||||
nx_disp_top_clkgen_set_clock_divisor_enable(to_mipi_clkgen, 0);
|
||||
nx_disp_top_clkgen_set_clock_pclk_mode(to_mipi_clkgen,
|
||||
nx_pclkmode_always);
|
||||
nx_disp_top_clkgen_set_clock_source(to_mipi_clkgen, HDMI_SPDIF_CLKOUT,
|
||||
2);
|
||||
nx_disp_top_clkgen_set_clock_divisor(to_mipi_clkgen, HDMI_SPDIF_CLKOUT,
|
||||
2);
|
||||
nx_disp_top_clkgen_set_clock_source(to_mipi_clkgen, 1, 7);
|
||||
nx_disp_top_clkgen_set_clock_divisor_enable(to_mipi_clkgen, 1);
|
||||
|
||||
/* must initialize this !!! */
|
||||
nx_disp_top_hdmi_set_vsync_hsstart_end(0, 0);
|
||||
nx_disp_top_hdmi_set_vsync_start(0);
|
||||
nx_disp_top_hdmi_set_hactive_start(0);
|
||||
nx_disp_top_hdmi_set_hactive_end(0);
|
||||
}
|
||||
|
||||
static void hdmi_vsync(struct dp_sync_info *sync)
|
||||
{
|
||||
int width = sync->h_active_len;
|
||||
int hsw = sync->h_sync_width;
|
||||
int hbp = sync->h_back_porch;
|
||||
int height = sync->v_active_len;
|
||||
int vsw = sync->v_sync_width;
|
||||
int vbp = sync->v_back_porch;
|
||||
|
||||
int v_sync_s = vsw + vbp + height - 1;
|
||||
int h_active_s = hsw + hbp;
|
||||
int h_active_e = width + hsw + hbp;
|
||||
int v_sync_hs_se0 = hsw + hbp + 1;
|
||||
int v_sync_hs_se1 = hsw + hbp + 2;
|
||||
|
||||
nx_disp_top_hdmi_set_vsync_start(v_sync_s);
|
||||
nx_disp_top_hdmi_set_hactive_start(h_active_s);
|
||||
nx_disp_top_hdmi_set_hactive_end(h_active_e);
|
||||
nx_disp_top_hdmi_set_vsync_hsstart_end(v_sync_hs_se0, v_sync_hs_se1);
|
||||
}
|
||||
|
||||
static int hdmi_prepare(struct dp_sync_info *sync)
|
||||
{
|
||||
int width = sync->h_active_len;
|
||||
int hsw = sync->h_sync_width;
|
||||
int hfp = sync->h_front_porch;
|
||||
int hbp = sync->h_back_porch;
|
||||
int height = sync->v_active_len;
|
||||
int vsw = sync->v_sync_width;
|
||||
int vfp = sync->v_front_porch;
|
||||
int vbp = sync->v_back_porch;
|
||||
|
||||
u32 h_blank, h_line, h_sync_start, h_sync_end;
|
||||
u32 v_blank, v2_blank, v_line;
|
||||
u32 v_sync_line_bef_1, v_sync_line_bef_2;
|
||||
|
||||
u32 fixed_ffff = 0xffff;
|
||||
|
||||
/* calculate sync variables */
|
||||
h_blank = hfp + hsw + hbp;
|
||||
v_blank = vfp + vsw + vbp;
|
||||
v2_blank = height + vfp + vsw + vbp;
|
||||
v_line = height + vfp + vsw + vbp; /* total v */
|
||||
h_line = width + hfp + hsw + hbp; /* total h */
|
||||
h_sync_start = hfp;
|
||||
h_sync_end = hfp + hsw;
|
||||
v_sync_line_bef_1 = vfp;
|
||||
v_sync_line_bef_2 = vfp + vsw;
|
||||
|
||||
/* no blue screen mode, encoding order as it is */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_0, (0 << 5) | (1 << 4));
|
||||
|
||||
/* set HDMI_LINK_BLUE_SCREEN_* to 0x0 */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_R_0, 0x5555);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_R_1, 0x5555);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_G_0, 0x5555);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_G_1, 0x5555);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_B_0, 0x5555);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_BLUE_SCREEN_B_1, 0x5555);
|
||||
|
||||
/* set HDMI_CON_1 to 0x0 */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_1, 0x0);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_2, 0x0);
|
||||
|
||||
/* set interrupt : enable hpd_plug, hpd_unplug */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_INTC_CON_0,
|
||||
(1 << 6) | (1 << 3) | (1 << 2));
|
||||
|
||||
/* set STATUS_EN to 0x17 */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_STATUS_EN, 0x17);
|
||||
|
||||
/* TODO set HDP to 0x0 : later check hpd */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_HPD, 0x0);
|
||||
|
||||
/* set MODE_SEL to 0x02 */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_MODE_SEL, 0x2);
|
||||
|
||||
/* set H_BLANK_*, V1_BLANK_*, V2_BLANK_*, V_LINE_*,
|
||||
* H_LINE_*, H_SYNC_START_*, H_SYNC_END_ *
|
||||
* V_SYNC_LINE_BEF_1_*, V_SYNC_LINE_BEF_2_*
|
||||
*/
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_BLANK_0, h_blank % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_BLANK_1, h_blank >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V1_BLANK_0, v_blank % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V1_BLANK_1, v_blank >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V2_BLANK_0, v2_blank % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V2_BLANK_1, v2_blank >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_LINE_0, v_line % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_LINE_1, v_line >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_LINE_0, h_line % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_LINE_1, h_line >> 8);
|
||||
|
||||
if (width == 1280) {
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_HSYNC_POL, 0x1);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VSYNC_POL, 0x1);
|
||||
} else {
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_HSYNC_POL, 0x0);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VSYNC_POL, 0x0);
|
||||
}
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_INT_PRO_MODE, 0x0);
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_START_0, (h_sync_start % 256) - 2);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_START_1, h_sync_start >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_END_0, (h_sync_end % 256) - 2);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_H_SYNC_END_1, h_sync_end >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_1_0,
|
||||
v_sync_line_bef_1 % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_1_1,
|
||||
v_sync_line_bef_1 >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_2_0,
|
||||
v_sync_line_bef_2 % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_BEF_2_1,
|
||||
v_sync_line_bef_2 >> 8);
|
||||
|
||||
/* Set V_SYNC_LINE_AFT*, V_SYNC_LINE_AFT_PXL*, VACT_SPACE* */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_1_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_1_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_2_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_2_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_3_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_3_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_4_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_4_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_5_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_5_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_6_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_6_1, fixed_ffff >> 8);
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_1_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_1_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_2_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_2_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_3_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_3_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_4_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_4_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_5_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_5_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_6_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_V_SYNC_LINE_AFT_PXL_6_1, fixed_ffff >> 8);
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE1_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE1_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE2_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE2_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE3_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE3_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE4_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE4_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE5_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE5_1, fixed_ffff >> 8);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE6_0, fixed_ffff % 256);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VACT_SPACE6_1, fixed_ffff >> 8);
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_CSC_MUX, 0x0);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_SYNC_GEN_MUX, 0x0);
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_SEND_START_0, 0xfd);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_SEND_START_1, 0x01);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_0, 0x0d);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_1, 0x3a);
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_SEND_END_2, 0x08);
|
||||
|
||||
/* Set DC_CONTROL to 0x00 */
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_DC_CONTROL, 0x0);
|
||||
|
||||
if (IS_ENABLED(CONFIG_HDMI_PATTERN))
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VIDEO_PATTERN_GEN, 0x1);
|
||||
else
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_VIDEO_PATTERN_GEN, 0x0);
|
||||
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_GCP_CON, 0x0a);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void hdmi_init(void)
|
||||
{
|
||||
void *base;
|
||||
/**
|
||||
* [SEQ 2] set the HDMI CLKGEN's PCLKMODE to always enabled
|
||||
*/
|
||||
base =
|
||||
__io_address(nx_disp_top_clkgen_get_physical_address(hdmi_clkgen));
|
||||
nx_disp_top_clkgen_set_base_address(hdmi_clkgen, base);
|
||||
nx_disp_top_clkgen_set_clock_pclk_mode(hdmi_clkgen, nx_pclkmode_always);
|
||||
|
||||
base = __io_address(nx_hdmi_get_physical_address(0));
|
||||
nx_hdmi_set_base_address(0, base);
|
||||
|
||||
/**
|
||||
* [SEQ 3] set the 0xC001100C[0] to 1
|
||||
*/
|
||||
nx_tieoff_set(NX_TIEOFF_DISPLAYTOP0_i_HDMI_PHY_REFCLK_SEL, 1);
|
||||
|
||||
/**
|
||||
* [SEQ 4] release the resets of HDMI.i_PHY_nRST and HDMI.i_nRST
|
||||
*/
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_PHY, RSTCON_ASSERT);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI, RSTCON_ASSERT);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI_PHY, RSTCON_NEGATE);
|
||||
nx_rstcon_setrst(RESET_ID_HDMI, RSTCON_NEGATE);
|
||||
}
|
||||
|
||||
void hdmi_enable(int input, int preset, struct dp_sync_info *sync, int enable)
|
||||
{
|
||||
if (enable) {
|
||||
nx_hdmi_set_reg(0, HDMI_LINK_HDMI_CON_0,
|
||||
(nx_hdmi_get_reg(0, HDMI_LINK_HDMI_CON_0) |
|
||||
0x1));
|
||||
hdmi_vsync(sync);
|
||||
} else {
|
||||
hdmi_phy_enable(preset, 0);
|
||||
}
|
||||
}
|
||||
|
||||
static int hdmi_setup(int input, int preset,
|
||||
struct dp_sync_info *sync, struct dp_ctrl_info *ctrl)
|
||||
{
|
||||
u32 HDMI_SEL = 0;
|
||||
int ret;
|
||||
|
||||
switch (input) {
|
||||
case DP_DEVICE_DP0:
|
||||
HDMI_SEL = primary_mlc;
|
||||
break;
|
||||
case DP_DEVICE_DP1:
|
||||
HDMI_SEL = secondary_mlc;
|
||||
break;
|
||||
case DP_DEVICE_RESCONV:
|
||||
HDMI_SEL = resolution_conv;
|
||||
break;
|
||||
default:
|
||||
printf("HDMI: not support source device %d\n", input);
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/**
|
||||
* [SEQ 5] set up the HDMI PHY to specific video clock.
|
||||
*/
|
||||
ret = hdmi_phy_enable(preset, 1);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
|
||||
/**
|
||||
* [SEQ 6] I2S (or SPDIFTX) configuration for the source audio data
|
||||
* this is done in another user app - ex> Android Audio HAL
|
||||
*/
|
||||
|
||||
/**
|
||||
* [SEQ 7] Wait for ECID ready
|
||||
*/
|
||||
|
||||
/**
|
||||
* [SEQ 8] release the resets of HDMI.i_VIDEO_nRST and HDMI.i_SPDIF_nRST
|
||||
* and HDMI.i_TMDS_nRST
|
||||
*/
|
||||
hdmi_reset();
|
||||
|
||||
/**
|
||||
* [SEQ 9] Wait for HDMI PHY ready (wait until 0xC0200020.[0], 1)
|
||||
*/
|
||||
if (hdmi_wait_phy_ready() == 0) {
|
||||
printf("%s: failed to wait for hdmiphy ready\n", __func__);
|
||||
hdmi_phy_enable(preset, 0);
|
||||
return -EIO;
|
||||
}
|
||||
/* set mux */
|
||||
nx_disp_top_set_hdmimux(1, HDMI_SEL);
|
||||
|
||||
/**
|
||||
* [SEC 10] Set the DPC CLKGEN's Source Clock to HDMI_CLK &
|
||||
* Set Sync Parameter
|
||||
*/
|
||||
hdmi_clock();
|
||||
/* set hdmi link clk to clkgen vs default is hdmi phy clk */
|
||||
|
||||
/**
|
||||
* [SEQ 11] Set up the HDMI Converter parameters
|
||||
*/
|
||||
hdmi_get_vsync(preset, sync, ctrl);
|
||||
hdmi_prepare(sync);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
struct dp_plane_info *plane = planes;
|
||||
int input = module == 0 ? DP_DEVICE_DP0 : DP_DEVICE_DP1;
|
||||
int count = top->plane_num;
|
||||
int preset = dev->preset;
|
||||
int i = 0;
|
||||
|
||||
debug("HDMI: display.%d\n", module);
|
||||
|
||||
switch (preset) {
|
||||
case 0:
|
||||
top->screen_width = 1280;
|
||||
top->screen_height = 720;
|
||||
sync->h_active_len = 1280;
|
||||
sync->v_active_len = 720;
|
||||
break;
|
||||
case 1:
|
||||
top->screen_width = 1920;
|
||||
top->screen_height = 1080;
|
||||
sync->h_active_len = 1920;
|
||||
sync->v_active_len = 1080;
|
||||
break;
|
||||
default:
|
||||
printf("hdmi not support preset %d\n", preset);
|
||||
return;
|
||||
}
|
||||
|
||||
printf("HDMI: display.%d, preset %d (%4d * %4d)\n",
|
||||
module, preset, top->screen_width, top->screen_height);
|
||||
|
||||
dp_control_init(module);
|
||||
dp_plane_init(module);
|
||||
|
||||
hdmi_init();
|
||||
hdmi_setup(input, preset, sync, ctrl);
|
||||
|
||||
dp_plane_screen_setup(module, top);
|
||||
for (i = 0; count > i; i++, plane++) {
|
||||
if (!plane->enable)
|
||||
continue;
|
||||
dp_plane_layer_setup(module, plane);
|
||||
dp_plane_layer_enable(module, plane, 1);
|
||||
}
|
||||
dp_plane_screen_enable(module, 1);
|
||||
|
||||
dp_control_setup(module, sync, ctrl);
|
||||
dp_control_enable(module, 1);
|
||||
|
||||
hdmi_enable(input, preset, sync, 1);
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user