diff --git a/arch/arm/mach-fh/Kconfig b/arch/arm/mach-fh/Kconfig index 3518d065dc..b693595964 100644 --- a/arch/arm/mach-fh/Kconfig +++ b/arch/arm/mach-fh/Kconfig @@ -68,6 +68,19 @@ endif choice prompt "Board" +config ARCH_FH8626V100 + bool "Fullhan FH8626V100" + depends on !USE_OF + 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 +94,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 +102,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/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/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..981aa69f66 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 @@ -238,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"); @@ -278,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); @@ -343,6 +360,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 +402,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; @@ -391,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) { @@ -402,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) @@ -527,7 +559,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 +582,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 +618,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 +794,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; }