From facdd1f89c845299ebcff829741215fd4ce5fa78 Mon Sep 17 00:00:00 2001 From: ArthurKoba <61914203+ArthurKoba@users.noreply.github.com> Date: Fri, 4 Sep 2026 14:09:57 +0300 Subject: [PATCH 1/2] ARM: fullhan: add FH8626V100 platform support --- arch/arm/mach-fh/Kconfig | 48 + arch/arm/mach-fh/Makefile | 9 +- arch/arm/mach-fh/fh8626v100/Makefile | 1 + arch/arm/mach-fh/fh8626v100/board.c | 888 ++++++++++++++++++ .../board_config.fh8626v100.appboard | 30 + arch/arm/mach-fh/fh8626v100/chip.c | 570 +++++++++++ arch/arm/mach-fh/fh8626v100/chip.h | 109 +++ arch/arm/mach-fh/fh8626v100/iopad.h | 575 ++++++++++++ arch/arm/mach-fh/fh8626v100/platform.h | 9 + arch/arm/mach-fh/fh8626v100/pmu.c | 283 ++++++ arch/arm/mach-fh/include/mach/fh_gmac_plat.h | 3 +- arch/arm/mach-fh/include/mach/pinctrl.h | 7 +- arch/arm/mach-fh/include/mach/pmu.h | 4 + arch/arm/mach-fh/pinctrl.c | 7 +- arch/arm/tools/mach-types | 1 + drivers/misc/fh_sadc_v2.c | 3 +- drivers/net/ethernet/fullhan/fh_gmac_main.c | 41 +- drivers/net/ethernet/fullhan/fh_gmac_phyt.c | 21 +- drivers/net/ethernet/fullhan/fh_gmac_phyt.h | 5 + drivers/pwm/Makefile | 2 +- drivers/pwm/pwm-fullhan-common.c | 35 +- drivers/rtc/rtc-fh_v2.c | 30 +- drivers/usb/dwc2/platform.c | 4 +- 23 files changed, 2643 insertions(+), 42 deletions(-) create mode 100644 arch/arm/mach-fh/fh8626v100/Makefile create mode 100644 arch/arm/mach-fh/fh8626v100/board.c create mode 100644 arch/arm/mach-fh/fh8626v100/board_config.fh8626v100.appboard create mode 100644 arch/arm/mach-fh/fh8626v100/chip.c create mode 100644 arch/arm/mach-fh/fh8626v100/chip.h create mode 100644 arch/arm/mach-fh/fh8626v100/iopad.h create mode 100644 arch/arm/mach-fh/fh8626v100/platform.h create mode 100644 arch/arm/mach-fh/fh8626v100/pmu.c diff --git a/arch/arm/mach-fh/Kconfig b/arch/arm/mach-fh/Kconfig index 3518d065dc..ceec359132 100644 --- a/arch/arm/mach-fh/Kconfig +++ b/arch/arm/mach-fh/Kconfig @@ -68,6 +68,18 @@ endif choice prompt "Board" +config ARCH_FH8626V100 + bool "Fullhan FH8626V100" + select CPU_V6 + select FULLHAN_INTC + select FULLHAN_TIMER + help + Enable support for the Fullhan FH8626V100 SoC. The target uses an + ARMv6 CPU with the Fullhan interrupt controller and timer. This + option provides the SoC-level facilities required by the legacy + non-device-tree platform code; board devices are registered by the + matching machine configuration. + config ARCH_FH885xV200 bool "Fullhan FH885xV200" select CPU_V6 @@ -81,6 +93,7 @@ endchoice config FH_CHIP_NAME string prompt "Select chip name, keep default" + default "fh8626v100" if MACH_FH8626V100 default "fh8856v200" if MACH_FH8856V200 default "fh8852v200" if MACH_FH8852V200 default "fh8858v200" if MACH_FH8858V200 @@ -88,6 +101,41 @@ config FH_CHIP_NAME default "fh8852v210" if MACH_FH8852V210 default "fh8858v210" if MACH_FH8858V210 +config MACH_FH8626V100 + bool "FullHan FH8626V100 board" + default y + depends on ARCH_FH8626V100 + help + Enable the legacy non-device-tree machine description for + FH8626V100 boards. It preserves the stock U-Boot ATAG handoff and + the verified early MMIO mappings while the native OpenIPC kernel is + brought up incrementally. Device support is added only after the + corresponding FH8626V100 hardware contract is verified. + +config FH8626V100_ONCHIP_RTC + bool "Enable the FH8626V100 on-chip RTC" + default y + depends on MACH_FH8626V100 && RTC_DRV_FH + help + Register the FH8626V100 on-chip RTC platform device. Individual board + profiles may disable it when the required clock/backup hardware is not + available or has not been validated on that board. The Fullhan TSENSOR + is accessed through the same RTC core command channel rather than a + direct temperature MMIO register, so enabling this option is also a + prerequisite for the legacy TSENSOR path but does not prove that either + function works on a particular board. + +config FH8626V100_AJL33PQ0866_MMC + bool "Enable AJL33PQ0866 one-bit SD0 slot" + default n + depends on MACH_FH8626V100 && MMC_FH + help + Register only the SD0 controller wired to the microSD slot on the + ANJIA AJL33PQ0866 and select its exact stock SD0_1BIT_NO_WP pinmux. + The one-bit profile leaves pad66 available as the active-low GPIO61 + reset button. Other FH8626V100 boards must select their own controller + registration and pinmux policy. + config MACH_FH8856V200 bool "FullHan FH8856V200 board" default n diff --git a/arch/arm/mach-fh/Makefile b/arch/arm/mach-fh/Makefile index 7f250d0cd7..2454703c34 100644 --- a/arch/arm/mach-fh/Makefile +++ b/arch/arm/mach-fh/Makefile @@ -1,10 +1,15 @@ CONFIG_FH_CHIP_NAME := $(subst ",,$(CONFIG_FH_CHIP_NAME)) EXTRA_CFLAGS += -Iarch/arm/mach-fh/$(CONFIG_FH_CHIP_NAME) -obj-y += pmu.o fullhan.o fh_common.o fh_chipid.o +obj-y += fullhan.o fh_common.o fh_chipid.o + +ifneq ($(CONFIG_MACH_FH8626V100),y) +obj-y += pmu.o +endif ifneq ($(CONFIG_USE_OF),y) -obj-y += pinctrl.o clock.o +obj-y += clock.o +obj-y += pinctrl.o obj-y += $(CONFIG_FH_CHIP_NAME)/ endif diff --git a/arch/arm/mach-fh/fh8626v100/Makefile b/arch/arm/mach-fh/fh8626v100/Makefile new file mode 100644 index 0000000000..56e2919bfc --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/Makefile @@ -0,0 +1 @@ +obj-y += board.o chip.o pmu.o diff --git a/arch/arm/mach-fh/fh8626v100/board.c b/arch/arm/mach-fh/fh8626v100/board.c new file mode 100644 index 0000000000..1ff137646c --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/board.c @@ -0,0 +1,888 @@ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#ifdef CONFIG_FH_DMAC +#include +#endif +#include +#include +#include +#ifdef CONFIG_FH8626V100_AJL33PQ0866_MMC +#include +#endif +#ifdef CONFIG_FH_DW_I2S +#include +#endif +#include +#ifdef CONFIG_FH8626V100_ONCHIP_RTC +#include +#endif +#include +#include +#include +#include +#include +#include +#include +#include + +#include "chip.h" +#include "platform.h" + +struct uart_port fh_serial_ports[FH_UART_NUMBER]; + +static const u8 fh8626v100_ethaddr_sentinel[ETH_ALEN] __initconst = { + 0x10, 0x20, 0x30, 0x40, 0x50, 0x60 +}; + +static const u8 openipc_ethaddr_sentinel[ETH_ALEN] __initconst = { + 0x00, 0x00, 0x23, 0x34, 0x45, 0x66 +}; + +static u8 boot_ethaddr[ETH_ALEN] __initdata; + +static bool __init fh8626v100_mac_is_usable(const u8 *addr) +{ + return is_valid_ether_addr(addr) && + !ether_addr_equal(addr, fh8626v100_ethaddr_sentinel) && + !ether_addr_equal(addr, openipc_ethaddr_sentinel); +} + +static int __init fh8626v100_parse_ethaddr(char *str) +{ + if (str && mac_pton(str, boot_ethaddr) && + fh8626v100_mac_is_usable(boot_ethaddr)) + return 0; + + eth_zero_addr(boot_ethaddr); + pr_warn("fh8626v100: ignoring invalid or sentinel ethaddr bootarg\n"); + return 0; +} + +early_param("ethaddr", fh8626v100_parse_ethaddr); + +static struct map_desc fh8626v100_io_desc[] __initdata = { + { + .virtual = VA_RAM_REG_BASE, + .pfn = __phys_to_pfn(RAM_BASE), + .length = SZ_16K, + .type = MT_MEMORY_RWX, + }, + { + .virtual = VA_DDRC_REG_BASE, + .pfn = __phys_to_pfn(DDRC_REG_BASE), + .length = SZ_16K, + .type = MT_DEVICE, + }, + { + .virtual = VA_INTC_REG_BASE, + .pfn = __phys_to_pfn(INTC_REG_BASE), + .length = SZ_16K, + .type = MT_DEVICE, + }, + { + .virtual = VA_TIMER_REG_BASE, + .pfn = __phys_to_pfn(TIMER_REG_BASE), + .length = SZ_16K, + .type = MT_DEVICE, + }, + { + .virtual = VA_PMU_REG_BASE, + .pfn = __phys_to_pfn(PMU_REG_BASE), + .length = SZ_16K, + .type = MT_DEVICE, + }, + { + .virtual = VA_UART0_REG_BASE, + .pfn = __phys_to_pfn(UART0_REG_BASE), + .length = SZ_16K, + .type = MT_DEVICE, + }, + { + .virtual = VA_UART1_REG_BASE, + .pfn = __phys_to_pfn(UART1_REG_BASE), + .length = SZ_16K, + .type = MT_DEVICE, + }, + { + .virtual = VA_UART2_REG_BASE, + .pfn = __phys_to_pfn(UART2_REG_BASE), + .length = SZ_16K, + .type = MT_DEVICE, + }, +}; + +static struct resource fh_uart0_resources[] = { + { + .start = UART0_REG_BASE, + .end = UART0_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = UART0_IRQ, + .end = UART0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource fh_uart1_resources[] = { + { + .start = UART1_REG_BASE, + .end = UART1_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = UART1_IRQ, + .end = UART1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource fh_uart2_resources[] = { + { + .start = UART2_REG_BASE, + .end = UART2_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = UART2_IRQ, + .end = UART2_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_platform_uart fh_uart_platform_data[] = { + { + .mapbase = UART0_REG_BASE, + .fifo_size = 16, + .irq = UART0_IRQ, + .uartclk = FH8626V100_UART_CLOCK, + .use_dma = 0, + .dma_info = NULL, + }, + { + .mapbase = UART1_REG_BASE, + .fifo_size = 32, + .irq = UART1_IRQ, + .uartclk = FH8626V100_UART_CLOCK, + .use_dma = 0, + .dma_info = NULL, + }, + { + .mapbase = UART2_REG_BASE, + .fifo_size = 32, + .irq = UART2_IRQ, + .uartclk = FH8626V100_UART_CLOCK, + .use_dma = 0, + .dma_info = NULL, + }, +}; + +static struct platform_device fh_uart0_device = { + .name = "ttyS", + .id = 0, + .num_resources = ARRAY_SIZE(fh_uart0_resources), + .resource = fh_uart0_resources, + .dev.platform_data = &fh_uart_platform_data[0], +}; + +static struct platform_device fh_uart1_device = { + .name = "ttyS", + .id = 1, + .num_resources = ARRAY_SIZE(fh_uart1_resources), + .resource = fh_uart1_resources, + .dev.platform_data = &fh_uart_platform_data[1], +}; + +static struct platform_device fh_uart2_device = { + .name = "ttyS", + .id = 2, + .num_resources = ARRAY_SIZE(fh_uart2_resources), + .resource = fh_uart2_resources, + .dev.platform_data = &fh_uart_platform_data[2], +}; + +static struct resource fh_gpio0_resources[] = { + { + .start = GPIO0_REG_BASE, + .end = GPIO0_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = GPIO0_IRQ, + .end = GPIO0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_gpio_chip fh_gpio0_chip = { + .chip = { + .owner = THIS_MODULE, + .label = "FH_GPIO0", + .base = 0, + .ngpio = 32, + }, +}; + +static struct platform_device fh_gpio0_device = { + .name = GPIO_NAME, + .id = 0, + .num_resources = ARRAY_SIZE(fh_gpio0_resources), + .resource = fh_gpio0_resources, + .dev.platform_data = &fh_gpio0_chip, +}; + +static struct resource fh_gpio1_resources[] = { + { + .start = GPIO1_REG_BASE, + .end = GPIO1_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = GPIO1_IRQ, + .end = GPIO1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_gpio_chip fh_gpio1_chip = { + .chip = { + .owner = THIS_MODULE, + .label = "FH_GPIO1", + .base = 32, + .ngpio = 32, + }, +}; + +static struct platform_device fh_gpio1_device = { + .name = GPIO_NAME, + .id = 1, + .num_resources = ARRAY_SIZE(fh_gpio1_resources), + .resource = fh_gpio1_resources, + .dev.platform_data = &fh_gpio1_chip, +}; + +static struct resource fh_gmac_resources[] = { + { + .start = GMAC_REG_BASE, + .end = GMAC_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = GMAC_IRQ, + .end = GMAC_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_gmac_platform_data fh_gmac_data = { + .phy_reset_pin = FH8626V100_PHY_RESET_GPIO, +}; + +static void __init fh8626v100_select_mac_address(void) +{ + if (fh8626v100_mac_is_usable(boot_ethaddr)) { + ether_addr_copy(fh_gmac_data.mac_addr, boot_ethaddr); + pr_info("fh8626v100: using ethaddr bootarg MAC %pM\n", + fh_gmac_data.mac_addr); + } else { + eth_zero_addr(fh_gmac_data.mac_addr); + pr_info("fh8626v100: no usable bootloader MAC address\n"); + } +} + +static struct platform_device fh_gmac_device = { + .name = "fh_gmac", + .id = 0, + .num_resources = ARRAY_SIZE(fh_gmac_resources), + .resource = fh_gmac_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &fh_gmac_data, + }, +}; + +static struct resource fh_i2c0_resources[] = { + { + .start = I2C0_REG_BASE, + .end = I2C0_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = I2C0_IRQ, + .end = I2C0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource fh_i2c1_resources[] = { + { + .start = I2C1_REG_BASE, + .end = I2C1_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = I2C1_IRQ, + .end = I2C1_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct resource fh_i2c2_resources[] = { + { + .start = I2C2_REG_BASE, + .end = I2C2_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = I2C2_IRQ, + .end = I2C2_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct platform_device fh_i2c0_device = { + .name = "fh_i2c", + .id = 0, + .num_resources = ARRAY_SIZE(fh_i2c0_resources), + .resource = fh_i2c0_resources, +}; + +static struct platform_device fh_i2c1_device = { + .name = "fh_i2c", + .id = 1, + .num_resources = ARRAY_SIZE(fh_i2c1_resources), + .resource = fh_i2c1_resources, +}; + +static struct platform_device fh_i2c2_device = { + .name = "fh_i2c", + .id = 2, + .num_resources = ARRAY_SIZE(fh_i2c2_resources), + .resource = fh_i2c2_resources, +}; + +#ifdef CONFIG_FH8626V100_AJL33PQ0866_MMC +static struct resource fh_sdc0_resources[] = { + { + .start = SDC0_REG_BASE, + .end = SDC0_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = SDC0_IRQ, + .end = SDC0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +/* + * Exact AJL33PQ0866 stock SD0 data. A zero caps field selects one-bit mode. + * Card detect comes from the controller's dedicated SD0_CD input. The + * SD0_1BIT_NO_WP mux has no write-protect pad, and stock leaves get_ro unset. + */ +static struct fh_mci_board fh_mci_sd0_data = { + .num_slots = 1, + .bus_hz = 50000000, + .detect_delay_ms = 200, + .drv_degree = 2, + .sam_degree = 0, +}; + +static struct platform_device fh_sd0_device = { + .name = "fh_mci", + .id = 0, + .num_resources = ARRAY_SIZE(fh_sdc0_resources), + .resource = fh_sdc0_resources, + .dev = { + .coherent_dma_mask = DMA_BIT_MASK(32), + .platform_data = &fh_mci_sd0_data, + }, +}; +#endif + +/* + * Keep RTC registration in the generic FH8626V100 platform. Board profiles + * without validated clock/backup hardware, including AJL33PQ0866, disable the + * option in their board-only configuration rather than removing shared SoC + * support. + */ +#ifdef CONFIG_FH8626V100_ONCHIP_RTC +static struct resource fh_rtc_resources[] = { + { + .start = RTC_REG_BASE, + .end = RTC_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = RTC_IRQ, + .end = RTC_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_rtc_plat_data fh_rtc_data = { + .lut_cof = 58, + .lut_offset = 0xff, + .tsensor_cp_default_out = 0x993, + .clk_name = "rtc_pclk_gate", +}; + +static struct platform_device fh_rtc_device = { + .name = "fh_rtc", + .id = 0, + .num_resources = ARRAY_SIZE(fh_rtc_resources), + .resource = fh_rtc_resources, + .dev.platform_data = &fh_rtc_data, +}; +#endif + +static struct resource fh_pwm_resources[] = { + { + .start = PWM_REG_BASE, + .end = PWM_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = PWM_IRQ, + .end = PWM_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_pwm_data fh_pwm_data = { + .npwm = 14, +}; + +static struct platform_device fh_pwm_device = { + .name = "fh_pwm", + .id = 0, + .num_resources = ARRAY_SIZE(fh_pwm_resources), + .resource = fh_pwm_resources, + .dev.platform_data = &fh_pwm_data, +}; + +static struct resource fh_sadc_resources[] = { + { + .start = SADC_REG_BASE, + .end = SADC_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = SADC_IRQ, + .end = SADC_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_sadc_platform_data fh_sadc_data = { + .ref_vol = 3300, + .active_bit = 0xfff, +}; + +static struct platform_device fh_sadc_device = { + .name = "fh_sadc", + .id = 0, + .num_resources = ARRAY_SIZE(fh_sadc_resources), + .resource = fh_sadc_resources, + .dev.platform_data = &fh_sadc_data, +}; + +static struct resource fh_efuse_resources[] = { + { + .start = EFUSE_REG_BASE, + .end = EFUSE_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, +}; + +static struct fh_efuse_platform_data fh_efuse_data = { + .efuse_support_flag = CRYPTO_CPU_SET_KEY | + CRYPTO_EX_MEM_SET_KEY | + CRYPTO_EX_MEM_SWITCH_KEY | + CRYPTO_EX_MEM_4_ENTRY_1_KEY | + CRYPTO_EX_MEM_INDEP_POWER, +}; + +static struct platform_device fh_efuse_device = { + .name = "fh_efuse", + .id = 0, + .num_resources = ARRAY_SIZE(fh_efuse_resources), + .resource = fh_efuse_resources, + .dev.platform_data = &fh_efuse_data, +}; + +#ifdef CONFIG_FH_DMAC +/* Resources and six-channel priority policy recovered from the stock kernel. */ +static struct resource fh_dma_resources[] = { + { + .start = DMAC_REG_BASE, + .end = DMAC_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = DMAC0_IRQ, + .end = DMAC0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_dma_platform_data fh_dma_data = { + .nr_channels = 6, + .chan_priority = CHAN_PRIORITY_ASCENDING, + .clk_name = "ahb_clk", +}; + +static struct platform_device fh_dma_device = { + .name = "fh_dmac", + .id = 0, + .num_resources = ARRAY_SIZE(fh_dma_resources), + .resource = fh_dma_resources, + .dev.platform_data = &fh_dma_data, +}; +#endif + +#ifdef CONFIG_FH_DW_I2S +/* + * Internal-codec audio contract recovered from the exact FH8626V100 stock + * kernel. This path does not use the external DWI2S pads, so deliberately do + * not add DWI2S to fh_pinctrl_selected_devices. + */ +static struct resource fh_i2s_resources[] = { + { + .start = I2S_REG_BASE, + .end = I2S_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = ACW_REG_BASE, + .end = ACW_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = I2S0_IRQ, + .end = I2S0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_i2s_platform_data fh_i2s_data = { + .dma_capture_channel = 2, + .dma_playback_channel = 3, + .dma_master = 1, + .dma_rx_hs_num = 10, + .dma_tx_hs_num = 11, + .clk = "i2s_clk", + .pclk = NULL, + .acodec_pclk = "acodec_pclk", + .acodec_mclk = "acodec_mclk", +}; + +static struct platform_device fh_i2s_device = { + .name = "fh_audio", + .id = 0, + .num_resources = ARRAY_SIZE(fh_i2s_resources), + .resource = fh_i2s_resources, + .dev.platform_data = &fh_i2s_data, +}; +#endif + +static struct resource fh_usb_resources[] = { + { + .start = USBC_REG_BASE, + .end = USBC_REG_BASE + SZ_1M - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = USBC_IRQ, + .end = USBC_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_usb_platform_data fh_usb_data = { + .dr_mode = "host", + .vbus_pwren = 0xffffffff, +}; + +static struct platform_device fh_usb_device = { + .name = "fh_usb", + .id = 0, + .num_resources = ARRAY_SIZE(fh_usb_resources), + .resource = fh_usb_resources, + .dev.platform_data = &fh_usb_data, +}; + +static struct resource fh_wdt_resources[] = { + { + .start = WDT_REG_BASE, + .end = WDT_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = WDT_IRQ, + .end = WDT_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_wdt_platform_data fh_wdt_data = { + .mode = MODE_DISCRETE, +}; + +static struct platform_device fh_wdt_device = { + .name = "fh_wdt", + .id = 0, + .num_resources = ARRAY_SIZE(fh_wdt_resources), + .resource = fh_wdt_resources, + .dev.platform_data = &fh_wdt_data, +}; + +static struct resource fh_spi0_resources[] = { + { + .start = SPI0_REG_BASE, + .end = SPI0_REG_BASE + SZ_16K - 1, + .flags = IORESOURCE_MEM, + }, + { + .start = SPI0_IRQ, + .end = SPI0_IRQ, + .flags = IORESOURCE_IRQ, + }, +}; + +static struct fh_spi_platform_data fh_spi0_data = { + .apb_clock_in = FH8626V100_SPI0_APB_CLOCK, + .slave_max_num = 2, + .clock_source = { FH8626V100_SPI0_APB_CLOCK }, + .clock_source_num = 1, + .cs_data[0].GPIO_Pin = FH8626V100_SPI0_CS0, + .cs_data[0].name = "spi0_cs0", + .cs_data[1].GPIO_Pin = FH8626V100_SPI0_CS1, + .cs_data[1].name = "spi0_cs1", + .bus_no = 0, + .clk_name = "spi0_clk", + .ctl_wire_support = ONE_WIRE_SUPPORT | DUAL_WIRE_SUPPORT | + MULTI_WIRE_SUPPORT, + .dma_transfer_enable = SPI_TRANSFER_USE_DMA, + .rx_handshake_num = 4, +}; + +static struct platform_device fh_spi0_device = { + .name = "fh_spi", + .id = 0, + .num_resources = ARRAY_SIZE(fh_spi0_resources), + .resource = fh_spi0_resources, + .dev.platform_data = &fh_spi0_data, +}; + +static struct mtd_partition fh8626v100_spi_parts[] = { + /* + * Keep the factory 8 MiB geometry: U-Boot and existing recovery notes + * use these exact offsets. OpenIPC only changes the userspace-facing + * names of data/app so standard overlay and sysupgrade code find them. + * + * MTD_WRITEABLE in mask_flags removes write permission. Protect + * immutable bootstrap/U-Boot. The environment remains writable for + * fw_setenv; kernel/rootfs are writable for sysupgrade; rootfs_data is + * the persistent JFFS2 overlay. It combines the factory data+res ranges: + * OpenIPC does not consume the proprietary resource filesystem, while a + * full 1 MiB upper layer is materially safer than 512 KiB. + */ + { + .name = "bootstrap", + .offset = 0, + .size = SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "uboot-env", + .offset = MTDPART_OFS_APPEND, + .size = SZ_64K, + }, + { + .name = "uboot", + .offset = MTDPART_OFS_APPEND, + .size = SZ_256K - SZ_64K, + .mask_flags = MTD_WRITEABLE, + }, + { + .name = "kernel", + .offset = MTDPART_OFS_APPEND, + .size = SZ_2M + SZ_1M, + }, + { + .name = "rootfs_data", + .offset = MTDPART_OFS_APPEND, + .size = SZ_1M, + }, + { + .name = "rootfs", + .offset = MTDPART_OFS_APPEND, + .size = MTDPART_SIZ_FULL, + }, +}; + +static struct flash_platform_data fh8626v100_flash_data = { + .parts = fh8626v100_spi_parts, + .nr_parts = ARRAY_SIZE(fh8626v100_spi_parts), +}; + +static struct spi_board_info fh8626v100_spi_devices[] = { + { + .modalias = "m25p80", + .bus_num = 0, + .chip_select = 0, + .max_speed_hz = 50000000, + .mode = SPI_MODE_3, + .platform_data = &fh8626v100_flash_data, + }, +}; + +#ifdef CONFIG_FH_PINCTRL_MISC_DEV +/* + * fh_pinctrl_init() installs the FH8626 pin database, while the misc driver + * still needs a matching platform device before it can expose + * /proc/driver/pinctrl. Other non-DT Fullhan boards register the same device. + * The ANJIA profile uses that userspace ABI to mux its board-specific GC1054 + * reset line before exporting GPIO5. + */ +static struct platform_device fh_pinctrl_device = { + .name = "fh_pinctrl", + .id = 0, +}; +#endif + +static struct platform_device *fh8626v100_devices[] __initdata = { + &fh_uart0_device, + &fh_uart1_device, + &fh_uart2_device, + &fh_gpio0_device, + &fh_gpio1_device, + &fh_i2c0_device, + &fh_i2c1_device, + &fh_i2c2_device, +#ifdef CONFIG_FH8626V100_AJL33PQ0866_MMC + &fh_sd0_device, +#endif +#ifdef CONFIG_FH_PINCTRL_MISC_DEV + &fh_pinctrl_device, +#endif +#ifdef CONFIG_FH8626V100_ONCHIP_RTC + &fh_rtc_device, +#endif + &fh_sadc_device, + &fh_efuse_device, +#ifdef CONFIG_FH_DMAC + &fh_dma_device, +#endif +#ifdef CONFIG_FH_DW_I2S + &fh_i2s_device, +#endif + &fh_usb_device, + &fh_pwm_device, + &fh_gmac_device, + &fh_spi0_device, + &fh_wdt_device, +}; + +static void __init fh_console_pre_init(struct fh_platform_uart *plat, int num) +{ + int idx; + + for (idx = 0; idx < num; idx++) { + struct uart_port *port = &fh_serial_ports[idx]; + + port->mapbase = plat[idx].mapbase; + port->fifosize = plat[idx].fifo_size; + port->uartclk = plat[idx].uartclk; + + switch (idx) { + case 0: + port->membase = (unsigned char *)VA_UART0_REG_BASE; + break; + case 1: + port->membase = (unsigned char *)VA_UART1_REG_BASE; + break; + case 2: + port->membase = (unsigned char *)VA_UART2_REG_BASE; + break; + } + } +} + +static void __init fh8626v100_map_io(void) +{ + iotable_init(fh8626v100_io_desc, ARRAY_SIZE(fh8626v100_io_desc)); + fh_console_pre_init(fh_uart_platform_data, + ARRAY_SIZE(fh_uart_platform_data)); +} + +static void __init fh8626v100_board_init(void) +{ + fh8626v100_select_mac_address(); + spi_register_board_info(fh8626v100_spi_devices, + ARRAY_SIZE(fh8626v100_spi_devices)); + platform_add_devices(fh8626v100_devices, + ARRAY_SIZE(fh8626v100_devices)); +} + +static void __init fh8626v100_init_early(void) +{ + fh_pmu_init(); + fh_pinctrl_init(VA_PMU_REG_BASE + 0x80); +#ifdef CONFIG_FH8626V100_AJL33PQ0866_MMC + /* AJL one-bit SD0 leaves pad66/SD0_DATA1 free for GPIO61 reset. */ + fh_pinctrl_sdev("SD0_1BIT_NO_WP", 0); +#endif +} + +static void __init fh8626v100_time_init(void) +{ + unsigned int vtimerbase; + + vtimerbase = (unsigned int)ioremap(TIMER_REG_BASE, SZ_4K); + fh_clk_init(); + fh_timer_init_no_of(vtimerbase, TMR0_IRQ); +} + +static void __init fh8626v100_intc_init(void) +{ + unsigned int vintcbase; + + vintcbase = (unsigned int)ioremap(INTC_REG_BASE, SZ_4K); + fh_intc_init_no_of(vintcbase); +} + +static void fh8626v100_restart(enum reboot_mode mode, const char *cmd) +{ + fh_pmu_restart(); +} + +MACHINE_START(FH8626V100, "FH8626V100") + .atag_offset = 0x100, + .map_io = fh8626v100_map_io, + .init_irq = fh8626v100_intc_init, + .init_time = fh8626v100_time_init, + .init_machine = fh8626v100_board_init, + .init_early = fh8626v100_init_early, + .restart = fh8626v100_restart, +MACHINE_END diff --git a/arch/arm/mach-fh/fh8626v100/board_config.fh8626v100.appboard b/arch/arm/mach-fh/fh8626v100/board_config.fh8626v100.appboard new file mode 100644 index 0000000000..c472aa2b77 --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/board_config.fh8626v100.appboard @@ -0,0 +1,30 @@ +#ifndef BOARD_CONFIG_H_ +#define BOARD_CONFIG_H_ + +/* + * Generic FH8626V100 platform configuration. Keep board-specific sensor + * power/reset GPIO sequencing out of this file. + */ + +#define CONFIG_SD_CD_FIXED + +#define CONFIG_ISP_CLK_RATE 200000000 +#define CONFIG_JPEG_CLK_RATE 200000000 +#define CONFIG_VEU_CLK_RATE 300000000 + +#define USB_VBUS_PWR_GPIO (47) +#define ETH_GPIO "ETH", "GPIO48", "GPIO49", "GPIO50", "GPIO51", "GPIO52",\ + "GPIO53", "GPIO54", "GPIO55", "GPIO56" + +#define CONFIG_PINCTRL_SELECT \ + "I2C0", "PWM2", "PWM3", "PWM4", "PWM5", "PWM6", "PWM7", \ + "PWM8", "PWM9", "SADC_XAIN0", "SADC_XAIN1", \ + "SADC_XAIN2", "SADC_XAIN3", "SD0_NO_WP", "SD1_NO_WP", \ + "SENSOR_CLK", "SSI0_4BIT", "UART0", "UART1", "GPIO4", \ + "GPIO13", "GPIO14", "GPIO15", ETH_GPIO, \ + "GPIO30", "GPIO31", "GPIO32", "GPIO43", "GPIO44", \ + "GPIO47", \ +\ + "GPIO11", "GPIO16", "GPIO45", "GPIO46" + +#endif /* BOARD_CONFIG_H_ */ diff --git a/arch/arm/mach-fh/fh8626v100/chip.c b/arch/arm/mach-fh/fh8626v100/chip.c new file mode 100644 index 0000000000..ff264452c4 --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/chip.c @@ -0,0 +1,570 @@ +#include +#include + +#include + +#include "chip.h" + +static struct fh_clk osc_clk = { + .name = "osc_clk", + .frequency = OSC_FREQUENCY, + .flag = CLOCK_FIXED, +}; + +static struct fh_clk pll0_clk = { + .name = "pll0_clk", + .flag = CLOCK_PLL, + .parent = { &osc_clk }, + .div_reg_offset = REG_PMU_PLL0, +}; + +static struct fh_clk pll1_clk = { + .name = "pll1_clk", + .flag = CLOCK_PLL, + .parent = { &osc_clk }, + .div_reg_offset = REG_PMU_PLL1, +}; + +static struct fh_clk cis_pix_clk = { + .name = "cis_pix_clk", + .frequency = 75000000, + .flag = CLOCK_FIXED, +}; + +static struct fh_clk cis_pix_clk_rt = { + .name = "cis_pix_clk_rt", + .frequency = 75000000, + .flag = CLOCK_FIXED, +}; + +static struct fh_clk mipi_pix_clk = { + .name = "mipi_pix_clk", + .flag = CLOCK_MULTI_PARENT | CLOCK_NOGATE | + CLOCK_NORESET, + .parent = { &pll0_clk, &pll1_clk }, + .prediv = 1, + .div_reg_offset = 0x0000003c, + .div_reg_mask = 0x001f0000, + .sel_reg_offset = 0x00000028, + .sel_reg_mask = 0x00000020, +}; + +static struct fh_clk pll0_cis_clk = { + .name = "pll0_cis_clk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00000010, +}; + +static struct fh_clk pix_clk = { + .name = "pix_clk", + .flag = CLOCK_MULTI_PARENT | CLOCK_NODIV | + CLOCK_NORESET, + .parent = { &cis_pix_clk, &cis_pix_clk_rt, + &mipi_pix_clk, &mipi_pix_clk }, + .prediv = 1, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00020000, + .sel_reg_offset = 0x00000028, + .sel_reg_mask = 0x00000060, +}; + +static struct fh_clk cis_clk_out = { + .name = "cis_clk_out", + .flag = CLOCK_MULTI_PARENT | CLOCK_NODIV, + .parent = { &osc_clk, &pll0_clk }, + .prediv = 1, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x00800000, + .sel_reg_offset = 0x00000028, + .sel_reg_mask = 0x00000008, +}; + +static struct fh_clk arc_clk = { + .name = "arc_clk", + .flag = CLOCK_MULTI_PARENT, + .parent = { &osc_clk, &pll0_clk }, + .prediv = 1, + .div_reg_offset = REG_PMU_CLK_DIV2, + .div_reg_mask = 0x000000f0, + .en_reg_offset = REG_PMU_CLK_GATE, + .en_reg_mask = 0x00000004, + .rst_reg_offset = REG_PMU_SWRST_APB_CTRL, + .rst_reg_mask = 0x00400000, + .sel_reg_offset = REG_PMU_SYS_CTRL, + .sel_reg_mask = 0x00000001, +}; + +static struct fh_clk ahb_clk = { + .name = "ahb_clk", + .flag = CLOCK_MULTI_PARENT | CLOCK_NORESET | + CLOCK_NOGATE, + .parent = { &osc_clk, &pll0_clk }, + .prediv = 2, + .div_reg_offset = REG_PMU_CLK_DIV2, + .div_reg_mask = 0x000000f0, + .sel_reg_offset = REG_PMU_SYS_CTRL, + .sel_reg_mask = 0x00000001, +}; + +static struct fh_clk dw_100m_clk = { + .name = "dw_100m_clk", + .flag = CLOCK_NOGATE | CLOCK_NODIV | CLOCK_NORESET, + .parent = { &pll1_clk }, + .prediv = 6, +}; + +/* Exact stock FH8626V100 SDC clock and phase controls. */ +static struct fh_clk sdc0_clk = { + .name = "sdc0_clk", + .parent = { &dw_100m_clk }, + .prediv = 2, + .div_reg_offset = REG_PMU_CLK_DIV2, + .div_reg_mask = 0x000f0000, + .en_reg_offset = REG_PMU_CLK_GATE, + .en_reg_mask = 0x00000200, + .rst_reg_offset = REG_PMU_SWRST_AHB_CTRL, + .rst_reg_mask = FH8626V100_SDC0_RESET_MASK, +}; + +static struct fh_clk sdc0_clk_drv = { + .name = "sdc0_clk_drv", + .flag = CLOCK_NOGATE | CLOCK_PHASE, + .parent = { &sdc0_clk }, + .prediv = 1, + .sel_reg_offset = REG_PMU_ETH_CTRL, + .sel_reg_mask = 0x00000180, +}; + +static struct fh_clk sdc0_clk_sample = { + .name = "sdc0_clk_sample", + .flag = CLOCK_NOGATE | CLOCK_PHASE, + .parent = { &sdc0_clk }, + .prediv = 1, + .sel_reg_offset = REG_PMU_ETH_CTRL, + .sel_reg_mask = 0x00000600, +}; + +static struct fh_clk sdc1_clk = { + .name = "sdc1_clk", + .parent = { &dw_100m_clk }, + .prediv = 2, + .div_reg_offset = REG_PMU_CLK_DIV2, + .div_reg_mask = 0x00f00000, + .en_reg_offset = REG_PMU_CLK_GATE, + .en_reg_mask = 0x00000400, + .rst_reg_offset = REG_PMU_SWRST_AHB_CTRL, + .rst_reg_mask = FH8626V100_SDC1_RESET_MASK, +}; + +static struct fh_clk sdc1_clk_drv = { + .name = "sdc1_clk_drv", + .flag = CLOCK_NOGATE | CLOCK_PHASE, + .parent = { &sdc1_clk }, + .prediv = 1, + .sel_reg_offset = REG_PMU_ETH_CTRL, + .sel_reg_mask = 0x00001800, +}; + +static struct fh_clk sdc1_clk_sample = { + .name = "sdc1_clk_sample", + .flag = CLOCK_NOGATE | CLOCK_PHASE, + .parent = { &sdc1_clk }, + .prediv = 1, + .sel_reg_offset = REG_PMU_ETH_CTRL, + .sel_reg_mask = 0x00006000, +}; + +static struct fh_clk pts_clk = { + .name = "pts_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x00000038, + .div_reg_mask = 0x01ff0000, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x00080000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00000001, +}; + +static struct fh_clk isp_hclk = { + .name = "isp_hclk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .prediv = 1, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x00000002, +}; + +static struct fh_clk isp_aclk = { + .name = "isp_aclk", + .flag = CLOCK_MULTI_PARENT, + .parent = { &pll0_clk, &pll1_clk }, + .prediv = 1, + .div_reg_offset = 0x0000003c, + .div_reg_mask = 0x00001f00, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x00000001, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00400000, + .sel_reg_offset = 0x00000028, + .sel_reg_mask = 0x00000010, +}; + +static struct fh_clk pae_clk = { + .name = "pae_clk", + .parent = { &pll0_clk }, + .prediv = 1, + .div_reg_offset = 0x0000003c, + .div_reg_mask = 0x07000000, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00400000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00800000, +}; + +static struct fh_clk pae_adpt_clk = { + .name = "pae_adpt_clk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x01000000, +}; + +static struct fh_clk multi_pae_clk = { + .name = "multi_pae_clk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00000200, +}; + +static struct fh_clk pae_hclk_gate = { + .name = "pae_hclk_gate", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00800000, +}; + +static struct fh_clk jpeg_hclk = { + .name = "jpeg_hclk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .prediv = 1, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00080000, +}; + +static struct fh_clk jpeg_clk = { + .name = "jpeg_clk", + .flag = CLOCK_MULTI_PARENT, + .parent = { &pll0_clk, &pll1_clk }, + .prediv = 1, + .div_reg_offset = 0x0000003c, + .div_reg_mask = 0x00001f00, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00040000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x01000000, + .sel_reg_offset = 0x00000028, + .sel_reg_mask = 0x00000010, +}; + +static struct fh_clk bgm_hclk = { + .name = "bgm_hclk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .prediv = 1, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00200000, +}; + +static struct fh_clk bgm_clk = { + .name = "bgm_clk", + .flag = CLOCK_MULTI_PARENT, + .parent = { &pll0_clk, &pll1_clk }, + .prediv = 1, + .div_reg_offset = 0x0000003c, + .div_reg_mask = 0x00001f00, + .en_reg_offset = 0x00000024, + .en_reg_mask = 0x00100000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x02000000, + .sel_reg_offset = 0x00000028, + .sel_reg_mask = 0x00000010, +}; + +static struct fh_clk spi0_clk = { + .name = "spi0_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = REG_PMU_CLK_DIV2, + .div_reg_mask = 0x00000f00, + .en_reg_offset = REG_PMU_CLK_GATE, + .en_reg_mask = 0x00000080, + .rst_reg_offset = REG_PMU_SWRST_APB_CTRL, + .rst_reg_mask = 0x00002000, +}; + +static struct fh_clk wdt_clk = { + .name = "wdt_clk", + .parent = { &ahb_clk }, + .prediv = 1, + .div_reg_offset = REG_PMU_CLK_DIV5, + .div_reg_mask = 0x0000ff00, + .en_reg_offset = REG_PMU_CLK_GATE1, + .en_reg_mask = 0x00000004, + .rst_reg_offset = REG_PMU_WDT_CLK_RST, + .rst_reg_mask = 0x00080000, +}; + +static struct fh_clk pll1_clk_div_2 = { + .name = "pll1_clk_div_2", + .flag = CLOCK_NOGATE | CLOCK_NODIV, + .parent = { &pll1_clk }, + .prediv = 2, +}; + +static struct fh_clk dw_50m_clk = { + .name = "dw_50m_clk", + .flag = CLOCK_NOGATE | CLOCK_NODIV | CLOCK_NORESET, + .parent = { &dw_100m_clk }, + .prediv = 2, +}; + +static struct fh_clk i2c0_clk = { + .name = "i2c0_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x00000034, + .div_reg_mask = 0x0000003f, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x00001000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00000200, +}; + +static struct fh_clk i2c1_clk = { + .name = "i2c1_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x00000034, + .div_reg_mask = 0x00003f00, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x08000000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00000100, +}; + +static struct fh_clk i2c2_clk = { + .name = "i2c2_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x00000034, + .div_reg_mask = 0x003f0000, + .en_reg_offset = 0x00000020, + .en_reg_mask = 0x00000200, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00000080, +}; + +static struct fh_clk eth_clk = { + .name = "eth_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x0000002c, + .div_reg_mask = 0x0f000000, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x02000000, + .rst_reg_offset = 0x00000054, + .rst_reg_mask = 0x00000400, +}; + +static struct fh_clk eth_rmii_clk = { + .name = "eth_rmii_clk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .prediv = 1, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x10000000, +}; + +/* + * Internal audio clock tree recovered field-for-field from the stock + * FH8626V100 kernel. The fixed 98.304 MHz source supports the codec's audio + * sample-rate family without depending on external I2S pin multiplexing. + * Keep the gate masks exact: xbus_rpc's RTX audio reset ioctl enables these + * clocks before the ARC firmware starts capture. A shifted mask lets the + * command path start but leaves the PCM DMA ring permanently empty. + */ +static struct fh_clk acodec_pll_clk = { + .name = "acodec_pll_clk", + .frequency = 98304000, + .flag = CLOCK_FIXED, +}; + +static struct fh_clk ac_clk = { + .name = "ac_clk", + .flag = CLOCK_MULTI_PARENT, + .parent = { &osc_clk, &acodec_pll_clk }, + .prediv = 1, + .div_reg_offset = REG_PMU_AUDIO_CTRL, + .div_reg_mask = 0x000003f0, + .en_reg_offset = REG_PMU_AUDIO_CTRL, + .en_reg_mask = 0x00100000, + .rst_reg_offset = REG_PMU_SWRST_APB_CTRL, + .rst_reg_mask = 0x00000040, + .sel_reg_offset = REG_PMU_AUDIO_CTRL, + .sel_reg_mask = 0x00000001, +}; + +static struct fh_clk i2s_clk = { + .name = "i2s_clk", + .parent = { &ac_clk }, + .prediv = 1, + .div_reg_offset = REG_PMU_AUDIO_CTRL, + .div_reg_mask = 0x0003f000, + .en_reg_offset = REG_PMU_AUDIO_CTRL, + .en_reg_mask = 0x01000000, + .rst_reg_offset = REG_PMU_SWRST_APB_CTRL, + .rst_reg_mask = 0x00001000, +}; + +static struct fh_clk acodec_pclk = { + .name = "acodec_pclk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .en_reg_offset = REG_PMU_CLK_GATE2, + .en_reg_mask = 0x00010000, +}; + +static struct fh_clk acodec_mclk = { + .name = "acodec_mclk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .en_reg_offset = REG_PMU_CLK_GATE2, + .en_reg_mask = 0x00008000, +}; + +static struct fh_clk rtc_pclk_gate = { + .name = "rtc_pclk_gate", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .en_reg_offset = 0x00000020, + .en_reg_mask = 0x00000002, +}; + +static struct fh_clk efuse_clk = { + .name = "efuse_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x0000002c, + .div_reg_mask = 0xf0000000, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x00002000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00000020, +}; + +static struct fh_clk pwm_clk = { + .name = "pwm_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x00000034, + .div_reg_mask = 0xff000000, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x00010000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00000010, + /* Stock FH8626V100 programs PWM to 25 MHz during clock init. */ + .def_rate = 25000000, +}; + +static struct fh_clk sadc_clk = { + .name = "sadc_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = 0x0000003c, + .div_reg_mask = 0x0000007f, + .en_reg_offset = 0x0000001c, + .en_reg_mask = 0x04000000, + .rst_reg_offset = 0x0000004c, + .rst_reg_mask = 0x00000008, +}; + +static struct fh_clk usb_clk = { + .name = "usb_clk", + .flag = CLOCK_MULTI_PARENT | CLOCK_NODIV, + .parent = { &osc_clk, &dw_50m_clk }, + .prediv = 1, + .en_reg_offset = REG_PMU_CLK_GATE2, + .en_reg_mask = 0x00002000, + .sel_reg_offset = REG_PMU_ETH_CTRL, + .sel_reg_mask = 0x00008000, +}; + +static struct fh_clk usb_hclk = { + .name = "usb_hclk", + .flag = CLOCK_NODIV | CLOCK_NORESET, + .prediv = 1, + .en_reg_offset = REG_PMU_CLK_GATE2, + .en_reg_mask = 0x00004000, +}; + +static struct fh_clk tmr0_clk = { + .name = "tmr0_clk", + .parent = { &dw_100m_clk }, + .prediv = 1, + .div_reg_offset = REG_PMU_CLK_DIV5, + .div_reg_mask = 0x000000ff, + .en_reg_offset = REG_PMU_CLK_GATE, + .en_reg_mask = 0x00020000, + .rst_reg_offset = REG_PMU_SWRST_APB_CTRL, + .rst_reg_mask = 0x00000002, +}; + +struct fh_clk *fh_clks[] = { + &osc_clk, + &pll0_clk, + &pll1_clk, + &cis_pix_clk, + &cis_pix_clk_rt, + &mipi_pix_clk, + &pll0_cis_clk, + &pix_clk, + &cis_clk_out, + &arc_clk, + &ahb_clk, + &dw_100m_clk, + &sdc0_clk, + &sdc0_clk_drv, + &sdc0_clk_sample, + &sdc1_clk, + &sdc1_clk_drv, + &sdc1_clk_sample, + &pts_clk, + &isp_hclk, + &isp_aclk, + &pae_clk, + &pae_adpt_clk, + &multi_pae_clk, + &pae_hclk_gate, + &jpeg_hclk, + &jpeg_clk, + &bgm_hclk, + &bgm_clk, + &spi0_clk, + &wdt_clk, + &pll1_clk_div_2, + &dw_50m_clk, + &i2c0_clk, + &i2c1_clk, + &i2c2_clk, + ð_clk, + ð_rmii_clk, + &acodec_pll_clk, + &ac_clk, + &i2s_clk, + &acodec_pclk, + &acodec_mclk, + &rtc_pclk_gate, + &efuse_clk, + &pwm_clk, + &sadc_clk, + &usb_clk, + &usb_hclk, + &tmr0_clk, + NULL, +}; +EXPORT_SYMBOL(fh_clks); diff --git a/arch/arm/mach-fh/fh8626v100/chip.h b/arch/arm/mach-fh/fh8626v100/chip.h new file mode 100644 index 0000000000..f45328dda9 --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/chip.h @@ -0,0 +1,109 @@ +#ifndef __FH8626V100_CHIP_H +#define __FH8626V100_CHIP_H + +#define RAM_BASE 0x10000000 +#define DDRC_REG_BASE 0xed000000 +#define INTC_REG_BASE 0xe0200000 +#define DMAC_REG_BASE 0xe0300000 +#define GMAC_REG_BASE 0xe0600000 +#define USBC_REG_BASE 0xe0700000 +#define SDC0_REG_BASE 0xe2000000 +#define SDC1_REG_BASE 0xe2200000 +#define PMU_REG_BASE 0xf0000000 +#define I2C2_REG_BASE 0xf0100000 +#define I2C0_REG_BASE 0xf0200000 +#define GPIO0_REG_BASE 0xf0300000 +#define PWM_REG_BASE 0xf0400000 +#define UART0_REG_BASE 0xf0700000 +#define UART1_REG_BASE 0xf0800000 +#define I2S_REG_BASE 0xf0900000 +#define ACW_REG_BASE 0xf0a00000 +#define I2C1_REG_BASE 0xf0b00000 +#define TIMER_REG_BASE 0xf0c00000 +#define WDT_REG_BASE 0xf0d00000 +#define SPI0_REG_BASE 0xf0e00000 +#define SADC_REG_BASE 0xf1200000 +#define UART2_REG_BASE 0xf1300000 +#define RTC_REG_BASE 0xf1500000 +#define EFUSE_REG_BASE 0xf1600000 +#define GPIO1_REG_BASE 0xf4000000 + +#define CONSOLE_REG_BASE UART0_REG_BASE +#define FH_UART_NUMBER 3 + +#define REG_PMU_CHIP_ID 0x0000 +#define REG_PMU_IP_VER 0x0004 +#define REG_PMU_SYS_CTRL 0x000c +#define REG_PMU_PLL0 0x0010 +#define REG_PMU_PLL1 0x0014 +#define REG_PMU_CLK_GATE 0x001c +#define REG_PMU_CLK_GATE1 0x0020 +#define REG_PMU_CLK_GATE2 0x0024 +#define REG_PMU_ETH_CTRL 0x0028 +#define REG_PMU_CLK_DIV2 0x002c +#define REG_PMU_CLK_DIV3 0x0030 +#define REG_PMU_CLK_DIV5 0x0038 +#define REG_PMU_AUDIO_CTRL 0x0048 +#define REG_PMU_SWRST_APB_CTRL 0x004c +#define REG_PMU_SWRST_AHB_CTRL 0x0054 +#define REG_PMU_WDT_CLK_RST 0x0058 +#define REG_PMU_ARC_RESET 0x01c4 +#define REG_PMU_A625_INT_RAWSTAT 0x01e4 +#define REG_PMU_ARM_INT_RAWSTAT 0x01f0 +#define REG_PMU_WDT_CTRL 0x01fc +#define REG_PMU_A625BOOT0 0x2000 +#define REG_PMU_A625BOOT1 0x2004 +#define REG_PMU_A625BOOT2 0x2008 +#define REG_PMU_A625BOOT3 0x200c +#define REG_PMU_A625_START_CTRL 0x2010 +#define REG_PMU_USB_SYS 0x0210 +#define REG_PMU_PTSLO 0x022c +#define REG_PMU_PTSHI 0x0230 + +#define WDT_IRQ 2 +#define TMR0_IRQ 3 +#define I2C0_IRQ 9 +#define I2C1_IRQ 10 +#define I2C2_IRQ 11 +#define I2S0_IRQ 12 +#define GMAC_IRQ 13 +#define SDC0_IRQ 14 +#define SDC1_IRQ 15 +#define SPI0_IRQ 17 +#define UART0_IRQ 18 +#define UART1_IRQ 19 +#define UART2_IRQ 20 +#define DMAC0_IRQ 21 +#define SADC_IRQ 25 +#define GPIO0_IRQ 26 +#define RTC_IRQ 33 +#define PWM_IRQ 36 +#define USBC_IRQ 27 +#define GPIO1_IRQ 40 + +#define FH8626V100_UART_CLOCK 16666667 +#define FH8626V100_SPI0_APB_CLOCK 100000000 +#define FH8626V100_SPI0_CS0 54 +#define FH8626V100_SPI0_CS1 55 +#define FH8626V100_PHY_RESET_GPIO 11 + +#define FH8626V100_ETH_SPEED_100M 0x00000004 +#define FH8626V100_EMAC_RESET_MASK 0x00000400 + +#define FH8626V100_SDC0_RESET_MASK 0x00001000 +#define FH8626V100_SDC1_RESET_MASK 0x00000800 + +#define FH8626V100_USB_UTMI_RESET_MASK 0x00080000 +#define FH8626V100_USB_PHY_IDDQ_MASK 0x80000000 +#define FH8626V100_USB_PHY_RESET_MASK 0x00000011 +#define FH8626V100_USB_SLEEP_MODE_MASK 0x01000000 + +#define FH8626V100_ARC_RESET_MASK 0x00040000 + +/* Exact FH8626V100 stock PMU layout used by fh_pmu_dwi2s_set_clk(). */ +#define PMU_DWI2S_CLK_DIV_REG REG_PMU_AUDIO_CTRL +#define PMU_DWI2S_CLK_DIV_SHIFT 4 +#define PMU_DWI2S_CLK_SEL_REG REG_PMU_AUDIO_CTRL +#define PMU_DWI2S_CLK_SEL_SHIFT 0 + +#endif diff --git a/arch/arm/mach-fh/fh8626v100/iopad.h b/arch/arm/mach-fh/fh8626v100/iopad.h new file mode 100644 index 0000000000..8695371d1a --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/iopad.h @@ -0,0 +1,575 @@ +#ifndef __FH8626V100_IOPAD_H +#define __FH8626V100_IOPAD_H + +#include +#include + +/* + * Generated from the exact stock Linux 4.9.129 image by + * workspace/tools/fh_extract_stock_pinctrl.py and + * workspace/tools/fh_generate_pinctrl_header.py. + */ + +/* Pin functions. */ +PINCTRL_FUNC(CIS_HSYNC, 0, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(GPIO19, 0, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(UART1_TX, 0, FUNC2, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_VSYNC, 1, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO20, 1, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(UART1_RX, 1, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(CIS_PCLK, 2, FUNC0, PUPD_UP, 4); +PINCTRL_FUNC(GPIO21, 2, FUNC1, PUPD_UP, 4); +PINCTRL_FUNC(PWM4, 2, FUNC2, PUPD_UP, 4); +PINCTRL_FUNC(CIS_D_0, 3, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(GPIO25, 3, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(I2C2_SDA, 3, FUNC2, PUPD_DOWN, 0); +PINCTRL_FUNC(SSI1_TXD, 3, FUNC3, PUPD_DOWN, 0); +PINCTRL_FUNC(PWM0, 3, FUNC4, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_1, 4, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(GPIO26, 4, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(I2C2_SCL, 4, FUNC2, PUPD_DOWN, 0); +PINCTRL_FUNC(SSI1_RXD, 4, FUNC3, PUPD_DOWN, 0); +PINCTRL_FUNC(PWM1, 4, FUNC4, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_2, 5, FUNC0, PUPD_DOWN, 4); +PINCTRL_FUNC(GPIO27, 5, FUNC1, PUPD_DOWN, 4); +PINCTRL_FUNC(UART2_TX, 5, FUNC2, PUPD_DOWN, 4); +PINCTRL_FUNC(SSI1_CLK, 5, FUNC3, PUPD_DOWN, 4); +PINCTRL_FUNC(PWM2, 5, FUNC4, PUPD_DOWN, 4); +PINCTRL_FUNC(CIS_D_3, 6, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(GPIO28, 6, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(UART2_RX, 6, FUNC2, PUPD_DOWN, 0); +PINCTRL_FUNC(SSI1_CSN_0, 6, FUNC3, PUPD_DOWN, 0); +PINCTRL_FUNC(PWM3, 6, FUNC4, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_4, 7, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(GPIO4, 7, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(I2C1_SDA, 7, FUNC2, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_5, 8, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(GPIO5, 8, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(I2C1_SCL, 8, FUNC2, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_6, 9, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(DN1_MIPI, 9, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_7, 10, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(DP1_MIPI, 10, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_8, 11, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(DN0_MIPI, 11, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_9, 12, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(DP0_MIPI, 12, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_10, 13, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(CKN_MIPI, 13, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(CIS_D_11, 14, FUNC0, PUPD_DOWN, 0); +PINCTRL_FUNC(CKP_MIPI, 14, FUNC1, PUPD_DOWN, 0); +PINCTRL_FUNC(MAC_RMII_CLK, 15, FUNC0, PUPD_UP, 4); +PINCTRL_FUNC(GPIO15, 15, FUNC1, PUPD_UP, 4); +PINCTRL_FUNC(SD1_CLK, 15, FUNC2, PUPD_UP, 4); +PINCTRL_FUNC(PWM0, 15, FUNC3, PUPD_UP, 4); +PINCTRL_FUNC(MAC_REF_CLK, 16, FUNC0, PUPD_NONE, 4); +PINCTRL_FUNC(MAC_MDC, 17, FUNC0, PUPD_UP, 4); +PINCTRL_FUNC(GPIO34, 17, FUNC1, PUPD_UP, 4); +PINCTRL_FUNC(SD1_WP, 17, FUNC2, PUPD_UP, 4); +PINCTRL_FUNC(AC_MCLK, 17, FUNC3, PUPD_UP, 4); +PINCTRL_FUNC(MAC_MDIO, 18, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO17, 18, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(PWM7, 18, FUNC2, PUPD_NONE, 0); +PINCTRL_FUNC(MAC_RXD_0, 22, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO16, 22, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(SD1_DATA_0, 22, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(PWM1, 22, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(MAC_RXD_1, 23, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO38, 23, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(SD1_DATA_1, 23, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(PWM2, 23, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(MAC_RXDV, 26, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO41, 26, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(SD1_CD, 26, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(PWM3, 26, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(MAC_TXD_0, 28, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO42, 28, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(SD1_DATA_2, 28, FUNC2, PUPD_NONE, 0); +PINCTRL_FUNC(PWM4, 28, FUNC3, PUPD_NONE, 0); +PINCTRL_FUNC(MAC_TXD_1, 29, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO43, 29, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(SD1_DATA_3, 29, FUNC2, PUPD_NONE, 0); +PINCTRL_FUNC(PWM5, 29, FUNC3, PUPD_NONE, 0); +PINCTRL_FUNC(MAC_TXEN, 32, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO46, 32, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(SD1_CMD_RSP, 32, FUNC2, PUPD_NONE, 0); +PINCTRL_FUNC(PWM6, 32, FUNC3, PUPD_NONE, 0); +PINCTRL_FUNC(ARM_JTAG_TRSTN, 35, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO0, 35, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(AC_I2S_DO, 35, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(DW_I2S_DO, 35, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(SSI1_TXD, 35, FUNC5, PUPD_UP, 0); +PINCTRL_FUNC(PWM3, 35, FUNC6, PUPD_UP, 0); +PINCTRL_FUNC(ARM_JTAG_TMS, 36, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO1, 36, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(AC_I2S_DI, 36, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(DW_I2S_DI, 36, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(SSI1_RXD, 36, FUNC5, PUPD_UP, 0); +PINCTRL_FUNC(PWM4, 36, FUNC6, PUPD_UP, 0); +PINCTRL_FUNC(ARM_JTAG_TCK, 37, FUNC0, PUPD_DOWN, 4); +PINCTRL_FUNC(GPIO2, 37, FUNC1, PUPD_DOWN, 4); +PINCTRL_FUNC(AC_I2S_CLK, 37, FUNC2, PUPD_DOWN, 4); +PINCTRL_FUNC(DW_I2S_CLK, 37, FUNC3, PUPD_DOWN, 4); +PINCTRL_FUNC(SSI1_CLK, 37, FUNC5, PUPD_DOWN, 4); +PINCTRL_FUNC(PWM5, 37, FUNC6, PUPD_DOWN, 4); +PINCTRL_FUNC(ARM_JTAG_TDI, 38, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO3, 38, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(AC_I2S_WS, 38, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(DW_I2S_WS, 38, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(SSI1_CSN_0, 38, FUNC5, PUPD_UP, 0); +PINCTRL_FUNC(PWM6, 38, FUNC6, PUPD_UP, 0); +PINCTRL_FUNC(SSI0_D_2, 39, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO50, 39, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(I2C2_SDA, 39, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(UART2_TX, 39, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(PWM10, 39, FUNC4, PUPD_UP, 0); +PINCTRL_FUNC(SSI0_D_3, 40, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO51, 40, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(I2C2_SCL, 40, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(UART2_RX, 40, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(PWM11, 40, FUNC4, PUPD_UP, 0); +PINCTRL_FUNC(PWM9, 41, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO6, 41, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(USB_PWREN, 41, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(RTC_CLK, 41, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(ARM_JTAG_TDO, 42, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO7, 42, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(I2C2_SDA, 42, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(UART2_TX, 42, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(AC_MCLK, 42, FUNC4, PUPD_UP, 0); +PINCTRL_FUNC(USB_DEBUG_CLK, 42, FUNC5, PUPD_UP, 0); +PINCTRL_FUNC(PWM7, 42, FUNC6, PUPD_UP, 0); +PINCTRL_FUNC(PWM8, 46, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO11, 46, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(I2C2_SCL, 46, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(UART2_RX, 46, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(GPIO12, 47, FUNC0, PUPD_UP, 4); +PINCTRL_FUNC(CIS_CLK, 47, FUNC1, PUPD_UP, 4); +PINCTRL_FUNC(GPIO13, 48, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO14, 49, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(UART0_RX, 50, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO48, 50, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(UART0_TX, 51, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO49, 51, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(I2C0_SCL, 52, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO57, 52, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(I2C0_SDA, 53, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO56, 53, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(SSI0_CLK, 56, FUNC0, PUPD_NONE, 4); +PINCTRL_FUNC(GPIO53, 56, FUNC1, PUPD_NONE, 4); +PINCTRL_FUNC(SSI0_TXD, 57, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO56, 57, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO54, 58, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(SSI0_RXD, 60, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO57, 60, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(SD0_CD, 61, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO52, 61, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(ARC_JTAG_TRSTN, 61, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(SD0_CLK, 63, FUNC0, PUPD_NONE, 4); +PINCTRL_FUNC(GPIO63, 63, FUNC1, PUPD_NONE, 4); +PINCTRL_FUNC(ARC_JTAG_TMS, 63, FUNC2, PUPD_NONE, 4); +PINCTRL_FUNC(SSI1_CLK, 63, FUNC3, PUPD_NONE, 4); +PINCTRL_FUNC(SD0_CMD_RSP, 64, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO29, 64, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(ARC_JTAG_TCK, 64, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(SSI1_TXD, 64, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(SD0_DATA_0, 65, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO62, 65, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(ARC_JTAG_TDI, 65, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(SSI1_RXD, 65, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(SD0_DATA_1, 66, FUNC0, PUPD_UP, 4); +PINCTRL_FUNC(GPIO61, 66, FUNC1, PUPD_UP, 4); +PINCTRL_FUNC(PWM0, 66, FUNC2, PUPD_UP, 4); +PINCTRL_FUNC(AC_MCLK, 66, FUNC3, PUPD_UP, 4); +PINCTRL_FUNC(SSI1_CSN_0, 66, FUNC4, PUPD_UP, 4); +PINCTRL_FUNC(SD0_DATA_2, 67, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO60, 67, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(I2C1_SDA, 67, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(UART1_TX, 67, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(ARC_JTAG_TDO, 67, FUNC4, PUPD_UP, 0); +PINCTRL_FUNC(PWM1, 67, FUNC6, PUPD_UP, 0); +PINCTRL_FUNC(SD0_DATA_3, 68, FUNC0, PUPD_UP, 0); +PINCTRL_FUNC(GPIO18, 68, FUNC1, PUPD_UP, 0); +PINCTRL_FUNC(I2C1_SCL, 68, FUNC2, PUPD_UP, 0); +PINCTRL_FUNC(UART1_RX, 68, FUNC3, PUPD_UP, 0); +PINCTRL_FUNC(SSI1_CSN_0, 68, FUNC4, PUPD_UP, 0); +PINCTRL_FUNC(PWM2, 68, FUNC5, PUPD_UP, 0); +PINCTRL_FUNC(SADC_CHANL0, 69, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO22, 69, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(SADC_CHANL1, 70, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO23, 70, FUNC1, PUPD_NONE, 0); +PINCTRL_FUNC(SADC_CHANL2, 71, FUNC0, PUPD_NONE, 0); +PINCTRL_FUNC(GPIO24, 71, FUNC1, PUPD_NONE, 0); + +/* Muxes. */ +PINCTRL_MUX(STOCK_AC_MCLK_49aa40, 2, &PAD17_AC_MCLK, &PAD42_AC_MCLK, &PAD66_AC_MCLK); +PINCTRL_MUX(STOCK_AC_I2S_CLK_49aa20, 0, &PAD37_AC_I2S_CLK); +PINCTRL_MUX(STOCK_AC_I2S_DI_49aa28, 0, &PAD36_AC_I2S_DI); +PINCTRL_MUX(STOCK_AC_I2S_DO_49aa30, 0, &PAD35_AC_I2S_DO); +PINCTRL_MUX(STOCK_AC_I2S_WS_49aa38, 0, &PAD38_AC_I2S_WS); +PINCTRL_MUX(STOCK_ARC_JTAG_TCK_49aa50, 0, &PAD64_ARC_JTAG_TCK); +PINCTRL_MUX(STOCK_ARC_JTAG_TDI_49aa58, 0, &PAD65_ARC_JTAG_TDI); +PINCTRL_MUX(STOCK_ARC_JTAG_TDO_49aa60, 0, &PAD67_ARC_JTAG_TDO); +PINCTRL_MUX(STOCK_ARC_JTAG_TMS_49aa68, 0, &PAD63_ARC_JTAG_TMS); +PINCTRL_MUX(STOCK_ARC_JTAG_TRSTN_49aa70, 0, &PAD61_ARC_JTAG_TRSTN); +PINCTRL_MUX(STOCK_ARM_JTAG_TCK_49aa78, 0, &PAD37_ARM_JTAG_TCK); +PINCTRL_MUX(STOCK_ARM_JTAG_TDI_49aa80, 0, &PAD38_ARM_JTAG_TDI); +PINCTRL_MUX(STOCK_ARM_JTAG_TDO_49aa88, 0, &PAD42_ARM_JTAG_TDO); +PINCTRL_MUX(STOCK_ARM_JTAG_TMS_49aa90, 0, &PAD36_ARM_JTAG_TMS); +PINCTRL_MUX(STOCK_ARM_JTAG_TRSTN_49aa98, 0, &PAD35_ARM_JTAG_TRSTN); +PINCTRL_MUX(STOCK_CIS_CLK_49aaa0, 0, &PAD47_CIS_CLK); +PINCTRL_MUX(STOCK_CIS_D_0_49aaa8, 0, &PAD3_CIS_D_0); +PINCTRL_MUX(STOCK_CIS_D_1_49aab0, 0, &PAD4_CIS_D_1); +PINCTRL_MUX(STOCK_CIS_D_10_49aab8, 0, &PAD13_CIS_D_10); +PINCTRL_MUX(STOCK_CIS_D_11_49aac0, 0, &PAD14_CIS_D_11); +PINCTRL_MUX(STOCK_CIS_D_2_49aac8, 0, &PAD5_CIS_D_2); +PINCTRL_MUX(STOCK_CIS_D_3_49aad0, 0, &PAD6_CIS_D_3); +PINCTRL_MUX(STOCK_CIS_D_4_49aad8, 0, &PAD7_CIS_D_4); +PINCTRL_MUX(STOCK_CIS_D_5_49aae0, 0, &PAD8_CIS_D_5); +PINCTRL_MUX(STOCK_CIS_D_6_49aae8, 0, &PAD9_CIS_D_6); +PINCTRL_MUX(STOCK_CIS_D_7_49aaf0, 0, &PAD10_CIS_D_7); +PINCTRL_MUX(STOCK_CIS_D_8_49aaf8, 0, &PAD11_CIS_D_8); +PINCTRL_MUX(STOCK_CIS_D_9_49ab00, 0, &PAD12_CIS_D_9); +PINCTRL_MUX(STOCK_CIS_HSYNC_49ab08, 0, &PAD0_CIS_HSYNC); +PINCTRL_MUX(STOCK_CIS_PCLK_49ab10, 0, &PAD2_CIS_PCLK); +PINCTRL_MUX(STOCK_CIS_VSYNC_49ab18, 0, &PAD1_CIS_VSYNC); +PINCTRL_MUX(STOCK_DW_I2S_CLK_49ab50, 0, &PAD37_DW_I2S_CLK); +PINCTRL_MUX(STOCK_DW_I2S_DI_49ab58, 0, &PAD36_DW_I2S_DI); +PINCTRL_MUX(STOCK_DW_I2S_DO_49ab60, 0, &PAD35_DW_I2S_DO); +PINCTRL_MUX(STOCK_DW_I2S_WS_49ab68, 0, &PAD38_DW_I2S_WS); +PINCTRL_MUX(STOCK_I2C0_SCL_49ace8, 0, &PAD52_I2C0_SCL); +PINCTRL_MUX(STOCK_I2C0_SDA_49acf0, 0, &PAD53_I2C0_SDA); +PINCTRL_MUX(STOCK_I2C1_SCL_49acf8, 1, &PAD8_I2C1_SCL, &PAD68_I2C1_SCL); +PINCTRL_MUX(STOCK_I2C1_SDA_49ad04, 1, &PAD7_I2C1_SDA, &PAD67_I2C1_SDA); +PINCTRL_MUX(STOCK_I2C2_SCL_49ad10, 0, &PAD4_I2C2_SCL, &PAD40_I2C2_SCL, &PAD46_I2C2_SCL); +PINCTRL_MUX(STOCK_I2C2_SDA_49ad20, 0, &PAD3_I2C2_SDA, &PAD39_I2C2_SDA, &PAD42_I2C2_SDA); +PINCTRL_MUX(STOCK_CKN_MIPI_49ab20, 0, &PAD13_CKN_MIPI); +PINCTRL_MUX(STOCK_CKP_MIPI_49ab28, 0, &PAD14_CKP_MIPI); +PINCTRL_MUX(STOCK_DN0_MIPI_49ab30, 0, &PAD11_DN0_MIPI); +PINCTRL_MUX(STOCK_DN1_MIPI_49ab38, 0, &PAD9_DN1_MIPI); +PINCTRL_MUX(STOCK_DP0_MIPI_49ab40, 0, &PAD12_DP0_MIPI); +PINCTRL_MUX(STOCK_DP1_MIPI_49ab48, 0, &PAD10_DP1_MIPI); +PINCTRL_MUX(STOCK_PWM0_49ad80, 0, &PAD3_PWM0, &PAD15_PWM0, &PAD66_PWM0); +PINCTRL_MUX(STOCK_PWM1_49ad90, 0, &PAD4_PWM1, &PAD22_PWM1, &PAD67_PWM1); +PINCTRL_MUX(STOCK_PWM10_49ada0, 0, &PAD39_PWM10); +PINCTRL_MUX(STOCK_PWM11_49ada8, 0, &PAD40_PWM11); +PINCTRL_MUX(STOCK_PWM2_49adb0, 0, &PAD5_PWM2, &PAD23_PWM2, &PAD68_PWM2); +PINCTRL_MUX(STOCK_PWM3_49adc0, 0, &PAD6_PWM3, &PAD26_PWM3, &PAD35_PWM3); +PINCTRL_MUX(STOCK_PWM4_49add0, 0, &PAD2_PWM4, &PAD28_PWM4, &PAD36_PWM4); +PINCTRL_MUX(STOCK_PWM5_49ade0, 0, &PAD29_PWM5, &PAD37_PWM5); +PINCTRL_MUX(STOCK_PWM6_49adec, 0, &PAD32_PWM6, &PAD38_PWM6); +PINCTRL_MUX(STOCK_PWM7_49adf8, 1, &PAD18_PWM7, &PAD42_PWM7); +PINCTRL_MUX(STOCK_PWM8_49ae04, 0, &PAD46_PWM8); +PINCTRL_MUX(STOCK_PWM9_49ae0c, 0, &PAD41_PWM9); +PINCTRL_MUX(STOCK_MAC_MDC_49ad30, 0, &PAD17_MAC_MDC); +PINCTRL_MUX(STOCK_MAC_MDIO_49ad38, 0, &PAD18_MAC_MDIO); +PINCTRL_MUX(STOCK_MAC_REF_CLK_49ad40, 0, &PAD16_MAC_REF_CLK); +PINCTRL_MUX(STOCK_MAC_RMII_CLK_49ad48, 0, &PAD15_MAC_RMII_CLK); +PINCTRL_MUX(STOCK_MAC_RXDV_49ad50, 0, &PAD26_MAC_RXDV); +PINCTRL_MUX(STOCK_MAC_RXD_0_49ad58, 0, &PAD22_MAC_RXD_0); +PINCTRL_MUX(STOCK_MAC_RXD_1_49ad60, 0, &PAD23_MAC_RXD_1); +PINCTRL_MUX(STOCK_MAC_TXD_0_49ad68, 0, &PAD28_MAC_TXD_0); +PINCTRL_MUX(STOCK_MAC_TXD_1_49ad70, 0, &PAD29_MAC_TXD_1); +PINCTRL_MUX(STOCK_MAC_TXEN_49ad78, 0, &PAD32_MAC_TXEN); +PINCTRL_MUX(STOCK_RTC_CLK_49ae14, 0, &PAD41_RTC_CLK); +PINCTRL_MUX(STOCK_SADC_CHANL0_49ae1c, 0, &PAD69_SADC_CHANL0); +PINCTRL_MUX(STOCK_SADC_CHANL1_49ae24, 0, &PAD70_SADC_CHANL1); +PINCTRL_MUX(STOCK_SADC_CHANL2_49ae2c, 0, &PAD71_SADC_CHANL2); +PINCTRL_MUX(STOCK_SD0_CD_49ae34, 0, &PAD61_SD0_CD); +PINCTRL_MUX(STOCK_SD0_CLK_49ae3c, 0, &PAD63_SD0_CLK); +PINCTRL_MUX(STOCK_SD0_CMD_RSP_49ae44, 0, &PAD64_SD0_CMD_RSP); +PINCTRL_MUX(STOCK_SD0_DATA_0_49ae4c, 0, &PAD65_SD0_DATA_0); +PINCTRL_MUX(STOCK_SD0_DATA_1_49ae54, 0, &PAD66_SD0_DATA_1); +PINCTRL_MUX(STOCK_SD0_DATA_2_49ae5c, 0, &PAD67_SD0_DATA_2); +PINCTRL_MUX(STOCK_SD0_DATA_3_49ae64, 0, &PAD68_SD0_DATA_3); +PINCTRL_MUX(STOCK_SD1_CD_49ae6c, 0, &PAD26_SD1_CD); +PINCTRL_MUX(STOCK_SD1_CLK_49ae7c, 0, &PAD15_SD1_CLK); +PINCTRL_MUX(STOCK_SD1_CMD_RSP_49ae8c, 0, &PAD32_SD1_CMD_RSP); +PINCTRL_MUX(STOCK_SD1_DATA_0_49ae9c, 0, &PAD22_SD1_DATA_0); +PINCTRL_MUX(STOCK_SD1_DATA_1_49aeac, 0, &PAD23_SD1_DATA_1); +PINCTRL_MUX(STOCK_SD1_DATA_2_49aebc, 0, &PAD28_SD1_DATA_2); +PINCTRL_MUX(STOCK_SD1_DATA_3_49aecc, 0, &PAD29_SD1_DATA_3); +PINCTRL_MUX(STOCK_SD1_WP_49aedc, 0, &PAD17_SD1_WP); +PINCTRL_MUX(STOCK_GPIO54_49ac98, 0, &PAD58_GPIO54); +PINCTRL_MUX(STOCK_SSI0_CLK_49aee4, 0, &PAD56_SSI0_CLK); +PINCTRL_MUX(STOCK_SSI0_RXD_49aefc, 0, &PAD60_SSI0_RXD); +PINCTRL_MUX(STOCK_SSI0_TXD_49af04, 0, &PAD57_SSI0_TXD); +PINCTRL_MUX(STOCK_SSI0_D_2_49aeec, 0, &PAD39_SSI0_D_2); +PINCTRL_MUX(STOCK_SSI0_D_3_49aef4, 0, &PAD40_SSI0_D_3); +PINCTRL_MUX(STOCK_SSI1_CLK_49af0c, 0, &PAD5_SSI1_CLK, &PAD37_SSI1_CLK, &PAD63_SSI1_CLK); +PINCTRL_MUX(STOCK_SSI1_CSN_0_49af1c, 0, &PAD6_SSI1_CSN_0, &PAD38_SSI1_CSN_0, &PAD66_SSI1_CSN_0, &PAD68_SSI1_CSN_0); +PINCTRL_MUX(STOCK_SSI1_RXD_49af30, 0, &PAD4_SSI1_RXD, &PAD36_SSI1_RXD, &PAD65_SSI1_RXD); +PINCTRL_MUX(STOCK_SSI1_TXD_49af40, 0, &PAD3_SSI1_TXD, &PAD35_SSI1_TXD, &PAD64_SSI1_TXD); +PINCTRL_MUX(STOCK_UART0_RX_49af50, 0, &PAD50_UART0_RX); +PINCTRL_MUX(STOCK_UART0_TX_49af58, 0, &PAD51_UART0_TX); +PINCTRL_MUX(STOCK_UART1_RX_49af60, 0, &PAD1_UART1_RX, &PAD68_UART1_RX); +PINCTRL_MUX(STOCK_UART1_TX_49af6c, 0, &PAD0_UART1_TX, &PAD67_UART1_TX); +PINCTRL_MUX(STOCK_UART2_RX_49af78, 0, &PAD6_UART2_RX, &PAD40_UART2_RX, &PAD46_UART2_RX); +PINCTRL_MUX(STOCK_UART2_TX_49af88, 0, &PAD5_UART2_TX, &PAD39_UART2_TX, &PAD42_UART2_TX); +PINCTRL_MUX(STOCK_USB_DEBUG_CLK_49af98, 0, &PAD42_USB_DEBUG_CLK); +PINCTRL_MUX(STOCK_USB_PWREN_49afa0, 0, &PAD41_USB_PWREN); +PINCTRL_MUX(STOCK_GPIO0_49ab70, 0, &PAD35_GPIO0); +PINCTRL_MUX(STOCK_GPIO1_49ab78, 0, &PAD36_GPIO1); +PINCTRL_MUX(STOCK_GPIO2_49abc8, 0, &PAD37_GPIO2); +PINCTRL_MUX(STOCK_GPIO3_49ac20, 0, &PAD38_GPIO3); +PINCTRL_MUX(STOCK_GPIO4_49ac38, 0, &PAD7_GPIO4); +PINCTRL_MUX(STOCK_GPIO5_49ac70, 0, &PAD8_GPIO5); +PINCTRL_MUX(STOCK_GPIO6_49acb8, 0, &PAD41_GPIO6); +PINCTRL_MUX(STOCK_GPIO7_49ace0, 0, &PAD42_GPIO7); +PINCTRL_MUX(STOCK_GPIO11_49ab80, 0, &PAD46_GPIO11); +PINCTRL_MUX(STOCK_GPIO12_49ab88, 0, &PAD47_GPIO12); +PINCTRL_MUX(STOCK_GPIO13_49ab90, 0, &PAD48_GPIO13); +PINCTRL_MUX(STOCK_GPIO14_49ab98, 0, &PAD49_GPIO14); +PINCTRL_MUX(STOCK_GPIO15_49aba0, 0, &PAD15_GPIO15); +PINCTRL_MUX(STOCK_GPIO16_49aba8, 0, &PAD22_GPIO16); +PINCTRL_MUX(STOCK_GPIO17_49abb0, 0, &PAD18_GPIO17); +PINCTRL_MUX(STOCK_GPIO18_49abb8, 0, &PAD68_GPIO18); +PINCTRL_MUX(STOCK_GPIO19_49abc0, 0, &PAD0_GPIO19); +PINCTRL_MUX(STOCK_GPIO20_49abd0, 0, &PAD1_GPIO20); +PINCTRL_MUX(STOCK_GPIO21_49abd8, 0, &PAD2_GPIO21); +PINCTRL_MUX(STOCK_GPIO22_49abe0, 0, &PAD69_GPIO22); +PINCTRL_MUX(STOCK_GPIO23_49abe8, 0, &PAD70_GPIO23); +PINCTRL_MUX(STOCK_GPIO24_49abf0, 0, &PAD71_GPIO24); +PINCTRL_MUX(STOCK_GPIO25_49abf8, 0, &PAD3_GPIO25); +PINCTRL_MUX(STOCK_GPIO26_49ac00, 0, &PAD4_GPIO26); +PINCTRL_MUX(STOCK_GPIO27_49ac08, 0, &PAD5_GPIO27); +PINCTRL_MUX(STOCK_GPIO28_49ac10, 0, &PAD6_GPIO28); +PINCTRL_MUX(STOCK_GPIO29_49ac18, 0, &PAD64_GPIO29); +PINCTRL_MUX(STOCK_GPIO34_49ac28, 0, &PAD17_GPIO34); +PINCTRL_MUX(STOCK_GPIO38_49ac30, 0, &PAD23_GPIO38); +PINCTRL_MUX(STOCK_GPIO41_49ac40, 0, &PAD26_GPIO41); +PINCTRL_MUX(STOCK_GPIO42_49ac48, 0, &PAD28_GPIO42); +PINCTRL_MUX(STOCK_GPIO43_49ac50, 0, &PAD29_GPIO43); +PINCTRL_MUX(STOCK_GPIO46_49ac58, 0, &PAD32_GPIO46); +PINCTRL_MUX(STOCK_GPIO48_49ac60, 0, &PAD50_GPIO48); +PINCTRL_MUX(STOCK_GPIO49_49ac68, 0, &PAD51_GPIO49); +PINCTRL_MUX(STOCK_GPIO50_49ac78, 0, &PAD39_GPIO50); +PINCTRL_MUX(STOCK_GPIO51_49ac80, 0, &PAD40_GPIO51); +PINCTRL_MUX(STOCK_GPIO52_49ac88, 0, &PAD61_GPIO52); +PINCTRL_MUX(STOCK_GPIO53_49ac90, 0, &PAD56_GPIO53); +PINCTRL_MUX(STOCK_GPIO56_49aca0, 0, &PAD53_GPIO56, &PAD57_GPIO56); +PINCTRL_MUX(STOCK_GPIO57_49acac, 0, &PAD52_GPIO57, &PAD60_GPIO57); +PINCTRL_MUX(STOCK_GPIO60_49acc0, 0, &PAD67_GPIO60); +PINCTRL_MUX(STOCK_GPIO61_49acc8, 0, &PAD66_GPIO61); +PINCTRL_MUX(STOCK_GPIO62_49acd0, 0, &PAD65_GPIO62); +PINCTRL_MUX(STOCK_GPIO63_49acd8, 0, &PAD63_GPIO63); +PINCTRL_MUX(STOCK_SD1_CLK_49ae84, 0, &PAD15_SD1_CLK); +PINCTRL_MUX(STOCK_SD1_CD_49ae74, 0, &PAD26_SD1_CD); +PINCTRL_MUX(STOCK_SD1_CMD_RSP_49ae94, 0, &PAD32_SD1_CMD_RSP); +PINCTRL_MUX(STOCK_SD1_DATA_0_49aea4, 0, &PAD22_SD1_DATA_0); +PINCTRL_MUX(STOCK_SD1_DATA_1_49aeb4, 0, &PAD23_SD1_DATA_1); +PINCTRL_MUX(STOCK_SD1_DATA_2_49aec4, 0, &PAD28_SD1_DATA_2); +PINCTRL_MUX(STOCK_SD1_DATA_3_49aed4, 0, &PAD29_SD1_DATA_3); + +/* Devices. */ +PINCTRL_DEVICE(AC_MCLK, 1, &MUX_STOCK_AC_MCLK_49aa40); +PINCTRL_DEVICE(ACI2S, 5, &MUX_STOCK_AC_I2S_CLK_49aa20, &MUX_STOCK_AC_I2S_DI_49aa28, &MUX_STOCK_AC_I2S_DO_49aa30, &MUX_STOCK_AC_I2S_WS_49aa38, &MUX_STOCK_AC_MCLK_49aa40); +PINCTRL_DEVICE(ARCJTAG, 5, &MUX_STOCK_ARC_JTAG_TCK_49aa50, &MUX_STOCK_ARC_JTAG_TDI_49aa58, &MUX_STOCK_ARC_JTAG_TDO_49aa60, &MUX_STOCK_ARC_JTAG_TMS_49aa68, &MUX_STOCK_ARC_JTAG_TRSTN_49aa70); +PINCTRL_DEVICE(ARMJTAG, 5, &MUX_STOCK_ARM_JTAG_TCK_49aa78, &MUX_STOCK_ARM_JTAG_TDI_49aa80, &MUX_STOCK_ARM_JTAG_TDO_49aa88, &MUX_STOCK_ARM_JTAG_TMS_49aa90, &MUX_STOCK_ARM_JTAG_TRSTN_49aa98); +PINCTRL_DEVICE(DVP, 16, &MUX_STOCK_CIS_CLK_49aaa0, &MUX_STOCK_CIS_D_0_49aaa8, &MUX_STOCK_CIS_D_1_49aab0, &MUX_STOCK_CIS_D_10_49aab8, &MUX_STOCK_CIS_D_11_49aac0, &MUX_STOCK_CIS_D_2_49aac8, &MUX_STOCK_CIS_D_3_49aad0, &MUX_STOCK_CIS_D_4_49aad8, &MUX_STOCK_CIS_D_5_49aae0, &MUX_STOCK_CIS_D_6_49aae8, &MUX_STOCK_CIS_D_7_49aaf0, &MUX_STOCK_CIS_D_8_49aaf8, &MUX_STOCK_CIS_D_9_49ab00, &MUX_STOCK_CIS_HSYNC_49ab08, &MUX_STOCK_CIS_PCLK_49ab10, &MUX_STOCK_CIS_VSYNC_49ab18); +PINCTRL_DEVICE(DWI2S, 4, &MUX_STOCK_DW_I2S_CLK_49ab50, &MUX_STOCK_DW_I2S_DI_49ab58, &MUX_STOCK_DW_I2S_DO_49ab60, &MUX_STOCK_DW_I2S_WS_49ab68); +PINCTRL_DEVICE(I2C0, 2, &MUX_STOCK_I2C0_SCL_49ace8, &MUX_STOCK_I2C0_SDA_49acf0); +PINCTRL_DEVICE(I2C1, 2, &MUX_STOCK_I2C1_SCL_49acf8, &MUX_STOCK_I2C1_SDA_49ad04); +PINCTRL_DEVICE(I2C2, 2, &MUX_STOCK_I2C2_SCL_49ad10, &MUX_STOCK_I2C2_SDA_49ad20); +PINCTRL_DEVICE(MIPI, 7, &MUX_STOCK_CIS_CLK_49aaa0, &MUX_STOCK_CKN_MIPI_49ab20, &MUX_STOCK_CKP_MIPI_49ab28, &MUX_STOCK_DN0_MIPI_49ab30, &MUX_STOCK_DN1_MIPI_49ab38, &MUX_STOCK_DP0_MIPI_49ab40, &MUX_STOCK_DP1_MIPI_49ab48); +PINCTRL_DEVICE(PWM0, 1, &MUX_STOCK_PWM0_49ad80); +PINCTRL_DEVICE(PWM1, 1, &MUX_STOCK_PWM1_49ad90); +PINCTRL_DEVICE(PWM10, 1, &MUX_STOCK_PWM10_49ada0); +PINCTRL_DEVICE(PWM11, 1, &MUX_STOCK_PWM11_49ada8); +PINCTRL_DEVICE(PWM2, 1, &MUX_STOCK_PWM2_49adb0); +PINCTRL_DEVICE(PWM3, 1, &MUX_STOCK_PWM3_49adc0); +PINCTRL_DEVICE(PWM4, 1, &MUX_STOCK_PWM4_49add0); +PINCTRL_DEVICE(PWM5, 1, &MUX_STOCK_PWM5_49ade0); +PINCTRL_DEVICE(PWM6, 1, &MUX_STOCK_PWM6_49adec); +PINCTRL_DEVICE(PWM7, 1, &MUX_STOCK_PWM7_49adf8); +PINCTRL_DEVICE(PWM8, 1, &MUX_STOCK_PWM8_49ae04); +PINCTRL_DEVICE(PWM9, 1, &MUX_STOCK_PWM9_49ae0c); +PINCTRL_DEVICE(RMII, 10, &MUX_STOCK_MAC_MDC_49ad30, &MUX_STOCK_MAC_MDIO_49ad38, &MUX_STOCK_MAC_REF_CLK_49ad40, &MUX_STOCK_MAC_RMII_CLK_49ad48, &MUX_STOCK_MAC_RXDV_49ad50, &MUX_STOCK_MAC_RXD_0_49ad58, &MUX_STOCK_MAC_RXD_1_49ad60, &MUX_STOCK_MAC_TXD_0_49ad68, &MUX_STOCK_MAC_TXD_1_49ad70, &MUX_STOCK_MAC_TXEN_49ad78); +PINCTRL_DEVICE(RTC, 1, &MUX_STOCK_RTC_CLK_49ae14); +PINCTRL_DEVICE(SADC_CHANL0, 1, &MUX_STOCK_SADC_CHANL0_49ae1c); +PINCTRL_DEVICE(SADC_CHANL1, 1, &MUX_STOCK_SADC_CHANL1_49ae24); +PINCTRL_DEVICE(SADC_CHANL2, 1, &MUX_STOCK_SADC_CHANL2_49ae2c); +PINCTRL_DEVICE(SD0, 7, &MUX_STOCK_SD0_CD_49ae34, &MUX_STOCK_SD0_CLK_49ae3c, &MUX_STOCK_SD0_CMD_RSP_49ae44, &MUX_STOCK_SD0_DATA_0_49ae4c, &MUX_STOCK_SD0_DATA_1_49ae54, &MUX_STOCK_SD0_DATA_2_49ae5c, &MUX_STOCK_SD0_DATA_3_49ae64); +PINCTRL_DEVICE(SD0_1BIT_NO_WP, 4, &MUX_STOCK_SD0_CD_49ae34, &MUX_STOCK_SD0_CLK_49ae3c, &MUX_STOCK_SD0_CMD_RSP_49ae44, &MUX_STOCK_SD0_DATA_0_49ae4c); +PINCTRL_DEVICE(SD0_NO_WP, 7, &MUX_STOCK_SD0_CD_49ae34, &MUX_STOCK_SD0_CLK_49ae3c, &MUX_STOCK_SD0_CMD_RSP_49ae44, &MUX_STOCK_SD0_DATA_0_49ae4c, &MUX_STOCK_SD0_DATA_1_49ae54, &MUX_STOCK_SD0_DATA_2_49ae5c, &MUX_STOCK_SD0_DATA_3_49ae64); +PINCTRL_DEVICE(SD1, 8, &MUX_STOCK_SD1_CD_49ae6c, &MUX_STOCK_SD1_CLK_49ae7c, &MUX_STOCK_SD1_CMD_RSP_49ae8c, &MUX_STOCK_SD1_DATA_0_49ae9c, &MUX_STOCK_SD1_DATA_1_49aeac, &MUX_STOCK_SD1_DATA_2_49aebc, &MUX_STOCK_SD1_DATA_3_49aecc, &MUX_STOCK_SD1_WP_49aedc); +PINCTRL_DEVICE(SD1_1BIT_NO_WP, 4, &MUX_STOCK_SD1_CD_49ae6c, &MUX_STOCK_SD1_CLK_49ae7c, &MUX_STOCK_SD1_CMD_RSP_49ae8c, &MUX_STOCK_SD1_DATA_0_49ae9c); +PINCTRL_DEVICE(SD1_NO_WP, 7, &MUX_STOCK_SD1_CD_49ae6c, &MUX_STOCK_SD1_CLK_49ae7c, &MUX_STOCK_SD1_CMD_RSP_49ae8c, &MUX_STOCK_SD1_DATA_0_49ae9c, &MUX_STOCK_SD1_DATA_1_49aeac, &MUX_STOCK_SD1_DATA_2_49aebc, &MUX_STOCK_SD1_DATA_3_49aecc); +PINCTRL_DEVICE(SSI0, 4, &MUX_STOCK_GPIO54_49ac98, &MUX_STOCK_SSI0_CLK_49aee4, &MUX_STOCK_SSI0_RXD_49aefc, &MUX_STOCK_SSI0_TXD_49af04); +PINCTRL_DEVICE(SSI0_4BIT, 6, &MUX_STOCK_GPIO54_49ac98, &MUX_STOCK_SSI0_CLK_49aee4, &MUX_STOCK_SSI0_D_2_49aeec, &MUX_STOCK_SSI0_D_3_49aef4, &MUX_STOCK_SSI0_RXD_49aefc, &MUX_STOCK_SSI0_TXD_49af04); +PINCTRL_DEVICE(SSI1, 4, &MUX_STOCK_SSI1_CLK_49af0c, &MUX_STOCK_SSI1_CSN_0_49af1c, &MUX_STOCK_SSI1_RXD_49af30, &MUX_STOCK_SSI1_TXD_49af40); +PINCTRL_DEVICE(UART0, 2, &MUX_STOCK_UART0_RX_49af50, &MUX_STOCK_UART0_TX_49af58); +PINCTRL_DEVICE(UART1, 2, &MUX_STOCK_UART1_RX_49af60, &MUX_STOCK_UART1_TX_49af6c); +PINCTRL_DEVICE(UART2, 2, &MUX_STOCK_UART2_RX_49af78, &MUX_STOCK_UART2_TX_49af88); +PINCTRL_DEVICE(USB, 2, &MUX_STOCK_USB_DEBUG_CLK_49af98, &MUX_STOCK_USB_PWREN_49afa0); +PINCTRL_DEVICE(GPIO0, 1, &MUX_STOCK_GPIO0_49ab70); +PINCTRL_DEVICE(GPIO1, 1, &MUX_STOCK_GPIO1_49ab78); +PINCTRL_DEVICE(GPIO2, 1, &MUX_STOCK_GPIO2_49abc8); +PINCTRL_DEVICE(GPIO3, 1, &MUX_STOCK_GPIO3_49ac20); +PINCTRL_DEVICE(GPIO4, 1, &MUX_STOCK_GPIO4_49ac38); +PINCTRL_DEVICE(GPIO5, 1, &MUX_STOCK_GPIO5_49ac70); +PINCTRL_DEVICE(GPIO6, 1, &MUX_STOCK_GPIO6_49acb8); +PINCTRL_DEVICE(GPIO7, 1, &MUX_STOCK_GPIO7_49ace0); +PINCTRL_DEVICE(GPIO11, 1, &MUX_STOCK_GPIO11_49ab80); +PINCTRL_DEVICE(GPIO12, 1, &MUX_STOCK_GPIO12_49ab88); +PINCTRL_DEVICE(GPIO13, 1, &MUX_STOCK_GPIO13_49ab90); +PINCTRL_DEVICE(GPIO14, 1, &MUX_STOCK_GPIO14_49ab98); +PINCTRL_DEVICE(GPIO15, 1, &MUX_STOCK_GPIO15_49aba0); +PINCTRL_DEVICE(GPIO16, 1, &MUX_STOCK_GPIO16_49aba8); +PINCTRL_DEVICE(GPIO17, 1, &MUX_STOCK_GPIO17_49abb0); +PINCTRL_DEVICE(GPIO18, 1, &MUX_STOCK_GPIO18_49abb8); +PINCTRL_DEVICE(GPIO19, 1, &MUX_STOCK_GPIO19_49abc0); +PINCTRL_DEVICE(GPIO20, 1, &MUX_STOCK_GPIO20_49abd0); +PINCTRL_DEVICE(GPIO21, 1, &MUX_STOCK_GPIO21_49abd8); +PINCTRL_DEVICE(GPIO22, 1, &MUX_STOCK_GPIO22_49abe0); +PINCTRL_DEVICE(GPIO23, 1, &MUX_STOCK_GPIO23_49abe8); +PINCTRL_DEVICE(GPIO24, 1, &MUX_STOCK_GPIO24_49abf0); +PINCTRL_DEVICE(GPIO25, 1, &MUX_STOCK_GPIO25_49abf8); +PINCTRL_DEVICE(GPIO26, 1, &MUX_STOCK_GPIO26_49ac00); +PINCTRL_DEVICE(GPIO27, 1, &MUX_STOCK_GPIO27_49ac08); +PINCTRL_DEVICE(GPIO28, 1, &MUX_STOCK_GPIO28_49ac10); +PINCTRL_DEVICE(GPIO29, 1, &MUX_STOCK_GPIO29_49ac18); +PINCTRL_DEVICE(GPIO34, 1, &MUX_STOCK_GPIO34_49ac28); +PINCTRL_DEVICE(GPIO38, 1, &MUX_STOCK_GPIO38_49ac30); +PINCTRL_DEVICE(GPIO41, 1, &MUX_STOCK_GPIO41_49ac40); +PINCTRL_DEVICE(GPIO42, 1, &MUX_STOCK_GPIO42_49ac48); +PINCTRL_DEVICE(GPIO43, 1, &MUX_STOCK_GPIO43_49ac50); +PINCTRL_DEVICE(GPIO46, 1, &MUX_STOCK_GPIO46_49ac58); +PINCTRL_DEVICE(GPIO48, 1, &MUX_STOCK_GPIO48_49ac60); +PINCTRL_DEVICE(GPIO49, 1, &MUX_STOCK_GPIO49_49ac68); +PINCTRL_DEVICE(GPIO50, 1, &MUX_STOCK_GPIO50_49ac78); +PINCTRL_DEVICE(GPIO51, 1, &MUX_STOCK_GPIO51_49ac80); +PINCTRL_DEVICE(GPIO52, 1, &MUX_STOCK_GPIO52_49ac88); +PINCTRL_DEVICE(GPIO53, 1, &MUX_STOCK_GPIO53_49ac90); +PINCTRL_DEVICE(GPIO54, 1, &MUX_STOCK_GPIO54_49ac98); +PINCTRL_DEVICE(GPIO56, 1, &MUX_STOCK_GPIO56_49aca0); +PINCTRL_DEVICE(GPIO57, 1, &MUX_STOCK_GPIO57_49acac); +PINCTRL_DEVICE(GPIO60, 1, &MUX_STOCK_GPIO60_49acc0); +PINCTRL_DEVICE(GPIO61, 1, &MUX_STOCK_GPIO61_49acc8); +PINCTRL_DEVICE(GPIO62, 1, &MUX_STOCK_GPIO62_49acd0); +PINCTRL_DEVICE(GPIO63, 1, &MUX_STOCK_GPIO63_49acd8); +PINCTRL_DEVICE(SD1_WIFI, 7, &MUX_STOCK_SD1_CLK_49ae84, &MUX_STOCK_SD1_CD_49ae74, &MUX_STOCK_SD1_CMD_RSP_49ae94, &MUX_STOCK_SD1_DATA_0_49aea4, &MUX_STOCK_SD1_DATA_1_49aeb4, &MUX_STOCK_SD1_DATA_2_49aec4, &MUX_STOCK_SD1_DATA_3_49aed4); +PINCTRL_DEVICE(SD1_WIFI_1BIT, 4, &MUX_STOCK_SD1_CLK_49ae84, &MUX_STOCK_SD1_CD_49ae74, &MUX_STOCK_SD1_CMD_RSP_49ae94, &MUX_STOCK_SD1_DATA_0_49aea4); + +void fh_pinctrl_init_devicelist(OS_LIST *list) +{ + OS_LIST_EMPTY(list); + PINCTRL_ADD_DEVICE(AC_MCLK); + PINCTRL_ADD_DEVICE(ACI2S); + PINCTRL_ADD_DEVICE(ARCJTAG); + PINCTRL_ADD_DEVICE(ARMJTAG); + PINCTRL_ADD_DEVICE(DVP); + PINCTRL_ADD_DEVICE(DWI2S); + PINCTRL_ADD_DEVICE(I2C0); + PINCTRL_ADD_DEVICE(I2C1); + PINCTRL_ADD_DEVICE(I2C2); + PINCTRL_ADD_DEVICE(MIPI); + PINCTRL_ADD_DEVICE(PWM0); + PINCTRL_ADD_DEVICE(PWM1); + PINCTRL_ADD_DEVICE(PWM10); + PINCTRL_ADD_DEVICE(PWM11); + PINCTRL_ADD_DEVICE(PWM2); + PINCTRL_ADD_DEVICE(PWM3); + PINCTRL_ADD_DEVICE(PWM4); + PINCTRL_ADD_DEVICE(PWM5); + PINCTRL_ADD_DEVICE(PWM6); + PINCTRL_ADD_DEVICE(PWM7); + PINCTRL_ADD_DEVICE(PWM8); + PINCTRL_ADD_DEVICE(PWM9); + PINCTRL_ADD_DEVICE(RMII); + PINCTRL_ADD_DEVICE(RTC); + PINCTRL_ADD_DEVICE(SADC_CHANL0); + PINCTRL_ADD_DEVICE(SADC_CHANL1); + PINCTRL_ADD_DEVICE(SADC_CHANL2); + PINCTRL_ADD_DEVICE(SD0); + PINCTRL_ADD_DEVICE(SD0_1BIT_NO_WP); + PINCTRL_ADD_DEVICE(SD0_NO_WP); + PINCTRL_ADD_DEVICE(SD1); + PINCTRL_ADD_DEVICE(SD1_1BIT_NO_WP); + PINCTRL_ADD_DEVICE(SD1_NO_WP); + PINCTRL_ADD_DEVICE(SSI0); + PINCTRL_ADD_DEVICE(SSI0_4BIT); + PINCTRL_ADD_DEVICE(SSI1); + PINCTRL_ADD_DEVICE(UART0); + PINCTRL_ADD_DEVICE(UART1); + PINCTRL_ADD_DEVICE(UART2); + PINCTRL_ADD_DEVICE(USB); + PINCTRL_ADD_DEVICE(GPIO0); + PINCTRL_ADD_DEVICE(GPIO1); + PINCTRL_ADD_DEVICE(GPIO2); + PINCTRL_ADD_DEVICE(GPIO3); + PINCTRL_ADD_DEVICE(GPIO4); + PINCTRL_ADD_DEVICE(GPIO5); + PINCTRL_ADD_DEVICE(GPIO6); + PINCTRL_ADD_DEVICE(GPIO7); + PINCTRL_ADD_DEVICE(GPIO11); + PINCTRL_ADD_DEVICE(GPIO12); + PINCTRL_ADD_DEVICE(GPIO13); + PINCTRL_ADD_DEVICE(GPIO14); + PINCTRL_ADD_DEVICE(GPIO15); + PINCTRL_ADD_DEVICE(GPIO16); + PINCTRL_ADD_DEVICE(GPIO17); + PINCTRL_ADD_DEVICE(GPIO18); + PINCTRL_ADD_DEVICE(GPIO19); + PINCTRL_ADD_DEVICE(GPIO20); + PINCTRL_ADD_DEVICE(GPIO21); + PINCTRL_ADD_DEVICE(GPIO22); + PINCTRL_ADD_DEVICE(GPIO23); + PINCTRL_ADD_DEVICE(GPIO24); + PINCTRL_ADD_DEVICE(GPIO25); + PINCTRL_ADD_DEVICE(GPIO26); + PINCTRL_ADD_DEVICE(GPIO27); + PINCTRL_ADD_DEVICE(GPIO28); + PINCTRL_ADD_DEVICE(GPIO29); + PINCTRL_ADD_DEVICE(GPIO34); + PINCTRL_ADD_DEVICE(GPIO38); + PINCTRL_ADD_DEVICE(GPIO41); + PINCTRL_ADD_DEVICE(GPIO42); + PINCTRL_ADD_DEVICE(GPIO43); + PINCTRL_ADD_DEVICE(GPIO46); + PINCTRL_ADD_DEVICE(GPIO48); + PINCTRL_ADD_DEVICE(GPIO49); + PINCTRL_ADD_DEVICE(GPIO50); + PINCTRL_ADD_DEVICE(GPIO51); + PINCTRL_ADD_DEVICE(GPIO52); + PINCTRL_ADD_DEVICE(GPIO53); + PINCTRL_ADD_DEVICE(GPIO54); + PINCTRL_ADD_DEVICE(GPIO56); + PINCTRL_ADD_DEVICE(GPIO57); + PINCTRL_ADD_DEVICE(GPIO60); + PINCTRL_ADD_DEVICE(GPIO61); + PINCTRL_ADD_DEVICE(GPIO62); + PINCTRL_ADD_DEVICE(GPIO63); + PINCTRL_ADD_DEVICE(SD1_WIFI); + PINCTRL_ADD_DEVICE(SD1_WIFI_1BIT); +} + +char *fh_pinctrl_selected_devices[] = { + "I2C0", + "MIPI", + "PWM7", + "RMII", + "SADC_CHANL0", + "SADC_CHANL1", + "SSI0", + "UART0", + "GPIO0", + "GPIO1", + "GPIO2", + "GPIO3", + "GPIO6", + "GPIO11", + "GPIO13", + "GPIO14", + "GPIO4", + "GPIO5", + "GPIO19", + "GPIO20", + "GPIO21", + "GPIO25", + "GPIO26", + "GPIO27", + "GPIO28", +}; + +#endif /* __FH8626V100_IOPAD_H */ diff --git a/arch/arm/mach-fh/fh8626v100/platform.h b/arch/arm/mach-fh/fh8626v100/platform.h new file mode 100644 index 0000000000..98dd7c4eeb --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/platform.h @@ -0,0 +1,9 @@ +#ifndef __FH8626V100_PLATFORM_H +#define __FH8626V100_PLATFORM_H + +#include + +void __init fh_timer_init_no_of(unsigned int iovbase, unsigned int irqno); +void __init fh_intc_init_no_of(unsigned int iovbase); + +#endif diff --git a/arch/arm/mach-fh/fh8626v100/pmu.c b/arch/arm/mach-fh/fh8626v100/pmu.c new file mode 100644 index 0000000000..c7393ca707 --- /dev/null +++ b/arch/arm/mach-fh/fh8626v100/pmu.c @@ -0,0 +1,283 @@ +#include +#include +#include + +#include +#include + +#include "chip.h" + +static void __iomem *fh_pmu_regs; + +void fh_pmu_set_reg(unsigned int offset, unsigned int data) +{ + writel(data, fh_pmu_regs + offset); +} +EXPORT_SYMBOL(fh_pmu_set_reg); + +unsigned int fh_pmu_get_reg(unsigned int offset) +{ + return readl(fh_pmu_regs + offset); +} +EXPORT_SYMBOL(fh_pmu_get_reg); + +void fh_pmu_set_reg_m(unsigned int offset, unsigned int data, + unsigned int mask) +{ + unsigned int value; + + value = fh_pmu_get_reg(offset); + value &= ~mask; + value |= data & mask; + fh_pmu_set_reg(offset, value); +} +EXPORT_SYMBOL(fh_pmu_set_reg_m); + +void fh_get_chipid(unsigned int *plat_id, unsigned int *chip_id) +{ + if (plat_id) + *plat_id = fh_pmu_get_reg(REG_PMU_CHIP_ID); + + if (chip_id) + *chip_id = fh_pmu_get_reg(REG_PMU_IP_VER); +} +EXPORT_SYMBOL(fh_get_chipid); + +unsigned int fh_pmu_get_ddrsize(void) +{ + return 0; +} +EXPORT_SYMBOL(fh_pmu_get_ddrsize); + +int fh_pmu_init(void) +{ + if (!fh_pmu_regs) + fh_pmu_regs = (void __iomem *)VA_PMU_REG_BASE; + + return 0; +} + +static void fh_pmu_ahb_reset(unsigned int value, unsigned int retry, + unsigned int delay_us) +{ + fh_pmu_set_reg(REG_PMU_SWRST_AHB_CTRL, value); + + while (fh_pmu_get_reg(REG_PMU_SWRST_AHB_CTRL) != 0xffffffff) { + if (!retry--) + return; + udelay(delay_us); + } +} + +void fh_pmu_sdc_reset(int slot_id) +{ + unsigned int reset_value = 0; + + if (slot_id == 0) + reset_value = ~FH8626V100_SDC0_RESET_MASK; + else if (slot_id == 1) + reset_value = ~FH8626V100_SDC1_RESET_MASK; + + fh_pmu_ahb_reset(reset_value, 1000, 1); +} +EXPORT_SYMBOL_GPL(fh_pmu_sdc_reset); + +/* + * Latch and read the common PMU presentation timestamp counter. Audio DMA + * records this value on capture completion; the offsets and latch sequence + * match the exact FH8626V100 stock implementation. + */ +unsigned int fh_pmu_get_ptsl(void) +{ + fh_pmu_set_reg(REG_PMU_PTSLO, 0x01); + return fh_pmu_get_reg(REG_PMU_PTSLO); +} +EXPORT_SYMBOL(fh_pmu_get_ptsl); + +unsigned int fh_pmu_get_ptsh(void) +{ + fh_pmu_set_reg(REG_PMU_PTSLO, 0x01); + return fh_pmu_get_reg(REG_PMU_PTSHI); +} +EXPORT_SYMBOL(fh_pmu_get_ptsh); + +unsigned long long fh_get_pts64(void) +{ + unsigned int high, low; + + fh_pmu_set_reg(REG_PMU_PTSLO, 0x01); + high = fh_pmu_get_reg(REG_PMU_PTSHI); + low = fh_pmu_get_reg(REG_PMU_PTSLO); + + return ((unsigned long long)high << 32) | low; +} +EXPORT_SYMBOL(fh_get_pts64); + +void fh_pmu_dwi2s_set_clk(unsigned int div_i2s, unsigned int div_mclk) +{ + unsigned int value; + + value = fh_pmu_get_reg(PMU_DWI2S_CLK_DIV_REG); + value &= ~(0xffff << PMU_DWI2S_CLK_DIV_SHIFT); + value |= (((div_i2s - 1) << 8) | (div_mclk - 1)) + << PMU_DWI2S_CLK_DIV_SHIFT; + fh_pmu_set_reg(PMU_DWI2S_CLK_DIV_REG, value); + + /* Select the stock audio PLL source after programming both divisors. */ + value = fh_pmu_get_reg(PMU_DWI2S_CLK_SEL_REG); + value |= 1 << PMU_DWI2S_CLK_SEL_SHIFT; + fh_pmu_set_reg(PMU_DWI2S_CLK_SEL_REG, value); +} +EXPORT_SYMBOL_GPL(fh_pmu_dwi2s_set_clk); + +void fh_pmu_eth_set_speed(unsigned int speed) +{ + unsigned int value; + + value = fh_pmu_get_reg(REG_PMU_ETH_CTRL); + + if (speed == 10) + value &= ~FH8626V100_ETH_SPEED_100M; + else if (speed == 100) + value |= FH8626V100_ETH_SPEED_100M; + else + return; + + fh_pmu_set_reg(REG_PMU_ETH_CTRL, value); +} +EXPORT_SYMBOL_GPL(fh_pmu_eth_set_speed); + +void fh_pmu_eth_reset(void) +{ + unsigned int retry = 1000; + + fh_pmu_set_reg(REG_PMU_SWRST_AHB_CTRL, + ~FH8626V100_EMAC_RESET_MASK); + + while (fh_pmu_get_reg(REG_PMU_SWRST_AHB_CTRL) != 0xffffffff) { + if (!retry--) + break; + udelay(1); + } +} +EXPORT_SYMBOL_GPL(fh_pmu_eth_reset); + +void fh_pmu_ephy_sel(__u32 phy_sel) +{ + (void)phy_sel; +} +EXPORT_SYMBOL(fh_pmu_ephy_sel); + +void fh_pmu_restart(void) +{ + fh_pmu_set_reg(REG_PMU_SWRST_APB_CTRL, 0x7fffffff); + + for (;;) + cpu_relax(); +} + +void fh_pmu_wdt_pause(void) +{ + unsigned int reg; + + reg = fh_pmu_get_reg(REG_PMU_WDT_CTRL); + reg |= 0x100; + fh_pmu_set_reg(REG_PMU_WDT_CTRL, reg); +} + +void fh_pmu_wdt_resume(void) +{ + unsigned int reg; + + reg = fh_pmu_get_reg(REG_PMU_WDT_CTRL); + reg &= ~0x100; + fh_pmu_set_reg(REG_PMU_WDT_CTRL, reg); +} + +void fh_pmu_arxc_write_A625_INT_RAWSTAT(unsigned int value) +{ + fh_pmu_set_reg(REG_PMU_A625_INT_RAWSTAT, value); +} +EXPORT_SYMBOL_GPL(fh_pmu_arxc_write_A625_INT_RAWSTAT); + +unsigned int fh_pmu_arxc_read_ARM_INT_RAWSTAT(void) +{ + return fh_pmu_get_reg(REG_PMU_ARM_INT_RAWSTAT); +} +EXPORT_SYMBOL_GPL(fh_pmu_arxc_read_ARM_INT_RAWSTAT); + +void fh_pmu_arxc_write_ARM_INT_RAWSTAT(unsigned int value) +{ + fh_pmu_set_reg(REG_PMU_ARM_INT_RAWSTAT, value); +} +EXPORT_SYMBOL_GPL(fh_pmu_arxc_write_ARM_INT_RAWSTAT); + +void fh_pmu_arxc_reset(unsigned long physical_address) +{ + unsigned int arc_address; + + fh_pmu_set_reg(REG_PMU_ARC_RESET, ~FH8626V100_ARC_RESET_MASK); + arc_address = (physical_address << 16) | (physical_address >> 16); + fh_pmu_set_reg(REG_PMU_A625BOOT0, 0x7940266b); + fh_pmu_set_reg(REG_PMU_A625BOOT1, arc_address); + fh_pmu_set_reg(REG_PMU_A625BOOT2, 0x0f802020); + fh_pmu_set_reg(REG_PMU_A625BOOT3, arc_address); + fh_pmu_arxc_write_ARM_INT_RAWSTAT(0); + fh_pmu_set_reg(REG_PMU_A625_START_CTRL, 0); + udelay(2); + fh_pmu_set_reg(REG_PMU_ARC_RESET, 0xffffffff); +} +EXPORT_SYMBOL_GPL(fh_pmu_arxc_reset); + +void fh_pmu_arxc_kickoff(void) +{ + fh_pmu_set_reg(REG_PMU_A625_START_CTRL, 0x10); +} +EXPORT_SYMBOL_GPL(fh_pmu_arxc_kickoff); + +void fh_pmu_usb_phy_rst(void) +{ + unsigned int value; + + value = fh_pmu_get_reg(REG_PMU_USB_SYS); + value &= ~FH8626V100_USB_PHY_IDDQ_MASK; + fh_pmu_set_reg(REG_PMU_USB_SYS, value); + mdelay(1); + + value = fh_pmu_get_reg(REG_PMU_USB_SYS); + value |= FH8626V100_USB_PHY_RESET_MASK; + fh_pmu_set_reg(REG_PMU_USB_SYS, value); + mdelay(1); + + value = fh_pmu_get_reg(REG_PMU_USB_SYS); + value &= ~FH8626V100_USB_PHY_RESET_MASK; + fh_pmu_set_reg(REG_PMU_USB_SYS, value); +} +EXPORT_SYMBOL_GPL(fh_pmu_usb_phy_rst); + +void fh_pmu_usb_utmi_rst(void) +{ + unsigned int value; + + value = fh_pmu_get_reg(REG_PMU_SWRST_APB_CTRL); + value &= ~FH8626V100_USB_UTMI_RESET_MASK; + fh_pmu_set_reg(REG_PMU_SWRST_APB_CTRL, value); + mdelay(1); + + value = fh_pmu_get_reg(REG_PMU_SWRST_APB_CTRL); + value |= FH8626V100_USB_UTMI_RESET_MASK; + fh_pmu_set_reg(REG_PMU_SWRST_APB_CTRL, value); + msleep(20); +} +EXPORT_SYMBOL_GPL(fh_pmu_usb_utmi_rst); + +void fh_pmu_usb_resume(void) +{ + unsigned int value; + + value = fh_pmu_get_reg(REG_PMU_USB_SYS); + value |= FH8626V100_USB_SLEEP_MODE_MASK; + fh_pmu_set_reg(REG_PMU_USB_SYS, value); + mdelay(1); +} +EXPORT_SYMBOL_GPL(fh_pmu_usb_resume); diff --git a/arch/arm/mach-fh/include/mach/fh_gmac_plat.h b/arch/arm/mach-fh/include/mach/fh_gmac_plat.h index 7526eac7d0..a516f15c32 100644 --- a/arch/arm/mach-fh/include/mach/fh_gmac_plat.h +++ b/arch/arm/mach-fh/include/mach/fh_gmac_plat.h @@ -6,5 +6,6 @@ struct fh_gmac_platform_data { u32 speed_switch_pmu_reg; u32 speed_switch_bit_pos; u32 speed_switch_100M_val; + u8 mac_addr[6]; }; -#endif \ No newline at end of file +#endif diff --git a/arch/arm/mach-fh/include/mach/pinctrl.h b/arch/arm/mach-fh/include/mach/pinctrl.h index 5665374474..1f2caf8175 100644 --- a/arch/arm/mach-fh/include/mach/pinctrl.h +++ b/arch/arm/mach-fh/include/mach/pinctrl.h @@ -131,9 +131,10 @@ typedef struct typedef struct { - void *vbase; - void *pbase; - PinCtrl_Pin *pinlist[PAD_NUM]; + void *vbase; + void *pbase; + PinCtrl_Pin *pinlist[PAD_NUM]; + PinCtrl_Register registers[PAD_NUM]; } PinCtrl_Object; typedef struct diff --git a/arch/arm/mach-fh/include/mach/pmu.h b/arch/arm/mach-fh/include/mach/pmu.h index 216152c181..63f78d0445 100644 --- a/arch/arm/mach-fh/include/mach/pmu.h +++ b/arch/arm/mach-fh/include/mach/pmu.h @@ -6,6 +6,10 @@ #include "chip.h" +void fh_pmu_set_reg(unsigned int offset, unsigned int data); +unsigned int fh_pmu_get_reg(unsigned int offset); +void fh_pmu_set_reg_m(unsigned int offset, unsigned int data, + unsigned int mask); void fh_get_chipid(unsigned int *plat_id, unsigned int *chip_id); unsigned int fh_pmu_get_ptsl(void); unsigned int fh_pmu_get_ptsh(void); diff --git a/arch/arm/mach-fh/pinctrl.c b/arch/arm/mach-fh/pinctrl.c index ec867a4f89..21d8667259 100644 --- a/arch/arm/mach-fh/pinctrl.c +++ b/arch/arm/mach-fh/pinctrl.c @@ -33,8 +33,6 @@ static void fh_pinctrl_check_duplicate_pin(PinCtrl_Pin *pin, int start_pad) static int fh_pinctrl_func_select(PinCtrl_Pin *pin, unsigned int flag) { - unsigned int reg; - if (!pin) { OS_PRINT("ERROR: pin is null\n\n"); @@ -51,9 +49,8 @@ static int fh_pinctrl_func_select(PinCtrl_Pin *pin, unsigned int flag) } fh_pinctrl_check_duplicate_pin(pin, 0); - reg = GET_REG(pinctrl_obj.vbase + pin->reg_offset); - - pin->reg = (PinCtrl_Register *)® + pin->reg = &pinctrl_obj.registers[pin->pad_id]; + pin->reg->dw = GET_REG(pinctrl_obj.vbase + pin->reg_offset); pin->reg->bit.mfs = pin->func_sel; diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index 8a3b96b9c3..d2ea00631d 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -1012,3 +1012,4 @@ fh8858v200 MACH_FH8858V200 FH8858V200 9999 fh8856v210 MACH_FH8856V210 FH8856V210 9999 fh8852v210 MACH_FH8852V210 FH8852V210 9999 fh8858v210 MACH_FH8858V210 FH8858V210 9999 +fh8626v100 MACH_FH8626V100 FH8626V100 9999 diff --git a/drivers/misc/fh_sadc_v2.c b/drivers/misc/fh_sadc_v2.c index 0df582be29..3f44be36b3 100644 --- a/drivers/misc/fh_sadc_v2.c +++ b/drivers/misc/fh_sadc_v2.c @@ -933,7 +933,8 @@ static int fh_sadc_probe(struct platform_device *pdev) goto fail_no_ioremap; } #endif - strncpy(fh_sadc_obj.isr_name, "sadc", sizeof("sadc")); + strlcpy(fh_sadc_obj.isr_name, "sadc", + sizeof(fh_sadc_obj.isr_name)); err = request_irq(fh_sadc_obj.irq_no, fh_sadc_isr, IRQF_NO_THREAD, fh_sadc_obj.isr_name, &fh_sadc_obj); if (err) { diff --git a/drivers/net/ethernet/fullhan/fh_gmac_main.c b/drivers/net/ethernet/fullhan/fh_gmac_main.c index 5c0cd48d93..f9f260fcc1 100644 --- a/drivers/net/ethernet/fullhan/fh_gmac_main.c +++ b/drivers/net/ethernet/fullhan/fh_gmac_main.c @@ -104,11 +104,17 @@ static void GMAC_SetMacAddress(Gmac_Object* pGmac) int gmac_dev_set_mac_addr(struct net_device *dev, void *p) { - Gmac_Object *pGmac = netdev_priv(dev); - struct sockaddr *addr = p; - memcpy(pGmac->local_mac_address, addr->sa_data, ETH_ALEN); - GMAC_SetMacAddress(pGmac); - return eth_mac_addr(dev, p); + Gmac_Object *pGmac = netdev_priv(dev); + int ret; + + /* Validate dev_addr before changing driver state or hardware. */ + ret = eth_mac_addr(dev, p); + if (ret) + return ret; + + ether_addr_copy(pGmac->local_mac_address, dev->dev_addr); + GMAC_SetMacAddress(pGmac); + return 0; } static inline void GMAC_EnableMac(Gmac_Object* pGmac) @@ -944,6 +950,7 @@ static int fh_gmac_probe(struct platform_device *pdev) Gmac_Object *pGmac; struct clk *rmii_clk; struct net_device *ndev; + bool mac_from_platform_data = false; #ifdef CONFIG_USE_OF struct device_node *np = pdev->dev.of_node; #else @@ -1042,8 +1049,7 @@ static int fh_gmac_probe(struct platform_device *pdev) ndev->netdev_ops = &fh_gmac_netdev_ops; fh_gmac_set_ethtool_ops(ndev); - ndev->hw_features = NETIF_F_SG | NETIF_F_IP_CSUM | - NETIF_F_HW_CSUM | NETIF_F_RXCSUM; + ndev->hw_features = NETIF_F_SG | NETIF_F_HW_CSUM | NETIF_F_RXCSUM; ndev->features |= ndev->hw_features | NETIF_F_HIGHDMA; ndev->watchdog_timeo = msecs_to_jiffies(watchdog); pGmac->msg_enable = netif_msg_init(debug, FH_GMAC_DEBUG); @@ -1051,13 +1057,28 @@ static int fh_gmac_probe(struct platform_device *pdev) pGmac->flow_ctrl = FLOW_AUTO; /* RX/TX pause on */ pGmac->pause = pause; netif_napi_add(ndev, &(pGmac->napi), fh_gmac_poll, NAPI_POLL_WEIGHT); - if (!is_valid_ether_addr(pGmac->local_mac_address)) { + ret = eth_platform_get_mac_address(&pdev->dev, + pGmac->local_mac_address); +#ifndef CONFIG_USE_OF + if ((ret || !is_valid_ether_addr(pGmac->local_mac_address)) && + p_plat_data && is_valid_ether_addr(p_plat_data->mac_addr)) { + ether_addr_copy(pGmac->local_mac_address, + p_plat_data->mac_addr); + ret = 0; + mac_from_platform_data = true; + } +#endif + if (ret || !is_valid_ether_addr(pGmac->local_mac_address)) { /* Use random MAC if none passed */ random_ether_addr(pGmac->local_mac_address); pr_warning("\tusing random MAC address: %pM\n", - pGmac->local_mac_address); + pGmac->local_mac_address); + } else { + pr_info("\tusing %s MAC address: %pM\n", + mac_from_platform_data ? "platform-data" : "platform", + pGmac->local_mac_address); } - ndev->dev_addr = pGmac->local_mac_address; + ether_addr_copy(ndev->dev_addr, pGmac->local_mac_address); if (auto_find_phy(pGmac)) pr_err("find no phy !!!!!!!"); diff --git a/drivers/net/ethernet/fullhan/fh_gmac_phyt.c b/drivers/net/ethernet/fullhan/fh_gmac_phyt.c index 07abfe9767..3224b01771 100644 --- a/drivers/net/ethernet/fullhan/fh_gmac_phyt.c +++ b/drivers/net/ethernet/fullhan/fh_gmac_phyt.c @@ -30,6 +30,11 @@ struct mdio_pin_mux_ref { unsigned int phy_support_list[] = { FH_GMAC_PHY_IP101G, FH_GMAC_PHY_RTL8201, + FH_GMAC_PHY_JL1101_4023, + FH_GMAC_PHY_JL1101_4024, + FH_GMAC_PHY_JL1101_4025, + FH_GMAC_PHY_JL1101_4026, + FH_GMAC_PHY_JL1101_4027, FH_GMAC_PHY_TI83848, FH_GMAC_PHY_INTERNAL, }; @@ -43,6 +48,13 @@ struct mdio_pin_mux_ref _mdio_pin_ref_obj[] = { void external_phy_pin_sel(Gmac_Object *gmac, int flag) { +#if defined(CONFIG_ARCH_FH8626V100) + + /* FH8626V100 RAM bring-up keeps the U-Boot RMII mux. The exact + * Linux 4.9 iopad table is closed separately before upstreaming. + */ + return; +#else int i; char temp_buf[16] = {0}; @@ -79,9 +91,9 @@ void external_phy_pin_sel(Gmac_Object *gmac, int flag) fh_pinctrl_set_oe("MAC_REF_CLK", 0); } } +#endif } - static int __fh_mdio_read(Gmac_Object *pGmac, int phyaddr, int phyreg) { int ret; @@ -219,8 +231,10 @@ int auto_find_phy(Gmac_Object *gmac) return -1; } +#if !defined(CONFIG_ARCH_FH8626V100) if (strcmp(c_driver, "Generic PHY") == 0) fh_pinctrl_sdev("RMII", 0); +#endif return 0; #endif @@ -354,6 +368,11 @@ static int fh_mdio_set_mii(struct mii_bus *bus) switch (pGmac->phydev->phy_id) { case FH_GMAC_PHY_RTL8201: + case FH_GMAC_PHY_JL1101_4023: + case FH_GMAC_PHY_JL1101_4024: + case FH_GMAC_PHY_JL1101_4025: + case FH_GMAC_PHY_JL1101_4026: + case FH_GMAC_PHY_JL1101_4027: fh_mdio_write(bus, phyid, gmac_phyt_rtl8201_page_select, 7); fh_mdio_write(bus, phyid, diff --git a/drivers/net/ethernet/fullhan/fh_gmac_phyt.h b/drivers/net/ethernet/fullhan/fh_gmac_phyt.h index 509782fbf1..e240fae606 100644 --- a/drivers/net/ethernet/fullhan/fh_gmac_phyt.h +++ b/drivers/net/ethernet/fullhan/fh_gmac_phyt.h @@ -11,6 +11,11 @@ #define FH_GMAC_PHY_IP101G 0x02430C54 #define FH_GMAC_PHY_RTL8201 0x001CC816 +#define FH_GMAC_PHY_JL1101_4023 0x937C4023 +#define FH_GMAC_PHY_JL1101_4024 0x937C4024 +#define FH_GMAC_PHY_JL1101_4025 0x937C4025 +#define FH_GMAC_PHY_JL1101_4026 0x937C4026 +#define FH_GMAC_PHY_JL1101_4027 0x937C4027 #define FH_GMAC_PHY_TI83848 0xFFFFFFFF #define FH_GMAC_PHY_INTERNAL 0x441400 diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile index 1d7e5d8386..e9bbd31c27 100644 --- a/drivers/pwm/Makefile +++ b/drivers/pwm/Makefile @@ -47,7 +47,7 @@ obj-$(CONFIG_PWM_TWL) += pwm-twl.o obj-$(CONFIG_PWM_TWL_LED) += pwm-twl-led.o obj-$(CONFIG_PWM_VT8500) += pwm-vt8500.o obj-$(CONFIG_PWM_FULLHAN) += pwm-fullhan-common.o +obj-$(CONFIG_PWM_FULLHAN_V21) += pwmv2.o ifeq ($(CONFIG_ARCH_FH885xV200),y) obj-$(CONFIG_PWM_FULLHAN) += pwmv3.o endif - diff --git a/drivers/pwm/pwm-fullhan-common.c b/drivers/pwm/pwm-fullhan-common.c index 03b322b4be..f9e8c24b24 100644 --- a/drivers/pwm/pwm-fullhan-common.c +++ b/drivers/pwm/pwm-fullhan-common.c @@ -20,13 +20,18 @@ #include #include #include +#include #include #include #include "pwm-fullhan-common.h" #include #include -#define FH_PWM_DEBUG +/* + * Register-by-register logging materially delays staging a multi-channel + * one-shot group and is not present in the stock FH8626 production path. + */ +/* #define FH_PWM_DEBUG */ #ifdef FH_PWM_DEBUG #define PRINT_DBG(fmt, args...) printk(fmt, ##args) #else @@ -343,6 +348,13 @@ static void fh_pwm_get_config(struct fh_pwm_chip_data *chip_data) unsigned int ctrl = 0, period, duty, delay, phase, pulses, status0, status1, status2; + if (!clk_rate) { + pr_err("PWM: cannot read config with a zero clock rate\n"); + memset(&chip_data->config, 0, sizeof(chip_data->config)); + memset(&chip_data->status, 0, sizeof(chip_data->status)); + return; + } + period = readl(fh_pwm_drv->base + OFFSET_PWM_CFG0(chip_data->id)); duty = readl(fh_pwm_drv->base + OFFSET_PWM_CFG1(chip_data->id)); phase = readl(fh_pwm_drv->base + OFFSET_PWM_CFG2(chip_data->id)); @@ -378,8 +390,15 @@ static void fh_pwm_get_config(struct fh_pwm_chip_data *chip_data) chip_data->config.delay_ns = delay * (NSEC_PER_SEC / clk_rate); chip_data->config.pulses = pulses; chip_data->config.stop = (ctrl >> 1) & 0x3; - chip_data->config.percent = chip_data->config.duty_ns / - (chip_data->config.period_ns / 100); + /* Unconfigured channels have period == 0. The proc status reader walks + * every hardware channel, so never divide by the derived zero divisor. + */ + if (chip_data->config.period_ns) + chip_data->config.percent = div_u64( + (u64)chip_data->config.duty_ns * 100, + chip_data->config.period_ns); + else + chip_data->config.percent = 0; chip_data->status.busy = (status2 >> 4) & 0x1; chip_data->status.error = (status2 >> 3) & 0x1; @@ -527,7 +546,7 @@ static long fh_pwm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) fh_pwm_drv->chip.pwms[chip_data.id].chip_data, (void *)&chip_data, sizeof(struct fh_pwm_chip_data)); - pr_info("ioctl: SET_PWM_DUTY_CYCLE, " + pr_debug("ioctl: SET_PWM_DUTY_CYCLE, " "pwm->id: %d, pwm->counter: %d, pwm->period: %d ns\n", chip_data.id, chip_data.config.duty_ns, chip_data.config.period_ns); @@ -550,7 +569,7 @@ static long fh_pwm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) fh_pwm_drv->chip.pwms[chip_data.id].chip_data, (void *)&chip_data, sizeof(struct fh_pwm_chip_data)); - pr_info("ioctl: GET_PWM_DUTY_CYCLE, " + pr_debug("ioctl: GET_PWM_DUTY_CYCLE, " "pwm->id: %d, pwm->counter: %d, pwm->period: %d ns\n", chip_data.id, chip_data.config.duty_ns, chip_data.config.period_ns); @@ -586,7 +605,7 @@ static long fh_pwm_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) fh_pwm_drv->chip.pwms[chip_data.id].chip_data, (void *)&chip_data, sizeof(struct fh_pwm_chip_data)); - pr_info("ioctl: SET_PWM_DUTY_CYCLE_PERCENT, " + pr_debug("ioctl: SET_PWM_DUTY_CYCLE_PERCENT, " "pwm->id: %d, pwm->counter: %d, pwm->period: %d ns\n", chip_data.id, chip_data.config.duty_ns, chip_data.config.period_ns); @@ -762,6 +781,10 @@ static int v_seq_show(struct seq_file *sfile, void *v) struct fh_pwm_chip_data *chip_data; pcd = pwm_get_chip_data(&fh_pwm_drv->chip.pwms[i]); + if (!pcd) { + seq_printf(sfile, "id: %d \tUNAVAILABLE\n", i); + continue; + } chip_data = &pcd->chip_data; fh_pwm_get_config(chip_data); diff --git a/drivers/rtc/rtc-fh_v2.c b/drivers/rtc/rtc-fh_v2.c index 67f81e3060..323e69e643 100644 --- a/drivers/rtc/rtc-fh_v2.c +++ b/drivers/rtc/rtc-fh_v2.c @@ -537,16 +537,20 @@ static int fh_rtc_get_alarm_time(unsigned int base_addr) return data; } -static unsigned int fh_rtc_get_hw_sec_data(unsigned int func_switch) -{ - unsigned int ret_sec, raw_value, sec_value; +static int fh_rtc_get_hw_sec_data(unsigned int func_switch, + unsigned int *seconds) +{ + unsigned int ret_sec, sec_value; unsigned int min_value, hour_value, day_value; + int raw_value; if (func_switch == TIME_FUNC) raw_value = fh_rtc_get_time((unsigned int)fh_rtc->regs); else raw_value = fh_rtc_get_alarm_time((unsigned int)fh_rtc->regs); + if (raw_value < 0) + return raw_value; sec_value = FH_GET_RTC_SEC(raw_value); min_value = FH_GET_RTC_MIN(raw_value); @@ -555,7 +559,8 @@ static unsigned int fh_rtc_get_hw_sec_data(unsigned int func_switch) ret_sec = (day_value * 86400) + (hour_value * 3600) + (min_value * 60) + sec_value; - return ret_sec; + *seconds = ret_sec; + return 0; } #ifdef DRIVER_TEST @@ -647,8 +652,11 @@ static int fh_rtc_tm_compare(struct rtc_time *tm0, struct rtc_time *tm1) static int fh_rtc_gettime_nosync(struct device *dev, struct rtc_time *rtc_tm) { unsigned int temp; + int status; - temp = fh_rtc_get_hw_sec_data(TIME_FUNC); + status = fh_rtc_get_hw_sec_data(TIME_FUNC, &temp); + if (status) + return status; rtc_time_to_tm(temp, rtc_tm); RTC_PRINT_DBG("rtc read date:0x%x\n", temp); @@ -661,16 +669,19 @@ static int fh_rtc_settime(struct device *dev, struct rtc_time *tm) tm->tm_mon + 1, tm->tm_mday, tm->tm_hour, tm->tm_min, tm->tm_sec); - fh_rtc_set_hw_sec_data(tm, TIME_FUNC); - - return 0; + return fh_rtc_set_hw_sec_data(tm, TIME_FUNC); } static int fh_rtc_getalarm(struct device *dev, struct rtc_wkalrm *alrm) { struct rtc_time *rtc_tm = &alrm->time; + unsigned int temp; + int status; - rtc_time_to_tm(fh_rtc_get_hw_sec_data(ALARM_FUNC), rtc_tm); + status = fh_rtc_get_hw_sec_data(ALARM_FUNC, &temp); + if (status) + return status; + rtc_time_to_tm(temp, rtc_tm); return 0; } @@ -972,7 +983,6 @@ static const struct rtc_class_ops fh_rtcops = { /*get the read of SADC and adjust RTC clock*/ static struct miscdevice fh_rtc_misc; - static struct of_device_id const fh_rtc_of_match[] = { { .compatible = "fh,fh_rtc" }, {} diff --git a/drivers/usb/dwc2/platform.c b/drivers/usb/dwc2/platform.c index 40b556bfa3..f91b9d30e7 100644 --- a/drivers/usb/dwc2/platform.c +++ b/drivers/usb/dwc2/platform.c @@ -279,8 +279,8 @@ static void fh_usb_pwr_on(struct dwc2_hsotg *hsotg) pwren_gpio = usb_get_vbus_pwren_gpio(hsotg->dev); if (pwren_gpio == 0xFFFFFFFF) { - dev_warn(hsotg->dev, - "Can't find usb vbus pwren gpio\n"); + dev_dbg(hsotg->dev, + "No controllable USB VBUS power GPIO\n"); return; } From ebf5d776c748edbd58c1aaf8be9d5b2639a16834 Mon Sep 17 00:00:00 2001 From: ArthurKoba <61914203+ArthurKoba@users.noreply.github.com> Date: Fri, 4 Sep 2026 15:08:14 +0300 Subject: [PATCH 2/2] ARM: fullhan: fix FH8626V100 configuration errors Keep the legacy FH8626V100 platform restricted to non-DT builds so its PMU implementation is always available. Replace the complete clock phase field instead of accumulating stale bits, fix phase readback, and report success using the clock API convention. Validate PWM timing before disabling an active channel and propagate configuration failures to callers. --- arch/arm/mach-fh/Kconfig | 1 + arch/arm/mach-fh/clock.c | 49 ++++++++++++++------------------ drivers/pwm/pwm-fullhan-common.c | 27 +++++++++++++----- 3 files changed, 42 insertions(+), 35 deletions(-) diff --git a/arch/arm/mach-fh/Kconfig b/arch/arm/mach-fh/Kconfig index ceec359132..b693595964 100644 --- a/arch/arm/mach-fh/Kconfig +++ b/arch/arm/mach-fh/Kconfig @@ -70,6 +70,7 @@ choice prompt "Board" config ARCH_FH8626V100 bool "Fullhan FH8626V100" + depends on !USE_OF select CPU_V6 select FULLHAN_INTC select FULLHAN_TIMER diff --git a/arch/arm/mach-fh/clock.c b/arch/arm/mach-fh/clock.c index b41616b006..3f68c1c287 100644 --- a/arch/arm/mach-fh/clock.c +++ b/arch/arm/mach-fh/clock.c @@ -235,60 +235,53 @@ int fh_pll_pr_clk_register(struct fh_clk *fh_clk) } -static int fh_clk_set_phase(struct clk_hw *hw, - int degree) +static int fh_clk_set_phase(struct clk_hw *hw, int degree) { - u32 reg; struct fh_clk_phase *phase = (struct fh_clk_phase *)hw; unsigned long flags = 0; - u32 local_degree = 0; - u32 shift = 0; - - /*printk("fh_clk_set_phase:%d\n",degree);*/ - if (phase->lock) - spin_lock_irqsave(phase->lock, flags); + u32 reg; + u32 shift; - /* Fetch the register value */ - reg = fh_pmu_get_reg(phase->reg); + if (!phase->mux) + return -EINVAL; - local_degree = degree; + shift = ffs(phase->mux) - 1; - shift = ffs(phase->mux)-1; + if (phase->lock) + spin_lock_irqsave(phase->lock, flags); - reg |= (local_degree << shift); + reg = fh_pmu_get_reg(phase->reg); + reg &= ~phase->mux; + reg |= ((u32)degree << shift) & phase->mux; + fh_pmu_set_reg(phase->reg, reg); - /* Apply them now */ - fh_pmu_set_reg(phase->reg, reg); if (phase->lock) spin_unlock_irqrestore(phase->lock, flags); - return 1; + return 0; } static int fh_clk_get_phase(struct clk_hw *hw) { - u32 reg; struct fh_clk_phase *phase = (struct fh_clk_phase *)hw; unsigned long flags = 0; - u32 local_degree = 0; + u32 reg; u32 shift; - if (phase->lock) - spin_lock_irqsave(phase->lock, flags); + if (!phase->mux) + return -EINVAL; - /* Fetch the register value */ - reg = fh_pmu_get_reg(phase->reg); - shift = ffs(phase->mux)-1; + shift = ffs(phase->mux) - 1; - reg = reg&(phase->mux) >> shift; - local_degree = reg; + if (phase->lock) + spin_lock_irqsave(phase->lock, flags); - /*printk("fh_clk_get_phase:%d\n",local_degree);*/ + reg = fh_pmu_get_reg(phase->reg); if (phase->lock) spin_unlock_irqrestore(phase->lock, flags); - return local_degree; + return (reg & phase->mux) >> shift; } diff --git a/drivers/pwm/pwm-fullhan-common.c b/drivers/pwm/pwm-fullhan-common.c index f9e8c24b24..981aa69f66 100644 --- a/drivers/pwm/pwm-fullhan-common.c +++ b/drivers/pwm/pwm-fullhan-common.c @@ -243,15 +243,25 @@ static int fh_pwm_wait_done(struct pwm_chip_data *pcd) static int fh_pwm_set_config(struct fh_pwm_chip_data *chip_data) { unsigned int clk_rate = clk_get_rate(fh_pwm_drv->clk); + unsigned int tick_ns; unsigned int ctrl = 0, period, duty, delay, phase, reg; unsigned int inverse = 0; - fh_pwm_config_disable(chip_data->id); + if (!clk_rate) { + pr_err("PWM: cannot configure with a zero clock rate\n"); + return -EINVAL; + } + + tick_ns = NSEC_PER_SEC / clk_rate; + if (!tick_ns) { + pr_err("PWM: clock rate is too high\n"); + return -EINVAL; + } - period = chip_data->config.period_ns / (NSEC_PER_SEC / clk_rate); - duty = chip_data->config.duty_ns / (NSEC_PER_SEC / clk_rate); - delay = chip_data->config.delay_ns / (NSEC_PER_SEC / clk_rate); - phase = chip_data->config.phase_ns / (NSEC_PER_SEC / clk_rate); + period = chip_data->config.period_ns / tick_ns; + duty = chip_data->config.duty_ns / tick_ns; + delay = chip_data->config.delay_ns / tick_ns; + phase = chip_data->config.phase_ns / tick_ns; if (period > 0x1ffffff) { pr_err("PWM: period exceed 24-bit\n"); @@ -283,6 +293,8 @@ static int fh_pwm_set_config(struct fh_pwm_chip_data *chip_data) } } + fh_pwm_config_disable(chip_data->id); + PRINT_DBG("set period: 0x%x\n", period); PRINT_DBG("set duty: 0x%x\n", duty); PRINT_DBG("set phase: 0x%x\n", phase); @@ -410,6 +422,7 @@ int fh_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, int duty_ns, int period_ns) { struct fh_pwm_chip_data *chip_data; + int ret; chip_data = kzalloc(sizeof(struct fh_pwm_chip_data), GFP_KERNEL); if (chip_data == NULL) { @@ -421,11 +434,11 @@ int fh_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm, chip_data->config.duty_ns = duty_ns; chip_data->config.period_ns = period_ns; - fh_pwm_set_config(chip_data); + ret = fh_pwm_set_config(chip_data); kfree(chip_data); - return 0; + return ret; } int fh_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)