From 7f04848221cf09a2bf8766bd64dfbd3e52febb27 Mon Sep 17 00:00:00 2001 From: carbon Date: Thu, 19 Oct 2023 16:39:21 +0800 Subject: [PATCH] buildroot: add duo-pinmux --- .../configs/milkv_duo_musl_riscv64_defconfig | 1 + buildroot-2021.05/package/Config.in | 1 + .../package/duo-pinmux/Config.in | 4 + .../package/duo-pinmux/duo-pinmux.mk | 14 ++ .../package/duo-pinmux/src/devmem.c | 105 ++++++++++ .../package/duo-pinmux/src/devmem.h | 12 ++ .../package/duo-pinmux/src/duo_pinmux.c | 193 ++++++++++++++++++ .../package/duo-pinmux/src/func.h | 188 +++++++++++++++++ 8 files changed, 518 insertions(+) create mode 100644 buildroot-2021.05/package/duo-pinmux/Config.in create mode 100644 buildroot-2021.05/package/duo-pinmux/duo-pinmux.mk create mode 100644 buildroot-2021.05/package/duo-pinmux/src/devmem.c create mode 100644 buildroot-2021.05/package/duo-pinmux/src/devmem.h create mode 100644 buildroot-2021.05/package/duo-pinmux/src/duo_pinmux.c create mode 100644 buildroot-2021.05/package/duo-pinmux/src/func.h diff --git a/buildroot-2021.05/configs/milkv_duo_musl_riscv64_defconfig b/buildroot-2021.05/configs/milkv_duo_musl_riscv64_defconfig index ebceb2e7d..d0a701b30 100644 --- a/buildroot-2021.05/configs/milkv_duo_musl_riscv64_defconfig +++ b/buildroot-2021.05/configs/milkv_duo_musl_riscv64_defconfig @@ -269,6 +269,7 @@ BR2_PACKAGE_BUSYBOX_CONFIG_FRAGMENT_FILES="" # BR2_PACKAGE_BUSYBOX_INDIVIDUAL_BINARIES is not set # BR2_PACKAGE_BUSYBOX_WATCHDOG is not set BR2_PACKAGE_WIRINGX=y +BR2_PACKAGE_DUO_PINMUX=y BR2_PACKAGE_SKELETON=y BR2_PACKAGE_HAS_SKELETON=y BR2_PACKAGE_PROVIDES_SKELETON="skeleton-init-sysv" diff --git a/buildroot-2021.05/package/Config.in b/buildroot-2021.05/package/Config.in index 0460f0eb4..e7e3235a9 100644 --- a/buildroot-2021.05/package/Config.in +++ b/buildroot-2021.05/package/Config.in @@ -2,6 +2,7 @@ menu "Target packages" source "package/busybox/Config.in" source "package/wiringx/Config.in" + source "package/duo-pinmux/Config.in" source "package/skeleton/Config.in" source "package/skeleton-custom/Config.in" source "package/skeleton-init-common/Config.in" diff --git a/buildroot-2021.05/package/duo-pinmux/Config.in b/buildroot-2021.05/package/duo-pinmux/Config.in new file mode 100644 index 000000000..e70507140 --- /dev/null +++ b/buildroot-2021.05/package/duo-pinmux/Config.in @@ -0,0 +1,4 @@ +config BR2_PACKAGE_DUO_PINMUX + bool "Duo pinmux" + help + Pinmux for Milk-V Duo diff --git a/buildroot-2021.05/package/duo-pinmux/duo-pinmux.mk b/buildroot-2021.05/package/duo-pinmux/duo-pinmux.mk new file mode 100644 index 000000000..4950b6440 --- /dev/null +++ b/buildroot-2021.05/package/duo-pinmux/duo-pinmux.mk @@ -0,0 +1,14 @@ +DUO_PINMUX_SITE = $(TOPDIR)/package/duo-pinmux/src +DUO_PINMUX_VERSION = 1.0.0 +DUO_PINMUX_SITE_METHOD = local + +define DUO_PINMUX_BUILD_CMDS + $(TARGET_MAKE_ENV) $(TARGET_CC) $(TARGET_CFLAGS) $(TARGET_LDFLAGS) \ + $(@D)/*.c -o $(@D)/duo-pinmux +endef + +define DUO_PINMUX_INSTALL_TARGET_CMDS + $(INSTALL) -D -m 0755 $(@D)/duo-pinmux $(TARGET_DIR)/usr/bin/ +endef + +$(eval $(generic-package)) diff --git a/buildroot-2021.05/package/duo-pinmux/src/devmem.c b/buildroot-2021.05/package/duo-pinmux/src/devmem.c new file mode 100644 index 000000000..2e37710cb --- /dev/null +++ b/buildroot-2021.05/package/duo-pinmux/src/devmem.c @@ -0,0 +1,105 @@ +/* + ** read/write phy addr in userspace + ** open /dev/mem + ** taiqiang.cao@bitmain.com + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "devmem.h" + +// DEBUG_SET_LEVEL(DEBUG_LEVEL_ERR); +#define ERR printf +#define DEBUG printf + +static int devmem_fd; + +void *devm_map(unsigned long addr, int len) +{ + off_t offset; + void *map_base; + + devmem_fd = open("/dev/mem", O_RDWR | O_SYNC); + if (devmem_fd == -1) { + ERR("cannot open '/dev/mem'\n"); + goto open_err; + } + // DEBUG("/dev/mem opened.\n"); + + offset = addr & ~(sysconf(_SC_PAGE_SIZE) - 1); + + map_base = mmap(NULL, len + addr - offset, PROT_READ | PROT_WRITE, MAP_SHARED, devmem_fd, offset); + if (map_base == MAP_FAILED) { + ERR("mmap failed\n"); + goto mmap_err; + } + + // DEBUG("Memory mapped at address %p.\n", map_base + addr - offset); + + return map_base + addr - offset; + +mmap_err: + close(devmem_fd); + +open_err: + return NULL; +} + +void devm_unmap(void *virt_addr, int len) +{ + unsigned long addr; + + if (devmem_fd == -1) { + ERR("'/dev/mem' is closed\n"); + return; + } + + /* page align */ + addr = (((unsigned long)virt_addr) & ~(sysconf(_SC_PAGE_SIZE) - 1)); + munmap((void *)addr, len + (unsigned long)virt_addr - addr); + close(devmem_fd); +} + +/* read/write 32bit data*/ +uint32_t devmem_readl(unsigned long addr) +{ + uint32_t val; + void *virt_addr; + + virt_addr = devm_map(addr, 4); + if (virt_addr == NULL) { + ERR("readl addr map failed\n"); + return 0; + } + + val = *(uint32_t *)virt_addr; + + devm_unmap(virt_addr, 4); + + return val; +} + +void devmem_writel(unsigned long addr, uint32_t val) +{ + void *virt_addr; + + virt_addr = devm_map(addr, 4); + if (virt_addr == NULL) { + ERR("writel addr map failed\n"); + return; + } + + *(uint32_t *)virt_addr = val; + + devm_unmap(virt_addr, 4); +} diff --git a/buildroot-2021.05/package/duo-pinmux/src/devmem.h b/buildroot-2021.05/package/duo-pinmux/src/devmem.h new file mode 100644 index 000000000..79fd8f9fb --- /dev/null +++ b/buildroot-2021.05/package/duo-pinmux/src/devmem.h @@ -0,0 +1,12 @@ +#ifndef _DEVMEM_H_ +#define _DEVMEM_H_ + +#include + +void *devm_map(unsigned long addr, int len); +void devm_unmap(void *virt_addr, int len); + +uint32_t devmem_readl(unsigned long addr); +void devmem_writel(unsigned long addr, uint32_t val); + +#endif diff --git a/buildroot-2021.05/package/duo-pinmux/src/duo_pinmux.c b/buildroot-2021.05/package/duo-pinmux/src/duo_pinmux.c new file mode 100644 index 000000000..00c64a92e --- /dev/null +++ b/buildroot-2021.05/package/duo-pinmux/src/duo_pinmux.c @@ -0,0 +1,193 @@ +#include "devmem.h" +#include "func.h" +#include +#include +#include +#include +#include + +#define NELEMS(x) (sizeof(x) / sizeof((x)[0])) +#define PINMUX_BASE 0x03001000 +#define INVALID_PIN 9999 + +struct pinlist { + char name[32]; + uint32_t offset; +} pinlist_st; + +struct pinlist cv180x_pin[] = { + { "GP0", 0x4c }, // IIC0_SCL + { "GP1", 0x50 }, // IIC0_SDA + { "GP2", 0x84 }, // SD1_GPIO1 + { "GP3", 0x88 }, // SD1_GPIO0 + { "GP4", 0x90 }, // SD1_D2 + { "GP5", 0x94 }, // SD1_D1 + { "GP6", 0xa0 }, // SD1_CLK + { "GP7", 0x9c }, // SD1_CMD + { "GP8", 0x98 }, // SD1_D0 + { "GP9", 0x8c }, // SD1_D3 + { "GP10", 0xf0 }, // PAD_MIPIRX1P + { "GP11", 0xf4 }, // PAD_MIPIRX0N + { "GP12", 0x24 }, // UART0_TX + { "GP13", 0x28 }, // UART0_RX + { "GP14", 0x1c }, // SD0_PWR_EN + { "GP15", 0x20 }, // SPK_EN + { "GP16", 0x3c }, // SPINOR_MISO + { "GP17", 0x40 }, // SPINOR_CS_X + { "GP18", 0x30 }, // SPINOR_SCK + { "GP19", 0x34 }, // SPINOR_MOSI + { "GP20", 0x38 }, // SPINOR_WP_X + { "GP21", 0x2c }, // SPINOR_HOLD_X + { "GP22", 0x68 }, // PWR_SEQ2 + { "GP26", 0xa8 }, // ADC1 + { "GP27", 0xac }, // USB_VBUS_DET + + { "GP25", 0x12c }, // PAD_AUD_AOUTR +}; + +uint32_t convert_func_to_value(char *pin, char *func) +{ + uint32_t i = 0; + uint32_t max_fun_num = NELEMS(cv180x_pin_func); + char v; + + for (i = 0; i < max_fun_num; i++) { + if (strcmp(cv180x_pin_func[i].func, func) == 0) { + if (strncmp(cv180x_pin_func[i].name, pin, strlen(pin)) == 0) { + v = cv180x_pin_func[i].name[strlen(cv180x_pin_func[i].name) - 1]; + break; + } + } + } + + if (i == max_fun_num) { + printf("ERROR: invalid pin or func\n"); + return INVALID_PIN; + } + + return (v - 0x30); +} + +void print_fun(char *name, uint32_t value) +{ + uint32_t i = 0; + uint32_t max_fun_num = NELEMS(cv180x_pin_func); + char pinname[128]; + + sprintf(pinname, "%s%d", name, value); + + printf("%s function:\n", name); + for (i = 0; i < max_fun_num; i++) { + if (strlen(cv180x_pin_func[i].name) != (strlen(name) + 1)) { + continue; + } + if (strncmp(pinname, cv180x_pin_func[i].name, strlen(name)) == 0) { + if (strcmp(pinname, cv180x_pin_func[i].name) == 0) + printf("[v] %s\n", cv180x_pin_func[i].func); + else + printf("[ ] %s\n", cv180x_pin_func[i].func); + // break; + } + } + printf("\n"); +} + +void print_usage(const char *prog) +{ + printf("pinmux for duo\n"); + printf("%s -p <== List all pins\n", prog); + printf("%s -l <== List all pins and its func\n", prog); + printf("%s -r pin <== Get func from pin\n", prog); + printf("%s -w pin/func <== Set func to pin\n", prog); +} + +int main(int argc, char *argv[]) +{ + int opt = 0; + uint32_t i = 0; + uint32_t value; + char pin[32]; + char func[32]; + uint32_t f_val; + + if (argc == 1) { + print_usage(argv[0]); + return 1; + } + + while ((opt = getopt(argc, argv, "hplr:w:")) != -1) { + switch (opt) { + case 'r': + for (i = 0; i < NELEMS(cv180x_pin); i++) { + if (strcmp(optarg, cv180x_pin[i].name) == 0) + break; + } + if (i != NELEMS(cv180x_pin)) { + value = devmem_readl(PINMUX_BASE + cv180x_pin[i].offset); + // printf("value %d\n", value); + print_fun(optarg, value); + + printf("register: 0x%x\n", PINMUX_BASE + cv180x_pin[i].offset); + printf("value: %d\n", value); + } else { + printf("\nInvalid option: %s", optarg); + } + break; + + case 'w': + // printf("optarg %s\n", optarg); + if (sscanf(optarg, "%[^/]/%s", pin, func) != 2) + print_usage(argv[0]); + + printf("pin %s\n", pin); + printf("func %s\n", func); + + for (i = 0; i < NELEMS(cv180x_pin); i++) { + if (strcmp(pin, cv180x_pin[i].name) == 0) + break; + } + + if (i != NELEMS(cv180x_pin)) { + f_val = convert_func_to_value(pin, func); + if (f_val == INVALID_PIN) + return 1; + devmem_writel(PINMUX_BASE + cv180x_pin[i].offset, f_val); + + printf("register: %x\n", PINMUX_BASE + cv180x_pin[i].offset); + printf("value: %d\n", f_val); + // printf("value %d\n", value); + } else { + printf("\nInvalid option: %s\n", optarg); + } + break; + + case 'p': + printf("Pinlist:\n"); + for (i = 0; i < NELEMS(cv180x_pin); i++) + printf("%s\n", cv180x_pin[i].name); + break; + + case 'l': + for (i = 0; i < NELEMS(cv180x_pin); i++) { + value = devmem_readl(PINMUX_BASE + cv180x_pin[i].offset); + // printf("value %d\n", value); + print_fun(cv180x_pin[i].name, value); + } + break; + + case 'h': + print_usage(argv[0]); + break; + + case '?': + print_usage(argv[0]); + break; + + default: + print_usage(argv[0]); + break; + } + } + + return 0; +} diff --git a/buildroot-2021.05/package/duo-pinmux/src/func.h b/buildroot-2021.05/package/duo-pinmux/src/func.h new file mode 100644 index 000000000..4a1253e93 --- /dev/null +++ b/buildroot-2021.05/package/duo-pinmux/src/func.h @@ -0,0 +1,188 @@ +struct funlist { + char name[32]; + char func[32]; +} funlist_st; + +struct funlist cv180x_pin_func[] = { + // GP0 IIC0_SCL + { "GP00", "JTAG_TDI"}, + { "GP01", "UART1_TX"}, + { "GP02", "UART2_TX"}, + { "GP03", "GP0"}, + { "GP04", "IIC0_SCL"}, + { "GP05", "WG0_D0"}, + { "GP07", "DBG_10"}, + + // GP1 IIC0_SDA + { "GP10", "JTAG_TDO"}, + { "GP11", "UART1_RX"}, + { "GP12", "UART2_RX"}, + { "GP13", "GP1"}, + { "GP14", "IIC0_SDA"}, + { "GP15", "WG0_D1"}, + { "GP16", "WG1_D0"}, + { "GP17", "DBG_11"}, + + // GP2 SD1_GPIO1 + { "GP21", "UART4_TX"}, + { "GP23", "GP2"}, + { "GP27", "PWM_10"}, + + // GP3 SD1_GPIO0 + { "GP31", "UART4_RX"}, + { "GP33", "GP3"}, + { "GP37", "PWM_11"}, + + // GP4 SD1_D2 + { "GP40", "PWR_SD1_D2"}, + { "GP41", "IIC1_SCL"}, + { "GP42", "UART2_TX"}, + { "GP43", "GP4"}, + { "GP44", "CAM_MCLK0"}, + { "GP45", "UART3_TX"}, + { "GP46", "PWR_SPINOR1_HOLD_X"}, + { "GP47", "PWM_5"}, + + // GP5 SD1_D1 + { "GP50", "PWR_SD1_D1"}, + { "GP51", "IIC1_SDA"}, + { "GP52", "UART2_RX"}, + { "GP53", "GP5"}, + { "GP54", "CAM_MCLK1"}, + { "GP55", "UART3_RX"}, + { "GP56", "PWR_SPINOR1_WP_X"}, + { "GP57", "PWM_6"}, + + // GP6 SD1_CLK + { "GP60", "PWR_SD1_CLK"}, + { "GP61", "SPI2_SCK"}, + { "GP62", "IIC3_SDA"}, + { "GP63", "GP6"}, + { "GP64", "CAM_HS0"}, + { "GP65", "EPHY_SPD_LED"}, + { "GP66", "PWR_SPINOR1_SCK"}, + { "GP67", "PWM_9"}, + + // GP7 SD1_CMD + { "GP70", "PWR_SD1_CMD"}, + { "GP71", "SPI2_SDO"}, + { "GP72", "IIC3_SCL"}, + { "GP73", "GP7"}, + { "GP74", "CAM_VS0"}, + { "GP75", "EPHY_LNK_LED"}, + { "GP76", "PWR_SPINOR1_MOSI"}, + { "GP77", "PWM_8"}, + + // GP8 SD1_D0 + { "GP80", "PWR_SD1_D0"}, + { "GP81", "SPI2_SDI"}, + { "GP82", "IIC1_SDA"}, + { "GP83", "GP8"}, + { "GP84", "CAM_MCLK1"}, + { "GP85", "UART3_RTS"}, + { "GP86", "PWR_SPINOR1_MISO"}, + { "GP87", "PWM_7"}, + + // GP9 SD1_D3 + { "GP90", "PWR_SD1_D3"}, + { "GP91", "SPI2_CS_X"}, + { "GP92", "IIC1_SCL"}, + { "GP93", "GP9"}, + { "GP94", "CAM_MCLK0"}, + { "GP95", "UART3_CTS"}, + { "GP96", "PWR_SPINOR1_CS_X"}, + { "GP97", "PWM_4"}, + + // GP10 PAD_MIPIRX1P + { "GP101", "VI0_D_6"}, + { "GP103", "GP10"}, + { "GP104", "IIC1_SDA"}, + { "GP106", "KEY_ROW2"}, + { "GP107", "DBG_9"}, + + // GP11 PAD_MIPIRX0N + { "GP111", "VI0_D_7"}, + { "GP113", "GP11"}, + { "GP114", "IIC1_SCL"}, + { "GP115", "CAM_MCLK1"}, + { "GP117", "DBG_10"}, + + // GP12 UART0_TX + { "GP120", "UART0_TX"}, + { "GP121", "CAM_MCLK1"}, + { "GP122", "PWM_4"}, + { "GP123", "GP12"}, + { "GP124", "UART1_TX"}, + { "GP125", "AUX1"}, + { "GP126", "JTAG_TMS"}, + { "GP127", "DBG_6"}, + + // GP13 UART0_RX + { "GP130", "UART0_RX"}, + { "GP131", "CAM_MCLK0"}, + { "GP132", "PWM_5"}, + { "GP133", "GP13"}, + { "GP134", "UART1_RX"}, + { "GP135", "AUX0"}, + { "GP136", "JTAG_TCK"}, + { "GP137", "DBG_7"}, + + // GP14 SD0_PWR_EN + { "GP140", "SDIO0_PWR_EN"}, + { "GP143", "GP14"}, + + // GP15 SPK_EN + { "GP153", "GP15"}, + + // GP16 SPINOR_MISO + { "GP161", "SPINOR_MISO"}, + { "GP162", "SPINAND_MISO"}, + { "GP163", "GP16"}, + + // GP17 SPINOR_CS_X + { "GP171", "SPINOR_CS_X"}, + { "GP172", "SPINAND_CS"}, + { "GP173", "GP17"}, + + // GP18 SPINOR_SCK + { "GP181", "SPINOR_SCK"}, + { "GP182", "SPINAND_CLK"}, + { "GP183", "GP18"}, + + // GP19 SPINOR_MOSI + { "GP191", "SPINOR_MOSI"}, + { "GP192", "SPINAND_MOSI"}, + { "GP193", "GP19"}, + + // GP20 SPINOR_WP_X + { "GP201", "SPINOR_WP_X"}, + { "GP202", "SPINAND_WP"}, + { "GP203", "GP20"}, + + // GP21 SPINOR_HOLD_X + { "GP211", "SPINOR_HOLD_X"}, + { "GP212", "SPINAND_HOLD"}, + { "GP213", "GP21"}, + + // GP22 PWR_SEQ2 + { "GP220", "PWR_SEQ2"}, + { "GP223", "GP22"}, + + // GP25 PAD_AUD_AOUTR + { "GP253", "GP25"}, + { "GP254", "IIS1_DI"}, + { "GP255", "IIS2_DO"}, + { "GP256", "IIS1_DO"}, + + // GP26 ADC1 + { "GP263", "GP26"}, + { "GP264", "KEY_COL2"}, + { "GP266", "PWM_3"}, + + // GP27 USB_VBUS_DET + { "GP270", "USB_VBUS_DET"}, + { "GP273", "GP27"}, + { "GP274", "CAM_MCLK0"}, + { "GP275", "CAM_MCLK1"}, + { "GP276", "PWM_4"}, +};