Commit 8a954eb695326eb406c4a548bb686190fea82bca
Committed by
Tom Rini
1 parent
8293009baa
Exists in
v2017.01-smarct4x
and in
33 other branches
hisilicon: hi6220: Add a hi6220 pinmux driver.
This patch adds basic pinmux support for the hi6220 SoC, which is found on the hikey board. Signed-off-by: Peter Griffin <peter.griffin@linaro.org>
Showing 5 changed files with 305 additions and 0 deletions Side-by-side Diff
arch/arm/cpu/armv8/Makefile
arch/arm/cpu/armv8/hisilicon/Makefile
arch/arm/cpu/armv8/hisilicon/pinmux.c
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Linaro. | |
| 3 | + * Peter Griffin <peter.griffin@linaro.org> | |
| 4 | + * | |
| 5 | + * SPDX-License-Identifier: GPL-2.0+ | |
| 6 | + */ | |
| 7 | + | |
| 8 | +#include <common.h> | |
| 9 | +#include <fdtdec.h> | |
| 10 | +#include <asm/gpio.h> | |
| 11 | +#include <asm/io.h> | |
| 12 | +#include <asm/arch/pinmux.h> | |
| 13 | + | |
| 14 | +struct hi6220_pinmux0_regs *pmx0 = | |
| 15 | + (struct hi6220_pinmux0_regs *)HI6220_PINMUX0_BASE; | |
| 16 | + | |
| 17 | +struct hi6220_pinmux1_regs *pmx1 = | |
| 18 | + (struct hi6220_pinmux1_regs *)HI6220_PINMUX1_BASE; | |
| 19 | + | |
| 20 | +static void hi6220_uart_config(int peripheral) | |
| 21 | +{ | |
| 22 | + switch (peripheral) { | |
| 23 | + case PERIPH_ID_UART0: | |
| 24 | + writel(MUX_M0, &pmx0->iomg[48]); /* UART0_RXD */ | |
| 25 | + writel(MUX_M0, &pmx0->iomg[49]); /* UART0_TXD */ | |
| 26 | + | |
| 27 | + writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[49]); /* UART0_RXD */ | |
| 28 | + writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[50]); /* UART0_TXD */ | |
| 29 | + break; | |
| 30 | + | |
| 31 | + case PERIPH_ID_UART1: | |
| 32 | + writel(MUX_M0, &pmx0->iomg[50]); /* UART1_CTS_N */ | |
| 33 | + writel(MUX_M0, &pmx0->iomg[51]); /* UART1_RTS_N */ | |
| 34 | + writel(MUX_M0, &pmx0->iomg[52]); /* UART1_RXD */ | |
| 35 | + writel(MUX_M0, &pmx0->iomg[53]); /* UART1_TXD */ | |
| 36 | + | |
| 37 | + writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[51]); /*UART1_CTS_N*/ | |
| 38 | + writel(DRIVE1_02MA | PULL_UP, &pmx1->iocfg[53]); /* UART1_RXD */ | |
| 39 | + writel(DRIVE1_02MA, &pmx1->iocfg[52]); /* UART1_RTS_N */ | |
| 40 | + writel(DRIVE1_02MA, &pmx1->iocfg[54]); /* UART1_TXD */ | |
| 41 | + break; | |
| 42 | + | |
| 43 | + case PERIPH_ID_UART2: | |
| 44 | + writel(MUX_M0, &pmx0->iomg[54]); /* UART2_CTS_N */ | |
| 45 | + writel(MUX_M0, &pmx0->iomg[55]); /* UART2_RTS_N */ | |
| 46 | + writel(MUX_M0, &pmx0->iomg[56]); /* UART2_RXD */ | |
| 47 | + writel(MUX_M0, &pmx0->iomg[57]); /* UART2_TXD */ | |
| 48 | + | |
| 49 | + writel(DRIVE1_02MA, &pmx1->iocfg[55]); /* UART2_CTS_N */ | |
| 50 | + writel(DRIVE1_02MA, &pmx1->iocfg[56]); /* UART2_RTS_N */ | |
| 51 | + writel(DRIVE1_02MA, &pmx1->iocfg[57]); /* UART2_RXD */ | |
| 52 | + writel(DRIVE1_02MA, &pmx1->iocfg[58]); /* UART2_TXD */ | |
| 53 | + break; | |
| 54 | + | |
| 55 | + case PERIPH_ID_UART3: | |
| 56 | + writel(MUX_M1, &pmx0->iomg[96]); /* UART3_CTS_N */ | |
| 57 | + writel(MUX_M1, &pmx0->iomg[97]); /* UART3_RTS_N */ | |
| 58 | + writel(MUX_M1, &pmx0->iomg[98]); /* UART3_RXD */ | |
| 59 | + writel(MUX_M1, &pmx0->iomg[99]); /* UART3_TXD */ | |
| 60 | + | |
| 61 | + /* UART3_TXD */ | |
| 62 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[100]); | |
| 63 | + /* UART3_RTS_N */ | |
| 64 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[101]); | |
| 65 | + /* UART3_RXD */ | |
| 66 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[102]); | |
| 67 | + /* UART3_TXD */ | |
| 68 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[103]); | |
| 69 | + break; | |
| 70 | + | |
| 71 | + case PERIPH_ID_UART4: | |
| 72 | + writel(MUX_M1, &pmx0->iomg[116]); /* UART4_CTS_N */ | |
| 73 | + writel(MUX_M1, &pmx0->iomg[117]); /* UART4_RTS_N */ | |
| 74 | + writel(MUX_M1, &pmx0->iomg[118]); /* UART4_RXD */ | |
| 75 | + writel(MUX_M1, &pmx0->iomg[119]); /* UART4_TXD */ | |
| 76 | + | |
| 77 | + /* UART4_CTS_N */ | |
| 78 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[120]); | |
| 79 | + /* UART4_RTS_N */ | |
| 80 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[121]); | |
| 81 | + /* UART4_RXD */ | |
| 82 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[122]); | |
| 83 | + /* UART4_TXD */ | |
| 84 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[123]); | |
| 85 | + break; | |
| 86 | + case PERIPH_ID_UART5: | |
| 87 | + writel(MUX_M1, &pmx0->iomg[114]); /* UART5_RXD */ | |
| 88 | + writel(MUX_M1, &pmx0->iomg[115]); /* UART5_TXD */ | |
| 89 | + | |
| 90 | + /* UART5_RXD */ | |
| 91 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[118]); | |
| 92 | + /* UART5_TXD */ | |
| 93 | + writel(DRIVE1_02MA | PULL_DOWN, &pmx1->iocfg[119]); | |
| 94 | + | |
| 95 | + break; | |
| 96 | + | |
| 97 | + default: | |
| 98 | + debug("%s: invalid peripheral %d", __func__, peripheral); | |
| 99 | + return; | |
| 100 | + } | |
| 101 | +} | |
| 102 | + | |
| 103 | +static int hi6220_mmc_config(int peripheral) | |
| 104 | +{ | |
| 105 | + u32 tmp; | |
| 106 | + | |
| 107 | + switch (peripheral) { | |
| 108 | + case PERIPH_ID_SDMMC0: | |
| 109 | + | |
| 110 | + /* eMMC pinmux config */ | |
| 111 | + writel(MUX_M0, &pmx0->iomg[64]); /* EMMC_CLK */ | |
| 112 | + writel(MUX_M0, &pmx0->iomg[65]); /* EMMC_CMD */ | |
| 113 | + writel(MUX_M0, &pmx0->iomg[66]); /* EMMC_DATA0 */ | |
| 114 | + writel(MUX_M0, &pmx0->iomg[67]); /* EMMC_DATA1 */ | |
| 115 | + writel(MUX_M0, &pmx0->iomg[68]); /* EMMC_DATA2 */ | |
| 116 | + writel(MUX_M0, &pmx0->iomg[69]); /* EMMC_DATA3 */ | |
| 117 | + writel(MUX_M0, &pmx0->iomg[70]); /* EMMC_DATA4 */ | |
| 118 | + writel(MUX_M0, &pmx0->iomg[71]); /* EMMC_DATA5 */ | |
| 119 | + writel(MUX_M0, &pmx0->iomg[72]); /* EMMC_DATA6 */ | |
| 120 | + writel(MUX_M0, &pmx0->iomg[73]); /* EMMC_DATA7 */ | |
| 121 | + | |
| 122 | + /*eMMC configure up/down/drive */ | |
| 123 | + writel(DRIVE1_08MA, &pmx1->iocfg[65]); /* EMMC_CLK */ | |
| 124 | + | |
| 125 | + tmp = DRIVE1_04MA | PULL_UP; | |
| 126 | + writel(tmp, &pmx1->iocfg[65]); /* EMMC_CMD */ | |
| 127 | + writel(tmp, &pmx1->iocfg[66]); /* EMMC_DATA0 */ | |
| 128 | + writel(tmp, &pmx1->iocfg[67]); /* EMMC_DATA1 */ | |
| 129 | + writel(tmp, &pmx1->iocfg[68]); /* EMMC_DATA2 */ | |
| 130 | + writel(tmp, &pmx1->iocfg[69]); /* EMMC_DATA3 */ | |
| 131 | + writel(tmp, &pmx1->iocfg[70]); /* EMMC_DATA4 */ | |
| 132 | + writel(tmp, &pmx1->iocfg[71]); /* EMMC_DATA5 */ | |
| 133 | + writel(tmp, &pmx1->iocfg[72]); /* EMMC_DATA6 */ | |
| 134 | + writel(tmp, &pmx1->iocfg[73]); /* EMMC_DATA7 */ | |
| 135 | + | |
| 136 | + writel(DRIVE1_04MA, &pmx1->iocfg[73]); /* EMMC_RST_N */ | |
| 137 | + break; | |
| 138 | + | |
| 139 | + case PERIPH_ID_SDMMC1: | |
| 140 | + | |
| 141 | + writel(MUX_M0, &pmx0->iomg[3]); /* SD_CLK */ | |
| 142 | + writel(MUX_M0, &pmx0->iomg[4]); /* SD_CMD */ | |
| 143 | + writel(MUX_M0, &pmx0->iomg[5]); /* SD_DATA0 */ | |
| 144 | + writel(MUX_M0, &pmx0->iomg[6]); /* SD_DATA1 */ | |
| 145 | + writel(MUX_M0, &pmx0->iomg[7]); /* SD_DATA2 */ | |
| 146 | + writel(MUX_M0, &pmx0->iomg[8]); /* SD_DATA3 */ | |
| 147 | + | |
| 148 | + writel(DRIVE1_10MA | BIT(2), &pmx1->iocfg[3]); /*SD_CLK*/ | |
| 149 | + writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[4]); /*SD_CMD*/ | |
| 150 | + writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[5]); /*SD_DATA0*/ | |
| 151 | + writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[6]); /*SD_DATA1*/ | |
| 152 | + writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[7]); /*SD_DATA2*/ | |
| 153 | + writel(DRIVE1_08MA | BIT(2), &pmx1->iocfg[8]); /*SD_DATA3*/ | |
| 154 | + break; | |
| 155 | + | |
| 156 | + default: | |
| 157 | + debug("%s: invalid peripheral %d", __func__, peripheral); | |
| 158 | + return -1; | |
| 159 | + } | |
| 160 | + | |
| 161 | + return 0; | |
| 162 | +} | |
| 163 | + | |
| 164 | +int hi6220_pinmux_config(int peripheral) | |
| 165 | +{ | |
| 166 | + switch (peripheral) { | |
| 167 | + case PERIPH_ID_UART0: | |
| 168 | + case PERIPH_ID_UART1: | |
| 169 | + case PERIPH_ID_UART2: | |
| 170 | + case PERIPH_ID_UART3: | |
| 171 | + hi6220_uart_config(peripheral); | |
| 172 | + break; | |
| 173 | + case PERIPH_ID_SDMMC0: | |
| 174 | + case PERIPH_ID_SDMMC1: | |
| 175 | + return hi6220_mmc_config(peripheral); | |
| 176 | + default: | |
| 177 | + debug("%s: invalid peripheral %d", __func__, peripheral); | |
| 178 | + return -1; | |
| 179 | + } | |
| 180 | + | |
| 181 | + return 0; | |
| 182 | +} |
arch/arm/include/asm/arch-hi6220/periph.h
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Linaro | |
| 3 | + * Peter Griffin <peter.griffin@linaro.org> | |
| 4 | + * | |
| 5 | + * SPDX-License-Identifier: GPL-2.0+ | |
| 6 | + */ | |
| 7 | + | |
| 8 | +#ifndef __ASM_ARM_ARCH_PERIPH_H | |
| 9 | +#define __ASM_ARM_ARCH_PERIPH_H | |
| 10 | + | |
| 11 | +/* | |
| 12 | + * Peripherals required for pinmux configuration. List will | |
| 13 | + * grow with support for more devices getting added. | |
| 14 | + * Numbering based on interrupt table. | |
| 15 | + * | |
| 16 | + */ | |
| 17 | +enum periph_id { | |
| 18 | + PERIPH_ID_UART0 = 36, | |
| 19 | + PERIPH_ID_UART1, | |
| 20 | + PERIPH_ID_UART2, | |
| 21 | + PERIPH_ID_UART3, | |
| 22 | + PERIPH_ID_UART4, | |
| 23 | + PERIPH_ID_UART5, | |
| 24 | + PERIPH_ID_SDMMC0 = 72, | |
| 25 | + PERIPH_ID_SDMMC1, | |
| 26 | + | |
| 27 | + PERIPH_ID_NONE = -1, | |
| 28 | +}; | |
| 29 | + | |
| 30 | +#endif /* __ASM_ARM_ARCH_PERIPH_H */ |
arch/arm/include/asm/arch-hi6220/pinmux.h
| 1 | +/* | |
| 2 | + * Copyright (C) 2015 Linaro | |
| 3 | + * Peter Griffin <peter.griffin@linaro.org> | |
| 4 | + * | |
| 5 | + * SPDX-License-Identifier: GPL-2.0+ | |
| 6 | + */ | |
| 7 | + | |
| 8 | +#ifndef __ASM_ARM_ARCH_PINMUX_H | |
| 9 | +#define __ASM_ARM_ARCH_PINMUX_H | |
| 10 | + | |
| 11 | +#include "periph.h" | |
| 12 | + | |
| 13 | + | |
| 14 | +/* iomg bit definition */ | |
| 15 | +#define MUX_M0 0 | |
| 16 | +#define MUX_M1 1 | |
| 17 | +#define MUX_M2 2 | |
| 18 | +#define MUX_M3 3 | |
| 19 | +#define MUX_M4 4 | |
| 20 | +#define MUX_M5 5 | |
| 21 | +#define MUX_M6 6 | |
| 22 | +#define MUX_M7 7 | |
| 23 | + | |
| 24 | +/* iocg bit definition */ | |
| 25 | +#define PULL_MASK (3) | |
| 26 | +#define PULL_DIS (0) | |
| 27 | +#define PULL_UP (1 << 0) | |
| 28 | +#define PULL_DOWN (1 << 1) | |
| 29 | + | |
| 30 | +/* drive strength definition */ | |
| 31 | +#define DRIVE_MASK (7 << 4) | |
| 32 | +#define DRIVE1_02MA (0 << 4) | |
| 33 | +#define DRIVE1_04MA (1 << 4) | |
| 34 | +#define DRIVE1_08MA (2 << 4) | |
| 35 | +#define DRIVE1_10MA (3 << 4) | |
| 36 | +#define DRIVE2_02MA (0 << 4) | |
| 37 | +#define DRIVE2_04MA (1 << 4) | |
| 38 | +#define DRIVE2_08MA (2 << 4) | |
| 39 | +#define DRIVE2_10MA (3 << 4) | |
| 40 | +#define DRIVE3_04MA (0 << 4) | |
| 41 | +#define DRIVE3_08MA (1 << 4) | |
| 42 | +#define DRIVE3_12MA (2 << 4) | |
| 43 | +#define DRIVE3_16MA (3 << 4) | |
| 44 | +#define DRIVE3_20MA (4 << 4) | |
| 45 | +#define DRIVE3_24MA (5 << 4) | |
| 46 | +#define DRIVE3_32MA (6 << 4) | |
| 47 | +#define DRIVE3_40MA (7 << 4) | |
| 48 | +#define DRIVE4_02MA (0 << 4) | |
| 49 | +#define DRIVE4_04MA (2 << 4) | |
| 50 | +#define DRIVE4_08MA (4 << 4) | |
| 51 | +#define DRIVE4_10MA (6 << 4) | |
| 52 | + | |
| 53 | +#define HI6220_PINMUX0_BASE 0xf7010000 | |
| 54 | +#define HI6220_PINMUX1_BASE 0xf7010800 | |
| 55 | + | |
| 56 | +#ifndef __ASSEMBLY__ | |
| 57 | + | |
| 58 | +/* maybe more registers, but highest used is 123 */ | |
| 59 | +#define REG_NUM 123 | |
| 60 | + | |
| 61 | +struct hi6220_pinmux0_regs { | |
| 62 | + uint32_t iomg[REG_NUM]; | |
| 63 | +}; | |
| 64 | + | |
| 65 | +struct hi6220_pinmux1_regs { | |
| 66 | + uint32_t iocfg[REG_NUM]; | |
| 67 | +}; | |
| 68 | + | |
| 69 | +#endif | |
| 70 | + | |
| 71 | +/** | |
| 72 | + * Configures the pinmux for a particular peripheral. | |
| 73 | + * | |
| 74 | + * This function will configure the peripheral pinmux along with | |
| 75 | + * pull-up/down and drive strength. | |
| 76 | + * | |
| 77 | + * @param peripheral peripheral to be configured | |
| 78 | + * @return 0 if ok, -1 on error (e.g. unsupported peripheral) | |
| 79 | + */ | |
| 80 | +int hi6220_pinmux_config(int peripheral); | |
| 81 | + | |
| 82 | +#endif |