From 677a6327e7a40c798c6b7fe208ebbdb213780893 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 29 Dec 2016 01:41:28 +0800 Subject: [PATCH 01/18] sunxi: makes an invisible option for H3-like DRAM controllers Allwinner SoCs after H3 (e.g. A64, H5, R40, V3s) uses a H3-like DesignWare DRAM controller, which do not have official free DRAM initialization code, but can use modified dram_sun8i_h3.c. Add a invisible option for easier DRAM initialization code reuse. Signed-off-by: Icenowy Zheng --- arch/arm/include/asm/arch-sunxi/dram.h | 2 +- arch/arm/mach-sunxi/Makefile | 2 +- board/sunxi/Kconfig | 7 +++++++ 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/dram.h b/arch/arm/include/asm/arch-sunxi/dram.h index e0be744dba48..c5456658a3b4 100644 --- a/arch/arm/include/asm/arch-sunxi/dram.h +++ b/arch/arm/include/asm/arch-sunxi/dram.h @@ -24,7 +24,7 @@ #include #elif defined(CONFIG_MACH_SUN8I_A83T) #include -#elif defined(CONFIG_MACH_SUN8I_H3) +#elif defined(CONFIG_SUNXI_H3_DW_DRAM) #include #elif defined(CONFIG_MACH_SUN9I) #include diff --git a/arch/arm/mach-sunxi/Makefile b/arch/arm/mach-sunxi/Makefile index e73114ee642c..dc737db4b9aa 100644 --- a/arch/arm/mach-sunxi/Makefile +++ b/arch/arm/mach-sunxi/Makefile @@ -48,6 +48,6 @@ obj-$(CONFIG_MACH_SUN7I) += dram_sun4i.o obj-$(CONFIG_MACH_SUN8I_A23) += dram_sun8i_a23.o obj-$(CONFIG_MACH_SUN8I_A33) += dram_sun8i_a33.o obj-$(CONFIG_MACH_SUN8I_A83T) += dram_sun8i_a83t.o -obj-$(CONFIG_MACH_SUN8I_H3) += dram_sun8i_h3.o +obj-$(CONFIG_SUNXI_H3_DW_DRAM) += dram_sun8i_h3.o obj-$(CONFIG_MACH_SUN9I) += dram_sun9i.o endif diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index e1d4ab148f08..4ddd99268435 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -42,6 +42,12 @@ config SUNXI_GEN_SUN6I separate ahb reset control registers, custom pmic bus, new style watchdog, etc. +config SUNXI_H3_DW_DRAM + bool + ---help--- + Select this for sunxi SoCs which uses a DRAM controller like the + DesignWare controller used in H3, mainly SoCs after H3, which do + not have official open-source DRAM initialization code. choice prompt "Sunxi SoC Variant" @@ -113,6 +119,7 @@ config MACH_SUN8I_H3 select ARCH_SUPPORT_PSCI select SUNXI_GEN_SUN6I select SUPPORT_SPL + select SUNXI_H3_DW_DRAM select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT config MACH_SUN9I From 42cf9d956673e67c79ef88bfb08f92e3b3bd9a9d Mon Sep 17 00:00:00 2001 From: Andre Przywara Date: Thu, 4 Aug 2016 19:58:58 +0200 Subject: [PATCH 02/18] sunxi: H3/A64: fix non-ODT setting According to Jens disabling the on-die-termination should set bit 5, not bit 1 in the respective register. Fix this. Reported-by: Jens Kuske Signed-off-by: Andre Przywara --- arch/arm/mach-sunxi/dram_sun8i_h3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/mach-sunxi/dram_sun8i_h3.c b/arch/arm/mach-sunxi/dram_sun8i_h3.c index b08b8e67ccab..8e2527dee142 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_h3.c +++ b/arch/arm/mach-sunxi/dram_sun8i_h3.c @@ -347,7 +347,7 @@ static int mctl_channel_init(struct dram_para *para) clrsetbits_le32(&mctl_ctl->datx[i].gcr, (0x3 << 4) | (0x1 << 1) | (0x3 << 2) | (0x3 << 12) | (0x3 << 14), - IS_ENABLED(CONFIG_DRAM_ODT_EN) ? 0x0 : 0x2); + IS_ENABLED(CONFIG_DRAM_ODT_EN) ? 0x0 : 0x20); /* AC PDR should always ON */ setbits_le32(&mctl_ctl->aciocr, 0x1 << 1); From 0278d3db93f9532640c337a9e5a79be03b7565c3 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 29 Dec 2016 01:48:27 +0800 Subject: [PATCH 03/18] sunxi: add DDR2 support to H3-like DRAM controller H3-like DRAM controller needs some special code to operate a DDR2 DRAM chip. Add the logic to probe such a chip. As there's no commercial boards available now with H3 and DDR2 DRAM, the patch is developed and tested on a V3s chip, which has in-package DDR2 DRAM. Signed-off-by: Icenowy Zheng --- arch/arm/mach-sunxi/dram_sun8i_h3.c | 114 ++++++++++++++++++++++++++-- board/sunxi/Kconfig | 11 +++ 2 files changed, 120 insertions(+), 5 deletions(-) diff --git a/arch/arm/mach-sunxi/dram_sun8i_h3.c b/arch/arm/mach-sunxi/dram_sun8i_h3.c index 8e2527dee142..a48320e01c43 100644 --- a/arch/arm/mach-sunxi/dram_sun8i_h3.c +++ b/arch/arm/mach-sunxi/dram_sun8i_h3.c @@ -22,6 +22,9 @@ struct dram_para { u8 bus_width; u8 dual_rank; u8 row_bits; +#ifdef CONFIG_SUNXI_H3_DRAM_DDR2 + u8 bank_bits; +#endif }; static inline int ns_to_t(int nanoseconds) @@ -136,36 +139,77 @@ static void mctl_set_timing_params(struct dram_para *para) struct sunxi_mctl_ctl_reg * const mctl_ctl = (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u8 tccd = 2; +#else + u8 tccd = 1; +#endif u8 tfaw = ns_to_t(50); +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u8 trrd = max(ns_to_t(10), 4); u8 trcd = ns_to_t(15); u8 trc = ns_to_t(53); u8 txp = max(ns_to_t(8), 3); u8 twtr = max(ns_to_t(8), 4); u8 trtp = max(ns_to_t(8), 4); +#else + u8 trrd = max(ns_to_t(10), 2); + u8 trcd = ns_to_t(20); + u8 trc = ns_to_t(65); + u8 txp = 2; + u8 twtr = max(ns_to_t(8), 2); + u8 trtp = max(ns_to_t(8), 2); +#endif u8 twr = max(ns_to_t(15), 3); u8 trp = ns_to_t(15); +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u8 tras = ns_to_t(38); +#else + u8 tras = ns_to_t(45); +#endif u16 trefi = ns_to_t(7800) / 32; +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u16 trfc = ns_to_t(350); +#else + u16 trfc = ns_to_t(328); +#endif u8 tmrw = 0; +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u8 tmrd = 4; +#else + u8 tmrd = 2; +#endif u8 tmod = 12; u8 tcke = 3; u8 tcksrx = 5; u8 tcksre = 5; u8 tckesr = 4; +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u8 trasmax = 24; +#else + u8 trasmax = 27; +#endif +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u8 tcl = 6; /* CL 12 */ u8 tcwl = 4; /* CWL 8 */ u8 t_rdata_en = 4; u8 wr_latency = 2; - +#else + u8 tcl = 3; /* CL 12 */ + u8 tcwl = 3; /* CWL 8 */ + u8 t_rdata_en = 1; + u8 wr_latency = 1; +#endif + +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 u32 tdinit0 = (500 * CONFIG_DRAM_CLK) + 1; /* 500us */ u32 tdinit1 = (360 * CONFIG_DRAM_CLK) / 1000 + 1; /* 360ns */ +#else + u32 tdinit0 = (400 * CONFIG_DRAM_CLK) + 1; /* 400us */ + u32 tdinit1 = (500 * CONFIG_DRAM_CLK) / 1000 + 1; /* 500ns */ +#endif u32 tdinit2 = (200 * CONFIG_DRAM_CLK) + 1; /* 200us */ u32 tdinit3 = (1 * CONFIG_DRAM_CLK) + 1; /* 1us */ @@ -174,9 +218,15 @@ static void mctl_set_timing_params(struct dram_para *para) u8 trd2wr = tcl + 2 + 1 - tcwl; /* RL + BL / 2 + 2 - WL */ /* set mode register */ +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 writel(0x1c70, &mctl_ctl->mr[0]); /* CL=11, WR=12 */ writel(0x40, &mctl_ctl->mr[1]); writel(0x18, &mctl_ctl->mr[2]); /* CWL=8 */ +#else + writel(0x263, &mctl_ctl->mr[0]); /* CL=11, WR=12 */ + writel(0x4, &mctl_ctl->mr[1]); + writel(0x0, &mctl_ctl->mr[2]); /* CWL=8 */ +#endif writel(0x0, &mctl_ctl->mr[3]); /* set DRAM timing */ @@ -244,7 +294,12 @@ static void mctl_zq_calibration(struct dram_para *para) writel(0x0a0a0a0a, &mctl_ctl->zqdr[2]); - for (i = 0; i < 6; i++) { +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 + for (i = 0; i < 6; i++) +#else + for (i = 0; i < 4; i++) +#endif + { u8 zq = (CONFIG_DRAM_ZQ >> (i * 4)) & 0xf; writel((zq << 20) | (zq << 16) | (zq << 12) | @@ -266,7 +321,9 @@ static void mctl_zq_calibration(struct dram_para *para) writel((zq_val[1] << 16) | zq_val[0], &mctl_ctl->zqdr[0]); writel((zq_val[3] << 16) | zq_val[2], &mctl_ctl->zqdr[1]); +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 writel((zq_val[5] << 16) | zq_val[4], &mctl_ctl->zqdr[2]); +#endif } } @@ -275,8 +332,16 @@ static void mctl_set_cr(struct dram_para *para) struct sunxi_mctl_com_reg * const mctl_com = (struct sunxi_mctl_com_reg *)SUNXI_DRAM_COM_BASE; - writel(MCTL_CR_BL8 | MCTL_CR_2T | MCTL_CR_DDR3 | MCTL_CR_INTERLEAVED | - MCTL_CR_EIGHT_BANKS | MCTL_CR_BUS_WIDTH(para->bus_width) | + writel(MCTL_CR_BL8 | MCTL_CR_2T | +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 + MCTL_CR_DDR3 | MCTL_CR_EIGHT_BANKS | + MCTL_CR_BUS_WIDTH(para->bus_width) | +#else + (para->bank_bits == 3 ? MCTL_CR_EIGHT_BANKS : MCTL_CR_FOUR_BANKS) | + MCTL_CR_DDR2 | + MCTL_CR_32BIT /* fixme, thats wrong but what boot0 does */ | +#endif + MCTL_CR_INTERLEAVED | (para->dual_rank ? MCTL_CR_DUAL_RANK : MCTL_CR_SINGLE_RANK) | MCTL_CR_PAGE_SIZE(para->page_size) | MCTL_CR_ROW_BITS(para->row_bits), &mctl_com->cr); @@ -380,7 +445,10 @@ static int mctl_channel_init(struct dram_para *para) mctl_zq_calibration(para); - mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | PIR_DRAMRST | + mctl_phy_init(PIR_PLLINIT | PIR_DCAL | PIR_PHYRST | +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 + PIR_DRAMRST | +#endif PIR_DRAMINIT | PIR_QSGATE); /* detect ranks and bus width */ @@ -435,12 +503,29 @@ static void mctl_auto_detect_dram_size(struct dram_para *para) /* detect row address bits */ para->page_size = 512; para->row_bits = 16; +#ifdef CONFIG_SUNXI_H3_DRAM_DDR2 + para->bank_bits = 2; +#endif mctl_set_cr(para); for (para->row_bits = 11; para->row_bits < 16; para->row_bits++) +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 if (mctl_mem_matches((1 << (para->row_bits + 3)) * para->page_size)) +#else + if (mctl_mem_matches((1 << (para->row_bits + para->bank_bits)) * para->page_size)) +#endif break; +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 + /* detect bank address bits */ + para->bank_bits = 3; + mctl_set_cr(para); + + for (para->bank_bits = 2; para->bank_bits < 3; para->bank_bits++) + if (mctl_mem_matches((1 << para->bank_bits) * para->page_size)) + break; +#endif + /* detect page size */ para->page_size = 8192; mctl_set_cr(para); @@ -458,11 +543,19 @@ unsigned long sunxi_dram_init(void) (struct sunxi_mctl_ctl_reg *)SUNXI_DRAM_CTL0_BASE; struct dram_para para = { +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 .read_delays = 0x00007979, /* dram_tpr12 */ .write_delays = 0x6aaa0000, /* dram_tpr11 */ +#else + .read_delays = 0x00007878, /* dram_tpr12 */ + .write_delays = 0x6a440000, /* dram_tpr11 */ +#endif .dual_rank = 0, .bus_width = 32, .row_bits = 15, +#ifdef CONFIG_SUNXI_H3_DRAM_DDR2 + .bank_bits = 3, +#endif .page_size = 4096, }; @@ -477,7 +570,13 @@ unsigned long sunxi_dram_init(void) udelay(1); /* odt delay */ +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 writel(0x0c000400, &mctl_ctl->odtcfg); +#else + writel(0x04000400, &mctl_ctl->odtcfg); + + clrbits_le32(&mctl_ctl->pgcr[2], (1 << 13)); +#endif /* clear credit value */ setbits_le32(&mctl_com->cccr, 1 << 31); @@ -486,6 +585,11 @@ unsigned long sunxi_dram_init(void) mctl_auto_detect_dram_size(¶); mctl_set_cr(¶); +#ifndef CONFIG_SUNXI_H3_DRAM_DDR2 return (1 << (para.row_bits + 3)) * para.page_size * (para.dual_rank ? 2 : 1); +#else + return (1 << (para.row_bits + para.bank_bits)) * para.page_size * + (para.dual_rank ? 2 : 1); +#endif } diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 4ddd99268435..c11d40ee7e96 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -260,6 +260,17 @@ config DRAM_ODT_CORRECTION then the correction is negative. Usually the value for this is 0. endif +if SUNXI_H3_DW_DRAM +config SUNXI_H3_DRAM_DDR2 + bool "Board uses DDR2 DRAM" + default no + ---help--- + Only select this option when your board uses DDR2 DRAM chips instead + of DDR3 ones. + DDR2 chips needs some special probing logic, which will be included by + selecting this option. +endif + config SYS_CLK_FREQ default 816000000 if MACH_SUN50I default 912000000 if MACH_SUN7I From 3bd4355c91199ffac9e4dfe0da8c666230fa1b31 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 29 Dec 2016 01:52:31 +0800 Subject: [PATCH 04/18] sunxi: add basic V3s support Currently a working SPL for V3s can be built now. The U-Boot main binary still cannot work. Signed-off-by: Icenowy Zheng --- arch/arm/include/asm/arch-sunxi/gpio.h | 1 + arch/arm/mach-sunxi/board.c | 9 +++++++-- arch/arm/mach-sunxi/cpu_info.c | 2 ++ board/sunxi/Kconfig | 13 ++++++++++++- include/configs/sun8i.h | 2 ++ 5 files changed, 24 insertions(+), 3 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 85a4ec3b0e8f..24f85206c825 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -161,6 +161,7 @@ enum sunxi_gpio_number { #define SUN8I_GPB_UART2 2 #define SUN8I_A33_GPB_UART0 3 #define SUN8I_A83T_GPB_UART0 2 +#define SUN8I_V3S_GPB_UART0 3 #define SUN50I_GPB_UART0 4 #define SUNXI_GPC_NAND 2 diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index aa114937485d..3b28478e2d28 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -110,6 +110,10 @@ static int gpio_init(void) sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_A83T_GPB_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPB(10), SUN8I_A83T_GPB_UART0); sunxi_gpio_set_pull(SUNXI_GPB(10), SUNXI_GPIO_PULL_UP); +#elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN8I_V3S) + sunxi_gpio_set_cfgpin(SUNXI_GPB(8), SUN8I_V3S_GPB_UART0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(9), SUN8I_V3S_GPB_UART0); + sunxi_gpio_set_pull(SUNXI_GPB(9), SUNXI_GPIO_PULL_UP); #elif CONFIG_CONS_INDEX == 1 && defined(CONFIG_MACH_SUN9I) sunxi_gpio_set_cfgpin(SUNXI_GPH(12), SUN9I_GPH_UART0); sunxi_gpio_set_cfgpin(SUNXI_GPH(13), SUN9I_GPH_UART0); @@ -180,10 +184,11 @@ void s_init(void) /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif -#if defined CONFIG_MACH_SUN6I || \ +#if (defined CONFIG_MACH_SUN6I || \ defined CONFIG_MACH_SUN7I || \ defined CONFIG_MACH_SUN8I || \ - defined CONFIG_MACH_SUN9I + defined CONFIG_MACH_SUN9I) && \ + !defined CONFIG_MACH_SUN8I_V3S /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ asm volatile( "mrc p15, 0, r0, c1, c0, 1\n" diff --git a/arch/arm/mach-sunxi/cpu_info.c b/arch/arm/mach-sunxi/cpu_info.c index f1f6fd5ba430..15f1e0e45a26 100644 --- a/arch/arm/mach-sunxi/cpu_info.c +++ b/arch/arm/mach-sunxi/cpu_info.c @@ -87,6 +87,8 @@ int print_cpuinfo(void) printf("CPU: Allwinner A83T (SUN8I %04x)\n", sunxi_get_sram_id()); #elif defined CONFIG_MACH_SUN8I_H3 printf("CPU: Allwinner H3 (SUN8I %04x)\n", sunxi_get_sram_id()); +#elif defined CONFIG_MACH_SUN8I_V3S + printf("CPU: Allwinner V3s (SUN8I %04x)\n", sunxi_get_sram_id()); #elif defined CONFIG_MACH_SUN9I puts("CPU: Allwinner A80 (SUN9I)\n"); #elif defined CONFIG_MACH_SUN50I diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index c11d40ee7e96..09af3537b2d2 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -122,6 +122,17 @@ config MACH_SUN8I_H3 select SUNXI_H3_DW_DRAM select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT +config MACH_SUN8I_V3S + bool "sun8i (Allwinner V3s)" + select CPU_V7 + select CPU_V7_HAS_NONSEC + select CPU_V7_HAS_VIRT + select SUNXI_GEN_SUN6I + select SUPPORT_SPL + select SUNXI_H3_DW_DRAM + select SUNXI_H3_DRAM_DDR2 + select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT + config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 @@ -138,7 +149,7 @@ endchoice # The sun8i SoCs share a lot, this helps to avoid a lot of "if A23 || A33" config MACH_SUN8I bool - default y if MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_H3 || MACH_SUN8I_A83T + default y if MACH_SUN8I_A23 || MACH_SUN8I_A33 || MACH_SUN8I_H3 || MACH_SUN8I_A83T || MACH_SUN8I_V3S config DRAM_TYPE int "sunxi dram type" diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index a4c3fb69e411..6ac42acaeadd 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -21,6 +21,8 @@ #define CONFIG_SUNXI_USB_PHYS 4 #elif defined CONFIG_MACH_SUN8I_A83T #define CONFIG_SUNXI_USB_PHYS 3 +#elif defined CONFIG_MACH_SUN8I_V3S + #define CONFIG_SUNXI_USB_PHYS 1 #else #define CONFIG_SUNXI_USB_PHYS 2 #endif From 4052766863366c94c1fd1e4aa16cd110a6ba8caf Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sun, 8 Jan 2017 01:02:58 +0800 Subject: [PATCH 05/18] sunxi: add DTSI file for V3s As we have now V3s support in board code, the V3s DTSI file should also be added. Add also some CCU include headers to satisfy the DTSI file. Signed-off-by: Icenowy Zheng --- arch/arm/dts/sun8i-v3s.dtsi | 284 ++++++++++++++++++++++ include/dt-bindings/clock/sun8i-v3s-ccu.h | 107 ++++++++ include/dt-bindings/reset/sun8i-v3s-ccu.h | 78 ++++++ 3 files changed, 469 insertions(+) create mode 100644 arch/arm/dts/sun8i-v3s.dtsi create mode 100644 include/dt-bindings/clock/sun8i-v3s-ccu.h create mode 100644 include/dt-bindings/reset/sun8i-v3s-ccu.h diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi new file mode 100644 index 000000000000..ebefc0fefef2 --- /dev/null +++ b/arch/arm/dts/sun8i-v3s.dtsi @@ -0,0 +1,284 @@ +/* + * Copyright (C) 2016 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include + +/ { + #address-cells = <1>; + #size-cells = <1>; + interrupt-parent = <&gic>; + + cpus { + #address-cells = <1>; + #size-cells = <0>; + + cpu@0 { + compatible = "arm,cortex-a7"; + device_type = "cpu"; + reg = <0>; + clocks = <&ccu CLK_CPU>; + }; + }; + + timer { + compatible = "arm,armv7-timer"; + interrupts = , + , + , + ; + }; + + clocks { + #address-cells = <1>; + #size-cells = <1>; + ranges; + + osc24M: osc24M_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <24000000>; + clock-output-names = "osc24M"; + }; + + osc32k: osc32k_clk { + #clock-cells = <0>; + compatible = "fixed-clock"; + clock-frequency = <32768>; + clock-output-names = "osc32k"; + }; + }; + + soc { + compatible = "simple-bus"; + #address-cells = <1>; + #size-cells = <1>; + ranges; + + mmc0: mmc@01c0f000 { + compatible = "allwinner,sun7i-a20-mmc"; + reg = <0x01c0f000 0x1000>; + clocks = <&ccu CLK_BUS_MMC0>, + <&ccu CLK_MMC0>, + <&ccu CLK_MMC0_OUTPUT>, + <&ccu CLK_MMC0_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC0>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc1: mmc@01c10000 { + compatible = "allwinner,sun7i-a20-mmc"; + reg = <0x01c10000 0x1000>; + clocks = <&ccu CLK_BUS_MMC1>, + <&ccu CLK_MMC1>, + <&ccu CLK_MMC1_OUTPUT>, + <&ccu CLK_MMC1_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC1>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + mmc2: mmc@01c11000 { + compatible = "allwinner,sun7i-a20-mmc"; + reg = <0x01c11000 0x1000>; + clocks = <&ccu CLK_BUS_MMC2>, + <&ccu CLK_MMC2>, + <&ccu CLK_MMC2_OUTPUT>, + <&ccu CLK_MMC2_SAMPLE>; + clock-names = "ahb", + "mmc", + "output", + "sample"; + resets = <&ccu RST_BUS_MMC2>; + reset-names = "ahb"; + interrupts = ; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + + usb_otg: usb@01c19000 { + compatible = "allwinner,sun8i-h3-musb"; + reg = <0x01c19000 0x0400>; + clocks = <&ccu CLK_BUS_OTG>; + resets = <&ccu RST_BUS_OTG>; + interrupts = ; + interrupt-names = "mc"; + phys = <&usbphy 0>; + phy-names = "usb"; + extcon = <&usbphy 0>; + status = "disabled"; + }; + + usbphy: phy@01c19400 { + compatible = "allwinner,sun8i-v3s-usb-phy"; + reg = <0x01c19400 0x2c>, + <0x01c1a800 0x4>; + reg-names = "phy_ctrl", + "pmu0"; + clocks = <&ccu CLK_USB_PHY0>; + clock-names = "usb0_phy"; + resets = <&ccu RST_USB_PHY0>; + reset-names = "usb0_reset"; + status = "disabled"; + #phy-cells = <1>; + }; + + ccu: clock@01c20000 { + compatible = "allwinner,sun8i-v3s-ccu"; + reg = <0x01c20000 0x400>; + clocks = <&osc24M>, <&osc32k>; + clock-names = "hosc", "losc"; + #clock-cells = <1>; + #reset-cells = <1>; + }; + + rtc: rtc@01c20400 { + compatible = "allwinner,sun6i-a31-rtc"; + reg = <0x01c20400 0x54>; + interrupts = , + ; + }; + + pio: pinctrl@01c20800 { + compatible = "allwinner,sun8i-v3s-pinctrl"; + reg = <0x01c20800 0x400>; + interrupts = , + ; + clocks = <&ccu CLK_BUS_PIO>, <&osc24M>, <&osc32k>; + clock-names = "apb", "hosc", "losc"; + gpio-controller; + #gpio-cells = <3>; + interrupt-controller; + #interrupt-cells = <3>; + + uart0_pins_a: uart0@0 { + pins = "PB8", "PB9"; + function = "uart0"; + bias-pull-up; + }; + + mmc0_pins_a: mmc0@0 { + pins = "PF0", "PF1", "PF2", "PF3", + "PF4", "PF5"; + function = "mmc0"; + drive-strength = <30>; + bias-pull-up; + }; + }; + + timer@01c20c00 { + compatible = "allwinner,sun4i-a10-timer"; + reg = <0x01c20c00 0xa0>; + interrupts = , + ; + clocks = <&osc24M>; + }; + + wdt0: watchdog@01c20ca0 { + compatible = "allwinner,sun6i-a31-wdt"; + reg = <0x01c20ca0 0x20>; + interrupts = ; + }; + + uart0: serial@01c28000 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28000 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART0>; + resets = <&ccu RST_BUS_UART0>; + status = "disabled"; + }; + + uart1: serial@01c28400 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28400 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART1>; + resets = <&ccu RST_BUS_UART1>; + status = "disabled"; + }; + + uart2: serial@01c28800 { + compatible = "snps,dw-apb-uart"; + reg = <0x01c28800 0x400>; + interrupts = ; + reg-shift = <2>; + reg-io-width = <4>; + clocks = <&ccu CLK_BUS_UART2>; + resets = <&ccu RST_BUS_UART2>; + status = "disabled"; + }; + + gic: interrupt-controller@01c81000 { + compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; + reg = <0x01c81000 0x1000>, + <0x01c82000 0x1000>, + <0x01c84000 0x2000>, + <0x01c86000 0x2000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupts = ; + }; + }; +}; diff --git a/include/dt-bindings/clock/sun8i-v3s-ccu.h b/include/dt-bindings/clock/sun8i-v3s-ccu.h new file mode 100644 index 000000000000..c0d5d5599c87 --- /dev/null +++ b/include/dt-bindings/clock/sun8i-v3s-ccu.h @@ -0,0 +1,107 @@ +/* + * Copyright (c) 2016 Icenowy Zheng + * + * Based on sun8i-h3-ccu.h, which is: + * Copyright (C) 2016 Maxime Ripard + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_CLK_SUN8I_V3S_H_ +#define _DT_BINDINGS_CLK_SUN8I_V3S_H_ + +#define CLK_CPU 14 + +#define CLK_BUS_CE 20 +#define CLK_BUS_DMA 21 +#define CLK_BUS_MMC0 22 +#define CLK_BUS_MMC1 23 +#define CLK_BUS_MMC2 24 +#define CLK_BUS_DRAM 25 +#define CLK_BUS_EMAC 26 +#define CLK_BUS_HSTIMER 27 +#define CLK_BUS_SPI0 28 +#define CLK_BUS_OTG 29 +#define CLK_BUS_EHCI0 30 +#define CLK_BUS_OHCI0 31 +#define CLK_BUS_VE 32 +#define CLK_BUS_TCON0 33 +#define CLK_BUS_CSI 34 +#define CLK_BUS_DE 35 +#define CLK_BUS_CODEC 36 +#define CLK_BUS_PIO 37 +#define CLK_BUS_I2C0 38 +#define CLK_BUS_I2C1 39 +#define CLK_BUS_UART0 40 +#define CLK_BUS_UART1 41 +#define CLK_BUS_UART2 42 +#define CLK_BUS_EPHY 43 +#define CLK_BUS_DBG 44 + +#define CLK_MMC0 45 +#define CLK_MMC0_SAMPLE 46 +#define CLK_MMC0_OUTPUT 47 +#define CLK_MMC1 48 +#define CLK_MMC1_SAMPLE 49 +#define CLK_MMC1_OUTPUT 50 +#define CLK_MMC2 51 +#define CLK_MMC2_SAMPLE 52 +#define CLK_MMC2_OUTPUT 53 +#define CLK_CE 54 +#define CLK_SPI0 55 +#define CLK_USB_PHY0 56 +#define CLK_USB_OHCI0 57 + +#define CLK_DRAM_VE 59 +#define CLK_DRAM_CSI 60 +#define CLK_DRAM_EHCI 61 +#define CLK_DRAM_OHCI 62 +#define CLK_DE 63 +#define CLK_TCON0 64 +#define CLK_CSI_MISC 65 +#define CLK_CSI0_MCLK 66 +#define CLK_CSI1_SCLK 67 +#define CLK_CSI1_MCLK 68 +#define CLK_VE 69 +#define CLK_AC_DIG 70 +#define CLK_AVS 71 + +#define CLK_MIPI_CSI 73 + +#endif /* _DT_BINDINGS_CLK_SUN8I_V3S_H_ */ diff --git a/include/dt-bindings/reset/sun8i-v3s-ccu.h b/include/dt-bindings/reset/sun8i-v3s-ccu.h new file mode 100644 index 000000000000..b58ef21a2e18 --- /dev/null +++ b/include/dt-bindings/reset/sun8i-v3s-ccu.h @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2016 Icenowy Zheng + * + * Based on sun8i-v3s-ccu.h, which is + * Copyright (C) 2016 Maxime Ripard + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +#ifndef _DT_BINDINGS_RST_SUN8I_V3S_H_ +#define _DT_BINDINGS_RST_SUN8I_V3S_H_ + +#define RST_USB_PHY0 0 + +#define RST_MBUS 1 + +#define RST_BUS_CE 5 +#define RST_BUS_DMA 6 +#define RST_BUS_MMC0 7 +#define RST_BUS_MMC1 8 +#define RST_BUS_MMC2 9 +#define RST_BUS_DRAM 11 +#define RST_BUS_EMAC 12 +#define RST_BUS_HSTIMER 14 +#define RST_BUS_SPI0 15 +#define RST_BUS_OTG 17 +#define RST_BUS_EHCI0 18 +#define RST_BUS_OHCI0 22 +#define RST_BUS_VE 26 +#define RST_BUS_TCON0 27 +#define RST_BUS_CSI 30 +#define RST_BUS_DE 34 +#define RST_BUS_DBG 38 +#define RST_BUS_EPHY 39 +#define RST_BUS_CODEC 40 +#define RST_BUS_I2C0 46 +#define RST_BUS_I2C1 47 +#define RST_BUS_UART0 49 +#define RST_BUS_UART1 50 +#define RST_BUS_UART2 51 + +#endif /* _DT_BINDINGS_RST_SUN8I_H3_H_ */ From 7557c42cdebdf8332bfad59f44d08763addfc729 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sun, 8 Jan 2017 01:11:30 +0800 Subject: [PATCH 06/18] sunxi: add support for Lichee Pi Zero Lichee Pi Zero is a development board with a V3s SoC. Add support for it. Signed-off-by: Icenowy Zheng --- arch/arm/dts/Makefile | 2 + arch/arm/dts/sun8i-v3s-licheepi-zero.dts | 83 ++++++++++++++++++++++++ board/sunxi/MAINTAINERS | 5 ++ configs/LicheePi_Zero_defconfig | 13 ++++ 4 files changed, 103 insertions(+) create mode 100644 arch/arm/dts/sun8i-v3s-licheepi-zero.dts create mode 100644 configs/LicheePi_Zero_defconfig diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 3ee608b5b465..469dd710cf67 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -280,6 +280,8 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \ sun8i-h3-orangepi-plus.dtb \ sun8i-h3-orangepi-plus2e.dtb \ sun8i-h3-nanopi-neo.dtb +dtb-$(CONFIG_MACH_SUN8I_V3S) += \ + sun8i-v3s-licheepi-zero.dtb dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-pine64-plus.dtb \ sun50i-a64-pine64.dtb diff --git a/arch/arm/dts/sun8i-v3s-licheepi-zero.dts b/arch/arm/dts/sun8i-v3s-licheepi-zero.dts new file mode 100644 index 000000000000..3d9168cbaeca --- /dev/null +++ b/arch/arm/dts/sun8i-v3s-licheepi-zero.dts @@ -0,0 +1,83 @@ +/* + * Copyright (C) 2016 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-v3s.dtsi" +#include "sunxi-common-regulators.dtsi" + +/ { + model = "Lichee Pi Zero"; + compatible = "licheepi,licheepi-zero", "allwinner,sun8i-v3s"; + + aliases { + serial0 = &uart0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&mmc0 { + pinctrl-0 = <&mmc0_pins_a>; + pinctrl-names = "default"; + broken-cd; + bus-width = <4>; + vmmc-supply = <®_vcc3v3>; + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0_pins_a>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usb_otg { + dr_mode = "otg"; + status = "okay"; +}; + +&usbphy { + usb0_id_det-gpio = <&pio 5 6 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; diff --git a/board/sunxi/MAINTAINERS b/board/sunxi/MAINTAINERS index e23d45eed9d6..fe4e51725674 100644 --- a/board/sunxi/MAINTAINERS +++ b/board/sunxi/MAINTAINERS @@ -182,6 +182,11 @@ M: Jelle de Jong S: Maintained F: configs/Lamobo_R1_defconfig +LICHEEPI-ZERO BOARD +M: Icenowy Zheng +S: Maintained +F: configs/LicheePi_Zero_defconfig + LINKSPRITE-PCDUINO BOARD M: Zoltan Herpai S: Maintained diff --git a/configs/LicheePi_Zero_defconfig b/configs/LicheePi_Zero_defconfig new file mode 100644 index 000000000000..42414a81a73e --- /dev/null +++ b/configs/LicheePi_Zero_defconfig @@ -0,0 +1,13 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +# CONFIG_ARMV7_NONSEC is not set +CONFIG_MACH_SUN8I_V3S=y +CONFIG_DRAM_CLK=360 +CONFIG_DRAM_ZQ=14779 +CONFIG_DEFAULT_DEVICE_TREE="sun8i-v3s-licheepi-zero" +# CONFIG_CONSOLE_MUX is not set +CONFIG_SPL=y +# CONFIG_CMD_IMLS is not set +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_NETDEVICES is not set From 08a066882507ac71328fa5a94e278c42fae95c78 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 29 Dec 2016 02:10:17 +0800 Subject: [PATCH 07/18] sunxi: low memory footprint for V3s V3s devices won't have enough memory to load U-Boot binary at 0x4a000000, and they do not have enough memory to reserve 64MiB for malloc() (it has only 64MiB at all!) Change the DRAM mapping for it. Signed-off-by: Icenowy Zheng --- include/configs/sunxi-common.h | 42 +++++++++++++++++++++++++++++++--- 1 file changed, 39 insertions(+), 3 deletions(-) diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index b0bfc0dfd7da..f4489fad6d80 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -75,8 +75,13 @@ #else #define SDRAM_OFFSET(x) 0x4##x #define CONFIG_SYS_SDRAM_BASE 0x40000000 -#define CONFIG_SYS_LOAD_ADDR 0x42000000 /* default load address */ +#define CONFIG_SYS_LOAD_ADDR 0x41000000 /* default load address */ +/* V3s do not have enough memory to place code at 0x4a000000 */ +#ifndef CONFIG_MACH_SUN8I_V3S #define CONFIG_SYS_TEXT_BASE 0x4a000000 +#else +#define CONFIG_SYS_TEXT_BASE 0x42e00000 +#endif /* Note SPL_STACK_R_ADDR is set through Kconfig, we include it here * since it needs to fit in with the other values. By also #defining it * we get warnings if the Kconfig value mismatches. */ @@ -148,8 +153,13 @@ #define CONFIG_SYS_MMC_MAX_DEVICE 4 #endif +#ifndef CONFIG_MACH_SUN8I_V3S /* 64MB of malloc() pool */ #define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (64 << 20)) +#else +/* 2MB of malloc() pool */ +#define CONFIG_SYS_MALLOC_LEN (CONFIG_ENV_SIZE + (2 << 20)) +#endif /* * Miscellaneous configurable options @@ -280,7 +290,11 @@ extern int soft_i2c_gpio_scl; * The amount of RAM to keep free at the top of RAM when relocating u-boot, * to use as framebuffer. This must be a multiple of 4096. */ +#ifndef CONFIG_MACH_SUN8I_V3S #define CONFIG_SUNXI_MAX_FB_SIZE (16 << 20) +#else +#define CONFIG_SUNXI_MAX_FB_SIZE (2 << 20) +#endif /* Do we want to initialize a simple FB? */ #define CONFIG_VIDEO_DT_SIMPLEFB @@ -383,27 +397,49 @@ extern int soft_i2c_gpio_scl; * 32M uncompressed kernel, 16M compressed kernel, 1M fdt, * 1M script, 1M pxe and the ramdisk at the end. */ - +#ifndef CONFIG_MACH_SUN8I_V3S +#define BOOTM_SIZE __stringify(0xa000000) #define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(2000000)) #define FDT_ADDR_R __stringify(SDRAM_OFFSET(3000000)) #define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(3100000)) #define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(3200000)) #define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(3300000)) +#else +/* + * 64M RAM minus 2MB heap + 16MB for u-boot, stack, fb, etc. + * 16M uncompressed kernel, 8M compressed kernel, 1M fdt, + * 1M script, 1M pxe and the ramdisk at the end. + */ +#define BOOTM_SIZE __stringify(0x2e00000) +#define KERNEL_ADDR_R __stringify(SDRAM_OFFSET(1000000)) +#define FDT_ADDR_R __stringify(SDRAM_OFFSET(1800000)) +#define SCRIPT_ADDR_R __stringify(SDRAM_OFFSET(1900000)) +#define PXEFILE_ADDR_R __stringify(SDRAM_OFFSET(1A00000)) +#define RAMDISK_ADDR_R __stringify(SDRAM_OFFSET(1B00000)) +#endif #endif #define MEM_LAYOUT_ENV_SETTINGS \ - "bootm_size=0xa000000\0" \ + "bootm_size=" BOOTM_SIZE "\0" \ "kernel_addr_r=" KERNEL_ADDR_R "\0" \ "fdt_addr_r=" FDT_ADDR_R "\0" \ "scriptaddr=" SCRIPT_ADDR_R "\0" \ "pxefile_addr_r=" PXEFILE_ADDR_R "\0" \ "ramdisk_addr_r=" RAMDISK_ADDR_R "\0" +#ifndef CONFIG_MACH_SUN8I_V3S #define DFU_ALT_INFO_RAM \ "dfu_alt_info_ram=" \ "kernel ram " KERNEL_ADDR_R " 0x1000000;" \ "fdt ram " FDT_ADDR_R " 0x100000;" \ "ramdisk ram " RAMDISK_ADDR_R " 0x4000000\0" +#else +#define DFU_ALT_INFO_RAM \ + "dfu_alt_info_ram=" \ + "kernel ram " KERNEL_ADDR_R " 0x800000;" \ + "fdt ram " FDT_ADDR_R " 0x100000;" \ + "ramdisk ram " RAMDISK_ADDR_R " 0x1000000\0" +#endif #ifdef CONFIG_MMC #define BOOT_TARGET_DEVICES_MMC(func) func(MMC, mmc, 0) From be1eb7123e7010d2b693dacf19edfe98434c5673 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 30 Dec 2016 19:08:44 +0800 Subject: [PATCH 08/18] sunxi: do a CCM quirk on V3s for USB to work properly USB OTG on V3s SoC seems to need the USB OTG clock gate to be passed and the reset to be deasserted before boot, otherwise it won't work in Linux. Add this quirk. Also add a generic quirk framework in sunxi's clock initialization code. Signed-off-by: Icenowy Zheng --- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 1 + arch/arm/mach-sunxi/clock.c | 5 +++++ arch/arm/mach-sunxi/clock_sun6i.c | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index be9fcfda0e35..9e22e156337f 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -376,6 +376,7 @@ struct sunxi_ccm_reg { #define CCM_PLL11_PATTERN 0xf5860000 /* ahb_reset0 offsets */ +#define AHB_RESET_OFFSET_OTG 24 #define AHB_RESET_OFFSET_GMAC 17 #define AHB_RESET_OFFSET_MCTL 14 #define AHB_RESET_OFFSET_MMC3 11 diff --git a/arch/arm/mach-sunxi/clock.c b/arch/arm/mach-sunxi/clock.c index e6f53f91e63a..505f9178dcfb 100644 --- a/arch/arm/mach-sunxi/clock.c +++ b/arch/arm/mach-sunxi/clock.c @@ -20,6 +20,10 @@ __weak void clock_init_sec(void) { } +__weak void clock_init_quirk(void) +{ +} + __weak void gtbus_init(void) { } @@ -32,6 +36,7 @@ int clock_init(void) #endif clock_init_uart(); clock_init_sec(); + clock_init_quirk(); return 0; } diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index ed8cd9bbb376..474c5a325d98 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -58,6 +58,17 @@ void clock_init_sec(void) #endif } +void clock_init_quirk(void) +{ + /* without this quirk, the USB PHY cannot be used in Linux */ +#ifdef CONFIG_MACH_SUN8I_V3S + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0); + setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_RESET_OFFSET_OTG); +#endif +} + void clock_init_uart(void) { #if CONFIG_CONS_INDEX < 5 From cd3e9062361d37dced6e09b081e3ace88922584d Mon Sep 17 00:00:00 2001 From: Jernej Skrabec Date: Fri, 9 Dec 2016 19:07:34 +0100 Subject: [PATCH 09/18] sunxi: Add clocks for DE2/HDMI/TCON This is needed for HDMI support, which will be added later. Signed-off-by: Jernej Skrabec [Icenowy: renamed back lcd0_ch0_clk_cfg, add PLL3 for DE2 on V3s, and add CONFIG_SUNXI_DE2] Signed-off-by: Icenowy Zheng --- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 40 +++++++++++++++++++ arch/arm/mach-sunxi/clock_sun6i.c | 28 +++++++++++++ board/sunxi/Kconfig | 5 +++ scripts/config_whitelist.txt | 1 + 4 files changed, 74 insertions(+) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 9e22e156337f..775943688f5d 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -67,7 +67,11 @@ struct sunxi_ccm_reg { u32 dram_pll_cfg; /* 0xf8 PLL_DDR cfg register, A33 only */ u32 mbus_reset; /* 0xfc MBUS reset control, A33 only */ u32 dram_clk_gate; /* 0x100 DRAM module gating */ +#ifdef CONFIG_SUNXI_DE2 + u32 de_clk_cfg; /* 0x104 DE module clock */ +#else u32 be0_clk_cfg; /* 0x104 BE0 module clock */ +#endif u32 be1_clk_cfg; /* 0x108 BE1 module clock */ u32 fe0_clk_cfg; /* 0x10c FE0 module clock */ u32 fe1_clk_cfg; /* 0x110 FE1 module clock */ @@ -85,7 +89,11 @@ struct sunxi_ccm_reg { u32 dmic_clk_cfg; /* 0x148 Digital Mic module clock*/ u32 reserved15; u32 hdmi_clk_cfg; /* 0x150 HDMI module clock */ +#ifdef CONFIG_SUNXI_DE2 + u32 hdmi_slow_clk_cfg; /* 0x154 HDMI slow module clock */ +#else u32 ps_clk_cfg; /* 0x154 PS module clock */ +#endif u32 mtc_clk_cfg; /* 0x158 MTC module clock */ u32 mbus0_clk_cfg; /* 0x15c MBUS0 module clock */ u32 mbus1_clk_cfg; /* 0x160 MBUS1 module clock */ @@ -220,6 +228,15 @@ struct sunxi_ccm_reg { #define CCM_MIPI_PLL_CTRL_LDO_EN (0x3 << 22) #define CCM_MIPI_PLL_CTRL_EN (0x1 << 31) +#define CCM_PLL10_CTRL_M_SHIFT 0 +#define CCM_PLL10_CTRL_M_MASK (0xf << CCM_PLL10_CTRL_M_SHIFT) +#define CCM_PLL10_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_PLL10_CTRL_N_SHIFT 8 +#define CCM_PLL10_CTRL_N_MASK (0x7f << CCM_PLL10_CTRL_N_SHIFT) +#define CCM_PLL10_CTRL_N(n) ((((n) - 1) & 0x7f) << 8) +#define CCM_PLL10_CTRL_INTEGER_MODE (0x1 << 24) +#define CCM_PLL10_CTRL_EN (0x1 << 31) + #define CCM_PLL11_CTRL_N(n) ((((n) - 1) & 0x3f) << 8) #define CCM_PLL11_CTRL_SIGMA_DELTA_EN (0x1 << 24) #define CCM_PLL11_CTRL_UPD (0x1 << 30) @@ -271,9 +288,12 @@ struct sunxi_ccm_reg { #define AHB_GATE_OFFSET_DRC0 25 #define AHB_GATE_OFFSET_DE_FE0 14 #define AHB_GATE_OFFSET_DE_BE0 12 +#define AHB_GATE_OFFSET_DE 12 #define AHB_GATE_OFFSET_HDMI 11 #define AHB_GATE_OFFSET_LCD1 5 #define AHB_GATE_OFFSET_LCD0 4 +#define AHB_GATE_OFFSET_TCON1 4 +#define AHB_GATE_OFFSET_TCON0 3 #define CCM_MMC_CTRL_M(x) ((x) - 1) #define CCM_MMC_CTRL_OCLK_DLY(x) ((x) << 8) @@ -346,6 +366,9 @@ struct sunxi_ccm_reg { #define CCM_LCD_CH0_CTRL_RST 0 #define CCM_LCD_CH0_CTRL_GATE (0x1 << 31) +#define CCM_TCON0_CTRL_GATE (0x1 << 31) +#define CCM_TCON0_CTRL_M(n) ((((n) - 1) & 0xf) << 0) + #define CCM_LCD_CH1_CTRL_M(n) ((((n) - 1) & 0xf) << 0) #define CCM_LCD_CH1_CTRL_HALF_SCLK1 0 /* no seperate sclk1 & 2 on sun6i */ #define CCM_LCD_CH1_CTRL_PLL3 (0 << 24) @@ -355,6 +378,7 @@ struct sunxi_ccm_reg { #define CCM_LCD_CH1_CTRL_GATE (0x1 << 31) #define CCM_HDMI_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_HDMI_CTRL_M_MASK (0xf << 0) #define CCM_HDMI_CTRL_PLL_MASK (3 << 24) #define CCM_HDMI_CTRL_PLL3 (0 << 24) #define CCM_HDMI_CTRL_PLL7 (1 << 24) @@ -363,6 +387,8 @@ struct sunxi_ccm_reg { #define CCM_HDMI_CTRL_DDC_GATE (0x1 << 30) #define CCM_HDMI_CTRL_GATE (0x1 << 31) +#define CCM_HDMI_SLOW_CTRL_DDC_GATE (1 << 31) + #if defined(CONFIG_MACH_SUN50I) #define MBUS_CLK_DEFAULT 0x81000002 /* PLL6x2 / 3 */ #elif defined(CONFIG_MACH_SUN8I) @@ -391,9 +417,13 @@ struct sunxi_ccm_reg { #define AHB_RESET_OFFSET_DRC0 25 #define AHB_RESET_OFFSET_DE_FE0 14 #define AHB_RESET_OFFSET_DE_BE0 12 +#define AHB_RESET_OFFSET_DE 12 #define AHB_RESET_OFFSET_HDMI 11 +#define AHB_RESET_OFFSET_HDMI2 10 #define AHB_RESET_OFFSET_LCD1 5 #define AHB_RESET_OFFSET_LCD0 4 +#define AHB_RESET_OFFSET_TCON1 4 +#define AHB_RESET_OFFSET_TCON0 3 /* ahb_reset2 offsets */ #define AHB_RESET_OFFSET_EPHY 2 @@ -416,6 +446,14 @@ struct sunxi_ccm_reg { #define CCM_DE_CTRL_PLL10 (5 << 24) #define CCM_DE_CTRL_GATE (1 << 31) +/* CCM bits common to all Display Engine 2.0 clock ctrl regs */ +#define CCM_DE2_CTRL_M(n) ((((n) - 1) & 0xf) << 0) +#define CCM_DE2_CTRL_PLL_MASK (3 << 24) +#define CCM_DE2_CTRL_PLL6_2X (0 << 24) +#define CCM_DE2_CTRL_PLL10 (1 << 24) +#define CCM_DE2_CTRL_PLL3 (1 << 24) /* for V3s */ +#define CCM_DE2_CTRL_GATE (1 << 31) + /* CCU security switch, H3 only */ #define CCM_SEC_SWITCH_MBUS_NONSEC (1 << 2) #define CCM_SEC_SWITCH_BUS_NONSEC (1 << 1) @@ -424,7 +462,9 @@ struct sunxi_ccm_reg { #ifndef __ASSEMBLY__ void clock_set_pll1(unsigned int hz); void clock_set_pll3(unsigned int hz); +void clock_set_pll3_factors(int m, int n); void clock_set_pll5(unsigned int clk, bool sigma_delta_enable); +void clock_set_pll10(unsigned int hz); void clock_set_pll11(unsigned int clk, bool sigma_delta_enable); void clock_set_mipi_pll(unsigned int hz); unsigned int clock_get_pll3(void); diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index 474c5a325d98..2a5db8f30223 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -152,6 +152,17 @@ void clock_set_pll3(unsigned int clk) &ccm->pll3_cfg); } +void clock_set_pll3_factors(int m, int n) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + + /* PLL3 rate = 24000000 * n / m */ + writel(CCM_PLL3_CTRL_EN | CCM_PLL3_CTRL_INTEGER_MODE | + CCM_PLL3_CTRL_N(n) | CCM_PLL3_CTRL_M(m), + &ccm->pll3_cfg); +} + void clock_set_pll5(unsigned int clk, bool sigma_delta_enable) { struct sunxi_ccm_reg * const ccm = @@ -224,6 +235,23 @@ void clock_set_mipi_pll(unsigned int clk) } #endif +void clock_set_pll10(unsigned int clk) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + const int m = 2; /* 12 MHz steps */ + + if (clk == 0) { + clrbits_le32(&ccm->pll10_cfg, CCM_PLL10_CTRL_EN); + return; + } + + /* PLL10 rate = 24000000 * n / m */ + writel(CCM_PLL10_CTRL_EN | CCM_PLL10_CTRL_INTEGER_MODE | + CCM_PLL10_CTRL_N(clk / (24000000 / m)) | CCM_PLL10_CTRL_M(m), + &ccm->pll10_cfg); +} + #ifdef CONFIG_MACH_SUN8I_A33 void clock_set_pll11(unsigned int clk, bool sigma_delta_enable) { diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index 09af3537b2d2..ed79563f840c 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -27,6 +27,11 @@ config SPL_POWER_SUPPORT config SPL_SERIAL_SUPPORT default y +config SUNXI_DE2 + bool + ---help--- + Select this for SoCs with DE2 instead of DE. + # Note only one of these may be selected at a time! But hidden choices are # not supported by Kconfig config SUNXI_GEN_SUN4I diff --git a/scripts/config_whitelist.txt b/scripts/config_whitelist.txt index 6d614c62ccf2..8de709b2d528 100644 --- a/scripts/config_whitelist.txt +++ b/scripts/config_whitelist.txt @@ -4274,6 +4274,7 @@ CONFIG_STV0991_HZ_CLOCK CONFIG_ST_SMI CONFIG_SUN4 CONFIG_SUNXI_AHCI +CONFIG_SUNXI_DE2 CONFIG_SUNXI_EMAC CONFIG_SUNXI_GMAC CONFIG_SUNXI_GPIO From 88cbcae36677a42e8da71860450149ed13e58f41 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Fri, 20 Jan 2017 01:21:02 +0800 Subject: [PATCH 10/18] sunxi: display: add simplefb support for V3s SoC V3s SoC features a DE2 composer. Add support for it. Signed-off-by: Icenowy Zheng --- arch/arm/include/asm/arch-sunxi/clock_sun6i.h | 7 +- arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 2 + arch/arm/include/asm/arch-sunxi/display.h | 119 ++++++++++++ arch/arm/include/asm/arch-sunxi/gpio.h | 2 + arch/arm/include/asm/arch-sunxi/pwm.h | 5 + arch/arm/mach-sunxi/clock_sun6i.c | 12 ++ board/sunxi/Kconfig | 1 + drivers/gpio/sunxi_gpio.c | 1 + drivers/video/sunxi_display.c | 175 ++++++++++++++++-- 9 files changed, 303 insertions(+), 21 deletions(-) diff --git a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h index 775943688f5d..4c494481c538 100644 --- a/arch/arm/include/asm/arch-sunxi/clock_sun6i.h +++ b/arch/arm/include/asm/arch-sunxi/clock_sun6i.h @@ -449,9 +449,13 @@ struct sunxi_ccm_reg { /* CCM bits common to all Display Engine 2.0 clock ctrl regs */ #define CCM_DE2_CTRL_M(n) ((((n) - 1) & 0xf) << 0) #define CCM_DE2_CTRL_PLL_MASK (3 << 24) +#ifndef CONFIG_MACH_SUN8I_V3S #define CCM_DE2_CTRL_PLL6_2X (0 << 24) #define CCM_DE2_CTRL_PLL10 (1 << 24) -#define CCM_DE2_CTRL_PLL3 (1 << 24) /* for V3s */ +#else +#define CCM_DE2_CTRL_PLL3 (0 << 24) /* for V3s */ +#define CCM_DE2_CTRL_PLL6_2X (2 << 24) +#endif #define CCM_DE2_CTRL_GATE (1 << 31) /* CCU security switch, H3 only */ @@ -470,6 +474,7 @@ void clock_set_mipi_pll(unsigned int hz); unsigned int clock_get_pll3(void); unsigned int clock_get_pll6(void); unsigned int clock_get_mipi_pll(void); +void clock_set_de2_mod_clock(u32 *clk_cfg, unsigned int hz); #endif #endif /* _SUNXI_CLOCK_SUN6I_H */ diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 3c852224e6a4..5184b3013b14 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -18,6 +18,8 @@ #define SUNXI_SRAM_D_BASE 0x00010000 /* 4 kiB */ #define SUNXI_SRAM_B_BASE 0x00020000 /* 64 kiB (secure) */ +#define SUNXI_DE2_BASE 0x01000000 + #ifdef CONFIG_MACH_SUN8I_A83T #define SUNXI_CPUCFG_BASE 0x01700000 #endif diff --git a/arch/arm/include/asm/arch-sunxi/display.h b/arch/arm/include/asm/arch-sunxi/display.h index b64f310b8bf1..9b56fd445613 100644 --- a/arch/arm/include/asm/arch-sunxi/display.h +++ b/arch/arm/include/asm/arch-sunxi/display.h @@ -157,6 +157,89 @@ struct sunxi_de_be_reg { u32 output_color_coef[12]; /* 0x9d0 */ }; +/* + * The following structures are for DE2. + * DE2 is a new generation of "composer" in some new Allwinner SoCs, such as + * A83T, H3, V3s, A64. + */ + +/* internal clock settings */ +struct de_clk { + u32 gate_cfg; + u32 bus_cfg; + u32 rst_cfg; + u32 div_cfg; + u32 sel_cfg; +}; + +/* global control */ +struct de_glb { + u32 ctl; + u32 status; + u32 dbuff; + u32 size; +}; + +/* alpha blending */ +struct de_bld { + u32 fcolor_ctl; /* 00 */ + struct { + u32 fcolor; + u32 insize; + u32 offset; + u32 dum; + } attr[4]; + u32 dum0[15]; /* (end of clear offset) */ + u32 route; /* 80 */ + u32 premultiply; + u32 bkcolor; + u32 output_size; + u32 bld_mode[4]; + u32 dum1[4]; + u32 ck_ctl; /* b0 */ + u32 ck_cfg; + u32 dum2[2]; + u32 ck_max[4]; /* c0 */ + u32 dum3[4]; + u32 ck_min[4]; /* e0 */ + u32 dum4[3]; + u32 out_ctl; /* fc */ +}; + +/* VI channel */ +struct de_vi { + struct { + u32 attr; + u32 size; + u32 coord; + u32 pitch[3]; + u32 top_laddr[3]; + u32 bot_laddr[3]; + } cfg[4]; + u32 fcolor[4]; /* c0 */ + u32 top_haddr[3]; /* d0 */ + u32 bot_haddr[3]; /* dc */ + u32 ovl_size[2]; /* e8 */ + u32 hori[2]; /* f0 */ + u32 vert[2]; /* f8 */ +}; + +struct de_ui { + struct { + u32 attr; + u32 size; + u32 coord; + u32 pitch; + u32 top_laddr; + u32 bot_laddr; + u32 fcolor; + u32 dum; + } cfg[4]; /* 00 */ + u32 top_haddr; /* 80 */ + u32 bot_haddr; + u32 ovl_size; /* 88 */ +}; + struct sunxi_lcdc_reg { u32 ctrl; /* 0x00 */ u32 int0; /* 0x04 */ @@ -346,6 +429,42 @@ struct sunxi_tve_reg { #define SUNXI_DE_BE_LAYER_ATTR1_FMT_XRGB8888 (0x09 << 8) #define SUNXI_DE_BE_OUTPUT_COLOR_CTRL_ENABLE 1 +/* + * DE2 register constants. + */ +#define SUNXI_DE2_MUX0_BASE (u8 *)(SUNXI_DE2_BASE + 0x100000) + +#define SUNXI_DE2_MUX_GLB_REGS 0x00000 +#define SUNXI_DE2_MUX_BLD_REGS 0x01000 +#define SUNXI_DE2_MUX_CHAN_REGS 0x02000 +#define SUNXI_DE2_MUX_CHAN_SZ 0x1000 +#define SUNXI_DE2_MUX_VSU_REGS 0x20000 +#define SUNXI_DE2_MUX_GSU1_REGS 0x30000 +#define SUNXI_DE2_MUX_GSU2_REGS 0x40000 +#define SUNXI_DE2_MUX_GSU3_REGS 0x50000 +#define SUNXI_DE2_MUX_FCE_REGS 0xa0000 +#define SUNXI_DE2_MUX_BWS_REGS 0xa2000 +#define SUNXI_DE2_MUX_LTI_REGS 0xa4000 +#define SUNXI_DE2_MUX_PEAK_REGS 0xa6000 +#define SUNXI_DE2_MUX_ASE_REGS 0xa8000 +#define SUNXI_DE2_MUX_FCC_REGS 0xaa000 +#define SUNXI_DE2_MUX_DCSC_REGS 0xb0000 + +#define SUNXI_DE2_FORMAT_ARGB_8888 0 +#define SUNXI_DE2_FORMAT_BGRA_8888 3 +#define SUNXI_DE2_FORMAT_XRGB_8888 4 +#define SUNXI_DE2_FORMAT_RGB_888 8 +#define SUNXI_DE2_FORMAT_BGR_888 9 + +#define SUNXI_DE2_MUX_GLB_CTL_RT_EN (1 << 0) + +#define SUNXI_DE2_UI_CFG_ATTR_EN (1 << 0) +#define SUNXI_DE2_UI_CFG_ATTR_ALPMOD(m) ((m & 3) << 1) +#define SUNXI_DE2_UI_CFG_ATTR_FMT(f) ((f & 0xf) << 8) +#define SUNXI_DE2_UI_CFG_ATTR_ALPHA(a) ((a & 0xff) << 24) + +#define SUNXI_DE2_WH(w, h) (((h - 1) << 16) | (w - 1)) + /* * LCDC register constants. */ diff --git a/arch/arm/include/asm/arch-sunxi/gpio.h b/arch/arm/include/asm/arch-sunxi/gpio.h index 24f85206c825..a681bdf005cd 100644 --- a/arch/arm/include/asm/arch-sunxi/gpio.h +++ b/arch/arm/include/asm/arch-sunxi/gpio.h @@ -151,6 +151,7 @@ enum sunxi_gpio_number { #define SUN8I_H3_GPA_UART0 2 #define SUN4I_GPB_PWM 2 +#define SUN8I_V3S_GPB_PWM 2 #define SUN4I_GPB_TWI0 2 #define SUN4I_GPB_TWI1 2 #define SUN5I_GPB_TWI1 2 @@ -176,6 +177,7 @@ enum sunxi_gpio_number { #define SUN5I_GPE_SDC2 3 #define SUN8I_GPE_TWI2 3 +#define SUN8I_V3S_GPE_LCD 3 #define SUNXI_GPF_SDC0 2 #define SUNXI_GPF_UART0 4 diff --git a/arch/arm/include/asm/arch-sunxi/pwm.h b/arch/arm/include/asm/arch-sunxi/pwm.h index 5884b5dbe7d4..c83ca377b408 100644 --- a/arch/arm/include/asm/arch-sunxi/pwm.h +++ b/arch/arm/include/asm/arch-sunxi/pwm.h @@ -31,4 +31,9 @@ #define SUNXI_PWM_MUX SUN8I_GPH_PWM #endif +#if defined CONFIG_MACH_SUN8I_V3S +#define SUNXI_PWM_PIN0 SUNXI_GPB(4) +#define SUNXI_PWM_MUX SUN8I_V3S_GPB_PWM +#endif + #endif diff --git a/arch/arm/mach-sunxi/clock_sun6i.c b/arch/arm/mach-sunxi/clock_sun6i.c index 2a5db8f30223..e8f8a30310c8 100644 --- a/arch/arm/mach-sunxi/clock_sun6i.c +++ b/arch/arm/mach-sunxi/clock_sun6i.c @@ -317,3 +317,15 @@ void clock_set_de_mod_clock(u32 *clk_cfg, unsigned int hz) writel(CCM_DE_CTRL_GATE | CCM_DE_CTRL_PLL6_2X | CCM_DE_CTRL_M(div), clk_cfg); } + +void clock_set_de2_mod_clock(u32 *clk_cfg, unsigned int hz) +{ + int pll = clock_get_pll6() * 2; + int div = 1; + + while ((pll / div) > hz) + div++; + + writel(CCM_DE2_CTRL_GATE | CCM_DE2_CTRL_PLL6_2X | CCM_DE2_CTRL_M(div), + clk_cfg); +} diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index ed79563f840c..a451f4797e91 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -136,6 +136,7 @@ config MACH_SUN8I_V3S select SUPPORT_SPL select SUNXI_H3_DW_DRAM select SUNXI_H3_DRAM_DDR2 + select SUNXI_DE2 select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT config MACH_SUN9I diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c index e8accaa33302..a79907ce66a8 100644 --- a/drivers/gpio/sunxi_gpio.c +++ b/drivers/gpio/sunxi_gpio.c @@ -352,6 +352,7 @@ static const struct udevice_id sunxi_gpio_ids[] = { ID("allwinner,sun8i-a33-pinctrl", a_all), ID("allwinner,sun8i-a83t-pinctrl", a_all), ID("allwinner,sun8i-h3-pinctrl", a_all), + ID("allwinner,sun8i-v3s-pinctrl", a_all), ID("allwinner,sun9i-a80-pinctrl", a_all), ID("allwinner,sun6i-a31-r-pinctrl", l_2), ID("allwinner,sun8i-a23-r-pinctrl", l_1), diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index 6f8ee01c1072..a4bcc9a8a03c 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -1,3 +1,5 @@ +#define DEBUG + /* * Display driver for Allwinner SoCs. * @@ -297,6 +299,26 @@ static int sunxi_hdmi_edid_get_mode(struct ctfb_res_modes *mode) #endif /* CONFIG_VIDEO_HDMI */ +static bool sunxi_is_composite(void) +{ + switch (sunxi_display.monitor) { + case sunxi_monitor_none: + case sunxi_monitor_dvi: + case sunxi_monitor_hdmi: + case sunxi_monitor_lcd: + case sunxi_monitor_vga: + return false; + case sunxi_monitor_composite_pal: + case sunxi_monitor_composite_ntsc: + case sunxi_monitor_composite_pal_m: + case sunxi_monitor_composite_pal_nc: + return true; + } + + return false; /* Never reached */ +} + +#ifndef CONFIG_SUNXI_DE2 #ifdef CONFIG_MACH_SUN4I /* * Testing has shown that on sun4i the display backend engine does not have @@ -405,25 +427,6 @@ static void sunxi_frontend_mode_set(const struct ctfb_res_modes *mode, static void sunxi_frontend_enable(void) {} #endif -static bool sunxi_is_composite(void) -{ - switch (sunxi_display.monitor) { - case sunxi_monitor_none: - case sunxi_monitor_dvi: - case sunxi_monitor_hdmi: - case sunxi_monitor_lcd: - case sunxi_monitor_vga: - return false; - case sunxi_monitor_composite_pal: - case sunxi_monitor_composite_ntsc: - case sunxi_monitor_composite_pal_m: - case sunxi_monitor_composite_pal_nc: - return true; - } - - return false; /* Never reached */ -} - /* * This is the entity that mixes and matches the different layers and inputs. * Allwinner calls it the back-end, but i like composer better. @@ -512,6 +515,127 @@ static void sunxi_composer_enable(void) setbits_le32(&de_be->reg_ctrl, SUNXI_DE_BE_REG_CTRL_LOAD_REGS); setbits_le32(&de_be->mode, SUNXI_DE_BE_MODE_START); } +#else /* CONFIG_SUNXI_DE2 */ +/* + * This is the entity that mixes and matches the different layers and inputs. + * Allwinner calls it display engine (DE 2.0), but here is called composer. + */ +static void sunxi_composer_init(void) +{ + struct sunxi_ccm_reg * const ccm = + (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; + +#ifndef CONFIG_MACH_SUN8I_V3S + clock_set_pll10(432000000); + + /* Set DE parent to pll10 */ + clrsetbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_PLL_MASK, + CCM_DE2_CTRL_PLL10); +#else + clock_set_de2_mod_clock(&ccm->de_clk_cfg, 300000000); +#endif + + /* Set ahb gating to pass */ + setbits_le32(&ccm->ahb_reset1_cfg, 1 << AHB_RESET_OFFSET_DE); + setbits_le32(&ccm->ahb_gate1, 1 << AHB_GATE_OFFSET_DE); + + /* Clock on */ + setbits_le32(&ccm->de_clk_cfg, CCM_DE2_CTRL_GATE); +} + +static void sunxi_composer_mode_set(const struct ctfb_res_modes *mode, + unsigned int address) +{ + struct de_clk * const de_clk_regs = + (struct de_clk *)(SUNXI_DE2_BASE); + struct de_glb * const de_glb_regs = + (struct de_glb *)(SUNXI_DE2_MUX0_BASE + + SUNXI_DE2_MUX_GLB_REGS); + struct de_bld * const de_bld_regs = + (struct de_bld *)(SUNXI_DE2_MUX0_BASE + + SUNXI_DE2_MUX_BLD_REGS); + struct de_ui * const de_ui_regs = + (struct de_ui *)(SUNXI_DE2_MUX0_BASE + + SUNXI_DE2_MUX_CHAN_REGS + + SUNXI_DE2_MUX_CHAN_SZ * 2); + u32 size = SUNXI_DE2_WH(mode->xres, mode->yres); + int channel, i; + u32 data; + + /* enable clock */ + setbits_le32(&de_clk_regs->rst_cfg, 1); + setbits_le32(&de_clk_regs->gate_cfg, 1); + setbits_le32(&de_clk_regs->bus_cfg, 1); + + clrbits_le32(&de_clk_regs->sel_cfg, 1); + + writel(SUNXI_DE2_MUX_GLB_CTL_RT_EN, &de_glb_regs->ctl); + writel(0, &de_glb_regs->status); + writel(1, &de_glb_regs->dbuff); + writel(size, &de_glb_regs->size); + + for (channel = 0; channel < 4; channel++) { + void *chan = SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_CHAN_REGS + + SUNXI_DE2_MUX_CHAN_SZ * channel; + memset(chan, 0, channel == 0 ? + sizeof(struct de_vi) : sizeof(struct de_ui)); + } + memset(de_bld_regs, 0, sizeof(struct de_bld)); + + writel(0x00000101, &de_bld_regs->fcolor_ctl); + + writel(2, &de_bld_regs->route); + + writel(0, &de_bld_regs->premultiply); + writel(0xff000000, &de_bld_regs->bkcolor); + + writel(0x03010301, &de_bld_regs->bld_mode[0]); + writel(0x03010301, &de_bld_regs->bld_mode[1]); + + writel(size, &de_bld_regs->output_size); + writel(mode->vmode & FB_VMODE_INTERLACED ? 2 : 0, + &de_bld_regs->out_ctl); + writel(0, &de_bld_regs->ck_ctl); + + for (i = 0; i < 4; i++) { + writel(0xff000000, &de_bld_regs->attr[i].fcolor); + writel(size, &de_bld_regs->attr[i].insize); + } + + /* Disable all other units */ + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_VSU_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_GSU1_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_GSU2_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_GSU3_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_FCE_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_BWS_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_LTI_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_PEAK_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_ASE_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_FCC_REGS); + writel(0, SUNXI_DE2_MUX0_BASE + SUNXI_DE2_MUX_DCSC_REGS); + + data = SUNXI_DE2_UI_CFG_ATTR_EN | + SUNXI_DE2_UI_CFG_ATTR_FMT(SUNXI_DE2_FORMAT_XRGB_8888) | + SUNXI_DE2_UI_CFG_ATTR_ALPMOD(1) | + SUNXI_DE2_UI_CFG_ATTR_ALPHA(0xff); + writel(data, &de_ui_regs->cfg[0].attr); + writel(size, &de_ui_regs->cfg[0].size); + writel(0, &de_ui_regs->cfg[0].coord); + writel(4 * mode->xres, &de_ui_regs->cfg[0].pitch); + writel(address, &de_ui_regs->cfg[0].top_laddr); + writel(size, &de_ui_regs->ovl_size); +} + +static void sunxi_composer_enable(void) +{ + struct de_glb * const de_glb_regs = + (struct de_glb *)(SUNXI_DE2_MUX0_BASE + + SUNXI_DE2_MUX_GLB_REGS); + + writel(1, &de_glb_regs->dbuff); +} +#endif /* CONFIG_SUNXI_DE2 */ /* * LCDC, what allwinner calls a CRTC, so timing controller and serializer. @@ -562,6 +686,8 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock, if (!(m & 1)) continue; + /* TCONs with DE2 do not support double clock */ +#ifndef CONFIG_SUNXI_DE2 n = (m * dotclock) / 6000; if ((n >= 9) && (n <= 127)) { value = (6000 * n) / m; @@ -573,6 +699,7 @@ static void sunxi_lcdc_pll_set(int tcon, int dotclock, best_double = 1; } } +#endif } #ifdef CONFIG_MACH_SUN6I @@ -778,6 +905,7 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, (struct sunxi_lcdc_reg *)SUNXI_LCD0_BASE; int bp, clk_delay, clk_div, clk_double, pin, total, val; +#ifndef CONFIG_MACH_SUN8I_V3S #if defined CONFIG_MACH_SUN8I && defined CONFIG_VIDEO_LCD_IF_LVDS for (pin = SUNXI_GPD(18); pin <= SUNXI_GPD(27); pin++) { #else @@ -793,6 +921,13 @@ static void sunxi_lcdc_tcon0_mode_set(const struct ctfb_res_modes *mode, sunxi_gpio_set_drv(pin, 3); #endif } +#else /* CONFIG_MACH_SUN8I_V3S */ + for (pin = SUNXI_GPE(0); pin <= SUNXI_GPE(24); pin++) { + if (pin >= SUNXI_GPE(20) && pin <= SUNXI_GPE(22)) + continue; /* These pins are not LCD */ + sunxi_gpio_set_cfgpin(pin, SUN8I_V3S_GPE_LCD); + } +#endif /* !CONFIG_MACH_SUN8I_V3S */ sunxi_lcdc_pll_set(0, mode->pixclock_khz, &clk_div, &clk_double); @@ -1141,7 +1276,7 @@ static void sunxi_tvencoder_enable(void) static void sunxi_drc_init(void) { -#ifdef CONFIG_SUNXI_GEN_SUN6I +#if defined CONFIG_SUNXI_GEN_SUN6I && !defined CONFIG_SUNXI_DE2 struct sunxi_ccm_reg * const ccm = (struct sunxi_ccm_reg *)SUNXI_CCM_BASE; From d282076db0c49749f062aa5c8276d7f063332b0b Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sun, 15 Jan 2017 13:37:59 +0800 Subject: [PATCH 11/18] sunxi: display: change pipeline string for DE2 DE2 do not have dedicated BE or FE. Remove the "_be" suffix in the pipeline string of DE2. Signed-off-by: Icenowy Zheng --- drivers/video/sunxi_display.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/drivers/video/sunxi_display.c b/drivers/video/sunxi_display.c index a4bcc9a8a03c..7049a3cbdcc8 100644 --- a/drivers/video/sunxi_display.c +++ b/drivers/video/sunxi_display.c @@ -1663,9 +1663,11 @@ int sunxi_simplefb_setup(void *blob) const char *pipeline = NULL; #ifdef CONFIG_MACH_SUN4I -#define PIPELINE_PREFIX "de_fe0-" +#define PIPELINE_PREFIX "de_fe0-de_be0-" +#elif defined CONFIG_SUNXI_DE2 +#define PIPELINE_PREFIX "de0-" #else -#define PIPELINE_PREFIX +#define PIPELINE_PREFIX "de_be0-" #endif switch (sunxi_display.monitor) { @@ -1673,16 +1675,16 @@ int sunxi_simplefb_setup(void *blob) return 0; case sunxi_monitor_dvi: case sunxi_monitor_hdmi: - pipeline = PIPELINE_PREFIX "de_be0-lcd0-hdmi"; + pipeline = PIPELINE_PREFIX "lcd0-hdmi"; break; case sunxi_monitor_lcd: - pipeline = PIPELINE_PREFIX "de_be0-lcd0"; + pipeline = PIPELINE_PREFIX "lcd0"; break; case sunxi_monitor_vga: #ifdef CONFIG_VIDEO_VGA - pipeline = PIPELINE_PREFIX "de_be0-lcd0-tve0"; + pipeline = PIPELINE_PREFIX "lcd0-tve0"; #elif defined CONFIG_VIDEO_VGA_VIA_LCD - pipeline = PIPELINE_PREFIX "de_be0-lcd0"; + pipeline = PIPELINE_PREFIX "lcd0"; #endif break; case sunxi_monitor_composite_pal: From cd94d29394aa0259e071da36abb278c6aa00fe05 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Thu, 13 Apr 2017 23:41:01 +0800 Subject: [PATCH 12/18] add Lichee Pi Zero with LCD defconfig's Signed-off-by: Icenowy Zheng --- configs/LicheePi_Zero_480x272LCD_defconfig | 19 +++++++++++++++++++ configs/LicheePi_Zero_800x480LCD_defconfig | 19 +++++++++++++++++++ 2 files changed, 38 insertions(+) create mode 100644 configs/LicheePi_Zero_480x272LCD_defconfig create mode 100644 configs/LicheePi_Zero_800x480LCD_defconfig diff --git a/configs/LicheePi_Zero_480x272LCD_defconfig b/configs/LicheePi_Zero_480x272LCD_defconfig new file mode 100644 index 000000000000..685c52241c2c --- /dev/null +++ b/configs/LicheePi_Zero_480x272LCD_defconfig @@ -0,0 +1,19 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +# CONFIG_ARMV7_NONSEC is not set +CONFIG_MACH_SUN8I_V3S=y +CONFIG_DRAM_CLK=360 +CONFIG_DRAM_ZQ=14779 +CONFIG_VIDEO_LCD_MODE="x:480,y:272,depth:18,pclk_khz:10000,le:42,ri:8,up:11,lo:4,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_BL_PWM="PB4" +# CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW is not set +CONFIG_DEFAULT_DEVICE_TREE="sun8i-v3s-licheepi-zero" +# CONFIG_CONSOLE_MUX is not set +CONFIG_SPL=y +CONFIG_CMD_BOOTMENU=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_MEMINFO=y +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_NETDEVICES is not set +CONFIG_OF_LIBFDT_OVERLAY=y diff --git a/configs/LicheePi_Zero_800x480LCD_defconfig b/configs/LicheePi_Zero_800x480LCD_defconfig new file mode 100644 index 000000000000..ef179534a35e --- /dev/null +++ b/configs/LicheePi_Zero_800x480LCD_defconfig @@ -0,0 +1,19 @@ +CONFIG_ARM=y +CONFIG_ARCH_SUNXI=y +# CONFIG_ARMV7_NONSEC is not set +CONFIG_MACH_SUN8I_V3S=y +CONFIG_DRAM_CLK=360 +CONFIG_DRAM_ZQ=14779 +CONFIG_VIDEO_LCD_MODE="x:800,y:480,depth:18,pclk_khz:33000,le:87,ri:40,up:31,lo:13,hs:1,vs:1,sync:3,vmode:0" +CONFIG_VIDEO_LCD_BL_PWM="PB4" +# CONFIG_VIDEO_LCD_BL_PWM_ACTIVE_LOW is not set +CONFIG_DEFAULT_DEVICE_TREE="sun8i-v3s-licheepi-zero" +# CONFIG_CONSOLE_MUX is not set +CONFIG_SPL=y +CONFIG_CMD_BOOTMENU=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_MEMINFO=y +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_FPGA is not set +# CONFIG_NETDEVICES is not set +CONFIG_OF_LIBFDT_OVERLAY=y From a297a99445bc828760e9917d6efa0ecb99444116 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 20 May 2017 23:43:46 +0800 Subject: [PATCH 13/18] sunxi: enable fdt overlay in lcd-less Lichee Pi Zero defconfig Signed-off-by: Icenowy Zheng --- configs/LicheePi_Zero_defconfig | 1 + 1 file changed, 1 insertion(+) diff --git a/configs/LicheePi_Zero_defconfig b/configs/LicheePi_Zero_defconfig index 42414a81a73e..6ab4f1a245d9 100644 --- a/configs/LicheePi_Zero_defconfig +++ b/configs/LicheePi_Zero_defconfig @@ -11,3 +11,4 @@ CONFIG_SPL=y # CONFIG_CMD_FLASH is not set # CONFIG_CMD_FPGA is not set # CONFIG_NETDEVICES is not set +CONFIG_OF_LIBFDT_OVERLAY=y From 32ab1804cd7c5858be8009e35ca07502dc8765c7 Mon Sep 17 00:00:00 2001 From: Icenowy Zheng Date: Sat, 12 Aug 2017 17:24:24 +0800 Subject: [PATCH 14/18] sunxi: fix SMP bit for V3s SoC The cache of Cortex-A7 is only enabled if the SMP bit is set, but the SMP bit of V3s is wrongly left unset, because I thought that it's not SMP-capable. Fix this. Signed-off-by: Icenowy Zheng --- arch/arm/mach-sunxi/board.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/arch/arm/mach-sunxi/board.c b/arch/arm/mach-sunxi/board.c index 3b28478e2d28..7a55ee335243 100644 --- a/arch/arm/mach-sunxi/board.c +++ b/arch/arm/mach-sunxi/board.c @@ -184,11 +184,10 @@ void s_init(void) /* No H3 BSP, boot0 seems to not modify SUNXI_SRAMC_BASE + 0x44 */ #endif -#if (defined CONFIG_MACH_SUN6I || \ +#if defined CONFIG_MACH_SUN6I || \ defined CONFIG_MACH_SUN7I || \ defined CONFIG_MACH_SUN8I || \ - defined CONFIG_MACH_SUN9I) && \ - !defined CONFIG_MACH_SUN8I_V3S + defined CONFIG_MACH_SUN9I /* Enable SMP mode for CPU0, by setting bit 6 of Auxiliary Ctl reg */ asm volatile( "mrc p15, 0, r0, c1, c0, 1\n" From f239f3ac4aac942ca05f7723efddb471b692616b Mon Sep 17 00:00:00 2001 From: ujuo Date: Fri, 18 Aug 2017 18:03:55 +0900 Subject: [PATCH 15/18] sunxi:Add usb ethernet supprot for V3s SoC --- arch/arm/Kconfig | 10 +- arch/arm/dts/Makefile | 3 +- arch/arm/dts/sun8i-v3s-camdroid.dts | 98 +++ arch/arm/dts/sun8i-v3s.dtsi | 31 + arch/arm/include/asm/arch-sunxi/cpu_sun4i.h | 4 + arch/arm/mach-sunxi/usb_phy.c | 11 +- board/sunxi/Kconfig | 6 + configs/sun8i_v3s_camdroid_defconfig | 852 ++++++++++++++++++++ drivers/gpio/Kconfig | 6 + drivers/usb/eth/asix.c | 238 +++++- drivers/usb/eth/usb_ether.c | 5 +- drivers/usb/musb-new/musb_regs.h | 7 +- drivers/usb/musb-new/musb_uboot.c | 15 +- drivers/usb/musb-new/sunxi.c | 44 +- include/configs/sun8i.h | 2 + include/configs/sunxi-common.h | 5 +- 16 files changed, 1310 insertions(+), 27 deletions(-) create mode 100644 arch/arm/dts/sun8i-v3s-camdroid.dts create mode 100644 configs/sun8i_v3s_camdroid_defconfig diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig index d871a45d4647..c3ddfad6ff8a 100644 --- a/arch/arm/Kconfig +++ b/arch/arm/Kconfig @@ -572,11 +572,11 @@ config ARCH_SUNXI select CMD_MMC if MMC select CMD_USB if DISTRO_DEFAULTS select DM - select DM_ETH +# select DM_ETH select DM_GPIO - select DM_KEYBOARD +# select DM_KEYBOARD select DM_SERIAL - select DM_USB if DISTRO_DEFAULTS +# select DM_USB if DISTRO_DEFAULTS select OF_BOARD_SETUP select OF_CONTROL select OF_SEPARATE @@ -584,8 +584,8 @@ config ARCH_SUNXI select SPL_SYS_MALLOC_SIMPLE if SUPPORT_SPL select SYS_NS16550 select USB if DISTRO_DEFAULTS - select USB_STORAGE if DISTRO_DEFAULTS - select USB_KEYBOARD if DISTRO_DEFAULTS +# select USB_STORAGE if DISTRO_DEFAULTS +# select USB_KEYBOARD if DISTRO_DEFAULTS select USE_TINY_PRINTF config TARGET_TS4600 diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile index 469dd710cf67..e00ce9bcfc92 100644 --- a/arch/arm/dts/Makefile +++ b/arch/arm/dts/Makefile @@ -281,7 +281,8 @@ dtb-$(CONFIG_MACH_SUN8I_H3) += \ sun8i-h3-orangepi-plus2e.dtb \ sun8i-h3-nanopi-neo.dtb dtb-$(CONFIG_MACH_SUN8I_V3S) += \ - sun8i-v3s-licheepi-zero.dtb + sun8i-v3s-licheepi-zero.dtb \ + sun8i-v3s-camdroid.dtb dtb-$(CONFIG_MACH_SUN50I) += \ sun50i-a64-pine64-plus.dtb \ sun50i-a64-pine64.dtb diff --git a/arch/arm/dts/sun8i-v3s-camdroid.dts b/arch/arm/dts/sun8i-v3s-camdroid.dts new file mode 100644 index 000000000000..aea2d7c0b38d --- /dev/null +++ b/arch/arm/dts/sun8i-v3s-camdroid.dts @@ -0,0 +1,98 @@ +/* + * Copyright (C) 2017 JuYoung Ryu + * Copyright (C) 2016 Icenowy Zheng + * + * This file is dual-licensed: you can use it either under the terms + * of the GPL or the X11 license, at your option. Note that this dual + * licensing only applies to this file, and not this project as a + * whole. + * + * a) This file is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License as + * published by the Free Software Foundation; either version 2 of the + * License, or (at your option) any later version. + * + * This file is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * Or, alternatively, + * + * b) Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall be + * included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + */ + +/dts-v1/; +#include "sun8i-v3s.dtsi" +#include "sunxi-common-regulators.dtsi" + +/ { + model = "Camdroid"; + compatible = "licheepi,licheepi-zero", "allwinner,sun8i-v3s"; + + aliases { + serial0 = &uart0; + spi0 = &spi0; + }; + + chosen { + stdout-path = "serial0:115200n8"; + }; +}; + +&mmc0 { + pinctrl-0 = <&mmc0_pins_a>; + pinctrl-names = "default"; + broken-cd; + bus-width = <4>; + vmmc-supply = <®_vcc3v3>; + status = "okay"; +}; + +&spi0 { + status = "okay"; +}; + +&uart0 { + pinctrl-0 = <&uart0_pins_a>; + pinctrl-names = "default"; + status = "okay"; +}; + +&usb_otg { + dr_mode = "host"; + status = "okay"; +}; + +&usbphy { + pinctrl-names = "default"; + usb0_id_det-gpio = <&pio 6 4 GPIO_ACTIVE_HIGH>; + usb0_vbus-supply = <®_usb0_vbus>; + status = "okay"; +}; + +&ehci1 { + pinctrl-names = "default"; +/* usb0_id_det-gpio = <&pio 6 4 GPIO_ACTIVE_HIGH>; + usb0_vbus-supply = <®_usb0_vbus>; */ + status = "okay"; +}; diff --git a/arch/arm/dts/sun8i-v3s.dtsi b/arch/arm/dts/sun8i-v3s.dtsi index ebefc0fefef2..1efcada6cfb9 100644 --- a/arch/arm/dts/sun8i-v3s.dtsi +++ b/arch/arm/dts/sun8i-v3s.dtsi @@ -1,4 +1,5 @@ /* + * Copyright (C) 2017 JuYoung Ryu * Copyright (C) 2016 Icenowy Zheng * * This file is dual-licensed: you can use it either under the terms @@ -180,6 +181,17 @@ #phy-cells = <1>; }; + ehci1: usb@01c1a000 { + compatible = "allwinner,sun8i-a23-ehci","generic-ehci"; + reg = <0x01c1a000 0x100>; + interrupts = ; + clocks = <&ccu CLK_BUS_EHCI0>; + phys = <&usbphy>; + phy-names = "usb"; + resets = <&ccu RST_BUS_EHCI0>; + status = "disabled"; + }; + ccu: clock@01c20000 { compatible = "allwinner,sun8i-v3s-ccu"; reg = <0x01c20000 0x400>; @@ -221,6 +233,11 @@ drive-strength = <30>; bias-pull-up; }; + + spi0_pins: spi0 { + pins = "PC0", "PC1", "PC2", "PC3"; + function = "spi0"; + }; }; timer@01c20c00 { @@ -270,6 +287,20 @@ status = "disabled"; }; + spi0: spi@1c68000 { + compatible = "allwinner,sun8i-h3-spi"; + reg = <0x01c68000 0x1000>; + interrupts = ; + clocks = <&ccu CLK_BUS_SPI0>, <&ccu CLK_SPI0>; + clock-names = "ahb", "mod"; + pinctrl-names = "default"; + pinctrl-0 = <&spi0_pins>; + resets = <&ccu RST_BUS_SPI0>; + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + }; + gic: interrupt-controller@01c81000 { compatible = "arm,cortex-a7-gic", "arm,cortex-a15-gic"; reg = <0x01c81000 0x1000>, diff --git a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h index 5184b3013b14..2d651d990cbe 100644 --- a/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h +++ b/arch/arm/include/asm/arch-sunxi/cpu_sun4i.h @@ -64,6 +64,10 @@ #define SUNXI_USB1_BASE 0x01c1b000 #define SUNXI_USB2_BASE 0x01c1c000 #define SUNXI_USB3_BASE 0x01c1d000 +#elif defined(CONFIG_MACH_SUN8I_V3S) +#define SUNXI_USBPHY_BASE 0x01c19000 +#define SUNXI_USB0_BASE 0x01c19000 +#define SUNXI_USB1_BASE 0x01c1a000 #else #define SUNXI_USB0_BASE 0x01c19000 #define SUNXI_USB1_BASE 0x01c1a000 diff --git a/arch/arm/mach-sunxi/usb_phy.c b/arch/arm/mach-sunxi/usb_phy.c index 278587b4933b..53850daba7df 100644 --- a/arch/arm/mach-sunxi/usb_phy.c +++ b/arch/arm/mach-sunxi/usb_phy.c @@ -19,7 +19,7 @@ #include #define SUNXI_USB_PMU_IRQ_ENABLE 0x800 -#ifdef CONFIG_MACH_SUN8I_A33 +#if defined CONFIG_MACH_SUN8I_A33 || defined(CONFIG_MACH_SUN8I_V3S) #define SUNXI_USB_CSR 0x410 #else #define SUNXI_USB_CSR 0x404 @@ -120,7 +120,7 @@ __maybe_unused static void usb_phy_write(struct sunxi_usb_phy *phy, int addr, int j = 0, usbc_bit = 0; void *dest = (void *)SUNXI_USB0_BASE + SUNXI_USB_CSR; -#ifdef CONFIG_MACH_SUN8I_A33 +#if defined CONFIG_MACH_SUN8I_A33 || defined(CONFIG_MACH_SUN8I_V3S) /* CSR needs to be explicitly initialized to 0 on A33 */ writel(0, dest); #endif @@ -165,7 +165,10 @@ static void sunxi_usb_phy_config(struct sunxi_usb_phy *phy) /* The following comments are machine * translated from Chinese, you have been warned! */ - +#if defined(CONFIG_MACH_SUN8I_V3S) + if (phy->id != 0) + clrbits_le32(phy->base + REG_PMU_UNK_H3, 0x02); +#endif /* Regulation 45 ohms */ if (phy->id == 0) usb_phy_write(phy, 0x0c, 0x01, 1); @@ -351,11 +354,13 @@ int sunxi_usb_phy_probe(void) phy->gpio_vbus_det = get_vbus_detect_gpio(i); if (phy->gpio_vbus_det >= 0) { ret = gpio_request(phy->gpio_vbus_det, "usb_vbus_det"); +#ifndef CONFIG_SUN8I_V3S_CAM if (ret) return ret; ret = gpio_direction_input(phy->gpio_vbus_det); if (ret) return ret; +#endif } phy->gpio_id_det = get_id_detect_gpio(i); diff --git a/board/sunxi/Kconfig b/board/sunxi/Kconfig index a451f4797e91..1f02e47d7f3f 100644 --- a/board/sunxi/Kconfig +++ b/board/sunxi/Kconfig @@ -139,6 +139,12 @@ config MACH_SUN8I_V3S select SUNXI_DE2 select ARMV7_BOOT_SEC_DEFAULT if OLD_SUNXI_KERNEL_COMPAT +config SUN8I_V3S_CAM + bool "sun8i v3s camdroid board" + depends on MACH_SUN8I_V3S + help + Support Camdroid board's usb ethernet. + config MACH_SUN9I bool "sun9i (Allwinner A80)" select CPU_V7 diff --git a/configs/sun8i_v3s_camdroid_defconfig b/configs/sun8i_v3s_camdroid_defconfig new file mode 100644 index 000000000000..e729b94e56a4 --- /dev/null +++ b/configs/sun8i_v3s_camdroid_defconfig @@ -0,0 +1,852 @@ +# +# Automatically generated file; DO NOT EDIT. +# U-Boot 2017.01-rc2 Configuration +# +CONFIG_CREATE_ARCH_SYMLINK=y +# CONFIG_ARC is not set +CONFIG_ARM=y +# CONFIG_AVR32 is not set +# CONFIG_BLACKFIN is not set +# CONFIG_M68K is not set +# CONFIG_MICROBLAZE is not set +# CONFIG_MIPS is not set +# CONFIG_NDS32 is not set +# CONFIG_NIOS2 is not set +# CONFIG_OPENRISC is not set +# CONFIG_PPC is not set +# CONFIG_SANDBOX is not set +# CONFIG_SH is not set +# CONFIG_SPARC is not set +# CONFIG_X86 is not set +# CONFIG_XTENSA is not set +CONFIG_SYS_ARCH="arm" +CONFIG_SYS_CPU="armv7" +CONFIG_SYS_SOC="sunxi" +CONFIG_SYS_BOARD="sunxi" +CONFIG_SYS_CONFIG_NAME="sun8i" + +# +# ARM architecture +# +CONFIG_HAS_VBAR=y +CONFIG_HAS_THUMB2=y +CONFIG_CPU_V7=y +CONFIG_SYS_ARM_ARCH=7 +CONFIG_SYS_CACHE_SHIFT_6=y +CONFIG_SYS_CACHELINE_SIZE=64 +# CONFIG_SEMIHOSTING is not set +# CONFIG_SYS_L2CACHE_OFF is not set +# CONFIG_ENABLE_ARM_SOC_BOOT0_HOOK is not set +# CONFIG_ARM64_SUPPORT_AARCH32 is not set +# CONFIG_ARCH_AT91 is not set +# CONFIG_TARGET_EDB93XX is not set +# CONFIG_TARGET_ASPENITE is not set +# CONFIG_TARGET_GPLUGD is not set +# CONFIG_ARCH_DAVINCI is not set +# CONFIG_KIRKWOOD is not set +# CONFIG_ARCH_MVEBU is not set +# CONFIG_TARGET_DEVKIT3250 is not set +# CONFIG_TARGET_WORK_92105 is not set +# CONFIG_TARGET_MX25PDK is not set +# CONFIG_TARGET_ZMX25 is not set +# CONFIG_TARGET_APF27 is not set +# CONFIG_TARGET_APX4DEVKIT is not set +# CONFIG_TARGET_XFI3 is not set +# CONFIG_TARGET_M28EVK is not set +# CONFIG_TARGET_MX23EVK is not set +# CONFIG_TARGET_MX28EVK is not set +# CONFIG_TARGET_MX23_OLINUXINO is not set +# CONFIG_TARGET_BG0900 is not set +# CONFIG_TARGET_SANSA_FUZE_PLUS is not set +# CONFIG_TARGET_SC_SPS_1 is not set +# CONFIG_ORION5X is not set +# CONFIG_TARGET_SPEAR300 is not set +# CONFIG_TARGET_SPEAR310 is not set +# CONFIG_TARGET_SPEAR320 is not set +# CONFIG_TARGET_SPEAR600 is not set +# CONFIG_TARGET_STV0991 is not set +# CONFIG_TARGET_X600 is not set +# CONFIG_TARGET_IMX31_PHYCORE is not set +# CONFIG_TARGET_MX31ADS is not set +# CONFIG_TARGET_MX31PDK is not set +# CONFIG_TARGET_WOODBURN is not set +# CONFIG_TARGET_WOODBURN_SD is not set +# CONFIG_TARGET_FLEA3 is not set +# CONFIG_TARGET_MX35PDK is not set +# CONFIG_ARCH_BCM283X is not set +# CONFIG_TARGET_VEXPRESS_CA15_TC2 is not set +# CONFIG_TARGET_VEXPRESS_CA5X2 is not set +# CONFIG_TARGET_VEXPRESS_CA9X4 is not set +# CONFIG_TARGET_BRXRE1 is not set +# CONFIG_TARGET_BRPPT1 is not set +# CONFIG_TARGET_DRACO is not set +# CONFIG_TARGET_THUBAN is not set +# CONFIG_TARGET_RASTABAN is not set +# CONFIG_TARGET_ETAMIN is not set +# CONFIG_TARGET_PXM2 is not set +# CONFIG_TARGET_RUT is not set +# CONFIG_TARGET_TI814X_EVM is not set +# CONFIG_TARGET_TI816X_EVM is not set +# CONFIG_TARGET_BCM23550_W1D is not set +# CONFIG_TARGET_BCM28155_AP is not set +# CONFIG_TARGET_BCMCYGNUS is not set +# CONFIG_TARGET_BCMNSP is not set +# CONFIG_ARCH_EXYNOS is not set +# CONFIG_ARCH_S5PC1XX is not set +# CONFIG_ARCH_HIGHBANK is not set +# CONFIG_ARCH_INTEGRATOR is not set +# CONFIG_ARCH_KEYSTONE is not set +# CONFIG_ARCH_MESON is not set +# CONFIG_ARCH_MX7 is not set +# CONFIG_ARCH_MX6 is not set +# CONFIG_ARCH_MX5 is not set +# CONFIG_TARGET_M53EVK is not set +# CONFIG_TARGET_MX51EVK is not set +# CONFIG_TARGET_MX53ARD is not set +# CONFIG_TARGET_MX53EVK is not set +# CONFIG_TARGET_MX53LOCO is not set +# CONFIG_TARGET_MX53SMD is not set +# CONFIG_OMAP34XX is not set +# CONFIG_OMAP44XX is not set +# CONFIG_OMAP54XX is not set +# CONFIG_AM43XX is not set +# CONFIG_AM33XX is not set +# CONFIG_ARCH_RMOBILE is not set +# CONFIG_TARGET_S32V234EVB is not set +# CONFIG_ARCH_SNAPDRAGON is not set +# CONFIG_ARCH_SOCFPGA is not set +# CONFIG_TARGET_CM_T43 is not set +CONFIG_ARCH_SUNXI=y +# CONFIG_TARGET_TS4600 is not set +# CONFIG_TARGET_TS4800 is not set +# CONFIG_TARGET_VF610TWR is not set +# CONFIG_TARGET_COLIBRI_VF is not set +# CONFIG_TARGET_PCM052 is not set +# CONFIG_TARGET_BK4R1 is not set +# CONFIG_ARCH_ZYNQ is not set +# CONFIG_ARCH_ZYNQMP is not set +# CONFIG_TEGRA is not set +# CONFIG_TARGET_VEXPRESS64_AEMV8A is not set +# CONFIG_TARGET_VEXPRESS64_BASE_FVP is not set +# CONFIG_TARGET_VEXPRESS64_BASE_FVP_DRAM is not set +# CONFIG_TARGET_VEXPRESS64_JUNO is not set +# CONFIG_TARGET_LS2080A_EMU is not set +# CONFIG_TARGET_LS2080A_SIMU is not set +# CONFIG_TARGET_LS2080AQDS is not set +# CONFIG_TARGET_LS2080ARDB is not set +# CONFIG_TARGET_HIKEY is not set +# CONFIG_TARGET_LS1012AQDS is not set +# CONFIG_TARGET_LS1012ARDB is not set +# CONFIG_TARGET_LS1012AFRDM is not set +# CONFIG_TARGET_LS1021AQDS is not set +# CONFIG_TARGET_LS1021ATWR is not set +# CONFIG_TARGET_LS1021AIOT is not set +# CONFIG_TARGET_LS1043AQDS is not set +# CONFIG_TARGET_LS1043ARDB is not set +# CONFIG_TARGET_LS1046AQDS is not set +# CONFIG_TARGET_LS1046ARDB is not set +# CONFIG_TARGET_H2200 is not set +# CONFIG_TARGET_ZIPITZ2 is not set +# CONFIG_TARGET_COLIBRI_PXA270 is not set +# CONFIG_ARCH_UNIPHIER is not set +# CONFIG_STM32 is not set +# CONFIG_ARCH_ROCKCHIP is not set +# CONFIG_TARGET_THUNDERX_88XX is not set +CONFIG_SPL_GPIO_SUPPORT=y +CONFIG_SPL_LIBCOMMON_SUPPORT=y +CONFIG_SPL_LIBGENERIC_SUPPORT=y +CONFIG_SYS_MALLOC_F_LEN=0x400 +# CONFIG_SPL_EXT_SUPPORT is not set +# CONFIG_SPL_FAT_SUPPORT is not set +# CONFIG_SPL_I2C_SUPPORT is not set +CONFIG_SPL_LIBDISK_SUPPORT=y +CONFIG_SPL_MMC_SUPPORT=y +# CONFIG_SPL_NAND_SUPPORT is not set +CONFIG_SPL_POWER_SUPPORT=y +CONFIG_SPL_SERIAL_SUPPORT=y +# CONFIG_SPL_DISPLAY_PRINT is not set +# CONFIG_SPL_ENV_SUPPORT is not set +# CONFIG_SPL_DRIVERS_MISC_SUPPORT is not set +# CONFIG_SPL_SPI_FLASH_SUPPORT is not set +# CONFIG_SPL_SPI_SUPPORT is not set +# CONFIG_SPL_WATCHDOG_SUPPORT is not set +CONFIG_CPU_V7_HAS_NONSEC=y +CONFIG_CPU_V7_HAS_VIRT=y +# CONFIG_ARMV7_NONSEC is not set +# CONFIG_ARMV7_LPAE is not set +CONFIG_IDENT_STRING=" Allwinner Technology" +CONFIG_PRE_CONSOLE_BUFFER=y +CONFIG_SUNXI_DE2=y +CONFIG_SUNXI_GEN_SUN6I=y +CONFIG_SUNXI_H3_DW_DRAM=y +# CONFIG_MACH_SUN4I is not set +# CONFIG_MACH_SUN5I is not set +# CONFIG_MACH_SUN6I is not set +# CONFIG_MACH_SUN7I is not set +# CONFIG_MACH_SUN8I_A23 is not set +# CONFIG_MACH_SUN8I_A33 is not set +# CONFIG_MACH_SUN8I_A83T is not set +# CONFIG_MACH_SUN8I_H3 is not set +CONFIG_MACH_SUN8I_V3S=y +CONFIG_SUN8I_V3S_CAM=y +# CONFIG_MACH_SUN9I is not set +# CONFIG_MACH_SUN50I is not set +CONFIG_MACH_SUN8I=y +CONFIG_DRAM_CLK=360 +CONFIG_DRAM_ZQ=14779 +# CONFIG_DRAM_ODT_EN is not set +CONFIG_SUNXI_H3_DRAM_DDR2=y +CONFIG_SYS_CLK_FREQ=1008000000 +# CONFIG_UART0_PORT_F is not set +# CONFIG_OLD_SUNXI_KERNEL_COMPAT is not set +CONFIG_MMC=y +CONFIG_MMC0_CD_PIN="" +CONFIG_MMC1_CD_PIN="" +CONFIG_MMC2_CD_PIN="" +CONFIG_MMC3_CD_PIN="" +CONFIG_MMC1_PINS="" +CONFIG_MMC2_PINS="" +CONFIG_MMC3_PINS="" +CONFIG_MMC_SUNXI_SLOT_EXTRA=-1 +CONFIG_INITIAL_USB_SCAN_DELAY=0 +CONFIG_USB0_VBUS_PIN="PG3" +CONFIG_USB0_VBUS_DET="" +CONFIG_USB0_ID_DET="PG4" +CONFIG_USB1_VBUS_PIN="PG3" +CONFIG_USB2_VBUS_PIN="" +CONFIG_USB3_VBUS_PIN="" +# CONFIG_I2C0_ENABLE is not set +# CONFIG_I2C1_ENABLE is not set +# CONFIG_I2C2_ENABLE is not set +# CONFIG_R_I2C_ENABLE is not set +# CONFIG_AXP_GPIO is not set +# CONFIG_VIDEO is not set +CONFIG_GMAC_TX_DELAY=0 +CONFIG_SPL_STACK_R_ADDR=0x4fe00000 +# CONFIG_SPL_YMODEM_SUPPORT is not set + +# +# ARM debug +# +# CONFIG_DEBUG_LL is not set +CONFIG_DEFAULT_DEVICE_TREE="sun8i-v3s-camdroid" +CONFIG_SMBIOS_PRODUCT_NAME="sunxi" +# CONFIG_AHCI is not set + +# +# General setup +# +CONFIG_LOCALVERSION="" +CONFIG_LOCALVERSION_AUTO=y +CONFIG_CC_OPTIMIZE_FOR_SIZE=y +CONFIG_DISTRO_DEFAULTS=y +CONFIG_SYS_MALLOC_F=y +CONFIG_EXPERT=y +CONFIG_SYS_MALLOC_CLEAR_ON_INIT=y +# CONFIG_TOOLS_DEBUG is not set +# CONFIG_PHYS_64BIT is not set + +# +# Boot images +# +# CONFIG_FIT is not set +CONFIG_OF_BOARD_SETUP=y +# CONFIG_OF_SYSTEM_SETUP is not set +# CONFIG_OF_STDOUT_VIA_ALIAS is not set +CONFIG_SYS_EXTRA_OPTIONS="" +CONFIG_ARCH_FIXUP_FDT_MEMORY=y + +# +# Boot timing +# +# CONFIG_BOOTSTAGE is not set +CONFIG_BOOTSTAGE_USER_COUNT=20 +CONFIG_BOOTSTAGE_STASH_ADDR=0 +CONFIG_BOOTSTAGE_STASH_SIZE=4096 + +# +# Boot media +# +# CONFIG_NAND_BOOT is not set +# CONFIG_ONENAND_BOOT is not set +# CONFIG_QSPI_BOOT is not set +# CONFIG_SATA_BOOT is not set +# CONFIG_SD_BOOT is not set +# CONFIG_SPI_BOOT is not set +CONFIG_BOOTDELAY=2 + +# +# Console +# +CONFIG_MENU=y +# CONFIG_CONSOLE_RECORD is not set +# CONFIG_SILENT_CONSOLE is not set +CONFIG_PRE_CON_BUF_SZ=4096 +CONFIG_PRE_CON_BUF_ADDR=0x4f000000 +# CONFIG_CONSOLE_MUX is not set +# CONFIG_SYS_CONSOLE_IS_IN_ENV is not set +# CONFIG_SYS_CONSOLE_OVERWRITE_ROUTINE is not set +# CONFIG_SYS_CONSOLE_ENV_OVERWRITE is not set +# CONFIG_SYS_CONSOLE_INFO_QUIET is not set +CONFIG_SYS_STDIO_DEREGISTER=y +CONFIG_DEFAULT_FDT_FILE="" +# CONFIG_SYS_NO_FLASH is not set +# CONFIG_VERSION_VARIABLE is not set +CONFIG_DISPLAY_CPUINFO=y +CONFIG_DISPLAY_BOARDINFO=y + +# +# SPL / TPL +# +CONFIG_SUPPORT_SPL=y +CONFIG_SPL=y +CONFIG_SPL_SYS_MALLOC_SIMPLE=y +CONFIG_SPL_STACK_R=y +CONFIG_SPL_STACK_R_MALLOC_SIMPLE_LEN=0x100000 +# CONFIG_SPL_SEPARATE_BSS is not set +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_USE_SECTOR=y +CONFIG_SYS_MMCSD_RAW_MODE_U_BOOT_SECTOR=0x50 +# CONFIG_SPL_CRYPTO_SUPPORT is not set +# CONFIG_SPL_HASH_SUPPORT is not set +# CONFIG_SPL_DMA_SUPPORT is not set +# CONFIG_SPL_FPGA_SUPPORT is not set +# CONFIG_SPL_MPC8XXX_INIT_DDR_SUPPORT is not set +# CONFIG_SPL_MTD_SUPPORT is not set +# CONFIG_SPL_MUSB_NEW_SUPPORT is not set +# CONFIG_SPL_NET_SUPPORT is not set +# CONFIG_SPL_NO_CPU_SUPPORT is not set +# CONFIG_SPL_NOR_SUPPORT is not set +# CONFIG_SPL_ONENAND_SUPPORT is not set +# CONFIG_SPL_OS_BOOT is not set +# CONFIG_SPL_POST_MEM_SUPPORT is not set +# CONFIG_SPL_SATA_SUPPORT is not set +# CONFIG_SPL_USB_HOST_SUPPORT is not set +# CONFIG_SPL_USB_GADGET_SUPPORT is not set + +# +# Command line interface +# +CONFIG_CMDLINE=y +CONFIG_HUSH_PARSER=y +CONFIG_SYS_PROMPT="=> " + +# +# Autoboot options +# +CONFIG_AUTOBOOT=y +# CONFIG_AUTOBOOT_KEYED is not set + +# +# FASTBOOT +# +# CONFIG_FASTBOOT is not set + +# +# Commands +# + +# +# Info commands +# +CONFIG_CMD_BDI=y +CONFIG_CMD_CONSOLE=y +# CONFIG_CMD_CPU is not set +# CONFIG_CMD_LICENSE is not set + +# +# Boot commands +# +CONFIG_CMD_BOOTD=y +CONFIG_CMD_BOOTM=y +CONFIG_CMD_BOOTZ=y +CONFIG_CMD_BOOTEFI=y +# CONFIG_CMD_BOOTEFI_HELLO_COMPILE is not set +# CONFIG_CMD_BOOTMENU is not set +CONFIG_CMD_ELF=y +CONFIG_CMD_FDT=y +CONFIG_CMD_GO=y +CONFIG_CMD_RUN=y +CONFIG_CMD_IMI=y +# CONFIG_CMD_IMLS is not set +CONFIG_CMD_XIMG=y + +# +# Environment commands +# +# CONFIG_CMD_ASKENV is not set +CONFIG_CMD_EXPORTENV=y +CONFIG_CMD_IMPORTENV=y +CONFIG_CMD_EDITENV=y +# CONFIG_CMD_GREPENV is not set +CONFIG_CMD_SAVEENV=y +CONFIG_CMD_ENV_EXISTS=y + +# +# Memory commands +# +CONFIG_CMD_MEMORY=y +CONFIG_CMD_CRC32=y +# CONFIG_LOOPW is not set +# CONFIG_CMD_MEMTEST is not set +# CONFIG_CMD_MX_CYCLIC is not set +# CONFIG_CMD_MEMINFO is not set + +# +# Device access commands +# +CONFIG_CMD_DM=y +# CONFIG_CMD_DEMO is not set +CONFIG_CMD_LOADB=y +CONFIG_CMD_LOADS=y +# CONFIG_CMD_FLASH is not set +# CONFIG_CMD_ARMFLASH is not set +CONFIG_CMD_MMC=y +# CONFIG_CMD_NAND is not set +# CONFIG_CMD_SF is not set +# CONFIG_CMD_SPI is not set +# CONFIG_CMD_I2C is not set +CONFIG_CMD_USB=y +# CONFIG_CMD_DFU is not set +# CONFIG_CMD_USB_MASS_STORAGE is not set +# CONFIG_CMD_FPGA is not set +CONFIG_CMD_GPIO=y + +# +# Shell scripting commands +# +CONFIG_CMD_ECHO=y +CONFIG_CMD_ITEST=y +CONFIG_CMD_SOURCE=y +CONFIG_CMD_SETEXPR=y + +# +# Network commands +# +CONFIG_CMD_NET=y +# CONFIG_CMD_TFTPPUT is not set +# CONFIG_CMD_TFTPSRV is not set +# CONFIG_CMD_RARP is not set +CONFIG_CMD_DHCP=y +CONFIG_CMD_PXE=y +CONFIG_CMD_NFS=y +CONFIG_CMD_MII=y +CONFIG_CMD_PING=y +# CONFIG_CMD_CDP is not set +# CONFIG_CMD_SNTP is not set +# CONFIG_CMD_DNS is not set +# CONFIG_CMD_LINK_LOCAL is not set + +# +# Misc commands +# +# CONFIG_CMD_BKOPS_ENABLE is not set +# CONFIG_CMD_CACHE is not set +# CONFIG_CMD_TIME is not set +CONFIG_CMD_MISC=y +# CONFIG_CMD_TIMER is not set +# CONFIG_CMD_QFW is not set + +# +# Power commands +# + +# +# Security commands +# + +# +# Firmware commands +# + +# +# Filesystem commands +# +CONFIG_CMD_EXT2=y +CONFIG_CMD_EXT4=y +# CONFIG_CMD_EXT4_WRITE is not set +CONFIG_CMD_FAT=y +CONFIG_CMD_FS_GENERIC=y +# CONFIG_CMD_UBI is not set +CONFIG_SUPPORT_OF_CONTROL=y + +# +# Device Tree Control +# +CONFIG_OF_CONTROL=y +# CONFIG_SPL_OF_CONTROL is not set +CONFIG_OF_SEPARATE=y +# CONFIG_OF_EMBED is not set +CONFIG_NET=y +CONFIG_NET_RANDOM_ETHADDR=y +# CONFIG_NETCONSOLE is not set +CONFIG_NET_TFTP_VARS=y +CONFIG_BOOTP_PXE_CLIENTARCH=0x15 +CONFIG_BOOTP_VCI_STRING="U-Boot.armv7" + +# +# Device Drivers +# + +# +# Generic Driver Options +# +CONFIG_DM=y +# CONFIG_SPL_DM is not set +CONFIG_DM_WARN=y +CONFIG_DM_DEVICE_REMOVE=y +CONFIG_DM_STDIO=y +CONFIG_DM_SEQ_ALIAS=y +# CONFIG_SPL_DM_SEQ_ALIAS is not set +# CONFIG_REGMAP is not set +# CONFIG_SPL_REGMAP is not set +# CONFIG_DEVRES is not set +CONFIG_SIMPLE_BUS=y +CONFIG_OF_TRANSLATE=y +# CONFIG_ADC is not set +# CONFIG_ADC_EXYNOS is not set +# CONFIG_ADC_SANDBOX is not set +# CONFIG_BLK is not set +# CONFIG_BLOCK_CACHE is not set + +# +# SATA/SCSI device support +# + +# +# Clock +# +# CONFIG_CLK is not set +# CONFIG_CPU is not set + +# +# Hardware crypto devices +# +# CONFIG_FSL_CAAM is not set + +# +# Demo for driver model +# +# CONFIG_DM_DEMO is not set + +# +# DFU support +# + +# +# DMA Support +# +# CONFIG_DMA is not set +# CONFIG_TI_EDMA3 is not set + +# +# FPGA support +# +# CONFIG_FPGA_ALTERA is not set +# CONFIG_FPGA_XILINX is not set + +# +# GPIO Support +# +CONFIG_DM_GPIO=y +# CONFIG_ALTERA_PIO is not set +# CONFIG_DWAPB_GPIO is not set +# CONFIG_ATMEL_PIO4 is not set +# CONFIG_INTEL_BROADWELL_GPIO is not set +CONFIG_SUNXI_GPIO=y +# CONFIG_LPC32XX_GPIO is not set +# CONFIG_MSM_GPIO is not set +# CONFIG_ROCKCHIP_GPIO is not set +# CONFIG_TEGRA_GPIO is not set +# CONFIG_TEGRA186_GPIO is not set +# CONFIG_VYBRID_GPIO is not set +# CONFIG_DM_74X164 is not set +# CONFIG_DM_PCA953X is not set +# CONFIG_MPC85XX_GPIO is not set + +# +# I2C support +# +# CONFIG_DM_I2C is not set +# CONFIG_DM_I2C_COMPAT is not set +# CONFIG_SYS_I2C_DW is not set +# CONFIG_DM_KEYBOARD is not set +# CONFIG_CROS_EC_KEYB is not set + +# +# LED Support +# +# CONFIG_LED is not set + +# +# Mailbox Controller Support +# +# CONFIG_DM_MAILBOX is not set + +# +# Memory Controller drivers +# + +# +# Multifunction device drivers +# +# CONFIG_MISC is not set +# CONFIG_CROS_EC is not set +# CONFIG_FSL_SEC_MON is not set +# CONFIG_MXC_OCOTP is not set +# CONFIG_NUVOTON_NCT6102D is not set +# CONFIG_PWRSEQ is not set +# CONFIG_PCA9551_LED is not set +# CONFIG_WINBOND_W83627 is not set + +# +# MMC Host controller Support +# +# CONFIG_DM_MMC is not set +# CONFIG_SPL_MMC_TINY is not set + +# +# MTD Support +# +# CONFIG_MTD is not set + +# +# NAND Device Support +# +# CONFIG_NAND_DENALI is not set +# CONFIG_NAND_VF610_NFC is not set +# CONFIG_NAND_PXA3XX is not set +# CONFIG_NAND_ARASAN is not set +# CONFIG_NAND_ZYNQ is not set + +# +# Generic NAND options +# +# CONFIG_SYS_NAND_U_BOOT_LOCATIONS is not set +# CONFIG_SPL_NAND_DENALI is not set + +# +# SPI Flash Support +# +CONFIG_DM_SPI_FLASH=y +CONFIG_SPI_FLASH=y +# CONFIG_SPI_FLASH_BAR is not set +# CONFIG_SPI_FLASH_ATMEL is not set +# CONFIG_SPI_FLASH_EON is not set +# CONFIG_SPI_FLASH_GIGADEVICE is not set +# CONFIG_SPI_FLASH_MACRONIX is not set +# CONFIG_SPI_FLASH_SPANSION is not set +# CONFIG_SPI_FLASH_STMICRO is not set +# CONFIG_SPI_FLASH_SST is not set +CONFIG_SPI_FLASH_WINBOND=y +CONFIG_SPI_FLASH_USE_4K_SECTORS=y +# CONFIG_SPI_FLASH_DATAFLASH is not set +# CONFIG_SPI_FLASH_MTD is not set + +# +# UBI support +# +# CONFIG_MTD_UBI is not set +# CONFIG_DM_ETH is not set +CONFIG_PHYLIB=y +# CONFIG_RTL8211X_PHY_FORCE_MASTER is not set +CONFIG_NETDEVICES=y +# CONFIG_E1000 is not set +# CONFIG_ETH_DESIGNWARE is not set +# CONFIG_ETHOC is not set +# CONFIG_RTL8139 is not set +# CONFIG_RTL8169 is not set +# CONFIG_PCI is not set +# CONFIG_MVEBU_COMPHY_SUPPORT is not set + +# +# Pin controllers +# +# CONFIG_PINCTRL is not set + +# +# Power +# + +# +# Power Domain Support +# +# CONFIG_POWER_DOMAIN is not set +# CONFIG_DM_PMIC is not set +# CONFIG_DM_REGULATOR is not set +CONFIG_SUNXI_NO_PMIC=y +# CONFIG_DM_PWM is not set +# CONFIG_RAM is not set + +# +# Remote Processor drivers +# + +# +# Reset Controller Support +# +# CONFIG_DM_RESET is not set + +# +# Real Time Clock +# +# CONFIG_DM_RTC is not set + +# +# Serial drivers +# +CONFIG_REQUIRE_SERIAL_CONSOLE=y +CONFIG_SERIAL_PRESENT=y +CONFIG_SPL_SERIAL_PRESENT=y +CONFIG_DM_SERIAL=y +# CONFIG_DEBUG_UART is not set +# CONFIG_DEBUG_UART_SKIP_INIT is not set +# CONFIG_ALTERA_JTAG_UART is not set +# CONFIG_ALTERA_UART is not set +# CONFIG_ATMEL_USART is not set +# CONFIG_FSL_LPUART is not set +# CONFIG_MVEBU_A3700_UART is not set +CONFIG_SYS_NS16550=y +# CONFIG_MSM_SERIAL is not set +# CONFIG_PXA_SERIAL is not set + +# +# Sound support +# +# CONFIG_SOUND is not set + +# +# SPI Support +# +CONFIG_DM_SPI=y +# CONFIG_ALTERA_SPI is not set +# CONFIG_CADENCE_QSPI is not set +# CONFIG_DESIGNWARE_SPI is not set +# CONFIG_EXYNOS_SPI is not set +# CONFIG_FSL_DSPI is not set +# CONFIG_ICH_SPI is not set +# CONFIG_MVEBU_A3700_SPI is not set +# CONFIG_ROCKCHIP_SPI is not set +# CONFIG_TEGRA114_SPI is not set +# CONFIG_TEGRA20_SFLASH is not set +# CONFIG_TEGRA20_SLINK is not set +# CONFIG_TEGRA210_QSPI is not set +# CONFIG_XILINX_SPI is not set +# CONFIG_OMAP3_SPI is not set +# CONFIG_FSL_ESPI is not set +# CONFIG_FSL_QSPI is not set +# CONFIG_TI_QSPI is not set + +# +# SPMI support +# +# CONFIG_SPMI is not set + +# +# System reset device drivers +# +# CONFIG_SYSRESET is not set +# CONFIG_DM_THERMAL is not set + +# +# Timer Support +# +# CONFIG_TIMER is not set + +# +# TPM support +# +CONFIG_USB=y +CONFIG_DM_USB=y + +# +# USB Host Controller Drivers +# +CONFIG_USB_HOST=y +# CONFIG_USB_XHCI_HCD is not set +CONFIG_USB_EHCI_HCD=y +CONFIG_USB_EHCI=y +# CONFIG_USB_EHCI_MSM is not set +CONFIG_USB_EHCI_GENERIC=y +CONFIG_USB_OHCI_HCD=y +# CONFIG_USB_OHCI_GENERIC is not set +# CONFIG_USB_UHCI_HCD is not set + +# +# MUSB Controller Driver +# +CONFIG_USB_MUSB_HOST=y +# CONFIG_USB_MUSB_GADGET is not set +# CONFIG_USB_MUSB_TI is not set +CONFIG_USB_MUSB_SUNXI=y + +# +# ULPI drivers +# + +# +# USB peripherals +# +CONFIG_USB_STORAGE=y +# CONFIG_USB_KEYBOARD is not set +# CONFIG_USB_GADGET is not set + +# +# Graphics support +# +# CONFIG_DM_VIDEO is not set + +# +# TrueType Fonts +# +# CONFIG_VIDEO_VESA is not set +# CONFIG_VIDEO_LCD_ANX9804 is not set +# CONFIG_VIDEO_LCD_SSD2828 is not set +# CONFIG_VIDEO_MVEBU is not set +# CONFIG_DISPLAY is not set +# CONFIG_VIDEO_TEGRA20 is not set +# CONFIG_VIDEO_BRIDGE is not set +# CONFIG_LCD is not set +# CONFIG_PHYS_TO_BUS is not set + +# +# File systems +# + +# +# Library routines +# +# CONFIG_CC_OPTIMIZE_LIBS_FOR_SPEED is not set +CONFIG_HAVE_PRIVATE_LIBGCC=y +CONFIG_USE_PRIVATE_LIBGCC=y +CONFIG_SYS_HZ=1000 +CONFIG_USE_TINY_PRINTF=y +CONFIG_REGEX=y +CONFIG_LIB_RAND=y +# CONFIG_CMD_DHRYSTONE is not set +# CONFIG_RSA is not set +# CONFIG_TPM is not set + +# +# Hashing Support +# +# CONFIG_SHA1 is not set +# CONFIG_SHA256 is not set +# CONFIG_SHA_HW_ACCEL is not set + +# +# Compression Support +# +# CONFIG_LZ4 is not set +# CONFIG_ERRNO_STR is not set +CONFIG_OF_LIBFDT=y +CONFIG_OF_LIBFDT_OVERLAY=y +# CONFIG_SPL_OF_LIBFDT is not set +# CONFIG_FDT_FIXUP_PARTITIONS is not set + +# +# System tables +# +CONFIG_GENERATE_SMBIOS_TABLE=y +CONFIG_SMBIOS_MANUFACTURER="" +CONFIG_EFI_LOADER=y +# CONFIG_UNIT_TEST is not set diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index 8d9ab5237e87..aa3a97fdf468 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -48,6 +48,12 @@ config INTEL_BROADWELL_GPIO driver from the common Intel ICH6 driver. It supports a total of 95 GPIOs which can be configured from the device tree. +config SUNXI_GPIO + bool "SUNXI GPIO driver" + default n + help + Support for the SUNXI GPIO driver. + config LPC32XX_GPIO bool "LPC32XX GPIO driver" depends on DM diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c index 1c6e967db1a0..8d88800d40ce 100644 --- a/drivers/usb/eth/asix.c +++ b/drivers/usb/eth/asix.c @@ -21,6 +21,8 @@ #define AX_CMD_WRITE_MII_REG 0x08 #define AX_CMD_SET_HW_MII 0x0a #define AX_CMD_READ_EEPROM 0x0b +#define AX_CMD_WRITE_ENABLE 0x0d +#define AX_CMD_WRITE_DISABLE 0x0e #define AX_CMD_READ_RX_CTL 0x0f #define AX_CMD_WRITE_RX_CTL 0x10 #define AX_CMD_WRITE_IPG0 0x12 @@ -28,6 +30,7 @@ #define AX_CMD_WRITE_NODE_ID 0x14 #define AX_CMD_READ_PHY_ID 0x19 #define AX_CMD_WRITE_MEDIUM_MODE 0x1b +#define AX_CMD_READ_GPIOS 0x1e #define AX_CMD_WRITE_GPIOS 0x1f #define AX_CMD_SW_RESET 0x20 #define AX_CMD_SW_PHY_SELECT 0x22 @@ -67,15 +70,23 @@ AX_MEDIUM_AC | AX_MEDIUM_RE) /* AX88772 & AX88178 RX_CTL values */ +#define AX_RX_CTL_RH2M 0x0200 /* 32-bit aligned RX IP header */ +#define AX_RX_CTL_RH1M 0x0100 /* Enable RX header format type 1 */ #define AX_RX_CTL_SO 0x0080 #define AX_RX_CTL_AB 0x0008 +#define AX_RX_HEADER_DEFAULT (AX_RX_CTL_RH1M | AX_RX_CTL_RH2M) #define AX_DEFAULT_RX_CTL \ (AX_RX_CTL_SO | AX_RX_CTL_AB) -/* GPIO 2 toggles */ +/* GPIO 0..2 toggles */ +#define AX_GPIO_GPO0EN 0x01 /* GPIO0 Output enable */ +#define AX_GPIO_GPO_0 0x02 /* GPIO0 Output value */ +#define AX_GPIO_GPO1EN 0x04 /* GPIO1 Output enable */ +#define AX_GPIO_GPO_1 0x08 /* GPIO1 Output value */ #define AX_GPIO_GPO2EN 0x10 /* GPIO2 Output enable */ #define AX_GPIO_GPO_2 0x20 /* GPIO2 Output value */ +#define AX_GPIO_RESERVED 0x40 /* Reserved */ #define AX_GPIO_RSE 0x80 /* Reload serial EEPROM */ /* local defines */ @@ -86,22 +97,38 @@ #define USB_BULK_RECV_TIMEOUT 5000 #define AX_RX_URB_SIZE 2048 +#define AX88178_RX_URB_SIZE 1024 * 0x12 #define PHY_CONNECT_TIMEOUT 5000 +/* PHY MODE */ +#define PHY_MODE_MARVELL 0x0000 +#define PHY_MODE_RTL8211CL 0x000C + /* asix_flags defines */ #define FLAG_NONE 0 #define FLAG_TYPE_AX88172 (1U << 0) #define FLAG_TYPE_AX88772 (1U << 1) #define FLAG_TYPE_AX88772B (1U << 2) -#define FLAG_EEPROM_MAC (1U << 3) /* initial mac address in eeprom */ +#define FLAG_TYPE_AX88178 (1U << 3) +#define FLAG_EEPROM_MAC (1U << 8) /* initial mac address in eeprom */ +#define ASIX_USB_VENDOR_ID 0x0b95 +#define AX88772B_USB_PRODUCT_ID 0x772b +#define AX88178_USB_PRODUCT_ID 0x1780 /* driver private */ struct asix_private { int flags; + int phymode; /* For ASIX88178 */ + int ledmode; + int rx_urb_size; + int supports_gmii; + int advertising; + int full_duplex; #ifdef CONFIG_DM_ETH struct ueth_data ueth; #endif + uint8_t rcv_buf[AX_RX_URB_SIZE * 8]; }; #ifndef CONFIG_DM_ETH @@ -360,7 +387,7 @@ static int asix_read_mac_common(struct ueth_data *dev, return 0; } -static int asix_basic_reset(struct ueth_data *dev) +static int asix_basic_reset(struct ueth_data *dev, struct asix_private *priv) { int embd_phy; u16 rx_ctl; @@ -426,10 +453,19 @@ static int asix_init_common(struct ueth_data *dev, uint8_t *enetaddr) int timeout = 0; #define TIMEOUT_RESOLUTION 50 /* ms */ int link_detected; - + u32 ctl = AX_DEFAULT_RX_CTL; + debug("** %s()\n", __func__); - if (asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL) < 0) + if ((dev->pusb_dev->descriptor.idVendor == ASIX_USB_VENDOR_ID) && + (dev->pusb_dev->descriptor.idProduct == AX88772B_USB_PRODUCT_ID)) + ctl |= AX_RX_HEADER_DEFAULT; + + if ((dev->pusb_dev->descriptor.idVendor == ASIX_USB_VENDOR_ID) && + (dev->pusb_dev->descriptor.idProduct == AX88178_USB_PRODUCT_ID)) + ctl |= AX_RX_HEADER_DEFAULT; + + if (asix_write_rx_ctl(dev, ctl) < 0) goto out_err; if (asix_write_hwaddr_common(dev, enetaddr) < 0) @@ -464,6 +500,56 @@ static int asix_init_common(struct ueth_data *dev, uint8_t *enetaddr) return -1; } + +/* Get the PHY Identifier from the PHYSID1 & PHYSID2 MII registers */ +static u32 asix_get_phyid(struct ueth_data *dev) +{ + int phy_reg; + u32 phy_id; + int i; + printf("%s enter\n", __func__); + /* Poll for the rare case the FW or phy isn't ready yet. */ + for (i = 0; i < 100; i++) { + phy_reg = asix_mdio_read(dev, dev->phy_id, MII_PHYSID1); + if (phy_reg != 0 && phy_reg != 0xFFFF) + break; + mdelay(1); + } + + if (phy_reg <= 0 || phy_reg == 0xFFFF) + return 0; + + phy_id = (phy_reg & 0xffff) << 16; + + phy_reg = asix_mdio_read(dev, dev->phy_id, MII_PHYSID2); + if (phy_reg < 0) + return 0; + + phy_id |= (phy_reg & 0xffff); + printf("%s exit\n", __func__); + return phy_id; +} + + +static int rtl8211cl_phy_init(struct ueth_data *dev, struct asix_private *priv) +{ + printf("%s enter\n", __func__); + + asix_mdio_write (dev, dev->phy_id, 0x1f, 0x0005); + asix_mdio_write (dev, dev->phy_id, 0x0c, 0); + asix_mdio_write (dev, dev->phy_id, 0x01, + asix_mdio_read (dev, dev->phy_id, 0x01) | 0x0080); + asix_mdio_write (dev, dev->phy_id, 0x1f, 0); + + if (priv->ledmode == 12) { + asix_mdio_write (dev, dev->phy_id, 0x1f, 0x0002); + asix_mdio_write (dev, dev->phy_id, 0x1a, 0x00cb); + asix_mdio_write (dev, dev->phy_id, 0x1f, 0); + } + printf("%s enter\n", __func__); + return 0; +} + static int asix_send_common(struct ueth_data *dev, void *packet, int length) { int err; @@ -562,6 +648,12 @@ static int asix_recv(struct eth_device *eth) return -1; } + if ((dev->pusb_dev->descriptor.idVendor == + ASIX_USB_VENDOR_ID) && + (dev->pusb_dev->descriptor.idProduct == + AX88772B_USB_PRODUCT_ID)) + buf_ptr += 2; + /* Notify net stack */ net_process_received_packet(buf_ptr + sizeof(packet_len), packet_len); @@ -617,6 +709,7 @@ static const struct asix_dongle asix_dongles[] = { { 0x2001, 0x3c05, FLAG_TYPE_AX88772 }, /* ASIX 88772B */ { 0x0b95, 0x772b, FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC }, + { 0x0b95, 0x772b, FLAG_TYPE_AX88772B }, { 0x0b95, 0x7e2b, FLAG_TYPE_AX88772B }, { 0x0000, 0x0000, FLAG_NONE } /* END - Do not remove */ }; @@ -708,6 +801,102 @@ int asix_eth_probe(struct usb_device *dev, unsigned int ifnum, return 1; } + +static int ax88178_reset(struct ueth_data *dev, struct asix_private *priv) +{ + int ret; + int gpio0 = 0; + u32 phyid; + __le16 eeprom; + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, status, 4); + ALLOC_CACHE_ALIGN_BUFFER(unsigned char, eep, 4); + printf("%s enter\n", __func__); + *status = 0; + asix_read_cmd(dev, AX_CMD_READ_GPIOS, 0, 0, 1, status); + debug("GPIO Status: 0x%04x\n", *status); + + *eep = 0; + asix_write_cmd(dev, AX_CMD_WRITE_ENABLE, 0, 0, 0, NULL); + asix_read_cmd(dev, AX_CMD_READ_EEPROM, 0x0017, 0, 2, eep); + asix_write_cmd(dev, AX_CMD_WRITE_DISABLE, 0, 0, 0, NULL); + + eeprom = *eep; + debug("EEPROM index 0x17 is 0x%04x\n", eeprom); + + if (eeprom == cpu_to_le16(0xffff)) { + priv->phymode = PHY_MODE_MARVELL; + priv->ledmode = 0; + gpio0 = 1; + } else { + priv->phymode = le16_to_cpu(eeprom) & 0x7F; + priv->ledmode = le16_to_cpu(eeprom) >> 8; + gpio0 = (le16_to_cpu(eeprom) & 0x80) ? 0 : 1; + } + debug("GPIO0: %d, PhyMode: %d\n", gpio0, priv->phymode); + + /* Power up external GigaPHY through AX88178 GPIO pin */ + asix_write_gpio(dev, AX_GPIO_RSE | AX_GPIO_GPO_1 | AX_GPIO_GPO1EN, 40); + if ((le16_to_cpu(eeprom) >> 8) != 1) { + asix_write_gpio(dev, 0x003c, 30); + asix_write_gpio(dev, 0x001c, 300); + asix_write_gpio(dev, 0x003c, 30); + } else { + debug("gpio phymode == 1 path"); + asix_write_gpio(dev, AX_GPIO_GPO1EN, 30); + asix_write_gpio(dev, AX_GPIO_GPO1EN | AX_GPIO_GPO_1, 30); + } + + dev->phy_id = asix_get_phy_addr(dev); + + /* Read PHYID register *AFTER* powering up PHY */ + phyid = asix_get_phyid(dev); + debug("PHYID=0x%08x\n", phyid); + + /* Set AX88178 to enable MII/GMII/RGMII interface for external PHY */ + asix_write_cmd(dev, AX_CMD_SW_PHY_SELECT, 0, 0, 0, NULL); + + asix_sw_reset(dev, 0); + mdelay(150); + + asix_sw_reset(dev, AX_SWRESET_PRL | AX_SWRESET_IPPD); + mdelay(150); + + asix_write_rx_ctl(dev, 0); + + if (priv->phymode == PHY_MODE_MARVELL) { +// marvell_phy_init(dev, priv); + mdelay(60); + } else if (priv->phymode == PHY_MODE_RTL8211CL) + rtl8211cl_phy_init(dev, priv); + + asix_mdio_write(dev, dev->phy_id, MII_BMCR, + BMCR_RESET | BMCR_ANENABLE); + asix_mdio_write(dev, dev->phy_id, MII_ADVERTISE, + ADVERTISE_ALL | ADVERTISE_CSMA | ADVERTISE_PAUSE_CAP); + asix_mdio_write(dev, dev->phy_id, MII_CTRL1000, + ADVERTISE_1000FULL); + + mii_nway_restart(dev); + + ret = asix_write_medium_mode(dev, AX88178_MEDIUM_DEFAULT | AX_MEDIUM_ENCK); + if (ret < 0) + return ret; +#if 0 /* Rewrite MAC ?? */ + /* Rewrite MAC address */ + memcpy(data->mac_addr, dev->net->dev_addr, ETH_ALEN); + ret = asix_write_cmd(dev, AX_CMD_WRITE_NODE_ID, 0, 0, ETH_ALEN, + data->mac_addr); + if (ret < 0) + return ret; +#endif + + ret = asix_write_rx_ctl(dev, AX_DEFAULT_RX_CTL); + if (ret < 0) + return ret; + printf("%s exit\n", __func__); + return 0; +} + int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, struct eth_device *eth) { @@ -726,8 +915,20 @@ int asix_eth_get_info(struct usb_device *dev, struct ueth_data *ss, eth->write_hwaddr = asix_write_hwaddr; eth->priv = ss; - if (asix_basic_reset(ss)) - return 0; + if (priv->flags & FLAG_TYPE_AX88178) { + priv->rx_urb_size = AX88178_RX_URB_SIZE; + } else { + priv->rx_urb_size = AX_RX_URB_SIZE; + } + + /* Check AX88178 for another initialize. */ + if (priv->flags & FLAG_TYPE_AX88172) { + if (ax88178_reset(ss, priv)) + return 0; + } else { + if (asix_basic_reset(ss, priv)) + return 0; + } /* Get the MAC address */ if (asix_read_mac_common(ss, priv, eth->enetaddr)) @@ -840,14 +1041,27 @@ static int asix_eth_probe(struct udevice *dev) int ret; priv->flags = dev->driver_data; + + if (priv->flags & FLAG_TYPE_AX88178) { + priv->rx_urb_size = AX88178_RX_URB_SIZE; + } else { + priv->rx_urb_size = AX_RX_URB_SIZE; + } + ret = usb_ether_register(dev, ss, AX_RX_URB_SIZE); if (ret) return ret; - ret = asix_basic_reset(ss); - if (ret) - goto err; - + if (priv->flags & FLAG_TYPE_AX88178) { + ret = ax88178_reset(ss, priv); + if (ret) + goto err; + } else { + ret = asix_basic_reset(ss, priv); + if (ret) + goto err; + } + /* Get the MAC address */ ret = asix_read_mac_common(ss, priv, pdata->enetaddr); if (ret) @@ -899,10 +1113,12 @@ static const struct usb_device_id asix_eth_id_table[] = { { USB_DEVICE(0x1557, 0x7720), .driver_info = FLAG_TYPE_AX88772 }, /* DLink DUB-E100 H/W Ver B1 Alternate */ { USB_DEVICE(0x2001, 0x3c05), .driver_info = FLAG_TYPE_AX88772 }, + { USB_DEVICE(0x0a46, 0x1269), .driver_info = FLAG_TYPE_AX88772 }, /* ASIX 88772B */ { USB_DEVICE(0x0b95, 0x772b), .driver_info = FLAG_TYPE_AX88772B | FLAG_EEPROM_MAC }, { USB_DEVICE(0x0b95, 0x7e2b), .driver_info = FLAG_TYPE_AX88772B }, + { USB_DEVICE(0x0b95, 0x1780), .driver_info = FLAG_TYPE_AX88178 }, { } /* Terminating entry */ }; diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c index 36734e2e51b3..fabcd4731eed 100644 --- a/drivers/usb/eth/usb_ether.c +++ b/drivers/usb/eth/usb_ether.c @@ -16,6 +16,7 @@ #ifdef CONFIG_DM_ETH #define USB_BULK_RECV_TIMEOUT 500 +unsigned char rxx_buf[32768] __attribute__ ((aligned(128))); int usb_ether_register(struct udevice *dev, struct ueth_data *ueth, int rxsize) { @@ -73,7 +74,9 @@ int usb_ether_register(struct udevice *dev, struct ueth_data *ueth, int rxsize) } ueth->rxsize = rxsize; - ueth->rxbuf = memalign(ARCH_DMA_MINALIGN, rxsize); +// ueth->rxbuf = memalign(ARCH_DMA_MINALIGN, rxsize); + ueth->rxbuf = rxx_buf; + if (!ueth->rxbuf) return -ENOMEM; diff --git a/drivers/usb/musb-new/musb_regs.h b/drivers/usb/musb-new/musb_regs.h index 0f18dd7f7eec..dd4579ab56b4 100644 --- a/drivers/usb/musb-new/musb_regs.h +++ b/drivers/usb/musb-new/musb_regs.h @@ -324,7 +324,10 @@ */ #define MUSB_DEVCTL 0x0041 - +#ifdef CONFIG_MACH_SUN8I_V3S +#define MUSB_VEND0 0x0043 +#define MUSB_VEND0_PIO_MODE 0 +#endif /* These are always controlled through the INDEX register */ #define MUSB_TXFIFOSZ 0x0090 #define MUSB_RXFIFOSZ 0x0094 @@ -434,7 +437,7 @@ static inline u8 musb_read_ulpi_buscontrol(void __iomem *mbase) static inline u8 musb_read_configdata(void __iomem *mbase) { -#if defined CONFIG_MACH_SUN8I_A33 || defined CONFIG_MACH_SUN8I_A83T +#if defined CONFIG_MACH_SUN8I_A33 || defined CONFIG_MACH_SUN8I_A83T || defined CONFIG_MACH_SUN8I_V3S /* allwinner saves a reg, and we need to hardcode this */ return 0xde; #else diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c index ea71f759476e..ddd77834a931 100644 --- a/drivers/usb/musb-new/musb_uboot.c +++ b/drivers/usb/musb-new/musb_uboot.c @@ -3,6 +3,9 @@ #include #ifdef CONFIG_ARCH_SUNXI #include +#ifdef CONFIG_SUN8I_V3S_CAM +#include +#endif #endif #include #include @@ -204,6 +207,10 @@ static int _musb_reset_root_port(struct musb_host_data *host, power = musb_readb(mbase, MUSB_POWER); musb_writeb(mbase, MUSB_POWER, ~MUSB_POWER_RESET & power); #ifdef CONFIG_ARCH_SUNXI +#ifdef CONFIG_SUN8I_V3S_CAM + gpio_direction_output(SUNXI_GPG(3),1); + power = musb_readb(mbase, MUSB_POWER); +#endif sunxi_usb_phy_enable_squelch_detect(0, 1); #endif host->host->isr(0, host->host); @@ -222,7 +229,8 @@ int musb_lowlevel_init(struct musb_host_data *host) /* USB spec says it may take up to 1 second for a device to connect */ unsigned long timeout = get_timer(0) + 1000; int ret; - + u8 mode; + if (!host->host) { printf("MUSB host is not registered\n"); return -ENODEV; @@ -233,6 +241,11 @@ int musb_lowlevel_init(struct musb_host_data *host) return ret; mbase = host->host->mregs; +#ifdef CONFIG_MACH_SUN8I_V3S + mode = musb_readb(mbase,MUSB_DEVCTL); + musb_writeb(mbase,MUSB_DEVCTL,mode|MUSB_DEVCTL_HM); + mode = musb_readb(mbase, MUSB_DEVCTL); +#endif do { if (musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_HM) break; diff --git a/drivers/usb/musb-new/sunxi.c b/drivers/usb/musb-new/sunxi.c index 469377fe4e6d..f5a5d2000660 100644 --- a/drivers/usb/musb-new/sunxi.c +++ b/drivers/usb/musb-new/sunxi.c @@ -226,7 +226,9 @@ static int sunxi_musb_enable(struct musb *musb) ret = sunxi_usb_phy_id_detect(0); if (ret == 1) { printf("No host cable detected: "); +#ifndef CONFIG_SUN8I_V3S_CAM return -ENODEV; +#endif } sunxi_usb_phy_power_on(0); /* port power on */ } @@ -260,7 +262,9 @@ static int sunxi_musb_init(struct musb *musb) pr_debug("%s():\n", __func__); musb->isr = sunxi_musb_interrupt; - +#ifdef CONFIG_MACH_SUN8I_V3S + musb_writeb(musb->mregs, MUSB_VEND0, MUSB_VEND0_PIO_MODE); +#endif setbits_le32(&ccm->ahb_gate0, 1 << AHB_GATE_OFFSET_USB0); #ifdef CONFIG_SUNXI_GEN_SUN6I setbits_le32(&ccm->ahb_reset0_cfg, 1 << AHB_GATE_OFFSET_USB0); @@ -289,11 +293,36 @@ static const struct musb_platform_ops sunxi_musb_ops = { .disable = sunxi_musb_disable, }; +#ifdef CONFIG_MACH_SUN8I_V3S +/* sunxi default FIFO config - fits in */ +static struct musb_fifo_cfg sunxi_musb_fifo_config[] = { + { .hw_ep_num = 1, .style = FIFO_TX, .maxpacket = 512, }, + { .hw_ep_num = 1, .style = FIFO_RX, .maxpacket = 512, }, + { .hw_ep_num = 2, .style = FIFO_TX, .maxpacket = 512, }, + { .hw_ep_num = 2, .style = FIFO_RX, .maxpacket = 512, }, + { .hw_ep_num = 3, .style = FIFO_TX, .maxpacket = 512, }, + { .hw_ep_num = 3, .style = FIFO_RX, .maxpacket = 512, }, + { .hw_ep_num = 4, .style = FIFO_TX, .maxpacket = 512, }, + { .hw_ep_num = 4, .style = FIFO_RX, .maxpacket = 512, }, +}; +#endif + static struct musb_hdrc_config musb_config = { +#ifdef CONFIG_MACH_SUN8I_V3S + .fifo_cfg = sunxi_musb_fifo_config, + .fifo_cfg_size = ARRAY_SIZE(sunxi_musb_fifo_config), + .multipoint = true, + .dyn_fifo = true, + .soft_con = true, + .num_eps = 5, + .ram_bits = 11, + .dma =0, +#else .multipoint = 1, .dyn_fifo = 1, .num_eps = 6, .ram_bits = 11, +#endif }; static struct musb_hdrc_platform_data musb_plat = { @@ -304,6 +333,9 @@ static struct musb_hdrc_platform_data musb_plat = { #endif .config = &musb_config, .power = 250, +#ifdef CONFIG_SUN8I_V3S_CAM + .set_power = sunxi_usb_phy_power_on, +#endif .platform_ops = &sunxi_musb_ops, }; @@ -351,9 +383,19 @@ static int musb_usb_remove(struct udevice *dev) return 0; } +#ifdef CONFIG_MACH_SUN8I_V3S +static const struct udevice_id sunxi_musb_ids[] = { + { .compatible = "allwinner,sun8i-h3-musb" }, + { } +}; +#endif + U_BOOT_DRIVER(usb_musb) = { .name = "sunxi-musb", .id = UCLASS_USB, +#ifdef CONFIG_MACH_SUN8I_V3S + .of_match = sunxi_musb_ids, +#endif .probe = musb_usb_probe, .remove = musb_usb_remove, .ops = &musb_usb_ops, diff --git a/include/configs/sun8i.h b/include/configs/sun8i.h index 6ac42acaeadd..1a410b0b3a5e 100644 --- a/include/configs/sun8i.h +++ b/include/configs/sun8i.h @@ -23,6 +23,8 @@ #define CONFIG_SUNXI_USB_PHYS 3 #elif defined CONFIG_MACH_SUN8I_V3S #define CONFIG_SUNXI_USB_PHYS 1 + #define CONFIG_USB_ETHER_ASIX + #define CONFIG_USB_HOST_ETHER #else #define CONFIG_SUNXI_USB_PHYS 2 #endif diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h index f4489fad6d80..90bcc4a2df90 100644 --- a/include/configs/sunxi-common.h +++ b/include/configs/sunxi-common.h @@ -148,7 +148,7 @@ #define CONFIG_GENERIC_MMC #define CONFIG_MMC_SUNXI #define CONFIG_MMC_SUNXI_SLOT 0 -#define CONFIG_ENV_IS_IN_MMC +#define CONFIG_ENV_IS_IN_MMC 1 #define CONFIG_SYS_MMC_ENV_DEV 0 /* first detected MMC controller */ #define CONFIG_SYS_MMC_MAX_DEVICE 4 #endif @@ -283,7 +283,7 @@ extern int soft_i2c_gpio_scl; #endif /* ifdef CONFIG_REQUIRE_SERIAL_CONSOLE */ /* GPIO */ -#define CONFIG_SUNXI_GPIO +/*#define CONFIG_SUNXI_GPIO*/ #ifdef CONFIG_VIDEO /* @@ -532,6 +532,7 @@ extern int soft_i2c_gpio_scl; "fdtfile=" CONFIG_DEFAULT_DEVICE_TREE ".dtb\0" \ "console=ttyS0,115200\0" \ BOOTCMD_SUNXI_COMPAT \ + "machid=1029\0" \ BOOTENV #else /* ifndef CONFIG_SPL_BUILD */ From fa92be96144e6d0b6459e1c1e3179ae6a3cbd93f Mon Sep 17 00:00:00 2001 From: ujuo Date: Fri, 15 Dec 2017 15:12:29 +0900 Subject: [PATCH 16/18] dm:i2c:sunxi:add i2c driver --- arch/arm/include/asm/arch-sunxi/sunxi_i2c.h | 87 +++++ drivers/i2c/sunxi_i2c.c | 383 ++++++++++++++++++++ 2 files changed, 470 insertions(+) create mode 100644 arch/arm/include/asm/arch-sunxi/sunxi_i2c.h create mode 100644 drivers/i2c/sunxi_i2c.c diff --git a/arch/arm/include/asm/arch-sunxi/sunxi_i2c.h b/arch/arm/include/asm/arch-sunxi/sunxi_i2c.h new file mode 100644 index 000000000000..618dfb36c1e8 --- /dev/null +++ b/arch/arm/include/asm/arch-sunxi/sunxi_i2c.h @@ -0,0 +1,87 @@ +/* + * Support for GPIO-I2C on SUN8I V3S + * + * Copyright(c) 2017 I4VINE Inc., + * All right reserved by JuYoung Ryu + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + */ + + +#ifndef _SUNXI_I2C_H +#define _SUNXI_I2C_H + +/* Register Map */ +#define TWI_ADDR 0x0000 + #define SLA GENMASK(7,1) + #define GCE BIT(0) +#define TWI_XADDR 0x0004 + #define SLAX GENMASK(7,0) +#define TWI_DATA 0x0008 + #define TWI_DATA_MASK GENMASK(7,0) +#define TWI_CNTR 0x000C + #define INT_EN BIT(7) + #define BUS_EN BIT(6) + #define M_STA BIT(5) + #define M_STP BIT(4) + #define INT_FLAG BIT(3) + #define A_ACK BIT(2) + +#define TWI_STAT 0x0010 + #define TWI_M_ACK 0x50 + #define TWI_M_NACK 0x58 +#define TWI_CCR 0x0014 + #define CLK_M GENMASK(6,3) + #define CLK_N GENMASK(2,0) +#define TWI_SRST 0x0018 + #define TWI_SRST_MASK BIT(0) +#define TWI_EFR 0x001C + #define DBN GENMASK(1,0) +#define TWI_LCR 0x0020 + #define SCL_STATE BIT(5) + #define SDA_STATE BIT(4) + #define SCL_CTL BIT(3) + #define SCL_CTL_EN BIT(2) + #define SDA_CTL BIT(1) + #define SDA_CTL_EN BIT(0) +#define TWI_DVFSCR 0x0024 /*TWI0 only*/ + #define MS_PRIORITY BIT(2) + #define CPU_BUSY_SET BIT(1) + #define DVFC_BUSY_SET BIT(0) + + +struct sun8i_i2c_regs { + u32 addr; //slavemode + u32 xaddr; //slavemode + u32 data; + u32 cntr; + u32 stat; + u32 ccr; + u32 srst; + u32 efr; + u32 lcr; + u32 dvfscr; //slavemode, twi0 only. +}; + +struct sun8i_i2c_pdata { + unsigned clk_max_div; + unsigned clk_offset; +}; + +struct sun8i_i2c_bus { + struct sun8i_i2c_regs *regs; + u32 status; + ulong bus_clk_rate; + u32 clock_frequency; + u32 speed; + u32 ccr_val; + const struct sun8i_i2c_pdata *pdata; +}; + +int sun8i_i2c_read(struct sun8i_i2c_regs* reg, u8 chip, uint addr, int alen, u8 *data, int len); +int sun8i_i2c_write(struct sun8i_i2c_regs *reg, u8 chip, uint addr, int alen, u8 *buffer, int len); + +#endif /* _SUNXI_I2C_H */ diff --git a/drivers/i2c/sunxi_i2c.c b/drivers/i2c/sunxi_i2c.c new file mode 100644 index 000000000000..5efebb960e39 --- /dev/null +++ b/drivers/i2c/sunxi_i2c.c @@ -0,0 +1,383 @@ +/* + * SUN8I V3S GPIO-I2C driver. + * + * Copyright(c) 2017 I4VINE Inc., + * All right reserved by JuYoung Ryu + * + * SPDX-License-Identifier: GPL-2.0+ + */ +//#define DEBUG 1 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +DECLARE_GLOBAL_DATA_PTR; +struct sun8i_i2c_regs i2c_regs; +struct sun8i_i2c_regs *i2c_reg; + +#define V3S_I2C_GPIO + +# ifndef I2C_DELAY +# define I2C_DELAY udelay(25) /* 1/4 I2C clock duration */ +# endif + +enum { + PIN_SDA = 0, + PIN_SCL, + PIN_COUNT, +}; + +void scl_ctl(struct sun8i_i2c_regs *reg, u8 val) +{ + u32 read_val=0; + read_val = readl(®->lcr); + if(val){ + writel(read_val|SCL_CTL, ®->lcr); + } else { + writel(read_val&~SCL_CTL, ®->lcr); + } +} + +void sda_ctl(struct sun8i_i2c_regs *reg, u8 val) +{ + u32 read_val=0; + read_val = readl(®->lcr); + if(val){ + writel(read_val|SDA_CTL, ®->lcr); + } else { + writel(read_val&~SDA_CTL, ®->lcr); + } +} + +static int write_byte(struct sun8i_i2c_regs *reg, unsigned char data) +{ + int i = 0; + int nack; + for(i=0; i<8; i++){ + scl_ctl(reg,0); + I2C_DELAY; + sda_ctl(reg,data & 0x80); + I2C_DELAY; + scl_ctl(reg,1); + I2C_DELAY; + I2C_DELAY; + + data <<= 1; + } + scl_ctl(reg,0); + I2C_DELAY; + + sda_ctl(reg,1); + I2C_DELAY; + scl_ctl(reg,1); + I2C_DELAY; + I2C_DELAY; + + nack = readl(®->lcr) & SDA_STATE ; + scl_ctl(reg,0); + I2C_DELAY; + I2C_DELAY; + return (nack&0x01); +} + +static void send_ack(struct sun8i_i2c_regs *reg, int ack) +{ + scl_ctl(reg,0); + I2C_DELAY; + + sda_ctl(reg,ack); + I2C_DELAY; + scl_ctl(reg,1); + I2C_DELAY; + I2C_DELAY; + scl_ctl(reg,0); + I2C_DELAY; +} + +static unsigned char read_byte(struct sun8i_i2c_regs *reg, int ack) +{ + unsigned char data = 0; + unsigned char read_bit = 0; + int i=0; + + sda_ctl(reg,1); + for(i=0; i<8; i++){ + scl_ctl(reg,0); + I2C_DELAY; + scl_ctl(reg,1); + I2C_DELAY; + data <<= 1; + read_bit = !!(readl(®->lcr) & SDA_STATE); + data |= read_bit; + I2C_DELAY; + } + send_ack(reg,ack); + + return data; +} + +static void send_start(struct sun8i_i2c_regs *reg) +{ + I2C_DELAY; + sda_ctl(reg,1); + I2C_DELAY; + scl_ctl(reg,1); + I2C_DELAY; + sda_ctl(reg,0); + I2C_DELAY; +} + +static void send_stop(struct sun8i_i2c_regs *reg) +{ + scl_ctl(reg,0); + I2C_DELAY; + sda_ctl(reg,0); + I2C_DELAY; + scl_ctl(reg,1); + I2C_DELAY; + sda_ctl(reg,1); + I2C_DELAY; +} + +static void sun8i_i2c_init(struct sun8i_i2c_regs *reg) +{ + i2c_reg = &i2c_regs; + i2c_reg = reg; + + writel(0x28, ®->ccr); + writel(BUS_EN, ®->cntr); + writel(SCL_CTL_EN|SDA_CTL_EN|SCL_CTL|SDA_CTL, ®->lcr); + +#ifdef V3S_I2C_GPIO + sunxi_gpio_set_cfgpin(SUNXI_GPB(6), SUN8I_GPB_TWI0);//SUNXI_GPIO_OUTPUT);//SUN8I_GPB_TWI0); + sunxi_gpio_set_cfgpin(SUNXI_GPB(7), SUN8I_GPB_TWI0);//SUNXI_GPIO_OUTPUT);//SUN8I_GPB_TWI0); + clock_twi_onoff(0, 1); + sunxi_gpio_set_cfgpin(SUNXI_GPE(21), SUN8I_GPE_TWI1);//SUNXI_GPIO_OUTPUT);//SUN8I_GPE_TWI1); + sunxi_gpio_set_cfgpin(SUNXI_GPE(22), SUN8I_GPE_TWI1);//SUNXI_GPIO_OUTPUT);//SUN8I_GPE_TWI1); + clock_twi_onoff(1, 1); +#endif +//slave mode + //addr = readl(®->addr); + //addr = (addr&0x01) | ((slaveaddr << 1)&0xFE); + //writel(addr, &®->addr); + + debug("%s exit\n", __func__); +} + +int sun8i_i2c_read(struct sun8i_i2c_regs* reg, u8 chip, uint addr, int alen, u8 *data, int len) +{ + unsigned char shift = 0; + int ret; + debug("%s enter chip 0x%X addr 0x%X alen %d len %d data 0x%X \n", __func__, chip,addr,alen,len,*data); + send_start(reg); +#if 0 + if(alen > 0) { + if(alen > 1) + debug("Not support yet over two bytes.\n"); + + ret = write_byte(reg,chip << 1); + if(ret) { /* write cycle */ + send_stop(reg); + debug("i2c_read, no chip responded %02X\n", chip); + return ret; + } + + + /* shift = (alen-1) * 8; + while(alen-- > 0) { + ret = write_byte(reg,addr >> shift); + if(ret) { + debug("i2c_read, address not ed\n"); + return ret; + } + shift -= 8; + } */ +#ifdef CONFIG_SOFT_I2C_READ_REPEATED_START + send_start(reg); +#else + send_stop(reg); + send_start(reg); +#endif + } +#endif + write_byte(reg,(chip << 1) | 1); /* read cycle */ + + while(len-- > 0) { + *data++ = read_byte(reg,len == 0); + } + send_stop(reg); + debug("%s exit\n", __func__); + return 0; +} + +int sun8i_i2c_write(struct sun8i_i2c_regs *reg, u8 chip, uint addr, int alen, u8 *buffer, int len) +{ + unsigned char data = *buffer; + int shift, failures = 0; + int ret=0; + debug("%s enter chip 0x%X, addr 0x%X val 0x%X alen %d len %d buf 0x%X\n", __func__,chip,addr,data,alen,len,buffer); + + send_start(reg); + + if(alen > 0){ + ret = write_byte(reg,chip << 1); + if(ret) { /* write cycle */ + send_stop(reg); + debug("i2c_write, no chip responded %02X\n", chip); + return ret; + } + /* shift = (alen-1) * 8; + while(alen-- > 0) { + ret = write_byte(reg,chip >> shift); + if(ret) { + debug("i2c_write, address not ed\n"); + return ret; + } + shift -= 8; + }*/ + } + + while(len-- > 0) { + ret = write_byte(reg,*buffer++); + if(ret) { + failures++; + } + } + send_stop(reg); + debug("%s exit\n", __func__); + return(failures); +} + +static int sun8i_i2c_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs) +{ + struct sun8i_i2c_bus *bus = dev_get_priv(dev); + struct sun8i_i2c_regs *reg = bus->regs; + struct i2c_msg *msgs = msg; + bool is_read; + u32 int_addr_flag = 0; + int ret = 0; + + debug("%s enter msgs %d chip=0x%x, len=0x%x\n\n", __func__,nmsgs,msgs->addr, msgs->len); + + for(; nmsgs>0; nmsgs--, msgs++){ + + if(msgs->flags & I2C_M_RD){ + ret = sun8i_i2c_read(reg, msgs->addr,0,1,msgs->buf,msgs->len); + } else { + ret = sun8i_i2c_write(reg, msgs->addr,0, 1, msgs->buf, msgs->len); + } + + if(ret) { + debug("i2c_write: error sending\n"); + return -EREMOTEIO; + } + } + debug("%s exit\n", __func__); + return ret; +} + +static int sun8i_i2c_probe_chip(struct udevice *dev, uint chip, uint chip_flags) +{ + struct sun8i_i2c_bus *bus = dev_get_priv(dev); + struct sun8i_i2c_regs *reg = bus->regs; + int ret; + u8 data = 0; + debug("%s enter\n", __func__); + + bus->regs = (struct sun8i_i2c_regs *)dev_get_addr(dev); + bus->speed = 400000; + + sun8i_i2c_init(reg); + + ret = sun8i_i2c_write(reg,chip,0x00,1,&data,1); + + debug("%s exit ret 0x%X\n", __func__,ret); + return ret; +} + +static int sun8i_i2c_probe(struct udevice *dev) +{ + struct sun8i_i2c_bus *bus = dev_get_priv(dev); + struct sun8i_i2c_regs *reg = bus->regs; + + int ret; + + debug("%s enter\n", __func__); + + bus->regs = (struct sun8i_i2c_regs *)dev_get_addr(dev); + bus->speed = 400000; + + sun8i_i2c_init(reg); + + debug("%s exit\n", __func__); + return 0; +} + +static int sun8i_i2c_ofdata_to_platdata(struct udevice *dev) +{ + const void *blob = gd->fdt_blob; + struct sun8i_i2c_bus *bus = dev_get_priv(dev); + int node = dev->of_offset; + debug("%s enter \n", __func__); + bus->regs = (struct sun8i_i2c_regs *)dev_get_addr(dev); + bus->pdata = (struct sun8i_i2c_pdata *)dev_get_driver_data(dev); + bus->clock_frequency = fdtdec_get_int(blob, node, + "clock-frequency", 100000); + debug("%s exit \n", __func__); + return 0; +} + +static int sun8i_i2c_set_bus_speed(struct udevice *dev, unsigned int speed) +{ + struct sun8i_i2c_bus *bus = dev_get_priv(dev); + struct sun8i_i2c_regs *reg = bus->regs; + bus->speed = 400000; + writel(0x28, ®->ccr); + + return 0; +} + +static int sun8i_i2c_reset(struct udevice *dev) +{ + struct sun8i_i2c_bus *bus = dev_get_priv(dev); + struct sun8i_i2c_regs *reg = bus->regs; + debug("%s enter\n", __func__); + writel(0x01, ®->srst); + sun8i_i2c_init(reg); + debug("%s exit\n", __func__); + return 0; +} + +static const struct dm_i2c_ops sun8i_i2c_ops = { + .xfer = sun8i_i2c_xfer, + .probe_chip = sun8i_i2c_probe_chip, + .set_bus_speed = sun8i_i2c_set_bus_speed, + .deblock = sun8i_i2c_reset, +/* .get_bus_speed = sun8i_i2c_get_bus_speed, */ +}; + +static const struct udevice_id sun8i_i2c_ids[] = { + { .compatible = "i4vine,i2c-sunxi",}, + { /* sentinel */ } +}; + + + +U_BOOT_DRIVER(i2c_sunxi) = { + .name = "i2c_sunxi", + .id = UCLASS_I2C, + .of_match = sun8i_i2c_ids, + .ofdata_to_platdata = sun8i_i2c_ofdata_to_platdata, + .per_child_auto_alloc_size = sizeof(struct dm_i2c_chip), + .priv_auto_alloc_size = sizeof(struct sun8i_i2c_bus), + .ops = &sun8i_i2c_ops, + .probe = sun8i_i2c_probe, +}; + From a5af77136a27e4c1a9ce222ce13b46b5bcd3e5fa Mon Sep 17 00:00:00 2001 From: ujuo Date: Fri, 15 Dec 2017 16:45:04 +0900 Subject: [PATCH 17/18] dm:i2c:sunxi:add i2c driver --- arch/arm/include/asm/arch-sunxi/sunxi_i2c.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/arch/arm/include/asm/arch-sunxi/sunxi_i2c.h b/arch/arm/include/asm/arch-sunxi/sunxi_i2c.h index 618dfb36c1e8..930523397277 100644 --- a/arch/arm/include/asm/arch-sunxi/sunxi_i2c.h +++ b/arch/arm/include/asm/arch-sunxi/sunxi_i2c.h @@ -1,5 +1,5 @@ /* - * Support for GPIO-I2C on SUN8I V3S + * SUN8I V3S I2C driver. * * Copyright(c) 2017 I4VINE Inc., * All right reserved by JuYoung Ryu From 4ac391e16098c190d6f9639cecc2108f2af8d54f Mon Sep 17 00:00:00 2001 From: ujuo Date: Fri, 15 Dec 2017 16:45:28 +0900 Subject: [PATCH 18/18] dm:i2c:sunxi:add i2c driver --- drivers/i2c/Kconfig | 6 ++++++ drivers/i2c/Makefile | 1 + drivers/i2c/sunxi_i2c.c | 2 +- 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig index 051f911e23b7..6814de4447b8 100644 --- a/drivers/i2c/Kconfig +++ b/drivers/i2c/Kconfig @@ -189,6 +189,12 @@ config TEGRA186_BPMP_I2C by the BPMP, and can only be accessed by the main CPU via IPC requests to the BPMP. This driver covers the latter case. +config I2C_SUNXI + bool "Enable sun8i i2c driver" + depends on DM_I2C + help + Support for sun8i v3s. + source "drivers/i2c/muxes/Kconfig" endmenu diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile index 7c86198863c4..1184e89007f6 100644 --- a/drivers/i2c/Makefile +++ b/drivers/i2c/Makefile @@ -43,5 +43,6 @@ obj-$(CONFIG_SYS_I2C_UNIPHIER) += i2c-uniphier.o obj-$(CONFIG_SYS_I2C_UNIPHIER_F) += i2c-uniphier-f.o obj-$(CONFIG_SYS_I2C_ZYNQ) += zynq_i2c.o obj-$(CONFIG_TEGRA186_BPMP_I2C) += tegra186_bpmp_i2c.o +obj-$(CONFIG_I2C_SUNXI) += sunxi_i2c.o obj-$(CONFIG_I2C_MUX) += muxes/ diff --git a/drivers/i2c/sunxi_i2c.c b/drivers/i2c/sunxi_i2c.c index 5efebb960e39..af8591d7e1a8 100644 --- a/drivers/i2c/sunxi_i2c.c +++ b/drivers/i2c/sunxi_i2c.c @@ -1,5 +1,5 @@ /* - * SUN8I V3S GPIO-I2C driver. + * SUN8I V3S I2C driver. * * Copyright(c) 2017 I4VINE Inc., * All right reserved by JuYoung Ryu