diff --git a/arch/riscv/Kconfig.socs b/arch/riscv/Kconfig.socs index fc05047f7bab..e4b0826c2625 100644 --- a/arch/riscv/Kconfig.socs +++ b/arch/riscv/Kconfig.socs @@ -176,6 +176,19 @@ config SPACEMIT_ERRATA_LOAD_ATOMIC help This enable fix errata caused by readforward and writeback. +config SPACEMIT_K1_PCIE_USR_MISALIGNED + bool "process user space misaligned access on PCIe Slave IO Area" + depends on SOC_SPACEMIT_K1X + default y + help + The PCIe controller in Spacemit K1 does not support discontinuous + write operations with AXI bus-generated wstrb signals. Consequently, + the PCIe slave memory space is mapped as IO attributes. However, + when user-space programs perform unaligned memory accesses in this + IO-attributed space, memory access faults occur. Specialized handling + for this specific error type is implemented to ensure proper execution + of user-space programs. + endif endmenu # "SoC selection" diff --git a/arch/riscv/boot/dts/spacemit/k1-x.dtsi b/arch/riscv/boot/dts/spacemit/k1-x.dtsi index d9d0c4e8f624..4500e30a46f7 100644 --- a/arch/riscv/boot/dts/spacemit/k1-x.dtsi +++ b/arch/riscv/boot/dts/spacemit/k1-x.dtsi @@ -2372,8 +2372,7 @@ #address-cells = <3>; #size-cells = <2>; ranges = <0x01000000 0x0 0xb7002000 0 0xb7002000 0x0 0x100000>, - <0x42000000 0x0 0xa0000000 0 0xa0000000 0x0 0x10000000>, - <0x02000000 0x0 0xb0000000 0 0xb0000000 0x0 0x7000000>; + <0x2000000 0x0 0xa0000000 0 0xa0000000 0x0 0x17000000>; interconnects = <&dram_range7>; interconnect-names = "dma-mem"; @@ -2731,6 +2730,7 @@ sound_hdmi: snd-card@0 { compatible = "spacemit,simple-audio-card"; simple-audio-card,name = "snd-hdmi"; + simple-audio-card,playback_only; status = "disabled"; interconnects = <&dram_range4>; interconnect-names = "dma-mem"; diff --git a/arch/riscv/boot/dts/spacemit/k1-x_lpi3a.dts b/arch/riscv/boot/dts/spacemit/k1-x_lpi3a.dts index c4bbfe2212fd..3e6e94eec012 100644 --- a/arch/riscv/boot/dts/spacemit/k1-x_lpi3a.dts +++ b/arch/riscv/boot/dts/spacemit/k1-x_lpi3a.dts @@ -1248,7 +1248,8 @@ sound-dai = <&es7210_audio_codec>; }; };*/ - //simple-audio-card,name = "snd-es8326"; + simple-audio-card,name = "snd-es8156"; + simple-audio-card,playback_only; spacemit,mclk-fs = <64>; simple-audio-card,codec { sound-dai = <&es8156_audio_codec>; diff --git a/arch/riscv/configs/k1_defconfig b/arch/riscv/configs/k1_defconfig index f2d92eaf6397..302410d2f245 100644 --- a/arch/riscv/configs/k1_defconfig +++ b/arch/riscv/configs/k1_defconfig @@ -897,6 +897,10 @@ CONFIG_SPACEMIT_K1X_VIR_CAMERA=y # CONFIG_DVB_SP2 is not set CONFIG_DRM_RADEON=m CONFIG_DRM_RADEON_USERPTR=y +CONFIG_DRM_AMDGPU=m +CONFIG_DRM_AMDGPU_SI=y +CONFIG_DRM_AMDGPU_CIK=y +CONFIG_DRM_AMDGPU_USERPTR=y CONFIG_DRM_SPACEMIT=y CONFIG_SPACEMIT_MIPI_PANEL=y CONFIG_SPACEMIT_HDMI=y diff --git a/arch/riscv/kernel/cpu.c b/arch/riscv/kernel/cpu.c index ebef4e101f7b..aec93f57fb7e 100644 --- a/arch/riscv/kernel/cpu.c +++ b/arch/riscv/kernel/cpu.c @@ -235,7 +235,11 @@ arch_initcall(riscv_cpuinfo_init); #ifdef CONFIG_PROC_FS +#ifdef CONFIG_SOC_SPACEMIT +static void print_isa(struct seq_file *f, unsigned long cpu_id) +#else static void print_isa(struct seq_file *f) +#endif { seq_puts(f, "isa\t\t: "); @@ -255,6 +259,10 @@ static void print_isa(struct seq_file *f) seq_printf(f, "%s", riscv_isa_ext[i].name); } +#ifdef CONFIG_SOC_SPACEMIT + if(cpumask_test_cpu(cpu_id, &ai_cpu_mask)) + seq_printf(f, "_ime"); +#endif seq_puts(f, "\n"); } @@ -313,7 +321,11 @@ static int c_show(struct seq_file *m, void *v) if (!of_property_read_string(node, "model", &model)) seq_printf(m, "model name\t: %s\n", model); +#ifdef CONFIG_SOC_SPACEMIT + print_isa(m, cpu_id); +#else print_isa(m); +#endif print_mmu(m); if (acpi_disabled) { diff --git a/arch/riscv/kernel/traps.c b/arch/riscv/kernel/traps.c index 590729a8cc11..c257bf5e1e68 100644 --- a/arch/riscv/kernel/traps.c +++ b/arch/riscv/kernel/traps.c @@ -211,8 +211,63 @@ asmlinkage __visible __trap_section void do_trap_insn_illegal(struct pt_regs *re } } +#ifdef CONFIG_SPACEMIT_K1_PCIE_USR_MISALIGNED + +#define SPACEMIT_K1_PCIE_DATA_LOW (0x80000000) +#define SPACEMIT_K1_PCIE_DATA_HIGH (0xB7FFFFFF) + +static int check_if_user_io_area_misaligned(struct pt_regs *regs) +{ + pte_t *ptep; + spinlock_t *ptl; + unsigned long v_addr = regs->badaddr, phy_addr; + struct mm_struct *mm = current->mm; + + /* try to get the pte of the trap address */ + ptep = get_locked_pte(mm, v_addr, &ptl); + if (!ptep) + return 0; + + /* check if the area is _PAGE_IO attribute */ + if (!pte_present(*ptep) || !(pte_val(*ptep) & _PAGE_IO)) { + pte_unmap_unlock(ptep, ptl); + return 0; + } + + /* release the pte */ + pte_unmap_unlock(ptep, ptl); + + /* check if the area is in pcie memory area */ + phy_addr = (pte_pfn(*ptep) << PAGE_SHIFT) | (v_addr & ~PAGE_MASK); + if ((phy_addr < SPACEMIT_K1_PCIE_DATA_LOW) || (phy_addr > SPACEMIT_K1_PCIE_DATA_HIGH)) { + return 0; + } + + return 1; +} + +DO_ERROR_INFO(do_trap_load_fault_inner, + SIGSEGV, SEGV_ACCERR, "load access fault"); +asmlinkage __visible __trap_section void do_trap_load_fault(struct pt_regs *regs) +{ + /* Try to process the exception as a load misaligned on io memory area */ + if (user_mode(regs)) { + irqentry_enter_from_user_mode(regs); + + if (check_if_user_io_area_misaligned(regs) && !handle_misaligned_load(regs)) { + irqentry_exit_to_user_mode(regs); + return; + } + + irqentry_exit_to_user_mode(regs); + } + + do_trap_load_fault_inner(regs); +} +#else DO_ERROR_INFO(do_trap_load_fault, SIGSEGV, SEGV_ACCERR, "load access fault"); +#endif asmlinkage __visible __trap_section void do_trap_load_misaligned(struct pt_regs *regs) { @@ -255,8 +310,31 @@ asmlinkage __visible __trap_section void do_trap_store_misaligned(struct pt_regs irqentry_nmi_exit(regs, state); } } + +#ifdef CONFIG_SPACEMIT_K1_PCIE_USR_MISALIGNED +DO_ERROR_INFO(do_trap_store_fault_inner, + SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); +asmlinkage __visible __trap_section void do_trap_store_fault(struct pt_regs *regs) +{ + /* Try to process the exception as a store misaligned on io memory area */ + if (user_mode(regs)) { + irqentry_enter_from_user_mode(regs); + + if (check_if_user_io_area_misaligned(regs) && !handle_misaligned_store(regs)) { + irqentry_exit_to_user_mode(regs); + return; + } + + irqentry_exit_to_user_mode(regs); + } + + do_trap_store_fault_inner(regs); +} +#else DO_ERROR_INFO(do_trap_store_fault, SIGSEGV, SEGV_ACCERR, "store (or AMO) access fault"); +#endif + DO_ERROR_INFO(do_trap_ecall_s, SIGILL, ILL_ILLTRP, "environment call from S-mode"); DO_ERROR_INFO(do_trap_ecall_m, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c index 8c3fb1562ffe..c11016fa6576 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c @@ -1103,6 +1103,9 @@ static struct ttm_tt *amdgpu_ttm_tt_create(struct ttm_buffer_object *bo, else caching = ttm_cached; +#ifdef CONFIG_SOC_SPACEMIT_K1X + caching = ttm_write_combined; +#endif /* allocate space for the uninitialized page entries */ if (ttm_sg_tt_init(>t->ttm, bo, page_flags, caching)) { kfree(gtt); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c index c7085a747b03..14788ed78287 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vram_mgr.c @@ -588,7 +588,11 @@ static int amdgpu_vram_mgr_new(struct ttm_resource_manager *man, if (adev->gmc.xgmi.connected_to_cpu) vres->base.bus.caching = ttm_cached; else +#ifdef CONFIG_SOC_SPACEMIT_K1X + vres->base.bus.caching = ttm_uncached; +#else vres->base.bus.caching = ttm_write_combined; +#endif atomic64_add(vis_usage, &mgr->vis_usage); *res = &vres->base; diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c index 62ecf4d89cb9..3295df009082 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v10_0.c @@ -965,13 +965,21 @@ static int gmc_v10_0_sw_init(void *handle) */ adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */ +#ifdef CONFIG_SOC_SPACEMIT_K1X + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(34)); +#else r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44)); +#endif if (r) { dev_warn(adev->dev, "amdgpu: No suitable DMA available.\n"); return r; } +#ifdef CONFIG_SOC_SPACEMIT_K1X + adev->need_swiotlb = drm_need_swiotlb(34); +#else adev->need_swiotlb = drm_need_swiotlb(44); +#endif r = gmc_v10_0_mc_init(adev); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c index 3d797a1adef3..33f3df3c5c5d 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v11_0.c @@ -822,13 +822,21 @@ static int gmc_v11_0_sw_init(void *handle) */ adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */ +#ifdef CONFIG_SOC_SPACEMIT_K1X + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(34)); +#else r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(44)); +#endif if (r) { dev_warn(adev->dev, "amdgpu: No suitable DMA available.\n"); return r; } +#ifdef CONFIG_SOC_SPACEMIT_K1X + adev->need_swiotlb = drm_need_swiotlb(34); +#else adev->need_swiotlb = drm_need_swiotlb(44); +#endif r = gmc_v11_0_mc_init(adev); if (r) diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c index dfee4aae8039..1b71d34c8705 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v6_0.c @@ -831,12 +831,20 @@ static int gmc_v6_0_sw_init(void *handle) adev->gmc.mc_mask = 0xffffffffffULL; +#ifdef CONFIG_SOC_SPACEMIT_K1X + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(34)); +#else r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); +#endif if (r) { dev_warn(adev->dev, "No suitable DMA available.\n"); return r; } +#ifdef CONFIG_SOC_SPACEMIT_K1X + adev->need_swiotlb = drm_need_swiotlb(34); +#else adev->need_swiotlb = drm_need_swiotlb(40); +#endif r = gmc_v6_0_init_microcode(adev); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c index fd905889a4c6..74eb44dcb1f2 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v7_0.c @@ -1010,12 +1010,20 @@ static int gmc_v7_0_sw_init(void *handle) */ adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */ +#ifdef CONFIG_SOC_SPACEMIT_K1X + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(34)); +#else r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); +#endif if (r) { pr_warn("No suitable DMA available\n"); return r; } +#ifdef CONFIG_SOC_SPACEMIT_K1X + adev->need_swiotlb = drm_need_swiotlb(34); +#else adev->need_swiotlb = drm_need_swiotlb(40); +#endif r = gmc_v7_0_init_microcode(adev); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c index 0bebcdbb2658..a4eefe2f1126 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v8_0.c @@ -1123,12 +1123,20 @@ static int gmc_v8_0_sw_init(void *handle) */ adev->gmc.mc_mask = 0xffffffffffULL; /* 40 bit MC */ +#ifdef CONFIG_SOC_SPACEMIT_K1X + r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(34)); +#else r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(40)); +#endif if (r) { pr_warn("No suitable DMA available\n"); return r; } +#ifdef CONFIG_SOC_SPACEMIT_K1X + adev->need_swiotlb = drm_need_swiotlb(34); +#else adev->need_swiotlb = drm_need_swiotlb(40); +#endif r = gmc_v8_0_init_microcode(adev); if (r) { diff --git a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c index 6d2b9d260d92..2f0f1622dbfe 100644 --- a/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c +++ b/drivers/gpu/drm/amd/amdgpu/gmc_v9_0.c @@ -2156,7 +2156,11 @@ static int gmc_v9_0_sw_init(void *handle) */ adev->gmc.mc_mask = 0xffffffffffffULL; /* 48 bit MC */ +#ifdef CONFIG_SOC_SPACEMIT_K1X + dma_addr_bits = 34; +#else dma_addr_bits = adev->ip_versions[GC_HWIP][0] >= IP_VERSION(9, 4, 2) ? 48:44; +#endif r = dma_set_mask_and_coherent(adev->dev, DMA_BIT_MASK(dma_addr_bits)); if (r) { dev_warn(adev->dev, "amdgpu: No suitable DMA available.\n"); diff --git a/drivers/gpu/drm/radeon/radeon_ttm.c b/drivers/gpu/drm/radeon/radeon_ttm.c index f3fd7e9fc48c..4ae8c37dcf91 100644 --- a/drivers/gpu/drm/radeon/radeon_ttm.c +++ b/drivers/gpu/drm/radeon/radeon_ttm.c @@ -288,7 +288,11 @@ static int radeon_ttm_io_mem_reserve(struct ttm_device *bdev, struct ttm_resourc return -EINVAL; mem->bus.offset += rdev->mc.aper_base; mem->bus.is_iomem = true; +#ifdef CONFIG_SOC_SPACEMIT_K1X + mem->bus.caching = ttm_uncached; +#else mem->bus.caching = ttm_write_combined; +#endif #ifdef __alpha__ /* * Alpha: use bus.addr to hold the ioremap() return, diff --git a/drivers/input/touchscreen/gt9xx.c b/drivers/input/touchscreen/gt9xx.c index 53d19d1c7b14..59ef121b67b2 100644 --- a/drivers/input/touchscreen/gt9xx.c +++ b/drivers/input/touchscreen/gt9xx.c @@ -1542,9 +1542,6 @@ static s8 gtp_request_input_dev(struct goodix_ts_data *ts) dev_info(&ts->client->dev, "Use type A report protocol\n"); } - input_set_capability(ts->input_dev, EV_KEY, GTP_PEN_BUTTON1); - input_set_capability(ts->input_dev, EV_KEY, GTP_PEN_BUTTON2); - /* touch key register */ for (index = 0; index < ts->pdata->key_nums; index++) input_set_capability(ts->input_dev, EV_KEY, diff --git a/drivers/mfd/spacemit-mfd.c b/drivers/mfd/spacemit-mfd.c index ef9ce982bc03..1d009248fd2e 100644 --- a/drivers/mfd/spacemit-mfd.c +++ b/drivers/mfd/spacemit-mfd.c @@ -39,8 +39,6 @@ static const struct restart_config_info config_info[] = { {"fastboot", 1}, // enter uboot shell after restart {"uboot", 2}, - // bit3 for charging flag - {"shutdown-charging", 4}, }; static const struct of_device_id spacemit_pmic_of_match[] = { @@ -76,16 +74,6 @@ static int spacemit_restart_notify(struct notifier_block *this, unsigned long mo int i, ret; struct spacemit_pmic *pmic = (struct spacemit_pmic *)match_data->ptr; - for (i = 0; i < ARRAY_SIZE(config_info); ++i) { - if(!strncmp(config_info[i].cmd_para, "shutdown-charging", - sizeof("shutdown-charging"))) { - regmap_update_bits(pmic->regmap, match_data->non_reset.reg, - match_data->non_reset.bit, config_info[i].value); - break; - } - } - - if (NULL != cmd) { for (i = 0; i < ARRAY_SIZE(config_info); i++) { if (0 == strcmp(cmd, config_info[i].cmd_para)) { diff --git a/drivers/net/wireless/realtek/rtl8852bs/phl/hal_g6/mac/mac_ax/wowlan.c b/drivers/net/wireless/realtek/rtl8852bs/phl/hal_g6/mac/mac_ax/wowlan.c index f8ab1aef6bd1..51e73fbe9a4a 100644 --- a/drivers/net/wireless/realtek/rtl8852bs/phl/hal_g6/mac/mac_ax/wowlan.c +++ b/drivers/net/wireless/realtek/rtl8852bs/phl/hal_g6/mac/mac_ax/wowlan.c @@ -2732,17 +2732,19 @@ u32 mac_wow_dbg_dump(struct mac_ax_adapter *adapter) #if MAC_AX_FEATURE_DBGPKG ret = fw_st_dbg_dump(adapter); - if (ret) { - PLTFM_MSG_ERR("fw_st_dbg_dump fail (%d)\n", ret); - return ret; - } + if (ret) { + PLTFM_MSG_ERR("fw_st_dbg_dump fail (%d)\n", ret); + PLTFM_MUTEX_UNLOCK(&adapter->lock_info.err_get_lock); + return ret; + } #endif #if MAC_AX_FEATURE_DBGPKG ret = mac_dump_err_status(adapter, HALT_C2H_L1_DBG_MODE); - if (ret) { - PLTFM_MSG_ERR("mac_dump_err_status fail (%d)\n", ret); - return ret; - } + if (ret) { + PLTFM_MSG_ERR("mac_dump_err_status fail (%d)\n", ret); + PLTFM_MUTEX_UNLOCK(&adapter->lock_info.err_get_lock); + return ret; + } #endif PLTFM_MUTEX_UNLOCK(&adapter->lock_info.err_get_lock); return ret; diff --git a/drivers/pci/setup-bus.c b/drivers/pci/setup-bus.c index 5a143ad5fca2..1191926254db 100644 --- a/drivers/pci/setup-bus.c +++ b/drivers/pci/setup-bus.c @@ -1067,6 +1067,10 @@ static int pbus_size_mem(struct pci_bus *bus, unsigned long mask, min_align = calculate_mem_align(aligns, max_order); min_align = max(min_align, window_alignment(bus, b_res->flags)); size0 = calculate_memsize(size, min_size, 0, 0, resource_size(b_res), min_align); +#ifdef CONFIG_SOC_SPACEMIT_K1X + if (size0 == 0x18000000U) + size0 = 0x16000000U; +#endif add_align = max(min_align, add_align); size1 = (!realloc_head || (realloc_head && !add_size && !children_add_size)) ? size0 : calculate_memsize(size, min_size, add_size, children_add_size, diff --git a/scripts/build_kernel.sh b/scripts/build_kernel.sh index 29116e0db62e..e5d75e745038 100755 --- a/scripts/build_kernel.sh +++ b/scripts/build_kernel.sh @@ -1,65 +1,319 @@ #!/bin/bash -e -SCRIPT="./scripts/build_kernel.sh" +PACKAGE_SRC_NAME="linux-riscv-spacemit" +CLEAN_CMD="make distclean && + VERSION=\$(grep -oP '^VERSION\\s*=\\s*\\K\\d+' Makefile) + PATCHLEVEL=\$(grep -oP '^PATCHLEVEL\\s*=\\s*\\K\\d+' Makefile) + SUBLEVEL=\$(grep -oP '^SUBLEVEL\\s*=\\s*\\K\\d+' Makefile) + export KERNELRELEASE=\$VERSION.\$PATCHLEVEL.\$SUBLEVEL && + rm -f ../linux-headers-\$KERNELRELEASE_*_riscv64.deb && + rm -f ../linux-image-\$KERNELRELEASE_*_riscv64.deb && + rm -f ../linux-image-\$KERNELRELEASE-dbg_*_riscv64.deb && + rm -f ../linux-tools-\$KERNELRELEASE_*_riscv64.deb && + rm -f ../linux-libc-dev_*_riscv64.deb && + rm -f ../linux-tools-common_*_all.deb && + rm -f ../linux-riscv-spacemit_*_riscv64.* +" +BUILD_CMD='make k1_defconfig && make -j$(nproc)' +BUILD_DEB_CMD="make k1_defconfig && + sed -i '/CONFIG_INITRAMFS_SOURCE=/d' arch/riscv/configs/k1_defconfig + VERSION=\$(grep -oP '^VERSION\\s*=\\s*\\K\\d+' Makefile) + PATCHLEVEL=\$(grep -oP '^PATCHLEVEL\\s*=\\s*\\K\\d+' Makefile) + SUBLEVEL=\$(grep -oP '^SUBLEVEL\\s*=\\s*\\K\\d+' Makefile) + export KERNELRELEASE=\$VERSION.\$PATCHLEVEL.\$SUBLEVEL + export LOCALVERSION=\"\" + KDEB_SOURCENAME=$PACKAGE_SRC_NAME \\ + KDEB_PKGVERSION=\$KERNELRELEASE-\$(TZ=Asia/Shanghai date +\"%Y%m%d%H%M%S\") \\ + KDEB_CHANGELOG_DIST=noble-porting \\ + make -j\$(nproc) bindeb-pkg +" + +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" +SOURCE_DIR="$(cd "$SCRIPT_DIR/.." && pwd)" +SOURCE_PARENT_DIR="$(cd "$SOURCE_DIR/.." && pwd)" +DOCKER_REPO="${DOCKER_REPO:-harbor.spacemit.com/bianbu-linux}" +IMAGE_NAME="${IMAGE_NAME:-bianbu-linux-builder:latest}" +CROSS_COMPILE="${CROSS_COMPILE:-riscv64-unknown-linux-gnu-}" +TOOLCHAIN_PATH="${TOOLCHAIN_PATH:-/opt/spacemit-toolchain-linux-glibc-x86_64-v1.0.0/bin}" +DIRECT_BUILD="${DIRECT_BUILD:-0}" CLEAN=false BUILD_DEB=false +ACTION="build" +DEBUG=false -while getopts "cdh" opt -do - case $opt in - c) +# Function to handle symlinks within git directory +handle_git_internal_symlinks() { + local git_dir="$1" + local container_git_dir="$2" + local -n git_mounts_ref="$3" # Reference to the git mounts array + + [ "$DEBUG" = true ] && echo "Scanning for symlinks in git directory: $git_dir" + + # Find all symlinks in the git directory + while IFS= read -r -d '' symlink; do + if [ -L "$symlink" ]; then + local real_target + real_target="$(readlink -f "$symlink")" + local relative_path="${symlink#$git_dir/}" + local container_target="$container_git_dir/$relative_path" + + if [ -e "$real_target" ]; then + [ "$DEBUG" = true ] && echo "Found symlink: $relative_path -> $real_target" + # Store mounts in the array - add both -v and the mount path + git_mounts_ref+=("-v" "$real_target:$container_target") + else + [ "$DEBUG" = true ] && echo "Warning: Broken symlink found: $symlink -> $real_target" + fi + fi + done < <(find "$git_dir" -type l -print0 2>/dev/null) +} + +# Function to setup all container volume mounts (including git handling) +setup_volume_mounts() { + local project_dir="$1" + local package_dir="$2" + local git_path="$package_dir/.git" + local container_base + container_base="/workspace/$(basename "$package_dir")" + + # Local git_mounts array for this function + local git_mounts=() + + [ "$DEBUG" = true ] && echo "Setting up container volume mounts..." + + # Initialize with basic mounts + VOLUME_MOUNTS=("-v" "$project_dir:/workspace" "-w" "$container_base") + + # Handle git directory if exists + if [ -e "$git_path" ]; then + local actual_git_dir + local container_git_path="$container_base/.git" + + if [ -L "$git_path" ]; then + [ "$DEBUG" = true ] && echo "Detected .git as symbolic link, resolving real git directory..." + actual_git_dir="$(readlink -f "$git_path")" + + if [ ! -d "$actual_git_dir" ]; then + echo "Error: Cannot find real git directory: $actual_git_dir" + echo "Please ensure the git repository is accessible." + exit 1 + fi + + # Set up main git directory mount + git_mounts+=("-v" "$actual_git_dir:$container_git_path") + [ "$DEBUG" = true ] && echo "Will mount real git directory: $actual_git_dir -> $container_git_path" + + elif [ -d "$git_path" ]; then + [ "$DEBUG" = true ] && echo "Found normal .git directory" + actual_git_dir="$git_path" + # For normal directories, no additional mount needed as it's part of the main project mount + + else + [ "$DEBUG" = true ] && echo "Warning: .git exists but is neither a directory nor a symlink" + actual_git_dir="" + fi + + # Handle symlinks within the git directory + if [ -n "$actual_git_dir" ]; then + handle_git_internal_symlinks "$actual_git_dir" "$container_git_path" git_mounts + fi + else + [ "$DEBUG" = true ] && echo "Warning: No .git directory found, some git operations may fail" + fi + + # Add all git mounts (both main directory and internal symlinks) + if [ ${#git_mounts[@]} -gt 0 ]; then + VOLUME_MOUNTS+=("${git_mounts[@]}") + [ "$DEBUG" = true ] && echo "Added $(( ${#git_mounts[@]} / 2 )) git-related mounts" + fi + + [ "$DEBUG" = true ] && echo "Total volume mounts configured: $(( (${#VOLUME_MOUNTS[@]} + 1) / 2 ))" + # fix this function will exit if bash set -e + return 0 +} + +# Setup container volume mounts (includes git handling) +setup_volume_mounts "$SOURCE_PARENT_DIR" "$SOURCE_DIR" + +usage() { + echo "Container-based build wrapper (universal version)" + echo "Usage: $(basename "$0") [OPTIONS] [COMMAND]" + echo "" + echo "Options:" + echo " -c, --clean Clean build (CLEAN_CMD before BUILD[_DEB]_CMD)" + echo " -d, --deb Build DEB packages (BUILD_DEB_CMD)" + echo " -h, --help Show this help message" + echo " -x, --debug Enable debug output (show docker command)" + echo "" + echo "Commands (run inside container):" + echo " build Build (BUILD_CMD, default)" + echo " shell Interactive shell" + echo "" + echo "Examples:" + echo " $(basename "$0") # Build in container" + echo " $(basename "$0") -c -d # Clean build with DEB packages" + echo " $(basename "$0") shell # Interactive container shell" +} + +# Parse command line arguments +while [[ $# -gt 0 ]]; do + case $1 in + -c|--clean) CLEAN=true + shift ;; - d) + -d|--deb) BUILD_DEB=true + shift ;; - ?) - echo "Usage: Run on the top of linux directory" - echo "$SCRIPT [-c] [-d]" + -h|--help) + usage + exit 0 + ;; + -x|--debug) + DEBUG=true + shift + ;; + build|shell) + ACTION="$1" + shift + ;; + *) + echo "Unknown option: $1" + usage exit 1 ;; esac done -if [ $0 != $SCRIPT ] -then - echo "Run $(basename $SCRIPT) on the top of linux directory" +# Check if Docker is available +if ! command -v docker &> /dev/null; then + echo "Error: Docker not found. Please install Docker." exit 1 fi -command -v riscv64-unknown-linux-gnu-gcc > /dev/null || \ - (echo "Install cross compile and add to PATH" && exit 1) - -VERSION=$(grep -oP '^VERSION\s*=\s*\K\d+' Makefile) -PATCHLEVEL=$(grep -oP '^PATCHLEVEL\s*=\s*\K\d+' Makefile) -SUBLEVEL=$(grep -oP '^SUBLEVEL\s*=\s*\K\d+' Makefile) -export ARCH=riscv -export CROSS_COMPILE=riscv64-unknown-linux-gnu- -export KERNELRELEASE=$VERSION.$PATCHLEVEL.$SUBLEVEL -export LOCALVERSION="" - -if [ $CLEAN = true ] -then - make distclean - if [ $BUILD_DEB = true ] - then - rm -f ../linux-headers-$KERNELRELEASE_*_riscv64.deb - rm -f ../linux-image-$KERNELRELEASE_*_riscv64.deb - rm -f ../linux-image-$KERNELRELEASE-dbg_*_riscv64.deb - rm -f ../linux-libc-dev_*_riscv64.deb - rm -f ../linux-riscv-spacemit_*_riscv64.* +# Set DEBEMAIL and DEBFULLNAME environment variable +if [ -z "$DEBEMAIL" ]; then + if [ -n "$MAIL" ]; then + DEBEMAIL="$MAIL" + else + DEBEMAIL="$(id -nu)@$(hostname -f 2>/dev/null || hostname)" fi fi -make k1_defconfig - -if [ $BUILD_DEB = true ] -then - KDEB_SOURCENAME=linux-riscv-spacemit \ - KDEB_PKGVERSION=$KERNELRELEASE-$(TZ=Asia/Shanghai date +"%Y%m%d%H%M%S") \ - KDEB_CHANGELOG_DIST=mantic-porting \ - make -j$(nproc) bindeb-pkg -else - make -j$(nproc) +if [ -z "$DEBFULLNAME" ]; then + if [ -n "$NAME" ]; then + DEBFULLNAME="$NAME" + elif echo "$DEBEMAIL" | grep -qE '^([^<]+)\s*<[^>]+>$'; then + # If DEBEMAIL matches "name ", extract name as DEBFULLNAME + DEBFULLNAME="$(echo "$DEBEMAIL" | sed -n 's/^\([^<][^<]*\)<.*$/\1/p' | sed 's/[[:space:]]*$//')" + else + DEBFULLNAME="$(id -nu)" + fi fi + +CONTAINER_ENV=("-e" "ARCH=riscv" "-e" "CROSS_COMPILE=$CROSS_COMPILE" "-e" "PATH=$TOOLCHAIN_PATH:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" "-e" "DEBEMAIL=$DEBEMAIL" "-e" "DEBFULLNAME=$DEBFULLNAME") + +# Function to create user permission files for container +create_user_files() { + local current_user current_group + current_user="$(whoami):x:$(id -u):$(id -g):$(whoami),,,:/home/$(whoami):/bin/bash" + current_group="$(id -gn):x:$(id -g):" + + # Create or update .passwd and .group files + if [ ! -f "$SOURCE_DIR/.passwd" ] || \ + [ ! -f "$SOURCE_DIR/.group" ] || \ + [ "$current_user" != "$(grep "^$(whoami):" "$SOURCE_DIR/.passwd" 2>/dev/null)" ] || \ + [ "$current_group" != "$(grep "^$(id -gn):" "$SOURCE_DIR/.group" 2>/dev/null)" ]; then + cp /etc/passwd "$SOURCE_DIR/.passwd.tmp" + cp /etc/group "$SOURCE_DIR/.group.tmp" + + if ! grep -q "^$(whoami):" "$SOURCE_DIR/.passwd.tmp"; then + echo "$current_user" >> "$SOURCE_DIR/.passwd.tmp" + fi + + if ! grep -q "^$(id -gn):" "$SOURCE_DIR/.group.tmp"; then + echo "$current_group" >> "$SOURCE_DIR/.group.tmp" + fi + + mv "$SOURCE_DIR/.passwd.tmp" "$SOURCE_DIR/.passwd" + mv "$SOURCE_DIR/.group.tmp" "$SOURCE_DIR/.group" + fi +} + +# Create user permission files +create_user_files + +# Function to run command in container +run_in_container() { + local cmd="$1" + + if [ "$DEBUG" = true ]; then + echo "--- Docker/Podman full command ---" + local full_cmd + full_cmd="docker run --rm -it --init" + for v in "${VOLUME_MOUNTS[@]}"; do + full_cmd+=" $v" + done + for e in "${CONTAINER_ENV[@]}"; do + full_cmd+=" $e" + done + full_cmd+=" -v $SOURCE_DIR/.passwd:/etc/passwd:ro" + full_cmd+=" -v $SOURCE_DIR/.group:/etc/group:ro" + full_cmd+=" -u $(id -u):$(id -g)" + full_cmd+=" $DOCKER_REPO/$IMAGE_NAME" + full_cmd+=" bash -c \"$cmd\"" + echo "$full_cmd" + echo "--- End docker command ---" + fi + + docker run --rm -it --init \ + "${VOLUME_MOUNTS[@]}" \ + "${CONTAINER_ENV[@]}" \ + -v "$SOURCE_DIR/.passwd:/etc/passwd:ro" \ + -v "$SOURCE_DIR/.group:/etc/group:ro" \ + -u "$(id -u):$(id -g)" \ + "$DOCKER_REPO/$IMAGE_NAME" \ + bash -c "$cmd" +} + +# Run command directly or in container based on DIRECT_BUILD +run_command() { + local cmd="$1" + if [ -n "$DIRECT_BUILD" ] && [ "$DIRECT_BUILD" != "0" ]; then + [ "$DEBUG" = true ] && echo "[DIRECT_BUILD] Executing locally: $cmd" + command -v riscv64-unknown-linux-gnu-gcc > /dev/null || \ + (echo "Install cross compile and add to PATH" && exit 1) + export ARCH=riscv + export CROSS_COMPILE=riscv64-unknown-linux-gnu- + bash -c "$cmd" + else + [ "$DEBUG" = true ] && echo "Building in container..." + run_in_container "$cmd" + fi +} + +# Execute container actions +case "$ACTION" in + build) + if [[ "$CLEAN" == true ]]; then + run_command "$CLEAN_CMD" + fi + if [[ "$BUILD_DEB" == true ]]; then + run_command "$BUILD_DEB_CMD" + else + run_command "$BUILD_CMD" + fi + echo "Build completed successfully!" + ;; + shell) + run_in_container "bash" + echo "Container shell session ended." + ;; + *) + echo "Unknown action: $ACTION" + usage + exit 1 + ;; +esac \ No newline at end of file diff --git a/scripts/package/mkdebian b/scripts/package/mkdebian index 335f295a2b9c..20a15c19c24d 100755 --- a/scripts/package/mkdebian +++ b/scripts/package/mkdebian @@ -155,7 +155,7 @@ else fi sourcename=${KDEB_SOURCENAME:-linux-upstream} -kernelgitver=$(git rev-parse --short HEAD) +kernelgitver=$(git rev-parse --short HEAD) || echo "" if [ "$ARCH" = "um" ] ; then packagename=user-mode-linux diff --git a/sound/soc/spacemit/spacemit-snd-pcm-dma.c b/sound/soc/spacemit/spacemit-snd-pcm-dma.c index 98e62ebb70ce..d12d3aefc841 100644 --- a/sound/soc/spacemit/spacemit-snd-pcm-dma.c +++ b/sound/soc/spacemit/spacemit-snd-pcm-dma.c @@ -1053,6 +1053,7 @@ static int spacemit_snd_pcm_new(struct snd_soc_component *component, struct snd_ struct snd_card *card = rtd->card->snd_card; struct snd_pcm *pcm = rtd->pcm; struct snd_pcm_substream *substream; + struct snd_soc_dai_link *dai_link = rtd->dai_link; pr_debug("%s enter, dev=%s\n", __FUNCTION__, dev_name(rtd->dev)); @@ -1066,12 +1067,18 @@ static int spacemit_snd_pcm_new(struct snd_soc_component *component, struct snd_ pr_err("%s: get dev error\n", __FUNCTION__); return -1; } - if (dev->dmadata->dma_id == DMA_HDMI) { + + if (dai_link->playback_only) { chan_num = 1; pr_debug("%s playback_only, dev=%s\n", __FUNCTION__, dev_name(rtd->dev)); + } else if (dai_link->capture_only) { + pr_err("%s not support capture_only, dev=%s\n", __FUNCTION__, dev_name(rtd->dev)); + ret = -EINVAL; + return ret; } else { chan_num = 2; } + dev->dmadata[0].stream = SNDRV_PCM_STREAM_PLAYBACK; dev->dmadata[1].stream = SNDRV_PCM_STREAM_CAPTURE;