From fd1a9d06cef85f16a4dcb16061a9128437e235f4 Mon Sep 17 00:00:00 2001 From: ReleaseRaptor Date: Wed, 1 Oct 2025 00:10:47 +0800 Subject: [PATCH] CIX P1 2025Q3 RELEASE --- .../devicetree/bindings/arm/cix.yaml | 26 + .../bindings/clock/cix,sky1-audss-clock.yaml | 80 + .../devicetree/bindings/dma/arm_dma350.txt | 45 + .../bindings/hwlock/sky1-hwspinlock.yaml | 41 + .../bindings/mailbox/cix-mailbox.yaml | 68 + .../bindings/pinctrl/cix,sky1-pinctrl.yaml | 65 + .../devicetree/bindings/pwm/sky1-pwm.yaml | 55 + .../bindings/remoteproc/cix_dsp_rproc.yaml | 113 + .../bindings/remoteproc/cix_sfh_rproc.yaml | 87 + .../bindings/reset/cix,sky1-src.yaml | 59 + .../bindings/soc/cix/cix,ddr_exception.yaml | 60 + .../bindings/soc/cix/cix,se_pm_execption.yaml | 44 + .../devicetree/bindings/sound/alc256.txt | 14 + .../devicetree/bindings/sound/alc257.txt | 14 + .../devicetree/bindings/sound/alc269.txt | 14 + .../devicetree/bindings/sound/alc3287.txt | 14 + .../bindings/sound/cdns,i2s-mc.yaml | 120 + .../bindings/sound/cdns,i2s-sc.yaml | 96 + .../bindings/sound/cix,sky1-card.yaml | 78 + .../devicetree/bindings/sound/ipbloq,hda.yaml | 60 + .../bindings/timer/timer-sky1-gpt.yaml | 55 + .../devicetree/bindings/vendor-prefixes.yaml | 4 + .../bindings/watchdog/sky1-watchdog.yaml | 49 + Documentation/driver-api/index.rst | 1 + Documentation/driver-api/pin-control-acpi.rst | 297 + Makefile | 3 + arch/arm64/Kconfig | 3 +- arch/arm64/Kconfig.platforms | 22 + arch/arm64/boot/dts/Makefile | 1 + arch/arm64/boot/dts/cix/Makefile | 30 + arch/arm64/boot/dts/cix/sky1-batura.dts | 104 + arch/arm64/boot/dts/cix/sky1-cloudbook.dts | 1362 + arch/arm64/boot/dts/cix/sky1-crb.dts | 1299 + arch/arm64/boot/dts/cix/sky1-emu-pm.dts | 10 + arch/arm64/boot/dts/cix/sky1-emu-smp.dts | 27 + arch/arm64/boot/dts/cix/sky1-emu.dts | 1571 ++ arch/arm64/boot/dts/cix/sky1-evb-csidma.dtsi | 417 + arch/arm64/boot/dts/cix/sky1-evb-display.dts | 29 + .../boot/dts/cix/sky1-evb-hda-alc256.dts | 50 + arch/arm64/boot/dts/cix/sky1-evb-iso.dts | 89 + arch/arm64/boot/dts/cix/sky1-evb-isp.dts | 93 + arch/arm64/boot/dts/cix/sky1-evb-isp.dtsi | 123 + .../boot/dts/cix/sky1-evb-lt7911uxc-audio.dts | 54 + .../boot/dts/cix/sky1-evb-npu-resmem.dts | 34 + .../boot/dts/cix/sky1-evb-pcie_width_x1.dts | 32 + .../boot/dts/cix/sky1-evb-pcie_width_x2.dts | 31 + .../boot/dts/cix/sky1-evb-pcie_width_x4.dts | 30 + arch/arm64/boot/dts/cix/sky1-evb-pciex10.dts | 29 + arch/arm64/boot/dts/cix/sky1-evb-pciex11.dts | 29 + arch/arm64/boot/dts/cix/sky1-evb-pciex2.dts | 29 + arch/arm64/boot/dts/cix/sky1-evb-pciex4.dts | 29 + arch/arm64/boot/dts/cix/sky1-evb-pciex8.dts | 29 + .../dts/cix/sky1-evb-sof-alc5682-alc1019.dts | 192 + arch/arm64/boot/dts/cix/sky1-evb-usb4_5.dts | 21 + arch/arm64/boot/dts/cix/sky1-evb.dts | 2532 ++ arch/arm64/boot/dts/cix/sky1-fpga.dts | 1698 ++ .../cix/sky1-orangepi-6-plus-40pin-pwm.dts | 94 + .../dts/cix/sky1-orangepi-6-plus-40pin.dts | 94 + .../boot/dts/cix/sky1-orangepi-6-plus.dts | 2311 ++ .../boot/dts/cix/sky1-orangepi-6-plus.dtsi | 4724 ++++ .../boot/dts/cix/sky1-orion-o6-40pin.dts | 24 + arch/arm64/boot/dts/cix/sky1-orion-o6.dts | 2394 ++ arch/arm64/boot/dts/cix/sky1.dtsi | 4448 ++++ arch/arm64/configs/cix.config | 554 + arch/arm64/configs/cix_cloudbook.config | 1 + arch/arm64/configs/cix_debug.config | 3 + arch/arm64/configs/cix_emu.config | 2 + arch/arm64/configs/cix_fpga.config | 2 + arch/arm64/configs/cix_redroid.config | 221 + arch/arm64/configs/defconfig | 8 +- arch/arm64/include/asm/acpi.h | 9 + arch/arm64/include/asm/el2_setup.h | 35 +- arch/arm64/include/asm/hw_breakpoint.h | 19 + arch/arm64/include/asm/irq.h | 6 + arch/arm64/include/asm/ptrace.h | 8 + arch/arm64/include/asm/smp.h | 2 + arch/arm64/include/asm/sysreg.h | 9 + arch/arm64/kernel/Makefile | 1 + arch/arm64/kernel/cix_dmi.c | 54 + arch/arm64/kernel/cix_dmi.h | 13 + arch/arm64/kernel/cpuinfo.c | 4 + arch/arm64/kernel/entry.S | 38 + arch/arm64/kernel/hibernate.c | 11 + arch/arm64/kernel/hw_breakpoint.c | 22 +- arch/arm64/kernel/process.c | 75 + arch/arm64/kernel/proton-pack.c | 2 + arch/arm64/kernel/smp.c | 30 +- arch/arm64/kernel/syscall.c | 9 + arch/arm64/kernel/traps.c | 34 +- arch/arm64/mm/fault.c | 20 +- arch/arm64/mm/init.c | 8 + drivers/Makefile | 3 + drivers/acpi/Kconfig | 7 + drivers/acpi/Makefile | 3 +- drivers/acpi/acpi_platform.c | 26 + drivers/acpi/cix_acpi_pd.c | 144 + drivers/acpi/cppc_acpi.c | 1 + drivers/acpi/device_perf.c | 544 + drivers/acpi/device_pm.c | 12 +- drivers/acpi/device_sysfs.c | 44 +- drivers/acpi/internal.h | 1 - drivers/acpi/processor_thermal.c | 286 +- drivers/acpi/property.c | 66 + drivers/acpi/scan.c | 10 +- drivers/acpi/sleep.c | 41 +- drivers/acpi/thermal.c | 105 +- drivers/acpi/thermal.h | 90 + drivers/android/Kconfig | 7 + drivers/android/Makefile | 1 + drivers/android/mpam_arch.c | 697 + drivers/android/mpam_arch.h | 10 + drivers/android/mpam_arch_internal.h | 54 + drivers/base/cpu.c | 1 + drivers/base/power/domain.c | 444 +- drivers/base/power/runtime.c | 4 + drivers/base/property.c | 10 + drivers/bluetooth/Kconfig | 6 + drivers/bluetooth/Makefile | 1 + drivers/bluetooth/rtk_btusb.c | 4881 ++++ drivers/bluetooth/rtk_btusb.h | 759 + drivers/char/hw_random/Kconfig | 12 + drivers/char/hw_random/Makefile | 1 + drivers/char/hw_random/sky1-rng.c | 160 + drivers/clk/Kconfig | 1 + drivers/clk/Makefile | 1 + drivers/clk/cix/Kconfig | 34 + drivers/clk/cix/Makefile | 9 + drivers/clk/cix/acpi_clk.c | 506 + drivers/clk/cix/acpi_clk.h | 45 + drivers/clk/cix/acpi_scmi_clk.c | 72 + drivers/clk/cix/cix-clk-debug.c | 266 + drivers/clk/cix/clk-sky1-audss.c | 1257 + drivers/clk/cix/clk.c | 82 + drivers/clk/cix/clk.h | 18 + drivers/clk/clk-composite.c | 15 + drivers/clk/clk-scmi.c | 41 +- drivers/clocksource/Kconfig | 6 + drivers/clocksource/Makefile | 1 + drivers/clocksource/arm_arch_timer.c | 4 + drivers/clocksource/timer-sky1-gpt.c | 396 + drivers/cpufreq/Kconfig | 5 + drivers/cpufreq/Kconfig.arm | 7 + drivers/cpufreq/Makefile | 1 + drivers/cpufreq/cix-cpufreq-dt.c | 272 + drivers/cpufreq/cppc_cpufreq.c | 206 +- drivers/cpufreq/scmi-cpufreq.c | 33 + drivers/devfreq/Kconfig | 27 + drivers/devfreq/Makefile | 2 + drivers/devfreq/cix-bus.c | 281 + drivers/devfreq/dsu-pctrl-devfreq.c | 938 + drivers/devfreq/event/Kconfig | 7 + drivers/devfreq/event/Makefile | 1 + drivers/devfreq/event/cix-pmu.c | 152 + drivers/dma-buf/dma-buf.c | 151 +- drivers/dma-buf/dma-heap.c | 198 +- drivers/dma-buf/heaps/Kconfig | 31 +- drivers/dma-buf/heaps/Makefile | 4 + drivers/dma-buf/heaps/cma_heap.c | 8 +- drivers/dma-buf/heaps/deferred-free-helper.c | 138 + drivers/dma-buf/heaps/deferred-free-helper.h | 55 + drivers/dma-buf/heaps/dsp_heap.c | 164 + drivers/dma-buf/heaps/page_pool.c | 294 + drivers/dma-buf/heaps/page_pool.h | 27 + drivers/dma-buf/heaps/system_heap.c | 174 +- drivers/dma-buf/heaps/vpu_heap.c | 316 + drivers/dma-buf/sw_sync.c | 8 +- drivers/dma-buf/sync_file.c | 7 + drivers/dma/Kconfig | 7 + drivers/dma/Makefile | 1 + drivers/dma/arm_dma350.c | 1529 ++ drivers/dma/dma350_ch_drv.h | 2012 ++ drivers/dma/dma350_regdef.h | 1148 + drivers/firmware/Kconfig | 1 + drivers/firmware/Makefile | 1 + drivers/firmware/arm_scmi/Kconfig | 23 + drivers/firmware/arm_scmi/bus.c | 15 +- drivers/firmware/arm_scmi/common.h | 4 +- drivers/firmware/arm_scmi/driver.c | 85 +- drivers/firmware/arm_scmi/mailbox.c | 79 +- drivers/firmware/arm_scmi/optee.c | 11 +- drivers/firmware/arm_scmi/perf.c | 75 +- drivers/firmware/arm_scmi/protocols.h | 3 + drivers/firmware/arm_scmi/scmi_pm_domain.c | 9 + drivers/firmware/arm_scmi/shmem.c | 140 +- drivers/firmware/arm_scmi/smc.c | 14 +- drivers/firmware/arm_scmi/virtio.c | 2 +- drivers/firmware/arm_sdei.c | 5 + drivers/firmware/cix/Kconfig | 9 + drivers/firmware/cix/Makefile | 2 + drivers/firmware/cix/cix-dsp.c | 174 + drivers/firmware/efi/efi-init.c | 7 + drivers/firmware/psci/psci.c | 31 + drivers/gpio/Kconfig | 2 +- drivers/gpio/gpio-cadence.c | 232 +- drivers/gpu/drm/Kconfig | 12 + drivers/gpu/drm/Makefile | 4 +- .../drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c | 4 +- drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c | 15 +- drivers/gpu/drm/amd/amdgpu/amdgpu_device.c | 42 +- drivers/gpu/drm/amd/amdgpu/amdgpu_job.c | 6 +- drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c | 21 - drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h | 1 - drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c | 22 +- drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h | 2 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c | 22 +- drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h | 2 +- drivers/gpu/drm/amd/amdgpu/cik_sdma.c | 5 - drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c | 12 +- drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c | 7 +- drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c | 5 - drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c | 5 - drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c | 16 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c | 10 +- drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c | 10 +- drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c | 10 +- drivers/gpu/drm/amd/amdgpu/si_dma.c | 5 - drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c | 2 - drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c | 2 - drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c | 2 - drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c | 2 - drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c | 4 - drivers/gpu/drm/amd/amdgpu/vce_v2_0.c | 2 - drivers/gpu/drm/amd/amdgpu/vce_v3_0.c | 2 - drivers/gpu/drm/amd/amdgpu/vce_v4_0.c | 5 - drivers/gpu/drm/cix/Kconfig | 55 + drivers/gpu/drm/cix/Makefile | 5 + drivers/gpu/drm/cix/cix_display.c | 204 + drivers/gpu/drm/cix/cix_virtual.c | 313 + drivers/gpu/drm/cix/dptx/Kconfig | 27 + drivers/gpu/drm/cix/dptx/Makefile | 11 + drivers/gpu/drm/cix/dptx/cix_edp_panel.c | 881 + drivers/gpu/drm/cix/dptx/cix_edp_panel.h | 26 + drivers/gpu/drm/cix/dptx/dptx_infoframe.c | 359 + drivers/gpu/drm/cix/dptx/dptx_infoframe.h | 46 + drivers/gpu/drm/cix/dptx/hdcp/cix_hdcp.c | 396 + drivers/gpu/drm/cix/dptx/hdcp/cix_hdcp.h | 141 + .../gpu/drm/cix/dptx/hdcp/cix_hdcp_ioctl.c | 183 + .../gpu/drm/cix/dptx/hdcp/cix_hdcp_ioctl.h | 22 + .../drm/cix/dptx/hdcp/cix_hdcp_ioctl_cmd.h | 116 + drivers/gpu/drm/cix/dptx/hdcp/dptx_aux_reg.h | 126 + drivers/gpu/drm/cix/dptx/hdcp/dptx_reg.h | 483 + drivers/gpu/drm/cix/dptx/hdcp/hdcp2_hw_tx.c | 920 + drivers/gpu/drm/cix/dptx/hdcp/hdcp2_hw_tx.h | 62 + .../gpu/drm/cix/dptx/hdcp/hdcp2_key_drvn_tx.c | 246 + .../gpu/drm/cix/dptx/hdcp/hdcp2_key_drvn_tx.h | 46 + .../gpu/drm/cix/dptx/hdcp/hdcp2_tx_state.c | 126 + .../gpu/drm/cix/dptx/hdcp/hdcp2_tx_state.h | 31 + drivers/gpu/drm/cix/dptx/hdcp/hdcp2_tx_tmr.c | 189 + drivers/gpu/drm/cix/dptx/hdcp/hdcp2_tx_tmr.h | 19 + drivers/gpu/drm/cix/dptx/trilin_dptx.c | 3302 +++ drivers/gpu/drm/cix/dptx/trilin_dptx.h | 580 + drivers/gpu/drm/cix/dptx/trilin_dptx_audio.c | 177 + drivers/gpu/drm/cix/dptx/trilin_dptx_audio.h | 51 + drivers/gpu/drm/cix/dptx/trilin_dptx_cix.c | 414 + drivers/gpu/drm/cix/dptx/trilin_dptx_reg.h | 452 + drivers/gpu/drm/cix/dptx/trilin_drm.c | 1183 + drivers/gpu/drm/cix/dptx/trilin_drm.h | 27 + drivers/gpu/drm/cix/dptx/trilin_drm_mst.c | 934 + drivers/gpu/drm/cix/dptx/trilin_drm_mst.h | 29 + drivers/gpu/drm/cix/dptx/trilin_edp_phy.c | 1185 + drivers/gpu/drm/cix/dptx/trilin_edp_phy.h | 746 + drivers/gpu/drm/cix/dptx/trilin_host_tmr.c | 254 + drivers/gpu/drm/cix/dptx/trilin_host_tmr.h | 62 + drivers/gpu/drm/cix/dptx/trilin_phy.h | 126 + drivers/gpu/drm/cix/dptx/trilin_usbdp_phy.c | 595 + drivers/gpu/drm/cix/dptx/trilin_usbdp_phy.h | 66 + drivers/gpu/drm/cix/linlon-dp/Makefile | 28 + drivers/gpu/drm/cix/linlon-dp/hw/dp_axi.c | 261 + .../gpu/drm/cix/linlon-dp/hw/dp_component.c | 1696 ++ drivers/gpu/drm/cix/linlon-dp/hw/dp_dev.c | 694 + drivers/gpu/drm/cix/linlon-dp/hw/dp_dev.h | 63 + drivers/gpu/drm/cix/linlon-dp/hw/dp_regs.h | 562 + .../drm/cix/linlon-dp/include/linlondp_drm.h | 26 + .../drm/cix/linlon-dp/include/linlondp_io.h | 46 + .../cix/linlon-dp/include/linlondp_product.h | 36 + .../cix/linlon-dp/include/linlondp_utils.h | 43 + .../gpu/drm/cix/linlon-dp/linlondp_coeffs.c | 120 + .../gpu/drm/cix/linlon-dp/linlondp_coeffs.h | 75 + .../drm/cix/linlon-dp/linlondp_color_mgmt.c | 270 + .../drm/cix/linlon-dp/linlondp_color_mgmt.h | 48 + drivers/gpu/drm/cix/linlon-dp/linlondp_crtc.c | 1014 + drivers/gpu/drm/cix/linlon-dp/linlondp_dev.c | 832 + drivers/gpu/drm/cix/linlon-dp/linlondp_dev.h | 303 + drivers/gpu/drm/cix/linlon-dp/linlondp_drv.c | 361 + .../gpu/drm/cix/linlon-dp/linlondp_event.c | 159 + .../drm/cix/linlon-dp/linlondp_format_caps.c | 149 + .../drm/cix/linlon-dp/linlondp_format_caps.h | 101 + .../drm/cix/linlon-dp/linlondp_framebuffer.c | 288 + .../drm/cix/linlon-dp/linlondp_framebuffer.h | 48 + drivers/gpu/drm/cix/linlon-dp/linlondp_io.h | 46 + drivers/gpu/drm/cix/linlon-dp/linlondp_kms.c | 413 + drivers/gpu/drm/cix/linlon-dp/linlondp_kms.h | 339 + .../gpu/drm/cix/linlon-dp/linlondp_pipeline.c | 464 + .../gpu/drm/cix/linlon-dp/linlondp_pipeline.h | 597 + .../cix/linlon-dp/linlondp_pipeline_state.c | 1733 ++ .../gpu/drm/cix/linlon-dp/linlondp_plane.c | 651 + .../drm/cix/linlon-dp/linlondp_private_obj.c | 433 + .../gpu/drm/cix/linlon-dp/linlondp_product.h | 37 + .../gpu/drm/cix/linlon-dp/linlondp_utils.h | 43 + .../drm/cix/linlon-dp/linlondp_wb_connector.c | 389 + drivers/gpu/drm/display/drm_dp_mst_topology.c | 2 +- drivers/gpu/drm/drm_debugfs.c | 11 +- drivers/gpu/drm/drm_gpuvm.c | 2752 ++ drivers/gpu/drm/drm_panel.c | 21 + drivers/gpu/drm/drm_writeback.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gem_submit.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_gpu.c | 2 +- drivers/gpu/drm/etnaviv/etnaviv_sched.c | 3 +- drivers/gpu/drm/lima/lima_device.c | 2 +- drivers/gpu/drm/lima/lima_sched.c | 6 +- drivers/gpu/drm/msm/adreno/adreno_device.c | 4 +- drivers/gpu/drm/msm/msm_gem_submit.c | 2 +- drivers/gpu/drm/msm/msm_gpu.h | 2 +- drivers/gpu/drm/msm/msm_ringbuffer.c | 7 +- drivers/gpu/drm/nouveau/nouveau_sched.c | 5 +- drivers/gpu/drm/panfrost/panfrost_drv.c | 2 +- drivers/gpu/drm/panfrost/panfrost_job.c | 5 +- drivers/gpu/drm/panthor/Kconfig | 23 + drivers/gpu/drm/panthor/Makefile | 14 + drivers/gpu/drm/panthor/panthor_devfreq.c | 310 + drivers/gpu/drm/panthor/panthor_devfreq.h | 21 + drivers/gpu/drm/panthor/panthor_device.c | 703 + drivers/gpu/drm/panthor/panthor_device.h | 413 + drivers/gpu/drm/panthor/panthor_drv.c | 1648 ++ drivers/gpu/drm/panthor/panthor_fw.c | 1420 + drivers/gpu/drm/panthor/panthor_fw.h | 503 + drivers/gpu/drm/panthor/panthor_gem.c | 249 + drivers/gpu/drm/panthor/panthor_gem.h | 146 + drivers/gpu/drm/panthor/panthor_gpu.c | 567 + drivers/gpu/drm/panthor/panthor_gpu.h | 56 + drivers/gpu/drm/panthor/panthor_heap.c | 605 + drivers/gpu/drm/panthor/panthor_heap.h | 39 + drivers/gpu/drm/panthor/panthor_mmu.c | 2811 ++ drivers/gpu/drm/panthor/panthor_mmu.h | 104 + drivers/gpu/drm/panthor/panthor_regs.h | 242 + drivers/gpu/drm/panthor/panthor_sched.c | 3885 +++ drivers/gpu/drm/panthor/panthor_sched.h | 52 + .../gpu/drm/scheduler/gpu_scheduler_trace.h | 6 +- drivers/gpu/drm/scheduler/sched_entity.c | 103 +- drivers/gpu/drm/scheduler/sched_fence.c | 4 +- drivers/gpu/drm/scheduler/sched_main.c | 648 +- drivers/gpu/drm/v3d/v3d_gem.c | 2 +- drivers/gpu/drm/v3d/v3d_sched.c | 15 +- drivers/hwspinlock/Kconfig | 10 + drivers/hwspinlock/Makefile | 1 + drivers/hwspinlock/sky1_hwspinlock.c | 151 + .../coresight/coresight-etm4x-core.c | 27 +- drivers/hwtracing/coresight/coresight-etm4x.h | 6 + .../hwtracing/coresight/coresight-funnel.c | 5 +- drivers/i2c/busses/i2c-cadence.c | 253 +- drivers/i3c/Kconfig | 13 + drivers/i3c/Makefile | 1 + drivers/i3c/i3cdev.c | 432 + drivers/i3c/internals.h | 1 + drivers/i3c/master.c | 15 +- drivers/i3c/master/i3c-master-cdns.c | 319 +- drivers/iio/imu/inv_icm42600/Kconfig | 14 + drivers/iio/imu/inv_icm42600/Makefile | 2 + .../iio/imu/inv_icm42600/cix_regmap_ref_spi.c | 308 + drivers/iio/imu/inv_icm42600/inv_icm42600.h | 188 +- .../imu/inv_icm42600/inv_icm42600_buffer.c | 60 +- .../iio/imu/inv_icm42600/inv_icm42600_core.c | 83 +- .../iio/imu/inv_icm42600/inv_icm42600_spi.c | 47 +- drivers/iio/magnetometer/Kconfig | 18 + drivers/iio/magnetometer/Makefile | 3 +- drivers/iio/magnetometer/mmc5633_i2c.c | 133 + drivers/iio/magnetometer/mmc5633_i3c.c | 108 + drivers/iommu/Kconfig | 17 + drivers/iommu/arm/arm-smmu-v3/Makefile | 3 + .../iommu/arm/arm-smmu-v3/arm-smmu-v3-debug.c | 189 + .../iommu/arm/arm-smmu-v3/arm-smmu-v3-dump.c | 302 + .../iommu/arm/arm-smmu-v3/arm-smmu-v3-dump.h | 69 + .../iommu/arm/arm-smmu-v3/arm-smmu-v3-walk.c | 234 + .../iommu/arm/arm-smmu-v3/arm-smmu-v3-walk.h | 33 + drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 317 +- drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.h | 18 + drivers/iommu/io-pgtable-arm.c | 141 +- drivers/iommu/io-pgtable-arm.h | 14 + drivers/iommu/io-pgtable.c | 23 + drivers/irqchip/Kconfig | 8 + drivers/irqchip/Makefile | 1 + drivers/irqchip/irq-gic-v3.c | 5 + drivers/irqchip/irq-sky1-pdc.c | 266 + drivers/mailbox/Kconfig | 10 + drivers/mailbox/Makefile | 2 + drivers/mailbox/cix-mailbox.c | 645 + drivers/mailbox/mailbox.c | 133 +- drivers/media/i2c/Kconfig | 10 +- drivers/media/i2c/Makefile | 3 + drivers/media/i2c/cix/lt7911uxc/Makefile | 34 + drivers/media/i2c/cix/lt7911uxc/lt7911uxc.c | 1359 + drivers/media/i2c/cix/lt7911uxc/lt7911uxc.h | 377 + drivers/media/platform/Kconfig | 24 + drivers/media/platform/Makefile | 4 + drivers/media/platform/cadence/cdns-csi2rx.c | 162 +- drivers/media/platform/cadence/cdns-csi2rx.h | 65 + drivers/media/platform/cix/Kconfig | 2 + drivers/media/platform/cix/Makefile | 2 + drivers/media/platform/cix/cix_isp/Makefile | 41 + .../platform/cix/cix_isp/armcb_isp_entry.c | 88 + .../platform/cix/cix_isp/cixvihw/Makefile | 3 + .../platform/cix/cix_isp/cixvihw/cix_vi_hw.c | 979 + .../platform/cix/cix_isp/cixvihw/cix_vi_hw.h | 84 + .../platform/cix/cix_isp/common/Makefile | 13 + .../cix/cix_isp/common/armcb_camera_io_drv.c | 1342 + .../cix/cix_isp/common/armcb_camera_io_drv.h | 199 + .../platform/cix/cix_isp/common/armcb_isp.h | 459 + .../cix/cix_isp/common/armcb_register.h | 195 + .../cix/cix_isp/common/armcb_v4l_sd.c | 251 + .../cix/cix_isp/common/armcb_v4l_sd.h | 103 + .../cix/cix_isp/common/isp_hw_if/Makefile | 7 + .../cix/cix_isp/common/isp_hw_if/isp_hw_ops.c | 928 + .../cix/cix_isp/common/isp_hw_if/isp_hw_ops.h | 45 + .../cix_isp/common/isp_hw_if/isp_hw_utils.c | 372 + .../cix_isp/common/isp_hw_if/isp_hw_utils.h | 61 + .../platform/cix/cix_isp/common/system_dma.c | 213 + .../platform/cix/cix_isp/common/system_dma.h | 27 + .../platform/cix/cix_isp/common/types_utils.h | 52 + .../media/platform/cix/cix_isp/isp/Makefile | 10 + .../cix/cix_isp/isp/armcb_isp_driver.c | 356 + .../cix/cix_isp/isp/armcb_isp_driver.h | 233 + .../cix/cix_isp/isp/armcb_isp_hw_reg.h | 93 + .../cix/cix_isp/isp/armcb_v4l2_config.c | 2058 ++ .../cix/cix_isp/isp/armcb_v4l2_config.h | 90 + .../cix/cix_isp/isp/armcb_v4l2_core.c | 1027 + .../cix/cix_isp/isp/armcb_v4l2_core.h | 108 + .../cix/cix_isp/isp/armcb_v4l2_stream.c | 405 + .../cix/cix_isp/isp/armcb_v4l2_stream.h | 108 + .../platform/cix/cix_isp/isp/armcb_vb2.c | 173 + .../platform/cix/cix_isp/isp/armcb_vb2.h | 37 + .../platform/cix/cix_isp/platform/Makefile | 9 + .../cix/cix_isp/platform/armcb_platform.c | 99 + .../cix/cix_isp/platform/armcb_platform.h | 30 + .../cix/cix_isp/platform/bus/Makefile | 5 + .../cix/cix_isp/platform/bus/i2c/Makefile | 6 + .../cix/cix_isp/platform/bus/i2c/system_i2c.c | 1352 + .../cix/cix_isp/platform/bus/i2c/system_i2c.h | 237 + .../cix/cix_isp/platform/bus/spi/Makefile | 6 + .../cix/cix_isp/platform/bus/spi/system_spi.c | 692 + .../cix/cix_isp/platform/bus/spi/system_spi.h | 162 + .../cix/cix_isp/platform/hdmi/system_hdmi.c | 1337 + .../cix/cix_isp/platform/logger/Makefile | 5 + .../cix_isp/platform/logger/system_logger.c | 117 + .../cix_isp/platform/logger/system_logger.h | 68 + .../platform/cix/cix_isp/sensor/Makefile | 8 + .../cix/cix_isp/sensor/actuator/Makefile | 7 + .../cix_isp/sensor/actuator/armcb_actuator.c | 391 + .../cix_isp/sensor/actuator/armcb_actuator.h | 65 + .../cix/cix_isp/sensor/armcb_sensor.c | 642 + .../cix/cix_isp/sensor/armcb_sensor.h | 132 + drivers/media/platform/cix/csi_dma/Makefile | 41 + .../platform/cix/csi_dma/csi_bridge_hw.c | 716 + .../platform/cix/csi_dma/csi_bridge_hw.h | 413 + .../media/platform/cix/csi_dma/csi_common.h | 686 + .../media/platform/cix/csi_dma/csi_dma_cap.c | 1478 ++ .../media/platform/cix/csi_dma/csi_dma_cap.h | 9 + .../media/platform/cix/csi_dma/csi_dma_core.c | 819 + .../platform/cix/csi_dma/csi_mipi_csi2.c | 1171 + .../platform/cix/csi_dma/csi_mipi_dphy_hw.c | 595 + .../platform/cix/csi_dma/csi_mipi_dphy_rx.c | 679 + .../media/platform/cix/csi_dma/csi_rcsu_hw.c | 138 + .../media/platform/cix/csi_dma/csi_rcsu_hw.h | 17 + drivers/media/platform/cix/linlon-aeu/Kconfig | 9 + .../media/platform/cix/linlon-aeu/Makefile | 9 + .../platform/cix/linlon-aeu/linlon_aeu.c | 302 + .../platform/cix/linlon-aeu/linlon_aeu_dev.h | 56 + .../platform/cix/linlon-aeu/linlon_aeu_hw.c | 1120 + .../platform/cix/linlon-aeu/linlon_aeu_hw.h | 269 + .../platform/cix/linlon-aeu/linlon_aeu_io.h | 27 + .../platform/cix/linlon-aeu/linlon_aeu_log.c | 221 + .../platform/cix/linlon-aeu/linlon_aeu_log.h | 16 + .../cix/linlon-aeu/linlon_aeu_reg_dump.c | 137 + .../cix/linlon-aeu/linlon_aeu_reg_dump.h | 46 + .../platform/cix/linlon-aeu/linlon_aeu_v4l2.c | 1052 + drivers/mfd/syscon.c | 33 + drivers/misc/Kconfig | 4 + drivers/misc/Makefile | 4 + drivers/misc/cix/sensor/cix_sensorhub/Kconfig | 8 + .../misc/cix/sensor/cix_sensorhub/Makefile | 5 + .../cix/sensor/cix_sensorhub/cix_sensorhub.c | 1894 ++ .../cix/sensor/cix_sensorhub/cix_sensorhub.h | 457 + .../cix/sensor/cix_sensorhub/sensor_list.c | 70 + .../cix/sensor/cix_sensorhub/sensor_list.h | 25 + .../cix/sensor/cix_sensorhub/sensorhub_ipi.c | 355 + .../cix/sensor/cix_sensorhub/sensorhub_ipi.h | 68 + drivers/misc/cix/sensor/core/Kconfig | 7 + drivers/misc/cix/sensor/core/Makefile | 3 + drivers/misc/cix/sensor/core/hf_manager.c | 1572 ++ drivers/misc/cix/sensor/core/hf_manager.h | 178 + drivers/misc/cix/sensor/core/hf_sensor_io.h | 103 + drivers/misc/cix/sensor/core/hf_sensor_type.h | 106 + drivers/misc/cix/sensor/scp/Kconfig | 10 + drivers/misc/cix/sensor/scp/Makefile | 5 + drivers/misc/cix/sensor/scp/include/scp.h | 144 + drivers/misc/cix/sensor/scp/scp_helper.c | 253 + drivers/misc/cix/sensor/scp/scp_helper.h | 167 + .../cix/sensor/scp/scp_reservedmem_define.h | 100 + drivers/misc/cix/sensor/test/Kconfig | 8 + drivers/misc/cix/sensor/test/Makefile | 6 + drivers/misc/cix/sensor/test/test.c | 180 + drivers/misc/cix/sensor/test/test_app.c | 184 + drivers/misc/cix/sensor/test/test_app1.c | 209 + drivers/misc/cix/sensor/test/test_app2.c | 163 + drivers/mtd/spi-nor/winbond.c | 7 + drivers/net/ethernet/cadence/macb.h | 2 + drivers/net/ethernet/cadence/macb_main.c | 263 +- drivers/net/ethernet/realtek/Kconfig | 55 + drivers/net/ethernet/realtek/Makefile | 4 + drivers/net/ethernet/realtek/pg_tool/Makefile | 26 + drivers/net/ethernet/realtek/pg_tool/pgdrv.c | 587 + drivers/net/ethernet/realtek/pg_tool/pgdrv.h | 86 + drivers/net/ethernet/realtek/r8125/Makefile | 221 + .../ethernet/realtek/r8125/Makefile_linux24x | 75 + drivers/net/ethernet/realtek/r8125/README | 143 + drivers/net/ethernet/realtek/r8125/r8125.h | 3058 +++ .../net/ethernet/realtek/r8125/r8125_dash.h | 196 + .../ethernet/realtek/r8125/r8125_firmware.c | 264 + .../ethernet/realtek/r8125/r8125_firmware.h | 68 + drivers/net/ethernet/realtek/r8125/r8125_n.c | 21327 ++++++++++++++++ .../net/ethernet/realtek/r8125/r8125_ptp.c | 1472 ++ .../net/ethernet/realtek/r8125/r8125_ptp.h | 159 + .../ethernet/realtek/r8125/r8125_realwow.h | 118 + .../net/ethernet/realtek/r8125/r8125_rss.c | 583 + .../net/ethernet/realtek/r8125/r8125_rss.h | 76 + .../net/ethernet/realtek/r8125/rtl_eeprom.c | 284 + .../net/ethernet/realtek/r8125/rtl_eeprom.h | 53 + drivers/net/ethernet/realtek/r8125/rtltool.c | 312 + drivers/net/ethernet/realtek/r8125/rtltool.h | 89 + drivers/net/ethernet/realtek/r8126/Makefile | 214 + .../ethernet/realtek/r8126/Makefile_linux24x | 75 + drivers/net/ethernet/realtek/r8126/r8126.h | 3047 +++ .../net/ethernet/realtek/r8126/r8126_dash.h | 261 + .../ethernet/realtek/r8126/r8126_firmware.c | 264 + .../ethernet/realtek/r8126/r8126_firmware.h | 68 + drivers/net/ethernet/realtek/r8126/r8126_n.c | 18199 +++++++++++++ .../net/ethernet/realtek/r8126/r8126_ptp.c | 944 + .../net/ethernet/realtek/r8126/r8126_ptp.h | 202 + .../ethernet/realtek/r8126/r8126_realwow.h | 118 + .../net/ethernet/realtek/r8126/r8126_rss.c | 583 + .../net/ethernet/realtek/r8126/r8126_rss.h | 76 + .../net/ethernet/realtek/r8126/rtl_eeprom.c | 285 + .../net/ethernet/realtek/r8126/rtl_eeprom.h | 58 + drivers/net/ethernet/realtek/r8126/rtltool.c | 285 + drivers/net/ethernet/realtek/r8126/rtltool.h | 89 + drivers/net/ethernet/realtek/r8127/Makefile | 209 + .../ethernet/realtek/r8127/Makefile_linux24x | 75 + drivers/net/ethernet/realtek/r8127/r8127.h | 3068 +++ .../net/ethernet/realtek/r8127/r8127_dash.h | 261 + .../ethernet/realtek/r8127/r8127_firmware.c | 264 + .../ethernet/realtek/r8127/r8127_firmware.h | 68 + drivers/net/ethernet/realtek/r8127/r8127_n.c | 17856 +++++++++++++ .../net/ethernet/realtek/r8127/r8127_ptp.c | 944 + .../net/ethernet/realtek/r8127/r8127_ptp.h | 202 + .../ethernet/realtek/r8127/r8127_realwow.h | 118 + .../net/ethernet/realtek/r8127/r8127_rss.c | 583 + .../net/ethernet/realtek/r8127/r8127_rss.h | 76 + .../net/ethernet/realtek/r8127/rtl_eeprom.c | 285 + .../net/ethernet/realtek/r8127/rtl_eeprom.h | 58 + drivers/net/ethernet/realtek/r8127/rtltool.c | 270 + drivers/net/ethernet/realtek/r8127/rtltool.h | 86 + drivers/net/mdio/acpi_mdio.c | 12 +- drivers/net/phy/phy.c | 4 + drivers/nvme/host/pci.c | 3 +- drivers/nvmem/Kconfig | 9 + drivers/nvmem/Makefile | 2 + drivers/nvmem/sky1_nvmem.c | 93 + drivers/of/property.c | 7 + drivers/opp/core.c | 3 +- drivers/pci/access.c | 12 + drivers/pci/controller/cadence/Kconfig | 14 + drivers/pci/controller/cadence/Makefile | 3 + .../pci/controller/cadence/pci-sky1-debugfs.c | 1340 + .../pci/controller/cadence/pci-sky1-debugfs.h | 17 + drivers/pci/controller/cadence/pci-sky1.c | 2550 ++ drivers/pci/controller/cadence/pci-sky1.h | 196 + .../pci/controller/cadence/pcie-cadence-ep.c | 8 +- .../controller/cadence/pcie-cadence-host.c | 240 +- drivers/pci/controller/cadence/pcie-cadence.c | 110 +- drivers/pci/controller/cadence/pcie-cadence.h | 280 +- drivers/pci/pci.c | 75 +- drivers/pci/pci.h | 13 +- drivers/pci/pcie/Makefile | 2 +- drivers/pci/pcie/aspm.c | 702 +- drivers/pci/probe.c | 62 +- drivers/pci/quirks.c | 3 + drivers/perf/arm-cmn.c | 6 +- drivers/perf/arm_spe_pmu.c | 10 + drivers/phy/Kconfig | 1 + drivers/phy/Makefile | 3 +- drivers/phy/cadence/cdns-dphy-rx.c | 21 +- drivers/phy/cadence/cdns-dphy-rx.h | 49 + drivers/phy/cix/Kconfig | 32 + drivers/phy/cix/Makefile | 5 + drivers/phy/cix/phy-cix-pcie.c | 631 + drivers/phy/cix/phy-cix-usb2.c | 56 + drivers/phy/cix/phy-cix-usb3.c | 477 + drivers/phy/cix/phy-cix-usbdp.c | 1616 ++ drivers/phy/cix/phy-cix-usbdp.h | 347 + drivers/pinctrl/Kconfig | 1 + drivers/pinctrl/Makefile | 2 + drivers/pinctrl/cix/Kconfig | 13 + drivers/pinctrl/cix/Makefile | 4 + drivers/pinctrl/cix/pinctrl-sky1-base.c | 856 + drivers/pinctrl/cix/pinctrl-sky1.c | 510 + drivers/pinctrl/cix/pinctrl-sky1.h | 55 + drivers/pinctrl/core.c | 17 +- drivers/pinctrl/core.h | 3 + drivers/pinctrl/pinctrl-acpi.c | 772 + drivers/pinctrl/pinctrl-acpi.h | 101 + drivers/platform/chrome/Kconfig | 1 + drivers/platform/chrome/Makefile | 1 + drivers/platform/chrome/cix_ec/Kconfig | 6 + drivers/platform/chrome/cix_ec/Makefile | 10 + .../platform/chrome/cix_ec/cix_ec_battery.c | 240 + .../platform/chrome/cix_ec/cix_ec_charge.c | 128 + drivers/platform/chrome/cix_ec/cix_ec_fan.c | 182 + drivers/platform/chrome/cix_ec/cix_ec_gpio.c | 147 + .../chrome/cix_ec/cix_ec_kb_backlight.c | 133 + drivers/platform/chrome/cix_ec/cix_ec_lid.c | 240 + drivers/platform/chrome/cix_ec/cix_ec_light.c | 129 + .../platform/chrome/cix_ec/cix_ec_pwrkey.c | 154 + drivers/platform/chrome/cros_ec.c | 68 +- drivers/platform/chrome/cros_ec_i2c.c | 18 +- drivers/platform/chrome/cros_ec_proto.c | 22 +- drivers/pwm/Kconfig | 9 + drivers/pwm/Makefile | 1 + drivers/pwm/pwm-cros-ec.c | 7 +- drivers/pwm/pwm-sky1.c | 329 + drivers/regulator/Makefile | 3 +- drivers/regulator/core.c | 91 +- drivers/regulator/fixed.c | 49 + drivers/regulator/fwnode_regulator.c | 737 + drivers/regulator/internal.h | 10 + drivers/remoteproc/Kconfig | 14 + drivers/remoteproc/Makefile | 2 + drivers/remoteproc/cix_dsp_rproc.c | 1236 + drivers/remoteproc/cix_sfh_rproc.c | 1343 + drivers/remoteproc/remoteproc_core.c | 5 + drivers/reset/Kconfig | 18 + drivers/reset/Makefile | 2 + drivers/reset/reset-sky1-audss.c | 196 + drivers/reset/reset-sky1.c | 421 + drivers/rpmsg/rpmsg_core.c | 51 + drivers/rtc/Kconfig | 9 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-hym8563.c | 15 +- drivers/rtc/rtc-rx8900.c | 1058 + drivers/soc/Kconfig | 1 + drivers/soc/Makefile | 2 + drivers/soc/arm/Makefile | 3 + drivers/soc/arm/scmi_perf_domain.c | 217 + drivers/soc/cix/Kconfig | 54 + drivers/soc/cix/Makefile | 11 + drivers/soc/cix/acpi/Makefile | 6 + drivers/soc/cix/acpi/acpi_resource_lookup.c | 561 + drivers/soc/cix/acpi/cix-acpi-plat.c | 138 + drivers/soc/cix/acpi/cix-fan-mode.c | 308 + drivers/soc/cix/acpi/dsdt_override.c | 173 + drivers/soc/cix/acpi/reserved_memory.c | 70 + .../ap/platform/sky1/mntn_dump_interface.h | 101 + .../ap/platform/sky1/mntn_public_interface.h | 202 + .../ap/platform/sky1/mntn_subtype_exception.h | 196 + drivers/soc/cix/cix-ddr-lp.c | 171 + drivers/soc/cix/cix-hibernate.c | 155 + drivers/soc/cix/cix-plat.c | 267 + drivers/soc/cix/cix-se-config.c | 92 + drivers/soc/cix/cix-sky1-socinfo.c | 716 + drivers/soc/cix/cix-suspend.c | 109 + drivers/soc/cix/cix_ap2se_ipc.c | 314 + drivers/soc/cix/cix_dst/Kconfig | 158 + drivers/soc/cix/cix_dst/Makefile | 29 + drivers/soc/cix/cix_dst/blackbox/Kconfig | 46 + drivers/soc/cix/cix_dst/blackbox/Makefile | 12 + .../cix_dst/blackbox/exception_trace/Makefile | 6 + .../exception_trace/rdr_exception_trace.c | 267 + .../exception_trace/rdr_exception_trace.h | 33 + .../exception_trace/rdr_exception_trace_ap.c | 162 + .../cix/cix_dst/blackbox/platform_ap/Makefile | 6 + .../platform_ap/include/rdr_ap_adapter.h | 82 + .../platform_ap/include/rdr_ap_hook.h | 179 + .../platform_ap/include/rdr_ap_logbuf.h | 19 + .../platform_ap/include/rdr_ap_memid.h | 19 + .../platform_ap/include/rdr_ap_moddump.h | 22 + .../platform_ap/include/rdr_ap_regdump.h | 30 + .../platform_ap/include/rdr_ap_stack.h | 36 + .../platform_ap/include/rdr_ap_suspend.h | 12 + .../blackbox/platform_ap/rdr_ap_adapter.c | 482 + .../blackbox/platform_ap/rdr_ap_exception.c | 98 + .../blackbox/platform_ap/rdr_ap_hook.c | 743 + .../blackbox/platform_ap/rdr_ap_moddump.c | 177 + .../blackbox/platform_ap/rdr_ap_pstore.c | 132 + .../blackbox/platform_ap/rdr_ap_regdump.c | 135 + .../blackbox/platform_ap/rdr_ap_ringbuffer.c | 202 + .../blackbox/platform_ap/rdr_ap_stack.c | 274 + .../blackbox/platform_ap/rdr_ap_suspend.c | 261 + .../soc/cix/cix_dst/blackbox/rdr_bootcheck.c | 200 + .../soc/cix/cix_dst/blackbox/rdr_cleartext.c | 600 + drivers/soc/cix/cix_dst/blackbox/rdr_common.c | 656 + drivers/soc/cix/cix_dst/blackbox/rdr_core.c | 513 + .../soc/cix/cix_dst/blackbox/rdr_dump_core.c | 450 + .../cix/cix_dst/blackbox/rdr_exception_core.c | 268 + .../cix/cix_dst/blackbox/rdr_exception_test.c | 110 + drivers/soc/cix/cix_dst/blackbox/rdr_field.h | 93 + .../soc/cix/cix_dst/blackbox/rdr_field_core.c | 362 + drivers/soc/cix/cix_dst/blackbox/rdr_inner.h | 267 + .../cix_dst/blackbox/rdr_logmonitor_core.c | 495 + .../cix/cix_dst/blackbox/rdr_module_core.c | 411 + drivers/soc/cix/cix_dst/blackbox/rdr_print.h | 37 + .../cix/cix_dst/blackbox/rdr_reboot_reason.c | 93 + .../soc/cix/cix_dst/blackbox/rdr_safemem.c | 285 + drivers/soc/cix/cix_dst/blackbox/rdr_utils.c | 103 + drivers/soc/cix/cix_dst/blackbox/rdr_utils.h | 13 + drivers/soc/cix/cix_dst/boot_postcode.c | 361 + .../cix_dst/cache_exception_monitor/Kconfig | 16 + .../cix_dst/cache_exception_monitor/Makefile | 7 + .../cache_core_exception_drv.c | 301 + .../cache_dsu_exception_drv.c | 138 + .../cache_exception_interface.c | 76 + .../cache_exception_interface.h | 36 + drivers/soc/cix/cix_dst/dsm/Kconfig | 17 + drivers/soc/cix/cix_dst/dsm/Makefile | 8 + drivers/soc/cix/cix_dst/dsm/dsm_core.c | 870 + drivers/soc/cix/cix_dst/dsm/dsm_core.h | 91 + drivers/soc/cix/cix_dst/dsm/dsm_errno.h | 26 + drivers/soc/cix/cix_dst/dsm/dsm_plat.c | 113 + drivers/soc/cix/cix_dst/dsm/dsm_test.c | 270 + .../soc/cix/cix_dst/dst_audio_timeout_error.c | 47 + drivers/soc/cix/cix_dst/dst_ddr_exception.c | 958 + drivers/soc/cix/cix_dst/dst_fdleak_main.c | 544 + drivers/soc/cix/cix_dst/dst_print.h | 25 + .../soc/cix/cix_dst/dst_rcsu_gasket_error.c | 167 + drivers/soc/cix/cix_dst/dst_reboot_reason.c | 230 + drivers/soc/cix/cix_dst/dst_sdei_exceptions.c | 150 + drivers/soc/cix/cix_dst/dst_sdei_ni700_idm.c | 187 + .../soc/cix/cix_dst/dst_sdei_tee_exceptions.c | 156 + drivers/soc/cix/cix_dst/dst_sdei_tfa_trace.c | 109 + drivers/soc/cix/cix_dst/dst_sdei_tzc400.c | 213 + drivers/soc/cix/cix_dst/dst_wakeup_source.c | 68 + drivers/soc/cix/cix_dst/hw_boottime.c | 212 + drivers/soc/cix/cix_dst/hw_breakpoint/Kconfig | 10 + .../soc/cix/cix_dst/hw_breakpoint/Makefile | 6 + .../hw_breakpoint/hw_breakpoint_plat.c | 1018 + .../hw_breakpoint/hw_breakpoint_proc.c | 442 + .../hw_breakpoint/hw_breakpoint_trigger.c | 302 + .../hw_breakpoint/hw_breakpoint_until.c | 144 + .../hw_breakpoint/hw_breakpoint_until.h | 20 + drivers/soc/cix/cix_dst/logger/Kconfig | 7 + drivers/soc/cix/cix_dst/logger/Makefile | 4 + drivers/soc/cix/cix_dst/logger/dst_logger.c | 904 + drivers/soc/cix/cix_dst/memory_dump/Kconfig | 14 + drivers/soc/cix/cix_dst/memory_dump/Makefile | 5 + .../soc/cix/cix_dst/memory_dump/kernel_dump.c | 323 + .../soc/cix/cix_dst/memory_dump/kernel_dump.h | 67 + drivers/soc/cix/cix_dst/mntn_dump.c | 269 + .../cix/cix_dst/pm_exception_monitor/Kconfig | 19 + .../cix/cix_dst/pm_exception_monitor/Makefile | 9 + .../pm_exception_monitor/pm_exception_drv.c | 109 + .../pm_exception_monitor/pm_exception_drv.h | 65 + .../pm_exception_monitor/pm_exception_dsm.c | 233 + .../pm_exception_monitor/pm_exception_dsm.h | 34 + .../pm_exception_ec_drv.c | 158 + .../pm_exception_protocol.c | 195 + drivers/soc/cix/cix_dst/printk_ext.c | 50 + .../soc/cix/cix_dst/se_crash_monitor/Kconfig | 8 + .../soc/cix/cix_dst/se_crash_monitor/Makefile | 7 + .../soc/cix/cix_dst/se_crash_monitor/pm_wdt.c | 42 + .../soc/cix/cix_dst/se_crash_monitor/se_amu.c | 84 + .../soc/cix/cix_dst/se_crash_monitor/se_clk.c | 41 + .../cix/cix_dst/se_crash_monitor/se_crash.h | 54 + .../cix_dst/se_crash_monitor/se_crash_drv.c | 315 + .../soc/cix/cix_dst/se_crash_monitor/se_ddr.c | 67 + .../cix/cix_dst/se_crash_monitor/se_power.c | 45 + .../soc/cix/cix_dst/se_crash_monitor/se_wdt.c | 91 + drivers/soc/cix/cix_dst/util.c | 672 + drivers/soc/cix/sched/Kconfig | 40 + drivers/soc/cix/sched/Makefile | 7 + drivers/soc/cix/sched/common.h | 28 + drivers/soc/cix/sched/core_ctl/core_ctl.c | 2272 ++ drivers/soc/cix/sched/core_ctl/core_ctl.h | 35 + .../soc/cix/sched/core_ctl/core_ctl_trace.h | 132 + drivers/soc/cix/sched/core_ctl/core_pause.c | 649 + drivers/soc/cix/sched/core_ctl/core_pause.h | 21 + .../soc/cix/sched/core_ctl/core_pause_trace.h | 108 + drivers/soc/cix/sched/core_ctl/sched_avg.c | 1054 + drivers/soc/cix/sched/core_ctl/sched_avg.h | 29 + drivers/soc/cix/sched/sched_sys_common.h | 17 + drivers/spi/spi-cadence-xspi.c | 217 +- drivers/spi/spi-cadence.c | 250 +- drivers/staging/Kconfig | 8 + drivers/staging/Makefile | 4 + drivers/staging/android/Kconfig | 15 + drivers/staging/android/Makefile | 4 + drivers/staging/android/TODO | 8 + drivers/staging/android/ashmem.c | 1000 + drivers/staging/android/ashmem.h | 26 + drivers/staging/android/uapi/ashmem.h | 44 + drivers/staging/hievent/Kconfig | 12 + drivers/staging/hievent/Makefile | 2 + drivers/staging/hievent/hievent_driver.c | 429 + drivers/staging/hievent/hievent_driver.h | 22 + drivers/staging/hievent/hiview_hievent.c | 486 + drivers/staging/hievent/hiview_hievent.h | 34 + drivers/staging/hisysevent/Kconfig | 6 + drivers/staging/hisysevent/Makefile | 6 + .../staging/hisysevent/hisysevent_builder.c | 360 + .../staging/hisysevent/hisysevent_builder.h | 87 + .../staging/hisysevent/hisysevent_raw_data.c | 116 + .../staging/hisysevent/hisysevent_raw_data.h | 33 + .../hisysevent/hisysevent_raw_data_encoder.c | 123 + .../hisysevent/hisysevent_raw_data_encoder.h | 21 + .../staging/hisysevent/hiview_hisysevent.c | 140 + drivers/staging/hungtask/Kconfig | 14 + drivers/staging/hungtask/Makefile | 3 + drivers/staging/hungtask/hungtask_base.c | 1037 + drivers/staging/hungtask/hungtask_user.c | 263 + drivers/staging/hungtask/hungtask_user.h | 37 + drivers/thermal/Kconfig | 17 + drivers/thermal/Makefile | 2 + drivers/thermal/cix/Kconfig | 15 + drivers/thermal/cix/Makefile | 6 + drivers/thermal/cix/cix_cpu_ipa.c | 127 + drivers/thermal/cix/cix_scmi_em.c | 106 + drivers/thermal/cpufreq_cooling.c | 20 + drivers/thermal/devfreq_cooling.c | 45 +- drivers/thermal/gov_acpi_dp.c | 202 + drivers/thermal/gov_power_allocator.c | 18 +- drivers/thermal/thermal_core.h | 4 +- drivers/tty/serial/amba-pl011.c | 387 +- drivers/usb/cdns3/Kconfig | 65 +- drivers/usb/cdns3/Makefile | 45 +- drivers/usb/cdns3/cdnsp-ep0.c | 25 +- drivers/usb/cdns3/cdnsp-gadget.c | 26 +- drivers/usb/cdns3/cdnsp-gadget.h | 4 +- drivers/usb/cdns3/cdnsp-mem.c | 2 +- drivers/usb/cdns3/cdnsp-plat.c | 481 + drivers/usb/cdns3/cdnsp-ring.c | 21 +- drivers/usb/cdns3/cdnsp-sky1.c | 822 + drivers/usb/cdns3/cdnsp-sky1.h | 123 + drivers/usb/cdns3/core.c | 114 +- drivers/usb/cdns3/core.h | 25 + drivers/usb/cdns3/drd.c | 43 +- drivers/usb/cdns3/drd.h | 8 + drivers/usb/cdns3/host.c | 41 +- drivers/usb/core/driver.c | 8 + drivers/usb/core/hcd.c | 7 + drivers/usb/gadget/function/f_ncm.c | 3 + drivers/usb/gadget/function/f_uvc.c | 22 +- drivers/usb/gadget/function/u_ether.c | 5 +- drivers/usb/host/xhci.c | 16 +- drivers/usb/serial/option.c | 49 + drivers/usb/storage/usb.c | 4 + drivers/usb/typec/Kconfig | 7 + drivers/usb/typec/Makefile | 1 + drivers/usb/typec/altmodes/displayport.c | 2 +- drivers/usb/typec/rts5453.c | 707 + drivers/video/backlight/Kconfig | 1 + drivers/video/backlight/pwm_bl.c | 81 +- drivers/watchdog/Kconfig | 14 + drivers/watchdog/Makefile | 1 + drivers/watchdog/sbsa_gwdt.c | 5 +- drivers/watchdog/sky1_wdt.c | 431 + fs/eventfd.c | 9 + fs/eventpoll.c | 9 + fs/pipe.c | 9 + fs/pstore/platform.c | 7 + fs/pstore/ram.c | 27 +- include/acpi/cppc_acpi.h | 11 + include/acpi/processor.h | 1 + include/dfx/hiview_hisysevent.h | 67 + include/dfx/hungtask_base.h | 111 + include/drm/drm_debugfs.h | 6 +- include/drm/drm_gem.h | 8 +- include/drm/drm_gpuvm.h | 1247 + include/drm/drm_mode_object.h | 2 +- include/drm/drm_panel.h | 1 + include/drm/gpu_scheduler.h | 119 +- include/dt-bindings/clock/sky1-audss.h | 71 + include/dt-bindings/clock/sky1-clk.h | 278 + include/dt-bindings/phy/phy-cadence-torrent.h | 62 + include/dt-bindings/pinctrl/pads-sky1.h | 587 + include/dt-bindings/power/sky1-power.h | 48 + include/dt-bindings/reset/sky1-reset-audss.h | 23 + include/dt-bindings/reset/sky1-reset-fch.h | 44 + include/dt-bindings/reset/sky1-reset.h | 166 + include/dt-bindings/thermal/sky1-thermal.h | 29 + include/linux/acpi.h | 21 + include/linux/acpi_clk-scmi.h | 60 + include/linux/acpi_pd-scmi.h | 43 + include/linux/cix/cix_scmi_em.h | 30 + include/linux/devfreq_cooling.h | 37 + include/linux/dma-buf.h | 74 + include/linux/dma-heap.h | 10 + include/linux/firmware/cix/dsp.h | 85 + include/linux/fwnode.h | 3 + include/linux/i3c/device.h | 1 + include/linux/i3c/i3cdev.h | 10 + include/linux/io-pgtable.h | 34 + include/linux/mailbox_controller.h | 5 +- include/linux/mfd/syscon.h | 9 + include/linux/mpam_policy.h | 10 + include/linux/pci.h | 28 +- include/linux/pci_ids.h | 3 + include/linux/perf_event.h | 1 + include/linux/pinctrl/pinctrl.h | 15 + .../linux/platform_data/cros_ec_commands.h | 85 +- include/linux/platform_data/cros_ec_proto.h | 3 + include/linux/pm_domain.h | 26 + include/linux/printk.h | 3 + include/linux/profile.h | 45 + include/linux/property.h | 3 + include/linux/regulator/driver.h | 7 + include/linux/regulator/fwnode_regulator.h | 23 + include/linux/rpmsg.h | 13 + include/linux/sched.h | 16 + include/linux/scmi_protocol.h | 39 + include/linux/soc/cix/boot_postcode.h | 16 + include/linux/soc/cix/cix_ap2se_ipc.h | 40 + include/linux/soc/cix/cix_ddr_lp.h | 11 + include/linux/soc/cix/cix_hibernate.h | 28 + include/linux/soc/cix/cix_suspend.h | 24 + include/linux/soc/cix/dsm_error_id.h | 10 + include/linux/soc/cix/dsm_pub.h | 207 + .../linux/soc/cix/dst_audio_timeout_error.h | 8 + include/linux/soc/cix/dst_fdleak.h | 111 + include/linux/soc/cix/dst_hung_task_ext.h | 32 + include/linux/soc/cix/dst_logger.h | 109 + include/linux/soc/cix/dst_rcsu_gasket_error.h | 6 + include/linux/soc/cix/dst_reboot_reason.h | 17 + include/linux/soc/cix/hw_boottime.h | 41 + include/linux/soc/cix/mntn_dump.h | 28 + include/linux/soc/cix/plat_hw_breakpoint.h | 173 + include/linux/soc/cix/printk_ext.h | 6 + include/linux/soc/cix/rdr_platform.h | 106 + include/linux/soc/cix/rdr_platform_ap_hook.h | 168 + .../soc/cix/rdr_platform_ap_ringbuffer.h | 47 + include/linux/soc/cix/rdr_pub.h | 486 + include/linux/soc/cix/rdr_types.h | 22 + include/linux/soc/cix/util.h | 110 + include/linux/thermal.h | 1 + include/linux/usb/role.h | 1 + include/net/cnss2.h | 319 + include/net/cnss_utils.h | 43 + include/net/qcn_sdio_al.h | 296 + include/sound/hda_codec.h | 1 + include/sound/hdaudio.h | 6 + include/sound/simple_card_utils.h | 27 +- include/sound/soc.h | 4 + include/sound/sof/dai-cix.h | 56 + include/sound/sof/dai.h | 5 + include/trace/events/dsu_pctrl.h | 38 + include/trace/hooks/sched.h | 64 + include/trace/hooks/vendor_hooks.h | 122 + include/uapi/drm/panthor_drm.h | 1017 + include/uapi/linux/arm_sdei.h | 2 + include/uapi/linux/i3c/device.h | 13 + include/uapi/linux/i3c/i3cdev.h | 34 + include/uapi/linux/pci_regs.h | 2 + include/uapi/linux/perf_event.h | 10 + include/uapi/linux/videodev2.h | 27 + include/uapi/sound/sof/tokens.h | 20 + init/Kconfig | 5 + init/main.c | 11 + init/version.c | 149 + kernel/dma/coherent.c | 4 +- kernel/exit.c | 2 + kernel/hung_task.c | 34 +- kernel/irq/irqdesc.c | 19 +- kernel/notifier.c | 11 +- kernel/power/suspend.c | 10 + kernel/printk/Makefile | 1 + kernel/printk/printk.c | 20 +- kernel/profile.c | 73 + kernel/sched/Makefile | 2 + kernel/sched/core.c | 61 +- kernel/sched/fair.c | 22 +- kernel/sched/mpam_policy.c | 407 + kernel/sched/rt.c | 4 + kernel/sched/sched.h | 6 + kernel/sched/vendor_hooks.c | 18 + kernel/softirq.c | 19 +- kernel/time/clocksource.c | 7 + kernel/time/sched_clock.c | 4 + kernel/tracepoint.c | 78 + kernel/workqueue.c | 9 + lib/nmi_backtrace.c | 14 +- mm/percpu.c | 9 + mm/slab_common.c | 14 + mm/vmalloc.c | 2 +- net/rfkill/Kconfig | 16 + net/rfkill/Makefile | 2 + net/rfkill/rfkill-bt.c | 413 + net/rfkill/rfkill-bt.h | 44 + net/rfkill/rfkill-wlan.c | 135 + net/socket.c | 10 + scripts/checkpatch.pl | 1 + scripts/headers_install.sh | 1 + scripts/package/builddeb | 4 +- sound/core/info.c | 1 + sound/hda/hdac_controller.c | 27 +- sound/hda/hdac_device.c | 1 + sound/hda/hdac_stream.c | 17 +- sound/pci/hda/Kconfig | 13 + sound/pci/hda/Makefile | 2 + sound/pci/hda/hda_cix_ipbloq.c | 900 + sound/pci/hda/hda_codec.c | 73 +- sound/pci/hda/hda_controller.c | 11 +- sound/pci/hda/patch_realtek.c | 14 + sound/soc/Kconfig | 1 + sound/soc/Makefile | 1 + sound/soc/cix/Kconfig | 27 + sound/soc/cix/Makefile | 9 + sound/soc/cix/card-utils.c | 995 + sound/soc/cix/card-utils.h | 72 + sound/soc/cix/cdns_i2s_mc.c | 1203 + sound/soc/cix/cdns_i2s_sc.c | 1253 + sound/soc/cix/sky1-card.c | 73 + sound/soc/codecs/Kconfig | 11 + sound/soc/codecs/Makefile | 7 + sound/soc/codecs/dummy-codec.c | 103 + sound/soc/codecs/es8326.c | 310 +- sound/soc/codecs/rt5682s.c | 42 +- sound/soc/codecs/rt5682s.h | 4 +- sound/soc/codecs/sn6040.c | 1786 ++ sound/soc/codecs/sn6040.h | 543 + sound/soc/generic/simple-card-utils.c | 72 + sound/soc/generic/simple-card.c | 6 + sound/soc/soc-core.c | 104 + sound/soc/sof/Kconfig | 1 + sound/soc/sof/Makefile | 1 + sound/soc/sof/cix/Kconfig | 34 + sound/soc/sof/cix/Makefile | 6 + sound/soc/sof/cix/cix-common.c | 105 + sound/soc/sof/cix/cix-common.h | 30 + sound/soc/sof/cix/cix-sky1.c | 585 + sound/soc/sof/ipc3-pcm.c | 20 + sound/soc/sof/ipc3-topology.c | 128 + sound/soc/sof/sof-audio.h | 2 + sound/soc/sof/topology.c | 11 +- tools/fdleak_test/.gitignore | 5 + tools/fdleak_test/Build | 1 + tools/fdleak_test/Makefile | 58 + tools/fdleak_test/fdleak_test.c | 57 + 1045 files changed, 281049 insertions(+), 2087 deletions(-) create mode 100644 Documentation/devicetree/bindings/arm/cix.yaml create mode 100644 Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml create mode 100755 Documentation/devicetree/bindings/dma/arm_dma350.txt create mode 100644 Documentation/devicetree/bindings/hwlock/sky1-hwspinlock.yaml create mode 100644 Documentation/devicetree/bindings/mailbox/cix-mailbox.yaml create mode 100644 Documentation/devicetree/bindings/pinctrl/cix,sky1-pinctrl.yaml create mode 100644 Documentation/devicetree/bindings/pwm/sky1-pwm.yaml create mode 100644 Documentation/devicetree/bindings/remoteproc/cix_dsp_rproc.yaml create mode 100644 Documentation/devicetree/bindings/remoteproc/cix_sfh_rproc.yaml create mode 100644 Documentation/devicetree/bindings/reset/cix,sky1-src.yaml create mode 100644 Documentation/devicetree/bindings/soc/cix/cix,ddr_exception.yaml create mode 100644 Documentation/devicetree/bindings/soc/cix/cix,se_pm_execption.yaml create mode 100644 Documentation/devicetree/bindings/sound/alc256.txt create mode 100644 Documentation/devicetree/bindings/sound/alc257.txt create mode 100644 Documentation/devicetree/bindings/sound/alc269.txt create mode 100644 Documentation/devicetree/bindings/sound/alc3287.txt create mode 100644 Documentation/devicetree/bindings/sound/cdns,i2s-mc.yaml create mode 100644 Documentation/devicetree/bindings/sound/cdns,i2s-sc.yaml create mode 100644 Documentation/devicetree/bindings/sound/cix,sky1-card.yaml create mode 100644 Documentation/devicetree/bindings/sound/ipbloq,hda.yaml create mode 100644 Documentation/devicetree/bindings/timer/timer-sky1-gpt.yaml create mode 100644 Documentation/devicetree/bindings/watchdog/sky1-watchdog.yaml create mode 100644 Documentation/driver-api/pin-control-acpi.rst create mode 100644 arch/arm64/boot/dts/cix/Makefile create mode 100644 arch/arm64/boot/dts/cix/sky1-batura.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-cloudbook.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-crb.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-emu-pm.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-emu-smp.dts create mode 100755 arch/arm64/boot/dts/cix/sky1-emu.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-csidma.dtsi create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-display.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-hda-alc256.dts create mode 100755 arch/arm64/boot/dts/cix/sky1-evb-iso.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-isp.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-isp.dtsi create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-lt7911uxc-audio.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-npu-resmem.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x1.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x2.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x4.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pciex10.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pciex11.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pciex2.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pciex4.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-pciex8.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-sof-alc5682-alc1019.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-evb-usb4_5.dts create mode 100755 arch/arm64/boot/dts/cix/sky1-evb.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-fpga.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin-pwm.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dtsi create mode 100644 arch/arm64/boot/dts/cix/sky1-orion-o6-40pin.dts create mode 100644 arch/arm64/boot/dts/cix/sky1-orion-o6.dts create mode 100755 arch/arm64/boot/dts/cix/sky1.dtsi create mode 100755 arch/arm64/configs/cix.config create mode 100644 arch/arm64/configs/cix_cloudbook.config create mode 100755 arch/arm64/configs/cix_debug.config create mode 100644 arch/arm64/configs/cix_emu.config create mode 100644 arch/arm64/configs/cix_fpga.config create mode 100644 arch/arm64/configs/cix_redroid.config create mode 100644 arch/arm64/kernel/cix_dmi.c create mode 100644 arch/arm64/kernel/cix_dmi.h create mode 100644 drivers/acpi/cix_acpi_pd.c create mode 100644 drivers/acpi/device_perf.c create mode 100644 drivers/acpi/thermal.h create mode 100644 drivers/android/mpam_arch.c create mode 100644 drivers/android/mpam_arch.h create mode 100644 drivers/android/mpam_arch_internal.h create mode 100644 drivers/bluetooth/rtk_btusb.c create mode 100644 drivers/bluetooth/rtk_btusb.h create mode 100644 drivers/char/hw_random/sky1-rng.c create mode 100644 drivers/clk/cix/Kconfig create mode 100644 drivers/clk/cix/Makefile create mode 100644 drivers/clk/cix/acpi_clk.c create mode 100644 drivers/clk/cix/acpi_clk.h create mode 100644 drivers/clk/cix/acpi_scmi_clk.c create mode 100755 drivers/clk/cix/cix-clk-debug.c create mode 100644 drivers/clk/cix/clk-sky1-audss.c create mode 100644 drivers/clk/cix/clk.c create mode 100644 drivers/clk/cix/clk.h create mode 100644 drivers/clocksource/timer-sky1-gpt.c create mode 100644 drivers/cpufreq/cix-cpufreq-dt.c create mode 100644 drivers/devfreq/cix-bus.c create mode 100644 drivers/devfreq/dsu-pctrl-devfreq.c create mode 100644 drivers/devfreq/event/cix-pmu.c create mode 100644 drivers/dma-buf/heaps/deferred-free-helper.c create mode 100644 drivers/dma-buf/heaps/deferred-free-helper.h create mode 100644 drivers/dma-buf/heaps/dsp_heap.c create mode 100644 drivers/dma-buf/heaps/page_pool.c create mode 100644 drivers/dma-buf/heaps/page_pool.h create mode 100644 drivers/dma-buf/heaps/vpu_heap.c create mode 100755 drivers/dma/arm_dma350.c create mode 100755 drivers/dma/dma350_ch_drv.h create mode 100755 drivers/dma/dma350_regdef.h create mode 100644 drivers/firmware/cix/Kconfig create mode 100644 drivers/firmware/cix/Makefile create mode 100644 drivers/firmware/cix/cix-dsp.c create mode 100644 drivers/gpu/drm/cix/Kconfig create mode 100644 drivers/gpu/drm/cix/Makefile create mode 100644 drivers/gpu/drm/cix/cix_display.c create mode 100644 drivers/gpu/drm/cix/cix_virtual.c create mode 100644 drivers/gpu/drm/cix/dptx/Kconfig create mode 100644 drivers/gpu/drm/cix/dptx/Makefile create mode 100644 drivers/gpu/drm/cix/dptx/cix_edp_panel.c create mode 100755 drivers/gpu/drm/cix/dptx/cix_edp_panel.h create mode 100644 drivers/gpu/drm/cix/dptx/dptx_infoframe.c create mode 100644 drivers/gpu/drm/cix/dptx/dptx_infoframe.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/cix_hdcp.c create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/cix_hdcp.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/cix_hdcp_ioctl.c create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/cix_hdcp_ioctl.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/cix_hdcp_ioctl_cmd.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/dptx_aux_reg.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/dptx_reg.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_hw_tx.c create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_hw_tx.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_key_drvn_tx.c create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_key_drvn_tx.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_tx_state.c create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_tx_state.h create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_tx_tmr.c create mode 100644 drivers/gpu/drm/cix/dptx/hdcp/hdcp2_tx_tmr.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_dptx.c create mode 100644 drivers/gpu/drm/cix/dptx/trilin_dptx.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_dptx_audio.c create mode 100644 drivers/gpu/drm/cix/dptx/trilin_dptx_audio.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_dptx_cix.c create mode 100644 drivers/gpu/drm/cix/dptx/trilin_dptx_reg.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_drm.c create mode 100644 drivers/gpu/drm/cix/dptx/trilin_drm.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_drm_mst.c create mode 100755 drivers/gpu/drm/cix/dptx/trilin_drm_mst.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_edp_phy.c create mode 100644 drivers/gpu/drm/cix/dptx/trilin_edp_phy.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_host_tmr.c create mode 100644 drivers/gpu/drm/cix/dptx/trilin_host_tmr.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_phy.h create mode 100644 drivers/gpu/drm/cix/dptx/trilin_usbdp_phy.c create mode 100644 drivers/gpu/drm/cix/dptx/trilin_usbdp_phy.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/Makefile create mode 100644 drivers/gpu/drm/cix/linlon-dp/hw/dp_axi.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/hw/dp_component.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/hw/dp_dev.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/hw/dp_dev.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/hw/dp_regs.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/include/linlondp_drm.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/include/linlondp_io.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/include/linlondp_product.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/include/linlondp_utils.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_coeffs.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_coeffs.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_color_mgmt.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_color_mgmt.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_crtc.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_dev.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_dev.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_drv.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_event.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_format_caps.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_format_caps.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_framebuffer.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_framebuffer.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_io.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_kms.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_kms.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_pipeline.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_pipeline.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_pipeline_state.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_plane.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_private_obj.c create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_product.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_utils.h create mode 100644 drivers/gpu/drm/cix/linlon-dp/linlondp_wb_connector.c create mode 100644 drivers/gpu/drm/drm_gpuvm.c create mode 100644 drivers/gpu/drm/panthor/Kconfig create mode 100644 drivers/gpu/drm/panthor/Makefile create mode 100644 drivers/gpu/drm/panthor/panthor_devfreq.c create mode 100644 drivers/gpu/drm/panthor/panthor_devfreq.h create mode 100644 drivers/gpu/drm/panthor/panthor_device.c create mode 100644 drivers/gpu/drm/panthor/panthor_device.h create mode 100644 drivers/gpu/drm/panthor/panthor_drv.c create mode 100644 drivers/gpu/drm/panthor/panthor_fw.c create mode 100644 drivers/gpu/drm/panthor/panthor_fw.h create mode 100644 drivers/gpu/drm/panthor/panthor_gem.c create mode 100644 drivers/gpu/drm/panthor/panthor_gem.h create mode 100644 drivers/gpu/drm/panthor/panthor_gpu.c create mode 100644 drivers/gpu/drm/panthor/panthor_gpu.h create mode 100644 drivers/gpu/drm/panthor/panthor_heap.c create mode 100644 drivers/gpu/drm/panthor/panthor_heap.h create mode 100644 drivers/gpu/drm/panthor/panthor_mmu.c create mode 100644 drivers/gpu/drm/panthor/panthor_mmu.h create mode 100644 drivers/gpu/drm/panthor/panthor_regs.h create mode 100644 drivers/gpu/drm/panthor/panthor_sched.c create mode 100644 drivers/gpu/drm/panthor/panthor_sched.h create mode 100644 drivers/hwspinlock/sky1_hwspinlock.c create mode 100755 drivers/i3c/i3cdev.c mode change 100644 => 100755 drivers/i3c/master/i3c-master-cdns.c create mode 100644 drivers/iio/imu/inv_icm42600/cix_regmap_ref_spi.c mode change 100644 => 100755 drivers/iio/magnetometer/Kconfig mode change 100644 => 100755 drivers/iio/magnetometer/Makefile create mode 100755 drivers/iio/magnetometer/mmc5633_i2c.c create mode 100644 drivers/iio/magnetometer/mmc5633_i3c.c create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-debug.c create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-dump.c create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-dump.h create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-walk.c create mode 100644 drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3-walk.h create mode 100644 drivers/irqchip/irq-sky1-pdc.c create mode 100644 drivers/mailbox/cix-mailbox.c create mode 100644 drivers/media/i2c/cix/lt7911uxc/Makefile create mode 100644 drivers/media/i2c/cix/lt7911uxc/lt7911uxc.c create mode 100644 drivers/media/i2c/cix/lt7911uxc/lt7911uxc.h create mode 100755 drivers/media/platform/cadence/cdns-csi2rx.h create mode 100644 drivers/media/platform/cix/Kconfig create mode 100755 drivers/media/platform/cix/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/armcb_isp_entry.c create mode 100755 drivers/media/platform/cix/cix_isp/cixvihw/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/cixvihw/cix_vi_hw.c create mode 100755 drivers/media/platform/cix/cix_isp/cixvihw/cix_vi_hw.h create mode 100755 drivers/media/platform/cix/cix_isp/common/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/common/armcb_camera_io_drv.c create mode 100644 drivers/media/platform/cix/cix_isp/common/armcb_camera_io_drv.h create mode 100644 drivers/media/platform/cix/cix_isp/common/armcb_isp.h create mode 100755 drivers/media/platform/cix/cix_isp/common/armcb_register.h create mode 100755 drivers/media/platform/cix/cix_isp/common/armcb_v4l_sd.c create mode 100755 drivers/media/platform/cix/cix_isp/common/armcb_v4l_sd.h create mode 100755 drivers/media/platform/cix/cix_isp/common/isp_hw_if/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/common/isp_hw_if/isp_hw_ops.c create mode 100755 drivers/media/platform/cix/cix_isp/common/isp_hw_if/isp_hw_ops.h create mode 100755 drivers/media/platform/cix/cix_isp/common/isp_hw_if/isp_hw_utils.c create mode 100755 drivers/media/platform/cix/cix_isp/common/isp_hw_if/isp_hw_utils.h create mode 100755 drivers/media/platform/cix/cix_isp/common/system_dma.c create mode 100755 drivers/media/platform/cix/cix_isp/common/system_dma.h create mode 100755 drivers/media/platform/cix/cix_isp/common/types_utils.h create mode 100755 drivers/media/platform/cix/cix_isp/isp/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_isp_driver.c create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_isp_driver.h create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_isp_hw_reg.h create mode 100644 drivers/media/platform/cix/cix_isp/isp/armcb_v4l2_config.c create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_v4l2_config.h create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_v4l2_core.c create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_v4l2_core.h create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_v4l2_stream.c create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_v4l2_stream.h create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_vb2.c create mode 100755 drivers/media/platform/cix/cix_isp/isp/armcb_vb2.h create mode 100755 drivers/media/platform/cix/cix_isp/platform/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/platform/armcb_platform.c create mode 100755 drivers/media/platform/cix/cix_isp/platform/armcb_platform.h create mode 100755 drivers/media/platform/cix/cix_isp/platform/bus/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/platform/bus/i2c/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/platform/bus/i2c/system_i2c.c create mode 100755 drivers/media/platform/cix/cix_isp/platform/bus/i2c/system_i2c.h create mode 100755 drivers/media/platform/cix/cix_isp/platform/bus/spi/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/platform/bus/spi/system_spi.c create mode 100755 drivers/media/platform/cix/cix_isp/platform/bus/spi/system_spi.h create mode 100755 drivers/media/platform/cix/cix_isp/platform/hdmi/system_hdmi.c create mode 100755 drivers/media/platform/cix/cix_isp/platform/logger/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/platform/logger/system_logger.c create mode 100755 drivers/media/platform/cix/cix_isp/platform/logger/system_logger.h create mode 100755 drivers/media/platform/cix/cix_isp/sensor/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/sensor/actuator/Makefile create mode 100755 drivers/media/platform/cix/cix_isp/sensor/actuator/armcb_actuator.c create mode 100755 drivers/media/platform/cix/cix_isp/sensor/actuator/armcb_actuator.h create mode 100755 drivers/media/platform/cix/cix_isp/sensor/armcb_sensor.c create mode 100644 drivers/media/platform/cix/cix_isp/sensor/armcb_sensor.h create mode 100755 drivers/media/platform/cix/csi_dma/Makefile create mode 100644 drivers/media/platform/cix/csi_dma/csi_bridge_hw.c create mode 100755 drivers/media/platform/cix/csi_dma/csi_bridge_hw.h create mode 100644 drivers/media/platform/cix/csi_dma/csi_common.h create mode 100644 drivers/media/platform/cix/csi_dma/csi_dma_cap.c create mode 100755 drivers/media/platform/cix/csi_dma/csi_dma_cap.h create mode 100644 drivers/media/platform/cix/csi_dma/csi_dma_core.c create mode 100644 drivers/media/platform/cix/csi_dma/csi_mipi_csi2.c create mode 100644 drivers/media/platform/cix/csi_dma/csi_mipi_dphy_hw.c create mode 100644 drivers/media/platform/cix/csi_dma/csi_mipi_dphy_rx.c create mode 100644 drivers/media/platform/cix/csi_dma/csi_rcsu_hw.c create mode 100644 drivers/media/platform/cix/csi_dma/csi_rcsu_hw.h create mode 100644 drivers/media/platform/cix/linlon-aeu/Kconfig create mode 100755 drivers/media/platform/cix/linlon-aeu/Makefile create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu.c create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_dev.h create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_hw.c create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_hw.h create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_io.h create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_log.c create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_log.h create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_reg_dump.c create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_reg_dump.h create mode 100755 drivers/media/platform/cix/linlon-aeu/linlon_aeu_v4l2.c create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/Kconfig create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/Makefile create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/cix_sensorhub.c create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/cix_sensorhub.h create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/sensor_list.c create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/sensor_list.h create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/sensorhub_ipi.c create mode 100644 drivers/misc/cix/sensor/cix_sensorhub/sensorhub_ipi.h create mode 100644 drivers/misc/cix/sensor/core/Kconfig create mode 100644 drivers/misc/cix/sensor/core/Makefile create mode 100644 drivers/misc/cix/sensor/core/hf_manager.c create mode 100644 drivers/misc/cix/sensor/core/hf_manager.h create mode 100644 drivers/misc/cix/sensor/core/hf_sensor_io.h create mode 100644 drivers/misc/cix/sensor/core/hf_sensor_type.h create mode 100644 drivers/misc/cix/sensor/scp/Kconfig create mode 100644 drivers/misc/cix/sensor/scp/Makefile create mode 100644 drivers/misc/cix/sensor/scp/include/scp.h create mode 100644 drivers/misc/cix/sensor/scp/scp_helper.c create mode 100644 drivers/misc/cix/sensor/scp/scp_helper.h create mode 100644 drivers/misc/cix/sensor/scp/scp_reservedmem_define.h create mode 100644 drivers/misc/cix/sensor/test/Kconfig create mode 100644 drivers/misc/cix/sensor/test/Makefile create mode 100644 drivers/misc/cix/sensor/test/test.c create mode 100644 drivers/misc/cix/sensor/test/test_app.c create mode 100644 drivers/misc/cix/sensor/test/test_app1.c create mode 100644 drivers/misc/cix/sensor/test/test_app2.c mode change 100644 => 100755 drivers/mtd/spi-nor/winbond.c create mode 100644 drivers/net/ethernet/realtek/pg_tool/Makefile create mode 100644 drivers/net/ethernet/realtek/pg_tool/pgdrv.c create mode 100644 drivers/net/ethernet/realtek/pg_tool/pgdrv.h create mode 100644 drivers/net/ethernet/realtek/r8125/Makefile create mode 100644 drivers/net/ethernet/realtek/r8125/Makefile_linux24x create mode 100644 drivers/net/ethernet/realtek/r8125/README create mode 100644 drivers/net/ethernet/realtek/r8125/r8125.h create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_dash.h create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_firmware.c create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_firmware.h create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_n.c create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_ptp.c create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_ptp.h create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_realwow.h create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_rss.c create mode 100644 drivers/net/ethernet/realtek/r8125/r8125_rss.h create mode 100644 drivers/net/ethernet/realtek/r8125/rtl_eeprom.c create mode 100644 drivers/net/ethernet/realtek/r8125/rtl_eeprom.h create mode 100644 drivers/net/ethernet/realtek/r8125/rtltool.c create mode 100644 drivers/net/ethernet/realtek/r8125/rtltool.h create mode 100644 drivers/net/ethernet/realtek/r8126/Makefile create mode 100644 drivers/net/ethernet/realtek/r8126/Makefile_linux24x create mode 100644 drivers/net/ethernet/realtek/r8126/r8126.h create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_dash.h create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_firmware.c create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_firmware.h create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_n.c create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_ptp.c create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_ptp.h create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_realwow.h create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_rss.c create mode 100644 drivers/net/ethernet/realtek/r8126/r8126_rss.h create mode 100644 drivers/net/ethernet/realtek/r8126/rtl_eeprom.c create mode 100644 drivers/net/ethernet/realtek/r8126/rtl_eeprom.h create mode 100644 drivers/net/ethernet/realtek/r8126/rtltool.c create mode 100644 drivers/net/ethernet/realtek/r8126/rtltool.h create mode 100644 drivers/net/ethernet/realtek/r8127/Makefile create mode 100644 drivers/net/ethernet/realtek/r8127/Makefile_linux24x create mode 100644 drivers/net/ethernet/realtek/r8127/r8127.h create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_dash.h create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_firmware.c create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_firmware.h create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_n.c create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_ptp.c create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_ptp.h create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_realwow.h create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_rss.c create mode 100644 drivers/net/ethernet/realtek/r8127/r8127_rss.h create mode 100644 drivers/net/ethernet/realtek/r8127/rtl_eeprom.c create mode 100644 drivers/net/ethernet/realtek/r8127/rtl_eeprom.h create mode 100644 drivers/net/ethernet/realtek/r8127/rtltool.c create mode 100644 drivers/net/ethernet/realtek/r8127/rtltool.h create mode 100644 drivers/nvmem/sky1_nvmem.c create mode 100644 drivers/pci/controller/cadence/pci-sky1-debugfs.c create mode 100644 drivers/pci/controller/cadence/pci-sky1-debugfs.h create mode 100644 drivers/pci/controller/cadence/pci-sky1.c create mode 100644 drivers/pci/controller/cadence/pci-sky1.h create mode 100755 drivers/phy/cadence/cdns-dphy-rx.h create mode 100644 drivers/phy/cix/Kconfig create mode 100644 drivers/phy/cix/Makefile create mode 100644 drivers/phy/cix/phy-cix-pcie.c create mode 100644 drivers/phy/cix/phy-cix-usb2.c create mode 100644 drivers/phy/cix/phy-cix-usb3.c create mode 100644 drivers/phy/cix/phy-cix-usbdp.c create mode 100644 drivers/phy/cix/phy-cix-usbdp.h create mode 100644 drivers/pinctrl/cix/Kconfig create mode 100644 drivers/pinctrl/cix/Makefile create mode 100644 drivers/pinctrl/cix/pinctrl-sky1-base.c create mode 100644 drivers/pinctrl/cix/pinctrl-sky1.c create mode 100644 drivers/pinctrl/cix/pinctrl-sky1.h create mode 100644 drivers/pinctrl/pinctrl-acpi.c create mode 100644 drivers/pinctrl/pinctrl-acpi.h create mode 100644 drivers/platform/chrome/cix_ec/Kconfig create mode 100644 drivers/platform/chrome/cix_ec/Makefile create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_battery.c create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_charge.c create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_fan.c create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_gpio.c create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_kb_backlight.c create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_lid.c create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_light.c create mode 100644 drivers/platform/chrome/cix_ec/cix_ec_pwrkey.c create mode 100644 drivers/pwm/pwm-sky1.c create mode 100644 drivers/regulator/fwnode_regulator.c create mode 100644 drivers/remoteproc/cix_dsp_rproc.c create mode 100755 drivers/remoteproc/cix_sfh_rproc.c create mode 100644 drivers/reset/reset-sky1-audss.c create mode 100644 drivers/reset/reset-sky1.c create mode 100755 drivers/rtc/rtc-rx8900.c create mode 100644 drivers/soc/arm/Makefile create mode 100644 drivers/soc/arm/scmi_perf_domain.c create mode 100755 drivers/soc/cix/Kconfig create mode 100755 drivers/soc/cix/Makefile create mode 100644 drivers/soc/cix/acpi/Makefile create mode 100644 drivers/soc/cix/acpi/acpi_resource_lookup.c create mode 100644 drivers/soc/cix/acpi/cix-acpi-plat.c create mode 100644 drivers/soc/cix/acpi/cix-fan-mode.c create mode 100644 drivers/soc/cix/acpi/dsdt_override.c create mode 100644 drivers/soc/cix/acpi/reserved_memory.c create mode 100755 drivers/soc/cix/ap/platform/sky1/mntn_dump_interface.h create mode 100755 drivers/soc/cix/ap/platform/sky1/mntn_public_interface.h create mode 100755 drivers/soc/cix/ap/platform/sky1/mntn_subtype_exception.h create mode 100644 drivers/soc/cix/cix-ddr-lp.c create mode 100644 drivers/soc/cix/cix-hibernate.c create mode 100644 drivers/soc/cix/cix-plat.c create mode 100644 drivers/soc/cix/cix-se-config.c create mode 100644 drivers/soc/cix/cix-sky1-socinfo.c create mode 100644 drivers/soc/cix/cix-suspend.c create mode 100644 drivers/soc/cix/cix_ap2se_ipc.c create mode 100755 drivers/soc/cix/cix_dst/Kconfig create mode 100755 drivers/soc/cix/cix_dst/Makefile create mode 100644 drivers/soc/cix/cix_dst/blackbox/Kconfig create mode 100644 drivers/soc/cix/cix_dst/blackbox/Makefile create mode 100644 drivers/soc/cix/cix_dst/blackbox/exception_trace/Makefile create mode 100755 drivers/soc/cix/cix_dst/blackbox/exception_trace/rdr_exception_trace.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/exception_trace/rdr_exception_trace.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/exception_trace/rdr_exception_trace_ap.c create mode 100755 drivers/soc/cix/cix_dst/blackbox/platform_ap/Makefile create mode 100755 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_adapter.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_hook.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_logbuf.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_memid.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_moddump.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_regdump.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_stack.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/include/rdr_ap_suspend.h create mode 100755 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_adapter.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_exception.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_hook.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_moddump.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_pstore.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_regdump.c create mode 100755 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_ringbuffer.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_stack.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/platform_ap/rdr_ap_suspend.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_bootcheck.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_cleartext.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_common.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_core.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_dump_core.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_exception_core.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_exception_test.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_field.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_field_core.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_inner.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_logmonitor_core.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_module_core.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_print.h create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_reboot_reason.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_safemem.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_utils.c create mode 100644 drivers/soc/cix/cix_dst/blackbox/rdr_utils.h create mode 100755 drivers/soc/cix/cix_dst/boot_postcode.c create mode 100644 drivers/soc/cix/cix_dst/cache_exception_monitor/Kconfig create mode 100644 drivers/soc/cix/cix_dst/cache_exception_monitor/Makefile create mode 100644 drivers/soc/cix/cix_dst/cache_exception_monitor/cache_core_exception_drv.c create mode 100644 drivers/soc/cix/cix_dst/cache_exception_monitor/cache_dsu_exception_drv.c create mode 100644 drivers/soc/cix/cix_dst/cache_exception_monitor/cache_exception_interface.c create mode 100644 drivers/soc/cix/cix_dst/cache_exception_monitor/cache_exception_interface.h create mode 100755 drivers/soc/cix/cix_dst/dsm/Kconfig create mode 100755 drivers/soc/cix/cix_dst/dsm/Makefile create mode 100755 drivers/soc/cix/cix_dst/dsm/dsm_core.c create mode 100755 drivers/soc/cix/cix_dst/dsm/dsm_core.h create mode 100755 drivers/soc/cix/cix_dst/dsm/dsm_errno.h create mode 100644 drivers/soc/cix/cix_dst/dsm/dsm_plat.c create mode 100755 drivers/soc/cix/cix_dst/dsm/dsm_test.c create mode 100755 drivers/soc/cix/cix_dst/dst_audio_timeout_error.c create mode 100644 drivers/soc/cix/cix_dst/dst_ddr_exception.c create mode 100755 drivers/soc/cix/cix_dst/dst_fdleak_main.c create mode 100755 drivers/soc/cix/cix_dst/dst_print.h create mode 100755 drivers/soc/cix/cix_dst/dst_rcsu_gasket_error.c create mode 100755 drivers/soc/cix/cix_dst/dst_reboot_reason.c create mode 100755 drivers/soc/cix/cix_dst/dst_sdei_exceptions.c create mode 100755 drivers/soc/cix/cix_dst/dst_sdei_ni700_idm.c create mode 100755 drivers/soc/cix/cix_dst/dst_sdei_tee_exceptions.c create mode 100755 drivers/soc/cix/cix_dst/dst_sdei_tfa_trace.c create mode 100755 drivers/soc/cix/cix_dst/dst_sdei_tzc400.c create mode 100644 drivers/soc/cix/cix_dst/dst_wakeup_source.c create mode 100755 drivers/soc/cix/cix_dst/hw_boottime.c create mode 100755 drivers/soc/cix/cix_dst/hw_breakpoint/Kconfig create mode 100755 drivers/soc/cix/cix_dst/hw_breakpoint/Makefile create mode 100755 drivers/soc/cix/cix_dst/hw_breakpoint/hw_breakpoint_plat.c create mode 100755 drivers/soc/cix/cix_dst/hw_breakpoint/hw_breakpoint_proc.c create mode 100755 drivers/soc/cix/cix_dst/hw_breakpoint/hw_breakpoint_trigger.c create mode 100644 drivers/soc/cix/cix_dst/hw_breakpoint/hw_breakpoint_until.c create mode 100644 drivers/soc/cix/cix_dst/hw_breakpoint/hw_breakpoint_until.h create mode 100755 drivers/soc/cix/cix_dst/logger/Kconfig create mode 100755 drivers/soc/cix/cix_dst/logger/Makefile create mode 100755 drivers/soc/cix/cix_dst/logger/dst_logger.c create mode 100755 drivers/soc/cix/cix_dst/memory_dump/Kconfig create mode 100755 drivers/soc/cix/cix_dst/memory_dump/Makefile create mode 100755 drivers/soc/cix/cix_dst/memory_dump/kernel_dump.c create mode 100755 drivers/soc/cix/cix_dst/memory_dump/kernel_dump.h create mode 100755 drivers/soc/cix/cix_dst/mntn_dump.c create mode 100755 drivers/soc/cix/cix_dst/pm_exception_monitor/Kconfig create mode 100644 drivers/soc/cix/cix_dst/pm_exception_monitor/Makefile create mode 100644 drivers/soc/cix/cix_dst/pm_exception_monitor/pm_exception_drv.c create mode 100644 drivers/soc/cix/cix_dst/pm_exception_monitor/pm_exception_drv.h create mode 100644 drivers/soc/cix/cix_dst/pm_exception_monitor/pm_exception_dsm.c create mode 100644 drivers/soc/cix/cix_dst/pm_exception_monitor/pm_exception_dsm.h create mode 100644 drivers/soc/cix/cix_dst/pm_exception_monitor/pm_exception_ec_drv.c create mode 100644 drivers/soc/cix/cix_dst/pm_exception_monitor/pm_exception_protocol.c create mode 100755 drivers/soc/cix/cix_dst/printk_ext.c create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/Kconfig create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/Makefile create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/pm_wdt.c create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/se_amu.c create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/se_clk.c create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/se_crash.h create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/se_crash_drv.c create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/se_ddr.c create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/se_power.c create mode 100644 drivers/soc/cix/cix_dst/se_crash_monitor/se_wdt.c create mode 100755 drivers/soc/cix/cix_dst/util.c create mode 100755 drivers/soc/cix/sched/Kconfig create mode 100755 drivers/soc/cix/sched/Makefile create mode 100755 drivers/soc/cix/sched/common.h create mode 100755 drivers/soc/cix/sched/core_ctl/core_ctl.c create mode 100755 drivers/soc/cix/sched/core_ctl/core_ctl.h create mode 100755 drivers/soc/cix/sched/core_ctl/core_ctl_trace.h create mode 100755 drivers/soc/cix/sched/core_ctl/core_pause.c create mode 100755 drivers/soc/cix/sched/core_ctl/core_pause.h create mode 100644 drivers/soc/cix/sched/core_ctl/core_pause_trace.h create mode 100755 drivers/soc/cix/sched/core_ctl/sched_avg.c create mode 100755 drivers/soc/cix/sched/core_ctl/sched_avg.h create mode 100755 drivers/soc/cix/sched/sched_sys_common.h mode change 100644 => 100755 drivers/spi/spi-cadence-xspi.c mode change 100644 => 100755 drivers/staging/Kconfig mode change 100644 => 100755 drivers/staging/Makefile create mode 100755 drivers/staging/android/Kconfig create mode 100755 drivers/staging/android/Makefile create mode 100755 drivers/staging/android/TODO create mode 100755 drivers/staging/android/ashmem.c create mode 100755 drivers/staging/android/ashmem.h create mode 100755 drivers/staging/android/uapi/ashmem.h create mode 100644 drivers/staging/hievent/Kconfig create mode 100644 drivers/staging/hievent/Makefile create mode 100644 drivers/staging/hievent/hievent_driver.c create mode 100644 drivers/staging/hievent/hievent_driver.h create mode 100644 drivers/staging/hievent/hiview_hievent.c create mode 100644 drivers/staging/hievent/hiview_hievent.h create mode 100644 drivers/staging/hisysevent/Kconfig create mode 100644 drivers/staging/hisysevent/Makefile create mode 100644 drivers/staging/hisysevent/hisysevent_builder.c create mode 100644 drivers/staging/hisysevent/hisysevent_builder.h create mode 100644 drivers/staging/hisysevent/hisysevent_raw_data.c create mode 100644 drivers/staging/hisysevent/hisysevent_raw_data.h create mode 100644 drivers/staging/hisysevent/hisysevent_raw_data_encoder.c create mode 100644 drivers/staging/hisysevent/hisysevent_raw_data_encoder.h create mode 100644 drivers/staging/hisysevent/hiview_hisysevent.c create mode 100755 drivers/staging/hungtask/Kconfig create mode 100755 drivers/staging/hungtask/Makefile create mode 100755 drivers/staging/hungtask/hungtask_base.c create mode 100755 drivers/staging/hungtask/hungtask_user.c create mode 100755 drivers/staging/hungtask/hungtask_user.h create mode 100644 drivers/thermal/cix/Kconfig create mode 100644 drivers/thermal/cix/Makefile create mode 100644 drivers/thermal/cix/cix_cpu_ipa.c create mode 100644 drivers/thermal/cix/cix_scmi_em.c create mode 100644 drivers/thermal/gov_acpi_dp.c mode change 100644 => 100755 drivers/tty/serial/amba-pl011.c create mode 100644 drivers/usb/cdns3/cdnsp-plat.c create mode 100644 drivers/usb/cdns3/cdnsp-sky1.c create mode 100644 drivers/usb/cdns3/cdnsp-sky1.h create mode 100644 drivers/usb/typec/rts5453.c create mode 100644 drivers/watchdog/sky1_wdt.c create mode 100644 include/dfx/hiview_hisysevent.h create mode 100755 include/dfx/hungtask_base.h create mode 100644 include/drm/drm_gpuvm.h create mode 100644 include/dt-bindings/clock/sky1-audss.h create mode 100644 include/dt-bindings/clock/sky1-clk.h create mode 100644 include/dt-bindings/phy/phy-cadence-torrent.h create mode 100644 include/dt-bindings/pinctrl/pads-sky1.h create mode 100644 include/dt-bindings/power/sky1-power.h create mode 100644 include/dt-bindings/reset/sky1-reset-audss.h create mode 100644 include/dt-bindings/reset/sky1-reset-fch.h create mode 100644 include/dt-bindings/reset/sky1-reset.h create mode 100644 include/dt-bindings/thermal/sky1-thermal.h create mode 100644 include/linux/acpi_clk-scmi.h create mode 100644 include/linux/acpi_pd-scmi.h create mode 100644 include/linux/cix/cix_scmi_em.h mode change 100644 => 100755 include/linux/dma-buf.h create mode 100644 include/linux/firmware/cix/dsp.h create mode 100644 include/linux/i3c/i3cdev.h create mode 100644 include/linux/mpam_policy.h create mode 100644 include/linux/regulator/fwnode_regulator.h create mode 100755 include/linux/soc/cix/boot_postcode.h create mode 100644 include/linux/soc/cix/cix_ap2se_ipc.h create mode 100644 include/linux/soc/cix/cix_ddr_lp.h create mode 100755 include/linux/soc/cix/cix_hibernate.h create mode 100644 include/linux/soc/cix/cix_suspend.h create mode 100644 include/linux/soc/cix/dsm_error_id.h create mode 100755 include/linux/soc/cix/dsm_pub.h create mode 100755 include/linux/soc/cix/dst_audio_timeout_error.h create mode 100755 include/linux/soc/cix/dst_fdleak.h create mode 100755 include/linux/soc/cix/dst_hung_task_ext.h create mode 100755 include/linux/soc/cix/dst_logger.h create mode 100644 include/linux/soc/cix/dst_rcsu_gasket_error.h create mode 100755 include/linux/soc/cix/dst_reboot_reason.h create mode 100755 include/linux/soc/cix/hw_boottime.h create mode 100755 include/linux/soc/cix/mntn_dump.h create mode 100644 include/linux/soc/cix/plat_hw_breakpoint.h create mode 100755 include/linux/soc/cix/printk_ext.h create mode 100755 include/linux/soc/cix/rdr_platform.h create mode 100755 include/linux/soc/cix/rdr_platform_ap_hook.h create mode 100755 include/linux/soc/cix/rdr_platform_ap_ringbuffer.h create mode 100755 include/linux/soc/cix/rdr_pub.h create mode 100755 include/linux/soc/cix/rdr_types.h create mode 100755 include/linux/soc/cix/util.h create mode 100755 include/net/cnss2.h create mode 100755 include/net/cnss_utils.h create mode 100755 include/net/qcn_sdio_al.h create mode 100644 include/sound/sof/dai-cix.h create mode 100644 include/trace/events/dsu_pctrl.h create mode 100755 include/trace/hooks/sched.h create mode 100755 include/trace/hooks/vendor_hooks.h create mode 100644 include/uapi/drm/panthor_drm.h create mode 100644 include/uapi/linux/i3c/device.h create mode 100644 include/uapi/linux/i3c/i3cdev.h create mode 100644 kernel/sched/mpam_policy.c create mode 100644 kernel/sched/vendor_hooks.c create mode 100644 net/rfkill/rfkill-bt.c create mode 100644 net/rfkill/rfkill-bt.h create mode 100644 net/rfkill/rfkill-wlan.c create mode 100644 sound/pci/hda/hda_cix_ipbloq.c create mode 100644 sound/soc/cix/Kconfig create mode 100644 sound/soc/cix/Makefile create mode 100644 sound/soc/cix/card-utils.c create mode 100644 sound/soc/cix/card-utils.h create mode 100644 sound/soc/cix/cdns_i2s_mc.c create mode 100644 sound/soc/cix/cdns_i2s_sc.c create mode 100644 sound/soc/cix/sky1-card.c create mode 100644 sound/soc/codecs/dummy-codec.c create mode 100644 sound/soc/codecs/sn6040.c create mode 100644 sound/soc/codecs/sn6040.h create mode 100644 sound/soc/sof/cix/Kconfig create mode 100644 sound/soc/sof/cix/Makefile create mode 100644 sound/soc/sof/cix/cix-common.c create mode 100644 sound/soc/sof/cix/cix-common.h create mode 100644 sound/soc/sof/cix/cix-sky1.c create mode 100644 tools/fdleak_test/.gitignore create mode 100644 tools/fdleak_test/Build create mode 100644 tools/fdleak_test/Makefile create mode 100644 tools/fdleak_test/fdleak_test.c diff --git a/Documentation/devicetree/bindings/arm/cix.yaml b/Documentation/devicetree/bindings/arm/cix.yaml new file mode 100644 index 000000000000..bc679be08d19 --- /dev/null +++ b/Documentation/devicetree/bindings/arm/cix.yaml @@ -0,0 +1,26 @@ +# SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/arm/cix.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cixcomputing SoC series device tree bindings + +maintainers: + - fugang.duan + +properties: + $nodename: + const: "/" + compatible: + oneOf: + - description: sky1 based Boards + items: + - enum: + - cix,sky1-evk # sky1 EVK Board + - cix,sky1-batura # sky1 BATURA Board + - const: cix,sky1 + +additionalProperties: true + +... diff --git a/Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml b/Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml new file mode 100644 index 000000000000..ff5ff2f067a9 --- /dev/null +++ b/Documentation/devicetree/bindings/clock/cix,sky1-audss-clock.yaml @@ -0,0 +1,80 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/clock/cix,sky1-audss-clock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cixtech Sky1 SoC Audio SubSystem Clock Controller Driver + +maintainers: + - Joakim Zhang + +description: | + All available clocks are defined as preprocessor macros in + include/dt-bindings/clock/sky1-audss.h header. + +properties: + compatible: + const: cix,sky1-audss-clock + + reg: + maxItems: 1 + + clocks: + description: + - audio_pll0 (FRAC) provides "audio_clk0" and "audio_clk1" that generates + I2S function clock, such as 8KHz, 16KHz etc, "audio_clk0" is also the clock + source of MCLK. + - audio_pll1 (FRAC) provides "audio_clk2" and "audio_clk3" that generates + I2S function clock, such as 11.025KHz, 22.5KHz etc, "audio_clk2" is also the clock + source of MCLK. + - mmsys_pll provides "audio_clk4" that generates AXI or APB clock for most devices + in audio subsystem (DSP, NOC, SRAM, HDA, DMAC, I2S, Timer and Mailbox). + - mmsys_pll provides "audio_clk5" that generates a fixed 48MHz clock for HDA, Timer + and Watchdog. + + clock-names: + minItems: 6 + items: + - const: audio_clk0 + - const: audio_clk1 + - const: audio_clk2 + - const: audio_clk3 + - const: audio_clk4 + - const: audio_clk5 + + "#clock-cells": + const: 1 + + resets: + description: signal to reset all modules in audio subsystem except HIFI5 DSP. + + reset-names: + const: noc + +required: + - compatible + - reg + - clocks + - clock-names + - "#clock-cells" + - resets + - reset-names + +additionalProperties: false + +examples: + - | + #include + + clock-controller@07100000 { + compatible = "cix,sky1-audss-clock"; + reg = <0x0 0x07100000 0x0 0x1000>; + clock-names = "audio_clk0", "audio_clk1", + "audio_clk2", "audio_clk3", + "audio_clk4", "audio_clk5"; + clocks = <&clocks CLK_AUDIO_CLK0>, <&clocks CLK_AUDIO_CLK1>, + <&clocks CLK_AUDIO_CLK2>, <&clocks CLK_AUDIO_CLK3>, + <&clocks CLK_AUDIO_CLK4>, <&clocks CLK_AUDIO_CLK5>; + #clock-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/dma/arm_dma350.txt b/Documentation/devicetree/bindings/dma/arm_dma350.txt new file mode 100755 index 000000000000..62a3f4b6cdf7 --- /dev/null +++ b/Documentation/devicetree/bindings/dma/arm_dma350.txt @@ -0,0 +1,45 @@ +* ARM DMA350 Controller + +The ARM DMA350 controller can move blocks of memory contents +between memory and peripherals or memory to memory. + +Required properties: + - compatible: should include both "arm,dma350" . + - reg: physical base address of the controller and length of memory mapped + region. + - interrupts: interrupt number to the cpu. + +Optional properties: + - dma-coherent : Present if dma operations are coherent + - #dma-cells: must be <2>. used to represent the number of integer + cells in the dmas property of client device. + - dma-channels: contains the total number of DMA channels supported by the DMAC + - dma-requests: contains the total number of DMA requests supported by the DMAC + + +Example: + + pdma0: pdma@12680000 { + compatible = "arm,dma350"; + reg = <0x12680000 0x1000>; + interrupts = <99>; + #dma-cells = <2>; + #dma-channels = <8>; + #dma-requests = <32>; + }; + +Client drivers (device nodes requiring dma transfers from dev-to-mem or +mem-to-dev) should specify the DMA channel numbers and dma channel names +as shown below. + + [property name] = <[phandle of the dma controller] [dma channel id] [dma request id]>; + [property name] = <[dma channel name]> + + where 'dma request id' is the dma request number which is connected + to the client controller. The 'property name' 'dmas' and 'dma-names' + as required by the generic dma device tree binding helpers. The dma + names correspond 1:1 with the dma request ids in the dmas property. + + Example: dmas = <&pdma0 1 12 + &pdma1 2 11>; + dma-names = "tx", "rx"; diff --git a/Documentation/devicetree/bindings/hwlock/sky1-hwspinlock.yaml b/Documentation/devicetree/bindings/hwlock/sky1-hwspinlock.yaml new file mode 100644 index 000000000000..bfd583f3353c --- /dev/null +++ b/Documentation/devicetree/bindings/hwlock/sky1-hwspinlock.yaml @@ -0,0 +1,41 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/hwlock/sky1-hwspinlock.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Sky1 Hardware Mutex Block + +maintainers: + - Jerry.Zhu + +description: + The hardware block provides mutexes utilized between different processors on + the SoC as part of the communication protocol used by these processors. + +properties: + compatible: + oneOf: + - enum: + - sky1,hwspinlock + reg: + maxItems: 1 + + '#hwlock-cells': + const: 1 + +required: + - compatible + - reg + - '#hwlock-cells' + +additionalProperties: false + +examples: + - | + hwclock: hwspinlock@06510000 { + compatible = "sky1,hwspinlock"; + reg = <0x0 0x06510000 0x0 0x1000>; + #hwlock-cells = <1>; + }; +... diff --git a/Documentation/devicetree/bindings/mailbox/cix-mailbox.yaml b/Documentation/devicetree/bindings/mailbox/cix-mailbox.yaml new file mode 100644 index 000000000000..0874ad7576bd --- /dev/null +++ b/Documentation/devicetree/bindings/mailbox/cix-mailbox.yaml @@ -0,0 +1,68 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/mailbox/cix-mailbox.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Cix mailbox controller bindings + +maintainers: + - Lihua Liu + +description: + CIX mailbox controller is used to exchange message within + multiple processors, such as AP, AUDIO DSP, SensorHub MCU, + etc. It supports 10 mailbox channels with different operating + mode and every channel is unidirectional. + +properties: + compatible: + const: cix,sky1-mbox + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + "#mbox-cells": + description: | + <&phandle channel> + phandle : Label name of controller + channel : Channel number + + This controller supports three types of unidirectional channels, they are + 1 register based channel, 1 fifo based channel and 8 fast channels. + A total of 10 channels for each controller. Following types are + supported: + channel 0_7 - Fast channel with 32bit transmit register and IRQ support. + channel 8 - Reg based channel with 32*32bit transsmit register and + Doorbell+transmit acknowledgment IRQ support + channel 9 - Fifo based channel with 32*32bit depth fifo and IRQ support. + const: 1 + + cix,mbox_dir: + description: Direction of the mailbox (0:TX or 1:RX) + enum: [0, 1] + +required: + - compatible + - reg + - interrupts + - "#mbox-cells" + - cix,mbox_dir + +additionalProperties: false + +examples: + - | + #include + + mbox0: mailbox@30000000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x30000000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; + status = "okay"; + }; diff --git a/Documentation/devicetree/bindings/pinctrl/cix,sky1-pinctrl.yaml b/Documentation/devicetree/bindings/pinctrl/cix,sky1-pinctrl.yaml new file mode 100644 index 000000000000..053985124c87 --- /dev/null +++ b/Documentation/devicetree/bindings/pinctrl/cix,sky1-pinctrl.yaml @@ -0,0 +1,65 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pinctrl/cix,sky1-pinctrl.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cix Sky1 IOMUX Controller + +maintainers: + - Jerry Zhu + + +properties: + compatible: + const: cix,sky1-iomuxc + + reg: + maxItems: 1 + +# Client device subnode's properties +patternProperties: + 'grp$': + type: object + description: + Pinctrl node's client devices use subnodes for desired pin configuration. + Client device subnodes use below standard properties. + + properties: + sky1,pins: + description: + each entry consists of 1 short represents for mux&conf reg and 1 integer + items: + items: + - description: | + "mux&conf_reg" indicates the offset of mux&conf register. + - description: | + "mux&conf_val" indicates the mux&conf value to be applied. + + required: + - sky1,pins + + additionalProperties: false + +required: + - compatible + - reg + +additionalProperties: false + +examples: + # Pinmux controller node + - | + iomuxc: pinctrl@04160000 { + compatible = "cix,sky1-iomuxc"; + reg = <0x0 0x04160000 0x0 0x10000>; + + pinctrl_uart2: uart2grp { + sky1,pins =< + 0x14c 0x1b + 0x150 0x1b + >; + }; + }; + +... diff --git a/Documentation/devicetree/bindings/pwm/sky1-pwm.yaml b/Documentation/devicetree/bindings/pwm/sky1-pwm.yaml new file mode 100644 index 000000000000..58bc068dd899 --- /dev/null +++ b/Documentation/devicetree/bindings/pwm/sky1-pwm.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/pwm/sky1-pwm.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cix Sky1 PWM controller + +maintainers: + - Jerry Zhu + +properties: + "#pwm-cells": + description: | + Should 3 for sky1 SoCs. See pwm.yaml in this directory for + a description of the cells format. + enum: + - 3 + + compatible: + oneOf: + - enum: + - cix,sky1-pwm + - items: + - const: cix,sky1-pwm + + reg: + maxItems: 1 + + clocks: + items: + - description: SoC PWM clock + + clock-names: + items: + - const: clk + +required: + - "#pwm-cells" + - compatible + - reg + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include +pwm: pwm@16001000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x16001000 0x0 0x10000>; + clock-names = "pclk", "iclk"; + status = "disabled"; +}; diff --git a/Documentation/devicetree/bindings/remoteproc/cix_dsp_rproc.yaml b/Documentation/devicetree/bindings/remoteproc/cix_dsp_rproc.yaml new file mode 100644 index 000000000000..633f9e666ec3 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/cix_dsp_rproc.yaml @@ -0,0 +1,113 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/remoteproc/cix_dsp_rproc.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Cix DSP Remoteproc Driver bindings + +maintainers: + - Lihua Liu + +description: + CIX DSP remoteproc driver is used to control audio dsp core, + such as start, stop and boot dsp. Mailbox will be + used for msg exchange between AP and dsp. In additional, + crash dump and recovery are supported with this driver when remote + processor crash happen. + +properties: + compatible: + const: cix,sky1-hifi5 + + reg: + maxItems: 1 + + interrupts: + description: Should contain the watchdog reset interrupt + maxItems: 1 + + clocks: + maxItems: 6 + + clock-names: + items: + - const: clk + - const: bclk + - const: pbclk + - const: sramclk + - const: mb0clk + - const: mb1clk + + "#mbox-cells": + description: | + <&phandle channel> + phandle : Label name of controller + channel : Channel index + + channel 0_7 - Fast channel with 32bit transmit register and IRQ support. + channel 8 - Reg based channel with 32*32bit transsmit register and + Doorbell+transmit acknowledgment IRQ support + channel 9 - Fifo based channel with 32*32bit depth fifo and IRQ support. + const: 1 + + firmware-name: + description: Default name of the firmware to load to the remote processor. + + memory-region: + description: + List of phandles to the reserved memory regions associated with the + remoteproc device. It describes the memories shared with + the remote processor (e.g. remoteproc firmware and carveouts, rpmsg + vrings, ...). + + wakeup-source: true + + resets: + maxItems: 1 + description: signal to reset HIFI5 DSP. + + reset-names: + maxItems: 1 + - const: dsp + + cix,dsp-ctrl: + description: Phandle to syscon block which provide access to Control Register Unit. + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - "#mbox-cells" + - "firmware-name" + - "memroy-region" + - resets + - reset-names + - cix,dsp-ctrl + +additionalProperties: false + +examples: + - | + #include + + audio-dsp { + compatible = "cix,sky1-hifi5"; + reg = <0x0 0x30000000 0x0 0x100000>; /* TBD */ + interrupts = ;/* TBD.IRQ? */ + firmware-name = "cix/hifi5.bin"; + mbox-names = "tx0", "rx0"; + mboxes = <&mbox0 9>, /* index=9: fifo base channel */ + <&mbox1 9>; + memory-region = <&dsp_vdev0buffer>, <&dsp_vdev0vring0>, + <&dsp_vdev0vring1>; + }; + + /* Reserve memory node */ + dsp_vdev0buffer: vdev0buffer@82008000 { /* 1M for tx/rx buffer */ + compatible = "shared-dma-pool"; + reg = <0x0 0x82008000 0x0 0x100000>; + no-map; + }; diff --git a/Documentation/devicetree/bindings/remoteproc/cix_sfh_rproc.yaml b/Documentation/devicetree/bindings/remoteproc/cix_sfh_rproc.yaml new file mode 100644 index 000000000000..26c633c8a716 --- /dev/null +++ b/Documentation/devicetree/bindings/remoteproc/cix_sfh_rproc.yaml @@ -0,0 +1,87 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: "http://devicetree.org/schemas/remoteproc/cix_sfh_rproc.yaml#" +$schema: "http://devicetree.org/meta-schemas/core.yaml#" + +title: Cix SFH Remoteproc Driver bindings + +maintainers: + - Lihua Liu + +description: + CIX Sensor Fusion Hub remoteproc driver is used to control sensorHub + M33 core, such as start, stop and boot sensorhub mcu. Mailbox will be + used for msg exchange between AP and sensorhub mcu. In additional, + crash dump and recovery are supported with this driver when remote + processor crash happen. + +properties: + compatible: + const: cix,sky1-sfh + + reg: + maxItems: 1 + + interrupts: + description: Should contain the watchdog reset interrupt + maxItems: 1 + + "#mbox-cells": + description: | + <&phandle channel> + phandle : Label name of controller + channel : Channel index + + channel 0_7 - Fast channel with 32bit transmit register and IRQ support. + channel 8 - Reg based channel with 32*32bit transsmit register and + Doorbell+transmit acknowledgment IRQ support + channel 9 - Fifo based channel with 32*32bit depth fifo and IRQ support. + const: 1 + + firmware-name: + description: Default name of the firmware to load to the remote processor. + + memory-region: + description: + List of phandles to the reserved memory regions associated with the + remoteproc device. It describes the memories shared with + the remote processor (e.g. remoteproc firmware and carveouts, rpmsg + vrings, ...). + + wakeup-source: true + +required: + - compatible + - reg + - interrupts + - "#mbox-cells" + - "firmware-name" + - "memroy-region" + - "wakeup-source" + +additionalProperties: false + +examples: + - | + #include + + sensor-mcu { + compatible = "cix,sky1-sfh"; + reg = <0x0 0x30000000 0x0 0x100000>; + interrupts = ; + firmware-name = "cix/sfh_fw.bin"; + mbox-names = "tx1", "rx1"; + mboxes = <&mbox2 0>, /* index=0: Fast channel */ + <&mbox3 0>; + memory-region = <&mcu_vdev0buffer>, <&mcu_vdev0vring0>, + <&mcu_vdev0vring1>, <&mcu_ram>; + wakeup-source; + }; + + /* Reserve memory node */ + mcu_vdev0buffer: vdev0buffer@40008000 { /* 1M for tx/rx buffer */ + compatible = "shared-dma-pool"; + reg = <0x0 0x40008000 0x0 0x100000>; + no-map; + }; diff --git a/Documentation/devicetree/bindings/reset/cix,sky1-src.yaml b/Documentation/devicetree/bindings/reset/cix,sky1-src.yaml new file mode 100644 index 000000000000..7d4ffd0f289f --- /dev/null +++ b/Documentation/devicetree/bindings/reset/cix,sky1-src.yaml @@ -0,0 +1,59 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/reset/cix,sky1-src.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cix Sky1 System Reset Controller + +maintainers: + - Jerry Zhu + +description: | + The system reset controller can be used to reset various set of + peripherals. Device nodes that need access to reset lines should + specify them as a reset phandle in their corresponding node as + specified in reset.txt. + + For list of all valid reset indices see + for Sky1 +properties: + compatible: + oneOf: + - items: + - enum: + - cix,sky1-src + - const: syscon + - items: + - enum: + - cix,sky1-src + - const: cix,sky1-src + - const: syscon + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + '#reset-cells': + const: 1 + +required: + - compatible + - reg + - interrupts + - '#reset-cells' + +additionalProperties: false + +examples: + - | + #include + + reset-controller@30390000 { + compatible = "cix,sky1-src", "syscon"; + reg = <0x0 0x16000000 0x0 0x10000>; + interrupts = ; + #reset-cells = <1>; + }; diff --git a/Documentation/devicetree/bindings/soc/cix/cix,ddr_exception.yaml b/Documentation/devicetree/bindings/soc/cix/cix,ddr_exception.yaml new file mode 100644 index 000000000000..43ee8e561766 --- /dev/null +++ b/Documentation/devicetree/bindings/soc/cix/cix,ddr_exception.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright 2025 Cix Technology Group Co., Ltd. +%YAML 1.2 +--- +$id: "" +$schema: "" + +title: Cix ddr exception driver. + +description: | + When a DDR exception occurs, it informs the AP through an interrupt, and the AP will parse the interrupt information. + +maintainers: + - Vincent Wu + - Vimoon Zheng + +properties: + compatible: + enum: + - cadence,ddr_ctrl + + reg: + description: DDR interrupt information reg and DDR information reg + maxItems: 2 + + interrupts: + description: DDR interrupt number + + channel_id: + description: DDR channel id + + mbox-names: + description: mailbox name + + mboxes: + description: Mailbox in use + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - channel_id + - mbox-names + - mboxes + +additionalProperties: false + +examples: + - | + ddr_ctrl1: ddr_ctrl@0C030000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C030000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x1>; + mbox-names = "tx4"; + mboxes = <&mbox_ap2se 10>; /* index=9: fifo base channel */ + status = "disabled"; + }; diff --git a/Documentation/devicetree/bindings/soc/cix/cix,se_pm_execption.yaml b/Documentation/devicetree/bindings/soc/cix/cix,se_pm_execption.yaml new file mode 100644 index 000000000000..9559551c0f5b --- /dev/null +++ b/Documentation/devicetree/bindings/soc/cix/cix,se_pm_execption.yaml @@ -0,0 +1,44 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# Copyright 2025 Cix Technology Group Co., Ltd. +%YAML 1.2 +--- +$id: "" +$schema: "" + +title: Cix SE & PM Exception Driver + +description: | + When an Exception occurs for SE or PM, AP will be notified to log this exception event. + +maintainers: + - Vincent Wu + - Vimoon Zheng + +properties: + compatible: + enum: + - cix,se_pm_crash + + mbox-names: + description: mailbox name + maxItems: 4 + + mboxes: + description: Mailbox in use + maxItems: 1 + +required: + - compatible + - mbox-names + - mboxes + +additionalProperties: false + +examples: + - | + crash: cix_se_pm_crash { + compatible = "cix,se_pm_crash"; + mbox-names = "rx4"; + mboxes = <&mbox_se2ap 9>; /* index=9: fifo base channel */ + status = "disabled"; + }; diff --git a/Documentation/devicetree/bindings/sound/alc256.txt b/Documentation/devicetree/bindings/sound/alc256.txt new file mode 100644 index 000000000000..2f472e634f63 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/alc256.txt @@ -0,0 +1,14 @@ +Alc256 ADC/DAC + +Required properties: + + - compatible : "realtek,alc256" + + - "#sound-dai-cells" : + const: 0 + +Example: + +alc256_codec { + compatible = "realtek,alc256"; +}; diff --git a/Documentation/devicetree/bindings/sound/alc257.txt b/Documentation/devicetree/bindings/sound/alc257.txt new file mode 100644 index 000000000000..c57d01d6c3b4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/alc257.txt @@ -0,0 +1,14 @@ +Alc256 ADC/DAC + +Required properties: + + - compatible : "realtek,alc257" + + - "#sound-dai-cells" : + const: 0 + +Example: + +alc257_codec { + compatible = "realtek,alc257"; +}; diff --git a/Documentation/devicetree/bindings/sound/alc269.txt b/Documentation/devicetree/bindings/sound/alc269.txt new file mode 100644 index 000000000000..7f1068b1ba2e --- /dev/null +++ b/Documentation/devicetree/bindings/sound/alc269.txt @@ -0,0 +1,14 @@ +Alc256 ADC/DAC + +Required properties: + + - compatible : "realtek,alc269" + + - "#sound-dai-cells" : + const: 0 + +Example: + +alc269_codec { + compatible = "realtek,alc269"; +}; diff --git a/Documentation/devicetree/bindings/sound/alc3287.txt b/Documentation/devicetree/bindings/sound/alc3287.txt new file mode 100644 index 000000000000..bc9f4aaa29dc --- /dev/null +++ b/Documentation/devicetree/bindings/sound/alc3287.txt @@ -0,0 +1,14 @@ +Alc256 ADC/DAC + +Required properties: + + - compatible : "realtek,alc3287" + + - "#sound-dai-cells" : + const: 0 + +Example: + +alc3287_codec { + compatible = "realtek,alc3287"; +}; diff --git a/Documentation/devicetree/bindings/sound/cdns,i2s-mc.yaml b/Documentation/devicetree/bindings/sound/cdns,i2s-mc.yaml new file mode 100644 index 000000000000..df4552993edb --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cdns,i2s-mc.yaml @@ -0,0 +1,120 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/cdns,i2s-mc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: + Cadence I2S-MC (MultiChannel) Controller Driver + +maintainers: + - Joakim Zhang + +properties: + compatible: + enum: + - cdns,sky1-i2s-mc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + minItems: 2 + maxItems: 3 + items: + - description: APB clock is used to provide synchronization of the design’s APB slave + interface with external APB master (at the SoC level). + The following modules are clocked by hst clock: + - U_CDNSI2SSC_APB_SLAVE + - U_CDNSI2SSC_SFR + - U_CDNSI2SSC_FIFO_RX_APB + - U_CDNSI2SSC_FIFO_TX_APB + - description: The main clock for synchronous logic in I2S transceiver. + The following modules are clocked by i2s clock: + - U_CDNSI2SMC_TRX_CHNx + - U_CDNSI2SMC_RX_CTRL + - U_CDNSI2SMC_TX_CTRL + - U_CDNSI2SMC_RX_FIFO_I2S + - U_CDNSI2SMC_TX_FIFO_I2S + - description: master clock feeding external codec + + clock-names: + minItems: 2 + maxItems: 3 + items: + - const: hst + - const: i2s + - const: mclk + + dmas: + items: + - description: audio playback dma + - description: audio capture dma + + dma-names: + items: + - const: tx + - const: rx + + cdns,pin-out-num: + description: The number of pins brought out by the SoC. + $ref: /schemas/types.yaml#/definitions/uint8 + minimum: 1 + maximum: 8 + + cdns,pin-tx-mask: + description: | + Transmit direction pin mask, if a bit is set the corresponding pin masked + as transmitter. + $ref: /schemas/types.yaml#/definitions/uint8 + + cdns,pin-rx-mask: + description: | + Receive direction pin mask, if a bit is set the corresponding pin masked + as receiver. + $ref: /schemas/types.yaml#/definitions/uint8 + + cdns,cru-ctrl: + description: Phandle to syscon block which provide access to Clock Reset Unit. + + cdns,mclk-idx: + description: The index of mclk if mclk is present. + + "#sound-dai-cells": + const: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - dmas + - dma-names + - cdns,pin-out-num + - cdns,pin-tx-mask + - cdns,pin-rx-mask + - cdns,mclk-idx + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + #include + i2s_mc0: i2s@03040000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x03040000 0x0 0x10000>; + interrupts = ; + clocks = <&clks 1>, <&clks 2>, <&clks 3>; + clock-names = "hst", "i2s", "mclk"; + dmas = <&dma>, <&dma>; + dma-names = "tx", "rx"; + cdns,pin-out-num = /bits/ 8 <8>; + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + cdns,pin-rx-mask = /bits/ 8 <240>; /* 0xf0, pin4-pin7 works as receiver */ + #sound-dai-cells = <1>; + } diff --git a/Documentation/devicetree/bindings/sound/cdns,i2s-sc.yaml b/Documentation/devicetree/bindings/sound/cdns,i2s-sc.yaml new file mode 100644 index 000000000000..bcbef3be1ee9 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cdns,i2s-sc.yaml @@ -0,0 +1,96 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/cdns,i2s-sc.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: + Cadence I2S-SC (SingleChannel) Controller Driver + +maintainers: + - Joakim Zhang + +properties: + compatible: + enum: + - cdns,sky1-i2s-sc + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + minItems: 2 + maxItems: 3 + items: + - description: APB clock is used to provide synchronization of the design’s APB slave + interface with external APB master (at the SoC level). + The following modules are clocked by hst clock: + - U_CDNSI2SSC_APB_SLAVE + - U_CDNSI2SSC_SFR + - U_CDNSI2SSC_FIFO_RX_APB + - U_CDNSI2SSC_FIFO_TX_APB + - description: The main clock for synchronous logic in I2S transceiver. + The following modules are clocked by i2s clock: + - U_CDNSI2SSC_TRX_CTRL + - U_CDNSI2SSC_RX_DATA + - U_CDNSI2SSC_TX_DATA + - U_CDNSI2SSC_FIFO_RX_I2S + - U_CDNSI2SSC_FIFO_TX_I2S + - description: master clock feeding external codec + + clock-names: + minItems: 2 + maxItems: 3 + items: + - const: hst + - const: i2s + - const: mclk + + dmas: + items: + - description: audio playback dma + - description: audio capture dma + + dma-names: + items: + - const: tx + - const: rx + + cdns,cru-ctrl: + description: Phandle to syscon block which provide access to Clock Reset Unit. + + cdns,mclk-idx: + description: The index of mclk if mclk is present. + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - dmas + - dma-names + - cdns,mclk-idx + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + #include + i2s_sc0: i2s@03010000 { + compatible = "cdns,sky1-i2s-sc"; + reg = <0x0 0x03010000 0x0 0x10000>; + interrupts = ; + clocks = <&clks 1>, <&clks 2>, <&clks 3>; + clock-names = "hst", "i2s", "mclk"; + dmas = <&dma>, <&dma>; + dma-names = "tx", "rx"; + #sound-dai-cells = <0>; + } diff --git a/Documentation/devicetree/bindings/sound/cix,sky1-card.yaml b/Documentation/devicetree/bindings/sound/cix,sky1-card.yaml new file mode 100644 index 000000000000..d6445ad2f0d4 --- /dev/null +++ b/Documentation/devicetree/bindings/sound/cix,sky1-card.yaml @@ -0,0 +1,78 @@ +# SPDX-License-Identifier: GPL-2.0 +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/cux,sky1-card.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: CIX, sky1 sound card + +maintainers: + - Xing Wang + +properties: + compatible: + items: + - const: cix,sky1-sound-card + + model: + $ref: /schemas/types.yaml#/definitions/string + description: User specified audio sound card name + +patternProperties: + "dai link name": + type: object + description: |- + dai-link child nodes, for i2s sc0~3, i2s mc , hda + Container for dai-link properties, cpu and codec sub-nodes. + There should be at least one (and probably more) subnode of this type + + patternProperties: + "cpu": + type: object + description: |- + cpus: + cpu dai node + + properties: + sound-dai: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: phandle of the CPU DAI + + required: + - sound-dai + + patternProperties: + "codec": + type: object + description: |- + codec: + codec dai node + + properties: + sound-dai: + $ref: /schemas/types.yaml#/definitions/phandle-array + description: phandle of the Codec DAI + + required: + - sound-dai + +required: + - model + - dai link name + +examples: + - | + sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "okay"; + + i2s-sc0 { + cpu { + sound-dai = <&i2s_sc0>; + }; + codec { + sound-dai = <&codec>; + }; + }; + } diff --git a/Documentation/devicetree/bindings/sound/ipbloq,hda.yaml b/Documentation/devicetree/bindings/sound/ipbloq,hda.yaml new file mode 100644 index 000000000000..f32cdfce0cce --- /dev/null +++ b/Documentation/devicetree/bindings/sound/ipbloq,hda.yaml @@ -0,0 +1,60 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/sound/ipbloq,hda.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: + IPBloq HDA Controller Driver + +maintainers: + - Xing Wang + +properties: + compatible: + enum: + - ipbloq,hda + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + minItems: 3 + maxItems: 3 + items: + - description: sysclk for APB clock + - description: The 48m clock for synchronous logic. + - description: reset clock + + clock-names: + minItems: 3 + maxItems: 3 + items: + - const: sysclk + - const: clk48m + - const: clkrst + + "#sound-dai-cells": + const: 0 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + - "#sound-dai-cells" + +additionalProperties: false + +examples: + - | + ipb_hda: ipb-hda@70b0000 { + compatible = "ipbloq, hda"; + reg = <0x0 0x700b0000 0x0 0x10000>; + #sound-dai-cells = <0>; + status = "disabled"; + }; diff --git a/Documentation/devicetree/bindings/timer/timer-sky1-gpt.yaml b/Documentation/devicetree/bindings/timer/timer-sky1-gpt.yaml new file mode 100644 index 000000000000..413499a52292 --- /dev/null +++ b/Documentation/devicetree/bindings/timer/timer-sky1-gpt.yaml @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/timer/ksy1-timer.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cixtech General Purpose Timer (GPT) + +maintainers: + - Jerry.Zhu + +description: + This is a simple driver for the sky1 general purpose timer. + The general purpose timer is configured(freerunning mode) + as a 64-bit incrementing counter with an auto-incrementing feature. + It continues incrementing after sending interrupts. The gpt timer + is used after system start. + +properties: + compatible: + - const: cix,sky1-gpt + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + + clock-names: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + - clock-names + +additionalProperties: false + +examples: + - | + #include /* TBD */ + + timer: timer@16001000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x16001000 0x0 0x10000>; + interrupts = ; + clocks = ; + clock-names = "soc_apb"; + status = "disabled" + }; diff --git a/Documentation/devicetree/bindings/vendor-prefixes.yaml b/Documentation/devicetree/bindings/vendor-prefixes.yaml index dc275ab60e53..b1e908799e2e 100644 --- a/Documentation/devicetree/bindings/vendor-prefixes.yaml +++ b/Documentation/devicetree/bindings/vendor-prefixes.yaml @@ -1598,6 +1598,10 @@ patternProperties: description: ZTE Corp. "^zyxel,.*": description: ZyXEL Communications Corp. + "^ipbloq,.*": + description: IPbloq, Lda + "^cix,.*": + description: Copyright 2024 Cix Technology Group Co., Ltd.Co., Ltd # Normal property name match without a comma # These should catch all node/property names without a prefix diff --git a/Documentation/devicetree/bindings/watchdog/sky1-watchdog.yaml b/Documentation/devicetree/bindings/watchdog/sky1-watchdog.yaml new file mode 100644 index 000000000000..3a71199e4d95 --- /dev/null +++ b/Documentation/devicetree/bindings/watchdog/sky1-watchdog.yaml @@ -0,0 +1,49 @@ +# SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) +%YAML 1.2 +--- +$id: http://devicetree.org/schemas/watchdog/sky1-watchdog.yaml# +$schema: http://devicetree.org/meta-schemas/core.yaml# + +title: Cixtech Sky1 Watchdog Timer (WDT) Controller + +maintainers: + - Jerry Zhu + +description: + The cix watchdog meets arm systemready requirement, and + is used in sky1 board for global reset. The watchdog + has two output signals ws0 and ws1. If ws0 is asserted and + timeout refresh occurs, ws1 is asserted. + +properties: + compatible: + const: cix,sky1-wdt + + reg: + maxItems: 1 + + interrupts: + maxItems: 1 + + clocks: + maxItems: 1 + +required: + - compatible + - reg + - interrupts + - clocks + +unevaluatedProperties: false + +examples: + - | + #include + + watchdog: watchdog@16003000 { + compatible = "cix,sky1-wdt"; + reg = <0x0 0x16003000 0x0 0x10000>; + interrupts = ; + //clocks = < >; /* TBD */ + status = "okay"; + }; diff --git a/Documentation/driver-api/index.rst b/Documentation/driver-api/index.rst index 1e16a40da3ba..2a854d5a577c 100644 --- a/Documentation/driver-api/index.rst +++ b/Documentation/driver-api/index.rst @@ -66,6 +66,7 @@ available subsections can be seen below. uio-howto firmware/index pin-control + pin-control-acpi gpio/index md/index media/index diff --git a/Documentation/driver-api/pin-control-acpi.rst b/Documentation/driver-api/pin-control-acpi.rst new file mode 100644 index 000000000000..9a427d76a581 --- /dev/null +++ b/Documentation/driver-api/pin-control-acpi.rst @@ -0,0 +1,297 @@ +.. SPDX-License-Identifier: GPL-2.0 + +Introduction +============ + +This document is an extension of the pin control subsystem in Linux [1] and describes +the pin control related ACPI properties supported in Linux kernel. + +On some platform, certains peripheral buses or devices could be connected to same +external pin header with a different pin configuration requirement. A simple example of +this would be a board where pins for I2C data and clock is multiplexed and shared with +GPIO pins for a display controller. Pins would require different +configuration in these two modes. For example, I2C functionality would require pin +bias to be set to pull up with pull strength of 10K Ohms and for GPIO functionality +pin bias needs to be set to pull down with pull strength of 20K Ohms, +input Schmitt-trigger enabled and a slew rate of 3. + +ACPI 6.2 version [2] introduced following resources to be able to describe different +pin functions and configurations required for devices. + +- PinFunction +- PinConfig +- PinGroup +- PinGroupFunction +- PinGroupConfig + +OSPM will have to handle the above resources and select the pin function and configuration +through vendor specific interfaces (e.g: memory mapped registers) for the devices to be +fully functional. + +Example 1 : I2C controller SDA/SCL muxed with display controller GPIO pin +========================================================================= + +.. code-block:: text + + // + // Description: GPIO + // + Device (GPI0) + { + Name (_HID, "PNPFFFE") + Name (_UID, 0x0) + Method (_STA) + { + Return(0xf) + } + Method (_CRS, 0x0, NotSerialized) + { + Name (RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0x4FE00000, 0x20) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x54} + }) + Return(RBUF) + } + } + + // + // Description: I2C controller 1 + // + Device (I2C1) + { + Name (_HID, "PNPFFFF") + Name (_UID, 0x0) + Method (_STA) + { + Return(0xf) + } + Method (_CRS, 0x0, NotSerialized) + { + Name (RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0x4F800000, 0x20) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x55} + PinFunction(Exclusive, PullDefault, 0x5, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + // Configure 10k Pull up for I2C SDA/SCL pins + PinConfig(Exclusive, 0x01, 10000, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + }) + Return(RBUF) + } + } + + // + // Description: Physical display panel + // + Device (SDIO) + { + Name (_HID, "PNPFFFD") + Name (_UID, 0x0) + Method (_STA) + { + Return(0xf) + } + Method (_CRS, 0x0, NotSerialized) + { + Name (RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0x4F900000, 0x20) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x57} + GpioIo(Shared, PullDefault, 0, 0, IoRestrictionNone, "\\_SB.GPI0",) {2, 3} + // Configure 20k Pull down + PinConfig(Exclusive, 0x02, 20000, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + // Enable Schmitt-trigger + PinConfig(Exclusive, 0x0D, 1, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + // Set slew rate to custom value 3 + PinConfig(Exclusive, 0x0B, 3, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + }) + Return(RBUF) + } + } + + +Example 2 : Pin muxing and configuration described with pin groups +================================================================== + +The configuration is similar to example 1 but described using pin group resources + +.. code-block:: text + + // + // Description: GPIO + // + Device (GPI0) + { + Name (_HID, "PNPFFFE") + Name (_UID, 0x0) + Method (_STA) + { + Return(0xf) + } + Method (_CRS, 0x0, NotSerialized) + { + Name (RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0x4FE00000, 0x20) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x54} + PinGroup("group1", ResourceProducer) {2, 3} + + }) + Return(RBUF) + } + } + + // + // Description: I2C controller 1 + // + Device (I2C1) + { + Name (_HID, "PNPFFFF") + Name (_UID, 0x0) + Method (_STA) + { + Return(0xf) + } + Method (_CRS, 0x0, NotSerialized) + { + Name (RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0x4F800000, 0x20) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x55} + // Set function I2C1 for SDA/SCL pins + PinGroupFunction(Exclusive, 0x5, "\\_SB.GPI0, 0, "group1", ResourceConsumer, ) + // Configure 10k Pull up for SDA/SCL pins + PinGroupConfig(Exclusive, 0x01, 10000, "\\_SB.GPI0 ", 0, "group1", ResourceConsumer, ) + }) + Return(RBUF) + } + } + + // + // Description: Physical display panel + // + Device (DISP) + { + Name (_HID, "PNPFFFD") + Name (_UID, 0x0) + Method (_STA) + { + Return(0xf) + } + Method (_CRS, 0x0, NotSerialized) + { + Name (RBUF, ResourceTemplate() + { + Memory32Fixed(ReadWrite, 0x4F900000, 0x20) + Interrupt(ResourceConsumer, Level, ActiveHigh, Shared) {0x57} + // Set function GPIO for pin group group1 + PinGroupFunction(Exclusive, 0x1, "\\_SB.GPI0 ", 0, "group1", + Ë“ResourceConsumer, ) + // Configure 20k Pull down + PinGroupConfig (Exclusive, 0x02, 20000, "\\_SB.GPI0 ", 0, "group1", + Ë“ResourceConsumer, ) + //Enable Schmitt-trigger + PinGroupConfig (Exclusive, 0x0D, 1, "\\_SB.GPI0 ", 0, "group1", + Ë“ResourceConsumer, ) + //Set slew rate to custom value 3 + PinGroupConfig (Exclusive, 0x0B, 3, "\\_SB.GPI0 ", 0, "group1", + Ë“ResourceConsumer, ) + }) + Return(RBUF) + } + } + } + +Notes for pin controller device driver developers +================================================= + +This section contains few examples and guidelines for device driver developers to +add bindings to handle ACPI pin resources. + +Pin control devices can add callbacks for following pinctrl_ops to handle ACPI +pin resources. + +.. code-block:: c + + struct pinctrl_ops { + ... + int (*acpi_node_to_map)(struct pinctrl_dev *pctldev, + struct pinctrl_acpi_resource *resource, + struct pinctrl_map **map, unsigned *num_maps); + void (*acpi_free_map)(struct pinctrl_dev *pctldev, + struct pinctrl_map *map, unsigned num_maps); + ... + } + +Following example demonstrate how the pinctrl_acpi_resource struct can be mapped +to generic pinctrl_map. + +.. code-block:: c + + int example_acpi_node_to_map(struct pinctrl_dev *pctldev, + struct pinctrl_acpi_resource *resource, + struct pinctrl_map **map, + unsigned *num_maps_out) + { + + ... + new_map = devm_kzalloc(pctldev->dev, sizeof(struct pinctrl_map), + GFP_KERNEL); + + switch (info->type) { + case PINCTRL_ACPI_PIN_FUNCTION: + new_map->type = PIN_MAP_TYPE_MUX_GROUP; + new_map->data.mux.group = example_pinctrl_find_pin_group( + info->function.function_number, + info->function.pins, info->function.npins); + new_map->data.mux.function = pinctrl_find_function(info->function.function_number); + break; + case PINCTRL_ACPI_PIN_CONFIG: + new_map->type = PIN_MAP_TYPE_CONFIGS_PIN; + new_map->data.configs.group_or_pin = pin_get_name(pctldev, info->config.pin); + new_map->data.configs.configs = devm_kcalloc( + pctldev->dev, info->config.nconfigs, + sizeof(unsigned long), GFP_KERNEL); + new_map->data.configs.num_configs = 0; + list_for_each_entry(config_node, info->config.configs, node) + new_map->data.configs.configs[new_map->data.configs.num_configs++] = + config_node->config; + break; + } + + ... + } + +Pin controller will have to map function numbers from ACPI to internal function numbers +and select appropriate group for pin muxing. Multiple pinctrl_map might need to generated +if more than one group needs to be activated. Above example just assumes all of the pins +belongs to a single group. + +Multiple configurations might need to be applied for a pin and ACPI could have multiple +resources to define them. E.g: + +.. code-block:: text + + // Configure 20k Pull down + PinConfig(Exclusive, 0x02, 20000, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + // Enable Schmitt-trigger + PinConfig(Exclusive, 0x0D, 1, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + // Set slew rate to custom value 3 + PinConfig(Exclusive, 0x0B, 3, "\\_SB.GPI0", 0, ResourceConsumer, ) {2, 3} + +ACPI pin controller will combine the configurations at the pin level and will invoke +acpi_node_to_map to map them to struct pinctrl_map. The above ACPI resources would +generate two struct pinctrl_acpi_resource descriptors, one for each pin, with list +of configs to apply for each pin. + +ACPI pin resources can be described at group level as described in example 2 above. +There is no change to the internal pinctrl ACPI interface due to this. ACPI pinctrl +subsystem will resolve all of the groups defined in AML to pins using PinGroup resources. + +References +========== + +[1] Documentation/driver-api/pin-control.rst + +[2] ACPI Specifications, Version 6.2 - Section 19.6.102 to 19.6.106 + https://uefi.org/sites/default/files/resources/ACPI_6_2.pdf diff --git a/Makefile b/Makefile index 23e90df5785c..90d438b87cf9 100644 --- a/Makefile +++ b/Makefile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: GPL-2.0 +export TARGET_SOC_PLATFORM := sky1 VERSION = 6 PATCHLEVEL = 6 SUBLEVEL = 89 @@ -554,6 +555,8 @@ LINUXINCLUDE := \ -I$(objtree)/include \ $(USERINCLUDE) +LINUXINCLUDE += -I$(srctree)/drivers/soc/cix/ap/platform/$(TARGET_SOC_PLATFORM) + KBUILD_AFLAGS := -D__ASSEMBLY__ -fno-PIE KBUILD_CFLAGS := diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 658c6a61ab6f..4171169de1cc 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -10,6 +10,7 @@ config ARM64 select ACPI_MCFG if (ACPI && PCI) select ACPI_SPCR_TABLE if ACPI select ACPI_PPTT if ACPI + select ACPI_SYSTEM_POWER_STATES_SUPPORT if ACPI select ARCH_HAS_DEBUG_WX select ARCH_BINFMT_ELF_EXTRA_PHDRS select ARCH_BINFMT_ELF_STATE @@ -210,8 +211,6 @@ config ARM64 select HAVE_FUNCTION_GRAPH_RETVAL if HAVE_FUNCTION_GRAPH_TRACER select HAVE_FUNCTION_GRAPH_TRACER select HAVE_GCC_PLUGINS - select HAVE_HARDLOCKUP_DETECTOR_PERF if PERF_EVENTS && \ - HW_PERF_EVENTS && HAVE_PERF_EVENTS_NMI select HAVE_HW_BREAKPOINT if PERF_EVENTS select HAVE_IOREMAP_PROT select HAVE_IRQ_TIME_ACCOUNTING diff --git a/arch/arm64/Kconfig.platforms b/arch/arm64/Kconfig.platforms index 6069120199bb..1d8347801d78 100644 --- a/arch/arm64/Kconfig.platforms +++ b/arch/arm64/Kconfig.platforms @@ -374,4 +374,26 @@ config ARCH_ZYNQMP help This enables support for Xilinx ZynqMP Family +config ARCH_CIX + bool "cixtech SoC family" + help + This enables support for the cixtech SoC family. + +config ARCH_CIX_EMU + bool "cixtech SoC family on EMU" + select ARCH_CIX_EMU_FPGA + help + This enables support for the cixtech SoC family on EMU. + +config ARCH_CIX_FPGA + bool "cixtech SoC family on FPGA" + select ARCH_CIX_EMU_FPGA + help + This enables support for the cixtech SoC family on FPGA. + +config ARCH_CIX_EMU_FPGA + bool "cixtech SoC family on both EMU and FPGA" + help + Please use this configuration for both EMU and FPGA suitable code. + endmenu # "Platform selection" diff --git a/arch/arm64/boot/dts/Makefile b/arch/arm64/boot/dts/Makefile index 30dd6347a929..19bb693febb5 100644 --- a/arch/arm64/boot/dts/Makefile +++ b/arch/arm64/boot/dts/Makefile @@ -33,3 +33,4 @@ subdir-y += tesla subdir-y += ti subdir-y += toshiba subdir-y += xilinx +subdir-y += cix diff --git a/arch/arm64/boot/dts/cix/Makefile b/arch/arm64/boot/dts/cix/Makefile new file mode 100644 index 000000000000..34063463f1ad --- /dev/null +++ b/arch/arm64/boot/dts/cix/Makefile @@ -0,0 +1,30 @@ +# SPDX-License-Identifier: GPL-2.0 +dtb-$(CONFIG_ARCH_CIX) += sky1-evb.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-crb.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-cloudbook.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-orion-o6.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-orion-o6-40pin.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-emu.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-fpga.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-batura.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-emu-smp.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-emu-pm.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-hda-alc256.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-lt7911uxc-audio.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-sof-alc5682-alc1019.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-display.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-iso.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-npu-resmem.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pciex8.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pciex4.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pciex2.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pciex10.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pciex11.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pcie_width_x1.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pcie_width_x2.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-pcie_width_x4.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-isp.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-evb-usb4_5.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-orangepi-6-plus.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-orangepi-6-plus-40pin.dtb +dtb-$(CONFIG_ARCH_CIX) += sky1-orangepi-6-plus-40pin-pwm.dtb diff --git a/arch/arm64/boot/dts/cix/sky1-batura.dts b/arch/arm64/boot/dts/cix/sky1-batura.dts new file mode 100644 index 000000000000..bf21a5c1d7c2 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-batura.dts @@ -0,0 +1,104 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1.dtsi" + +/ { + model = "CIX sky1 BATURA board"; + compatible = "cix,sky1"; + + chosen { + stdout-path = "serial2:115200n8"; + }; +}; + +&thermal_zones { + cpu-m1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M1_TEMP_SENSOR_ID>; + + trips { + m1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B1_TEMP_SENSOR_ID>; + + trips { + b1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-m0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + + trips { + m0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B0_TEMP_SENSOR_ID>; + + trips { + b0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-cloudbook.dts b/arch/arm64/boot/dts/cix/sky1-cloudbook.dts new file mode 100644 index 000000000000..4cdf66c32252 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-cloudbook.dts @@ -0,0 +1,1362 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1.dtsi" +/delete-node/ ®_definition; + +/ { + model = "CIX sky1 Cloudbook PCBA board"; + compatible = "cix,sky1"; + + chosen { + stdout-path = &uart2; + }; + + alc256_codec: alc256_codec { + compatible = "realtek,alc256"; + #sound-dai-cells = <0>; + status = "okay"; + }; + + sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "okay"; + + hda { + status = "okay"; + + cpu { + sound-dai = <&ipb_hda>; + }; + + codec { + sound-dai = <&alc256_codec>; + }; + }; + + }; + + dp2_backlight: dp2_backlight { + compatible = "pwm-backlight"; + enable-gpios = <&fch_gpio3 15 GPIO_ACTIVE_HIGH>; + pwms = <&pwm0 0 100000>; + status = "okay"; + + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + + }; + + panel_edp0: panel_edp0 { + status = "okay"; + compatible = "cix-edp-panel"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_edp0>; + backlight = <&dp2_backlight>; + prepare-delay-ms = <120>; + enable-delay-ms = <120>; + unprepare-delay-ms = <500>; + disable-delay-ms = <120>; + width-mm = <129>; + height-mm = <171>; + enable-gpios = <&fch_gpio3 16 GPIO_ACTIVE_HIGH>; + }; + + wireless_bluetooth: wireless-bluetooth { + compatible = "bluetooth-platdata"; + pinctrl-names = "default"; + pinctrl-0 = <&bt_reset_gpio>; + BT,reset-gpios = <&s5_gpio0 2 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + vdd_3v3_pcie: regulator-vdd-3v3-pcie { + compatible = "regulator-fixed"; + regulator-name = "VDD_3V3_PCIE"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_vbat_gpio>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&s5_gpio0 12 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us=<15000>; + }; + + wlan_poweren: wlan-poweren { + compatible = "regulator-fixed"; + regulator-name = "WLAN_POWEREN_PCIE"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_poweren_gpio>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&s5_gpio0 10 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us=<15000>; + }; + + e_shutter: e_shutter { + compatible = "sky1, e_shutter"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_e_shutter>; + lid-gpio = <&s5_gpio1 0 GPIO_ACTIVE_HIGH>; + poweren-gpio = <&ec_gpio 1 GPIO_ACTIVE_HIGH>; + status ="okay"; + }; + +}; + +&fch_gpio0 { + status = "okay"; +}; + +&fch_gpio1 { + status = "okay"; +}; + +&fch_gpio3 { + status = "okay"; +}; + +&s5_gpio0 { + status = "okay"; +}; + +&s5_gpio1 { + status = "okay"; +}; + +&iomuxc_s5 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_s5>; + pinctrl_hog_s5: pinctrl_hog_s5 { + + }; + + pinctrl_fch_spi0: pinctrl_fch_spi0_grp { + sky1,pins = < + 0x000000a8 0x0000005c + 0x000000ac 0x0000005c + 0x000000b0 0x0000005c + 0x000000b4 0x0000005c + 0x000000b8 0x0000001c + >; + }; + + pinctrl_pcie_x8_rc: pinctrl_pcie_x8_rc { + sky1,pins = < + 0x00000004 0x00000024 + >; + }; + + pinctrl_pcie_x4_rc: pinctrl_pcie_x4_rc { + sky1,pins = < + 0x0000000c 0x00000024 + >; + }; + + pinctrl_pcie_x2_rc: pinctrl_pcie_x2_rc { + sky1,pins = < + 0x0000000c 0x00000024 + >; + }; + + pinctrl_pcie_x1_1_rc: pinctrl_pcie_x1_1_rc {/*x1_1*/ + sky1,pins = < + 0x00000014 0x00000024 + >; + }; + + pinctrl_pcie_x1_0_rc: pinctrl_pcie_x1_0_rc {/*x1_0*/ + sky1,pins = < + 0x00000010 0x00000024 + >; + }; + + pinctrl_e_shutter: pinctrl_e_shutter { + sky1,pins = < + 0x00000080 0x00000057 + >; + }; +}; + +&iomuxc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + pinctrl_hog: pinctrl_hog { + + }; + + pinctrl_fch_pwm0: pinctrl_fch_pwm0 { + sky1,pins = < + 0x00000050 0x00000007 + >; + }; + + pinctrl_fch_pwm1: pinctrl_fch_pwm1 { + sky1,pins = < + 0x0000013c 0x000000b7 + >; + }; + + pinctrl_gmac0: pinctrl_gmac0 { + sky1,pins = + /* rfclk_25M */ + < 0x000001a4 0x000000fc>, + /* txc_trl */ + < 0x000001a8 0x000000bc>, + /* txd0 */ + < 0x000001ac 0x000000bc>, + /* txd1 */ + < 0x000001b0 0x000000bc>, + /* txd2 */ + < 0x000001b4 0x000000bc>, + /* txd3 */ + < 0x000001b8 0x000000bc>, + /* tx_clk */ + < 0x000001bc 0x000000bc>, + /* rx_ctl */ + < 0x000001c0 0x000000a4>, + /* rxd0 */ + < 0x000001c4 0x000000a4>, + /* rxd1 */ + < 0x000001c8 0x000000a4>, + /* rxd2 */ + < 0x000001cc 0x000000a4>, + /* rxd3 */ + < 0x000001d0 0x000000a4>, + /* rx_clk */ + < 0x000001d4 0x000000a4>, + /* mdc */ + < 0x000001d8 0x000000bc>, + /* mdio */ + < 0x000001dc 0x000000dc>; + }; + + pinctrl_fch_fan0: pinctrl_fch_fan0 { + sky1,pins = < + 0x0000014c 0x000000b7 + >; + }; + + pinctrl_fch_fan1: pinctrl_fch_fan1 { + sky1,pins = < + 0x00000154 0x000000b7 + >; + }; + + pinctrl_fch_fan2: pinctrl_fch_fan2 { + sky1,pins = < + 0x00000144 0x000000b7 + >; + }; + + pinctrl_fch_i2c0: pinctrl_fch_i2c0 { + sky1,pins = < + 0x00000078 0x00000047 + 0x0000007c 0x00000047 + >; + }; + + pinctrl_fch_i2c1: pinctrl_fch_i2c1 { + sky1,pins = < + 0x00000080 0x00000047 + 0x00000084 0x00000047 + >; + }; + + pinctrl_fch_i2c2: pinctrl_fch_i2c2 { + sky1,pins = < + 0x00000088 0x0000005c + 0x0000008c 0x0000005c + >; + }; + + pinctrl_fch_i2c3: pinctrl_fch_i2c3 { + sky1,pins = < + 0x00000094 0x0000005c + 0x00000098 0x0000005c + >; + }; + + pinctrl_fch_i2c4: pinctrl_fch_i2c4 { + sky1,pins = < + 0x000000a0 0x00000047 + 0x000000a4 0x00000047 + >; + }; + + pinctrl_fch_i2c5: pinctrl_fch_i2c5 { + sky1,pins = < + 0x00000068 0x00000047 + 0x0000006c 0x00000047 + >; + }; + + pinctrl_fch_i2c6: pinctrl_fch_i2c6 { + sky1,pins = < + 0x00000070 0x00000047 + 0x00000074 0x00000047 + >; + }; + + pinctrl_fch_i2c7: pinctrl_fch_i2c7 { + sky1,pins = < + 0x00000054 0x00000047 + 0x00000058 0x00000047 + >; + }; + + pinctrl_fch_i3c0: pinctrl_fch_i3c0 { + sky1,pins = < + 0x00000088 0x000000dc + 0x0000008c 0x000000dc + 0x00000090 0x000000dc + >; + }; + + pinctrl_fch_i3c1: pinctrl_fch_i3c1 { + sky1,pins = < + 0x00000094 0x000000dc + 0x00000098 0x000000dc + 0x0000009c 0x000000dc + >; + }; + + pinctrl_fch_uart0: pinctrl_fch_uart0 { + sky1,pins = < + 0x0000013c 0x00000057 + 0x00000140 0x00000057 + 0x00000144 0x00000057 + 0x00000148 0x00000057 + >; + }; + + pinctrl_fch_uart1: pinctrl_fch_uart1 { + sky1,pins = < + 0x0000014c 0x00000057 + 0x00000150 0x00000057 + 0x00000154 0x00000057 + 0x00000158 0x00000057 + >; + }; + + pinctrl_fch_uart2: pinctrl_fch_uart2 { + sky1,pins = < + 0x0000015c 0x00000047 + 0x00000160 0x00000047 + >; + }; + + pinctrl_hda: pinctrl_hda_grp { + sky1,pins = < + 0x000000a8 0x0000003c /* hda bitclk */ + 0x000000ac 0x0000003c /* hda rst */ + 0x000000b0 0x0000003c /* hda sdin0 */ + 0x000000b4 0x0000005c /* hda sdout0 */ + 0x000000b8 0x0000005c /* hda sync */ + 0x000000bc 0x0000003c /* hda sdin1 */ + 0x000000c0 0x0000003c /* hda sdout1 */ + >; + }; + + pinctrl_edp0: pinctrl_edp0 { + sky1,pins = < + 0x00000048 0x00000024 /* DP2_DIGON */ + 0x0000004C 0x00000024 /* DP2_BLON */ + >; + }; +}; + +&iomuxc_s5 { + status = "okay"; + + wifi_poweren_gpio: wifi_poweren_gpio { + sky1,pins = < + 0x00000028 0x0000005c + >; + }; + + wifi_vbat_gpio: wifi_vbat_gpio { + sky1,pins = < + 0x00000030 0x0000005c + >; + }; + + bt_reset_gpio: bt_reset_gpio { + sky1,pins = < + 0x00000008 0x0000005c + >; + }; + + pinctrl_usb0: pinctrl_usb0_oc_grp { + sky1,pins = < + 0x000000bc 0x000000c4 /* USB0 OC_L */ + >; + }; + pinctrl_usb2: pinctrl_usb2_oc_grp { + sky1,pins = < + 0x000000c4 0x000000c4 /* USB2 OC_L */ + >; + }; + pinctrl_usb4: pinctrl_usb4_grp { + sky1,pins = < + 0x000000e8 0x000000a4 /* USB4 VBUS_DRIVE */ + >; + }; +}; + +&hifi5 { + status = "disabled"; +}; + +&mbox_dsp2ap { + status = "disabled"; +}; + +&mbox_ap2dsp { + status = "disabled"; +}; + +&audss_cru { + status = "okay"; +}; + +&audss_clk { + status = "okay"; +}; + +&audss_rst { + status = "okay"; +}; + +&audss_dmac { + status = "disabled"; +}; + +&i2s0 { + /* i2s_sc0 for codec */ + status = "disabled"; +}; + +&i2s1 { + /* i2s_sc1 for 5G/BT */ + status = "disabled"; +}; + +&i2s2 { + /* i2s_sc2 for loopback */ + status = "disabled"; +}; + +&i2s3 { + /* i2s_mc2a for speaker */ + status = "disabled"; +}; + +&i2s4 { + /* i2s_mc2b for dp-in */ + cdns,pin-rx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as receiver */ + status = "disabled"; +}; + +&i2s5 { + /* i2s_mc5a for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s6 { + /* i2s_mc5b for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s7 { + /* i2s_mc5c for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s8 { + /* i2s_mc5d for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s9 { + /* i2s_mc5e for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&ipb_hda { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hda>; + memory-region = <&audio_alsa_hda>; + status = "okay"; +}; + +&sensorhub { + memory-region = <&sfh_vdev0buffer>, <&sfh_vdev0vring0>, + <&sfh_vdev0vring1>, <&sfh_ram>; + status = "disabled"; +}; + +/*uart0 for BT*/ +&uart0{ + pinctrl-names = "default"; + timeout-value = <10000>; + pinctrl-0 = <&pinctrl_fch_uart0>; + dmas = <&fch_dmac 2 0>, <&fch_dmac 3 1>; + dma-names = "tx","rx"; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart2>; + status = "okay"; +}; + +&usbc_phy0 { + orientation-switch; + svid = <0xff01>; + default_conf = /bits/ 8 <0x03>; + status = "okay"; + mode-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy0_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_phy_sw>; + }; + }; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&sky1_usbss_0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_0 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_0_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_role_sw>; + }; + }; +}; + + +&usbc_phy1 { + status = "okay"; + default_conf = /bits/ 8 <0x02>; +}; + +&usbc0_dp_phy { + status = "okay"; +}; + +&usbc1_dp_phy { + status = "okay"; +}; + + +&usbc_phy2 { + orientation-switch; + svid = <0xff01>; + default_conf = /bits/ 8 <0x02>; + status = "okay"; + mode-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy2_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_phy_sw>; + }; + }; +}; + +&usb3_phy2 { + status = "okay"; +}; + +&usbc2_dp_phy { + status = "okay"; +}; + +&sky1_usbss_2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb2>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_2 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_2_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_role_sw>; + }; + }; +}; + +&usb3_phy4 { + status = "okay"; +}; + +&usb3_phy4_0 { + status = "okay"; +}; + +&sky1_usbss_4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb4>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_4 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_0 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_0 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_1 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_1 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_2 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_2 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_3 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_3 { + status = "okay"; + dr_mode = "host"; +}; + + +/********** clickpad **********/ +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + i2c-hid-dev@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + hid-descr-addr = <0x0001>; + interrupt-parent = <&s5_gpio0>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; +}; + +/********** RTC **********/ +&i2c3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c3>; + ra8900ce: ra8900ce@32 { + compatible = "rtc,rx8900"; + reg = <0x32>; + interrupt-parent = <&s5_gpio0>; + interrupts = <26 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; +}; + +&i2c4 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; +}; + +/********** HID_EC **********/ +&i2c5 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; + clock-frequency = <100000>; + keyboard_0: keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + interrupt-parent = <&s5_gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + hid-descr-addr = <0x0001>; + status = "okay"; + }; +}; + +/********** OS_PROTOCOL_EC **********/ +&i2c6 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c6>; + cros_ec: ec@76 { + compatible = "google,cros-ec-i2c"; + reg = <0x76>; + //interrupt-parent = <&s5_gpio0>; + //interrupts = <6 IRQ_TYPE_EDGE_RISING>; + //wakeup-source; + status = "okay"; + }; +}; + +&cros_ec { + cros_ec_pwm: ec-pwm { + compatible = "google,cros-ec-pwm"; + #pwm-cells = <1>; + status = "disabled"; + }; + + cix_fan: pwm-fan { + compatible = "pwm-fan"; + cooling-levels = <0 150 200 255>; + #cooling-cells = <2>; + pwms = <&cros_ec_pwm 0>; + status = "disabled"; + }; + + cix_ec_light { + compatible = "cix,cix-ec-light"; + status = "disabled"; + }; + + cix_ec_lid { + compatible = "cix,cix-ec-lid"; + status = "disabled"; + }; + + cix_ec_battery { + compatible = "cix,cix-ec-battery"; + status = "okay"; + }; + + cix_ec_charge { + compatible = "cix,cix-ec-charge"; + status = "okay"; + }; + + cix_ec_kb_backlight{ + compatible = "cix,cix-ec-keyboard-backlight"; + status = "disabled"; + }; + + ec_gpio: cix_ec_gpio { + compatible = "cix,cix-ec-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <104>; + status = "okay"; + }; +}; + +/********** PD1&PD2 **********/ +&i2c7 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c7>; + clock-frequency = <100000>; + rts5453_pd0:rts5453@30 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + id = <0>; + reg = <0x30>; + status = "okay"; + usbc_con0 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc0_role_sw: endpoint { + remote-endpoint = <&cdnsp_0_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc0_phy_sw: endpoint { + remote-endpoint = <&usbdpphy0_lane_switch>; + }; + }; + }; + }; + + rts5453_pd1:rts5453@31 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; + id = <1>; + reg = <0x31>; + status = "okay"; + usbc_con1 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc2_role_sw: endpoint { + remote-endpoint = <&cdnsp_2_role_switch>; + }; + }; + + port@1 { + reg = <1>; + usbc2_phy_sw: endpoint { + remote-endpoint = <&usbdpphy2_lane_switch>; + }; + }; + }; + }; +}; + +/*********** dTPM ***********/ +&spi0{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + /* Character device nodes for device communication on CS0(/dev/spidev0.0) */ + spidev0_0:spi@0_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; +}; + +&its_pcie { + status = "okay"; +}; + +&smmu_pciehub{ + status = "disabled"; +}; + +&pcie_x8_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x8_rc>; + reset-gpios = <&s5_gpio0 1 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pcie_x4_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x4_rc>; + reset-gpios = <&s5_gpio0 3 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&pcie_x2_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x2_rc>; + reset-gpios = <&s5_gpio0 2 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pcie_x1_1_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_1_rc>; + reset-gpios = <&s5_gpio0 5 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pcie_x1_0_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_0_rc>; + reset-gpios = <&s5_gpio0 4 GPIO_ACTIVE_HIGH>; + vcc-pcie-supply = <&vdd_3v3_pcie>; + wlan-en-supply = <&wlan_poweren>; + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + +&pcie_x4_phy { + status = "okay"; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie_x8_phy { + status = "okay"; +}; + +&pciex211_phy { + status = "okay"; +}; + +&pcie_x1_phy0 { + status = "okay"; +}; + +&pcie_x1_phy1 { + status = "okay"; +}; + +&pcie_x2_phy { + status = "okay"; +}; + +&pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm0>; + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm1>; + status = "disabled"; +}; + +&dp0 { + status = "okay"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + dp0_0_in: endpoint { + remote-endpoint = <&dpu0_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp0_1_in: endpoint { + remote-endpoint = <&dpu0_pipe1_out>; + }; + }; + }; +}; + +&dp1 { + status = "okay"; + cix,dp-max-rate = <540000>; + cix,delay_after_hpd = <128>; + + ports { + port@0 { + reg = <0>; + dp1_0_in: endpoint { + remote-endpoint = <&dpu1_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp1_1_in: endpoint { + remote-endpoint = <&dpu1_pipe1_out>; + }; + }; + }; +}; + +&dp2 { + status = "okay"; + cix,dp-max-rate = <540000>; + edp-panel = <&panel_edp0>; + + ports { + port@0 { + reg = <0>; + dp2_0_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp2_1_in: endpoint { + remote-endpoint = <&dpu2_pipe1_out>; + }; + }; + }; +}; + +&dp3 { + status = "okay"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + dp3_0_in: endpoint { + remote-endpoint = <&dpu3_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp3_1_in: endpoint { + remote-endpoint = <&dpu3_pipe1_out>; + }; + }; + }; +}; + +&dp4 { + status = "disabled"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + dp4_0_in: endpoint { + remote-endpoint = <&dpu4_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp4_1_in: endpoint { + remote-endpoint = <&dpu4_pipe1_out>; + }; + }; + }; +}; + +&dpu0 { + status = "okay"; + + pipeline@0 { + port { + dpu0_pipe0_out: endpoint { + remote-endpoint = <&dp0_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu0_pipe1_out: endpoint { + remote-endpoint = <&dp0_1_in>; + }; + }; + }; +}; + +&dpu1 { + status = "okay"; + + pipeline@0 { + port { + dpu1_pipe0_out: endpoint { + remote-endpoint = <&dp1_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu1_pipe1_out: endpoint { + remote-endpoint = <&dp1_1_in>; + }; + }; + }; +}; + +&dpu2 { + status = "okay"; + + pipeline@0 { + port { + dpu2_pipe0_out: endpoint { + remote-endpoint = <&dp2_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu2_pipe1_out: endpoint { + remote-endpoint = <&dp2_1_in>; + }; + }; + }; +}; + +&dpu3 { + status = "okay"; + + pipeline@0 { + port { + dpu3_pipe0_out: endpoint { + remote-endpoint = <&dp3_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu3_pipe1_out: endpoint { + remote-endpoint = <&dp3_1_in>; + }; + }; + }; +}; + +&dpu4 { + status = "disabled"; + + pipeline@0 { + port { + dpu4_pipe0_out: endpoint { + remote-endpoint = <&dp4_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu4_pipe1_out: endpoint { + remote-endpoint = <&dp4_1_in>; + }; + }; + }; +}; + +&aeu0 { + status = "disabled"; +}; + +&aeu1 { + status = "disabled"; +}; + +&aeu2 { + status = "disabled"; +}; + +&aeu3 { + status = "disabled"; +}; + +&aeu4 { + status = "disabled"; +}; + +&mbox_ap2pm { + status = "okay"; +}; + +&mbox_pm2ap { + status = "okay"; +}; + +&ap2pm_scmi_mem { + status = "okay"; +}; + +&pm2ap_scmi_mem { + status = "okay"; +}; + +&ap_tfa_scmi_mem { + status = "okay"; +}; + +&ap_to_pm_scmi { + status = "okay"; +}; + +&ap_to_tfa_scmi { + status = "okay"; +}; + +&vpu { + status = "okay"; +}; + +&thermal_zones { + cpu-m1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M1_TEMP_SENSOR_ID>; + + trips { + m1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B1_TEMP_SENSOR_ID>; + + trips { + b1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-m0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + + trips { + m0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B0_TEMP_SENSOR_ID>; + + trips { + b0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; + +&gpu { + gpu-microvolt = <800000>; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-crb.dts b/arch/arm64/boot/dts/cix/sky1-crb.dts new file mode 100644 index 000000000000..e10babec1bd5 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-crb.dts @@ -0,0 +1,1299 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1.dtsi" +/delete-node/ ®_definition; + +/ { + model = "CIX sky1 CRB board"; + compatible = "cix,sky1"; + + chosen { + stdout-path = &uart2; + }; + + alc5682: codec { + compatible = "realtek,rt5682s"; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "disabled"; + + dai-link-i2s0 { + cpu { + sound-dai = <&i2s0>; + }; + codec { + sound-dai = <&alc5682 0>; + }; + }; + + dai-link-dp-out { + jack-det,dpout; + cpu { + sound-dai = <&i2s5 0>; + }; + }; + }; + + dp2_backlight: dp2_backlight { + compatible = "pwm-backlight"; + enable-gpios = <&fch_gpio3 15 GPIO_ACTIVE_HIGH>; + pwms = <&pwm0 0 100000>; + status = "disabled"; + + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + + }; + + panel_edp0: panel_edp0 { + status = "disabled"; + compatible = "cix-edp-panel"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_edp0>; + backlight = <&dp2_backlight>; + prepare-delay-ms = <120>; + enable-delay-ms = <120>; + unprepare-delay-ms = <500>; + disable-delay-ms = <120>; + width-mm = <129>; + height-mm = <171>; + enable-gpios = <&fch_gpio3 16 GPIO_ACTIVE_HIGH>; + }; +}; + +&s5_gpio0 { + status = "okay"; +}; + +&iomuxc_s5 { + status = "okay"; + + pinctrl_sfi_i2c0: pinctrl_sfi_i2c0_grp { + sky1,pins = < + 0x00000070 0x0000005c + 0x00000074 0x0000005c + >; + }; + pinctrl_sfi_i2c1: pinctrl_sfi_i2c1_grp { + sky1,pins = < + 0x00000078 0x00000057 + 0x0000007c 0x00000057 + >; + }; + pinctrl_sfi_i3c0: pinctrl_sfi_i3c0_grp { + sky1,pins = < + 0x00000070 0x000000dc + 0x00000074 0x000000dc + 0x000000a0 0x00000157 + >; + }; + pinctrl_sfi_i3c1: pinctrl_sfi_i3c1_grp { + sky1,pins = < + 0x00000078 0x000000dc + 0x0000007c 0x000000dc + 0x000000a4 0x00000157 + >; + }; + pinctrl_sfi_spi: pinctrl_sfi_spi_grp { + sky1,pins = < + 0x00000078 0x00000157 + 0x0000007c 0x00000157 + 0x00000080 0x00000097 + 0x00000084 0x000000d7 + 0x00000088 0x000000d7 + >; + }; + + pinctrl_fch_spi0: pinctrl_fch_spi0_grp { + sky1,pins = < + 0x000000a8 0x0000005c + 0x000000ac 0x0000005c + 0x000000b0 0x0000005c + 0x000000b4 0x0000005c + 0x000000b8 0x0000001c + >; + }; + pinctrl_fch_xspi: pinctrl_fch_xspi_grp { + sky1,pins = < + 0x000000f0 0x000000dc + 0x000000f4 0x000000dc + 0x000000f8 0x000000dc + 0x000000fc 0x000000dc + 0x00000100 0x000000dc + 0x00000104 0x000000dc + >; + }; + pinctrl_usb4: pinctrl_usb4_grp { + sky1,pins = < + 0x000000cc 0x000000c4 + 0x000000e8 0x000000a4 + >; + }; + + pinctrl_usb5: pinctrl_usb5_grp { + sky1,pins = < + 0x000000d0 0x000000c4 + 0x000000ec 0x000000a4 + >; + }; + pinctrl_usb6: pinctrl_usb6_oc_grp { + sky1,pins = < + 0x000000d4 0x000000c4 + >; + }; + pinctrl_usb8: pinctrl_usb8_oc_grp { + sky1,pins = < + 0x000000dc 0x000000c4 + >; + }; + pinctrl_usb9: pinctrl_usb9_oc_grp { + sky1,pins = < + 0x000000e0 0x000000c4 + >; + }; +}; + +&iomuxc_s5 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_s5>; + pinctrl_hog_s5: pinctrl_hog_s5 { + + }; + + pinctrl_pcie_x8_rc: pinctrl_pcie_x8_rc { + sky1,pins = < + 0x00000004 0x00000024 + >; + }; + + pinctrl_pcie_x4_rc: pinctrl_pcie_x4_rc { + sky1,pins = < + 0x00000008 0x00000024 + >; + }; + + pinctrl_pcie_x2_rc: pinctrl_pcie_x2_rc { + sky1,pins = < + 0x0000000c 0x00000024 + >; + }; + + pinctrl_pcie_x1_1_rc: pinctrl_pcie_x1_1_rc {/*x1_1*/ + sky1,pins = < + 0x00000014 0x00000024 + >; + }; + + pinctrl_pcie_x1_0_rc: pinctrl_pcie_x1_0_rc {/*x1_0*/ + sky1,pins = < + 0x00000010 0x00000024 + >; + }; +}; + +&iomuxc { + status = "okay"; + pinctrl_fch_pwm0: pinctrl_fch_pwm0 { + sky1,pins = < + 0x0000013c 0x000000b7 + >; + }; + + pinctrl_fch_pwm1: pinctrl_fch_pwm1 { + sky1,pins = < + 0x00000140 0x000000b7 + >; + }; + + pinctrl_gmac0: pinctrl_gmac0 { + sky1,pins = + /* rfclk_25M */ + < 0x000001a4 0x0000009c>, + /* txc_trl */ + < 0x000001a8 0x0000009c>, + /* txd0 */ + < 0x000001ac 0x0000009c>, + /* txd1 */ + < 0x000001b0 0x0000009c>, + /* txd2 */ + < 0x000001b4 0x0000009c>, + /* txd3 */ + < 0x000001b8 0x0000009c>, + /* tx_clk */ + < 0x000001bc 0x00000094>, + /* rx_ctl */ + < 0x000001c0 0x00000094>, + /* rxd0 */ + < 0x000001c4 0x00000094>, + /* rxd1 */ + < 0x000001c8 0x00000094>, + /* rxd2 */ + < 0x000001cc 0x00000094>, + /* rxd3 */ + < 0x000001d0 0x00000094>, + /* rx_clk */ + < 0x000001d4 0x00000094>, + /* mdc */ + < 0x000001d8 0x0000009c>, + /* mdio */ + < 0x000001dc 0x0000009c>; + }; + + pinctrl_fch_fan0: pinctrl_fch_fan0 { + sky1,pins = < + 0x0000014c 0x000000b7 + >; + }; + + pinctrl_fch_fan1: pinctrl_fch_fan1 { + sky1,pins = < + 0x00000154 0x000000b7 + >; + }; + + pinctrl_fch_fan2: pinctrl_fch_fan2 { + sky1,pins = < + 0x00000144 0x000000b7 + >; + }; + + pinctrl_fch_i2c0: pinctrl_fch_i2c0 { + sky1,pins = < + 0x00000078 0x00000047 + 0x0000007c 0x00000047 + >; + }; + + pinctrl_fch_i2c1: pinctrl_fch_i2c1 { + sky1,pins = < + 0x00000080 0x00000047 + 0x00000084 0x00000047 + >; + }; + + pinctrl_fch_i2c2: pinctrl_fch_i2c2 { + sky1,pins = < + 0x00000088 0x0000005c + 0x0000008c 0x0000005c + >; + }; + + pinctrl_fch_i2c3: pinctrl_fch_i2c3 { + sky1,pins = < + 0x00000094 0x0000005c + 0x00000098 0x0000005c + >; + }; + + pinctrl_fch_i2c4: pinctrl_fch_i2c4 { + sky1,pins = < + 0x000000a0 0x00000047 + 0x000000a4 0x00000047 + >; + }; + + pinctrl_fch_i2c5: pinctrl_fch_i2c5 { + sky1,pins = < + 0x00000068 0x00000047 + 0x0000006c 0x00000047 + >; + }; + + pinctrl_fch_i2c6: pinctrl_fch_i2c6 { + sky1,pins = < + 0x00000070 0x00000047 + 0x00000074 0x00000047 + >; + }; + + pinctrl_fch_i2c7: pinctrl_fch_i2c7 { + sky1,pins = < + 0x00000054 0x00000047 + 0x00000058 0x00000047 + >; + }; + + pinctrl_fch_spi1: pinctrl_fch_spi1_grp { + sky1,pins = < + 0x000001e8 0x0000015c + 0x000001ec 0x0000015c + 0x000001f0 0x0000015c + 0x000001f4 0x0000015c + 0x000001f8 0x0000011c + >; + }; + + pinctrl_fch_i3c0: pinctrl_fch_i3c0 { + sky1,pins = < + 0x00000088 0x000000dc + 0x0000008c 0x000000dc + 0x00000090 0x000000dc + >; + }; + + pinctrl_fch_i3c1: pinctrl_fch_i3c1 { + sky1,pins = < + 0x00000094 0x000000dc + 0x00000098 0x000000dc + 0x0000009c 0x000000dc + >; + }; + + pinctrl_fch_uart0: pinctrl_fch_uart0 { + sky1,pins = < + 0x0000013c 0x00000057 + 0x00000140 0x00000057 + 0x00000144 0x00000057 + 0x00000148 0x00000057 + >; + }; + + pinctrl_fch_uart1: pinctrl_fch_uart1 { + sky1,pins = < + 0x0000014c 0x00000057 + 0x00000150 0x00000057 + 0x00000154 0x00000057 + 0x00000158 0x00000057 + >; + }; + + pinctrl_fch_uart2: pinctrl_fch_uart2 { + sky1,pins = < + 0x0000015c 0x00000047 + 0x00000160 0x00000047 + >; + }; + + pinctrl_edp0: pinctrl_edp0 { + sky1,pins = < + 0x00000048 0x00000024 /* DP2_DIGON */ + 0x0000004C 0x00000024 /* DP2_BLON */ + 0x00000050 0x00000007 /* DP2_VARY_BL */ + >; + }; +}; + +&hifi5 { + status = "disabled"; +}; + +&mbox_dsp2ap { + status = "disabled"; +}; + +&mbox_ap2dsp { + status = "disabled"; +}; + +&audss_cru { + status = "disabled"; +}; + +&i2s0 { + /* i2s_sc0 for codec */ + status = "disabled"; +}; + +&i2s1 { + /* i2s_sc1 for 5G/BT */ + status = "disabled"; +}; + +&i2s2 { + /* i2s_sc2 for loopback */ + status = "disabled"; +}; + +&i2s3 { + /* i2s_mc2a for speaker */ + status = "disabled"; +}; + +&i2s4 { + /* i2s_mc2b for dp-in */ + cdns,pin-rx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as receiver */ + status = "disabled"; +}; + +&i2s5 { + /* i2s_mc5a for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s6 { + /* i2s_mc5b for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s7 { + /* i2s_mc5c for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s8 { + /* i2s_mc5d for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s9 { + /* i2s_mc5e for dp-out */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&sensorhub { + memory-region = <&sfh_vdev0buffer>, <&sfh_vdev0vring0>, + <&sfh_vdev0vring1>, <&sfh_ram>; + status = "disabled"; +}; + +/*********** adapter card -> camera **********/ +&i2c0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c0>; +}; + +/********** adapter card -> camera **********/ +&i2c1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c1>; + rts5453_pd1:rts5453@30 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; + id = <2>; + reg = <0x30>; + status = "okay"; + usbc_con2 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc2_role_sw: endpoint { + remote-endpoint = <&cdnsp_2_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc2_phy_sw: endpoint { + remote-endpoint = <&usbdpphy2_lane_switch>; + }; + }; + }; + }; +}; + +/********** touch screen & codes ***********/ +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + i2c-hid-dev@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + hid-descr-addr = <0x0001>; + interrupt-parent = <&s5_gpio0>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; +}; + +/********** clickpad & adapter card -> camera***********/ +&i2c3 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c3>; +}; + +/********** NFC & adapter card -> camera ***********/ +&i2c4 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; + nfc: nfc@28 { + compatible = "nfc,nfc_28h"; + reg = <0x28>; + status = "disabled"; + }; +}; + +/********** EC ***********/ +&i2c5 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; +}; + +/********** EC ***********/ +&i2c6 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c6>; +}; + +/********** PD card ***********/ +&i2c7 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c7>; + rts5453_pd0:rts5453@30 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + id = <0>; + reg = <0x30>; + status = "okay"; + usbc_con0 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc0_role_sw: endpoint { + remote-endpoint = <&cdnsp_0_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc0_phy_sw: endpoint { + remote-endpoint = <&usbdpphy0_lane_switch>; + }; + }; + }; + }; +}; + +/********** HID_EC **********/ +&i2c5 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; + clock-frequency = <100000>; + keyboard_0: keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + interrupt-parent = <&s5_gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + hid-descr-addr = <0x0001>; + status = "disabled"; + }; +}; + +/********** OS_PROTOCOL_EC **********/ +&i2c6 { + status = "disabled"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c6>; + cros_ec: ec@76 { + compatible = "google,cros-ec-i2c"; + reg = <0x76>; + interrupt-parent = <&s5_gpio0>; + interrupts = <6 IRQ_TYPE_EDGE_RISING>; + wakeup-source; + status = "disabled"; + }; +}; + +&cros_ec { + cros_ec_pwm: ec-pwm { + compatible = "google,cros-ec-pwm"; + #pwm-cells = <1>; + status = "disabled"; + }; + + cix_fan: pwm-fan { + compatible = "pwm-fan"; + cooling-levels = <0 150 200 255>; + #cooling-cells = <2>; + pwms = <&cros_ec_pwm 0>; + status = "disabled"; + }; + + cix_ec_light { + compatible = "cix,cix-ec-light"; + status = "disabled"; + }; + + cix_ec_lid { + compatible = "cix,cix-ec-lid"; + status = "disabled"; + }; + + cix_ec_battery { + compatible = "cix,cix-ec-battery"; + status = "disabled"; + }; + + cix_ec_charge { + compatible = "cix,cix-ec-charge"; + status = "disabled"; + }; + + cix_ec_kb_backlight{ + compatible = "cix,cix-ec-keyboard-backlight"; + status = "disabled"; + }; + + ec_gpio: cix_ec_gpio { + compatible = "cix,cix-ec-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <104>; + status = "disabled"; + }; +}; + +/*uart0 for BT*/ +&uart0{ + pinctrl-names = "default"; + timeout-value = <10000>; + pinctrl-0 = <&pinctrl_fch_uart0>; + dmas = <&fch_dmac 2 0>, <&fch_dmac 3 1>; + dma-names = "tx","rx"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart2>; + clock-names = "uartclk", "apb_pclk"; + status = "okay"; +}; + +&gmac_rcsu { + status = "okay"; +}; + +&fch_gpio0 { + status = "okay"; +}; + +&macb0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gmac0>; + phy-mode = "rgmii-id"; + cix,gmac-ctrl = <&gmac_rcsu>; + phy-handle = <&mac0_phy>; + reset-delay-us = <20000>; /* 20ms */ + reset-post-delay-us = <100000>; /* 100ms */ + reset-gpios = <&fch_gpio0 0 GPIO_ACTIVE_LOW>; + mac0_phy: ethernet-phy@1 { + reg = <1>; + device_type = "ethernet-phy"; + compatible = "ethernet-phy-ieee802.3-c22"; + }; +}; + +&usbc_phy0 { + orientation-switch; + mode-switch; + svid = <0xff01>; + status = "okay"; + default_conf = /bits/ 8 <0x03>; + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy0_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_phy_sw>; + }; + }; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&sky1_usbss_0 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_0 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_0_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_role_sw>; + }; + }; +}; + +&usbc_phy2 { + status = "okay"; + orientation-switch; + svid = <0xff01>; + mode-switch; + default_conf = /bits/ 8 <0x03>; + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy2_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_phy_sw>; + }; + }; +}; + +&usb3_phy2 { + status = "okay"; +}; + +&sky1_usbss_2 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_2 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_2_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_role_sw>; + }; + }; +}; + + +&usbc_phy3 { + default_conf = /bits/ 8 <0x03>; + status = "okay"; +}; + +&usb3_phy3 { + status = "okay"; +}; + +&sky1_usbss_3 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_3 { + status = "okay"; + dr_mode = "host"; +}; + +&usb3_phy4 { + status = "okay"; +}; + +&usb3_phy4_0 { + status = "okay"; +}; + +&sky1_usbss_4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb4>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_4 { + status = "okay"; + dr_mode = "host"; +}; + +&usb3_phy4_1 { + status = "okay"; +}; + +&sky1_usbss_5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb5>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_5 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb6>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_0 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbhs_1 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_1 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbhs_2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb8>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_2 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbhs_3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb9>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_3 { + status = "disabled"; + dr_mode = "host"; +}; + +&its_pcie { + status = "okay"; +}; + +&smmu_pciehub{ + status = "disabled"; +}; + +&pcie_x8_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x8_rc>; + reset-gpios = <&s5_gpio0 1 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pcie_x4_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x4_rc>; + reset-gpios = <&s5_gpio0 3 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +&pcie_x2_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x2_rc>; + reset-gpios = <&s5_gpio0 2 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pcie_x1_1_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_1_rc>; + reset-gpios = <&s5_gpio0 5 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pcie_x1_0_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_0_rc>; + reset-gpios = <&s5_gpio0 4 GPIO_ACTIVE_HIGH>; + status = "disabled"; +}; + +&pcie1_phy { + status = "okay"; +}; + +&pcie_x4_phy { + status = "okay"; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie_x8_phy { + status = "okay"; +}; + +&pciex211_phy { + status = "okay"; +}; + +&pcie_x1_phy0 { + status = "okay"; +}; + +&pcie_x1_phy1 { + status = "okay"; +}; + +&pcie_x2_phy { + status = "okay"; +}; + +&dp0 { + status = "disabled"; + + port { + dp0_in: endpoint { + remote-endpoint = <&dpu0_pipe0_out>; + }; + }; +}; + +&dp1 { + status = "disabled"; + + port { + dp1_in: endpoint { + remote-endpoint = <&dpu1_pipe0_out>; + }; + }; +}; + +&dp2 { + status = "disabled"; + + edp-panel = <&panel_edp0>; + + port { + dp2_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; +}; + +&dp3 { + status = "disabled"; + + port { + dp3_in: endpoint { + remote-endpoint = <&dpu3_pipe0_out>; + }; + }; +}; + +&dp4 { + status = "disabled"; + + port { + dp4_in: endpoint { + remote-endpoint = <&dpu4_pipe0_out>; + }; + }; +}; + +&dpu0 { + status = "disabled"; + + pipeline@0 { + port { + dpu0_pipe0_out: endpoint { + remote-endpoint = <&dp0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu0_pipe1_out: endpoint { + //remote-endpoint = <&vt_enc1_in>; + }; + }; + }; +}; + +&dpu1 { + status = "disabled"; + + pipeline@0 { + port { + dpu1_pipe0_out: endpoint { + remote-endpoint = <&dp1_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu1_pipe1_out: endpoint { + //remote-endpoint = <&vt_enc3_in>; + }; + }; + }; +}; + +&dpu2 { + status = "disabled"; + + pipeline@0 { + port { + dpu2_pipe0_out: endpoint { + remote-endpoint = <&dp2_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu2_pipe1_out: endpoint { + //remote-endpoint = <&vt_enc5_in>; + }; + }; + }; +}; + +&dpu3 { + status = "disabled"; + + pipeline@0 { + port { + dpu3_pipe0_out: endpoint { + remote-endpoint = <&dp3_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu3_pipe1_out: endpoint { + //remote-endpoint = <&vt_enc7_in>; + }; + }; + }; +}; + +&dpu4 { + status = "disabled"; + + pipeline@0 { + port { + dpu4_pipe0_out: endpoint { + remote-endpoint = <&dp4_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu4_pipe1_out: endpoint { + //remote-endpoint = <&vt_enc9_in>; + }; + }; + }; +}; + +&aeu0 { + status = "disabled"; +}; + +&aeu1 { + status = "disabled"; +}; + +&aeu2 { + status = "disabled"; +}; + +&aeu3 { + status = "disabled"; +}; + +&aeu4 { + status = "disabled"; +}; + +&mbox_ap2pm { + status = "okay"; +}; + +&mbox_pm2ap { + status = "okay"; +}; + +&ap2pm_scmi_mem { + status = "okay"; +}; + +&pm2ap_scmi_mem { + status = "okay"; +}; + +&ap_tfa_scmi_mem { + status = "okay"; +}; + +&ap_to_pm_scmi { + status = "okay"; +}; + +&ap_to_tfa_scmi { + status = "okay"; +}; + +&thermal_zones { + cpu-m1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M1_TEMP_SENSOR_ID>; + + trips { + m1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B1_TEMP_SENSOR_ID>; + + trips { + b1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-m0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + + trips { + m0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + + trips { + b0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-emu-pm.dts b/arch/arm64/boot/dts/cix/sky1-emu-pm.dts new file mode 100644 index 000000000000..c3bace36d765 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-emu-pm.dts @@ -0,0 +1,10 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "sky1-emu.dts" + +&smmu_mmhub{ + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-emu-smp.dts b/arch/arm64/boot/dts/cix/sky1-emu-smp.dts new file mode 100644 index 000000000000..81ac9abee7cf --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-emu-smp.dts @@ -0,0 +1,27 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ +#include "sky1-emu.dts" + +&gic { + #redistributor-regions = <12>; + reg = <0x0 0x0e010000 0 0x10000>, /* GICD */ + <0x0 0x0e090000 0 0x40000>, /* GICR0 */ + <0x0 0x0e0d0000 0 0x40000>, /* GICR1 */ + <0x0 0x0e110000 0 0x40000>, /* GICR2 */ + <0x0 0x0e150000 0 0x40000>, /* GICR3 */ + <0x0 0x0e190000 0 0x40000>, /* GICR4 */ + <0x0 0x0e1d0000 0 0x40000>, /* GICR5 */ + <0x0 0x0e210000 0 0x40000>, /* GICR6 */ + <0x0 0x0e250000 0 0x40000>, /* GICR7 */ + <0x0 0x0e290000 0 0x40000>, /* GICR8 */ + <0x0 0x0e2d0000 0 0x40000>, /* GICR9 */ + <0x0 0x0e310000 0 0x40000>, /* GICR10 */ + <0x0 0x0e350000 0 0x40000>; /* GICR11 */ +}; + +&smmu_mmhub{ + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-emu.dts b/arch/arm64/boot/dts/cix/sky1-emu.dts new file mode 100755 index 000000000000..a934dacc8cb3 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-emu.dts @@ -0,0 +1,1571 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +#define CONFIG_ARCH_CIX_EMU_FPGA + +#include "sky1.dtsi" +/delete-node/ ®_definition; + +/ { + model = "CIX sky1 EMU platform"; + compatible = "cix,sky1-emu", "cix,sky1"; + + sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "disabled"; + + i2s-sc0 { + format = "dsp_a"; + frame-master = <&i2s_sc0>; + bitclock-master = <&i2s_sc0>; + bitclock-inversion; + mclk-fs = <256>; + + dai-tdm-slot-tx-mask = <1 1 1 1>; + dai-tdm-slot-rx-mask = <1 1 1 1>; + dai-tdm-slot-num = <4>; + dai-tdm-slot-width = <16>; + + i2s_sc0: cpu { + sound-dai = <&i2s0>; + }; + }; + + i2s-mc0 { + format = "i2s"; + bitclock-inversion; + mclk-fs = <256>; + + cpu { + sound-dai = <&i2s3 0>; + }; + }; + + }; + + chosen { + stdout-path = "serial2:921600n8"; + }; + + virtual-encoder@0 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc0_in: endpoint { + remote-endpoint = <&dpu0_pipe0_out>; + }; + }; + }; + + virtual-encoder@1 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc1_in: endpoint { + remote-endpoint = <&dpu0_pipe1_out>; + }; + }; + }; + + virtual-encoder@2 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc2_in: endpoint { + remote-endpoint = <&dpu1_pipe0_out>; + }; + }; + }; + + virtual-encoder@3 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc3_in: endpoint { + remote-endpoint = <&dpu1_pipe1_out>; + }; + }; + }; + + virtual-encoder@4 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc4_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; + }; + + virtual-encoder@5 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc5_in: endpoint { + remote-endpoint = <&dpu2_pipe1_out>; + }; + }; + }; + + virtual-encoder@6 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc6_in: endpoint { + remote-endpoint = <&dpu3_pipe0_out>; + }; + }; + }; + + virtual-encoder@7 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc7_in: endpoint { + remote-endpoint = <&dpu3_pipe1_out>; + }; + }; + }; + + virtual-encoder@8 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc8_in: endpoint { + remote-endpoint = <&dpu4_pipe0_out>; + }; + }; + }; + + virtual-encoder@9 { + compatible = "cix,virtual-display"; + status = "disabled"; + + port { + vt_enc9_in: endpoint { + remote-endpoint = <&dpu4_pipe1_out>; + }; + }; + }; + + soc@0 { + uart2: uart@040d0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040d0000 0x0 0x1000>; + interrupts = ; + clocks = <&uartclk>, <&uart_apb_pclk>; + clock-names = "uartclk", "apb_pclk"; + status = "okay"; + }; + + vcc: eeprom{ + compatible = "regulator-fixed"; + regulator-name = "vcc"; + regulator-always-on; + regulator-boot-on; + regulator-min-microvolt = <12000000>; + regulator-max-microvolt = <12000000>; + }; + + }; +}; + +&iomuxc_s5 { + status = "okay"; + pinctrl_sfi_i2c0: pinctrl_sfi_i2c0_grp { + sky1,pins = < + 0x00000070 0x0000005c + 0x00000074 0x0000005c + >; + }; + + pinctrl_sfi_i2c1: pinctrl_sfi_i2c1_grp { + sky1,pins = < + 0x00000078 0x00000057 + 0x0000007c 0x00000057 + >; + }; + + pinctrl_sfi_i3c0: pinctrl_sfi_i3c0_grp { + sky1,pins = < + 0x00000070 0x000000dc + 0x00000074 0x000000dc + 0x000000a0 0x00000157 + >; + }; + + pinctrl_sfi_i3c1: pinctrl_sfi_i3c1_grp { + sky1,pins = < + 0x00000078 0x000000dc + 0x0000007c 0x000000dc + 0x000000a4 0x00000157 + >; + }; + + pinctrl_sfi_spi: pinctrl_sfi_spi_grp { + sky1,pins = < + 0x00000078 0x00000157 + 0x0000007c 0x00000157 + 0x00000080 0x000000d7 + 0x00000084 0x000000d7 + 0x00000088 0x000000d7 + >; + }; + + pinctrl_fch_spi0: pinctrl_fch_spi0_grp { + sky1,pins = < + 0x000000a8 0x0000005c + 0x000000ac 0x0000005c + 0x000000b0 0x0000005c + 0x000000b4 0x0000005c + 0x000000b8 0x0000005c + >; + }; + + pinctrl_fch_xspi: pinctrl_fch_xspi_grp { + sky1,pins = < + 0x000000f0 0x000000dc + 0x000000f4 0x000000dc + 0x000000f8 0x000000dc + 0x000000fc 0x000000dc + 0x00000100 0x000000dc + 0x00000104 0x000000dc + >; + }; +}; + +&iomuxc { + status = "okay"; + pinctrl_fch_pwm0: pinctrl_fch_pwm0 { + sky1,pins = < + 0x0000013c 0x000000b7 + >; + }; + + pinctrl_fch_pwm1: pinctrl_fch_pwm1 { + sky1,pins = < + 0x00000140 0x000000b7 + >; + }; + + pinctrl_fch_fan0: pinctrl_fch_fan0 { + sky1,pins = < + 0x0000014c 0x000000b7 + >; + }; + + pinctrl_fch_fan1: pinctrl_fch_fan1 { + sky1,pins = < + 0x00000154 0x000000b7 + >; + }; + + pinctrl_fch_fan2: pinctrl_fch_fan2 { + sky1,pins = < + 0x00000144 0x000000b7 + >; + }; + + pinctrl_fch_i2c0: pinctrl_fch_i2c0 { + sky1,pins = < + 0x00000078 0x00000047 + 0x0000007c 0x00000047 + >; + }; + + pinctrl_fch_i2c1: pinctrl_fch_i2c1 { + sky1,pins = < + 0x00000080 0x00000047 + 0x00000084 0x00000047 + >; + }; + + pinctrl_fch_i2c2: pinctrl_fch_i2c2 { + sky1,pins = < + 0x00000088 0x0000005c + 0x0000008c 0x0000005c + >; + }; + + pinctrl_fch_i2c3: pinctrl_fch_i2c3 { + sky1,pins = < + 0x00000094 0x0000005c + 0x00000098 0x0000005c + >; + }; + + pinctrl_fch_i2c4: pinctrl_fch_i2c4 { + sky1,pins = < + 0x000000a0 0x00000047 + 0x000000a4 0x00000047 + >; + }; + + pinctrl_fch_i2c5: pinctrl_fch_i2c5 { + sky1,pins = < + 0x00000068 0x00000047 + 0x0000006c 0x00000047 + >; + }; + + pinctrl_fch_i2c6: pinctrl_fch_i2c6 { + sky1,pins = < + 0x00000070 0x00000047 + 0x00000074 0x00000047 + >; + }; + + pinctrl_fch_i2c7: pinctrl_fch_i2c7 { + sky1,pins = < + 0x00000054 0x00000047 + 0x00000058 0x00000047 + >; + }; + + pinctrl_fch_spi1: pinctrl_fch_spi1_grp { + sky1,pins = < + 0x000001e8 0x0000013c + 0x000001ec 0x0000013c + 0x000001f0 0x0000013c + 0x000001f4 0x0000013c + 0x000001f8 0x0000013c + >; + }; + + pinctrl_fch_i3c0: pinctrl_fch_i3c0 { + sky1,pins = < + 0x00000088 0x000000dc + 0x0000008c 0x000000dc + 0x00000090 0x000000dc + >; + }; + + pinctrl_fch_i3c1: pinctrl_fch_i3c1 { + sky1,pins = < + 0x00000094 0x000000dc + 0x00000098 0x000000dc + 0x0000009c 0x000000dc + >; + }; + + pinctrl_fch_uart0: pinctrl_fch_uart0 { + sky1,pins = < + 0x0000013c 0x00000037 + 0x00000140 0x00000037 + 0x00000144 0x00000037 + 0x00000148 0x00000037 + >; + }; + + pinctrl_fch_uart1: pinctrl_fch_uart1 { + sky1,pins = < + 0x0000014c 0x00000037 + 0x00000150 0x00000037 + 0x00000154 0x00000037 + 0x00000158 0x00000037 + >; + }; + + pinctrl_fch_uart2: pinctrl_fch_uart2 { + sky1,pins = < + 0x0000015c 0x00000027 + 0x00000160 0x00000027 + 0x00000164 0x00000027 + 0x00000168 0x00000027 + >; + }; +}; + +&pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm0>; + status = "disabled"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm1>; + status = "disabled"; +}; + +&sky1_usbss_0 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbss_0 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbss_1 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbss_1 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbss_2 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbss_2 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbss_3 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbss_3 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbss_4 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbss_4 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbss_5 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbss_5 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbhs_0 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_0 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbhs_1 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_1 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbhs_2 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_2 { + status = "disabled"; + dr_mode = "host"; +}; + +&sky1_usbhs_3 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "disabled"; +}; + +&usbhs_3 { + status = "disabled"; + dr_mode = "host"; +}; + +&uart0{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart0>; + dmas = <&fch_dmac 2 0>, <&fch_dmac 3 1>; + dma-names = "tx","rx"; +}; + +&uart1{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart1>; + dmas = <&fch_dmac 4 2>, <&fch_dmac 5 3>; + dma-names = "tx","rx"; +}; + +&uart2{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart2>; +}; + +&xspi{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_xspi>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-max-frequency = <25000000>; + }; +}; + +&spi0{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + spidev0:spi@0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <50000000>; + }; +}; + +&spi1{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi1>; + spidev1:spi@0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <50000000>; + }; +}; + + +&i3c0{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c0>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50 0 0x10>; + vin-supply = <&vcc>; + }; +}; + +&i3c1{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c1>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50 0 0x10>; + vin-supply = <&vcc>; + }; +}; + + +&hifi5 { + status = "disabled"; +}; + +&mbox_dsp2ap { + status = "disabled"; +}; + +&mbox_ap2dsp { + status = "disabled"; +}; + +&audss_cru { + status = "disabled"; +}; + +&audss_dmac { + memory-region = <&audio_alsa>; + status = "disabled"; +}; + +&i2s0 { + /* i2s_sc0 for codec */ + dmas = <&audss_dmac 0 0>, <&audss_dmac 1 1>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s1 { + /* i2s_sc1 for 5G/BT */ + dmas = <&audss_dmac 2 2>, <&audss_dmac 3 3>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s2 { + /* i2s_sc2 for loopback */ + status = "disabled"; +}; + +&i2s3 { + /* i2s_mc2a for speaker */ + dmas = <&audss_dmac 4 6>; + dma-names = "tx"; + status = "disabled"; +}; + +&i2s4 { + /* i2s_mc2b for dp-in */ + dmas = <&audss_dmac 6 9>; + dma-names = "rx"; + status = "disabled"; +}; + +&i2s5 { + /* i2s_mc5a for dp-out */ + dmas = <&audss_dmac 7 10>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s6 { + /* i2s_mc5b for dp-out */ + dmas = <&audss_dmac 7 12>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s7 { + /* i2s_mc5c for dp-out */ + dmas = <&audss_dmac 7 14>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s8 { + /* i2s_mc5d for dp-out */ + dmas = <&audss_dmac 7 16>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s9 { + /* i2s_mc5e for dp-out */ + dmas = <&audss_dmac 7 18>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&dp2 { + status = "disabled"; + + cix,platform-id = <1>; + cix,aux-clock-divider = <15>; + port { + dp2_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; +}; + +&dpu0 { + status = "disabled"; + + pipeline@0 { + port { + dpu0_pipe0_out: endpoint { + remote-endpoint = <&vt_enc0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu0_pipe1_out: endpoint { + remote-endpoint = <&vt_enc1_in>; + }; + }; + }; +}; + +&dpu1 { + status = "disabled"; + + pipeline@0 { + port { + dpu1_pipe0_out: endpoint { + remote-endpoint = <&vt_enc2_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu1_pipe1_out: endpoint { + remote-endpoint = <&vt_enc3_in>; + }; + }; + }; +}; + +&dpu2 { + status = "disabled"; + + pipeline@0 { + port { + dpu2_pipe0_out: endpoint { + remote-endpoint = <&vt_enc4_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu2_pipe1_out: endpoint { + remote-endpoint = <&vt_enc5_in>; + }; + }; + }; +}; + +&dpu3 { + status = "disabled"; + + pipeline@0 { + port { + dpu3_pipe0_out: endpoint { + remote-endpoint = <&vt_enc6_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu3_pipe1_out: endpoint { + remote-endpoint = <&vt_enc7_in>; + }; + }; + }; +}; + +&dpu4 { + status = "disabled"; + + pipeline@0 { + port { + dpu4_pipe0_out: endpoint { + remote-endpoint = <&vt_enc8_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu4_pipe1_out: endpoint { + remote-endpoint = <&vt_enc9_in>; + }; + }; + }; +}; + +&uartclk { + clock-frequency = <25000000>; +}; + +&uart_apb_pclk { + clock-frequency = <25000000>; +}; + +&pmu { + status = "okay"; +}; + +&smmu_mmhub{ + status = "okay"; +}; + +&smmu_pciehub{ + status = "disabled"; +}; + +&vpu { + status = "okay"; +}; + +&cix_csi_rcsu_0 { + status = "okay"; +}; + +&cix_csi_rcsu_1 { + status = "okay"; +}; + +&cix_bridge_0 { + status = "okay"; + port { + cix_bridge_0_in: endpoint { + remote-endpoint = <&mipi_csi2_0_out>; + }; + }; +}; + +&cix_bridge_1 { + status = "okay"; + port { + cix_bridge_1_in: endpoint { + remote-endpoint = <&mipi_csi2_1_out>; + }; + }; +}; + +&cix_bridge_2 { + status = "okay"; + port { + cix_bridge_2_in: endpoint { + remote-endpoint = <&mipi_csi2_2_out>; + }; + }; +}; + +&cix_bridge_3 { + status = "okay"; + port { + cix_bridge_3_in: endpoint { + remote-endpoint = <&mipi_csi2_3_out>; + }; + }; +}; + +&cix_mipi_csi_0 { + lanes = <1>; + status = "okay"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_0_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy1_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_0_in>; + }; + }; + }; +}; + +&cix_mipi_csi_1 { + lanes = <1>; + status = "okay"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_1_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy2_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_1_in>; + }; + }; + }; +}; + +&cix_mipi_csi_2 { + lanes = <1>; + status = "okay"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_2_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy4_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_2_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_2_in>; + }; + }; + }; +}; + +&cix_mipi_csi_3 { + lanes = <1>; + status = "okay"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_3_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy5_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_3_in>; + }; + }; + }; +}; + +&cix_dphy_0 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy0_in: endpoint@1 { + reg = <1>; + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_0_in>; + }; + }; + }; +}; + +&cix_dphy_1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy1_in: endpoint@1 { + reg = <1>; + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_0_in>; + }; + }; + }; +}; + +&cix_dphy_2 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy2_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_0_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy2_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_1_in>; + }; + }; + }; + +}; + +&cix_dphy_3 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy3_in: endpoint@1 { + reg = <1>; + /*this not active*/ + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_2_in>; + }; + }; + }; +}; + +&cix_dphy_4 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy4_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_1_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy4_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_2_in>; + }; + }; + }; +}; + +&cix_dphy_5 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy5_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_2_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy5_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_3_in>; + }; + }; + }; +}; + +&cix_dphy_hw_0 { + status = "okay"; +}; + +&cix_dphy_hw_1 { + status = "okay"; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c0>; + + lt7911uxc: lt7911uxc@3d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3d>; + status = "okay"; + port { + lt7911uxc_out: endpoint { + remote-endpoint = <&dphy1_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_0: virtual_lt7911uxc_0@0d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0d>; + status = "okay"; + port { + virt_lt7911uxc_0_out: endpoint { + remote-endpoint = <&dphy2_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_1: virtual_lt7911uxc_1@1d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1d>; + status = "okay"; + port { + virt_lt7911uxc_1_out: endpoint { + remote-endpoint = <&dphy4_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_2: virtual_lt7911uxc_2@2d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2d>; + status = "okay"; + port { + virt_lt7911uxc_2_out: endpoint { + remote-endpoint = <&dphy5_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + isp_motor: motor0@40 { + compatible = "motor,ms42919"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + pi-max-frequency = <124999999>; + status = "okay"; + }; + + imgsensor00: imgsensor0@34 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x34>; + actuator-src = <&isp_motor>; + isp-src = <&i7_isp>; + status = "okay"; + }; + + imgsensor01: imgsensor0@36 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x36>; + isp-src = <&i7_isp_fake1>; + status = "okay"; + }; + + imgsensor02: imgsensor0@38 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x38>; + isp-src = <&i7_isp_fake2>; + status = "okay"; + }; + + imgsensor03: imgsensor0@3a { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3a>; + isp-src = <&i7_isp_fake3>; + status = "okay"; + }; +}; + +&i2c1{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c1>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50>; + vin-supply = <&vcc>; + }; +}; + +&i2c2{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50>; + vin-supply = <&vcc>; + }; +}; + +&i2c3{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c3>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50>; + vin-supply = <&vcc>; + }; +}; + + +&i2c4{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50>; + vin-supply = <&vcc>; + }; +}; + +&i2c5{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50>; + vin-supply = <&vcc>; + }; +}; + +&i2c6{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c6>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50>; + vin-supply = <&vcc>; + }; +}; + +&i2c7{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c7>; + m24c01@50 { + compatible = "24c01"; + reg = <0x50>; + vin-supply = <&vcc>; + }; +}; + +&i7_isp { + status = "okay"; +}; + +&armcb_config { + status = "okay"; +}; + +&armcb_ispmem { + status = "okay"; +}; + +&npu { + status = "okay"; +}; + +&sensorhub { + memory-region = <&sfh_vdev0buffer>, <&sfh_vdev0vring0>, + <&sfh_vdev0vring1>, <&sfh_ram>; + status = "okay"; +}; + +&macb0 { + status = "disabled"; + local-mac-address = [3a 0e 03 04 05 06]; + phy-handle = <&mac_phy0>; + phy-mode = "fixed"; + fixed-link { + speed = <1000>; + full-duplex; + }; + mac_phy0: phy@1 { + forced-link-speed = <1000>; + forced-link-duplex = <1>; + force-link = <1>; + }; +}; + +&macb1 { + status = "disabled"; + local-mac-address = [3a 0e 03 04 05 08]; + phy-handle = <&mac_phy1>; + phy-mode = "fixed"; + fixed-link { + speed = <1000>; + full-duplex; + }; + mac_phy1: phy@2 { + forced-link-speed = <1000>; + forced-link-duplex = <1>; + force-link = <1>; + }; +}; + +&its_pcie { + status = "disabled"; +}; + +&pcie_x8_rc { + plat-emu; + status = "disabled"; +}; + +&pcie_x4_rc { + plat-emu; + status = "disabled"; +}; + +&pcie_x2_rc { + plat-emu; + status = "disabled"; +}; + +&pcie_x1_1_rc { + plat-emu; + status = "disabled"; +}; + +&pcie_x1_0_rc { + plat-emu; + status = "disabled"; +}; + +&watchdog { + status = "disabled"; +}; + +&cix_dst { + status = "okay"; +}; + +&ap_adapter { + status = "okay"; +}; + +&mntndump { + status = "okay"; +}; + +&mbox_ap2pm { + status = "okay"; +}; + +&mbox_pm2ap { + status = "okay"; +}; + +&ap2pm_scmi_mem { + status = "okay"; +}; + +&pm2ap_scmi_mem { + status = "okay"; +}; + +&ap_tfa_scmi_mem { + status = "okay"; +}; + +&ap_to_pm_scmi { + status = "okay"; +}; + +&ap_to_tfa_scmi { + status = "okay"; +}; + +&thermal_zones { + cpu-m1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M1_TEMP_SENSOR_ID>; + + trips { + m1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B1_TEMP_SENSOR_ID>; + + trips { + b1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-m0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + + trips { + m0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B0_TEMP_SENSOR_ID>; + + trips { + b0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-csidma.dtsi b/arch/arm64/boot/dts/cix/sky1-evb-csidma.dtsi new file mode 100644 index 000000000000..a5d84195a925 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-csidma.dtsi @@ -0,0 +1,417 @@ + +&cix_csi_rcsu_0 { + status = "okay"; +}; + +&cix_csi_rcsu_1 { + status = "disabled"; +}; + +&cix_bridge_0 { + status = "okay"; + port { + cix_bridge_0_in: endpoint { + remote-endpoint = <&mipi_csi2_0_out>; + }; + }; +}; + +&cix_bridge_1 { + status = "disabled"; + port { + cix_bridge_1_in: endpoint { + remote-endpoint = <&mipi_csi2_1_out>; + }; + }; +}; + +&cix_bridge_2 { + status = "disabled"; + port { + cix_bridge_2_in: endpoint { + remote-endpoint = <&mipi_csi2_2_out>; + }; + }; +}; + +&cix_bridge_3 { + status = "disabled"; + port { + cix_bridge_3_in: endpoint { + remote-endpoint = <&mipi_csi2_3_out>; + }; + }; +}; + +&cix_mipi_csi_0 { + lanes = <4>; + status = "okay"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_0_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy1_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_0_in>; + }; + }; + }; +}; + +&cix_mipi_csi_1 { + lanes = <4>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_1_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy2_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_1_in>; + }; + }; + }; +}; + +&cix_mipi_csi_2 { + lanes = <4>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_2_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy4_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_2_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_2_in>; + }; + }; + }; +}; + +&cix_mipi_csi_3 { + lanes = <4>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_3_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy5_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_3_in>; + }; + }; + }; +}; + +&cix_dphy_0 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy0_in: endpoint@1 { + reg = <1>; + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_0_in>; + }; + }; + }; +}; + +&cix_dphy_1 { + status = "okay"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy1_in: endpoint@1 { + reg = <1>; + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_0_in>; + }; + }; + }; +}; + +&cix_dphy_2 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy2_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_0_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy2_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_1_in>; + }; + }; + }; + +}; + +&cix_dphy_3 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy3_in: endpoint@1 { + reg = <1>; + /*this not active*/ + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_2_in>; + }; + }; + }; +}; + +&cix_dphy_4 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy4_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_1_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy4_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_2_in>; + }; + }; + }; +}; + +&cix_dphy_5 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy5_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_2_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy5_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_3_in>; + }; + }; + }; +}; + +&cix_dphy_hw_0 { + status = "okay"; +}; + +&cix_dphy_hw_1 { + status = "disabled"; +}; + +&i2c0 { + lt7911uxc: lt7911uxc@43 { + compatible = "lontium,lt7911uxc"; + #sound-dai-cells = <0>; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x43>; + /*interrupt-parent = <&gpio0>;*/ + /*interrupts = ;*/ + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_lt7911_hw>; + pinctrl-1 = <&pinctrl_lt7911_hw>; + pwdn-gpios = <&fch_gpio0 15 GPIO_ACTIVE_HIGH>; + power-gpios = <&fch_gpio1 16 GPIO_ACTIVE_HIGH>; + power1-gpios = <&fch_gpio1 18 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio1 12 GPIO_ACTIVE_HIGH>; + status = "okay"; + port { + lt7911uxc_out: endpoint { + //remote-endpoint = <&dphy0_in>; + remote-endpoint = <&dphy1_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_0: virtual_lt7911uxc_0@0d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0d>; + status = "disabled"; + port { + virt_lt7911uxc_0_out: endpoint { + remote-endpoint = <&dphy2_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_1: virtual_lt7911uxc_1@1d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1d>; + status = "disabled"; + port { + virt_lt7911uxc_1_out: endpoint { + remote-endpoint = <&dphy4_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_2: virtual_lt7911uxc_2@2d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2d>; + status = "disabled"; + port { + virt_lt7911uxc_2_out: endpoint { + remote-endpoint = <&dphy5_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-display.dts b/arch/arm64/boot/dts/cix/sky1-evb-display.dts new file mode 100644 index 000000000000..863b08fbe342 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-display.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&dpu0 { + side_by_side_master = <0>; +}; + +&dpu1 { + side_by_side_master = <0>; +}; + +&dpu2 { + side_by_side_master = <0>; +}; + +&dpu3 { + side_by_side_master = <0>; +}; + +&dpu4 { + side_by_side_master = <0>; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-hda-alc256.dts b/arch/arm64/boot/dts/cix/sky1-evb-hda-alc256.dts new file mode 100644 index 000000000000..12c2eafdf363 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-hda-alc256.dts @@ -0,0 +1,50 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&sound { + /delete-property/ pdb0-gpios; + status = "okay"; +}; + +&ipb_hda { + status = "okay"; +}; + +&pa_alc1019 { + status = "disabled"; +}; + +&codec_alc5682 { + status = "disabled"; +}; + +&i2s_lp { + status = "disabled"; +}; + +&alc5682 { + status = "disabled"; +}; + +&dummy_codec { + status = "disabled"; +}; + +&i2s0 { + status = "disabled"; +}; + +&i2s2 { + status = "disabled"; +}; + +&i2s3 { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-iso.dts b/arch/arm64/boot/dts/cix/sky1-evb-iso.dts new file mode 100755 index 000000000000..4854a690dbcb --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-iso.dts @@ -0,0 +1,89 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +#include "sky1-evb.dts" +/ { + chosen { + status = "disabled"; + }; +}; + +&dp2_backlight { + status = "disabled"; +}; + +&panel_edp0 { + status = "disabled"; +}; + +&fch_gpio1 { + status = "disabled"; +}; + +&fch_gpio3 { + status = "disabled"; +}; + +&gpt_timer3 { + status = "disabled"; +}; + +&pwm0 { + status = "disabled"; +}; + +&pwm1 { + status = "disabled"; +}; + +&dp0 { + status = "disabled"; +}; + +&dp1 { + status = "disabled"; +}; + +&dp2 { + status = "disabled"; +}; + +&dp3 { + status = "disabled"; +}; + +&dp4 { + status = "disabled"; +}; + +&dpu0 { + status = "disabled"; +}; + +&dpu1 { + status = "disabled"; +}; + +&dpu2 { + status = "disabled"; +}; + +&dpu3 { + status = "disabled"; +}; + +&dpu4 { + status = "disabled"; +}; + +&smmu_mmhub{ + status = "disabled"; +}; + +&uart2 { + status = "disabled"; +}; \ No newline at end of file diff --git a/arch/arm64/boot/dts/cix/sky1-evb-isp.dts b/arch/arm64/boot/dts/cix/sky1-evb-isp.dts new file mode 100644 index 000000000000..04a6935bfbad --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-isp.dts @@ -0,0 +1,93 @@ +/dts-v1/; + +#include "sky1-evb.dts" +#include "sky1-evb-isp.dtsi" + +/*disable the csidma all node dts*/ +&cix_csi_rcsu_0 { + status = "disabled"; +}; + +&cix_csi_rcsu_1 { + status = "disabled"; +}; + +&cix_bridge_0 { + status = "disabled"; +}; + +&cix_bridge_1 { + status = "disabled"; +}; + +&cix_bridge_2 { + status = "disabled"; +}; + +&cix_bridge_3 { + status = "disabled"; +}; + +&cix_mipi_csi_0 { + status = "disabled"; +}; + +&cix_mipi_csi_1 { + status = "disabled"; +}; + +&cix_mipi_csi_2 { + status = "disabled"; +}; + +&cix_mipi_csi_3 { + status = "disabled"; +}; + +&cix_dphy_0 { + status = "disabled"; +}; + +&cix_dphy_1 { + status = "disabled"; +}; + +&cix_dphy_2 { + status = "disabled"; +}; + +&cix_dphy_3 { + status = "disabled"; +}; + +&cix_dphy_4 { + status = "disabled"; +}; + +&cix_dphy_5 { + status = "disabled"; +}; + +&cix_dphy_hw_0 { + status = "disabled"; +}; + +&cix_dphy_hw_1 { + status = "disabled"; +}; + +<7911uxc { + status = "disabled"; +}; + +&virtual_lt7911uxc_0{ + status = "disabled"; +}; + +&virtual_lt7911uxc_1 { + status = "disabled"; +}; + +&virtual_lt7911uxc_2 { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-isp.dtsi b/arch/arm64/boot/dts/cix/sky1-evb-isp.dtsi new file mode 100644 index 000000000000..6fc2dd678261 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-isp.dtsi @@ -0,0 +1,123 @@ +&i7_isp { + status = "okay"; +}; + +&armcb_config { + status = "okay"; +}; + +&armcb_ispmem { + status = "okay"; +}; + +&cix_vi_hw { + status = "okay"; +}; + +&cam_power_en_0 { + status = "okay"; +}; + +&cam_power_en_1 { + status = "okay"; +}; + +&cam_power_en_2 { + status = "okay"; +}; + +&cam_power_en_3 { + status = "okay"; +}; + +&i2c0 { + imgsensor00: imgsensor00@34 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x34>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam0_hw>; + pinctrl-1 = <&pinctrl_cam0_hw>; + power0-supply = <&cam_power_en_0>; + power1-supply = <&cam_power_en_1>; + reset-gpios = <&fch_gpio1 12 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 15 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK0>; + clock-names = "mclk"; + cix,camera-module-index = <0>; + actuator-src = <&isp_motor>; + isp-src = <&i7_isp>; + status = "okay"; + }; + + isp_motor: motor0@40 { + compatible = "motor,ms42919"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + pi-max-frequency = <124999999>; + status = "okay"; + }; +}; + +&i2c1 { + imgsensor02: imgsensor02@38 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x38>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam2_hw>; + pinctrl-1 = <&pinctrl_cam2_hw>; + power0-supply = <&cam_power_en_2>; + power1-supply = <&cam_power_en_3>; + reset-gpios = <&fch_gpio1 10 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 7 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK2>; + clock-names = "mclk"; + + cix,camera-module-index = <2>; + status = "okay"; + }; +}; + +&i2c3 { + imgsensor01: imgsensor01@36 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x36>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam1_hw>; + pinctrl-1 = <&pinctrl_cam1_hw>; + power0-supply = <&cam_power_en_0>; + power1-supply = <&cam_power_en_1>; + reset-gpios = <&fch_gpio1 17 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 19 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK1>; + clock-names = "mclk"; + cix,camera-module-index = <1>; + status = "okay"; + }; +}; + +&i2c4 { + imgsensor03: imgsensor03@3a { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3a>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam3_hw>; + pinctrl-1 = <&pinctrl_cam3_hw>; + power0-supply = <&cam_power_en_2>; + power1-supply = <&cam_power_en_3>; + reset-gpios = <&fch_gpio1 13 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 14 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK3>; + clock-names = "mclk"; + cix,camera-module-index = <3>; + status = "okay"; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-lt7911uxc-audio.dts b/arch/arm64/boot/dts/cix/sky1-evb-lt7911uxc-audio.dts new file mode 100644 index 000000000000..d00addcd81b0 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-lt7911uxc-audio.dts @@ -0,0 +1,54 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pa_alc1019 { + status = "disabled"; +}; + +&codec_alc5682 { + status = "disabled"; +}; + +&i2s_lp { + status = "disabled"; +}; + +&alc5682 { + status = "disabled"; +}; + +&dummy_codec { + status = "disabled"; +}; + +&i2s0 { + status = "disabled"; +}; + +&i2s2 { + status = "disabled"; +}; + +&dprx_lt7911uxc { + status = "okay"; + + cpu { + sound-dai = <&i2s3 1>; + }; +}; + +&i2s3 { + dmas = <&audss_dmac 7 0xff>; + dma-names = "rx"; + cdns,pin-rx-mask = /bits/ 8 <0x0f>; + cdns,pin-tx-mask = /bits/ 8 <0x00>; + status = "okay"; +}; + diff --git a/arch/arm64/boot/dts/cix/sky1-evb-npu-resmem.dts b/arch/arm64/boot/dts/cix/sky1-evb-npu-resmem.dts new file mode 100644 index 000000000000..0a835891fd94 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-npu-resmem.dts @@ -0,0 +1,34 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +/ { + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + aipu_reserve_0: memory@100000000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x1 0x00000000 0x1 0x00000000>; + asid = <0 1>; + }; + }; +}; + +&npu { + memory-region = <&aipu_reserve_0>; + /delete-property/ iommus; + status = "okay"; +}; + +&smmu_mmhub{ + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x1.dts b/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x1.dts new file mode 100644 index 000000000000..1fe8e6c22998 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x1.dts @@ -0,0 +1,32 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + num-lanes = <1>; + status = "okay"; +}; + +&pcie_x4_rc { + num-lanes = <1>; + status = "okay"; +}; + +&pcie_x2_rc { + num-lanes = <1>; + status = "okay"; +}; + +&pcie_x1_1_rc { + status = "disabled"; +}; + +&pcie_x1_0_rc { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x2.dts b/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x2.dts new file mode 100644 index 000000000000..c477bf222d85 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x2.dts @@ -0,0 +1,31 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + num-lanes = <2>; + status = "okay"; +}; + +&pcie_x4_rc { + num-lanes = <2>; + status = "okay"; +}; + +&pcie_x2_rc { + status = "disabled"; +}; + +&pcie_x1_1_rc { + status = "disabled"; +}; + +&pcie_x1_0_rc { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x4.dts b/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x4.dts new file mode 100644 index 000000000000..01795126a78d --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pcie_width_x4.dts @@ -0,0 +1,30 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + num-lanes = <4>; + status = "okay"; +}; + +&pcie_x4_rc { + status = "disabled"; +}; + +&pcie_x2_rc { + status = "disabled"; +}; + +&pcie_x1_1_rc { + status = "disabled"; +}; + +&pcie_x1_0_rc { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pciex10.dts b/arch/arm64/boot/dts/cix/sky1-evb-pciex10.dts new file mode 100644 index 000000000000..d1b1e7f0073f --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pciex10.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + status = "disabled"; +}; + +&pcie_x4_rc { + status = "okay"; +}; + +&pcie_x2_rc { + status = "disabled"; +}; + +&pcie_x1_1_rc { + status = "disabled"; +}; + +&pcie_x1_0_rc { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pciex11.dts b/arch/arm64/boot/dts/cix/sky1-evb-pciex11.dts new file mode 100644 index 000000000000..5e3269d8966a --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pciex11.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + status = "disabled"; +}; + +&pcie_x4_rc { + status = "okay"; +}; + +&pcie_x2_rc { + status = "disabled"; +}; + +&pcie_x1_1_rc { + status = "okay"; +}; + +&pcie_x1_0_rc { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pciex2.dts b/arch/arm64/boot/dts/cix/sky1-evb-pciex2.dts new file mode 100644 index 000000000000..0ed87d9e7d27 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pciex2.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + status = "disabled"; +}; + +&pcie_x4_rc { + status = "okay"; +}; + +&pcie_x2_rc { + status = "okay"; +}; + +&pcie_x1_1_rc { + status = "disabled"; +}; + +&pcie_x1_0_rc { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pciex4.dts b/arch/arm64/boot/dts/cix/sky1-evb-pciex4.dts new file mode 100644 index 000000000000..350af51435f8 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pciex4.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + status = "disabled"; +}; + +&pcie_x4_rc { + status = "okay"; +}; + +&pcie_x2_rc { + status = "disabled"; +}; + +&pcie_x1_1_rc { + status = "disabled"; +}; + +&pcie_x1_0_rc { + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-pciex8.dts b/arch/arm64/boot/dts/cix/sky1-evb-pciex8.dts new file mode 100644 index 000000000000..8e603ac0e4ad --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-pciex8.dts @@ -0,0 +1,29 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&pcie_x8_rc { + status = "okay"; +}; + +&pcie_x4_rc { + status = "okay"; +}; + +&pcie_x2_rc { + status = "disabled"; +}; + +&pcie_x1_1_rc { + status = "disabled"; +}; + +&pcie_x1_0_rc { + status = "disabled"; +}; \ No newline at end of file diff --git a/arch/arm64/boot/dts/cix/sky1-evb-sof-alc5682-alc1019.dts b/arch/arm64/boot/dts/cix/sky1-evb-sof-alc5682-alc1019.dts new file mode 100644 index 000000000000..5b86c6244a27 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-sof-alc5682-alc1019.dts @@ -0,0 +1,192 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +/ { + reserved-memory { + /delete-node/ dsp_vdev0vring0; + /delete-node/ dsp_vdev0vring1; + /delete-node/ dsp_vdev0buffer; + /delete-node/ dsp_reserved; + /delete-node/ dsp_reserved_heap; + /delete-node/ audio_alsa; + /delete-node/ audio_alsa_hda; + + dsp_reserved0: dsp_reserved0 { + reg = <0x0 0xce000000 0x0 0x1000000>; + no-map; + }; + + dsp_reserved1: dsp_reserved1 { + compatible = "shared-dma-pool"; + reg = <0x0 0xcf000000 0x0 0x1000000>; + no-map; + }; + }; + + alc5682-alc1019-sound { + compatible = "simple-audio-card"; + simple-audio-card,name = "alc5682-alc1019-audio"; + + #address-cells = <1>; + #size-cells = <0>; + + simple-audio-card,dai-link@0 { /* alc1019 pa */ + reg = <0>; + format = "i2s"; + bitclock-master = <&sndcpu0>; + frame-master = <&sndcpu0>; + + sndcpu0: cpu { + sound-dai = <&hifi5 1>; + }; + sndcodec0: codec { + pd-gpio,pa; + pdb0-gpios = <&fch_gpio3 5 GPIO_ACTIVE_HIGH>; + pdb1-gpios = <&fch_gpio3 6 GPIO_ACTIVE_HIGH>; + pdb2-gpios = <&fch_gpio3 7 GPIO_ACTIVE_HIGH>; + pdb3-gpios = <&fch_gpio3 8 GPIO_ACTIVE_HIGH>; + + sound-dai = <&dummy_codec 0>; + }; + }; + + simple-audio-card,dai-link@1 { /* alc5682 codec */ + reg = <1>; + format = "i2s"; + bitclock-master = <&sndcpu1>; + frame-master = <&sndcpu1>; + + sndcpu1: cpu { + sound-dai = <&hifi5 0>; + }; + sndcodec1: codec { + mclk-fs = <512>; + jack-det,hs; + + sound-dai = <&alc5682 0>; + }; + }; + }; +}; + +&sound { + status = "disabled"; +}; + +&codec_alc5682 { + status = "disabled"; +}; + +&i2s0 { + status = "disabled"; +}; + +&i2s_lp { + status = "disabled"; +}; + +&i2s2 { + status = "disabled"; +}; + +&pa_alc1019 { + status = "disabled"; +}; + +&i2s3 { + status = "disabled"; +}; + +&dptx0_audio { + status = "disabled"; +}; + +&i2s5 { + status = "disabled"; +}; + +&dptx1_audio { + status = "disabled"; +}; + +&i2s6 { + status = "disabled"; +}; + +&dptx2_audio { + status = "disabled"; +}; + +&i2s7 { + status = "disabled"; +}; + +&dptx3_audio { + status = "disabled"; +}; + +&i2s8 { + status = "disabled"; +}; + +&dptx4_audio { + status = "disabled"; +}; + +&i2s9 { + status = "disabled"; +}; + +&audss_dmac { + status = "disabled"; +}; + +&iomuxc { + pinctrl_i2s0_i2s3: pinctrl_i2s0_i2s3 { + sky1,pins = < + CIX_PAD_HDA_BITCLK_FUNC_I2S0_SCK (PULL_DOWN|ST|DS_LEVEL12) /* I2S0_SCK */ + CIX_PAD_HDA_RST_L_FUNC_I2S0_DATA_IN (PULL_DOWN|ST|DS_LEVEL12) /* I2S0_DATA_IN */ + CIX_PAD_HDA_SDIN0_FUNC_I2S0_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* I2S0_MCLK */ + CIX_PAD_HDA_SDOUT0_FUNC_I2S0_DATA_OUT (PULL_UP|ST|DS_LEVEL12) /* I2S0_DATA_OUT */ + CIX_PAD_HDA_SYNC_FUNC_I2S0_WS (PULL_UP|ST|DS_LEVEL12) /* I2S0_WS */ + + CIX_PAD_I2S2_MCLK_FUNC_I2S2_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_mclk */ + CIX_PAD_I2S2_RSCK_FUNC_I2S2_RSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_rsck */ + CIX_PAD_I2S2_RWS_FUNC_I2S2_RWS (PULL_UP|ST|DS_LEVEL12) /* i2s2_rws */ + CIX_PAD_I2S2_TSCK_FUNC_I2S2_TSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_tsck */ + CIX_PAD_I2S2_TWS_FUNC_I2S2_TWS (PULL_UP|ST|DS_LEVEL12) /* i2s2_tws */ + CIX_PAD_I2S2_DATA_IN0_FUNC_I2S2_DATA_IN0 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_in0 */ + CIX_PAD_I2S2_DATA_IN1_FUNC_I2S2_DATA_IN1 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_in1 */ + CIX_PAD_I2S2_DATA_OUT0_FUNC_I2S2_DATA_OUT0 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out0 */ + CIX_PAD_I2S2_DATA_OUT1_FUNC_I2S2_DATA_OUT1 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out1 */ + CIX_PAD_I2S2_DATA_OUT2_FUNC_I2S2_DATA_OUT2 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out2 */ + CIX_PAD_I2S2_DATA_OUT3_FUNC_I2S2_DATA_OUT3 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out3 */ + >; + }; +}; + +&hifi5 { + #sound-dai-cells = <1>; + compatible = "cix,sky1-dsp"; + + /delete-property/interrupts; + /delete-property/firmware-name; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_i2s0_i2s3>; + + mbox-names = "txdb", "rxdb"; + mboxes = <&mbox_ap2dsp 8>, /* index=8: db base channel */ + <&mbox_dsp2ap 8>; + + memory-region = <&dsp_reserved1>, <&dsp_reserved0>; + + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb-usb4_5.dts b/arch/arm64/boot/dts/cix/sky1-evb-usb4_5.dts new file mode 100644 index 000000000000..06dd0ecda6fe --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb-usb4_5.dts @@ -0,0 +1,21 @@ +/* + * Copyright (c) 2024, Cix Technology Group Co., Ltd. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-evb.dts" + +&usbss_4 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; +}; + +&usbss_5 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-evb.dts b/arch/arm64/boot/dts/cix/sky1-evb.dts new file mode 100755 index 000000000000..484c8f1ed7bd --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-evb.dts @@ -0,0 +1,2532 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1.dtsi" +#include "sky1-evb-csidma.dtsi" +/delete-node/ ®_definition; +/ { + model = "CIX sky1 EVB board"; + compatible = "cix,sky1"; + + chosen { + stdout-path = &uart2; + }; + + dummy_codec: dummy_codec { + #sound-dai-cells = <1>; + compatible = "linux,dummy"; + status = "okay"; + }; + + sound: sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "okay"; + + /* for pa alc1019 */ + pdb0-gpios = <&fch_gpio3 5 GPIO_ACTIVE_HIGH>; + pdb1-gpios = <&fch_gpio3 6 GPIO_ACTIVE_HIGH>; + pdb2-gpios = <&fch_gpio3 7 GPIO_ACTIVE_HIGH>; + pdb3-gpios = <&fch_gpio3 8 GPIO_ACTIVE_HIGH>; + + cru-ctrl = <&audss_cru>; + + codec_alc5682: codec_alc5682 { + status = "okay"; + + clocks = <&audss_clk CLK_MCLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "mclk", "audio_clk0", "audio_clk2"; + mclk-idx = /bits/ 8 <0>; + + format = "i2s"; + mclk-fs = <512>; + jack-det,hp; + + cpu { + sound-dai = <&i2s0>; + }; + + codec { + sound-dai = <&alc5682 0>; + }; + }; + + pa_alc1019: pa_alc1019 { + status = "okay"; + + format = "i2s"; + cpu { + sound-dai = <&i2s3 0>; + }; + }; + + bt_audio { + status = "disabled"; + + format = "dsp_a"; + dai-tdm-slot-tx-mask = <1>; + dai-tdm-slot-rx-mask = <1>; + dai-tdm-slot-num = <1>; + dai-tdm-slot-width = <16>; + + cpu { + sound-dai = <&i2s1>; + }; + }; + + i2s_lp: i2s_lp { + status = "okay"; + + format = "i2s"; + + frame-master = <&dummy_codec_mst>; + bitclock-master = <&dummy_codec_mst>; + + cpu { + sound-dai = <&i2s2>; + }; + + dummy_codec_mst: codec { + sound-dai = <&dummy_codec 0>; + }; + + }; + + dprx_lt7911uxc: dprx_lt7911uxc { + status = "disabled"; + + format = "i2s"; + jack-det,dpin; + + frame-master = <<7911uxc_codec>; + bitclock-master = <<7911uxc_codec>; + + cpu { + sound-dai = <&i2s4 1>; + }; + + lt7911uxc_codec: codec { + sound-dai = <<7911uxc>; + }; + }; + + dptx0_audio: dptx0_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s5 0>; + }; + + codec { + sound-dai = <&dp0>; + }; + }; + + dptx1_audio: dptx1_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s6 0>; + }; + + codec { + sound-dai = <&dp1>; + }; + }; + + dptx2_audio: dptx2_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s7 0>; + }; + + codec { + sound-dai = <&dp2>; + }; + }; + + dptx3_audio: dptx3_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s8 0>; + }; + + codec { + sound-dai = <&dp3>; + }; + }; + + dptx4_audio: dptx4_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s9 0>; + }; + + codec { + sound-dai = <&dp4>; + }; + }; + }; + + dp2_backlight: dp2_backlight { + compatible = "pwm-backlight"; + enable-gpios = <&fch_gpio3 15 GPIO_ACTIVE_HIGH>; + pwms = <&pwm0 0 100000>; + status = "okay"; + + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + + }; + + panel_edp0: panel_edp0 { + status = "okay"; + compatible = "cix-edp-panel"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_edp0>; + backlight = <&dp2_backlight>; + prepare-delay-ms = <120>; + enable-delay-ms = <120>; + unprepare-delay-ms = <500>; + disable-delay-ms = <120>; + width-mm = <129>; + height-mm = <171>; + enable-gpios = <&fch_gpio3 16 GPIO_ACTIVE_HIGH>; + }; + + wireless_bluetooth: wireless_bluetooth { + compatible = "bluetooth-platdata"; + BT,reset-gpios = <&ec_gpio 97 GPIO_ACTIVE_HIGH>; + }; + + vdd_3v3_pcie: regulator-vdd-3v3-pcie { + compatible = "regulator-fixed"; + regulator-name = "VDD_3V3_PCIE"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_vbat_gpio>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&s5_gpio0 12 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us=<15000>; + }; + + wlan_poweren: wlan-poweren { + compatible = "regulator-fixed"; + regulator-name = "WLAN_POWEREN_PCIE"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&ec_gpio 96 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us=<15000>; + }; + + rfkill_wwan: rfkill_wwan { + compatible = "wwan-rfkill"; + status = "disabled"; + poweren-gpios = <&ec_gpio 103 GPIO_ACTIVE_HIGH>; + vbat-gpios = <&ec_gpio 98 GPIO_ACTIVE_HIGH>; + reset-gpios = <&ec_gpio 74 GPIO_ACTIVE_HIGH>; + }; + + cam_power_en_0: cam-power-0-3v3 { + compatible = "regulator-fixed"; + regulator-name = "cam_power_en_0"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam_power_0>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&fch_gpio1 16 GPIO_ACTIVE_HIGH>; + enable-active-high; + status = "disabled"; + }; + + cam_power_en_1: cam-power-1-3v3 { + compatible = "regulator-fixed"; + regulator-name = "cam_power_en_1"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam_power_1>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&fch_gpio1 18 GPIO_ACTIVE_HIGH>; + enable-active-high; + status = "disabled"; + }; + + cam_power_en_2: cam-power-2-3v3 { + compatible = "regulator-fixed"; + regulator-name = "cam_power_en_2"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam_power_2>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&fch_gpio1 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + status = "disabled"; + }; + + cam_power_en_3: cam-power-3-3v3 { + compatible = "regulator-fixed"; + regulator-name = "cam_power_en_3"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam_power_3>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&fch_gpio1 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + status = "disabled"; + }; +}; + +&fch_gpio0 { + status = "okay"; +}; + +&fch_gpio1 { + status = "okay"; +}; + +&fch_gpio3 { + gpio-io-mask = <0x00018000>; /* pwm/edp pin output */ + status = "okay"; +}; + +&s5_gpio0 { + status = "okay"; +}; + + +&hwclock { + status = "okay"; +}; + +&iomuxc_s5 { + status = "okay"; + + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_s5>; + pinctrl_hog_s5: pinctrl_hog_s5 { + sky1,pins = < + CIX_PAD_GPIO014_FUNC_GPIO014 (PULL_UP|DS_LEVEL4) /* GPIO14 hp det */ + CIX_PAD_GPIO040_FUNC_GPIO040 (PULL_UP|DS_LEVEL4) /* GPIO40 */ + >; + }; + + wifi_vbat_gpio: wifi_vbat_gpio { + sky1,pins = < + CIX_PAD_GPIO013_FUNC_GPIO013 (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_sfi_i2c0: pinctrl_sfi_i2c0_grp { + sky1,pins = < + CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I2C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I2C0_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_sfi_i2c1: pinctrl_sfi_i2c1_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I2C1_SCL (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I2C1_SDA (PULL_UP|ST|DS_LEVEL7) + >; + }; + pinctrl_sfi_i3c0: pinctrl_sfi_i3c0_grp { + sky1,pins = < + CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I3C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I3C0_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO023_FUNC_SFI_I3C0_PUR_EN_L (PULL_UP|ST|DS_LEVEL7) + >; + }; + pinctrl_sfi_i3c1: pinctrl_sfi_i3c1_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I3C1_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I3C1_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO024_FUNC_SFI_I3C1_PUR_EN_L (PULL_UP|ST|DS_LEVEL7) + >; + }; + pinctrl_sfi_spi: pinctrl_sfi_spi_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_SPI_CS0 (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_SPI_CS1 (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO0_FUNC_SFI_SPI_SCK (ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO1_FUNC_SFI_SPI_MOSI (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO2_FUNC_SFI_SPI_MISO (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_spi0: pinctrl_fch_spi0_grp { + sky1,pins = < + CIX_PAD_SPI1_MISO_FUNC_SPI1_MISO (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CS0_FUNC_SPI1_CS0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CS1_FUNC_SPI1_CS1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_MOSI_FUNC_SPI1_MOSI (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CLK_FUNC_SPI1_CLK (ST|DS_LEVEL12) + >; + }; + pinctrl_fch_xspi: pinctrl_fch_xspi_grp { + sky1,pins = < + CIX_PAD_SE_QSPI_CLK_FUNC_QSPI_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_CS_L_FUNC_QSPI_CS_L (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA0_FUNC_QSPI_DATA0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA1_FUNC_QSPI_DATA1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA2_FUNC_QSPI_DATA2 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA3_FUNC_QSPI_DATA3 (PULL_UP|ST|DS_LEVEL12) + >; + }; + pinctrl_usb0: pinctrl_usb0_oc_grp { + sky1,pins = < + CIX_PAD_GPIO036_FUNC_GPIO036 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb1: pinctrl_usb1_oc_grp { + sky1,pins = < + CIX_PAD_GPIO037_FUNC_GPIO037 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb2: pinctrl_usb2_oc_grp { + sky1,pins = < + CIX_PAD_GPIO038_FUNC_GPIO038 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb3: pinctrl_usb3_oc_grp { + sky1,pins = < + CIX_PAD_GPIO039_FUNC_GPIO039 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb4: pinctrl_usb4_grp { + sky1,pins = < + CIX_PAD_GPIO034_FUNC_GPIO034 (PULL_UP|DS_LEVEL4) + CIX_PAD_GPIO041_FUNC_USB_DRIVE_VBUS4 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_usb5: pinctrl_usb5_grp { + sky1,pins = < + CIX_PAD_GPIO035_FUNC_GPIO035 (PULL_UP|DS_LEVEL4) + CIX_PAD_GPIO042_FUNC_USB_DRIVE_VBUS5 (PULL_DOWN|DS_LEVEL4) + >; + }; + pinctrl_usb6: pinctrl_usb6_oc_grp { + sky1,pins = < + CIX_PAD_GPIO030_FUNC_GPIO030 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb7: pinctrl_usb7_oc_grp { + sky1,pins = < + CIX_PAD_GPIO031_FUNC_GPIO031 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb8: pinctrl_usb8_oc_grp { + sky1,pins = < + CIX_PAD_GPIO032_FUNC_GPIO032 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb9: pinctrl_usb9_oc_grp { + sky1,pins = < + CIX_PAD_GPIO033_FUNC_GPIO033 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x8_rc: pinctrl_pcie_x8_rc { + sky1,pins = < + CIX_PAD_GPIO002_FUNC_GPIO002 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x4_rc: pinctrl_pcie_x4_rc { + sky1,pins = < + CIX_PAD_GPIO004_FUNC_GPIO004 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x2_rc: pinctrl_pcie_x2_rc { + sky1,pins = < + CIX_PAD_GPIO003_FUNC_GPIO003 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x1_1_rc: pinctrl_pcie_x1_1_rc {/*x1_1*/ + sky1,pins = < + CIX_PAD_GPIO006_FUNC_GPIO006 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x1_0_rc: pinctrl_pcie_x1_0_rc {/*x1_0*/ + sky1,pins = < + CIX_PAD_GPIO005_FUNC_GPIO005 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_ra8900ce_irq: pinctrl_ra8900ce_irq { + sky1,pins = < + CIX_PAD_GPIO011_FUNC_GPIO011 (PULL_UP|DS_LEVEL4) /* GPIO011 - S5_gpio0 10 */ + >; + }; + + pinctrl_hiddev_68_irq: pinctrl_hiddev_68_irq { + sky1,pins = < + CIX_PAD_GPIO010_FUNC_GPIO010 (PULL_UP|DS_LEVEL4) /* GPIO010 - S5_gpio0 9 */ + >; + }; + + pinctrl_hiddev_15_irq: pinctrl_hiddev_15_irq { + sky1,pins = < + CIX_PAD_GPIO010_FUNC_GPIO010 (PULL_UP|DS_LEVEL4) /* GPIO010 - S5_gpio0 9 */ + >; + }; +}; + +&iomuxc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: pinctrl_hog { + sky1,pins = < + CIX_PAD_GPIO144_FUNC_GPIO144 (PULL_DOWN|DS_LEVEL4) /* GPIO144 pdb0 */ + CIX_PAD_GPIO145_FUNC_GPIO145 (PULL_DOWN|DS_LEVEL4) /* GPIO145 pdb1 */ + CIX_PAD_GPIO146_FUNC_GPIO146 (PULL_DOWN|DS_LEVEL4) /* GPIO146 pdb2 */ + CIX_PAD_GPIO147_FUNC_GPIO147 (PULL_DOWN|DS_LEVEL4) /* GPIO147 pdb3 */ + >; + }; + + pinctrl_fch_pwm0: pinctrl_fch_pwm0 { + sky1,pins = < + CIX_PAD_DP2_VARY_BL_FUNC_DP2_VARY_BL (DS_LEVEL7) + >; + }; + + pinctrl_fch_pwm1: pinctrl_fch_pwm1 { + sky1,pins = < + CIX_PAD_UART0_TXD_FUNC_PWM0 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_gmac0: pinctrl_gmac0 { + sky1,pins = + /* rfclk_25M */ + , + /* txc_trl */ + , + /* txd0 */ + , + /* txd1 */ + , + /* txd2 */ + , + /* txd3 */ + , + /* tx_clk */ + , + /* rx_ctl */ + , + + /* rxd0 */ + , + /* rxd1 */ + , + /* rxd2 */ + , + /* rxd3 */ + , + /* rx_clk */ + , + /* mdc */ + , + /* mdio */ + ; + }; + +pinctrl_gmac1: pinctrl_gmac1 { + sky1,pins = + /* rfclk_25M */ + , + /* txc_trl */ + , + /* txd0 */ + , + /* txd1 */ + , + /* txd2 */ + , + /* txd3 */ + , + /* tx_clk */ + , + /* rx_ctl */ + , + /* rxd0 */ + , + /* rxd1 */ + , + /* rxd2 */ + , + /* rxd3 */ + , + /* rx_clk */ + , + /* mdc */ + , + /* mdio */ + ; + }; + + pinctrl_fch_fan0: pinctrl_fch_fan0 { + sky1,pins = < + CIX_PAD_UART1_TXD_FUNC_FAN_OUT0 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_fan1: pinctrl_fch_fan1 { + sky1,pins = < + CIX_PAD_UART1_CTS_FUNC_FAN_OUT1 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_fan2: pinctrl_fch_fan2 { + sky1,pins = < + CIX_PAD_UART0_CTS_FUNC_FAN_OUT2 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c0: pinctrl_fch_i2c0 { + sky1,pins = < + CIX_PAD_I2C0_CLK_FUNC_I2C0_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C0_SDA_FUNC_I2C0_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c1: pinctrl_fch_i2c1 { + sky1,pins = < + CIX_PAD_I2C1_CLK_FUNC_I2C1_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C1_SDA_FUNC_I2C1_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c2: pinctrl_fch_i2c2 { + sky1,pins = < + CIX_PAD_I2C2_SCL_FUNC_I2C2_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C2_SDA_FUNC_I2C2_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i2c3: pinctrl_fch_i2c3 { + sky1,pins = < + CIX_PAD_I2C3_CLK_FUNC_I2C3_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C3_SDA_FUNC_I2C3_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i2c4: pinctrl_fch_i2c4 { + sky1,pins = < + CIX_PAD_I2C4_CLK_FUNC_I2C4_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C4_SDA_FUNC_I2C4_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c5: pinctrl_fch_i2c5 { + sky1,pins = < + CIX_PAD_I2C5_SCL_FUNC_I2C5_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C5_SDA_FUNC_I2C5_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c6: pinctrl_fch_i2c6 { + sky1,pins = < + CIX_PAD_I2C6_SCL_FUNC_I2C6_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C6_SDA_FUNC_I2C6_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c7: pinctrl_fch_i2c7 { + sky1,pins = < + CIX_PAD_I2C7_SCL_FUNC_I2C7_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C7_SDA_FUNC_I2C7_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_spi1: pinctrl_fch_spi1_grp { + sky1,pins = < + CIX_PAD_GPIO138_FUNC_SPI2_MISO (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO139_FUNC_SPI2_CS0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO140_FUNC_SPI2_CS1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO141_FUNC_SPI2_MOSI (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO142_FUNC_SPI2_CLK (ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i3c0: pinctrl_fch_i3c0 { + sky1,pins = < + CIX_PAD_I2C2_SCL_FUNC_I3C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C2_SDA_FUNC_I3C0_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO057_FUNC_I3C0_PUR_EN_L (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i3c1: pinctrl_fch_i3c1 { + sky1,pins = < + CIX_PAD_I2C3_CLK_FUNC_I3C1_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C3_SDA_FUNC_I3C1_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO060_FUNC_I3C1_PUR_EN_L (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_uart0: pinctrl_fch_uart0 { + sky1,pins = < + CIX_PAD_UART0_TXD_FUNC_UART0_TXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_RXD_FUNC_UART0_RXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_CTS_FUNC_UART0_CTS (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_RTS_FUNC_UART0_RTS (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart1: pinctrl_fch_uart1 { + sky1,pins = < + CIX_PAD_UART1_TXD_FUNC_UART1_TXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART1_RXD_FUNC_UART1_RXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART1_CTS_FUNC_UART1_CTS (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART1_RTS_FUNC_UART1_RTS (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart2: pinctrl_fch_uart2 { + sky1,pins = < + CIX_PAD_UART2_TXD_FUNC_UART2_TXD (PULL_UP|DS_LEVEL7) + CIX_PAD_UART2_RXD_FUNC_UART2_RXD (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_hda: pinctrl_hda_grp { + sky1,pins = < + CIX_PAD_HDA_BITCLK_FUNC_HDA_BITCLK (PULL_DOWN|ST|DS_LEVEL12) /* hda bitclk */ + CIX_PAD_HDA_RST_L_FUNC_HDA_RST_L (PULL_DOWN|ST|DS_LEVEL12) /* hda rst */ + CIX_PAD_HDA_SDIN0_FUNC_HDA_SDIN0 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdin0 */ + CIX_PAD_HDA_SDOUT0_FUNC_HDA_SDOUT0 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdout0 */ + CIX_PAD_HDA_SYNC_FUNC_HDA_SYNC (PULL_DOWN|ST|DS_LEVEL12) /* hda sync */ + CIX_PAD_HDA_SDIN1_FUNC_HDA_SDIN1 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdin1 */ + CIX_PAD_HDA_SDOUT1_FUNC_HDA_SDOUT1 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdout1 */ + >; + }; + + pinctrl_substrate_i2s0: pinctrl_substrate_i2s0 { + sky1,pins = < + /* I2S0_SCK */ + CIX_PAD_HDA_BITCLK_FUNC_I2S0_SCK (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_DATA_IN */ + CIX_PAD_HDA_RST_L_FUNC_I2S0_DATA_IN (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_MCLK */ + CIX_PAD_HDA_SDIN0_FUNC_I2S0_MCLK (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_DATA_OUT */ + + CIX_PAD_HDA_SDOUT0_FUNC_I2S0_DATA_OUT (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_WS */ + CIX_PAD_HDA_SYNC_FUNC_I2S0_WS (PULL_DOWN|ST|DS_LEVEL12) + >; + }; + + pinctrl_substrate_i2s1: pinctrl_substrate_i2s1 { + sky1,pins = < + CIX_PAD_I2S1_MCLK_FUNC_I2S1_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_mclk */ + CIX_PAD_I2S1_SCK_FUNC_I2S1_SCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_sck */ + CIX_PAD_I2S1_WS_FUNC_I2S1_WS (PULL_UP|ST|DS_LEVEL12) /* i2s1_ws */ + CIX_PAD_I2S1_DATA_IN_FUNC_I2S1_DATA_IN (PULL_UP|ST|DS_LEVEL12) /* i2s1_data_in */ + CIX_PAD_I2S1_DATA_OUT_FUNC_I2S1_DATA_OUT (PULL_UP|ST|DS_LEVEL12) /* i2s1_data_out */ + >; + }; + + pinctrl_substrate_i2s2: pinctrl_substrate_i2s2 { + sky1,pins = < + CIX_PAD_I2S2_MCLK_FUNC_I2S2_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_mclk */ + CIX_PAD_I2S2_RSCK_FUNC_I2S2_RSCK (PULL_UP|ST|DS_LEVEL12) /* i2s2_rsck */ + CIX_PAD_I2S2_RWS_FUNC_I2S2_RWS (PULL_UP|ST|DS_LEVEL12) /* i2s2_rws */ + CIX_PAD_I2S2_TSCK_FUNC_I2S2_TSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_tsck */ + CIX_PAD_I2S2_TWS_FUNC_I2S2_TWS (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_tws */ + CIX_PAD_I2S2_DATA_IN0_FUNC_I2S2_DATA_IN0 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_in0 */ + CIX_PAD_I2S2_DATA_IN1_FUNC_I2S2_DATA_IN1 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_in1 */ + CIX_PAD_I2S2_DATA_OUT0_FUNC_I2S2_DATA_OUT0 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_out0 */ + CIX_PAD_I2S2_DATA_OUT1_FUNC_I2S2_DATA_OUT1 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_out1 */ + CIX_PAD_I2S2_DATA_OUT2_FUNC_I2S2_DATA_OUT2 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_out2 */ + CIX_PAD_I2S2_DATA_OUT3_FUNC_I2S2_DATA_OUT3 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_out3 */ + >; + }; + + pinctrl_substrate_i2s3: pinctrl_substrate_i2s3 { + sky1,pins = < + CIX_PAD_I2S3_MCLK_FUNC_I2S3_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_mclk */ + CIX_PAD_I2S3_RSCK_FUNC_I2S3_RSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_rsck */ + CIX_PAD_I2S3_RWS_FUNC_I2S3_RWS (PULL_UP|ST|DS_LEVEL12) /* i2s3_rws */ + CIX_PAD_I2S3_TSCK_FUNC_I2S3_TSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_tsck */ + CIX_PAD_I2S3_TWS_FUNC_I2S3_TWS (PULL_UP|ST|DS_LEVEL12) /* i2s3_tws */ + CIX_PAD_I2S3_DATA_IN0_FUNC_I2S3_DATA_IN0 (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_data_in0 */ + CIX_PAD_I2S3_DATA_IN1_FUNC_I2S3_DATA_IN1 (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_data_in1 */ + CIX_PAD_I2S3_DATA_OUT0_FUNC_I2S3_DATA_OUT0 (PULL_UP|ST|DS_LEVEL12) /* i2s3_data_out0 */ + CIX_PAD_I2S3_DATA_OUT1_FUNC_I2S3_DATA_OUT1 (PULL_UP|ST|DS_LEVEL12) /* i2s3_data_out1 */ + >; + }; + + pinctrl_substrate_i2s4_lb: pinctrl_substrate_i2s4_lb { + sky1,pins = < + CIX_PAD_GPIO090_FUNC_I2S4_MCLK_LB (ST|DS_LEVEL12) /* i2s4_mclk_lb */ + CIX_PAD_GPIO091_FUNC_I2S4_SCK_LB (ST|DS_LEVEL12) /* i2s4_sck_lb */ + CIX_PAD_GPIO092_FUNC_I2S4_WS_LB (ST|DS_LEVEL12) /* i2s4_ws_lb */ + /*CIX_PAD_GPIO093_FUNC_I2S4_DATA_IN_LB (ST|DS_LEVEL12)*/ /* i2s4_data_in_lb */ + CIX_PAD_GPIO094_FUNC_I2S4_DATA_OUT_LB (ST|DS_LEVEL12) /* i2s4_data_out_lb */ + >; + }; + + pinctrl_alc5682_irq: pinctrl_alc5682_irq { + sky1,pins = < + /* GPIO149 */ + CIX_PAD_GPIO149_FUNC_GPIO149 (ST|DS_LEVEL12) + >; + }; + + pinctrl_edp0: pinctrl_edp0 { + sky1,pins = < + CIX_PAD_DP2_DIGON_FUNC_DP2_DIGON (PULL_DOWN|DS_LEVEL4) /* DP2_DIGON */ + CIX_PAD_DP2_BLON_FUNC_DP2_BLON (PULL_DOWN|DS_LEVEL4) /* DP2_BLON */ + >; + }; + + pinctrl_cam0_hw: pinctrl_cam0_hw { + sky1,pins = < + CIX_PAD_CSI0_MCLK0_FUNC_CSI0_MCLK0 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_IN1_FUNC_GPIO087 (ST|DS_LEVEL12) + CIX_PAD_GPIO090_FUNC_GPIO090 (ST|DS_LEVEL12) + >; + }; + + pinctrl_cam1_hw: pinctrl_cam1_hw { + sky1,pins = < + CIX_PAD_CSI0_MCLK1_FUNC_CSI0_MCLK1 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_GPIO092_FUNC_GPIO092 (ST|DS_LEVEL12) + CIX_PAD_GPIO094_FUNC_GPIO094 (ST|DS_LEVEL12) + >; + }; + + pinctrl_cam2_hw: pinctrl_cam2_hw { + sky1,pins = < + CIX_PAD_CSI1_MCLK0_FUNC_CSI1_MCLK0 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_TWS_FUNC_GPIO085 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_RSCK_FUNC_GPIO082 (PULL_DOWN|ST|DS_LEVEL12) + >; + }; + + pinctrl_cam3_hw: pinctrl_cam3_hw { + sky1,pins = < + CIX_PAD_CSI1_MCLK1_FUNC_CSI1_MCLK1 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_OUT0_FUNC_GPIO088 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_OUT1_FUNC_GPIO089 (PULL_DOWN|ST|DS_LEVEL12) + >; + }; + + pinctrl_lt7911_hw: pinctrl_lt7911_hw { + sky1,pins = < + CIX_PAD_I2S3_DATA_IN1_FUNC_GPIO087 (DS_LEVEL12) //cam0 reset + CIX_PAD_GPIO090_FUNC_GPIO090 (DS_LEVEL12) //cam0 pwdn + CIX_PAD_GPIO091_FUNC_GPIO091 (DS_LEVEL12) //cam0 pwen + CIX_PAD_GPIO093_FUNC_GPIO093 (ST|DS_LEVEL12) //cam1_pwen + >; + }; + + pinctrl_cam_power_0: pinctrl_cam_power_0 { + sky1,pins = < + CIX_PAD_GPIO091_FUNC_GPIO091 (DS_LEVEL12) + >; + }; + pinctrl_cam_power_1: pinctrl_cam_power_1 { + sky1,pins = < + CIX_PAD_GPIO093_FUNC_GPIO093 (ST|DS_LEVEL12) + >; + }; + pinctrl_cam_power_2: pinctrl_cam_power_2 { + sky1,pins = < + CIX_PAD_I2S3_RWS_FUNC_GPIO083 (ST|DS_LEVEL12) + >; + }; + pinctrl_cam_power_3: pinctrl_cam_power_3 { + sky1,pins = < + CIX_PAD_I2S3_DATA_IN0_FUNC_GPIO086 (PULL_DOWN|ST|DS_LEVEL12) + >; + }; +}; + +&pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm0>; + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm1>; + status = "okay"; +}; + +&hifi5 { + status = "okay"; +}; + +&mbox_dsp2ap { + status = "okay"; +}; + +&mbox_ap2dsp { + status = "okay"; +}; + +&audss_cru { + status = "okay"; +}; + +&audss_clk { + status = "okay"; +}; + +&audss_rst { + status = "okay"; +}; + +&audss_dmac { + memory-region = <&audio_alsa>; + status = "okay"; +}; + +&i2s0 { + /* i2s_sc0 for codec */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s0>; + dmas = <&audss_dmac 0 0xff>, <&audss_dmac 1 0xff>; + dma-names = "tx", "rx"; + status = "okay"; +}; + +&i2s1 { + /* i2s_sc1 for 5G/BT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s1>; + dmas = <&audss_dmac 2 0xff>, <&audss_dmac 3 0xff>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s2 { + /* i2s_sc2 for loopback */ + dmas = <&audss_dmac 4 0xff>, <&audss_dmac 5 0xff>; + dma-names = "tx", "rx"; + status = "okay"; +}; + +&i2s3 { + /* i2s_mc2a for speaker */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s2>; + dmas = <&audss_dmac 6 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x3c>; /* 0x3c, pin2-pin5 works as transmitter */ + status = "okay"; +}; + +&i2s4 { + /* i2s_mc2b for dp-in */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s3>; + dmas = <&audss_dmac 9 0xff>; + dma-names = "rx"; + cdns,pin-rx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as receiver */ + cdns,pin-tx-mask = /bits/ 8 <0x00>; + status = "disabled"; +}; + +&i2s5 { + /* i2s_mc5a for dp-out */ + dmas = <&audss_dmac 10 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s6 { + /* i2s_mc5b for dp-out */ + dmas = <&audss_dmac 12 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s7 { + /* i2s_mc5c for dp-out */ + dmas = <&audss_dmac 14 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s8 { + /* i2s_mc5d for dp-out */ + dmas = <&audss_dmac 16 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s9 { + /* i2s_mc5e for dp-out */ + dmas = <&audss_dmac 18 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&ipb_hda { + cix,model = "CIX SKY1 EVB HDA"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hda>; + pdb-gpios = <&fch_gpio3 5 GPIO_ACTIVE_HIGH>; + depop-mute-gpios = <&ec_gpio 22 GPIO_ACTIVE_HIGH>; + memory-region = <&audio_alsa_hda>; + status = "disabled"; +}; + +&sensorhub { + memory-region = <&sfh_vdev0buffer>, <&sfh_vdev0vring0>, + <&sfh_vdev0vring1>, <&sfh_ram>; + cix,auto-boot; + status = "okay"; +}; + +&sfh_scp { + memory-region = <&sfh_sharebuffer>; + status = "okay"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart2>; + clock-names = "uartclk", "apb_pclk"; + status = "okay"; +}; + +&dp0 { + status = "okay"; + + ports { + port@0 { + reg = <0>; + dp0_0_in: endpoint { + remote-endpoint = <&dpu0_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp0_1_in: endpoint { + remote-endpoint = <&dpu0_pipe1_out>; + }; + }; + }; +}; + +&dp1 { + status = "okay"; + + ports { + port@0 { + reg = <0>; + dp1_0_in: endpoint { + remote-endpoint = <&dpu1_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp1_1_in: endpoint { + remote-endpoint = <&dpu1_pipe1_out>; + }; + }; + }; +}; + +&dp2 { + status = "okay"; + edp-panel = <&panel_edp0>; + cix,dp-psr-default-on = <1>; + + ports { + port@0 { + reg = <0>; + dp2_0_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp2_1_in: endpoint { + remote-endpoint = <&dpu2_pipe1_out>; + }; + }; + }; +}; + +&dp3 { + status = "okay"; + + ports { + port@0 { + reg = <0>; + dp3_0_in: endpoint { + remote-endpoint = <&dpu3_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp3_1_in: endpoint { + remote-endpoint = <&dpu3_pipe1_out>; + }; + }; + }; +}; + +&dp4 { + status = "okay"; + + ports { + port@0 { + reg = <0>; + dp4_0_in: endpoint { + remote-endpoint = <&dpu4_pipe0_out>; + }; + }; + port@1 { + reg = <1>; + dp4_1_in: endpoint { + remote-endpoint = <&dpu4_pipe1_out>; + }; + }; + }; +}; + +&dpu0 { + status = "okay"; + + aclk_freq_fixed = <800000000>; + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + port { + dpu0_pipe0_out: endpoint { + remote-endpoint = <&dp0_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu0_pipe1_out: endpoint { + remote-endpoint = <&dp0_1_in>; + }; + }; + }; +}; + +&dpu1 { + status = "okay"; + + aclk_freq_fixed = <800000000>; + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + port { + dpu1_pipe0_out: endpoint { + remote-endpoint = <&dp1_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu1_pipe1_out: endpoint { + remote-endpoint = <&dp1_1_in>; + }; + }; + }; +}; + +&dpu2 { + status = "okay"; + + aclk_freq_fixed = <800000000>; + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + port { + dpu2_pipe0_out: endpoint { + remote-endpoint = <&dp2_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu2_pipe1_out: endpoint { + remote-endpoint = <&dp2_1_in>; + }; + }; + }; +}; + +&dpu3 { + status = "okay"; + + aclk_freq_fixed = <800000000>; + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + port { + dpu3_pipe0_out: endpoint { + remote-endpoint = <&dp3_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu3_pipe1_out: endpoint { + remote-endpoint = <&dp3_1_in>; + }; + }; + }; +}; + +&dpu4 { + status = "okay"; + + aclk_freq_fixed = <800000000>; + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + port { + dpu4_pipe0_out: endpoint { + remote-endpoint = <&dp4_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu4_pipe1_out: endpoint { + remote-endpoint = <&dp4_1_in>; + }; + }; + }; +}; + +&aeu0 { + status = "disabled"; +}; + +&aeu1 { + status = "disabled"; +}; + +&aeu2 { + status = "disabled"; +}; + +&aeu3 { + status = "disabled"; +}; + +&aeu4 { + status = "disabled"; +}; + +&gmac_rcsu { + status = "okay"; +}; + +&macb0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gmac0>; + phy-mode = "rgmii-id"; + cix,gmac-ctrl = <&gmac_rcsu>; + phy-handle = <&mac0_phy>; + reset-delay-us = <20000>; /* 20ms */ + reset-post-delay-us = <100000>; /* 100ms */ + reset-gpios = <&fch_gpio0 0 GPIO_ACTIVE_LOW>; + mac0_phy: ethernet-phy@1 { + reg = <1>; + device_type = "ethernet-phy"; + compatible = "ethernet-phy-ieee802.3-c22"; + }; +}; + +&macb1 { + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gmac1>; + phy-mode = "rgmii-id"; + phy-handle = <&mac1_phy>; + reset-delay-us = <20000>; /* 20ms */ + reset-post-delay-us = <100000>; /* 100ms */ + reset-gpios = <&fch_gpio0 1 GPIO_ACTIVE_LOW>; + mac1_phy: ethernet-phy@2 { + reg = <2>; + device_type = "ethernet-phy"; + compatible = "ethernet-phy-ieee802.3-c22"; + }; +}; + +&usbc_phy0 { + orientation-switch; + svid = <0xff01>; + status = "okay"; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy0_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_phy_sw>; + }; + }; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&usbc0_dp_phy { + status = "okay"; +}; + +&sky1_usbss_0 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>; + oc-gpio = <&s5_gpio0 25 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; +}; + +&usbss_0 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_0_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_role_sw>; + }; + }; +}; + +&usbc_phy1 { + status = "okay"; + orientation-switch; + svid = <0xff01>; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy1_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc1_phy_sw>; + }; + }; +}; + +&usb3_phy1 { + status = "okay"; +}; + +&usbc1_dp_phy { + status = "okay"; +}; + +&sky1_usbss_1 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1>; + oc-gpio = <&s5_gpio0 26 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; +}; + +&usbss_1 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_1_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc1_role_sw>; + }; + }; +}; + +&usbc_phy2 { + status = "okay"; + orientation-switch; + svid = <0xff01>; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy2_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_phy_sw>; + }; + }; +}; + +&usb3_phy2 { + status = "okay"; +}; + +&usbc2_dp_phy { + status = "okay"; +}; + +&sky1_usbss_2 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb2>; + oc-gpio = <&s5_gpio0 27 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; +}; + +&usbss_2 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_2_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_role_sw>; + }; + }; +}; + +&usbc_phy3 { + status = "okay"; + orientation-switch; + svid = <0xff01>; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy3_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc3_phy_sw>; + }; + }; +}; + +&usb3_phy3 { + status = "okay"; +}; + +&usbc3_dp_phy { + status = "okay"; +}; + +&sky1_usbss_3 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb3>; + oc-gpio = <&s5_gpio0 28 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; +}; + +&usbss_3 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_3_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc3_role_sw>; + }; + }; +}; + +&usb3_phy4 { + status = "okay"; +}; + +&usb3_phy4_0 { + status = "okay"; +}; + +&sky1_usbss_4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb4>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_4 { + status = "okay"; + dr_mode = "host"; +}; + +&usb3_phy4_1 { + status = "okay"; +}; + +&sky1_usbss_5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb5>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_5 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb6>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_0 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb7>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_1 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb8>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_2 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb9>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_3 { + status = "okay"; + dr_mode = "host"; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c0>; +}; + +&i2c1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c1>; + clock-frequency = <100000>; + rts5453_pd1_port0:rts5453@30 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; + id = <2>; + reg = <0x30>; + status = "okay"; + usbc_con2 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc2_role_sw: endpoint { + remote-endpoint = <&cdnsp_2_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc2_phy_sw: endpoint { + remote-endpoint = <&usbdpphy2_lane_switch>; + }; + }; + }; + }; + + rts5453_pd1_port1:rts5453@31 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; + id = <3>; + reg = <0x31>; + status = "okay"; + usbc_con3 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc3_role_sw: endpoint { + remote-endpoint = <&cdnsp_3_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc3_phy_sw: endpoint { + remote-endpoint = <&usbdpphy3_lane_switch>; + }; + }; + }; + }; +}; + +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + + alc5682: codec@1a { + compatible = "realtek,rt5682s"; + reg = <0x1a>; + + interrupt-parent = <&fch_gpio3>; + interrupts = <10 IRQ_TYPE_EDGE_BOTH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_alc5682_irq>; + + realtek,dmic1-data-pin = <1>; /* using GPIO2 pin as dmic1 data pin */ + realtek,dmic1-clk-pin = <2>; /* using GPIO3 pin as dmic1 clock pin */ + realtek,dmic-clk-rate-hz = <2048000>; + + realtek,jd-src = <1>; /* using JD1 as JD source */ + + #sound-dai-cells = <1>; + status = "okay"; + }; + + i2c-hid-dev@68 { + compatible = "hid-over-i2c"; + reg = <0x68>; + hid-descr-addr = <0x0020>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hiddev_68_irq>; + interrupt-parent = <&s5_gpio0>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; + + i2c-hid-dev@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + hid-descr-addr = <0x0001>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hiddev_15_irq>; + interrupt-parent = <&s5_gpio0>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + status = "disabled"; + }; +}; + +&i2c2_slave { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + clock-frequency = <1000000>; + status = "disabled"; +}; + +&i2c3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c3>; + + ra8900ce: ra8900ce@32 { + compatible = "rtc,rx8900"; + reg = <0x32>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ra8900ce_irq>; + interrupt-parent = <&s5_gpio0>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; +}; + +&i2c4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; + + nfc: nfc@28 { + status = "disabled"; + compatible = "nfc,nfc_28h"; + reg = <0x28>; + }; +}; + +/*EC_HDI*/ +&i2c5 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; + + keyboard_0: keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + interrupt-parent = <&s5_gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + hid-descr-addr = <0x0001>; + wakeup-source; + status = "okay"; + }; +}; + +/*EC_HOST*/ +&i2c6 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c6>; + + cros_ec: ec@76 { + compatible = "google,cros-ec-i2c"; + reg = <0x76>; + interrupt-parent = <&s5_gpio0>; + interrupts = <6 IRQ_TYPE_EDGE_RISING>; + wakeup-source; + status = "okay"; + }; +}; + +&cros_ec { + cros_ec_pwm: ec-pwm { + compatible = "google,cros-ec-pwm"; + #pwm-cells = <1>; + status = "disabled"; + }; + + cix_fan: pwm-fan { + compatible = "pwm-fan"; + cooling-levels = <0 150 200 255>; + #cooling-cells = <2>; + pwms = <&cros_ec_pwm 0>; + status = "disabled"; + }; + + cix_ec_light { + compatible = "cix,cix-ec-light"; + status = "disabled"; + }; + + cix_ec_lid { + compatible = "cix,cix-ec-lid"; + status = "okay"; + }; + + cix_ec_battery { + compatible = "cix,cix-ec-battery"; + status = "okay"; + }; + + cix_ec_charge { + compatible = "cix,cix-ec-charge"; + status = "okay"; + }; + + cix_ec_kb_backlight{ + compatible = "cix,cix-ec-keyboard-backlight"; + status = "disabled"; + }; + + ec_gpio: cix_ec_gpio { + compatible = "cix,cix-ec-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <104>; + status = "okay"; + }; + + cix_ec_pwrkey { + compatible = "cix,cix-ec-pwrkey"; + status = "okay"; + }; + + cix_ec_excp { + compatible = "cix,cix-ec-excp"; + status = "okay"; + }; + + cix_ec_fan { + compatible = "cix,cix-ec-fan"; + status = "okay"; + }; + +}; + +&i2c7 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c7>; + clock-frequency = <100000>; + rts5453_pd0_port0:rts5453@30 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + id = <0>; + reg = <0x30>; + status = "okay"; + usbc_con0 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc0_role_sw: endpoint { + remote-endpoint = <&cdnsp_0_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc0_phy_sw: endpoint { + remote-endpoint = <&usbdpphy0_lane_switch>; + }; + }; + }; + }; + + rts5453_pd0_port1:rts5453@31 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + id = <1>; + reg = <0x31>; + status = "okay"; + usbc_con1 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc1_role_sw: endpoint { + remote-endpoint = <&cdnsp_1_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc1_phy_sw: endpoint { + remote-endpoint = <&usbdpphy1_lane_switch>; + }; + }; + }; + }; +}; + +&sf_i2c0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i2c0>; +}; + +&sf_i2c1 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i2c1>; +}; + +&i3c0{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c0>; + i3c-scl-hz = <100000>; + mmc5633_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&i3c1{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c1>; + i3c-scl-hz = <100000>; + mmc5633_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&sf_i3c0{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i3c0>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + mmc5633c_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c0@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&sf_i3c1{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i3c1>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + mmc5633c_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c0@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&spi0{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + /* Character device nodes for device communication on CS0(/dev/spidev0.0) */ + spidev0_0:spi@0_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev0.1) */ + spidev0_1:spi@0_1{ + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +&spi1{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi1>; + /* Character device nodes for device communication on CS0(/dev/spidev1.0) */ + spidev1_0:spi@1_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; +}; + +&sf_spi{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_spi>; + /* Character device nodes for device communication on CS0(/dev/spidev2.0) */ + spidev2_0:spi@2_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev2.1) */ + spidev2_1:spi@2_1{ + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +&xspi{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_xspi>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-max-frequency = <25000000>; + }; +}; + +&uart0{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart0>; + dmas = <&fch_dmac 0 2>, <&fch_dmac 1 3>; + dma-names = "tx","rx"; +}; +&uart1{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart1>; + dmas = <&fch_dmac 2 4>, <&fch_dmac 3 5>; + dma-names = "tx","rx"; +}; + +&aipu_res_0 { + status = "disabled"; +}; + +&npu { + status = "okay"; +}; + +&its_pcie { + status = "okay"; +}; + +&smmu_pciehub{ + status = "disabled"; +}; + +&smmu_mmhub{ + status = "okay"; +}; + +&pcie_x8_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x8_rc>; + reset-gpios = <&s5_gpio0 1 GPIO_ACTIVE_HIGH>; + aspm-no-l0s; + status = "okay"; +}; + +&pcie_x4_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x4_rc>; + reset-gpios = <&s5_gpio0 3 GPIO_ACTIVE_HIGH>; + aspm-no-l0s; + status = "okay"; +}; + +&pcie_x2_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x2_rc>; + reset-gpios = <&s5_gpio0 2 GPIO_ACTIVE_HIGH>; + aspm-no-l0s; + status = "okay"; +}; + +&pcie_x1_1_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_1_rc>; + reset-gpios = <&s5_gpio0 5 GPIO_ACTIVE_HIGH>; + aspm-no-l0s; + status = "okay"; +}; + +&pcie_x1_0_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_0_rc>; + reset-gpios = <&s5_gpio0 4 GPIO_ACTIVE_HIGH>; + vcc-pcie-supply = <&vdd_3v3_pcie>; + wlan-en-supply = <&wlan_poweren>; + aspm-no-l0s; + sky1,str-pwron; + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + +&pcie_x4_phy { + status = "okay"; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie_x8_phy { + status = "okay"; +}; + +&pciex211_phy { + status = "okay"; +}; + +&pcie_x1_phy0 { + status = "okay"; +}; + +&pcie_x1_phy1 { + status = "okay"; +}; + +&pcie_x2_phy { + status = "okay"; +}; + +&mbox_ap2pm { + status = "okay"; +}; + +&mbox_pm2ap { + status = "okay"; +}; + +&mbox_se2ap { + status = "okay"; +}; + +&mbox_ap2se { + status = "okay"; +}; + +&sky1_crash { + status = "okay"; +}; + +&ap2pm_scmi_mem { + status = "okay"; +}; + +&pm2ap_scmi_mem { + status = "okay"; +}; + +&ap_tfa_scmi_mem { + status = "okay"; +}; + +&ap_to_pm_scmi { + status = "okay"; +}; + +&ap_to_tfa_scmi { + status = "okay"; +}; + +&scmi_dvfs { + status = "okay"; +}; + +&vpu { + status = "okay"; +}; + +&ramoops { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&cix_dst { + status = "okay"; +}; + +&exception_trace { + status = "okay"; +}; + +&ap_adapter { + status = "okay"; +}; + +&mntndump { + status = "okay"; +}; + +&ddr_ctrl0 { + status = "okay"; +}; + +&ddr_ctrl1 { + status = "okay"; +}; + +&ddr_ctrl2 { + status = "okay"; +}; + +&ddr_ctrl3 { + status = "okay"; +}; + +&cix_pmu_ci700 { + status = "disabled"; +}; + +&cix_pmu_ni700 { + status = "disabled"; +}; + +&cix_bus_ci700 { + status = "disabled"; +}; + +&cix_bus_ni700 { + status = "disabled"; +}; + +&rfkill_wwan { + status = "okay"; +}; + +&thermal_zones { + cpu-m1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M1_TEMP_SENSOR_ID>; + sustainable-power = <4500>; + + trips { + m1_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + m1_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + m1_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&m1_trip1>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B1_TEMP_SENSOR_ID>; + sustainable-power = <6000>; + + trips { + b1_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + b1_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + b1_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&b1_trip1>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-m0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + sustainable-power = <5000>; + + trips { + m0_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + m0_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + m0_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&m0_trip1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B0_TEMP_SENSOR_ID>; + sustainable-power = <5500>; + + trips { + b0_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + b0_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + b0_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&b0_trip1>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; + +&wireless_bluetooth { + status = "okay"; +}; + +&cix_ddrlp { + status = "okay"; +}; + +&cix_ipa { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-fpga.dts b/arch/arm64/boot/dts/cix/sky1-fpga.dts new file mode 100644 index 000000000000..c8481092be61 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-fpga.dts @@ -0,0 +1,1698 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; +#define CONFIG_ARCH_CIX_EMU_FPGA + +#include "sky1.dtsi" + +/ { + model = "CIX sky1 FPGA platform"; + compatible = "cix,sky1-fpga", "cix,sky1"; + + aliases { + linlondp0 = &dpu2; + linlondp1 = &dpu2; + }; + + virtual-encoder@0 { + compatible = "cix,virtual-display"; + status = "okay"; + + port { + vt_enc0_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; + }; + + virtual-encoder@1 { + compatible = "cix,virtual-display"; + status = "okay"; + + port { + vt_enc1_in: endpoint { + remote-endpoint = <&dpu2_pipe1_out>; + }; + }; + }; + + chosen { + stdout-path = "serial2:115200n8"; + }; + + dummy_codec: dummy_codec { + #sound-dai-cells = <1>; + compatible = "linux,dummy"; + status = "disabled"; + }; + + alc256_codec: alc256_codec { + compatible = "realtek,alc256"; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "disabled"; + + /* for alc1019 */ + pdb0-gpios = <&s5_gpio0 0 GPIO_ACTIVE_HIGH>; + beep-gpios = <&s5_gpio0 1 GPIO_ACTIVE_HIGH>; + /* for alc5682 */ + codec-gpios = <&fch_gpio0 3 GPIO_ACTIVE_HIGH>; + i2sint-gpios = <&s5_gpio0 31 GPIO_ACTIVE_LOW>; + hpmicdet-gpios = <&fch_gpio0 2 GPIO_ACTIVE_LOW>; + + i2s-sc0 { + status = "disabled"; + + format = "dsp_a"; + frame-master = <&i2s_sc0>; + bitclock-master = <&i2s_sc0>; + bitclock-inversion; + mclk-fs = <256>; + + dai-tdm-slot-tx-mask = <1 1 1 1>; + dai-tdm-slot-rx-mask = <1 1 1 1>; + dai-tdm-slot-num = <4>; + dai-tdm-slot-width = <16>; + + i2s_sc0: cpu { + sound-dai = <&i2s0>; + }; + }; + + i2s-sc2 { + status = "disabled"; + + format = "i2s"; + bitclock-inversion; + mclk-fs = <256>; + + frame-master = <&dummy_c>; + bitclock-master = <&dummy_c>; + + cpu { + sound-dai = <&i2s2>; + }; + + dummy_c: codec { + sound-dai = <&dummy_codec 0>; + }; + + }; + + i2s-mc0 { + status = "disabled"; + + format = "i2s"; + bitclock-inversion; + mclk-fs = <256>; + + cpu { + sound-dai = <&i2s3 0>; + }; + }; + + pa_alc1019 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <256>; + cpu { + sound-dai = <&i2s0>; + }; + }; + + codec_alc5682 { + status = "disabled"; + + format = "i2s"; + mclk-fs = <512>; + jack-det,hp; + + cpu { + sound-dai = <&i2s0 0>; + }; + codec { + sound-dai = <&alc5682>; + }; + }; + + dpout { + status = "disabled"; + + format = "i2s"; + /* bitclock-inversion; //if for external codec */ + mclk-fs = <256>; + jack-det,dpout; + cpu { + sound-dai = <&i2s7 0>; + }; + codec { + sound-dai = <&dp2>; + }; + }; + + hda { + status = "disabled"; + + cpu { + sound-dai = <&ipb_hda>; + }; + codec { + sound-dai = <&alc256_codec>; + }; + }; + }; + + dp2_backlight: dp2_backlight { + compatible = "pwm-backlight"; + enable-gpios = <&fch_gpio3 15 GPIO_ACTIVE_HIGH>; + pwms = <&pwm0 0 100000>; + status = "okay"; + + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + + }; + + panel_edp0: panel_edp0 { + status = "okay"; + compatible = "cix-edp-panel"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_edp0>; + backlight = <&dp2_backlight>; + prepare-delay-ms = <120>; + enable-delay-ms = <120>; + unprepare-delay-ms = <500>; + disable-delay-ms = <120>; + width-mm = <129>; + height-mm = <171>; + enable-gpios = <&fch_gpio3 16 GPIO_ACTIVE_HIGH>; + }; +}; + +&iomuxc_s5 { + status = "okay"; + pinctrl_sfi_i2c0: pinctrl_sfi_i2c0_grp { + sky1,pins = < + 0x00000070 0x0000005c + 0x00000074 0x0000005c + >; + }; + + pinctrl_sfi_i2c1: pinctrl_sfi_i2c1_grp { + sky1,pins = < + 0x00000078 0x00000057 + 0x0000007c 0x00000057 + >; + }; + + pinctrl_sfi_i3c0: pinctrl_sfi_i3c0_grp { + sky1,pins = < + 0x00000070 0x000000dc + 0x00000074 0x000000dc + 0x000000a0 0x00000157 + >; + }; + + pinctrl_sfi_i3c1: pinctrl_sfi_i3c1_grp { + sky1,pins = < + 0x00000078 0x000000dc + 0x0000007c 0x000000dc + 0x000000a4 0x00000157 + >; + }; + + pinctrl_sfi_spi: pinctrl_sfi_spi_grp { + sky1,pins = < + 0x00000078 0x00000157 + 0x0000007c 0x00000157 + 0x00000080 0x000000d7 + 0x00000084 0x000000d7 + 0x00000088 0x000000d7 + >; + }; + + pinctrl_fch_spi0: pinctrl_fch_spi0_grp { + sky1,pins = < + 0x000000a8 0x0000005c + 0x000000ac 0x0000005c + 0x000000b0 0x0000005c + 0x000000b4 0x0000005c + 0x000000b8 0x0000005c + >; + }; + + pinctrl_fch_xspi: pinctrl_fch_xspi_grp { + sky1,pins = < + 0x000000f0 0x000000dc + 0x000000f4 0x000000dc + 0x000000f8 0x000000dc + 0x000000fc 0x000000dc + 0x00000100 0x000000dc + 0x00000104 0x000000dc + >; + }; + +}; + +&iomuxc { + status = "okay"; + pinctrl_fch_pwm0: pinctrl_fch_pwm0 { + sky1,pins = < + 0x0000013c 0x000000b7 + >; + }; + + pinctrl_fch_pwm1: pinctrl_fch_pwm1 { + sky1,pins = < + 0x00000140 0x000000b7 + >; + }; + + pinctrl_gmac0: pinctrl_gmac0 { + sky1,pins = + /* rfclk_25M */ + < 0x000001a4 0x000000fc>, + /* txc_trl */ + < 0x000001a8 0x000000bc>, + /* txd0 */ + < 0x000001ac 0x000000bc>, + /* txd1 */ + < 0x000001b0 0x000000bc>, + /* txd2 */ + < 0x000001b4 0x000000bc>, + /* txd3 */ + < 0x000001b8 0x000000bc>, + /* tx_clk */ + < 0x000001bc 0x000000bc>, + /* rx_ctl */ + < 0x000001c0 0x000000a4>, + /* rxd0 */ + < 0x000001c4 0x000000a4>, + /* rxd1 */ + < 0x000001c8 0x000000a4>, + /* rxd2 */ + < 0x000001cc 0x000000a4>, + /* rxd3 */ + < 0x000001d0 0x000000a4>, + /* rx_clk */ + < 0x000001d4 0x000000a4>, + /* mdc */ + < 0x000001d8 0x000000bc>, + /* mdio */ + < 0x000001dc 0x000000dc>; + }; + + pinctrl_fch_fan0: pinctrl_fch_fan0 { + sky1,pins = < + 0x0000014c 0x000000b7 + >; + }; + + pinctrl_fch_fan1: pinctrl_fch_fan1 { + sky1,pins = < + 0x00000154 0x000000b7 + >; + }; + + pinctrl_fch_fan2: pinctrl_fch_fan2 { + sky1,pins = < + 0x00000144 0x000000b7 + >; + }; + + pinctrl_fch_i2c0: pinctrl_fch_i2c0 { + sky1,pins = < + 0x00000078 0x00000047 + 0x0000007c 0x00000047 + >; + }; + + pinctrl_fch_i2c0_gpio: pinctrl_fch_i2c0_gpio { + sky1,pins = < + 0x00000078 0x000000c7 + 0x0000007c 0x000000c7 + >; + }; + + pinctrl_fch_i2c1: pinctrl_fch_i2c1 { + sky1,pins = < + 0x00000080 0x00000047 + 0x00000084 0x00000047 + >; + }; + + pinctrl_fch_i2c1_gpio: pinctrl_fch_i2c1_gpio { + sky1,pins = < + 0x00000080 0x000000c7 + 0x00000084 0x000000c7 + >; + }; + + pinctrl_fch_i2c2: pinctrl_fch_i2c2 { + sky1,pins = < + 0x00000088 0x0000005c + 0x0000008c 0x0000005c + >; + }; + + pinctrl_fch_i2c2_gpio: pinctrl_fch_i2c2_gpio { + sky1,pins = < + 0x00000088 0x0000015c + 0x0000008c 0x0000015c + >; + }; + + pinctrl_fch_i2c3: pinctrl_fch_i2c3 { + sky1,pins = < + 0x00000094 0x0000005c + 0x00000098 0x0000005c + >; + }; + + pinctrl_fch_i2c3_gpio: pinctrl_fch_i2c3_gpio { + sky1,pins = < + 0x00000094 0x0000015c + 0x00000098 0x0000015c + >; + }; + + pinctrl_fch_i2c4: pinctrl_fch_i2c4 { + sky1,pins = < + 0x000000a0 0x00000047 + 0x000000a4 0x00000047 + >; + }; + + pinctrl_fch_i2c4_gpio: pinctrl_fch_i2c4_gpio { + sky1,pins = < + 0x000000a0 0x000000c7 + 0x000000a4 0x000000c7 + >; + }; + + pinctrl_fch_i2c5: pinctrl_fch_i2c5 { + sky1,pins = < + 0x00000068 0x00000047 + 0x0000006c 0x00000047 + >; + }; + + pinctrl_fch_i2c5_gpio: pinctrl_fch_i2c5_gpio { + sky1,pins = < + 0x00000068 0x000000c7 + 0x0000006c 0x000000c7 + >; + }; + + pinctrl_fch_i2c6: pinctrl_fch_i2c6 { + sky1,pins = < + 0x00000070 0x00000047 + 0x00000074 0x00000047 + >; + }; + + pinctrl_fch_i2c6_gpio: pinctrl_fch_i2c6_gpio { + sky1,pins = < + 0x00000070 0x000000c7 + 0x00000074 0x000000c7 + >; + }; + + pinctrl_fch_i2c7: pinctrl_fch_i2c7 { + sky1,pins = < + 0x00000054 0x00000047 + 0x00000058 0x00000047 + >; + }; + + pinctrl_fch_spi1: pinctrl_fch_spi1_grp { + sky1,pins = < + 0x000001e8 0x0000013c + 0x000001ec 0x0000013c + 0x000001f0 0x0000013c + 0x000001f4 0x0000013c + 0x000001f8 0x0000013c + >; + }; + + pinctrl_fch_i3c0: pinctrl_fch_i3c0 { + sky1,pins = < + 0x00000088 0x000000dc + 0x0000008c 0x000000dc + 0x00000090 0x000000dc + >; + }; + + pinctrl_fch_i3c1: pinctrl_fch_i3c1 { + sky1,pins = < + 0x00000094 0x000000dc + 0x00000098 0x000000dc + 0x0000009c 0x000000dc + >; + }; + + pinctrl_fch_uart0: pinctrl_fch_uart0 { + sky1,pins = < + 0x0000013c 0x00000037 + 0x00000140 0x00000037 + 0x00000144 0x00000037 + 0x00000148 0x00000037 + >; + }; + + pinctrl_fch_uart1: pinctrl_fch_uart1 { + sky1,pins = < + 0x0000014c 0x00000037 + 0x00000150 0x00000037 + 0x00000154 0x00000037 + 0x00000158 0x00000037 + >; + }; + + pinctrl_fch_uart2: pinctrl_fch_uart2 { + sky1,pins = < + 0x0000015c 0x00000027 + 0x00000160 0x00000027 + 0x00000164 0x00000027 + 0x00000168 0x00000027 + >; + }; + + pinctrl_hda: pinctrl_hda_grp { + sky1,pins = < + 0x000000a8 0x00000057 + 0x000000ac 0x00000057 + 0x000000b0 0x00000057 + 0x000000b4 0x00000057 + 0x000000b8 0x00000057 + >; + }; + + pinctrl_cam0_hw: pinctrl_cam0_hw { + sky1,pins = < + 0x00000194 0x0000003C + 0x00000134 0x0000001C + 0x0000011C 0x0000009C + 0x00000128 0x0000001C + >; + }; + pinctrl_cam1_hw: pinctrl_cam1_hw { + sky1,pins = < + 0x00000198 0x0000003C + 0x00000134 0x0000001C + 0x00000130 0x0000001C + 0x00000138 0x0000001C + >; + }; + pinctrl_cam2_hw: pinctrl_cam2_hw { + sky1,pins = < + 0x0000019C 0x0000003C + 0x00000118 0x000000BC + 0x00000114 0x000000BC + 0x00000108 0x000000BC + >; + }; + pinctrl_cam3_hw: pinctrl_cam3_hw { + sky1,pins = < + 0x000001A0 0x0000003C + 0x00000118 0x000000BC + 0x00000120 0x000000BC + 0x00000124 0x000000BC + >; + }; + + pinctrl_lt7911_hw: pinctrl_lt7911_hw { + sky1,pins = < + 0x0000012c 0x0000001c + 0x0000011c 0x000000bc + >; + }; + + pinctrl_edp0: pinctrl_edp0 { + sky1,pins = < + 0x00000048 0x00000024 + 0x0000004C 0x00000024 + 0x00000050 0x00000007 + >; + }; +}; + +&pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm0>; + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm1>; + status = "disabled"; +}; + +&pmu { + status = "okay"; +}; + +&uartclk { + clock-frequency = <5000000>; +}; + +&uart_apb_pclk { + clock-frequency = <5000000>; +}; + +&hifi5 { + status = "okay"; +}; + +&mbox_dsp2ap { + status = "okay"; +}; + +&mbox_ap2dsp { + status = "okay"; +}; + +&audss_cru { + status = "okay"; +}; + +&audss_dmac { + memory-region = <&audio_alsa>; + status = "disabled"; +}; + +&i2s0 { + /* i2s_sc0 for codec */ + dmas = <&audss_dmac 0 0>, <&audss_dmac 1 1>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s1 { + /* i2s_sc1 for 5G/BT */ + dmas = <&audss_dmac 2 2>, <&audss_dmac 3 3>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s2 { + /* i2s_sc2 for loopback */ + dmas = <&audss_dmac 4 4>, <&audss_dmac 5 5>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s3 { + /* i2s_mc2a for speaker */ + dmas = <&audss_dmac 4 6>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s4 { + /* i2s_mc2b for dp-in */ + dmas = <&audss_dmac 6 9>; + dma-names = "rx"; + status = "disabled"; +}; + +&i2s5 { + /* i2s_mc5a for dp-out */ + dmas = <&audss_dmac 7 10>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s6 { + /* i2s_mc5b for dp-out */ + dmas = <&audss_dmac 7 12>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s7 { + /* i2s_mc5c for dp-out */ + dmas = <&audss_dmac 7 14>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <1>; /* pin0 for dp out codec now */ + status = "disabled"; +}; + +&i2s8 { + /* i2s_mc5d for dp-out */ + dmas = <&audss_dmac 7 16>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s9 { + /* i2s_mc5e for dp-out */ + dmas = <&audss_dmac 7 18>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <15>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&ipb_hda { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hda>; + pdb-gpios = <&fch_gpio0 3 GPIO_ACTIVE_HIGH>; + memory-region = <&audio_alsa>; + status = "disabled"; +}; + +&uart0{ + pinctrl-names = "default"; + timeout-value = <10000>; + pinctrl-0 = <&pinctrl_fch_uart0>; + dmas = <&fch_dmac 2 0>, <&fch_dmac 3 1>; + dma-names = "tx","rx"; +}; + +&uart1{ + status = "okay"; + pinctrl-names = "default"; + timeout-value = <10000>; + pinctrl-0 = <&pinctrl_fch_uart1>; + dmas = <&fch_dmac 4 2>, <&fch_dmac 5 3>; + dma-names = "tx","rx"; +}; + +&uart2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart2>; +}; + +&spi0{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + spidev0:spi@0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; +}; + +&spi1{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi1>; + spidev1:spi@0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; +}; + +&sf_spi{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_spi>; + spidev2:spi@0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; +}; + +&xspi{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_xspi>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-max-frequency = <5000000>; + }; +}; + +&sensorhub { + memory-region = <&sfh_vdev0buffer>, <&sfh_vdev0vring0>, + <&sfh_vdev0vring1>, <&sfh_ram>; + status = "okay"; +}; + +&sky1_usbss_0 { + u3-port-disable; + lpm_clk_freq = <4000000>; + sof_clk_freq = <4000000>; + status = "disabled"; +}; + +&usbss_0 { + dr_mode = "host"; + status = "disabled"; +}; +&macb0 { + #address-cells = <1>; + #size-cells = <0>; + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_gmac0>; + phy-mode = "rgmii-id"; + phy-handle = <&mac0_phy>; + mac0_phy: ethernet-phy@1 { + reg = <1>; + device_type = "ethernet-phy"; + compatible = "ethernet-phy-ieee802.3-c22"; + //reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; + + }; +}; + +&macb1 { + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + phy-mode = "rgmii-id"; + phy-handle = <&mac1_phy>; + fixed-link { + speed = <10>; + full-duplex; + }; + mac1_phy: ethernet-phy@1 { + reg = <1>; + device_type = "ethernet-phy"; + compatible = "ethernet-phy-ieee802.3-c22"; + //reset-gpios = <&gpio GPIOZ_14 GPIO_ACTIVE_LOW>; + + }; +}; + +&cix_csi_rcsu_0 { + status = "disabled"; +}; + +&cix_csi_rcsu_1 { + status = "disabled"; +}; + +&cix_bridge_0 { + status = "disabled"; + port { + cix_bridge_0_in: endpoint { + remote-endpoint = <&mipi_csi2_0_out>; + }; + }; +}; + +&cix_bridge_1 { + status = "disabled"; + port { + cix_bridge_1_in: endpoint { + remote-endpoint = <&mipi_csi2_1_out>; + }; + }; +}; + +&cix_bridge_2 { + status = "disabled"; + port { + cix_bridge_2_in: endpoint { + remote-endpoint = <&mipi_csi2_2_out>; + }; + }; +}; + +&cix_bridge_3 { + status = "disabled"; + port { + cix_bridge_3_in: endpoint { + remote-endpoint = <&mipi_csi2_3_out>; + }; + }; +}; + +&cix_mipi_csi_0 { + lanes = <1>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_0_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy1_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_0_in>; + }; + }; + }; +}; + +&cix_mipi_csi_1 { + lanes = <1>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_1_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy2_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_1_in>; + }; + }; + }; +}; + +&cix_mipi_csi_2 { + lanes = <1>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_2_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy4_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_2_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_2_in>; + }; + }; + }; +}; + +&cix_mipi_csi_3 { + lanes = <1>; + status = "disabled"; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_3_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&dphy5_out>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + mipi_csi2_3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&cix_bridge_3_in>; + }; + }; + }; +}; + +&cix_dphy_0 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy0_in: endpoint@1 { + reg = <1>; + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy0_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_0_in>; + }; + }; + }; +}; + +&cix_dphy_1 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy1_in: endpoint@1 { + reg = <1>; + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy1_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_0_in>; + }; + }; + }; +}; + +&cix_dphy_2 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy2_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_0_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy2_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_1_in>; + }; + }; + }; + +}; + +&cix_dphy_3 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy3_in: endpoint@1 { + reg = <1>; + /*this not active*/ + remote-endpoint = <<7911uxc_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy3_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_2_in>; + }; + }; + }; +}; + +&cix_dphy_4 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy4_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_1_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy4_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_2_in>; + }; + }; + }; +}; + +&cix_dphy_5 { + status = "disabled"; + #address-cells = <1>; + #size-cells = <0>; + ports { + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + #address-cells = <1>; + #size-cells = <0>; + dphy5_in: endpoint@1 { + reg = <1>; + remote-endpoint = <&virt_lt7911uxc_2_out>; + data-lanes = <1 2 3 4>; + clock-lanes = <0>; + }; + }; + port@1 { + reg = <1>; + #address-cells = <1>; + #size-cells = <0>; + dphy5_out: endpoint@0 { + reg = <0>; + remote-endpoint = <&mipi_csi2_3_in>; + }; + }; + }; +}; + +&cix_dphy_hw_0 { + status = "disabled"; +}; + +&cix_dphy_hw_1 { + status = "disabled"; +}; + +&i2c0 { + status = "disabled"; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_fch_i2c0>; + pinctrl-1 = <&pinctrl_fch_i2c0_gpio>; + imgsensor00: imgsensor00@34 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x34>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam0_hw>; + pwren-gpios = <&fch_gpio1 18 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio1 12 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 15 GPIO_ACTIVE_HIGH>; + + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK0>; + clock-names = "mclk"; + actuator-src = <&isp_motor>; + isp-src = <&i7_isp>; + status = "disabled"; + }; +}; + +&i2c1 { + status = "disabled"; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_fch_i2c1>; + pinctrl-1 = <&pinctrl_fch_i2c1_gpio>; + imgsensor02: imgsensor02@38 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x38>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam2_hw>; + pwren-gpios = <&fch_gpio1 11 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio1 10 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 7 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK2>; + clock-names = "mclk"; + isp-src = <&i7_isp>; + status = "disabled"; + }; +}; +&i2c4 { + status = "disabled"; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_fch_i2c4>; + pinctrl-1 = <&pinctrl_fch_i2c4_gpio>; + imgsensor03: imgsensor03@3a { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x3a>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam3_hw>; + pwren-gpios = <&fch_gpio1 11 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio1 13 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 14 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK3>; + clock-names = "mclk"; + isp-src = <&i7_isp>; + status = "disabled"; + }; +}; + +&i2c3 { + status = "okay"; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_fch_i2c3>; + pinctrl-1 = <&pinctrl_fch_i2c3_gpio>; + scl-gpios = <&fch_gpio0 15 GPIO_ACTIVE_HIGH>; + sda-gpios = <&fch_gpio0 16 GPIO_ACTIVE_HIGH>; + lt7911uxc: lt7911uxc@43 { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x43>; + /*interrupt-parent = <&gpio0>;*/ + /*interrupts = ;*/ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_lt7911_hw>; + plugin-det-gpios = <&fch_gpio0 8 GPIO_ACTIVE_LOW>; + power-gpios = <&fch_gpio1 12 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio1 16 GPIO_ACTIVE_HIGH>; + status = "okay"; + port { + lt7911uxc_out: endpoint { + //remote-endpoint = <&dphy0_in>; + remote-endpoint = <&dphy1_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_0: virtual_lt7911uxc_0@0d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x0d>; + status = "disabled"; + port { + virt_lt7911uxc_0_out: endpoint { + remote-endpoint = <&dphy2_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_1: virtual_lt7911uxc_1@1d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x1d>; + status = "disabled"; + port { + virt_lt7911uxc_1_out: endpoint { + remote-endpoint = <&dphy4_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + virtual_lt7911uxc_2: virtual_lt7911uxc_2@2d { + compatible = "lontium,lt7911uxc"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x2d>; + status = "disabled"; + port { + virt_lt7911uxc_2_out: endpoint { + remote-endpoint = <&dphy5_in>; + data-lanes = <4>; + clock-lanes = <0>; + }; + }; + }; + + isp_motor: motor0@40 { + compatible = "motor,ms42919"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + pi-max-frequency = <124999999>; + status = "okay"; + }; + + imgsensor01: imgsensor01@36 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x36>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_cam1_hw>; + pwren-gpios = <&fch_gpio1 18 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio1 17 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 19 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK1>; + clock-names = "mclk"; + isp-src = <&i7_isp>; + status = "okay"; + }; + + ra8900ce: ra8900ce@32 { + compatible = "rtc,rx8900"; + reg = <0x32>; + interrupt-parent = <&s5_gpio0>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + status = "disabled"; + }; +}; + +&dp2 { + status = "okay"; + + cix,dp-lane-number = <1>; + cix,dp-max-rate = <162000>; + cix,aux-clock-divider = <25>; + +// edp-panel = <&panel_edp0>; + + port { + dp2_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; +}; + +&dpu2 { + status = "okay"; + + pipeline@0 { + port { + dpu2_pipe0_out: endpoint { + remote-endpoint = <&vt_enc0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu2_pipe1_out: endpoint { + }; + }; + }; +}; + +&aeu2 { + status = "okay"; +}; + +&i7_isp { + status = "okay"; +}; + +&armcb_config { + status = "okay"; +}; + +&armcb_ispmem { + status = "okay"; +}; + +&its_pcie { + status = "disabled"; +}; + +&smmu_pciehub{ + status = "disabled"; +}; + +&smmu_mmhub{ + status = "okay"; +}; + +&pcie_x8_rc { + plat-fpga; + status = "disabled"; +}; + +&pcie_x4_rc { + plat-fpga; + reset-gpios = <&s5_gpio0 7 GPIO_ACTIVE_HIGH>; + /*wake-gpios = <&s5_gpio0 7 GPIO_ACTIVE_HIGH>;*/ + /*reset-gpio = <&s5_gpio0 7 GPIO_ACTIVE_LOW>;*/ + status = "disabled"; +}; + +&pcie_x2_rc { + plat-fpga; + status = "disabled"; +}; + +&pcie_x1_1_rc { + plat-fpga; + status = "disabled"; +}; + +&pcie_x1_0_rc { + plat-fpga; + status = "disabled"; +}; + +&ramoops { + status = "okay"; +}; + +&watchdog { + status = "disabled"; +}; + +&cix_dst { + status = "okay"; +}; + +&ap_adapter { + status = "okay"; +}; + +&mntndump { + status = "okay"; +}; + +&vpu { + status = "okay"; +}; + +&npu { + status = "okay"; +}; + +&fch_gpio0 { + status = "okay"; +}; + +&fch_gpio3 { + status = "okay"; +}; + +&s5_gpio0 { + status = "okay"; +}; + +&i2c2 { + status = "okay"; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + pinctrl-1 = <&pinctrl_fch_i2c2_gpio>; + scl-gpios = <&fch_gpio0 12 GPIO_ACTIVE_HIGH>; + sda-gpios = <&fch_gpio0 13 GPIO_ACTIVE_HIGH>; + mmc5633: mmc5633@30 { + compatible = "mmc,mmc5633"; + reg = <0x30>; + }; + + alc5682: codec@1a { + compatible = "realtek,rt5682s"; + #sound-dai-cells = <0>; + status = "disabled"; + reg = <0x1a>; + + interrupt-parent = <&s5_gpio0>; + interrupts = <31 IRQ_TYPE_LEVEL_LOW>; + + realtek,jd-src = <1>; + }; +}; + +&i3c_apb_clk{ + clock-frequency = <5000000>; +}; + +&i3c_sys_clk{ + clock-frequency = <5000000>; +}; + +&i3c0{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c0>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + + mmc5633_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&i3c1{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c1>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + + 24c08@50 { + status = "disabled"; + compatible = "eeprom"; + reg = <0x50 0 0x0>; + }; + 24c08@51 { + status = "disabled"; + compatible = "eeprom"; + reg = <0x51 0 0x0>; + }; + 24c08@52 { + status = "disabled"; + compatible = "eeprom"; + reg = <0x52 0 0x0>; + }; + 24c08@53{ + status = "disabled"; + compatible = "eeprom"; + reg = <0x53 0 0x0>; + }; +}; + +&sf_i3c0{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i3c0>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + + mmc5633c_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c0@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&mbox_ap2pm { + status = "okay"; +}; + +&mbox_pm2ap { + status = "okay"; +}; + +&ap2pm_scmi_mem { + status = "okay"; +}; + +&pm2ap_scmi_mem { + status = "okay"; +}; + +&ap_tfa_scmi_mem { + status = "okay"; +}; + +&ap_to_pm_scmi { + status = "okay"; +}; + +&ap_to_tfa_scmi { + status = "okay"; +}; + +&thermal_zones { + cpu-m1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M1_TEMP_SENSOR_ID>; + + trips { + m1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B1_TEMP_SENSOR_ID>; + + trips { + b1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-m0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + + trips { + m0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B0_TEMP_SENSOR_ID>; + + trips { + b0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin-pwm.dts b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin-pwm.dts new file mode 100644 index 000000000000..d1a99c77b051 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin-pwm.dts @@ -0,0 +1,94 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-orangepi-6-plus.dts" + +&iomuxc_s5 { + pinctrl_hog_s5: pinctrl_hog_s5 { + sky1,pins = < + CIX_PAD_GPIO014_FUNC_GPIO014 (PULL_UP|DS_LEVEL4) /* GPIO14 hp det */ + CIX_PAD_GPIO040_FUNC_GPIO040 (PULL_UP|DS_LEVEL4) /* GPIO40 */ + >; + }; +}; + +&iomuxc { + pinctrl_hog: pinctrl_hog { + sky1,pins = < + CIX_PAD_GPIO144_FUNC_GPIO144 (PULL_DOWN|DS_LEVEL4) /* GPIO144 pdb0 */ + CIX_PAD_GPIO145_FUNC_GPIO145 (PULL_DOWN|DS_LEVEL4) /* GPIO145 pdb1 */ + CIX_PAD_GPIO146_FUNC_GPIO146 (PULL_DOWN|DS_LEVEL4) /* GPIO146 pdb2 */ + CIX_PAD_GPIO147_FUNC_GPIO147 (PULL_DOWN|DS_LEVEL4) /* GPIO147 pdb3 */ + >; + }; +}; + +//40pin +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; +}; + +//40pin +&i2c4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; +}; + +//40pin +&i2c5 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; +}; + +//40pin +&uart1{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart1>; + dmas = <&fch_dmac 2 4>, <&fch_dmac 3 5>; + dma-names = "tx","rx"; +}; + +//40pin +&uart3{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart3>; + dmas = <&fch_dmac 6 6>, <&fch_dmac 7 7>; + dma-names = "tx","rx"; +}; + +//40pin +&spi0{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + /* Character device nodes for device communication on CS0(/dev/spidev0.0) */ + spidev0_0:spi@0_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev0.1) */ + spidev0_1:spi@0_1{ + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +//40pin 04113000 +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm3>; + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin.dts b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin.dts new file mode 100644 index 000000000000..c1adddbec394 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus-40pin.dts @@ -0,0 +1,94 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-orangepi-6-plus.dts" + +&iomuxc_s5 { + pinctrl_hog_s5: pinctrl_hog_s5 { + sky1,pins = < + CIX_PAD_GPIO014_FUNC_GPIO014 (PULL_UP|DS_LEVEL4) /* GPIO14 hp det */ + CIX_PAD_GPIO040_FUNC_GPIO040 (PULL_UP|DS_LEVEL4) /* GPIO40 */ + >; + }; +}; + +&iomuxc { + pinctrl_hog: pinctrl_hog { + sky1,pins = < + CIX_PAD_GPIO144_FUNC_GPIO144 (PULL_DOWN|DS_LEVEL4) /* GPIO144 pdb0 */ + CIX_PAD_GPIO145_FUNC_GPIO145 (PULL_DOWN|DS_LEVEL4) /* GPIO145 pdb1 */ + CIX_PAD_GPIO146_FUNC_GPIO146 (PULL_DOWN|DS_LEVEL4) /* GPIO146 pdb2 */ + CIX_PAD_GPIO147_FUNC_GPIO147 (PULL_DOWN|DS_LEVEL4) /* GPIO147 pdb3 */ + >; + }; +}; + +//40pin +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; +}; + +//40pin +&i2c4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; +}; + +//40pin +&i2c5 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; +}; + +//40pin +&uart1{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart1>; + dmas = <&fch_dmac 2 4>, <&fch_dmac 3 5>; + dma-names = "tx","rx"; +}; + +//40pin +&uart3{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart3>; + dmas = <&fch_dmac 6 6>, <&fch_dmac 7 7>; + dma-names = "tx","rx"; +}; + +//40pin +&spi0{ + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + /* Character device nodes for device communication on CS0(/dev/spidev0.0) */ + spidev0_0:spi@0_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev0.1) */ + spidev0_1:spi@0_1{ + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +//40pin 04113000 +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm3>; + status = "disabled"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dts b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dts new file mode 100644 index 000000000000..6de55ce69c13 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dts @@ -0,0 +1,2311 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * Copyright (c) 2024, Radxa Computer (Shenzhen) Co., Ltd. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-orangepi-6-plus.dtsi" + +/delete-node/ ®_definition; +/ { + model = "Orange Pi 6 Plus"; + compatible = "cix,sky1"; + + chosen { + stdout-path = &uart2; + }; + + alc269_codec: alc269_codec { + compatible = "realtek,alc269"; + #sound-dai-cells = <0>; + status = "okay"; + }; + + sound: sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "okay"; + + hda: hda { + status = "okay"; + + cpu { + sound-dai = <&ipb_hda>; + }; + + codec { + sound-dai = <&alc269_codec>; + }; + }; + + bt_audio { + status = "disabled"; + + format = "dsp_a"; + dai-tdm-slot-tx-mask = <1>; + dai-tdm-slot-rx-mask = <1>; + dai-tdm-slot-num = <1>; + dai-tdm-slot-width = <16>; + + cpu { + sound-dai = <&i2s1>; + }; + }; + + dptx0_audio: dptx0_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s5 0>; + }; + + codec { + sound-dai = <&dp0>; + }; + }; + + dptx1_audio: dptx1_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s6 0>; + }; + + codec { + sound-dai = <&dp1>; + }; + }; + + dptx2_audio: dptx2_audio { + status = "disabled"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s7 0>; + }; + + codec { + sound-dai = <&dp2>; + }; + }; + + dptx3_audio: dptx3_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s8 0>; + }; + + codec { + sound-dai = <&dp3>; + }; + }; + + dptx4_audio: dptx4_audio { + status = "okay"; + + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s9 0>; + }; + + codec { + sound-dai = <&dp4>; + }; + }; + }; + + dp2_backlight: dp2_backlight { + compatible = "pwm-backlight"; + enable-gpios = <&fch_gpio3 15 GPIO_ACTIVE_HIGH>; + pwms = <&pwm0 0 100000>; + status = "okay"; + + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + + }; + + panel_edp0: panel_edp0 { + status = "okay"; + compatible = "cix-edp-panel"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_edp0>; + backlight = <&dp2_backlight>; + prepare-delay-ms = <120>; + enable-delay-ms = <120>; + unprepare-delay-ms = <500>; + disable-delay-ms = <120>; + width-mm = <129>; + height-mm = <171>; + enable-gpios = <&fch_gpio3 16 GPIO_ACTIVE_HIGH>; + }; + + vdd_1v8_pcie_x4_rc: regulator-vdd-1v8-pcie-x4-rc { + compatible = "regulator-fixed"; + regulator-name = "VDD_1V8_PCIE_X4_RC"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x4_rc_power>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&s5_gpio0 11 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-boot-on; + regulator-always-on; + status = "okay"; + }; + + vdd_1v8_pcie_x8_rc: regulator-vdd-1v8-pcie-x8-rc { + compatible = "regulator-fixed"; + regulator-name = "VDD_1V8_PCIE_X8_RC"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x8_rc_power>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&s5_gpio0 8 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-boot-on; + regulator-always-on; + status = "okay"; + }; + + vdd_1v8_pcie_x1_0_rc: regulator-vdd-1v8-pcie-x1-0-rc { + compatible = "regulator-fixed"; + regulator-name = "VDD_1V8_PCIE_WIFI"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_0_rc_power>; + regulator-min-microvolt = <1800000>; + regulator-max-microvolt = <1800000>; + gpio = <&s5_gpio0 12 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-boot-on; + regulator-always-on; + status = "okay"; + }; + + gpio-leds { + compatible = "gpio-leds"; + pinctrl-names = "default"; + status = "okay"; + + power-led { + gpios = <&ec_gpio 1 GPIO_ACTIVE_HIGH>; + linux,default-trigger = "default-on"; + //linux,default-trigger = "heartbeat"; + }; + }; +}; + +&fch_gpio0 { + status = "okay"; +}; + +&fch_gpio1 { + status = "okay"; +}; + +&fch_gpio2 { + status = "okay"; +}; + +&fch_gpio3 { + status = "okay"; +}; + +&s5_gpio0 { + status = "okay"; +}; + +&s5_gpio1 { + status = "okay"; +}; + +&s5_gpio2 { + status = "okay"; +}; + +&hwclock { + status = "okay"; +}; + +&iomuxc_s5 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_s5>; + pinctrl_hog_s5: pinctrl_hog_s5 { + sky1,pins = < + CIX_PAD_GPIO014_FUNC_GPIO014 (PULL_UP|DS_LEVEL4) /* GPIO14 hp det */ + CIX_PAD_GPIO040_FUNC_GPIO040 (PULL_UP|DS_LEVEL4) /* GPIO40 */ + + CIX_PAD_SFI_GPIO0_FUNC_GPIO015 (PULL_UP|DS_LEVEL4) /* 40pin - 11 */ + CIX_PAD_SFI_GPIO2_FUNC_GPIO017 (PULL_UP|DS_LEVEL4) /* 40pin - 12 */ + CIX_PAD_SFI_GPIO1_FUNC_GPIO016 (PULL_UP|DS_LEVEL4) /* 40pin - 13 */ + CIX_PAD_GPIO018_FUNC_GPIO018 (PULL_UP|DS_LEVEL4) /* 40pin - 18 */ + CIX_PAD_SPI1_MOSI_FUNC_GPIO028 (PULL_UP|DS_LEVEL4) /* 40pin - 19 */ + CIX_PAD_SPI1_MISO_FUNC_GPIO025 (PULL_UP|DS_LEVEL4) /* 40pin - 21 */ + CIX_PAD_GPIO019_FUNC_GPIO019 (PULL_UP|DS_LEVEL4) /* 40pin - 22 */ + CIX_PAD_SPI1_CLK_FUNC_GPIO029 (PULL_UP|DS_LEVEL4) /* 40pin - 23 */ + CIX_PAD_SPI1_CS0_FUNC_GPIO026 (PULL_UP|DS_LEVEL4) /* 40pin - 24 */ + CIX_PAD_SPI1_CS1_FUNC_GPIO027 (PULL_UP|DS_LEVEL4) /* 40pin - 26 */ + CIX_PAD_SPI1_CLK_FUNC_GPIO029 (PULL_UP|DS_LEVEL4) /* 40pin - 29 */ + CIX_PAD_GPIO023_FUNC_GPIO023 (PULL_UP|DS_LEVEL4) /* 40pin - 31 */ + CIX_PAD_GPIO021_FUNC_GPIO021 (PULL_UP|DS_LEVEL4) /* 40pin - 32 */ + CIX_PAD_GPIO024_FUNC_GPIO024 (PULL_UP|DS_LEVEL4) /* 40pin - 33 */ + CIX_PAD_GPIO022_FUNC_GPIO022 (PULL_UP|DS_LEVEL4) /* 40pin - 36 */ + >; + }; + + pinctrl_sfi_i2c0: pinctrl_sfi_i2c0_grp { + sky1,pins = < + CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I2C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I2C0_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_sfi_i2c1: pinctrl_sfi_i2c1_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I2C1_SCL (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I2C1_SDA (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_sfi_i3c0: pinctrl_sfi_i3c0_grp { + sky1,pins = < + CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I3C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I3C0_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO023_FUNC_SFI_I3C0_PUR_EN_L (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_sfi_i3c1: pinctrl_sfi_i3c1_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I3C1_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I3C1_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO024_FUNC_SFI_I3C1_PUR_EN_L (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_sfi_spi: pinctrl_sfi_spi_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_SPI_CS0 (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_SPI_CS1 (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO0_FUNC_SFI_SPI_SCK (ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO1_FUNC_SFI_SPI_MOSI (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO2_FUNC_SFI_SPI_MISO (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_spi0: pinctrl_fch_spi0_grp { + sky1,pins = < + CIX_PAD_SPI1_MISO_FUNC_SPI1_MISO (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CS0_FUNC_SPI1_CS0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CS1_FUNC_SPI1_CS1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_MOSI_FUNC_SPI1_MOSI (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CLK_FUNC_SPI1_CLK (ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_xspi: pinctrl_fch_xspi_grp { + sky1,pins = < + CIX_PAD_SE_QSPI_CLK_FUNC_QSPI_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_CS_L_FUNC_QSPI_CS_L (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA0_FUNC_QSPI_DATA0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA1_FUNC_QSPI_DATA1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA2_FUNC_QSPI_DATA2 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA3_FUNC_QSPI_DATA3 (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_usb0: pinctrl_usb0_oc_grp { + sky1,pins = < + CIX_PAD_GPIO036_FUNC_GPIO036 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb1: pinctrl_usb1_oc_grp { + sky1,pins = < + CIX_PAD_GPIO037_FUNC_GPIO037 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb4: pinctrl_usb4_grp { + sky1,pins = < + CIX_PAD_GPIO034_FUNC_GPIO034 (PULL_UP|DS_LEVEL4) + CIX_PAD_GPIO041_FUNC_USB_DRIVE_VBUS4 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_usb5: pinctrl_usb5_grp { + sky1,pins = < + CIX_PAD_GPIO035_FUNC_GPIO035 (PULL_UP|DS_LEVEL4) + CIX_PAD_GPIO042_FUNC_USB_DRIVE_VBUS5 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_usb6: pinctrl_usb6_oc_grp { + sky1,pins = < + CIX_PAD_GPIO030_FUNC_GPIO030 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb7: pinctrl_usb7_oc_grp { + sky1,pins = < + CIX_PAD_GPIO031_FUNC_GPIO031 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb8: pinctrl_usb8_oc_grp { + sky1,pins = < + CIX_PAD_GPIO032_FUNC_GPIO032 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb9: pinctrl_usb9_oc_grp { + sky1,pins = < + CIX_PAD_GPIO033_FUNC_GPIO033 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x8_rc_power: pinctrl_pcie_x8_rc_power { + sky1,pins = < + CIX_PAD_GPIO009_FUNC_GPIO009 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x8_rc: pinctrl_pcie_x8_rc { + sky1,pins = < + CIX_PAD_GPIO002_FUNC_GPIO002 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x4_rc_power: pinctrl_pcie_x4_rc_power { + sky1,pins = < + CIX_PAD_GPIO012_FUNC_GPIO012 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x4_rc: pinctrl_pcie_x4_rc { + sky1,pins = < + CIX_PAD_GPIO004_FUNC_GPIO004 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x2_rc: pinctrl_pcie_x2_rc { + sky1,pins = < + CIX_PAD_GPIO003_FUNC_GPIO003 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x1_1_rc: pinctrl_pcie_x1_1_rc {/*x1_1*/ + sky1,pins = < + CIX_PAD_GPIO006_FUNC_GPIO006 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x1_0_rc_power: pinctrl_pcie_x1_0_rc_power { + sky1,pins = < + CIX_PAD_GPIO013_FUNC_GPIO013 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x1_0_rc: pinctrl_pcie_x1_0_rc {/*x1_0*/ + sky1,pins = < + CIX_PAD_GPIO005_FUNC_GPIO005 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_ra8900ce_irq: pinctrl_ra8900ce_irq { + sky1,pins = < + CIX_PAD_GPIO011_FUNC_GPIO011 (PULL_UP|DS_LEVEL4) /* GPIO011 - S5_gpio0 10 */ + >; + }; + + pinctrl_hiddev_68_irq: pinctrl_hiddev_68_irq { + sky1,pins = < + CIX_PAD_GPIO010_FUNC_GPIO010 (PULL_UP|DS_LEVEL4) /* GPIO010 - S5_gpio0 9 */ + >; + }; + + pinctrl_hiddev_15_irq: pinctrl_hiddev_15_irq { + sky1,pins = < + CIX_PAD_GPIO010_FUNC_GPIO010 (PULL_UP|DS_LEVEL4) /* GPIO010 - S5_gpio0 9 */ + >; + }; +}; + +&iomuxc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: pinctrl_hog { + sky1,pins = < + CIX_PAD_GPIO144_FUNC_GPIO144 (PULL_DOWN|DS_LEVEL4) /* GPIO144 pdb0 */ + CIX_PAD_GPIO145_FUNC_GPIO145 (PULL_DOWN|DS_LEVEL4) /* GPIO145 pdb1 */ + CIX_PAD_GPIO146_FUNC_GPIO146 (PULL_DOWN|DS_LEVEL4) /* GPIO146 pdb2 */ + CIX_PAD_GPIO147_FUNC_GPIO147 (PULL_DOWN|DS_LEVEL4) /* GPIO147 pdb3 */ + + CIX_PAD_I2C2_SDA_FUNC_GPIO056 (PULL_UP|DS_LEVEL4) /* 40pin - 3 */ + CIX_PAD_I2C2_SCL_FUNC_GPIO055 (PULL_UP|DS_LEVEL4) /* 40pin - 5 */ + CIX_PAD_UART3_TXD_FUNC_GPIO105 (PULL_UP|DS_LEVEL4) /* 40pin - 8 */ + CIX_PAD_UART3_RXD_FUNC_GPIO106 (PULL_UP|DS_LEVEL4) /* 40pin - 10 */ + CIX_PAD_UART1_TXD_FUNC_GPIO099 (PULL_UP|DS_LEVEL4) /* 40pin - 15 */ + CIX_PAD_UART1_RXD_FUNC_GPIO100 (PULL_UP|DS_LEVEL4) /* 40pin - 16 */ + CIX_PAD_I2C5_SDA_FUNC_GPIO048 (PULL_UP|DS_LEVEL4) /* 40pin - 27 */ + CIX_PAD_I2C5_SCL_FUNC_GPIO047 (PULL_UP|DS_LEVEL4) /* 40pin - 28 */ + CIX_PAD_GPIO057_FUNC_GPIO057 (PULL_UP|DS_LEVEL4) /* 40pin - 35 */ + CIX_PAD_GPIO060_FUNC_GPIO060 (PULL_UP|DS_LEVEL4) /* 40pin - 37 */ + CIX_PAD_I2C4_CLK_FUNC_GPIO061 (PULL_UP|DS_LEVEL4) /* 40pin - 38 */ + CIX_PAD_I2C4_SDA_FUNC_GPIO062 (PULL_UP|DS_LEVEL4) /* 40pin - 40 */ + >; + }; + + pinctrl_dp_to_hdmi_ps185: pinctrl_dp_to_hdmi_ps185 { + sky1,pins = < + CIX_PAD_I2S2_TWS_FUNC_GPIO074 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_fch_pwm0: pinctrl_fch_pwm0 { + sky1,pins = < + CIX_PAD_DP2_VARY_BL_FUNC_DP2_VARY_BL (DS_LEVEL7) + >; + }; + + pinctrl_fch_pwm2: pinctrl_fch_pwm2 { + sky1,pins = < + CIX_PAD_UART0_RXD_FUNC_PWM1 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_pwm3: pinctrl_fch_pwm3 { + sky1,pins = < + CIX_PAD_UART1_TXD_FUNC_FAN_OUT0 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_gmac0: pinctrl_gmac0 { + sky1,pins = + /* rfclk_25M */ + , + /* txc_trl */ + , + /* txd0 */ + , + /* txd1 */ + , + /* txd2 */ + , + /* txd3 */ + , + /* tx_clk */ + , + /* rx_ctl */ + , + + /* rxd0 */ + , + /* rxd1 */ + , + /* rxd2 */ + , + /* rxd3 */ + , + /* rx_clk */ + , + /* mdc */ + , + /* mdio */ + ; + }; + + pinctrl_gmac1: pinctrl_gmac1 { + sky1,pins = + /* rfclk_25M */ + , + /* txc_trl */ + , + /* txd0 */ + , + /* txd1 */ + , + /* txd2 */ + , + /* txd3 */ + , + /* tx_clk */ + , + /* rx_ctl */ + , + /* rxd0 */ + , + /* rxd1 */ + , + /* rxd2 */ + , + /* rxd3 */ + , + /* rx_clk */ + , + /* mdc */ + , + /* mdio */ + ; + }; + + pinctrl_fch_fan0: pinctrl_fch_fan0 { + sky1,pins = < + CIX_PAD_UART1_TXD_FUNC_FAN_OUT0 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_fan1: pinctrl_fch_fan1 { + sky1,pins = < + CIX_PAD_UART1_CTS_FUNC_FAN_OUT1 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_fan2: pinctrl_fch_fan2 { + sky1,pins = < + CIX_PAD_UART0_CTS_FUNC_FAN_OUT2 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c0: pinctrl_fch_i2c0 { + sky1,pins = < + CIX_PAD_I2C0_CLK_FUNC_I2C0_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C0_SDA_FUNC_I2C0_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c1: pinctrl_fch_i2c1 { + sky1,pins = < + CIX_PAD_I2C1_CLK_FUNC_I2C1_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C1_SDA_FUNC_I2C1_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c2: pinctrl_fch_i2c2 { + sky1,pins = < + CIX_PAD_I2C2_SCL_FUNC_I2C2_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C2_SDA_FUNC_I2C2_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i2c3: pinctrl_fch_i2c3 { + sky1,pins = < + CIX_PAD_I2C3_CLK_FUNC_I2C3_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C3_SDA_FUNC_I2C3_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i2c4: pinctrl_fch_i2c4 { + sky1,pins = < + CIX_PAD_I2C4_CLK_FUNC_I2C4_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C4_SDA_FUNC_I2C4_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c5: pinctrl_fch_i2c5 { + sky1,pins = < + CIX_PAD_I2C5_SCL_FUNC_I2C5_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C5_SDA_FUNC_I2C5_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c6: pinctrl_fch_i2c6 { + sky1,pins = < + CIX_PAD_I2C6_SCL_FUNC_I2C6_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C6_SDA_FUNC_I2C6_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c7: pinctrl_fch_i2c7 { + sky1,pins = < + CIX_PAD_I2C7_SCL_FUNC_I2C7_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C7_SDA_FUNC_I2C7_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i3c0: pinctrl_fch_i3c0 { + sky1,pins = < + CIX_PAD_I2C2_SCL_FUNC_I3C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C2_SDA_FUNC_I3C0_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO057_FUNC_I3C0_PUR_EN_L (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i3c1: pinctrl_fch_i3c1 { + sky1,pins = < + CIX_PAD_I2C3_CLK_FUNC_I3C1_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C3_SDA_FUNC_I3C1_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO060_FUNC_I3C1_PUR_EN_L (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_uart0: pinctrl_fch_uart0 { + sky1,pins = < + CIX_PAD_UART0_TXD_FUNC_UART0_TXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_RXD_FUNC_UART0_RXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_CTS_FUNC_UART0_CTS (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_RTS_FUNC_UART0_RTS (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart1: pinctrl_fch_uart1 { + sky1,pins = < + CIX_PAD_UART1_TXD_FUNC_UART1_TXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART1_RXD_FUNC_UART1_RXD (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart2: pinctrl_fch_uart2 { + sky1,pins = < + CIX_PAD_UART2_TXD_FUNC_UART2_TXD (PULL_UP|DS_LEVEL7) + CIX_PAD_UART2_RXD_FUNC_UART2_RXD (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart3: pinctrl_fch_uart3 { + sky1,pins = < + CIX_PAD_UART3_TXD_FUNC_UART3_TXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART3_RXD_FUNC_UART3_RXD (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_hda: pinctrl_hda_grp { + sky1,pins = < + CIX_PAD_HDA_BITCLK_FUNC_HDA_BITCLK (PULL_DOWN|ST|DS_LEVEL12) /* hda bitclk */ + CIX_PAD_HDA_RST_L_FUNC_HDA_RST_L (PULL_DOWN|ST|DS_LEVEL12) /* hda rst */ + CIX_PAD_HDA_SDIN0_FUNC_HDA_SDIN0 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdin0 */ + CIX_PAD_HDA_SDOUT0_FUNC_HDA_SDOUT0 (PULL_UP|ST|DS_LEVEL12) /* hda sdout0 */ + CIX_PAD_HDA_SYNC_FUNC_HDA_SYNC (PULL_UP|ST|DS_LEVEL12) /* hda sync */ + >; + }; + + pinctrl_substrate_i2s0: pinctrl_substrate_i2s0 { + sky1,pins = < + /* I2S0_SCK */ + CIX_PAD_HDA_BITCLK_FUNC_I2S0_SCK (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_DATA_IN */ + CIX_PAD_HDA_RST_L_FUNC_I2S0_DATA_IN (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_MCLK */ + CIX_PAD_HDA_SDIN0_FUNC_I2S0_MCLK (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_DATA_OUT */ + + CIX_PAD_HDA_SDOUT0_FUNC_I2S0_DATA_OUT (PULL_UP|ST|DS_LEVEL12) + /* I2S0_WS */ + CIX_PAD_HDA_SYNC_FUNC_I2S0_WS (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_substrate_i2s1: pinctrl_substrate_i2s1 { + sky1,pins = < + CIX_PAD_I2S1_MCLK_FUNC_I2S1_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_mclk */ + CIX_PAD_I2S1_SCK_FUNC_I2S1_SCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_sck */ + CIX_PAD_I2S1_WS_FUNC_I2S1_WS (PULL_UP|ST|DS_LEVEL12) /* i2s1_ws */ + CIX_PAD_I2S1_DATA_IN_FUNC_I2S1_DATA_IN (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_data_in */ + CIX_PAD_I2S1_DATA_OUT_FUNC_I2S1_DATA_OUT (PULL_UP|ST|DS_LEVEL12) /* i2s1_data_out */ + >; + }; + + pinctrl_substrate_i2s2: pinctrl_substrate_i2s2 { + sky1,pins = < + CIX_PAD_I2S2_MCLK_FUNC_I2S2_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_mclk */ + CIX_PAD_I2S2_RSCK_FUNC_I2S2_RSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_rsck */ + CIX_PAD_I2S2_RWS_FUNC_I2S2_RWS (PULL_UP|ST|DS_LEVEL12) /* i2s2_rws */ + CIX_PAD_I2S2_TSCK_FUNC_I2S2_TSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_tsck */ + CIX_PAD_I2S2_TWS_FUNC_I2S2_TWS (PULL_UP|ST|DS_LEVEL12) /* i2s2_tws */ + CIX_PAD_I2S2_DATA_IN0_FUNC_I2S2_DATA_IN0 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_in0 */ + CIX_PAD_I2S2_DATA_IN1_FUNC_I2S2_DATA_IN1 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_in1 */ + CIX_PAD_I2S2_DATA_OUT0_FUNC_I2S2_DATA_OUT0 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out0 */ + CIX_PAD_I2S2_DATA_OUT1_FUNC_I2S2_DATA_OUT1 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out1 */ + CIX_PAD_I2S2_DATA_OUT2_FUNC_I2S2_DATA_OUT2 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out2 */ + CIX_PAD_I2S2_DATA_OUT3_FUNC_I2S2_DATA_OUT3 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out3 */ + >; + }; + + pinctrl_substrate_i2s3: pinctrl_substrate_i2s3 { + sky1,pins = < + CIX_PAD_I2S3_MCLK_FUNC_I2S3_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_mclk */ + CIX_PAD_I2S3_RSCK_FUNC_I2S3_RSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_rsck */ + CIX_PAD_I2S3_RWS_FUNC_I2S3_RWS (PULL_UP|ST|DS_LEVEL12) /* i2s3_rws */ + CIX_PAD_I2S3_TSCK_FUNC_I2S3_TSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_tsck */ + CIX_PAD_I2S3_TWS_FUNC_I2S3_TWS (PULL_UP|ST|DS_LEVEL12) /* i2s3_tws */ + CIX_PAD_I2S3_DATA_IN0_FUNC_I2S3_DATA_IN0 (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_data_in0 */ + CIX_PAD_I2S3_DATA_IN1_FUNC_I2S3_DATA_IN1 (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_data_in1 */ + CIX_PAD_I2S3_DATA_OUT0_FUNC_I2S3_DATA_OUT0 (PULL_UP|ST|DS_LEVEL12) /* i2s3_data_out0 */ + CIX_PAD_I2S3_DATA_OUT1_FUNC_I2S3_DATA_OUT1 (PULL_UP|ST|DS_LEVEL12) /* i2s3_data_out1 */ + >; + }; + + pinctrl_substrate_i2s4_lb: pinctrl_substrate_i2s4_lb { + sky1,pins = < + CIX_PAD_GPIO090_FUNC_I2S4_MCLK_LB (ST|DS_LEVEL12) /* i2s4_mclk_lb */ + CIX_PAD_GPIO091_FUNC_I2S4_SCK_LB (ST|DS_LEVEL12) /* i2s4_sck_lb */ + CIX_PAD_GPIO092_FUNC_I2S4_WS_LB (ST|DS_LEVEL12) /* i2s4_ws_lb */ + CIX_PAD_GPIO093_FUNC_I2S4_DATA_IN_LB (ST|DS_LEVEL12) /* i2s4_data_in_lb */ + CIX_PAD_GPIO094_FUNC_I2S4_DATA_OUT_LB (ST|DS_LEVEL12) /* i2s4_data_out_lb */ + >; + }; + + pinctrl_alc5682_irq: pinctrl_alc5682_irq { + sky1,pins = < + /* GPIO149 */ + CIX_PAD_GPIO149_FUNC_GPIO149 (ST|DS_LEVEL12) + >; + }; + + pinctrl_edp0: pinctrl_edp0 { + sky1,pins = < + CIX_PAD_DP2_DIGON_FUNC_DP2_DIGON (PULL_DOWN|DS_LEVEL4) /* DP2_DIGON */ + CIX_PAD_DP2_BLON_FUNC_DP2_BLON (PULL_DOWN|DS_LEVEL4) /* DP2_BLON */ + CIX_PAD_GPIO136_FUNC_GPIO136 (PULL_UP|DS_LEVEL4) /* TOUCH INT */ + >; + }; + + pinctrl_cam0_hw: pinctrl_cam0_hw { + sky1,pins = < + CIX_PAD_CSI0_MCLK0_FUNC_CSI0_MCLK0 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_IN1_FUNC_GPIO087 (ST|DS_LEVEL12) + CIX_PAD_GPIO090_FUNC_GPIO090 (ST|DS_LEVEL12) + >; + }; + + pinctrl_cam1_hw: pinctrl_cam1_hw { + sky1,pins = < + CIX_PAD_CSI0_MCLK1_FUNC_CSI0_MCLK1 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_GPIO092_FUNC_GPIO092 (ST|DS_LEVEL12) + CIX_PAD_GPIO094_FUNC_GPIO094 (ST|DS_LEVEL12) + >; + }; + + pinctrl_cam2_hw: pinctrl_cam2_hw { + sky1,pins = < + CIX_PAD_CSI1_MCLK0_FUNC_CSI1_MCLK0 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_IN0_FUNC_GPIO086 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_RSCK_FUNC_GPIO082 (PULL_DOWN|ST|DS_LEVEL12) + >; + }; + + pinctrl_cam3_hw: pinctrl_cam3_hw { + sky1,pins = < + CIX_PAD_CSI1_MCLK1_FUNC_CSI1_MCLK1 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_OUT0_FUNC_GPIO088 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_OUT1_FUNC_GPIO089 (PULL_DOWN|ST|DS_LEVEL12) + >; + }; + + pinctrl_lt7911_hw: pinctrl_lt7911_hw { + sky1,pins = < + CIX_PAD_I2S3_DATA_IN1_FUNC_GPIO087 (DS_LEVEL12) //cam0 reset + CIX_PAD_GPIO090_FUNC_GPIO090 (DS_LEVEL12) //cam0 pwdn + CIX_PAD_GPIO091_FUNC_GPIO091 (DS_LEVEL12) //cam0 pwen + CIX_PAD_GPIO093_FUNC_GPIO093 (ST|DS_LEVEL12) //cam1_pwen + >; + }; +}; + +&pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm0>; + status = "okay"; +}; + +&pwm1 { + status = "disabled"; +}; + +//pwm2@04112000 +&pwm2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm2>; + status = "disabled"; +}; + +&hifi5 { + status = "okay"; +}; + +&mbox_dsp2ap { + status = "okay"; +}; + +&mbox_ap2dsp { + status = "okay"; +}; + +&audss_cru { + status = "okay"; +}; + +&audss_clk { + status = "okay"; +}; + +&audss_rst { + status = "okay"; +}; + +&audss_dmac { + memory-region = <&audio_alsa>; + status = "okay"; +}; + +&i2s0 { + /* i2s_sc0 for codec */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s0>; + dmas = <&audss_dmac 0 0xff>, <&audss_dmac 1 0xff>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s1 { + /* i2s_sc1 for 5G/BT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s1>; + dmas = <&audss_dmac 2 0xff>, <&audss_dmac 3 0xff>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s2 { + /* i2s_sc2 for loopback */ + dmas = <&audss_dmac 4 0xff>, <&audss_dmac 5 0xff>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s3 { + /* i2s_mc2a for speaker */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s2>; + dmas = <&audss_dmac 6 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <0x3c>; /* 0x3c, pin2-pin5 works as transmitter */ + status = "disabled"; +}; + +&i2s4 { + /* i2s_mc2b for dp-in */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s3>; + dmas = <&audss_dmac 9 0xff>; + dma-names = "rx"; + cdns,pin-rx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as receiver */ + cdns,pin-tx-mask = /bits/ 8 <0x00>; + status = "disabled"; +}; + +&i2s5 { + /* i2s_mc5a for dp-out */ + dmas = <&audss_dmac 10 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s6 { + /* i2s_mc5b for dp-out */ + dmas = <&audss_dmac 12 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s7 { + /* i2s_mc5c for dp-out */ + dmas = <&audss_dmac 14 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s8 { + /* i2s_mc5d for dp-out */ + dmas = <&audss_dmac 16 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s9 { + /* i2s_mc5e for dp-out */ + dmas = <&audss_dmac 18 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&ipb_hda { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hda>; + //pdb-gpios = <&fch_gpio3 5 GPIO_ACTIVE_HIGH>; + memory-region = <&audio_alsa>; + status = "okay"; +}; + +&sensorhub { + memory-region = <&sfh_vdev0buffer>, <&sfh_vdev0vring0>, + <&sfh_vdev0vring1>, <&sfh_ram>; + cix,auto-boot; + status = "disabled"; +}; + +&sfh_scp { + memory-region = <&sfh_sharebuffer>; + status = "disabled"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart2>; + clock-names = "uartclk", "apb_pclk"; + status = "okay"; +}; + +&dp0 { + status = "okay"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + + dp0_0_in: endpoint { + remote-endpoint = <&dpu0_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp0_1_in: endpoint { + remote-endpoint = <&dpu0_pipe1_out>; + }; + }; + }; +}; + +&dp1 { + status = "okay"; + cix,dp-max-rate = <540000>; + support_d3_cmd = "no"; + + ports { + port@0 { + reg = <0>; + + dp1_0_in: endpoint { + remote-endpoint = <&dpu1_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp1_1_in: endpoint { + remote-endpoint = <&dpu1_pipe1_out>; + }; + }; + }; +}; + +&dp2 { + status = "okay"; + edp-panel = <&panel_edp0>; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + + dp2_0_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp2_1_in: endpoint { + remote-endpoint = <&dpu2_pipe1_out>; + }; + }; + }; +}; + +&dp3 { + status = "okay"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + + dp3_0_in: endpoint { + remote-endpoint = <&dpu3_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp3_1_in: endpoint { + remote-endpoint = <&dpu3_pipe1_out>; + }; + }; + }; +}; + +&dp4 { + status = "okay"; + cix,dp-max-rate = <540000>; + dp_to_hdmi = "yes"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_dp_to_hdmi_ps185>; + pdb-gpios = <&fch_gpio0 31 GPIO_ACTIVE_LOW>; + + ports { + port@0 { + reg = <0>; + + dp4_0_in: endpoint { + remote-endpoint = <&dpu4_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp4_1_in: endpoint { + remote-endpoint = <&dpu4_pipe1_out>; + }; + }; + }; +}; + +&dpu0 { + status = "okay"; + + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu0_pipe0_out: endpoint { + remote-endpoint = <&dp0_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu0_pipe1_out: endpoint { + remote-endpoint = <&dp0_1_in>; + }; + }; + }; +}; + +&dpu1 { + status = "okay"; + + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu1_pipe0_out: endpoint { + remote-endpoint = <&dp1_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu1_pipe1_out: endpoint { + remote-endpoint = <&dp1_1_in>; + }; + }; + }; +}; + +&dpu2 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu2_pipe0_out: endpoint { + remote-endpoint = <&dp2_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu2_pipe1_out: endpoint { + remote-endpoint = <&dp2_1_in>; + }; + }; + }; +}; + +&dpu3 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu3_pipe0_out: endpoint { + remote-endpoint = <&dp3_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu3_pipe1_out: endpoint { + remote-endpoint = <&dp3_1_in>; + }; + }; + }; +}; + +&dpu4 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu4_pipe0_out: endpoint { + remote-endpoint = <&dp4_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu4_pipe1_out: endpoint { + remote-endpoint = <&dp4_1_in>; + }; + }; + }; +}; + +&aeu0 { + status = "disabled"; +}; + +&aeu1 { + status = "disabled"; +}; + +&aeu2 { + status = "disabled"; +}; + +&aeu3 { + status = "disabled"; +}; + +&aeu4 { + status = "disabled"; +}; + +&gmac_rcsu { + status = "disabled"; +}; + +&usbc_phy0 { + orientation-switch; + svid = <0xff01>; + status = "okay"; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy0_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_phy_sw>; + }; + }; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&usbc0_dp_phy { + status = "okay"; +}; + +&sky1_usbss_0 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>; + oc-gpio = <&s5_gpio0 25 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; +}; + +&usbss_0 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + + cdnsp_0_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_role_sw>; + }; + }; +}; + +&usbc_phy1 { + status = "okay"; + orientation-switch; + svid = <0xff01>; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + usbdpphy1_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc1_phy_sw>; + }; + }; +}; + +&usb3_phy1 { + status = "okay"; +}; + +&usbc1_dp_phy { + status = "okay"; +}; + +&sky1_usbss_1 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1>; + oc-gpio = <&s5_gpio0 26 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; +}; + +&usbss_1 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + port { + #address-cells = <1>; + #size-cells = <0>; + cdnsp_1_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc1_role_sw>; + }; + }; +}; + +&usbc_phy2 { + status = "okay"; + default_conf = /bits/ 8 <0x02>; +}; + +&usb3_phy2 { + status = "disabled"; +}; + +&usbc2_dp_phy { + status = "okay"; +}; + +&sky1_usbss_2 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + u3-port-disable; + status = "okay"; +}; + +&usbss_2 { + dr_mode = "host"; + status = "okay"; +}; + +&usbc_phy3 { + status = "okay"; + default_conf = /bits/ 8 <0x02>; +}; + +&usb3_phy3 { + status = "disabled"; +}; + +&usbc3_dp_phy { + status = "okay"; +}; + +&sky1_usbss_3 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + u3-port-disable; + status = "okay"; +}; + +&usbss_3 { + status = "okay"; + dr_mode = "host"; +}; + +&usb3_phy4 { + status = "okay"; +}; + +&usb3_phy4_0 { + status = "okay"; +}; + +&sky1_usbss_4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb4>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_4 { + status = "okay"; + dr_mode = "host"; +}; + +&usb3_phy4_1 { + status = "okay"; +}; + +&sky1_usbss_5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb5>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_5 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb6>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_0 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb7>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_1 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb8>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_2 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb9>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_3 { + status = "okay"; + dr_mode = "host"; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c0>; +}; + +&i2c1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c1>; + clock-frequency = <100000>; +}; + +&i2c2_slave { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + clock-frequency = <1000000>; + status = "disabled"; +}; + +&i2c3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c3>; + + ra8900ce: ra8900ce@32 { + compatible = "rtc,rx8900"; + reg = <0x32>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_ra8900ce_irq>; + interrupt-parent = <&s5_gpio0>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; +}; + +/*EC_HOST*/ +&i2c6 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c6>; + + cros_ec: ec@76 { + compatible = "google,cros-ec-i2c"; + reg = <0x76>; + interrupt-parent = <&s5_gpio0>; + interrupts = <6 IRQ_TYPE_EDGE_RISING>; + wakeup-source; + status = "okay"; + }; +}; + +&cros_ec { + cros_ec_pwm: ec-pwm { + compatible = "google,cros-ec-pwm"; + #pwm-cells = <1>; + status = "okay"; + }; + + cix_fan: pwm-fan { + compatible = "pwm-fan"; + cooling-levels = <0 150 200 255>; + #cooling-cells = <2>; + pwms = <&cros_ec_pwm 0>; + status = "disabled"; + }; + + cix_ec_light { + compatible = "cix,cix-ec-light"; + status = "disabled"; + }; + + cix_ec_lid { + compatible = "cix,cix-ec-lid"; + status = "okay"; + }; + + cix_ec_battery { + compatible = "cix,cix-ec-battery"; + status = "okay"; + }; + + cix_ec_charge { + compatible = "cix,cix-ec-charge"; + status = "okay"; + }; + + cix_ec_kb_backlight{ + compatible = "cix,cix-ec-keyboard-backlight"; + status = "disabled"; + }; + + ec_gpio: cix_ec_gpio { + compatible = "cix,cix-ec-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <104>; + status = "okay"; + }; + + cix_ec_pwrkey { + compatible = "cix,cix-ec-pwrkey"; + status = "okay"; + }; + + cix_ec_excp { + compatible = "cix,cix-ec-excp"; + status = "okay"; + }; + + cix_ec_fan { + compatible = "cix,cix-ec-fan"; + status = "okay"; + }; +}; + +&i2c7 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c7>; + clock-frequency = <100000>; + rts5453_pd0_port0:rts5453@30 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + id = <0>; + reg = <0x30>; + status = "okay"; + usbc_con0 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc0_role_sw: endpoint { + remote-endpoint = <&cdnsp_0_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc0_phy_sw: endpoint { + remote-endpoint = <&usbdpphy0_lane_switch>; + }; + }; + }; + }; + + rts5453_pd0_port1:rts5453@31 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <7 IRQ_TYPE_LEVEL_LOW>; + id = <1>; + reg = <0x31>; + status = "okay"; + usbc_con1 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + port@0 { + reg = <0>; + usbc1_role_sw: endpoint { + remote-endpoint = <&cdnsp_1_role_switch>; + }; + }; + port@1 { + reg = <1>; + usbc1_phy_sw: endpoint { + remote-endpoint = <&usbdpphy1_lane_switch>; + }; + }; + }; + }; +}; + +&sf_i2c0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i2c0>; +}; + +&sf_i2c1 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i2c1>; +}; + +&i3c0{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c0>; + i3c-scl-hz = <100000>; + mmc5633_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&i3c1{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c1>; + i3c-scl-hz = <100000>; + mmc5633_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&sf_i3c0{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i3c0>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + mmc5633c_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c0@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&sf_i3c1{ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i3c1>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + mmc5633c_i3c@30 { + status = "disabled"; + reg = <0x30 0x04a2 0x0000f000>; + assigned-address = <0x36>; + }; + mmc5633_i2c0@30 { + status = "disabled"; + compatible = "mmc,mmc5633"; + reg = <0x30 0x0 0x0>; + }; +}; + +&spi1{ + status = "disabled"; +}; + +&sf_spi{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_spi>; + /* Character device nodes for device communication on CS0(/dev/spidev2.0) */ + spidev2_0:spi@2_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev2.1) */ + spidev2_1:spi@2_1{ + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +&xspi{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_xspi>; + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-max-frequency = <25000000>; + }; +}; + +&uart0{ + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart0>; + dmas = <&fch_dmac 0 2>, <&fch_dmac 1 3>; + dma-names = "tx","rx"; +}; + +&aipu_res_0 { + status = "okay"; +}; + +&npu { + status = "okay"; +}; + +&its_pcie { + status = "okay"; +}; + +&smmu_pciehub{ + status = "disabled"; +}; + +&smmu_mmhub{ + status = "okay"; +}; + +//SSD2 +&pcie_x8_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x8_rc>; + vcc-pcie-supply = <&vdd_1v8_pcie_x8_rc>; + aspm-no-l0s; + reset-gpios = <&s5_gpio0 1 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +//SSD1 +&pcie_x4_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x4_rc>; + vcc-pcie-supply = <&vdd_1v8_pcie_x4_rc>; + aspm-no-l0s; + reset-gpios = <&s5_gpio0 3 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +//5G Ethernet +&pcie_x2_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x2_rc>; + reset-gpios = <&s5_gpio0 2 GPIO_ACTIVE_HIGH>; + num-lanes = <1>; + aspm-no-l0s; + status = "okay"; +}; + +//5G Ethernet +&pcie_x1_1_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_1_rc>; + reset-gpios = <&s5_gpio0 5 GPIO_ACTIVE_HIGH>; + aspm-no-l0s; + status = "okay"; +}; + +//WIFI +&pcie_x1_0_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_0_rc>; + vcc-pcie-supply = <&vdd_1v8_pcie_x1_0_rc>; + reset-gpios = <&s5_gpio0 4 GPIO_ACTIVE_HIGH>; + aspm-no-l0s; + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + +&pcie_x4_phy { + status = "okay"; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie_x8_phy { + num-lanes = <4>; + status = "okay"; +}; + +&pciex211_phy { + status = "okay"; +}; + +&pcie_x1_phy0 { + status = "okay"; +}; + +&pcie_x1_phy1 { + status = "okay"; +}; + +&pcie_x2_phy { + status = "okay"; +}; + +&mbox_ap2pm { + status = "okay"; +}; + +&mbox_pm2ap { + status = "okay"; +}; + +&mbox_se2ap { + status = "okay"; +}; + +&mbox_ap2se { + status = "okay"; +}; + +&sky1_crash { + status = "okay"; +}; + +&ap2pm_scmi_mem { + status = "okay"; +}; + +&pm2ap_scmi_mem { + status = "okay"; +}; + +&ap_tfa_scmi_mem { + status = "okay"; +}; + +&ap_to_pm_scmi { + status = "okay"; +}; + +&ap_to_tfa_scmi { + status = "okay"; +}; + +&scmi_dvfs { + status = "okay"; +}; + +&vpu { + status = "okay"; +}; + +&ramoops { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&cix_dst { + status = "okay"; +}; + +&exception_trace { + status = "okay"; +}; + +&ap_adapter { + status = "okay"; +}; + +&mntndump { + status = "okay"; +}; + +&ddr_ctrl0 { + status = "okay"; +}; + +&ddr_ctrl1 { + status = "okay"; +}; + +&ddr_ctrl2 { + status = "okay"; +}; + +&ddr_ctrl3 { + status = "okay"; +}; + +&cix_pmu_ci700 { + status = "disabled"; +}; + +&cix_pmu_ni700 { + status = "disabled"; +}; + +&cix_bus_ci700 { + status = "disabled"; +}; + +&cix_bus_ni700 { + status = "disabled"; +}; + +&dsu_cache_exception { + status = "okay"; +}; + +&cache_exception_core0 { + status = "okay"; +}; + +&cache_exception_core1 { + status = "okay"; +}; + +&cache_exception_core2 { + status = "okay"; +}; + +&cache_exception_core3 { + status = "okay"; +}; + +&cache_exception_core4 { + status = "okay"; +}; + +&cache_exception_core5 { + status = "okay"; +}; + +&cache_exception_core6 { + status = "okay"; +}; + +&cache_exception_core7 { + status = "okay"; +}; + +&cache_exception_core8 { + status = "okay"; +}; + +&cache_exception_core9 { + status = "okay"; +}; + +&cache_exception_core10 { + status = "okay"; +}; + +&cache_exception_core11 { + status = "okay"; +}; + +//40pin +&i2c2 { + //status = "okay"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; +}; + +//40pin +&i2c4 { + //status = "okay"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; +}; + +//40pin +&i2c5 { + //status = "okay"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; +}; + +//40pin +&uart1{ + //status = "okay"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart1>; + dmas = <&fch_dmac 2 4>, <&fch_dmac 3 5>; + dma-names = "tx","rx"; +}; + +//40pin +&uart3{ + //status = "okay"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart3>; + dmas = <&fch_dmac 6 6>, <&fch_dmac 7 7>; + dma-names = "tx","rx"; +}; + +//40pin +&spi0{ + //status = "okay"; + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + /* Character device nodes for device communication on CS0(/dev/spidev0.0) */ + spidev0_0:spi@0_0{ + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev0.1) */ + spidev0_1:spi@0_1{ + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +//40pin 04113000 +&pwm3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm3>; + status = "disabled"; +}; + +//add the isp support +&i7_isp { + status = "okay"; +}; + +&armcb_config { + status = "okay"; +}; + +&armcb_ispmem { + status = "okay"; +}; + +&cix_vi_hw { + status = "okay"; +}; + +&i2c0 { + imgsensor00: imgsensor00@34 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x34>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam0_hw>; + pinctrl-1 = <&pinctrl_cam0_hw>; + reset-gpios = <&fch_gpio1 12 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 15 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK0>; + clock-names = "mclk"; + cix,camera-module-index = <0>; + actuator-src = <&isp_motor>; + isp-src = <&i7_isp>; + status = "okay"; + }; + + isp_motor: motor0@40 { + compatible = "motor,ms42919"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + pi-max-frequency = <124999999>; + status = "okay"; + }; +}; + +&i2c1 { + imgsensor02: imgsensor02@38 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x38>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam2_hw>; + pinctrl-1 = <&pinctrl_cam2_hw>; + reset-gpios = <&fch_gpio1 11 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 7 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK2>; + clock-names = "mclk"; + + cix,camera-module-index = <2>; + status = "okay"; + }; + + imgsensor01: imgsensor01@36 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x36>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam1_hw>; + pinctrl-1 = <&pinctrl_cam1_hw>; + reset-gpios = <&fch_gpio1 17 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 19 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK1>; + clock-names = "mclk"; + cix,camera-module-index = <1>; + status = "okay"; + }; +}; diff --git a/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dtsi b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dtsi new file mode 100644 index 000000000000..3ce2e62e884e --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-orangepi-6-plus.dtsi @@ -0,0 +1,4724 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/memreserve/ 0x80000000 0x6000000; + +/ { + interrupt-parent = <&pdc>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + serial5 = &uart5; + cix-bridge0 = &cix_bridge_0; + cix-bridge1 = &cix_bridge_1; + cix-bridge2 = &cix_bridge_2; + cix-bridge3 = &cix_bridge_3; + cix-csi0 = &cix_mipi_csi_0; + cix-csi1 = &cix_mipi_csi_1; + cix-csi2 = &cix_mipi_csi_2; + cix-csi3 = &cix_mipi_csi_3; + cix-dphy0 = &cix_dphy_0; + cix-dphy1 = &cix_dphy_1; + cix-dphy2 = &cix_dphy_2; + cix-dphy3 = &cix_dphy_3; + cix-dphy4 = &cix_dphy_4; + cix-dphy5 = &cix_dphy_5; + cix-dphy-hw0 = &cix_dphy_hw_0; + cix-dphy-hw1 = &cix_dphy_hw_1; + pcie_rc0 = &pcie_x8_rc; + pcie_rc1 = &pcie_x4_rc; + pcie_rc2 = &pcie_x2_rc; + pcie_rc3 = &pcie_x1_1_rc; + pcie_rc4 = &pcie_x1_0_rc; + i2s0 = &i2s0; + i2s1 = &i2s1; + i2s2 = &i2s2; + i2s3 = &i2s3; + i2s4 = &i2s4; + i2s5 = &i2s5; + i2s6 = &i2s6; + i2s7 = &i2s7; + i2s8 = &i2s8; + i2s9 = &i2s9; + usb0 = &sky1_usbss_0; + usb1 = &sky1_usbss_1; + usb2 = &sky1_usbss_2; + usb3 = &sky1_usbss_3; + usb4 = &sky1_usbss_4; + usb5 = &sky1_usbss_5; + usb6 = &sky1_usbhs_0; + usb7 = &sky1_usbhs_1; + usb8 = &sky1_usbhs_2; + usb9 = &sky1_usbhs_3; + usbdpphy0 = &usbc_phy0; + usbdpphy1 = &usbc_phy1; + usbdpphy2 = &usbc_phy2; + usbdpphy3 = &usbc_phy3; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &sf_i2c0; + i2c9 = &sf_i2c1; + i2c10 = &i2c2_slave; + i3c0 = &i3c0; + i3c1 = &i3c1; + i3c2 = &sf_i3c0; + i3c3 = &sf_i3c1; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &sf_spi; + gpio0 = &s5_gpio0; + gpio1 = &s5_gpio1; + gpio2 = &s5_gpio2; + gpio3 = &fch_gpio0; + gpio4 = &fch_gpio1; + gpio5 = &fch_gpio2; + gpio6 = &fch_gpio3; + linlondp0 = &dpu0; + linlondp1 = &dpu1; + linlondp2 = &dpu2; + linlondp3 = &dpu3; + linlondp4 = &dpu4; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + core4 { + cpu = <&CPU4>; + }; + core5 { + cpu = <&CPU5>; + }; + core6 { + cpu = <&CPU6>; + }; + core7 { + cpu = <&CPU7>; + }; + core8 { + cpu = <&CPU8>; + }; + core9 { + cpu = <&CPU9>; + }; + core10 { + cpu = <&CPU10>; + }; + core11 { + cpu = <&CPU11>; + }; + }; + }; + + idle-states { + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <34>; + exit-latency-us = <100>; + min-residency-us = <3000>; + }; + + CPU_SLEEP_1: cpu-sleep-1 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x10000>; + local-timer-stop; + entry-latency-us = <31>; + exit-latency-us = <79>; + min-residency-us = <3000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <41>; + exit-latency-us = <104>; + min-residency-us = <4000>; + }; + }; + + CPU0: cpu0@0 { + compatible = "arm,armv8"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU1: cpu1@100 { + compatible = "arm,armv8"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU2: cpu2@200 { + compatible = "arm,armv8"; + reg = <0x0 0x200>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU3: cpu3@300 { + compatible = "arm,armv8"; + reg = <0x0 0x300>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU4: cpu4@400 { + compatible = "arm,armv8"; + reg = <0x0 0x400>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 5>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU5: cpu5@500 { + compatible = "arm,armv8"; + reg = <0x0 0x500>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 5>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU6: cpu6@600 { + compatible = "arm,armv8"; + reg = <0x0 0x600>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 6>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU7: cpu7@700 { + compatible = "arm,armv8"; + reg = <0x0 0x700>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 6>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU8: cpu8@800 { + compatible = "arm,armv8"; + reg = <0x0 0x800>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 3>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU9: cpu9@900 { + compatible = "arm,armv8"; + reg = <0x0 0x900>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 3>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU10: cpu10@a00 { + compatible = "arm,armv8"; + reg = <0x0 0xa00>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 4>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU11: cpu11@b00 { + compatible = "arm,armv8"; + reg = <0x0 0xb00>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 4>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + }; + + dsu_pctrl: dsu_pctrl { + compatible = "arm,dsu_pctrl_r0"; + size = <8192>; /* size in KB */ + line-size = <64>; + static-leakage-per-mb = <10000>; /*uW/MB */ + dram-energy-per-mb = <130>; /* uJ/MB */ + polling = <10000>; /* miliseconds */ + /* hw-automatic-control; */ + /* cluster-l3-dn-th0 = <100>; */ + /* cluster-l3-dn-th1 = <200>; */ + /* cluster-l3-up-th0 = <300>; */ + /* cluster-l3-up-th1 = <400>; */ + /* cluster-l3-up-th2 = <500>; */ + /* cluster-l3-auto-interval = <5>; */ /* IMP_CLUSTERPWRCTLR_EL1.AUTOPRTN */ + status = "disabled"; + }; + + /* + * L3 cache in the DSU is the Memory System Component (MSC) + * The MPAM registers are accessed through utility bus in the DSU + */ + msc0 { + compatible = "arm,mpam-msc"; + reg = <0x0 0xf010000 0x0 0x2000>; + status = "disabled"; + }; + + memory@80000000 { + #address-cells = <2>; + #size-cells = <2>; + device_type = "memory"; + reg = <0x00000000 0x80000000 0x1 0x00000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0x28000000>; + linux,cma-default; + }; + + dpu_gop: dpu_gop@84800000 { + reg = <0x0 0x84800000 0x0 0x2000000>; + iommu-addresses = <&dpu0 0x0 0x84800000 0x0 0x02000000>, + <&dpu1 0x0 0x84800000 0x0 0x02000000>, + <&dpu2 0x0 0x84800000 0x0 0x02000000>, + <&dpu3 0x0 0x84800000 0x0 0x02000000>, + <&dpu4 0x0 0x84800000 0x0 0x02000000>; + status = "disabled"; /* not for device dma and cma memory */ + no-map; + }; + + smc_shmem_reserved: smc_shmem@84380000 { + reg = <0x0 0x84380000 0x0 0x80000>; + no-map; + }; + + smc_shmem_tee_reserved: smc_shmem@82500000 { + reg = <0x0 0x82500000 0x0 0xb00000>; + no-map; + }; + + ramoops: cix_ramoops@83d00000 { + compatible = "ramoops"; + reg = <0x0 0x83d00000 0x0 0x000a0000>; + record-size = <0x10000>; + console-size = <0x10000>; + pmsg-size = <0x1000>; + status = "disabled"; + }; + + mntndump: mntndump@83de0000 { + compatible = "cix-dst,mntndump"; + no-map; + reg = <0 0x83de0000 0 0x00020000>; + status = "disabled"; + }; + + rdr_res_region: rdr@83000000 { + reg = <0 0x83000000 0 0x400000>; + no-map; + }; + + sfh_vdev0vring0: vdev0vring0@84000000 { + reg = <0x0 0x84000000 0x0 0x4000>; /* 16k for vring0 */ + no-map; + }; + + sfh_vdev0vring1: vdev0vring1@84004000 { + reg = <0x0 0x84004000 0x0 0x4000>; /* 16k for vring1 */ + no-map; + }; + + sfh_vdev0buffer: vdev0buffer@84008000 { /* 1M for tx/rx buffer */ + compatible = "shared-dma-pool"; + reg = <0x0 0x84008000 0x0 0x100000>; + no-map; + }; + + sfh_sharebuffer: sfh_sharebuffer@84800000 { + reg = <0x0 0x84800000 0x0 0x800000>; /* 8M for IPC */ + no-map; + }; + + sfh_ram: ram0@1ca0000000 { /* 512KB RAM */ + reg = <0x1c 0xa0000000 0x0 0x80000>; + no-map; + }; + + aipu_res_0: memory@90000000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x0 0x90000000 0x0 0x20000000>; + }; + + mali_protected: mali_protected@bce00000 { + compatible = "mali-reserved"; + reg = <0x0 0xbce00000 0x0 0x1000000>; + }; + + vpu_private: vpu_private { + reg = <0x0 0xbde00000 0x0 0x800000>; + no-map; + status = "disabled"; + }; + + vpu_protected: vpu_protected { + reg = <0x0 0xbe600000 0x0 0x1800000>; + no-map; + status = "disabled"; + }; + + media_protected: media_protected { + reg = <0x0 0xbfe00000 0x0 0xe000000>; + no-map; + status = "disabled"; + }; + + dsp_vdev0vring0: vdev0vring0@cde00000 { + reg = <0x0 0xcde00000 0x0 0x4000>; /* 16k for vring0 */ + no-map; + }; + + dsp_vdev0vring1: vdev0vring1@cde04000 { + reg = <0x0 0xcde04000 0x0 0x4000>; /* 16k for vring1 */ + no-map; + }; + + dsp_vdev0buffer: vdev0buffer@cde08000 { /* 1M for tx/rx buffer */ + compatible = "shared-dma-pool"; + reg = <0x0 0xcde08000 0x0 0x100000>; + no-map; + }; + + dsp_reserved: dsp_reserved { + reg = <0x0 0xce000000 0x0 0x1000000>; + no-map; + }; + + dsp_reserved_heap: dsp_reserved_heap { + reg = <0x0 0xcf000000 0x0 0x1000000>; + no-map; + }; + + audio_alsa: audio_alsa@d0000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0xd0000000 0x0 0xe00000>; + no-map; + }; + + }; + + smmu_syshub: iommu@0b0e0000 { + compatible = "arm,smmu-v3"; + reg = <0 0x0b0e0000 0x0 0xc0000>; + #iommu-cells = <1>; + interrupts = , + , + , + ; + interrupt-names = "eventq", "priq", "cmdq-sync", "gerror"; + status = "disabled"; + }; + + smmu_mmhub: iommu@0b1b0000 { + compatible = "arm,smmu-v3"; + reg = <0 0x0b1b0000 0x0 0x400000>; + #iommu-cells = <1>; + interrupts = , + , + , + ; + interrupt-names = "eventq", "priq", "cmdq-sync", "gerror"; + status = "disabled"; + + port { + endpoint { + remote-endpoint = <&cix_display>; + }; + }; + }; + + smmu_pciehub: iommu@0b010000 { + compatible = "arm,smmu-v3"; + reg = <0 0x0b010000 0x0 0xc0000>; + #iommu-cells = <1>; + interrupts = , + , + , + ; + interrupt-names = "eventq", "priq", "cmdq-sync", "gerror"; + status = "disabled"; + }; + + smmu_mmhub_tcu: smmu-mmhub-tcu@0xb1b0000 { + compatible = "arm,smmu-v3-pmcg"; /* smmu mmhub tcu pmu */ + reg = <0x0 0xb1b2000 0x0 0x1000>, + <0x0 0xb1d2000 0x0 0x1000>; + interrupts = ; + interrupt-names = "SMMU_MMHUB TCU"; + status = "disabled"; + }; + + smmu_mmhub_npu_tbu0: smmu-mmhub-npu_tbu0@0xb3d0000 { + compatible = "arm,smmu-v3-pmcg"; /* smmu mmhub npu tbu0 pmu */ + reg = <0x0 0xb3d2000 0x0 0x1000>, + <0x0 0xb3e2000 0x0 0x1000>; + interrupts = ; + interrupt-names = "SMMU_MMHUB NPU TBU0"; + status = "disabled"; + }; + + smmu_mmhub_npu_tbu1: smmu-mmhub-npu_tbu1@0xb3f0000 { + compatible = "arm,smmu-v3-pmcg"; /* smmu mmhub npu tbu1 pmu */ + reg = <0x0 0xb3f2000 0x0 0x1000>, + <0x0 0xb402000 0x0 0x100>; + interrupts = ; + interrupt-names = "SMMU_MMHUB NPU TBU1"; + status = "disabled"; + }; + + pmu: pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + spe_pmu: spe_pmu { + compatible = "arm,statistical-profiling-extension-v1"; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + pdc: pdc@16000000 { + compatible = "cix,sky1-pdc", "syscon"; + reg = <0x0 0x16000000 0x0 0x1000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + clock-frequency = <1000000000>; + interrupt-parent = <&gic>; + arm,no-tick-in-suspend; +#ifdef CONFIG_ARCH_CIX_EMU_FPGA + always-on; /* only on EMU/FPGA */ +#endif + }; + + sky1_fixed_clocks: fixed-clocks { + i2cclk: i2cclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "i2cclk"; + }; + + spi_ref_clk: spi_ref_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "spi_ref_clk"; + }; + + spi_apb_pclk: spi_apb_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "spi_apb_pclk"; + }; + + uartclk: uartclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "uartclk"; + }; + + uart_apb_pclk: uart_apb_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "apb_pclk"; + }; + + i3c_apb_clk: i3c_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "i3c_apb_clk"; + }; + + i3c_sys_clk: i3c_sys_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "i3c_sys_clk"; + }; + + xspi_maclk: xspi_maclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "xspi_maclk"; + }; + + xspi_pclk: xspi_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "xspi_apb_pclk"; + }; + + xspi_funcclk: xspi_funcclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "xspi_funcclk"; + }; + + dma_axi_clk: dma_axi_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "dma_axi_clk"; + }; + + dma_apb_pclk: dma_apb_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "dma_apb_pclk"; + }; + + dfd_clk: dummyclk { + compatible = "fixed-clock"; + clock-frequency = <800000000>; + #clock-cells = <0>; + }; + + fch_timer_apb_clk: fch_timer_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "fch_timer_apb_clk"; + }; + + fch_timer_func_clk: fch_timer_func_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "fch_timer_func_pclk"; + }; + + s5_gpio_apb_clk: s5_gpio_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "s5_gpio_apb_clk"; + }; + + fch_gpio_apb_clk: fch_gpio_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "fch_gpio_apb_clk"; + }; + }; + + soc@0 { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + dma-ranges; + + i2c0: i2c@04010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04010000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C0_APB>; + resets = <&src_fch SW_I2C0_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c1: i2c@04020000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04020000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C1_APB>; + resets = <&src_fch SW_I2C1_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c2: i2c@04030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04030000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C2_APB>; + resets = <&src_fch SW_I2C2_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c2_slave: i2c_slave@04030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04030000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C2_APB>; + resets = <&src_fch SW_I2C2_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c3: i2c@04040000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04040000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C3_APB>; + resets = <&src_fch SW_I2C3_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c4: i2c@04050000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04050000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C4_APB>; + resets = <&src_fch SW_I2C4_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c5: i2c@04060000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04060000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C5_APB>; + resets = <&src_fch SW_I2C5_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c6: i2c@04070000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04070000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C6_APB>; + resets = <&src_fch SW_I2C6_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c7: i2c@04080000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04080000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C7_APB>; + resets = <&src_fch SW_I2C7_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + spi0: spi@04090000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,spi-r1p6"; + reg = <0x0 0x04090000 0x0 0x10000>; + clocks = <&scmi_clk CLK_TREE_FCH_SPI0_APB>, + <&scmi_clk CLK_TREE_FCH_SPI0_APB>; + clock-names = "pclk", "ref_clk"; + resets = <&src_fch SW_SPI0_RST_APB_N>; + reset-names = "spi_reset"; + interrupts = ; + fifo-width = <32>; + status = "disabled"; + }; + + spi1: spi@040a0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,spi-r1p6"; + reg = <0x0 0x040a0000 0x0 0x10000>; + clocks = <&scmi_clk CLK_TREE_FCH_SPI1_APB>, + <&scmi_clk CLK_TREE_FCH_SPI1_APB>; + clock-names = "pclk", "ref_clk"; + resets = <&src_fch SW_SPI1_RST_APB_N>; + reset-names = "spi_reset"; + interrupts = ; + fifo-width = <32>; + status = "disabled"; + }; + + uart0: uart@040b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040b0000 0x0 0x1000>; + timeout-enable; + timeout-value = <25000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART0_FUNC>, <&scmi_clk CLK_TREE_FCH_UART0_APB>; + clock-names = "uartclk", "apb_pclk"; + resets = <&src_fch SW_UART0_RST_FUNC_N>, <&src_fch SW_UART0_RST_APB_N>; + reset-names = "uart_func_reset", "uart_apb_reset"; + status = "disabled"; + }; + + uart1: uart@040c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040c0000 0x0 0x1000>; + timeout-enable; + timeout-value = <25000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART1_FUNC>, <&scmi_clk CLK_TREE_FCH_UART1_APB>; + clock-names = "uartclk", "apb_pclk"; + resets = <&src_fch SW_UART1_RST_FUNC_N>, <&src_fch SW_UART1_RST_APB_N>; + reset-names = "uart_func_reset", "uart_apb_reset"; + status = "disabled"; + }; + + uart2: uart@040d0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040d0000 0x0 0x1000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART2_FUNC>, <&scmi_clk CLK_TREE_FCH_UART2_APB>; + clock-names = "uartclk", "apb_pclk"; + status = "disabled"; + }; + + uart3: uart@040e0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040e0000 0x0 0x1000>; + timeout-enable; + timeout-value = <25000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART3_FUNC>, <&scmi_clk CLK_TREE_FCH_UART3_APB>; + clock-names = "uartclk", "apb_pclk"; + resets = <&src_fch SW_UART3_RST_FUNC_N>, <&src_fch SW_UART3_RST_APB_N>; + reset-names = "uart_func_reset", "uart_apb_reset"; + status = "disabled"; + }; + + uart4: uart@06540000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x6540000 0x0 0x1000>; + status = "disabled"; + }; + + uart5: uart@05020000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x5020000 0x0 0x1000>; + interrupts = ; + status = "disabled"; + }; + + i3c0: i3c@040f0000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x040f0000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_I3C0_APB>, <&scmi_clk CLK_TREE_FCH_I3C0_FUNC>; + clock-names = "pclk", "sysclk"; + resets = <&src_fch SW_I3C0_RST_FUNC_G_N>, <&src_fch SW_I3C0_RST_FUNC_I_N>, <&src_fch SW_I3C0_RST_APB_N>; + reset-names = "i3c_funcg","i3c_funci","i3c_apb"; + status = "disabled"; + }; + + i3c1: i3c@04100000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x04100000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_I3C1_APB>, <&scmi_clk CLK_TREE_FCH_I3C1_FUNC>; + clock-names = "pclk", "sysclk"; + resets = <&src_fch SW_I3C1_RST_FUNC_G_N>, <&src_fch SW_I3C1_RST_FUNC_I_N>, <&src_fch SW_I3C1_RST_APB_N>; + reset-names = "i3c_funcg","i3c_funci","i3c_apb"; + status = "disabled"; + }; + + xspi: xspi@04180000 { + compatible = "cdns,xspi-nor"; + reg = <0x0 0x04180000 0x0 0x10000>, <0x0 0x10000 0x0 0x4000000>; + reg-names = "io", "sdma"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_XSPI_APB>, <&scmi_clk CLK_TREE_FCH_XSPI_MACLK>, <&scmi_clk CLK_TREE_FCH_XSPI_FUNC>; + clock-names = "pclk", "maclk", "funcclk"; + resets = <&src_fch SW_XSPI_SYS_RST_N>, <&src_fch SW_XSPI_REG_RST_N>; + reset-names = "xspi_sys_reset", "xspi_reg_reset"; + status = "disabled"; + }; + + fch_cru: fch_cru@0x416009c { + compatible = "sky1,fch_cru", "syscon"; + reg = <0x0 0x0416009c 0x0 0x80>; + }; + + fch_dmac: dma-controller@4190000 { + compatible = "arm,dma350-full"; + reg = <0x0 0x4190000 0x0 0x10000>; + #dma-cells = <2>; + dma-channels = <8>; + dma-requests = <8>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_DMA_ACLK>; + clock-names = "axiclk"; + resets = <&src_fch SW_DMA_RST_AXI_N>; + reset-names = "dma_reset"; + status = "okay"; + }; + + csu_se@05000000 { + compatible = "cix,sky1-se"; + mbox-names = "tx3", "rx3"; + mboxes = <&mbox_ap2se 9>, /* index=9: fifo base channel */ + <&mbox_se2ap 9>; + status = "disabled"; + }; + + csu_pm@06000000 { + compatible = "cix,sky1-pm"; + mbox-names = "tx2", "rx2"; + mboxes = <&mbox_ap2pm 8>, /* index=8: Reg/DB base channel */ + <&mbox_pm2ap 8>; + status = "disabled"; + }; + + sf_i2c0: i2c@08030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x08030000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&i2cclk>; + interrupts = ; + status = "disabled"; + }; + + sf_i2c1: i2c@08040000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x08040000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&i2cclk>; + interrupts = ; + status = "disabled"; + }; + + sf_spi: spi@08070000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,spi-r1p6"; + reg = <0x0 0x08070000 0x0 0x10000>; + clocks = <&spi_ref_clk>, <&spi_apb_pclk>; + clock-names = "pclk", "ref_clk"; + interrupts = ; + fifo-width = <32>; + status = "disabled"; + }; + + sf_i3c0: i3c@08050000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x08050000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + i3c-scl-hz = <100000>; + interrupts = ; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + clock-names = "pclk", "sysclk"; + status = "disabled"; + }; + + sf_i3c1: i3c@08060000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x08060000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + interrupts = ; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + clock-names = "pclk", "sysclk"; + status = "disabled"; + }; + + hifi5: audio-dsp@07000000 { + compatible = "cix,sky1-hifi5"; + reg = <0x0 0x07000000 0x0 0x1000000>; + interrupts = ; /* watchdog interrupt */ + resets = <&src SKY1_AUDIO_HIFI5_RESET_N>, + <&audss_rst AUDSS_MB0_SW_RST_N>, + <&audss_rst AUDSS_MB1_SW_RST_N>; + reset-names = "dsp", "mb0", "mb1"; + clocks = <&audss_clk CLK_DSP_CLK>, + <&audss_clk CLK_DSP_BCLK>, + <&audss_clk CLK_DSP_PBCLK>, + <&audss_clk CLK_SRAM_AXI>, + <&audss_clk CLK_MB_0_APB>, + <&audss_clk CLK_MB_1_APB>; + clock-names = "clk", "bclk", "pbclk", "sramclk", "mb0clk", "mb1clk"; + firmware-name = "dsp_fw.bin"; + mbox-names = "tx0", "rx0"; + mboxes = <&mbox_ap2dsp 9>, /* index=9: fifo base channel */ + <&mbox_dsp2ap 9>; + cix,dsp-ctrl = <&audss_cru>; + status = "disabled"; + }; + + audss_dmac: dma-controller@07010000 { + compatible = "arm,dma350-no-pause"; + reg = <0x0 0x07010000 0x0 0x10000>; + interrupts = ; + #dma-cells = <2>; + dma-channels = <8>; + dma-requests = <20>; + clocks = <&audss_clk CLK_DMAC_AXI>; + clock-names = "axiclk"; + arm,clk-enable-atomic; + arm,reg-map = <0x07010000 0x20000000>; + arm,ram-map = <0xc0000000 0x30000000>; + arm,remote-ctrl = <&audss_cru>; + resets = <&audss_rst AUDSS_DMAC_SW_RST_N>; + reset-names = "dma_reset"; + status = "disabled"; + }; + + i2s0: i2s@07020000 { + compatible = "cdns,sky1-i2s-sc"; + reg = <0x0 0x07020000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S0_APB>, + <&audss_clk CLK_I2S0>, + <&audss_clk CLK_MCLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", "mclk", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S0_SW_RST_N>; + reset-names = "i2s"; + cdns,mclk-idx = /bits/ 8 <0>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s1: i2s@07030000 { + compatible = "cdns,sky1-i2s-sc"; + reg = <0x0 0x07030000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S1_APB>, + <&audss_clk CLK_I2S1>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S1_SW_RST_N>; + reset-names = "i2s"; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s2: i2s@07040000 { + compatible = "cdns,sky1-i2s-sc"; + reg = <0x0 0x07040000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S2_APB>, + <&audss_clk CLK_I2S2>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S2_SW_RST_N>; + reset-names = "i2s"; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s3: i2s@07050000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07050000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S3_APB>, + <&audss_clk CLK_I2S3>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK1>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>, + <&scmi_clk CLK_TREE_AUDIO_CLK3>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk1", + "audio_clk2", "audio_clk3"; + resets = <&audss_rst AUDSS_I2S3_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <6>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s4: i2s@07060000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07060000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S4_APB>, + <&audss_clk CLK_I2S4>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK1>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>, + <&scmi_clk CLK_TREE_AUDIO_CLK3>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk1", + "audio_clk2", "audio_clk3"; + resets = <&audss_rst AUDSS_I2S4_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s5: i2s@07070000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07070000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S5_APB>, + <&audss_clk CLK_I2S5>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S5_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s6: i2s@07080000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07080000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S6_APB>, + <&audss_clk CLK_I2S6>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S6_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s7: i2s@07090000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07090000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S7_APB>, + <&audss_clk CLK_I2S7>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S7_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s8: i2s@070a0000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x070a0000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S8_APB>, + <&audss_clk CLK_I2S8>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S8_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s9: i2s@070b0000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x070b0000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S9_APB>, + <&audss_clk CLK_I2S9>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S9_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + ipb_hda: ipb-hda@070c0000 { + compatible = "ipbloq,hda"; + reg = <0x0 0x070c0000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_HDA_SYS>, + <&audss_clk CLK_HDA_HDA>; + clock-names = "sysclk", "clk48m"; + resets = <&audss_rst AUDSS_HDA_SW_RST_N>; + reset-names = "hda"; + cru-ctrl = <&audss_cru>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + mbox_ap2dsp: mailbox@70f0000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x070f0000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_dsp2ap: mailbox@7100000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x07100000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + audss_cru: system-controller@07110000 { + compatible = "cix,audio-ss-cru", "simple-mfd", "syscon"; + reg = <0x0 0x07110000 0x0 0x10000>; + status = "disabled"; + + audss_clk: clock-controller { + compatible = "cix,sky1-audss-clock"; + power-domains = <&smc_devpd SKY1_PD_AUDIO>; + power-domain-names = "audio"; + resets = <&src SKY1_AUDIO_HIFI5_NOC_RESET_N>; + reset-names = "noc"; + clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>, <&scmi_clk CLK_TREE_AUDIO_CLK1>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>, <&scmi_clk CLK_TREE_AUDIO_CLK3>, + <&scmi_clk CLK_TREE_AUDIO_CLK4>, <&scmi_clk CLK_TREE_AUDIO_CLK5>; + clock-names = "audio_clk0", "audio_clk1", + "audio_clk2", "audio_clk3", + "audio_clk4", "audio_clk5"; + #clock-cells = <1>; + status = "disabled"; + }; + + audss_rst: reset-controller { + compatible = "cix,sky1-audss-reset"; + #reset-cells = <1>; + status = "disabled"; + }; + }; + + sensorhub: sensor-mcu@08000000 { + compatible = "cix,sky1-sfh"; + reg = <0x0 0x08000000 0x0 0x1000000>; + interrupts = , + ; + interrupt-names = "wdt","sw_intr"; + firmware-name = "sfh_fw.bin"; + clocks = <&scmi_clk CLK_TREE_S5_SENSOR_HUB_25M>, + <&scmi_clk CLK_TREE_S5_SENSOR_HUB_400M>; + clock-names = "sensor_hub_25M", "sensor_hub_400M"; + resets = <&src SKY1_SENSORHUB_RESET_N>, + <&src SKY1_SENSORHUB_NOC_RESET_N>; + reset-names = "reset", "noc_reset"; + mbox-names = "tx1", "rx1"; + mboxes = <&mbox_ap2sfh 9>, /* index=9: FIFO based channel */ + <&mbox_sfh2ap 9>; + cix,sfh-ctrl = <&sfh_cru>; + wakeup-source; + status = "disabled"; + }; + + sfh_cru: sfh_cru@08080000 { + compatible = "sky1,sfh_cru", "syscon"; + reg = <0x0 0x08080000 0x0 0x1000>; + }; + + sfh_scp: sfh_scp@08100000 { + compatible = "cix,sfh_scp"; + status = "disabled"; + }; + + sky1_crash: cix_se_pm_crash { + compatible = "cix,se_pm_crash"; + mbox-names = "rx4"; + mboxes = <&mbox_se2ap 9>; /* index=9: fifo base channel */ + status = "disabled"; + }; + + gmac_rcsu: gmac_rcsu@9310000 { + compatible = "sky1,gmac_rcsu", "syscon"; + reg = <0x0 0x09310000 0x0 0x1000>; + }; + + macb0: ethernet@9320000 { + compatible = "cdns,sky1-gem"; + reg = <0x0 0x09320000 0x0 0x10000>; + iommus = <&smmu_syshub 0xC>; + interrupts = , /* Queue 0 */ + , /* Queue 1 */ + , /* Queue 2 */ + , /* Queue 3 */ + , /* Queue 4 */ + , /* Queue 5 */ + , /* Queue 6 */ + ; /* Queue 7 */ + clocks = <&scmi_clk CLK_TREE_GMAC0_ACLK>, + <&scmi_clk CLK_TREE_GMAC0_PCLK>, + <&scmi_clk CLK_TREE_GMAC0_DIV_TXCLK>; + clock-names = "aclk", "pclk", "tx_clk"; + resets = <&src SKY1_GMAC0_RST_N>; + reset-names = "gmac_rstn"; + status = "disabled"; + }; + + macb1: ethernet@9330000 { + compatible = "cdns,sky1-gem"; + reg = <0x0 0x09330000 0x0 0x10000>; + iommus = <&smmu_syshub 0xB>; + interrupts = , /* Queue 0 */ + , /* Queue 1 */ + , /* Queue 2 */ + , /* Queue 3 */ + , /* Queue 4 */ + , /* Queue 5 */ + , /* Queue 6 */ + ; /* Queue 7 */ + clocks = <&scmi_clk CLK_TREE_GMAC1_ACLK>, + <&scmi_clk CLK_TREE_GMAC1_PCLK>, + <&scmi_clk CLK_TREE_GMAC1_DIV_TXCLK>; + clock-names = "aclk", "pclk", "tx_clk"; + resets = <&src SKY1_GMAC1_RST_N>; + reset-names = "gmac_rstn"; + status = "disabled"; + }; + + sky1_usbss_0:usb@9000000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09000310 0x00 0x4>, + <0x00 0x09000400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS0_PRST_N>, + <&src SKY1_USBC_SS0_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_DRD_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_DRD_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_DRD_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_DRD_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_0: usb-controller@9010000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9010000 0x00 0x4000>, + <0x00 0x9014000 0x00 0x4000>, + <0x00 0x9018000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "otg"; + phys = <&usb3_phy0>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + usb2_phy4:usb-phy@9020000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS4_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy0:usb-phy@9030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x9030000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY0_RST_N>, + <&src SKY1_USB_DP_PHY0_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_DRD_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy0: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc0_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_1:usb@9070000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09070310 0x00 0x4>, + <0x00 0x09070400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS1_PRST_N>, + <&src SKY1_USBC_SS1_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_H0_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_0_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_H0_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_0_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_1: usb-controller@9080000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9080000 0x00 0x4000>, + <0x00 0x9084000 0x00 0x4000>, + <0x00 0x9088000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "host"; + phys = <&usb3_phy1>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + usb2_phy5:usb-phy@9090000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS5_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy1:usb-phy@90A0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x90A0000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY1_RST_N>, + <&src SKY1_USB_DP_PHY1_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_0_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy1: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc1_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_2:usb@90e0000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x090e0310 0x00 0x4>, + <0x00 0x090e0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS4_PRST_N>, + <&src SKY1_USBC_SS4_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_H1_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_1_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_H1_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_1_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_2: usb-controller@90f0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x90f0000 0x00 0x4000>, + <0x00 0x90f4000 0x00 0x4000>, + <0x00 0x90f8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "host"; + status = "disabled"; + phys = <&usb3_phy2>; + phy-names = "cdnsp,usb3-phy"; + }; + }; + + usb2_phy8:usb-phy@9100000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS8_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy2:usb-phy@9110000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x9110000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY2_RST_N>, + <&src SKY1_USB_DP_PHY2_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_1_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy2: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc2_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_3:usb@9150000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09150310 0x00 0x4>, + <0x00 0x09150400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS5_PRST_N>, + <&src SKY1_USBC_SS5_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_H2_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_2_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_H2_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_2_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_3: usb-controller@9160000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9160000 0x00 0x4000>, + <0x00 0x9164000 0x00 0x4000>, + <0x00 0x9168000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "host"; + status = "disabled"; + phys = <&usb3_phy3>; + phy-names = "cdnsp,usb3-phy"; + }; + }; + + usb2_phy9:usb-phy@9170000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS9_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy3:usb-phy@9180000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x9180000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY3_RST_N>, + <&src SKY1_USB_DP_PHY3_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_2_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy3: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc3_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_4:usb@91c0300 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x091c0314 0x00 0x4>, + <0x00 0x091c0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS2_PRST_N>, + <&src SKY1_USBC_SS2_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3A_H0_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3A_0_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3A_H0_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3A_0_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_4: usb-controller@91d0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x91d0000 0x00 0x4000>, + <0x00 0x91d4000 0x00 0x4000>, + <0x00 0x91d8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "otg"; + phys = <&usb3_phy4_0>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + sky1_usbss_5:usb@91c0304 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x091c0324 0x00 0x4>, + <0x00 0x091c0410 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS3_PRST_N>, + <&src SKY1_USBC_SS3_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3A_H1_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3A_1_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3A_H1_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3A_1_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_5: usb-controller@91e0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x91e0000 0x00 0x4000>, + <0x00 0x91e4000 0x00 0x4000>, + <0x00 0x91e8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "otg"; + phys = <&usb3_phy4_1>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + usb2_phy6:usb-phy@91f0000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS6_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usb2_phy7:usb-phy@9200000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS7_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usb3_phy4:usb-phy@9210000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usb3-phy"; + reg = <0x00 0x09210000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USBPHY_SS_RST_N>, + <&src SKY1_USBPHY_SS_PST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3A_PHY3_GATE>, + <&scmi_clk CLK_TREE_USB3A_PHY_x2_REF>; + clock-names = "apb_clk", "ref_clk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy4_0: usb-port@0 { + #phy-cells = <0>; + id = <0>; + status = "disabled"; + }; + usb3_phy4_1: usb-port@1 { + #phy-cells = <0>; + id = <1>; + status = "disabled"; + }; + }; + + sky1_usbhs_0:usb@9250000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09250310 0x00 0x4>, + <0x00 0x09250400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS0_PRST_N>, + <&src SKY1_USBC_HS0_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_0_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_0_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_0_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_0_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_0: usb-controller@9260000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9260000 0x00 0x4000>, + <0x00 0x9264000 0x00 0x4000>, + <0x00 0x9268000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + sky1_usbhs_1:usb@9280000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09280310 0x00 0x4>, + <0x00 0x09280400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS1_PRST_N>, + <&src SKY1_USBC_HS1_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_1_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_1_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_1_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_1_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_1: usb-controller@9290000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9290000 0x00 0x4000>, + <0x00 0x9294000 0x00 0x4000>, + <0x00 0x9298000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + usb2_phy0:usb-phy@9270000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS0_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + usb2_phy1:usb-phy@92a0000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS1_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + sky1_usbhs_2:usb@92b0000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x092b0310 0x00 0x4>, + <0x00 0x092b0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS2_PRST_N>, + <&src SKY1_USBC_HS2_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_2_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_2_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_2_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_2_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_2: usb-controller@92c0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x92c0000 0x00 0x4000>, + <0x00 0x92c4000 0x00 0x4000>, + <0x00 0x92c8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + usb2_phy2:usb-phy@92d0000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS2_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + sky1_usbhs_3:usb@92e0000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x092e0310 0x00 0x4>, + <0x00 0x092e0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS3_PRST_N>, + <&src SKY1_USBC_HS3_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_3_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_3_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_3_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_3_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_3: usb-controller@92f0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x92f0000 0x00 0x4000>, + <0x00 0x92f4000 0x00 0x4000>, + <0x00 0x92f8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + usb2_phy3:usb-phy@9300000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS3_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + pcie_x8_rc: pcie@0a010000 { /* X8 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a010000 0x00 0x10000>, + <0x00 0x0a000000 0x00 0x10000>, + <0x00 0x2c000000 0x00 0x4000000>, + <0x00 0x60000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0xc0 0xff>; + max-link-speed = <4>; + num-lanes = <8>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x60100000 0x0 0x60100000 0x0 0x00100000>, + <0x02000000 0x0 0x60200000 0x0 0x60200000 0x0 0x1fe00000>, + <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL0_CLK>, + <&scmi_clk CLK_TREE_PCIE_X8CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B0>; + clock-names = "axi_clk", "apb_clk","refclk_b"; + power-domains = <&smc_devpd SKY1_PD_PCIE_CTRL0>; + power-domain-names = "pcie_pd"; + resets = <&src SKY1_PCIE0_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x0>; + msi-map = <0xc000 &its_pcie 0xc000 0x4000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0xc000 &smmu_pciehub 0xc000 0x3fff>; + phys = <&pcie_x8_phy>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pcie0_phy: pcie_phy@0a020000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-pcie-phy"; + reg = <0x00 0x0a020000 0x00 0x40000>; + status = "disabled"; + clocks =<&scmi_clk CLK_TREE_PCIE_X8_PHY_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_PHY_X8>; + + clock-names = "pclk", "refclk"; + + pcie_x8_phy: link@0 { + #phy-cells = <0>; + reg = <0x0>; + num-lanes = <8>; + status = "disabled"; + }; + }; + + pcie_x4_rc: pcie@0a070000 { /* X4 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a070000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x29000000 0x00 0x3000000>, + <0x00 0x50000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x90 0xbf>; + max-link-speed = <4>; + num-lanes = <4>; + max-payload = <512>; + ranges = <0x01000000 0x00 0x50100000 0x00 0x50100000 0x00 0x00100000>, + <0x02000000 0x00 0x50200000 0x00 0x50200000 0x00 0x0fe00000>, + <0x43000000 0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL1_CLK>, + <&scmi_clk CLK_TREE_PCIE_X4CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B1>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + resets = <&src SKY1_PCIE1_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x1>; + msi-map = <0x9000 &its_pcie 0x9000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x9000 &smmu_pciehub 0x9000 0x2fff>; + phys = <&pcie_x4_phy>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pcie1_phy: pcie_phy@0a080000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-pcie-phy"; + reg = <0x00 0x0a080000 0x00 0x40000>; + status = "disabled"; + clocks = <&scmi_clk CLK_TREE_PCIE_X4_PHY_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_PHY_X4>; + + clock-names = "pclk", "refclk"; + + pcie_x4_phy: link@0 { + #phy-cells = <0>; + reg = <0x0>; + num-lanes = <4>; + status = "disabled"; + }; + }; + + pcie_x2_rc: pcie@0a0c0000 { /* X2 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a0c0000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x26000000 0x00 0x3000000>, + <0x00 0x40000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x60 0x8f>; + max-link-speed = <4>; + num-lanes = <2>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x40100000 0x0 0x40100000 0x0 0x00100000>, + <0x02000000 0x0 0x40200000 0x0 0x40200000 0x0 0x0fe00000>, + <0x43000000 0x10 0x00000000 0x10 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL2_CLK>, + <&scmi_clk CLK_TREE_PCIE_X2CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B2>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + resets = <&src SKY1_PCIE2_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x2>; + msi-map = <0x6000 &its_pcie 0x6000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x6000 &smmu_pciehub 0x6000 0x2fff>; + phys = <&pcie_x2_phy>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pciex211_phy: pcie_phy@0a0f0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-pcie-phy"; + reg = <0x00 0x0a0f0000 0x00 0x40000>; + status = "disabled"; + clocks = <&scmi_clk CLK_TREE_PCIE_X211_PHY_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_PHY_X211>; + + clock-names = "pclk", "refclk"; + + pcie_x1_phy0: link@0 { + #phy-cells = <0>; + reg = <0x0>; + num-lanes = <1>; + status = "disabled"; + }; + + pcie_x1_phy1: link@1 { + #phy-cells = <0>; + reg = <0x1>; + num-lanes = <1>; + status = "disabled"; + }; + + pcie_x2_phy: link@2 { + #phy-cells = <0>; + reg = <0x2>; + num-lanes = <2>; + status = "disabled"; + }; + }; + + pcie_x1_1_rc: pcie@0a0e0000 { /* X1_1 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a0e0000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x23000000 0x00 0x3000000>, + <0x00 0x38000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x30 0x5f>; + max-link-speed = <4>; + num-lanes = <1>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x38100000 0x0 0x38100000 0x0 0x00100000>, + <0x02000000 0x0 0x38200000 0x0 0x38200000 0x0 0x07e00000>, + <0x43000000 0x0C 0x00000000 0x0C 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL4_CLK>, + <&scmi_clk CLK_TREE_PCIE_X1_1CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B4>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + resets = <&src SKY1_PCIE4_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x3>; + msi-map = <0x3000 &its_pcie 0x3000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x3000 &smmu_pciehub 0x3000 0x2fff>; + phys = <&pcie_x1_phy1>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pcie_x1_0_rc: pcie@0a0d0000 { /* X1_0 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a0d0000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x20000000 0x00 0x3000000>, + <0x00 0x30000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x00 0x2f>; + max-link-speed = <4>; + num-lanes = <1>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x30100000 0x0 0x30100000 0x0 0x00100000>, + <0x02000000 0x0 0x30200000 0x0 0x30200000 0x0 0x07e00000>, + <0x43000000 0x08 0x00000000 0x08 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL3_CLK>, + <&scmi_clk CLK_TREE_PCIE_X1_0CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B3>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + resets = <&src SKY1_PCIE3_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x4>; + msi-map = <0x0000 &its_pcie 0x0000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x0000 &smmu_pciehub 0x0000 0x2fff>; + phys = <&pcie_x1_phy0>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + gic: interrupt-controller@0e001000 { + compatible = "arm,gic-700", "arm,gic-v3"; + #address-cells = <2>; + #interrupt-cells = <3>; + #size-cells = <2>; + single-redist; + ranges; + interrupt-controller; +#ifndef CONFIG_ARCH_CIX_EMU_FPGA + #redistributor-regions = <12>; + reg = <0x0 0x0e010000 0 0x10000>, /* GICD */ + <0x0 0x0e090000 0 0x40000>, /* GICR */ + <0x0 0x0e0d0000 0 0x40000>, /* GICR1 */ + <0x0 0x0e110000 0 0x40000>, /* GICR2 */ + <0x0 0x0e150000 0 0x40000>, /* GICR3 */ + <0x0 0x0e190000 0 0x40000>, /* GICR4 */ + <0x0 0x0e1d0000 0 0x40000>, /* GICR5 */ + <0x0 0x0e210000 0 0x40000>, /* GICR6 */ + <0x0 0x0e250000 0 0x40000>, /* GICR7 */ + <0x0 0x0e290000 0 0x40000>, /* GICR8 */ + <0x0 0x0e2d0000 0 0x40000>, /* GICR9 */ + <0x0 0x0e310000 0 0x40000>, /* GICR10 */ + <0x0 0x0e350000 0 0x40000>; /* GICR11 */ +#else + #redistributor-regions = <1>; + reg = <0x0 0x0e010000 0 0x10000>, /* GICD */ + <0x0 0x0e090000 0 0x40000>; /* GICR */ +#endif + interrupts = ; + interrupt-parent = <&gic>; + + its_pcie: its@0e050000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x0e050000 0x0 0x30000>; + }; + }; + + dsu_pmu: dsu_pmu { + compatible = "arm,dsu-pmu"; + interrupts = ; + cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, + <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>, + <&CPU8>, <&CPU9>, <&CPU10>, <&CPU11>; + status = "okay"; + }; + + cmn_pmu: cmn_pmu@10010000 { + compatible = "arm,ci-700"; + reg = <0x0 0x10010000 0x0 0x3FF0000>; + interrupts = ; + status = "okay"; + }; + + cix_display: cix-display { + compatible = "cix,display"; + //reset-control = <0x4>; + status = "disabled"; + }; + + dpu0: disp-controller@14010000 { + device-id = <0>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x14010000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 0>, <&smmu_mmhub 1>, + <&smmu_mmhub 3>, <&smmu_mmhub 4>; + power-domains = <&smc_devpd SKY1_PD_DPU0>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU0_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU0_RCSU_RESET_N>, + <&src SKY1_DPU_RESET0_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu0_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP0_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu0_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP0_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu1: disp-controller@14080000 { + device-id = <1>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x14080000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 6>, <&smmu_mmhub 7>, + <&smmu_mmhub 9>, <&smmu_mmhub 10>; + power-domains = <&smc_devpd SKY1_PD_DPU1>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU1_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU1_RCSU_RESET_N>, + <&src SKY1_DPU_RESET1_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu1_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP1_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu1_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP1_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu2: disp-controller@140f0000 { + device-id = <2>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x140f0000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 12>, <&smmu_mmhub 13>, + <&smmu_mmhub 15>, <&smmu_mmhub 16>; + power-domains = <&smc_devpd SKY1_PD_DPU2>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU2_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU2_RCSU_RESET_N>, + <&src SKY1_DPU_RESET2_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu2_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP2_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu2_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP2_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu3: disp-controller@14160000 { + device-id = <3>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x14160000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 18>, <&smmu_mmhub 19>, + <&smmu_mmhub 21>, <&smmu_mmhub 22>; + power-domains = <&smc_devpd SKY1_PD_DPU3>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU3_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU3_RCSU_RESET_N>, + <&src SKY1_DPU_RESET3_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu3_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP3_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu3_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP3_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu4: disp-controller@141d0000 { + device-id = <4>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x141d0000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 24>, <&smmu_mmhub 25>, + <&smmu_mmhub 27>, <&smmu_mmhub 28>; + power-domains = <&smc_devpd SKY1_PD_DPU4>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU4_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU4_RCSU_RESET_N>, + <&src SKY1_DPU_RESET4_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu4_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP4_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu4_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP4_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + aeu0: aeu@14030000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x14030000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 2>; + power-domains = <&smc_devpd SKY1_PD_DPU0>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU0_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu1: aeu@140a0000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x140a0000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 8>; + power-domains = <&smc_devpd SKY1_PD_DPU1>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU1_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu2: aeu@14110000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x14110000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 14>; + power-domains = <&smc_devpd SKY1_PD_DPU2>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU2_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu3: aeu@14180000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x14180000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 20>; + power-domains = <&smc_devpd SKY1_PD_DPU3>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU3_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu4: aeu@141f0000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x141f0000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 26>; + power-domains = <&smc_devpd SKY1_PD_DPU4>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU4_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + dp0: dp@14060000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x14064000 0x0 0x4000>, + <0x0 0x14068000 0x0 0x4000>, + <0x0 0x1406ff00 0x0 0x0100>; + reg-names = "dp", "dsc", "dp_phy"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC0_APBCLK>, + <&scmi_clk CLK_TREE_DPC0_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC0_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP0_RCSU_RESET_N>, + <&src SKY1_DP_RESET0_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc0_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + dp1: dp@140d0000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x140d4000 0x0 0x4000>, + <0x0 0x140d8000 0x0 0x4000>, + <0x0 0x140dff00 0x0 0x0100>; + reg-names = "dp", "dsc", "dp_phy"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC1_APBCLK>, + <&scmi_clk CLK_TREE_DPC1_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC1_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP1_RCSU_RESET_N>, + <&src SKY1_DP_RESET1_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc1_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + dp2: dp@14140000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x14144000 0x0 0x4000>, + <0x0 0x14148000 0x0 0x4000>, + <0x0 0x1414c000 0x0 0x4000>; + reg-names = "dp", "dsc", "dp_phy"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC2_APBCLK>, + <&scmi_clk CLK_TREE_DPC2_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC2_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP2_RCSU_RESET_N>, + <&src SKY1_DP_RESET2_N>, + <&src SKY1_DP_PHY_RST_N>; + reset-names = "dp_rcsu_reset", "dp_reset", "phy_reset"; + enabled_by_gop = <0>; + status = "disabled"; + }; + + dp3: dp@141b0000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x141b4000 0x0 0x4000>, + <0x0 0x141b8000 0x0 0x4000>, + <0x0 0x141bff00 0x0 0x0100>; + reg-names = "dp", "dsc", "dp_phy"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC3_APBCLK>, + <&scmi_clk CLK_TREE_DPC3_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC3_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP3_RCSU_RESET_N>, + <&src SKY1_DP_RESET3_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc2_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + dp4: dp@14220000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x14224000 0x0 0x4000>, + <0x0 0x14228000 0x0 0x4000>, + <0x0 0x1422ff00 0x0 0x0100>; + reg-names = "dp", "dsc", "dp_phy"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC4_APBCLK>, + <&scmi_clk CLK_TREE_DPC4_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC4_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP4_RCSU_RESET_N>, + <&src SKY1_DP_RESET4_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc3_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + vpu: vpu@14230000 { + compatible = "armChina,linlon-v8"; + reg = <0x0 0x14230000 0x0 0x10000>, + <0x0 0x14240000 0x0 0x10000>; + reg-names = "vpu_rcsu", "vpu"; + interrupts = ; + power-domains = <&smc_devpd SKY1_PD_VPU_TOP>, + <&smc_devpd SKY1_PD_VPU_CORE0>, + <&smc_devpd SKY1_PD_VPU_CORE1>, + <&smc_devpd SKY1_PD_VPU_CORE2>, + <&smc_devpd SKY1_PD_VPU_CORE3>, + <&scmi_dvfs VPU_DFS_DOMAIN_ID>; + + power-domain-names = "vpu_top", "vpu_core0", "vpu_core1", + "vpu_core2", "vpu_core3", "perf"; + clocks = <&scmi_clk CLK_TREE_VPU_APBCLK>; + clock-names = "vpu_clk"; + resets = <&src SKY1_VPU_RESET_N>, + <&src SKY1_VPU_RCSU_RESET_N>; + reset-names = "vpu_reset", "vpu_rcsu_reset"; + status = "disabled"; + }; + + npu: aipu@14260000 { + compatible = "armchina,zhouyi"; + core_mask = <3>; + power-domains = <&smc_devpd SKY1_PD_NPU_CORE0>, + <&smc_devpd SKY1_PD_NPU_CORE1>, + <&smc_devpd SKY1_PD_NPU_CORE2>, + <&scmi_dvfs NPU_DFS_DOMAIN_ID>; + power-domain-names = "pd_core0", "pd_core1", "pd_core2", "perf"; + cluster-partition = <0 0>; /* x2 only: cluster #0 -> partition #0 */ + reg = <0x0 0x14260000 0x0 0x10000>; + iommus = <&smmu_mmhub 0x1e>; + gm-policy = <1>; /* x2 only: 1: shared by tasks of all QoS level */ + interrupts = ; + status = "disabled"; + }; + + i7_isp: armcb_isp@14340000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "armcb,sky1-isp"; + reg = <0x0 0x14340000 0x0 0x10000>, + <0x0 0x14360000 0x0 0x50000>; + status = "disabled"; + }; + + i7_isp_fake1:isp_fake1{ + compatible = "armcb,isp_fake"; + }; + + i7_isp_fake2:isp_fake2{ + compatible = "armcb,isp_fake"; + }; + + i7_isp_fake3:isp_fake3{ + compatible = "armcb,isp_fake"; + }; + + gpu_physical_memory_group_manager: physical-memory-group-manager { + compatible = "arm,physical-memory-group-manager"; + }; + + gpu_protected_memory_allocator: protected-memory-allocator { + compatible = "arm,protected-memory-allocator"; + memory-region = <&mali_protected>; + }; + + gpu: gpu@15010000 { + compatible = "arm,mali-valhall"; + reg = <0x0 0x15000000 0x0 0x10000>, + <0x0 0x15010000 0x0 0x480000>; + reg-names = "gpu_rcsu", "gpu"; + interrupts = , + , + ; + interrupt-names = "JOB", "MMU", "GPU"; + system-coherency = <0>; + physical-memory-group-manager = <&gpu_physical_memory_group_manager>; + protected-memory-allocator = <&gpu_protected_memory_allocator>; + power-domains = <&smc_devpd SKY1_PD_GPU>, <&scmi_dvfs 0>; + power-domain-names = "pd_gpu", "perf"; + clocks = <&scmi_clk CLK_TREE_GPU_CLK_CORE>, <&scmi_clk CLK_TREE_GPU_CLK_STACKS>, + <&scmi_clk CLK_TREE_GPU_CLK_200M>, <&scmi_clk CLK_TREE_GPU_CLK_400M>; + clock-names = "gpu_clk_core", "gpu_clk_stacks", + "gpu_clk_200M", "gpu_clk_400M"; + resets = <&src SKY1_GPU_RCSU_RESET_N>, + <&src SKY1_GPU_RESET_N>; + reset-names = "gpu_rcsu_reset", "gpu_reset"; + #cooling-cells = <2>; /* Requested by cooling device state */ + dynamic-power-coefficient = <4687>; /* Requested by Energy Model (EM) */ + power_model@0 { + /*Note: it was designed for the Juno platform, and may not be suitable for sky1.*/ + compatible = "arm,mali-simple-power-model"; + static-coefficient = <2427750>; + dynamic-coefficient = <4687>; + ts = <20000 2000 (-20) 2>; + thermal-zone = "thermal-zone-gpu"; + }; + pbha { + int_id_override = <2 0x23>, <4 0x23>, <16 0x22>, <17 0x32>, + <18 0x52>, <21 0x32>, <22 0x52>, <24 0x22>, <28 0x32>; + }; + }; + + hwclock: hwspinlock@06510000 { + compatible = "sky1,hwspinlock"; + reg = <0x0 0x06510000 0x0 0x1000>; + #hwlock-cells = <1>; + status = "disabled"; + }; + + gpt_timer0: gpt_timer@04110000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04110000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "disabled"; + }; + + gpt_timer1: gpt_timer@04112000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04112000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "disabled"; + }; + + gpt_timer2: gpt_timer@04114000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04114000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "disabled"; + }; + + gpt_timer3: gpt_timer@04116000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04116000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "okay"; + }; + + pwm0: pwm0@04111000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04110000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm1: pwm1@04112000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04111000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm2: pwm2@04112000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04112000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm3: pwm3@04113000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04113000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm4: pwm4@04114000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04114000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm5: pwm5@04115000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04115000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm6: pwm6@04116000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04116000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm7: pwm7@04117000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04117000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + watchdog: watchdog@16003000 { + compatible = "cix,sky1-wdt"; + reg = <0x0 0x16003000 0x0 0x1000 + 0x0 0x16008000 0x0 0x1000>; + interrupts = ; + status = "disabled"; + }; + + src: reset-controller@16000000 { + compatible = "cix,sky1-src", "syscon"; + reg = <0x0 0x16000000 0x0 0x1000>; + #reset-cells = <1>; + status = "okay"; + }; + + src_fch: reset-controller@04160000 { + compatible = "cix,sky1-src-fch", "syscon"; + reg = <0x0 0x04160000 0x0 0x90>; + #reset-cells = <1>; + status = "okay"; + }; + + s5_gpio0: gpio-controller@16004000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x16004000 0x0 0x1000>; + clocks = <&s5_gpio_apb_clk>; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + s5_gpio1: gpio-controller@16005000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x16005000 0x0 0x1000>; + clocks = <&s5_gpio_apb_clk>; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <10>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + s5_gpio2: gpio-controller@16006000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x16006000 0x0 0x1000>; + clocks = <&s5_gpio_apb_clk>; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <10>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio0: gpio-controller@4120000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4120000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio1: gpio-controller@4130000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4130000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio2: gpio-controller@4140000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4140000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio3: gpio-controller@4150000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4150000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <17>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + iomuxc_s5: pinctrl_s5_sky1 { + compatible = "cix,sky1-iomuxc-s5"; + reg = <0x0 0x16007000 0x0 0x1000>; + }; + + iomuxc: pinctrl_sky1 { + compatible = "cix,sky1-iomuxc"; + reg = <0x0 0x04170000 0x0 0x1000>; + }; + + nvmem: nvmem_fw { + compatible = "cix,sky1-nvmem-fw"; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + npu_harvest_0: npu_harveset_0@1 { + reg = <0x1 0x1>; + bits = <7 1>; + }; + + opn: opn@4c7 { + reg = <0x4dc 0x8>; + bits = <0 64>; + }; + }; + + sky1_top: sky1_top { + compatible = "cix,sky1-top"; + reg = <0x0 0x83E01000 0x0 0x2000>; + nvmem-cells = <&opn>; + nvmem-cell-names = "opn"; + status = "okay"; + }; + + cix_csi_rcsu_0: cix_csi_rcsu@14270000 { + compatible = "cix,cix-csi-rcsu-hw"; + reg = <0x0 0x14270000 0x0 0x10000>; + status = "disabled"; + }; + + cix_csi_rcsu_1: cix_csi_rcsu@142D0000 { + compatible = "cix,cix-csi-rcsu-hw"; + reg = <0x0 0x142D0000 0x0 0x10000>; + status = "disabled"; + }; + + cix_bridge_0: cix_bridge@142B0000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA0_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE0_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x142B0000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_0>; + interrupts = ; + interface = <0 0>; + axi-uid = <0x21>; + iommus = <&smmu_mmhub 0x21>; + status = "disabled"; + }; + + cix_bridge_1: cix_bridge@142C0000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA1_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE1_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x142C0000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_0>; + interrupts = ; + interface = <0 0>; + axi-uid= <0x21>; + status = "disabled"; + }; + + cix_bridge_2: cix_bridge@14310000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA2_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE2_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x14310000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_1>; + interrupts = ; + interface = <0 0>; + axi-uid= <0x22>; + iommus = <&smmu_mmhub 0x22>; + status = "disabled"; + }; + + cix_bridge_3: cix_bridge@14320000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA3_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE3_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x14320000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_1>; + interrupts = ; + interface = <0 0>; + axi-uid = <0x21>; + status = "disabled"; + }; + + cix_mipi_csi_0: csi@14280000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL0_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL3_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk", + "csi_p1clk", "csi_p2clk", "csi_p3clk"; + resets = <&src SKY1_CSI_RCSU0_RESET_N>, + <&src SKY1_CSI0_RST_N>; + reset-names = "rcsu_reset", "csi_reset"; + reg = <0x0 0x14280000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_mipi_csi_1: csi@14290000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL1_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_PIXEL0_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk"; + resets = <&src SKY1_CSI1_RST_N>; + reset-names = "csi_reset"; + reg = <0x0 0x14290000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_mipi_csi_2: csi@142E0000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL2_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL3_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk", + "csi_p1clk", "csi_p2clk", "csi_p3clk"; + resets = <&src SKY1_CSI_RCSU1_RESET_N>, + <&src SKY1_CSI2_RST_N>; + reset-names = "rcsu_reset", "csi_reset"; + reg = <0x0 0x142E0000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_mipi_csi_3: csi@142F0000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL3_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_PIXEL0_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk"; + resets = <&src SKY1_CSI3_RST_N>; + reset-names = "csi_reset"; + reg = <0x0 0x142F0000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_dphy_0: cix_dph_0 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_0>; + status = "disabled"; + }; + + cix_dphy_1: cix_dph_1 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_0>; + status = "disabled"; + }; + + cix_dphy_2: cix_dph_2 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_0>; + status = "disabled"; + }; + + cix_dphy_3: cix_dph_3 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_1>; + status = "disabled"; + }; + + cix_dphy_4: cix_dph_4 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_1>; + status = "disabled"; + }; + + cix_dphy_5: cix_dph_5 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_1>; + status = "disabled"; + }; + + cix_dphy_hw_0: phy@142A0000 { + compatible = "cix,cix-mipi-dphy-hw"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_PHY0_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY0_APBCLK>; + clock-names = "phy_psmclk", "phy_apbclk"; + resets = <&src SKY1_CSIDPHY_PRST0_N>, + <&src SKY1_CSIDPHY_CMNRST0_N>; + reset-names = "phy_prst", "phy_cmnrst"; + reg = <0x0 0x142A0000 0x0 0x10000>; + status = "disabled"; + }; + + cix_dphy_hw_1: phy@14300000 { + compatible = "cix,cix-mipi-dphy-hw"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_PHY1_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY1_APBCLK>; + clock-names = "phy_psmclk", "phy_apbclk"; + resets = <&src SKY1_CSIDPHY_PRST1_N>, + <&src SKY1_CSIDPHY_CMNRST1_N>; + reset-names = "phy_prst", "phy_cmnrst"; + reg = <0x0 0x14300000 0x0 0x10000>; + status = "disabled"; + }; + }; + + mbox_sfh2ap: mailbox@8090000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x08090000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "okay"; + }; + + mbox_ap2sfh: mailbox@80a0000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x080a0000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "okay"; + }; + + mbox_ap2pm: mailbox@6590000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x06590000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_pm2ap: mailbox@65a0000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x065a0000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_ap2se: mailbox@5060000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x05060000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_se2ap: mailbox@5070000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x05070000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + ap2pm_scmi_mem: ap2pm-shmem@0 { + compatible = "arm,scmi-shmem"; + #address-cells = <2>; + #size-cells = <2>; + reg = <0x0 0x06590000 0x0 0x80>; + status = "disabled"; + }; + + pm2ap_scmi_mem: pm2pm-shmem@0 { + compatible = "arm,scmi-shmem"; + #address-cells = <2>; + #size-cells = <2>; + reg = <0x0 0x065a0000 0x0 0x80>; + status = "disabled"; + }; + + ap_tfa_scmi_mem: ap2tf-shmem@1 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x84380000 0x0 0x80>; + status = "disabled"; + }; + + firmware { + ap_to_pm_scmi: scmi { + compatible = "arm,scmi"; + mbox-names = "tx", "rx"; + mboxes = <&mbox_ap2pm 8>, /*index=8: Reg/DB base channel*/ + <&mbox_pm2ap 8>; + shmem = <&ap2pm_scmi_mem &pm2ap_scmi_mem>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + + scmi_sensor: protocol@15 { + reg = <0x15>; + #thermal-sensor-cells = <1>; + }; + + scmi_pm_excp: protocol@81 { + reg = <0x81>; + }; + }; + + ap_to_tfa_scmi:scmi-smc { + compatible = "arm,scmi-smc"; + arm,smc-id = <0xc2000001>; + #address-cells = <1>; + #size-cells = <0>; + shmem = <&ap_tfa_scmi_mem>; + status = "disabled"; + + smc_devpd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + }; + + sdei: sdei-smc { + compatible = "arm,sdei-1.0"; + method = "smc"; + status = "okay"; + }; + + optee: optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + armcb_config: armcb_config { + compatible = "armcb,sky1-config-i7"; + interrupts = , + ; + status = "disabled"; + }; + + cix_vi_hw: cix_vi_hw { + compatible = "cix,cix-vi-hw"; + clocks = <&scmi_clk CLK_TREE_CSI_PHY0_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY0_APBCLK>, + <&scmi_clk CLK_TREE_CSI_PHY1_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY1_APBCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL3_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL3_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_DMA0_PCLK>, + <&scmi_clk CLK_TREE_CSI_DMA1_PCLK>, + <&scmi_clk CLK_TREE_CSI_DMA2_PCLK>, + <&scmi_clk CLK_TREE_CSI_DMA3_PCLK>; + clock-names = "phy0_psmclk", "phy0_apbclk", + "phy1_psmclk", "phy1_apbclk", + "csi0_pclk", "csi0_sclk", "csi0_p0clk", + "csi0_p1clk", "csi0_p2clk", "csi0_p3clk", + "csi1_pclk", "csi1_sclk", "csi1_p0clk", + "csi2_pclk", "csi2_sclk", "csi2_p0clk", + "csi2_p1clk", "csi2_p2clk", "csi2_p3clk", + "csi3_pclk", "csi3_sclk", "csi3_p0clk", + "dma0_pclk", "dma1_pclk", + "dma2_pclk", "dma3_pclk"; + + resets = <&src SKY1_CSIDPHY_PRST0_N>, + <&src SKY1_CSIDPHY_CMNRST0_N>, + <&src SKY1_CSIDPHY_PRST1_N>, + <&src SKY1_CSIDPHY_CMNRST1_N>, + <&src SKY1_CSI_RCSU0_RESET_N>, + <&src SKY1_CSI_RCSU1_RESET_N>, + <&src SKY1_CSI0_RST_N>, + <&src SKY1_CSI1_RST_N>, + <&src SKY1_CSI2_RST_N>, + <&src SKY1_CSI3_RST_N>, + <&src SKY1_CSIBRDGE0_RST_N>, + <&src SKY1_CSIBRDGE1_RST_N>, + <&src SKY1_CSIBRDGE2_RST_N>, + <&src SKY1_CSIBRDGE3_RST_N>; + + reset-names = "phy0_prst", "phy0_cmnrst", + "phy1_prst", "phy1_cmnrst", + "rcsu0_reset", "rcsu1_reset", + "csi0_reset", "csi1_reset", + "csi2_reset", "csi3_reset", + "csibridge0_reset", + "csibridge1_reset", + "csibridge2_reset", + "csibridge3_reset"; + ahb-dphy0-base = <0x142A0000>; + ahb-dphy0-size = <0x10000>; + ahb-dphy1-base = <0x14300000>; + ahb-dphy1-size = <0x10000>; + ahb-csi0-base = <0x14280000>; + ahb-csi0-size = <0x10000>; + ahb-csi1-base = <0x14290000>; + ahb-csi1-size = <0x10000>; + ahb-csi2-base = <0x142E0000>; + ahb-csi2-size = <0x10000>; + ahb-csi3-base = <0x142F0000>; + ahb-csi3-size = <0x10000>; + ahb-csidma0-base = <0x142B0000>; + ahb-csidma0-size = <0x10000>; + ahb-csidma1-base = <0x142C0000>; + ahb-csidma1-size = <0x10000>; + ahb-csidma2-base = <0x14310000>; + ahb-csidma2-size = <0x10000>; + ahb-csidma3-base = <0x14320000>; + ahb-csidma3-size = <0x10000>; + ahb-csircsu0-base = <0x14270000>; + ahb-csircsu0-size = <0x10000>; + ahb-csircsu1-base = <0x142D0000>; + ahb-csircsu1-size = <0x10000>; + interrupts =, + , + , + , + , + , + , + ; + status = "disabled"; + }; + + armcb_ispmem: armcb_ispmem { + compatible = "armcb,isp-mem"; + power-domains = <&smc_devpd SKY1_PD_ISP0>; + power-domain-names = "pd_isp0"; + clocks = <&scmi_clk CLK_TREE_ISP_ACLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "isp_aclk", "isp_sclk"; + resets = <&src SKY1_ISP_RCSU0_RESET_N>, + <&src SKY1_ISP_SRESET_N>, + <&src SKY1_ISP_ARESET_N>, + <&src SKY1_ISP_HRESET_N>, + <&src SKY1_ISP_GDCRESET_N>; + reset-names = "rcsu_reset", "isp_sreset", "isp_areset", + "isp_hreset", "isp_gdcreset"; + + ahb-pmctrl-res-base = <0x16000404>; + ahb-pmctrl-res-size = <0x1>; + ahb-rcsuisp0-res-base = <0x14330000>; + ahb-rcsuisp0-res-size = <0x1000>; + ahb-rcsuisp1-res-base = <0x14350000>; + ahb-rcsuisp1-res-size = <0x1000>; + iommus = <&smmu_mmhub 0x1F>; + status = "disabled"; + }; + + reg_definition: reg-definition@05040100 { + compatible = "sky1,csu_se_pub", "syscon"; + reg = <0x0 0x05040000 0x0 0x1000>; + }; + + sky1_rng: sky1-rng@05055300 { + compatible = "cix,sky1-rng"; + reg = <0x0 0x05055300 0x0 0x30>; + status = "disabled"; + }; + + cix_reboot{ + compatible = "cix,reboot"; + arm,smc-id = <0xc2000002>; + /*need to add register to record reason*/ + status = "disabled"; + }; + + cix_pmu_ci700: cix_pmu_ci700 { + compatible = "cix,pmu"; + reg = <0x00 0x0a00032c 0x00 0x4>, + <0x00 0x0a000330 0x00 0x4>, + <0x00 0x0a000334 0x00 0x4>, + <0x00 0x0a00033c 0x00 0x4>; + status = "disabled"; + }; + + cix_pmu_ni700: cix_pmu_ni700 { + compatible = "cix,pmu"; + reg = <0x00 0x0a06032c 0x00 0x4>, + <0x00 0x0a060330 0x00 0x4>, + <0x00 0x0a060334 0x00 0x4>, + <0x00 0x0a06033c 0x00 0x4>; + status = "disabled"; + }; + + cix_bus_ci700: cix_bus_ci700 { + compatible = "cix,bus-ci700"; + power-domain-names = "perf"; + power-domains = <&scmi_dvfs CI700_DFS_DOMAIN_ID>; + devfreq-events = <&cix_pmu_ci700>; + status = "disabled"; + }; + + cix_bus_ni700: cix_bus_ni700 { + compatible = "cix,bus-ni700"; + power-domain-names = "perf"; + power-domains = <&scmi_dvfs NI700_DFS_DOMAIN_ID>; + devfreq-events = <&cix_pmu_ni700>; + status = "disabled"; + }; + + thermal-zones { + /*thermal zone for GPU*/ + thermal_zone_gpu: thermal-zone-gpu { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 2>; + + trips { + switch_on:trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&switch_on>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + /*thermal zone for CPU_M0*/ + thermal_zone_cpu: thermal-zone1 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 10>; + + trips { + m0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + /*thermal zone for CPU_M1*/ + thermal_zone_cpu_m1: thermal-zone2 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 8>; + + trips { + m1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + /*thermal zone for CPU_B0*/ + thermal_zone_cpu_b0: thermal-zone3 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 11>; + + trips { + b0_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + /*thermal zone for CPU_B1*/ + thermal_zone_cpu_b1: thermal-zone4 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 9>; + + trips { + b1_trip0: trip-point-0 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + /* below thermal zone only used for monitor temp */ + thermal_zone_vpu: thermal-zone5 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 0>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + thermal_zone_gpu1: thermal-zone6 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 1>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + thermal_zone_brc: thermal-zone7 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 3>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + thermal_zone_ddr0: thermal-zone8 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 4>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + thermal_zone_ddr1: thermal-zone9 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 5>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + thermal_zone_ci700: thermal-zone10 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 6>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + thermal_zone_npu: thermal-zone11 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 7>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + thermal_zone_trc: thermal-zone12 { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor 12>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + }; + + cix_dst: cix_dst { + compatible = "cix,dst", "simple-bus"; + hwreboot_reason_addr = <0x0 0x16000218>; + ramlog_addr = <0x0 0x83DA0000>; + ramlog_size = <0x0 0x00040000>; + bbox_addr = <&rdr_res_region>; + rdr-log-max-size = <0x800000>; + rdr_area_num = <15>; + rdr_area_sizes = <0x100000 0x10000 0x10000 0x10000 0x10000 0x10000 + 0x10000 0x10000 0x10000 0x10000 0x10000 0x10000 + 0x10000 0x10000 0x10000>; + rdr-log-max-nums = <6>; + wait-dumplog-timeout = <1000>; + unexpected-max-reboot-times = <1>; + rdr-dumpctl="1111111111"; + status = "disabled"; + + exception_trace: exception_trace { + compatible = "rdr,exceptiontrace"; + area_num = <1>; + area_sizes = < 0x1000 >; + status = "disabled"; + }; + + ap_adapter: ap_adapter{ + compatible = "rdr,rdr_ap_adapter"; + /* reg-dump-regions = <3>; */ + /* reg = <0 0x61080000 0 0x10000>, */ + /* <0 0x61090000 0 0x10000>, */ + /* <0 0x610a0000 0 0x10000>; */ + /* reg-names = "test1", "test2", "test3"; */ + ap_trace_irq_size = <0x10000>; + ap_trace_task_size = <0x10000>; + ap_trace_cpu_idle_size = <0x10000>; + ap_trace_worker_size = <0x10000>; + ap_trace_time_size = <0x10000>; + ap_trace_cpu_on_off_size = <0x10000>; + ap_trace_syscall_size = <0x10000>; + ap_trace_hung_task_size = <0x10000>; + ap_trace_tasklet_size = <0x10000>; + ap_last_task_switch = <1>; + ap_dump_mem_modu_test_size = <1024>; + ap_dump_mem_modu_idm_size = <0x1000>; + ap_dump_mem_modu_tzc400_size = <0x1000>; + ap_dump_mem_modu_smmu_size = <0x1000>; + ap_dump_mem_modu_tfa_size = <0x4000>; + ap_dump_mem_modu_gap_size = <256>; + status = "disabled"; + }; + }; + + ddr_ctrl0: ddr_ctrl@0C010000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C010000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x0>; + mbox-names = "tx4"; + mboxes = <&mbox_ap2se 10>; /* index=9: fifo base channel */ + status = "disabled"; + }; + + ddr_ctrl1: ddr_ctrl@0C030000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C030000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x1>; + mbox-names = "tx4"; + mboxes = <&mbox_ap2se 10>; /* index=9: fifo base channel */ + status = "disabled"; + }; + + ddr_ctrl2: ddr_ctrl@0C050000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C050000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x2>; + mbox-names = "tx4"; + mboxes = <&mbox_ap2se 10>; /* index=9: fifo base channel */ + status = "disabled"; + }; + + ddr_ctrl3: ddr_ctrl@0C070000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C070000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x3>; + mbox-names = "tx4"; + mboxes = <&mbox_ap2se 10>; /* index=9: fifo base channel */ + status = "disabled"; + }; + + dsu_cache_exception: dsu_cache_exception { + compatible = "cix,sky1_exception_dsu_cache"; + interrupts = , + ; + interrupt-names = "dsu_errirq", "dsu_faultirq"; + status = "disabled"; + }; + + cache_exception_core0: cache_exception_core0 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU0>; + has-complex; + interrupts = , + , + , + ; + interrupt-names = "complex_errirq", "complex_faultirq", + "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core1: cache_exception_core1 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU1>; + has-complex; + interrupts = , + , + , + ; + interrupt-names = "complex_errirq", "complex_faultirq", + "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core2: cache_exception_core2 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU2>; + has-complex; + interrupts = , + , + , + ; + interrupt-names = "complex_errirq", "complex_faultirq", + "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core3: cache_exception_core3 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU3>; + has-complex; + interrupts = , + , + , + ; + interrupt-names = "complex_errirq", "complex_faultirq", + "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core4: cache_exception_core4 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU4>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core5: cache_exception_core5 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU5>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core6: cache_exception_core6 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU6>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core7: cache_exception_core7 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU7>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core8: cache_exception_core8 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU8>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core9: cache_exception_core9 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU9>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core10: cache_exception_core10 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU10>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + + cache_exception_core11: cache_exception_core11 { + compatible = "cix,sky1_exception_core_cache"; + cpu = <&CPU11>; + interrupts = , + ; + interrupt-names = "core_errirq", "core_faultirq"; + interrupt-parent = <&gic>; + status = "disabled"; + }; + +#ifdef SKY1_CORESIGHT_SUPPORT + ete0: ete0 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU0>; + status = "okay"; +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port0: endpoint { + remote-endpoint = <&dsu_funnel_in_port0>; + }; + }; + }; +#endif + }; + + ete1: ete1 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU1>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port1: endpoint { + remote-endpoint = <&dsu_funnel_in_port1>; + }; + }; + }; +#endif + }; + + ete2: ete2 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU2>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port2: endpoint { + remote-endpoint = <&dsu_funnel_in_port2>; + }; + }; + }; +#endif + }; + + ete3: ete3 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU3>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port3: endpoint { + remote-endpoint = <&dsu_funnel_in_port3>; + }; + }; + }; +#endif + }; + + ete4: ete4 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU4>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port4: endpoint { + remote-endpoint = <&dsu_funnel_in_port4>; + }; + }; + }; +#endif + }; + + ete5: ete5 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU5>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port5: endpoint { + remote-endpoint = <&dsu_funnel_in_port5>; + }; + }; + }; +#endif + }; + + ete6: ete6 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU6>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port6: endpoint { + remote-endpoint = <&dsu_funnel_in_port6>; + }; + }; + }; +#endif + }; + + ete7: ete7 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU7>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port7: endpoint { + remote-endpoint = <&dsu_funnel_in_port7>; + }; + }; + }; +#endif + }; + + ete8: ete8 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU8>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port8: endpoint { + remote-endpoint = <&dsu_funnel_in_port8>; + }; + }; + }; +#endif + }; + + ete9: ete9 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU9>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port9: endpoint { + remote-endpoint = <&dsu_funnel_in_port9>; + }; + }; + }; +#endif + }; + + ete10: ete10 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU10>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port10: endpoint { + remote-endpoint = <&dsu_funnel_in_port10>; + }; + }; + }; +#endif + }; + + ete11: ete11 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU11>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port11: endpoint { + remote-endpoint = <&dsu_funnel_in_port11>; + }; + }; + }; +#endif + }; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + funnel_dsu: funnel@dsu { + compatible = "arm,coresight-static-funnel"; + status = "okay"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsu_funnel_in_port0: endpoint { + remote-endpoint = <&ete_out_port0>; + }; + }; + + port@1 { + reg = <1>; + dsu_funnel_in_port1: endpoint { + remote-endpoint = <&ete_out_port1>; + }; + }; + + port@2 { + reg = <2>; + dsu_funnel_in_port2: endpoint { + remote-endpoint = <&ete_out_port2>; + }; + }; + + port@3 { + reg = <3>; + dsu_funnel_in_port3: endpoint { + remote-endpoint = <&ete_out_port3>; + }; + }; + + port@4 { + reg = <4>; + dsu_funnel_in_port4: endpoint { + remote-endpoint = <&ete_out_port4>; + }; + }; + + port@5 { + reg = <5>; + dsu_funnel_in_port5: endpoint { + remote-endpoint = <&ete_out_port5>; + }; + }; + + port@6 { + reg = <6>; + dsu_funnel_in_port6: endpoint { + remote-endpoint = <&ete_out_port6>; + }; + }; + + port@7 { + reg = <7>; + dsu_funnel_in_port7: endpoint { + remote-endpoint = <&ete_out_port7>; + }; + }; + + port@8 { + reg = <8>; + dsu_funnel_in_port8: endpoint { + remote-endpoint = <&ete_out_port8>; + }; + }; + + port@9 { + reg = <9>; + dsu_funnel_in_port9: endpoint { + remote-endpoint = <&ete_out_port9>; + }; + }; + + port@10 { + reg = <10>; + dsu_funnel_in_port10: endpoint { + remote-endpoint = <&ete_out_port10>; + }; + }; + + port@11 { + reg = <11>; + dsu_funnel_in_port11: endpoint { + remote-endpoint = <&ete_out_port11>; + }; + }; + }; + + out-ports { + port { + dsu_funnel_out_port: endpoint { + remote-endpoint = <&cpu_etf_in_port>; + }; + }; + }; + }; + + etf_cpu: etf@cpu { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x18060000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9ea>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + cpu_etf_in_port: endpoint { + remote-endpoint = <&dsu_funnel_out_port>; + }; + }; + }; + + out-ports { + port { + cpu_etf_out_port: endpoint { + remote-endpoint = <&soc_funnel_in_port2>; + }; + }; + }; + }; + + stm: stm@18010000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0 0x18010000 0 0x10000>, + <0x0000001C 0xB0000000 0 0x1000000>; + reg-names = "stm-base", "stm-stimulus-base"; + arm,primecell-periphid = <0x000bb963>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + out-ports { + port { + stm0_out_port: endpoint { + remote-endpoint = <&stm_etf_in_port>; + }; + }; + }; + }; + + etf_stm: etf@stm { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x180A0000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9ea>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + stm_etf_in_port: endpoint { + remote-endpoint = <&stm0_out_port>; + }; + }; + }; + + out-ports { + port { + stm_etf_out_port: endpoint { + remote-endpoint = <&soc_funnel_in_port6>; + }; + }; + }; + }; + + funnel_soc: funnel@soc { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x180B0000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9eb>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@2 { + reg = <2>; + soc_funnel_in_port2: endpoint { + remote-endpoint = <&cpu_etf_out_port>; + }; + }; + + port@6 { + reg = <6>; + soc_funnel_in_port6: endpoint { + remote-endpoint = <&stm_etf_out_port>; + }; + }; + + }; + + out-ports { + port { + soc_funnel_out_port: endpoint { + remote-endpoint = <&soc_etf_in_port>; + }; + }; + }; + }; + + etf_soc: etf@soc { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x19000000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9ea>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + soc_etf_in_port: endpoint { + remote-endpoint = <&soc_funnel_out_port>; + }; + }; + }; + + out-ports { + port { + soc_etf_out_port: endpoint { + remote-endpoint = <&etr_in_port>; + }; + }; + }; + }; + + etr0: etr@180c0000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x180c0000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9e8>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + etr_in_port: endpoint { + remote-endpoint = <&soc_etf_out_port>; + }; + }; + }; + + out-ports { + port { + etr_out_port: endpoint { + remote-endpoint = <&catu_in_port>; + }; + }; + }; + }; + + catu0: catu@180d0000 { + compatible = "arm,coresight-catu", "arm,primecell"; + reg = <0 0x180d0000 0 0x10000>; + /* interrupts = ; */ + arm,primecell-periphid = <0x000bb9ee>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + catu_in_port: endpoint { + remote-endpoint = <&etr_out_port>; + }; + }; + }; + }; +#endif + +#ifdef SKY1_CORESIGHT_TRBE_SUPPORT + trbe { + compatible = "arm,trace-buffer-extension"; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; +#endif +#endif +}; + diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6-40pin.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6-40pin.dts new file mode 100644 index 000000000000..ca39954fd528 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6-40pin.dts @@ -0,0 +1,24 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1-orion-o6.dts" + + +&i2s2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s4_lb>; + status = "okay"; +}; + + +&uart3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart3>; + status = "okay"; +}; + diff --git a/arch/arm64/boot/dts/cix/sky1-orion-o6.dts b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts new file mode 100644 index 000000000000..225efd449c68 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1-orion-o6.dts @@ -0,0 +1,2394 @@ +/* + * Copyright (c) 2024, Cix Technology Group Co., Ltd. All rights reserved. + * Copyright (c) 2024, Radxa Computer (Shenzhen) Co., Ltd. All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/dts-v1/; + +#include "sky1.dtsi" + +/delete-node/ ®_definition; +/ { + model = "Radxa Orion O6"; + compatible = "radxa,orion-o6"; + + chosen { + stdout-path = &uart2; + }; + + dummy_codec: dummy_codec { + #sound-dai-cells = <1>; + compatible = "linux,dummy"; + status = "disabled"; + }; + + sound: sound { + compatible = "cix,sky1-sound-card"; + model = "cix,sky1"; + status = "okay"; + + bt_audio { + status = "disabled"; + format = "dsp_a"; + dai-tdm-slot-tx-mask = <1>; + dai-tdm-slot-rx-mask = <1>; + dai-tdm-slot-num = <1>; + dai-tdm-slot-width = <16>; + + cpu { + sound-dai = <&i2s1>; + }; + }; + + i2s_lp: i2s_lp { + status = "disabled"; + format = "i2s"; + mclk-fs = <256>; + frame-master = <&dummy_codec_mst>; + bitclock-master = <&dummy_codec_mst>; + + cpu { + sound-dai = <&i2s2>; + }; + + dummy_codec_mst: codec { + sound-dai = <&dummy_codec 0>; + }; + }; + + dptx0_audio: dptx0_audio { + status = "okay"; + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s5 0>; + }; + + codec { + sound-dai = <&dp0>; + }; + }; + + dptx1_audio: dptx1_audio { + status = "okay"; + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s6 0>; + }; + + codec { + sound-dai = <&dp1>; + }; + }; + + dptx2_audio: dptx2_audio { + status = "disabled"; + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s7 0>; + }; + + codec { + sound-dai = <&dp2>; + }; + }; + + dptx3_audio: dptx3_audio { + status = "okay"; + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s8 0>; + }; + + codec { + sound-dai = <&dp3>; + }; + }; + + dptx4_audio: dptx4_audio { + status = "okay"; + format = "i2s"; + bitclock-inversion; + jack-det,dpout; + + cpu { + sound-dai = <&i2s9 0>; + }; + + codec { + sound-dai = <&dp4>; + }; + }; + + }; + + dp2_backlight: dp2_backlight { + compatible = "pwm-backlight"; + enable-gpios = <&fch_gpio3 15 GPIO_ACTIVE_HIGH>; + pwms = <&pwm0 0 100000>; + status = "okay"; + brightness-levels = < + 0 1 2 3 4 5 6 7 + 8 9 10 11 12 13 14 15 + 16 17 18 19 20 21 22 23 + 24 25 26 27 28 29 30 31 + 32 33 34 35 36 37 38 39 + 40 41 42 43 44 45 46 47 + 48 49 50 51 52 53 54 55 + 56 57 58 59 60 61 62 63 + 64 65 66 67 68 69 70 71 + 72 73 74 75 76 77 78 79 + 80 81 82 83 84 85 86 87 + 88 89 90 91 92 93 94 95 + 96 97 98 99 100 101 102 103 + 104 105 106 107 108 109 110 111 + 112 113 114 115 116 117 118 119 + 120 121 122 123 124 125 126 127 + 128 129 130 131 132 133 134 135 + 136 137 138 139 140 141 142 143 + 144 145 146 147 148 149 150 151 + 152 153 154 155 156 157 158 159 + 160 161 162 163 164 165 166 167 + 168 169 170 171 172 173 174 175 + 176 177 178 179 180 181 182 183 + 184 185 186 187 188 189 190 191 + 192 193 194 195 196 197 198 199 + 200 201 202 203 204 205 206 207 + 208 209 210 211 212 213 214 215 + 216 217 218 219 220 221 222 223 + 224 225 226 227 228 229 230 231 + 232 233 234 235 236 237 238 239 + 240 241 242 243 244 245 246 247 + 248 249 250 251 252 253 254 255>; + default-brightness-level = <200>; + + }; + + panel_edp0: panel_edp0 { + status = "okay"; + compatible = "cix-edp-panel"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_edp0>; + backlight = <&dp2_backlight>; + prepare-delay-ms = <120>; + enable-delay-ms = <120>; + unprepare-delay-ms = <500>; + disable-delay-ms = <120>; + width-mm = <129>; + height-mm = <171>; + enable-gpios = <&fch_gpio3 16 GPIO_ACTIVE_HIGH>; + }; + + wireless_bluetooth: wireless-bluetooth { + compatible = "bluetooth-platdata"; + pinctrl-names = "default"; + pinctrl-0 = <&bt_reset_gpio>; + BT,reset-gpios = <&s5_gpio0 19 GPIO_ACTIVE_HIGH>; + status = "okay"; + }; + + vgfx_power: vgfx-power { + compatible = "regulator-fixed"; + regulator-name = "vgfx_power"; + pinctrl-names = "default"; + pinctrl-0 = <&vgfx_poweren_gpio>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&s5_gpio1 2 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us = <15000>; + }; + + vdd_3v3_pcie: regulator-vdd-3v3-pcie { + compatible = "regulator-fixed"; + regulator-name = "vdd_3v3_pcie"; + pinctrl-names = "default"; + pinctrl-0 = <&wifi_vbat_gpio>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&s5_gpio0 12 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us = <15000>; + }; + + gbe1_power_3v3: gbe1-power-3v3 { + compatible = "regulator-fixed"; + regulator-name = "gbe1_power_3v3"; + pinctrl-names = "default"; + pinctrl-0 = <&gbe1_poweren_gpio>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&s5_gpio2 7 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us = <15000>; + }; + + cam_power_en:cam-power-3v3 { + compatible = "regulator-fixed"; + regulator-name = "cam_power_en"; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&fch_gpio1 6 GPIO_ACTIVE_HIGH>; + regulator-always-on; + enable-active-high; + }; + + gbe2_power_3v3: gbe2-power-3v3 { + compatible = "regulator-fixed"; + regulator-name = "gbe2_power_3v3"; + pinctrl-names = "default"; + pinctrl-0 = <&gbe2_poweren_gpio>; + regulator-min-microvolt = <3300000>; + regulator-max-microvolt = <3300000>; + gpio = <&s5_gpio0 9 GPIO_ACTIVE_HIGH>; + regulator-pull-down; + enable-active-high; + off-on-delay-us = <15000>; + }; + + usb20f_5v: usb20f-5v { + compatible = "regulator-fixed"; + regulator-name = "usb20f_5v"; + pinctrl-names = "default"; + pinctrl-0 = <&usb20f_5v_gpio>; + regulator-min-microvolt = <5000000>; + regulator-max-microvolt = <5000000>; + gpio = <&s5_gpio2 6 GPIO_ACTIVE_HIGH>; + enable-active-high; + regulator-always-on; + regulator-boot-on; + off-on-delay-us = <15000>; + }; +}; + +&fch_gpio0 { + status = "okay"; +}; + +&fch_gpio1 { + status = "okay"; +}; + +&fch_gpio2 { + status = "okay"; +}; + +&fch_gpio3 { + status = "okay"; +}; + +&s5_gpio0 { + status = "okay"; +}; + +&s5_gpio1 { + status = "okay"; +}; + +&s5_gpio2 { + status = "okay"; +}; + +&iomuxc_s5 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog_s5>; + + pinctrl_hog_s5: pinctrl_hog_s5 { + sky1,pins = < + CIX_PAD_GPIO014_FUNC_GPIO014 (PULL_UP|DS_LEVEL4) /* GPIO14 hp det */ + >; + }; + + wifi_vbat_gpio: wifi_vbat_gpio { + sky1,pins = < + CIX_PAD_GPIO012_FUNC_GPIO012 (PULL_UP|DS_LEVEL4) /* GPIO0-12 */ + >; + }; + + vgfx_poweren_gpio: vgfx_poweren_gpio { + sky1,pins = < + CIX_PAD_SFI_GPIO2_FUNC_GPIO017 (PULL_UP|DS_LEVEL4) /* GPIO0-17 */ + >; + }; + + bt_reset_gpio: bt_reset_gpio { + sky1,pins = < + CIX_PAD_GPIO019_FUNC_GPIO019 (PULL_UP|ST|DS_LEVEL7) /* GPIO0-19 */ + >; + }; + + pinctrl_sfi_i2c0: pinctrl_sfi_i2c0_grp { + sky1,pins = < + CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I2C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I2C0_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_sfi_i2c1: pinctrl_sfi_i2c1_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I2C1_SCL (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I2C1_SDA (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_sfi_i3c0: pinctrl_sfi_i3c0_grp { + sky1,pins = < + CIX_PAD_SFI_I2C0_SCL_FUNC_SFI_I3C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C0_SDA_FUNC_SFI_I3C0_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO023_FUNC_SFI_I3C0_PUR_EN_L (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_sfi_i3c1: pinctrl_sfi_i3c1_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_I3C1_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_I3C1_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO024_FUNC_SFI_I3C1_PUR_EN_L (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_sfi_spi: pinctrl_sfi_spi_grp { + sky1,pins = < + CIX_PAD_SFI_I2C1_SCL_FUNC_SFI_SPI_CS0 (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_I2C1_SDA_FUNC_SFI_SPI_CS1 (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO0_FUNC_SFI_SPI_SCK (ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO1_FUNC_SFI_SPI_MOSI (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_SFI_GPIO2_FUNC_SFI_SPI_MISO (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_spi0: pinctrl_fch_spi0_grp { + sky1,pins = < + CIX_PAD_SPI1_MISO_FUNC_SPI1_MISO (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CS0_FUNC_SPI1_CS0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CS1_FUNC_SPI1_CS1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_MOSI_FUNC_SPI1_MOSI (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SPI1_CLK_FUNC_SPI1_CLK (ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_xspi: pinctrl_fch_xspi_grp { + sky1,pins = < + CIX_PAD_SE_QSPI_CLK_FUNC_QSPI_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_CS_L_FUNC_QSPI_CS_L (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA0_FUNC_QSPI_DATA0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA1_FUNC_QSPI_DATA1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA2_FUNC_QSPI_DATA2 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_SE_QSPI_DATA3_FUNC_QSPI_DATA3 (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_usb0: pinctrl_usb0_oc_grp { + sky1,pins = < + CIX_PAD_GPIO036_FUNC_GPIO036 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb1: pinctrl_usb1_oc_grp { + sky1,pins = < + CIX_PAD_GPIO037_FUNC_GPIO037 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb2: pinctrl_usb2_oc_grp { + sky1,pins = < + CIX_PAD_GPIO038_FUNC_GPIO038 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb3: pinctrl_usb3_oc_grp { + sky1,pins = < + CIX_PAD_GPIO039_FUNC_GPIO039 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_usb4: pinctrl_usb4_grp { + sky1,pins = < + CIX_PAD_GPIO034_FUNC_GPIO034 (PULL_UP|DS_LEVEL4) + CIX_PAD_GPIO041_FUNC_USB_DRIVE_VBUS4 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_usb5: pinctrl_usb5_grp { + sky1,pins = < + CIX_PAD_GPIO035_FUNC_GPIO035 (PULL_UP|DS_LEVEL4) + CIX_PAD_GPIO042_FUNC_USB_DRIVE_VBUS5 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_usb6_usb7: pinctrl_usb6_usb7_vbus_grp { + sky1,pins = < + CIX_PAD_GPIO040_FUNC_GPIO040 (PULL_UP|DS_LEVEL4) //usb6-usb7 vbus + >; + }; + + pinctrl_usb6: pinctrl_usb6_oc_grp { + sky1,pins = < + CIX_PAD_GPIO030_FUNC_GPIO030 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb7: pinctrl_usb7_oc_grp { + sky1,pins = < + CIX_PAD_GPIO031_FUNC_GPIO031 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb8: pinctrl_usb8_oc_grp { + sky1,pins = < + CIX_PAD_GPIO032_FUNC_GPIO032 (PULL_UP|DS_LEVEL4) + >; + }; + pinctrl_usb9: pinctrl_usb9_oc_grp { + sky1,pins = < + CIX_PAD_GPIO033_FUNC_GPIO033 (PULL_UP|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x8_rc: pinctrl_pcie_x8_rc { + sky1,pins = < + CIX_PAD_GPIO002_FUNC_GPIO002 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x4_rc: pinctrl_pcie_x4_rc { + sky1,pins = < + CIX_PAD_GPIO004_FUNC_GPIO004 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x2_rc: pinctrl_pcie_x2_rc { + sky1,pins = < + CIX_PAD_GPIO005_FUNC_GPIO005 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x1_1_rc: pinctrl_pcie_x1_1_rc { + sky1,pins = < + CIX_PAD_GPIO003_FUNC_GPIO003 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_pcie_x1_0_rc: pinctrl_pcie_x1_0_rc { + sky1,pins = < + CIX_PAD_GPIO006_FUNC_GPIO006 (PULL_DOWN|DS_LEVEL4) + >; + }; + + pinctrl_hym8563_irq: pinctrl_hym8563_irq { + sky1,pins = < + CIX_PAD_GPIO011_FUNC_GPIO011 (PULL_UP|DS_LEVEL4) /* GPIO011 - S5_gpio0 10 */ + >; + }; + + pinctrl_hiddev_68_irq: pinctrl_hiddev_68_irq { + sky1,pins = < + CIX_PAD_GPIO010_FUNC_GPIO010 (PULL_UP|DS_LEVEL4) /* GPIO010 - S5_gpio0 9 */ + >; + }; + + pinctrl_hiddev_15_irq: pinctrl_hiddev_15_irq { + sky1,pins = < + CIX_PAD_GPIO010_FUNC_GPIO010 (PULL_UP|DS_LEVEL4) /* GPIO010 - S5_gpio0 9 */ + >; + }; + + gbe1_poweren_gpio: gbe1_poweren_gpio { + sky1,pins = < + CIX_PAD_GPIO022_FUNC_GPIO022 (PULL_UP|ST|DS_LEVEL7) /* GPIO022 - S5_gpio2 7 */ + >; + }; + + gbe2_poweren_gpio: gbe2_poweren_gpio { + sky1,pins = < + CIX_PAD_GPIO010_FUNC_GPIO010 (PULL_UP|DS_LEVEL4) /* GPIO010 - S5_gpio0 9 */ + >; + }; + + usb20f_5v_gpio: usb20f-5v-gpio { + sky1,pins = < + CIX_PAD_GPIO021_FUNC_GPIO021 (PULL_UP|ST|DS_LEVEL7) /* GPIO021 - S5_gpio2 6 */ + >; + }; +}; + +&iomuxc { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hog>; + + pinctrl_hog: pinctrl_hog { + sky1,pins = < + CIX_PAD_GPIO144_FUNC_GPIO144 (PULL_DOWN|DS_LEVEL4) /* GPIO144 pdb0 */ + CIX_PAD_GPIO145_FUNC_GPIO145 (PULL_DOWN|DS_LEVEL4) /* GPIO145 pdb1 */ + CIX_PAD_GPIO146_FUNC_GPIO146 (PULL_DOWN|DS_LEVEL4) /* GPIO146 pdb2 */ + CIX_PAD_GPIO147_FUNC_GPIO147 (PULL_DOWN|DS_LEVEL4) /* GPIO147 pdb3 */ + >; + }; + + pinctrl_touch_panel: pinctrl_touch_panel { + sky1,pins = < + CIX_PAD_GPIO129_FUNC_GPIO129 (PULL_DOWN|DS_LEVEL4) /* GPIO129 for touch panel */ + CIX_PAD_GPIO136_FUNC_GPIO136 (PULL_DOWN|ST|DS_LEVEL12) /* GPIO136 for touch panel */ + >; + }; + + pinctrl_fch_pwm0: pinctrl_fch_pwm0 { + sky1,pins = < + CIX_PAD_DP2_VARY_BL_FUNC_DP2_VARY_BL (DS_LEVEL7) + >; + }; + + pinctrl_fch_pwm1: pinctrl_fch_pwm1 { + sky1,pins = < + CIX_PAD_UART0_TXD_FUNC_PWM0 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_gmac0: pinctrl_gmac0 { + sky1,pins = + /* rfclk_25M */ + , + /* txc_trl */ + , + /* txd0 */ + , + /* txd1 */ + , + /* txd2 */ + , + /* txd3 */ + , + /* tx_clk */ + , + /* rx_ctl */ + , + + /* rxd0 */ + , + /* rxd1 */ + , + /* rxd2 */ + , + /* rxd3 */ + , + /* rx_clk */ + , + /* mdc */ + , + /* mdio */ + ; + }; + + pinctrl_gmac1: pinctrl_gmac1 { + sky1,pins = + /* rfclk_25M */ + , + /* txc_trl */ + , + /* txd0 */ + , + /* txd1 */ + , + /* txd2 */ + , + /* txd3 */ + , + /* tx_clk */ + , + /* rx_ctl */ + , + /* rxd0 */ + , + /* rxd1 */ + , + /* rxd2 */ + , + /* rxd3 */ + , + /* rx_clk */ + , + /* mdc */ + , + /* mdio */ + ; + }; + + pinctrl_fch_fan0: pinctrl_fch_fan0 { + sky1,pins = < + CIX_PAD_UART1_TXD_FUNC_FAN_OUT0 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_fan1: pinctrl_fch_fan1 { + sky1,pins = < + CIX_PAD_UART1_CTS_FUNC_FAN_OUT1 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_fan2: pinctrl_fch_fan2 { + sky1,pins = < + CIX_PAD_UART0_CTS_FUNC_FAN_OUT2 (PULL_DOWN|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c0: pinctrl_fch_i2c0 { + sky1,pins = < + CIX_PAD_I2C0_CLK_FUNC_I2C0_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C0_SDA_FUNC_I2C0_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c1: pinctrl_fch_i2c1 { + sky1,pins = < + CIX_PAD_I2C1_CLK_FUNC_I2C1_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C1_SDA_FUNC_I2C1_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c2: pinctrl_fch_i2c2 { + sky1,pins = < + CIX_PAD_I2C2_SCL_FUNC_I2C2_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C2_SDA_FUNC_I2C2_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i2c3: pinctrl_fch_i2c3 { + sky1,pins = < + CIX_PAD_I2C3_CLK_FUNC_I2C3_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C3_SDA_FUNC_I2C3_SDA (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i2c4: pinctrl_fch_i2c4 { + sky1,pins = < + CIX_PAD_I2C4_CLK_FUNC_I2C4_CLK (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C4_SDA_FUNC_I2C4_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c5: pinctrl_fch_i2c5 { + sky1,pins = < + CIX_PAD_I2C5_SCL_FUNC_I2C5_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C5_SDA_FUNC_I2C5_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c6: pinctrl_fch_i2c6 { + sky1,pins = < + CIX_PAD_I2C6_SCL_FUNC_I2C6_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C6_SDA_FUNC_I2C6_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_i2c7: pinctrl_fch_i2c7 { + sky1,pins = < + CIX_PAD_I2C7_SCL_FUNC_I2C7_SCL (PULL_UP|DS_LEVEL7) + CIX_PAD_I2C7_SDA_FUNC_I2C7_SDA (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_spi1: pinctrl_fch_spi1_grp { + sky1,pins = < + CIX_PAD_GPIO138_FUNC_SPI2_MISO (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO139_FUNC_SPI2_CS0 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO140_FUNC_SPI2_CS1 (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO141_FUNC_SPI2_MOSI (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO142_FUNC_SPI2_CLK (ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i3c0: pinctrl_fch_i3c0 { + sky1,pins = < + CIX_PAD_I2C2_SCL_FUNC_I3C0_SCL (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C2_SDA_FUNC_I3C0_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO057_FUNC_I3C0_PUR_EN_L (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_i3c1: pinctrl_fch_i3c1 { + sky1,pins = < + CIX_PAD_I2C3_CLK_FUNC_I3C1_CLK (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_I2C3_SDA_FUNC_I3C1_SDA (PULL_UP|ST|DS_LEVEL12) + CIX_PAD_GPIO060_FUNC_I3C1_PUR_EN_L (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_fch_uart0: pinctrl_fch_uart0 { + sky1,pins = < + CIX_PAD_UART0_TXD_FUNC_UART0_TXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_RXD_FUNC_UART0_RXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_CTS_FUNC_UART0_CTS (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART0_RTS_FUNC_UART0_RTS (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart1: pinctrl_fch_uart1 { + sky1,pins = < + CIX_PAD_UART1_TXD_FUNC_UART1_TXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART1_RXD_FUNC_UART1_RXD (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART1_CTS_FUNC_UART1_CTS (PULL_UP|ST|DS_LEVEL7) + CIX_PAD_UART1_RTS_FUNC_UART1_RTS (PULL_UP|ST|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart2: pinctrl_fch_uart2 { + sky1,pins = < + CIX_PAD_UART2_TXD_FUNC_UART2_TXD (PULL_UP|DS_LEVEL7) + CIX_PAD_UART2_RXD_FUNC_UART2_RXD (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_fch_uart3: pinctrl_fch_uart3 { + sky1,pins = < + CIX_PAD_UART3_TXD_FUNC_UART3_TXD (PULL_UP|DS_LEVEL7) + CIX_PAD_UART3_RXD_FUNC_UART3_RXD (PULL_UP|DS_LEVEL7) + >; + }; + + pinctrl_hda: pinctrl_hda_grp { + sky1,pins = < + CIX_PAD_HDA_BITCLK_FUNC_HDA_BITCLK (PULL_DOWN|ST|DS_LEVEL12) /* hda bitclk */ + CIX_PAD_HDA_RST_L_FUNC_HDA_RST_L (PULL_DOWN|ST|DS_LEVEL12) /* hda rst */ + CIX_PAD_HDA_SDIN0_FUNC_HDA_SDIN0 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdin0 */ + CIX_PAD_HDA_SDOUT0_FUNC_HDA_SDOUT0 (PULL_UP|ST|DS_LEVEL12) /* hda sdout0 */ + CIX_PAD_HDA_SYNC_FUNC_HDA_SYNC (PULL_UP|ST|DS_LEVEL12) /* hda sync */ + CIX_PAD_HDA_SDIN1_FUNC_HDA_SDIN1 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdin1 */ + CIX_PAD_HDA_SDOUT1_FUNC_HDA_SDOUT1 (PULL_DOWN|ST|DS_LEVEL12) /* hda sdout1 */ + >; + }; + + pinctrl_substrate_i2s0: pinctrl_substrate_i2s0 { + sky1,pins = < + /* I2S0_SCK */ + CIX_PAD_HDA_BITCLK_FUNC_I2S0_SCK (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_DATA_IN */ + CIX_PAD_HDA_RST_L_FUNC_I2S0_DATA_IN (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_MCLK */ + CIX_PAD_HDA_SDIN0_FUNC_I2S0_MCLK (PULL_DOWN|ST|DS_LEVEL12) + /* I2S0_DATA_OUT */ + + CIX_PAD_HDA_SDOUT0_FUNC_I2S0_DATA_OUT (PULL_UP|ST|DS_LEVEL12) + /* I2S0_WS */ + CIX_PAD_HDA_SYNC_FUNC_I2S0_WS (PULL_UP|ST|DS_LEVEL12) + >; + }; + + pinctrl_substrate_i2s1: pinctrl_substrate_i2s1 { + sky1,pins = < + CIX_PAD_I2S1_MCLK_FUNC_I2S1_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_mclk */ + CIX_PAD_I2S1_SCK_FUNC_I2S1_SCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_sck */ + CIX_PAD_I2S1_WS_FUNC_I2S1_WS (PULL_UP|ST|DS_LEVEL12) /* i2s1_ws */ + CIX_PAD_I2S1_DATA_IN_FUNC_I2S1_DATA_IN (PULL_DOWN|ST|DS_LEVEL12) /* i2s1_data_in */ + CIX_PAD_I2S1_DATA_OUT_FUNC_I2S1_DATA_OUT (PULL_UP|ST|DS_LEVEL12) /* i2s1_data_out */ + >; + }; + + pinctrl_substrate_i2s2: pinctrl_substrate_i2s2 { + sky1,pins = < + CIX_PAD_I2S2_MCLK_FUNC_I2S2_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_mclk */ + CIX_PAD_I2S2_RSCK_FUNC_I2S2_RSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_rsck */ + CIX_PAD_I2S2_RWS_FUNC_I2S2_RWS (PULL_UP|ST|DS_LEVEL12) /* i2s2_rws */ + CIX_PAD_I2S2_TSCK_FUNC_I2S2_TSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_tsck */ + CIX_PAD_I2S2_TWS_FUNC_I2S2_TWS (PULL_UP|ST|DS_LEVEL12) /* i2s2_tws */ + CIX_PAD_I2S2_DATA_IN0_FUNC_I2S2_DATA_IN0 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_in0 */ + CIX_PAD_I2S2_DATA_IN1_FUNC_I2S2_DATA_IN1 (PULL_DOWN|ST|DS_LEVEL12) /* i2s2_data_in1 */ + CIX_PAD_I2S2_DATA_OUT0_FUNC_I2S2_DATA_OUT0 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out0 */ + CIX_PAD_I2S2_DATA_OUT1_FUNC_I2S2_DATA_OUT1 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out1 */ + CIX_PAD_I2S2_DATA_OUT2_FUNC_I2S2_DATA_OUT2 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out2 */ + CIX_PAD_I2S2_DATA_OUT3_FUNC_I2S2_DATA_OUT3 (PULL_UP|ST|DS_LEVEL12) /* i2s2_data_out3 */ + >; + }; + + pinctrl_substrate_i2s3: pinctrl_substrate_i2s3 { + sky1,pins = < + CIX_PAD_I2S3_MCLK_FUNC_I2S3_MCLK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_mclk */ + CIX_PAD_I2S3_RSCK_FUNC_I2S3_RSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_rsck */ + CIX_PAD_I2S3_RWS_FUNC_I2S3_RWS (PULL_UP|ST|DS_LEVEL12) /* i2s3_rws */ + CIX_PAD_I2S3_TSCK_FUNC_I2S3_TSCK (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_tsck */ + CIX_PAD_I2S3_TWS_FUNC_I2S3_TWS (PULL_UP|ST|DS_LEVEL12) /* i2s3_tws */ + CIX_PAD_I2S3_DATA_IN0_FUNC_I2S3_DATA_IN0 (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_data_in0 */ + CIX_PAD_I2S3_DATA_IN1_FUNC_I2S3_DATA_IN1 (PULL_DOWN|ST|DS_LEVEL12) /* i2s3_data_in1 */ + CIX_PAD_I2S3_DATA_OUT0_FUNC_I2S3_DATA_OUT0 (PULL_UP|ST|DS_LEVEL12) /* i2s3_data_out0 */ + CIX_PAD_I2S3_DATA_OUT1_FUNC_I2S3_DATA_OUT1 (PULL_UP|ST|DS_LEVEL12) /* i2s3_data_out1 */ + >; + }; + + pinctrl_substrate_i2s4_lb: pinctrl_substrate_i2s4_lb { + sky1,pins = < + CIX_PAD_GPIO090_FUNC_I2S4_MCLK_LB (ST|DS_LEVEL12) /* i2s4_mclk_lb */ + CIX_PAD_GPIO091_FUNC_I2S4_SCK_LB (ST|DS_LEVEL12) /* i2s4_sck_lb */ + CIX_PAD_GPIO092_FUNC_I2S4_WS_LB (ST|DS_LEVEL12) /* i2s4_ws_lb */ + CIX_PAD_GPIO093_FUNC_I2S4_DATA_IN_LB (ST|DS_LEVEL12) /* i2s4_data_in_lb */ + CIX_PAD_GPIO094_FUNC_I2S4_DATA_OUT_LB (ST|DS_LEVEL12) /* i2s4_data_out_lb */ + >; + }; + + pinctrl_edp0: pinctrl_edp0 { + sky1,pins = < + CIX_PAD_DP2_DIGON_FUNC_DP2_DIGON (PULL_DOWN|DS_LEVEL4) /* DP2_DIGON */ + CIX_PAD_DP2_BLON_FUNC_DP2_BLON (PULL_DOWN|DS_LEVEL4) /* DP2_BLON */ + >; + }; + + pinctrl_cam0_hw: pinctrl_cam0_hw { + sky1,pins = < + CIX_PAD_I2S3_DATA_OUT0_FUNC_GPIO088 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_DATA_OUT1_FUNC_GPIO089 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_MCLK_FUNC_GPIO081 (ST|DS_LEVEL12) + >; + }; + + pinctrl_cam1_hw: pinctrl_cam1_hw { + sky1,pins = < + CIX_PAD_I2S3_RSCK_FUNC_GPIO082 (PULL_DOWN|ST|DS_LEVEL12) + CIX_PAD_I2S3_MCLK_FUNC_GPIO081 (ST|DS_LEVEL12) + CIX_PAD_I2S3_TWS_FUNC_GPIO085 (PULL_DOWN|ST|DS_LEVEL12) + >; + }; + +}; + +&pwm0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm0>; + status = "okay"; +}; + +&pwm1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_pwm1>; + status = "disabled"; +}; + +&hifi5 { + status = "okay"; +}; + +&mbox_dsp2ap { + status = "okay"; +}; + +&mbox_ap2dsp { + status = "okay"; +}; + +&audss_cru { + status = "okay"; +}; + +&audss_clk { + status = "okay"; +}; + +&audss_rst { + status = "okay"; +}; + +&audss_dmac { + memory-region = <&audio_alsa>; + status = "okay"; +}; + +&i2s0 { + /* i2s_sc0 for codec */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s0>; + dmas = <&audss_dmac 0 0xff>, <&audss_dmac 1 0xff>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s1 { + /* i2s_sc1 for 5G/BT */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s1>; + dmas = <&audss_dmac 2 0xff>, <&audss_dmac 3 0xff>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s2 { + /* i2s_sc2 for loopback */ + dmas = <&audss_dmac 4 0xff>, <&audss_dmac 5 0xff>; + dma-names = "tx", "rx"; + status = "disabled"; +}; + +&i2s3 { + /* i2s_mc2a for speaker */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s2>; + dmas = <&audss_dmac 6 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; /* 0x00, zero pin as receiver */ + cdns,pin-tx-mask = /bits/ 8 <0x3c>; /* 0x3c, pin2-pin5 works as transmitter */ + status = "disabled"; +}; + +&i2s4 { + /* i2s_mc2b for dp-in */ + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_substrate_i2s3>; + dmas = <&audss_dmac 9 0xff>; + dma-names = "rx"; + cdns,pin-rx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as receiver */ + cdns,pin-tx-mask = /bits/ 8 <0x00>; + status = "disabled"; +}; + +&i2s5 { + /* i2s_mc5a for dp-out */ + dmas = <&audss_dmac 10 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s6 { + /* i2s_mc5b for dp-out */ + dmas = <&audss_dmac 12 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s7 { + /* i2s_mc5c for dp-out */ + dmas = <&audss_dmac 14 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "disabled"; +}; + +&i2s8 { + /* i2s_mc5d for dp-out */ + dmas = <&audss_dmac 16 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&i2s9 { + /* i2s_mc5e for dp-out */ + dmas = <&audss_dmac 18 0xff>; + dma-names = "tx"; + cdns,pin-rx-mask = /bits/ 8 <0x00>; + cdns,pin-tx-mask = /bits/ 8 <0x0f>; /* 0x0f, pin0-pin3 works as transmitter */ + status = "okay"; +}; + +&ipb_hda { + cix,model = "CIX SKY1 ORION O6 HDA"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hda>; + pdb-gpios = <&fch_gpio3 5 GPIO_ACTIVE_HIGH>; + memory-region = <&audio_alsa_hda>; + status = "okay"; +}; + +&sensorhub { + memory-region = <&sfh_vdev0buffer>, <&sfh_vdev0vring0>, + <&sfh_vdev0vring1>, <&sfh_ram>; + cix,auto-boot; + status = "disabled"; +}; + +&sfh_scp { + memory-region = <&sfh_sharebuffer>; + status = "disabled"; +}; + +&uart2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart2>; + clock-names = "uartclk", "apb_pclk"; + status = "okay"; +}; + +&dp0 { + status = "okay"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + + dp0_0_in: endpoint { + remote-endpoint = <&dpu0_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp0_1_in: endpoint { + remote-endpoint = <&dpu0_pipe1_out>; + }; + }; + }; +}; + +&dp1 { + status = "okay"; + cix,dp-max-rate = <540000>; + support_d3_cmd = "no"; + + ports { + port@0 { + reg = <0>; + + dp1_0_in: endpoint { + remote-endpoint = <&dpu1_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp1_1_in: endpoint { + remote-endpoint = <&dpu1_pipe1_out>; + }; + }; + }; +}; + +&dp2 { + status = "okay"; + edp-panel = <&panel_edp0>; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + + dp2_0_in: endpoint { + remote-endpoint = <&dpu2_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp2_1_in: endpoint { + remote-endpoint = <&dpu2_pipe1_out>; + }; + }; + }; +}; + +&dp3 { + status = "okay"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + + dp3_0_in: endpoint { + remote-endpoint = <&dpu3_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp3_1_in: endpoint { + remote-endpoint = <&dpu3_pipe1_out>; + }; + }; + }; +}; + +&dp4 { + status = "okay"; + cix,dp-max-rate = <540000>; + + ports { + port@0 { + reg = <0>; + + dp4_0_in: endpoint { + remote-endpoint = <&dpu4_pipe0_out>; + }; + }; + + port@1 { + reg = <1>; + + dp4_1_in: endpoint { + remote-endpoint = <&dpu4_pipe1_out>; + }; + }; + }; +}; + +&dpu0 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu0_pipe0_out: endpoint { + remote-endpoint = <&dp0_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu0_pipe1_out: endpoint { + remote-endpoint = <&dp0_1_in>; + }; + }; + }; +}; + +&dpu1 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu1_pipe0_out: endpoint { + remote-endpoint = <&dp1_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu1_pipe1_out: endpoint { + remote-endpoint = <&dp1_1_in>; + }; + }; + }; +}; + +&dpu2 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu2_pipe0_out: endpoint { + remote-endpoint = <&dp2_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu2_pipe1_out: endpoint { + remote-endpoint = <&dp2_1_in>; + }; + }; + }; +}; + +&dpu3 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu3_pipe0_out: endpoint { + remote-endpoint = <&dp3_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu3_pipe1_out: endpoint { + remote-endpoint = <&dp3_1_in>; + }; + }; + }; +}; + +&dpu4 { + status = "okay"; + aclk_freq_fixed = <800000000>; + + pipeline@0 { + lpu_raxi_aoutstdcapb = <32>; + lpu_raxi_boutstdcapb = <32>; + lpu_raxi_ben = <0>; + lpu_raxi_burstlen = <16>; + lpu_raxi_arqos = <15>; + lpu_raxi_ord = <0>; + lpu_waxi_outstdcapb = <16>; + lpu_waxi_burstlen = <16>; + lpu_waxi_awqos = <15>; + lpu_waxi_ord = <0>; + lpu_l0_arcache = <3>; + lpu_l1_arcache = <3>; + lpu_l2_arcache = <3>; + lpu_l3_arcache = <3>; + lpu_lw_arcache = <3>; + + port { + dpu4_pipe0_out: endpoint { + remote-endpoint = <&dp4_0_in>; + }; + }; + }; + + pipeline@1 { + port { + dpu4_pipe1_out: endpoint { + remote-endpoint = <&dp4_1_in>; + }; + }; + }; +}; + +&aeu0 { + status = "disabled"; +}; + +&aeu1 { + status = "disabled"; +}; + +&aeu2 { + status = "disabled"; +}; + +&aeu3 { + status = "disabled"; +}; + +&aeu4 { + status = "disabled"; +}; + +&gmac_rcsu { + status = "disabled"; +}; + +&macb0 { + status = "disabled"; +}; + +&macb1 { + status = "disabled"; +}; + +&usbc_phy0 { + orientation-switch; + svid = <0xff01>; + status = "okay"; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + + usbdpphy0_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_phy_sw>; + }; + }; +}; + +&usb3_phy0 { + status = "okay"; +}; + +&usbc0_dp_phy { + status = "okay"; +}; + +&sky1_usbss_0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb0>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_0 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + + cdnsp_0_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc0_role_sw>; + }; + }; +}; + +&usbc_phy1 { + status = "okay"; + default_conf = /bits/ 8 <0x02>; +}; + +&usb3_phy1 { + status = "disabled"; +}; + +&usbc1_dp_phy { + status = "okay"; +}; + +&sky1_usbss_1 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb1>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + u3-port-disable; + status = "okay"; +}; + +&usb2_phy1 { + compatible = "usb-nop-xceiv"; + status = "okay"; +}; + +&usbss_1 { + status = "okay"; + dr_mode = "host"; + phys = <&usb2_phy1>; + phy-names = "cdnsp,usb2-phy"; +}; + +&usbc_phy2 { + status = "okay"; + orientation-switch; + svid = <0xff01>; + default_conf = /bits/ 8 <0x03>; + mode-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + + usbdpphy2_lane_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_phy_sw>; + }; + }; +}; + +&usb3_phy2 { + status = "okay"; +}; + +&usbc2_dp_phy { + status = "okay"; +}; + +&sky1_usbss_2 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb2>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_2 { + status = "okay"; + dr_mode = "otg"; + usb-role-switch; + + port { + #address-cells = <1>; + #size-cells = <0>; + + cdnsp_2_role_switch: endpoint@0 { + reg = <0>; + remote-endpoint = <&usbc2_role_sw>; + }; + }; +}; + +&usbc_phy3 { + status = "okay"; + default_conf = /bits/ 8 <0x02>; +}; + +&usb3_phy3 { + status = "disabled"; +}; + +&usbc3_dp_phy { + status = "okay"; +}; + +&sky1_usbss_3 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb3>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + u3-port-disable; + status = "okay"; +}; + +&usb2_phy3 { + compatible = "usb-nop-xceiv"; + status = "okay"; +}; + +&usbss_3 { + status = "okay"; + dr_mode = "host"; + phys = <&usb2_phy3>; + phy-names = "cdnsp,usb2-phy"; +}; + +&usb3_phy4 { + status = "okay"; +}; + +&usb3_phy4_0 { + status = "okay"; +}; + +&sky1_usbss_4 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb4>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_4 { + status = "okay"; + dr_mode = "host"; +}; + +&usb3_phy4_1 { + status = "okay"; +}; + +&sky1_usbss_5 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb5>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbss_5 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_0 { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_usb6_usb7>; + pinctrl-assert-gpios = <&s5_gpio0 29 0>; + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_0 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_1 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_1 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_2 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_2 { + status = "okay"; + dr_mode = "host"; +}; + +&sky1_usbhs_3 { + sof_clk_freq = <8000000>; + lpm_clk_freq = <32000>; + status = "okay"; +}; + +&usbhs_3 { + status = "okay"; + dr_mode = "host"; +}; + +&i2c0 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c0>; +}; + +&i2c1 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c1>; + clock-frequency = <100000>; + + rts5453_pd1_port0:rts5453@30 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; + id = <0>; + reg = <0x30>; + status = "okay"; + + usbc_con0 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usbc0_role_sw: endpoint { + remote-endpoint = <&cdnsp_0_role_switch>; + }; + }; + + port@1 { + reg = <1>; + + usbc0_phy_sw: endpoint { + remote-endpoint = <&usbdpphy0_lane_switch>; + }; + }; + }; + }; + + rts5453_pd1_port1:rts5453@31 { + compatible = "realtek,rts5453h"; + interrupt-parent = <&s5_gpio0>; + interrupts = <8 IRQ_TYPE_LEVEL_LOW>; + id = <2>; + reg = <0x31>; + status = "okay"; + + usbc_con2 { + data-role = "host"; + power-role = "source"; + try-power-role = "source"; + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + + usbc2_role_sw: endpoint { + remote-endpoint = <&cdnsp_2_role_switch>; + }; + }; + + port@1 { + reg = <1>; + + usbc2_phy_sw: endpoint { + remote-endpoint = <&usbdpphy2_lane_switch>; + }; + }; + }; + }; +}; + +&i7_isp { + status = "okay"; +}; + +&armcb_config { + status = "okay"; +}; + +&armcb_ispmem { + status = "okay"; +}; + +&cix_vi_hw { + status = "okay"; +}; + +&i2c0 { + imgsensor00: imgsensor00@34 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x34>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam0_hw>; + pinctrl-1 = <&pinctrl_cam0_hw>; + reset-gpios = <&fch_gpio1 13 GPIO_ACTIVE_HIGH>; + pwdn-gpios = <&fch_gpio1 14 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK0>; + clock-names = "mclk"; + cix,camera-module-index = <0>; + actuator-src = <&isp_motor>; + isp-src = <&i7_isp>; + power0-supply = <&cam_power_en>; + status = "okay"; + }; + + isp_motor: motor0@40 { + compatible = "motor,ms42919"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x40>; + pi-max-frequency = <124999999>; + status = "okay"; + }; +}; +/* +&i2c1 { + imgsensor01: imgsensor01@36 { + compatible = "image,sensor0"; + #address-cells = <1>; + #size-cells = <0>; + reg = <0x36>; + pinctrl-names = "default","gpio"; + pinctrl-0 = <&pinctrl_cam1_hw>; + pinctrl-1 = <&pinctrl_cam1_hw>; + pwdn-gpios = <&fch_gpio1 7 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio1 10 GPIO_ACTIVE_HIGH>; + clocks = <&scmi_clk CLK_TREE_CAMERA_MCLK2>; + clock-names = "mclk"; + cix,camera-module-index = <1>; + power0-supply = <&cam_power_en>; + status = "okay"; + }; +}; +*/ +&i2c2 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + + radxa_touch: radxa-touch@14 { + compatible = "goodix,gt911"; + reg = <0x14>; + interrupt-parent = <&fch_gpio2>; + interrupts = <29 IRQ_TYPE_EDGE_RISING>; + irq-gpios = <&fch_gpio2 29 GPIO_ACTIVE_HIGH>; + reset-gpios = <&fch_gpio2 22 GPIO_ACTIVE_HIGH>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_touch_panel>; + }; + + i2c-hid-dev@68 { + compatible = "hid-over-i2c"; + reg = <0x68>; + hid-descr-addr = <0x0020>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hiddev_68_irq>; + interrupt-parent = <&s5_gpio0>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + status = "disabled"; + }; + + i2c-hid-dev@15 { + compatible = "hid-over-i2c"; + reg = <0x15>; + hid-descr-addr = <0x0001>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hiddev_15_irq>; + interrupt-parent = <&s5_gpio0>; + interrupts = <9 IRQ_TYPE_LEVEL_LOW>; + status = "disabled"; + }; +}; + +&i2c2_slave { + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c2>; + clock-frequency = <1000000>; + status = "disabled"; +}; + +&i2c3 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c3>; + + hym8563: hym8563@51 { + compatible = "haoyu,hym8563"; + reg = <0x51>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_hym8563_irq>; + interrupt-parent = <&s5_gpio0>; + interrupts = <10 IRQ_TYPE_LEVEL_LOW>; + status = "okay"; + }; +}; + +&i2c4 { + status = "okay"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c4>; + + nfc: nfc@28 { + status = "disabled"; + compatible = "nfc,nfc_28h"; + reg = <0x28>; + }; +}; + +/* EC_HID */ +&i2c5 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c5>; + + keyboard_0: keyboard@3a { + compatible = "hid-over-i2c"; + reg = <0x3a>; + interrupt-parent = <&s5_gpio0>; + interrupts = <0 IRQ_TYPE_EDGE_RISING>; + hid-descr-addr = <0x0001>; + status = "disabled"; + }; +}; + +/* EC_HOST */ +&i2c6 { + status = "okay"; + clock-frequency = <100000>; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c6>; + + cros_ec: ec@76 { + compatible = "google,cros-ec-i2c"; + reg = <0x76>; + interrupt-parent = <&s5_gpio0>; + interrupts = <6 IRQ_TYPE_EDGE_RISING>; + wakeup-source; + status = "okay"; + }; +}; + +&cros_ec { + cros_ec_pwm: ec-pwm { + compatible = "google,cros-ec-pwm"; + #pwm-cells = <1>; + status = "disabled"; + }; + + cix_fan: pwm-fan { + compatible = "pwm-fan"; + cooling-levels = <0 150 200 255>; + #cooling-cells = <2>; + pwms = <&cros_ec_pwm 0>; + status = "disabled"; + }; + + cix_ec_light { + compatible = "cix,cix-ec-light"; + status = "disabled"; + }; + + cix_ec_lid { + compatible = "cix,cix-ec-lid"; + status = "disabled"; + }; + + cix_ec_battery { + compatible = "cix,cix-ec-battery"; + status = "disabled"; + }; + + cix_ec_charge { + compatible = "cix,cix-ec-charge"; + status = "disabled"; + }; + + cix_ec_kb_backlight{ + compatible = "cix,cix-ec-keyboard-backlight"; + status = "disabled"; + }; + + ec_gpio: cix_ec_gpio { + compatible = "cix,cix-ec-gpio"; + gpio-controller; + #gpio-cells = <2>; + ngpios = <104>; + status = "disabled"; + }; + + cix_ec_pwrkey { + compatible = "cix,cix-ec-pwrkey"; + status = "okay"; + }; + + cix_ec_excp { + compatible = "cix,cix-ec-excp"; + status = "disabled"; + }; + + cix_ec_sleevekey { + compatible = "cix,cix-ec-sleevekey"; + status = "okay"; + }; +}; + +&i2c7 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i2c7>; + clock-frequency = <100000>; +}; + +&sf_i2c0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i2c0>; +}; + +&sf_i2c1 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i2c1>; +}; + +&i3c0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c0>; + i3c-scl-hz = <100000>; +}; + +&i3c1 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_i3c1>; + 3c-scl-hz = <100000>; +}; + +&sf_i3c0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i3c0>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; +}; + +&sf_i3c1 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_i3c1>; + i3c-scl-hz = <100000>; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; +}; + +&spi0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi0>; + /* Character device nodes for device communication on CS0(/dev/spidev0.0) */ + spidev0_0: spi@0_0 { + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev0.1) */ + spidev0_1: spi@0_1 { + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +&spi1 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_spi1>; + /* Character device nodes for device communication on CS0(/dev/spidev1.0) */ + spidev1_0: spi@1_0 { + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; +}; + +&sf_spi { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_sfi_spi>; + /* Character device nodes for device communication on CS0(/dev/spidev2.0) */ + spidev2_0: spi@2_0 { + compatible = "rohm,dh2228fv"; + reg = <0>; + spi-max-frequency = <5000000>; + }; + /* Character device nodes for device communication on CS1(/dev/spidev2.1) */ + spidev2_1: spi@2_1 { + compatible = "rohm,dh2228fv"; + reg = <1>; + spi-max-frequency = <5000000>; + }; +}; + +&xspi { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_xspi>; + + flash@0 { + compatible = "jedec,spi-nor"; + reg = <0>; + spi-rx-bus-width = <4>; + spi-max-frequency = <25000000>; + }; +}; + +&uart0 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart0>; + dmas = <&fch_dmac 2 0>, <&fch_dmac 3 1>; + dma-names = "tx","rx"; +}; + +&uart1 { + status = "disabled"; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_fch_uart1>; + dmas = <&fch_dmac 4 2>, <&fch_dmac 5 3>; + dma-names = "tx","rx"; +}; + +&aipu_res_0 { + status = "okay"; +}; + +&npu { + status = "okay"; +}; + +&its_pcie { + status = "okay"; +}; + +&smmu_pciehub { + status = "disabled"; +}; + +&smmu_mmhub { + status = "okay"; +}; + +/* PCIe X16 Slot */ +&pcie_x8_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x8_rc>; + reset-gpios = <&s5_gpio0 1 GPIO_ACTIVE_HIGH>; + vcc-pcie-supply = <&vgfx_power>; + status = "okay"; +}; + +/* M.2 M-Key */ +&pcie_x4_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x4_rc>; + reset-gpios = <&s5_gpio0 3 GPIO_ACTIVE_HIGH>; + status = "okay"; +}; + +/* M.2 E-Key */ +&pcie_x2_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x2_rc>; + reset-gpios = <&s5_gpio0 4 GPIO_ACTIVE_HIGH>; + vcc-pcie-supply = <&vdd_3v3_pcie>; + status = "okay"; +}; + +/* 5GBE-1 */ +&pcie_x1_1_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_1_rc>; + reset-gpios = <&s5_gpio0 2 GPIO_ACTIVE_HIGH>; + vcc-pcie-supply = <&gbe1_power_3v3>; + status = "okay"; +}; + +/* 5GBE-2 */ +&pcie_x1_0_rc { + plat-evk; + pinctrl-names = "default"; + pinctrl-0 = <&pinctrl_pcie_x1_0_rc>; + reset-gpios = <&s5_gpio0 5 GPIO_ACTIVE_HIGH>; + vcc-pcie-supply = <&gbe2_power_3v3>; + status = "okay"; +}; + +&pcie1_phy { + status = "okay"; +}; + +&pcie_x4_phy { + status = "okay"; +}; + +&pcie0_phy { + status = "okay"; +}; + +&pcie_x8_phy { + status = "okay"; +}; + +&pciex211_phy { + status = "okay"; +}; + +&pcie_x1_phy0 { + status = "okay"; +}; + +&pcie_x1_phy1 { + status = "okay"; +}; + +&pcie_x2_phy { + status = "okay"; +}; + +&mbox_ap2pm { + status = "okay"; +}; + +&mbox_pm2ap { + status = "okay"; +}; + +&mbox_se2ap { + status = "okay"; +}; + +&mbox_ap2se { + status = "okay"; +}; + +&sky1_crash { + status = "okay"; +}; + +&ap2pm_scmi_mem { + status = "okay"; +}; + +&pm2ap_scmi_mem { + status = "okay"; +}; + +&ap_tfa_scmi_mem { + status = "okay"; +}; + +&ap_to_pm_scmi { + status = "okay"; +}; + +&ap_to_tfa_scmi { + status = "okay"; +}; + +&scmi_dvfs { + status = "okay"; +}; + +&vpu { + status = "okay"; +}; + +&ramoops { + status = "okay"; +}; + +&watchdog { + status = "okay"; +}; + +&cix_dst { + status = "okay"; +}; + +&exception_trace { + status = "okay"; +}; + +&ap_adapter { + status = "okay"; +}; + +&mntndump { + status = "okay"; +}; + +&ddr_ctrl0 { + status = "okay"; +}; + +&ddr_ctrl1 { + status = "okay"; +}; + +&ddr_ctrl2 { + status = "okay"; +}; + +&ddr_ctrl3 { + status = "okay"; +}; + +&thermal_zones { + cpu-m1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M1_TEMP_SENSOR_ID>; + sustainable-power = <4500>; + + trips { + m1_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + m1_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + m1_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&m1_trip0>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&m1_trip1>; + cooling-device = <&CPU6 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B1_TEMP_SENSOR_ID>; + sustainable-power = <6000>; + + trips { + b1_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + b1_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + b1_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&b1_trip0>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&b1_trip1>; + cooling-device = <&CPU10 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-m0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_M0_TEMP_SENSOR_ID>; + sustainable-power = <5000>; + + trips { + m0_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + m0_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + m0_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&m0_trip0>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&m0_trip1>; + cooling-device = <&CPU4 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + + cpu-b0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CPU_B0_TEMP_SENSOR_ID>; + sustainable-power = <5500>; + + trips { + b0_trip0: trip-point-0 { + temperature = <60000>; + hysteresis = <1000>; + type = "passive"; + }; + b0_trip1: trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + b0_trip2: trip-point-2 { + temperature = <98000>; + hysteresis = <1000>; + type = "critical"; + }; + }; + + cooling-maps { + map0 { + trip = <&b0_trip0>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&b0_trip1>; + cooling-device = <&CPU8 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; +}; + +&cix_ipa { + status = "okay"; +}; diff --git a/arch/arm64/boot/dts/cix/sky1.dtsi b/arch/arm64/boot/dts/cix/sky1.dtsi new file mode 100755 index 000000000000..629018057674 --- /dev/null +++ b/arch/arm64/boot/dts/cix/sky1.dtsi @@ -0,0 +1,4448 @@ +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/memreserve/ 0x80000000 0x6000000; + +/ { + interrupt-parent = <&pdc>; + #address-cells = <2>; + #size-cells = <2>; + + aliases { + serial0 = &uart0; + serial1 = &uart1; + serial2 = &uart2; + serial3 = &uart3; + serial4 = &uart4; + serial5 = &uart5; + cix-bridge0 = &cix_bridge_0; + cix-bridge1 = &cix_bridge_1; + cix-bridge2 = &cix_bridge_2; + cix-bridge3 = &cix_bridge_3; + cix-csi0 = &cix_mipi_csi_0; + cix-csi1 = &cix_mipi_csi_1; + cix-csi2 = &cix_mipi_csi_2; + cix-csi3 = &cix_mipi_csi_3; + cix-dphy0 = &cix_dphy_0; + cix-dphy1 = &cix_dphy_1; + cix-dphy2 = &cix_dphy_2; + cix-dphy3 = &cix_dphy_3; + cix-dphy4 = &cix_dphy_4; + cix-dphy5 = &cix_dphy_5; + cix-dphy-hw0 = &cix_dphy_hw_0; + cix-dphy-hw1 = &cix_dphy_hw_1; + pcie_rc0 = &pcie_x8_rc; + pcie_rc1 = &pcie_x4_rc; + pcie_rc2 = &pcie_x2_rc; + pcie_rc3 = &pcie_x1_1_rc; + pcie_rc4 = &pcie_x1_0_rc; + i2s0 = &i2s0; + i2s1 = &i2s1; + i2s2 = &i2s2; + i2s3 = &i2s3; + i2s4 = &i2s4; + i2s5 = &i2s5; + i2s6 = &i2s6; + i2s7 = &i2s7; + i2s8 = &i2s8; + i2s9 = &i2s9; + usb0 = &sky1_usbss_0; + usb1 = &sky1_usbss_1; + usb2 = &sky1_usbss_2; + usb3 = &sky1_usbss_3; + usb4 = &sky1_usbss_4; + usb5 = &sky1_usbss_5; + usb6 = &sky1_usbhs_0; + usb7 = &sky1_usbhs_1; + usb8 = &sky1_usbhs_2; + usb9 = &sky1_usbhs_3; + usbdpphy0 = &usbc_phy0; + usbdpphy1 = &usbc_phy1; + usbdpphy2 = &usbc_phy2; + usbdpphy3 = &usbc_phy3; + i2c0 = &i2c0; + i2c1 = &i2c1; + i2c2 = &i2c2; + i2c3 = &i2c3; + i2c4 = &i2c4; + i2c5 = &i2c5; + i2c6 = &i2c6; + i2c7 = &i2c7; + i2c8 = &sf_i2c0; + i2c9 = &sf_i2c1; + i2c10 = &i2c2_slave; + i3c0 = &i3c0; + i3c1 = &i3c1; + i3c2 = &sf_i3c0; + i3c3 = &sf_i3c1; + spi0 = &spi0; + spi1 = &spi1; + spi2 = &sf_spi; + gpio0 = &s5_gpio0; + gpio1 = &s5_gpio1; + gpio2 = &s5_gpio2; + gpio3 = &fch_gpio0; + gpio4 = &fch_gpio1; + gpio5 = &fch_gpio2; + gpio6 = &fch_gpio3; + linlondp0 = &dpu0; + linlondp1 = &dpu1; + linlondp2 = &dpu2; + linlondp3 = &dpu3; + linlondp4 = &dpu4; + }; + + cpus { + #address-cells = <2>; + #size-cells = <0>; + + cpu-map { + cluster0 { + core0 { + cpu = <&CPU0>; + }; + core1 { + cpu = <&CPU1>; + }; + core2 { + cpu = <&CPU2>; + }; + core3 { + cpu = <&CPU3>; + }; + core4 { + cpu = <&CPU4>; + }; + core5 { + cpu = <&CPU5>; + }; + core6 { + cpu = <&CPU6>; + }; + core7 { + cpu = <&CPU7>; + }; + core8 { + cpu = <&CPU8>; + }; + core9 { + cpu = <&CPU9>; + }; + core10 { + cpu = <&CPU10>; + }; + core11 { + cpu = <&CPU11>; + }; + }; + }; + + idle-states { + CPU_SLEEP_0: cpu-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x0010000>; + local-timer-stop; + entry-latency-us = <34>; + exit-latency-us = <100>; + min-residency-us = <3000>; + }; + + CPU_SLEEP_1: cpu-sleep-1 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x10000>; + local-timer-stop; + entry-latency-us = <31>; + exit-latency-us = <79>; + min-residency-us = <3000>; + }; + + CLUSTER_SLEEP_0: cluster-sleep-0 { + compatible = "arm,idle-state"; + arm,psci-suspend-param = <0x1010000>; + local-timer-stop; + entry-latency-us = <41>; + exit-latency-us = <104>; + min-residency-us = <4000>; + }; + }; + + CPU0: cpu0@0 { + compatible = "arm,armv8"; + reg = <0x0 0x0>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU1: cpu1@100 { + compatible = "arm,armv8"; + reg = <0x0 0x100>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU2: cpu2@200 { + compatible = "arm,armv8"; + reg = <0x0 0x200>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU3: cpu3@300 { + compatible = "arm,armv8"; + reg = <0x0 0x300>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 2>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <403>; + }; + + CPU4: cpu4@400 { + compatible = "arm,armv8"; + reg = <0x0 0x400>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 5>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU5: cpu5@500 { + compatible = "arm,armv8"; + reg = <0x0 0x500>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 5>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU6: cpu6@600 { + compatible = "arm,armv8"; + reg = <0x0 0x600>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 6>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU7: cpu7@700 { + compatible = "arm,armv8"; + reg = <0x0 0x700>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 6>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU8: cpu8@800 { + compatible = "arm,armv8"; + reg = <0x0 0x800>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 3>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU9: cpu9@900 { + compatible = "arm,armv8"; + reg = <0x0 0x900>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 3>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU10: cpu10@a00 { + compatible = "arm,armv8"; + reg = <0x0 0xa00>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 4>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + + CPU11: cpu11@b00 { + compatible = "arm,armv8"; + reg = <0x0 0xb00>; + device_type = "cpu"; + enable-method = "psci"; + clocks = <&scmi_dvfs 4>; + #cooling-cells = <2>; + cpu-idle-states = <&CPU_SLEEP_1 &CLUSTER_SLEEP_0>; + capacity-dmips-mhz = <1024>; + }; + }; + + dsu_pctrl: dsu_pctrl { + compatible = "arm,dsu_pctrl_r0"; + size = <8192>; /* size in KB */ + line-size = <64>; + static-leakage-per-mb = <10000>; /*uW/MB */ + dram-energy-per-mb = <130>; /* uJ/MB */ + polling = <10000>; /* miliseconds */ + /* hw-automatic-control; */ + /* cluster-l3-dn-th0 = <100>; */ + /* cluster-l3-dn-th1 = <200>; */ + /* cluster-l3-up-th0 = <300>; */ + /* cluster-l3-up-th1 = <400>; */ + /* cluster-l3-up-th2 = <500>; */ + /* cluster-l3-auto-interval = <5>; */ /* IMP_CLUSTERPWRCTLR_EL1.AUTOPRTN */ + status = "disabled"; + }; + + /* + * L3 cache in the DSU is the Memory System Component (MSC) + * The MPAM registers are accessed through utility bus in the DSU + */ + msc0 { + compatible = "arm,mpam-msc"; + reg = <0x0 0xf010000 0x0 0x2000>; + status = "disabled"; + }; + + memory@80000000 { + #address-cells = <2>; + #size-cells = <2>; + device_type = "memory"; + reg = <0x00000000 0x80000000 0x1 0x00000000>; + }; + + reserved-memory { + #address-cells = <2>; + #size-cells = <2>; + ranges; + + linux,cma { + compatible = "shared-dma-pool"; + reusable; + size = <0x0 0x28000000>; + linux,cma-default; + }; + + dpu_gop: dpu_gop@84800000 { + reg = <0x0 0x84800000 0x0 0x2000000>; + iommu-addresses = <&dpu0 0x0 0x84800000 0x0 0x02000000>, + <&dpu1 0x0 0x84800000 0x0 0x02000000>, + <&dpu2 0x0 0x84800000 0x0 0x02000000>, + <&dpu3 0x0 0x84800000 0x0 0x02000000>, + <&dpu4 0x0 0x84800000 0x0 0x02000000>; + status = "disabled"; /* not for device dma and cma memory */ + no-map; + }; + + smc_shmem_reserved: smc_shmem@84380000 { + reg = <0x0 0x84380000 0x0 0x80000>; + no-map; + }; + + smc_shmem_tee_reserved: smc_shmem@82500000 { + reg = <0x0 0x82500000 0x0 0xb00000>; + no-map; + }; + + ramoops: cix_ramoops@83d00000 { + compatible = "ramoops"; + reg = <0x0 0x83d00000 0x0 0x000a0000>; + record-size = <0x10000>; + console-size = <0x10000>; + pmsg-size = <0x1000>; + status = "disabled"; + }; + + mntndump: mntndump@83de0000 { + compatible = "cix-dst,mntndump"; + no-map; + reg = <0 0x83de0000 0 0x00020000>; + status = "disabled"; + }; + + rdr_res_region: rdr@83000000 { + reg = <0 0x83000000 0 0x400000>; + no-map; + }; + + sfh_vdev0vring0: vdev0vring0@84000000 { + reg = <0x0 0x84000000 0x0 0x4000>; /* 16k for vring0 */ + no-map; + }; + + sfh_vdev0vring1: vdev0vring1@84004000 { + reg = <0x0 0x84004000 0x0 0x4000>; /* 16k for vring1 */ + no-map; + }; + + sfh_vdev0buffer: vdev0buffer@84008000 { /* 1M for tx/rx buffer */ + compatible = "shared-dma-pool"; + reg = <0x0 0x84008000 0x0 0x100000>; + no-map; + }; + + sfh_sharebuffer: sfh_sharebuffer@84800000 { + reg = <0x0 0x84800000 0x0 0x800000>; /* 8M for IPC */ + no-map; + }; + + sfh_ram: ram0@1ca0000000 { /* 512KB RAM */ + reg = <0x1c 0xa0000000 0x0 0x80000>; + no-map; + }; + + aipu_res_0: memory@90000000 { + compatible = "shared-dma-pool"; + no-map; + reg = <0x0 0x90000000 0x0 0x20000000>; + }; + + mali_protected: mali_protected@bce00000 { + compatible = "mali-reserved"; + reg = <0x0 0xbce00000 0x0 0x1000000>; + }; + + vpu_private: vpu_private { + reg = <0x0 0xbde00000 0x0 0x800000>; + no-map; + status = "disabled"; + }; + + vpu_protected: vpu_protected { + reg = <0x0 0xbe600000 0x0 0x1800000>; + no-map; + status = "disabled"; + }; + + media_protected: media_protected { + reg = <0x0 0xbfe00000 0x0 0xe000000>; + no-map; + status = "disabled"; + }; + + dsp_vdev0vring0: vdev0vring0@cde00000 { + reg = <0x0 0xcde00000 0x0 0x4000>; /* 16k for vring0 */ + no-map; + }; + + dsp_vdev0vring1: vdev0vring1@cde04000 { + reg = <0x0 0xcde04000 0x0 0x4000>; /* 16k for vring1 */ + no-map; + }; + + dsp_vdev0buffer: vdev0buffer@cde08000 { /* 1M for tx/rx buffer */ + compatible = "shared-dma-pool"; + reg = <0x0 0xcde08000 0x0 0x100000>; + no-map; + }; + + dsp_reserved: dsp_reserved { + reg = <0x0 0xce000000 0x0 0x1000000>; + no-map; + }; + + dsp_reserved_heap: dsp_reserved_heap { + reg = <0x0 0xcf000000 0x0 0x1000000>; + no-map; + }; + + audio_alsa: audio_alsa@d0000000 { + compatible = "shared-dma-pool"; + reg = <0x0 0xd0000000 0x0 0xc00000>; + no-map; + }; + + audio_alsa_hda: audio_alsa_hda@d0c00000 { + compatible = "shared-dma-pool"; + reg = <0x0 0xd0c00000 0x0 0x200000>; + no-map; + }; + + }; + + smmu_syshub: iommu@0b0e0000 { + compatible = "arm,smmu-v3"; + reg = <0 0x0b0e0000 0x0 0xc0000>; + #iommu-cells = <1>; + interrupts = , + , + , + ; + interrupt-names = "eventq", "priq", "cmdq-sync", "gerror"; + status = "disabled"; + }; + + smmu_mmhub: iommu@0b1b0000 { + compatible = "arm,smmu-v3"; + reg = <0 0x0b1b0000 0x0 0x400000>; + #iommu-cells = <1>; + interrupts = , + , + , + ; + interrupt-names = "eventq", "priq", "cmdq-sync", "gerror"; + status = "disabled"; + }; + + smmu_pciehub: iommu@0b010000 { + compatible = "arm,smmu-v3"; + reg = <0 0x0b010000 0x0 0xc0000>; + #iommu-cells = <1>; + interrupts = , + , + , + ; + interrupt-names = "eventq", "priq", "cmdq-sync", "gerror"; + status = "disabled"; + }; + + smmu_mmhub_tcu: smmu-mmhub-tcu@0xb1b0000 { + compatible = "arm,smmu-v3-pmcg"; /* smmu mmhub tcu pmu */ + reg = <0x0 0xb1b2000 0x0 0x1000>, + <0x0 0xb1d2000 0x0 0x1000>; + interrupts = ; + interrupt-names = "SMMU_MMHUB TCU"; + status = "disabled"; + }; + + smmu_mmhub_npu_tbu0: smmu-mmhub-npu_tbu0@0xb3d0000 { + compatible = "arm,smmu-v3-pmcg"; /* smmu mmhub npu tbu0 pmu */ + reg = <0x0 0xb3d2000 0x0 0x1000>, + <0x0 0xb3e2000 0x0 0x1000>; + interrupts = ; + interrupt-names = "SMMU_MMHUB NPU TBU0"; + status = "disabled"; + }; + + smmu_mmhub_npu_tbu1: smmu-mmhub-npu_tbu1@0xb3f0000 { + compatible = "arm,smmu-v3-pmcg"; /* smmu mmhub npu tbu1 pmu */ + reg = <0x0 0xb3f2000 0x0 0x1000>, + <0x0 0xb402000 0x0 0x100>; + interrupts = ; + interrupt-names = "SMMU_MMHUB NPU TBU1"; + status = "disabled"; + }; + + pmu: pmu { + compatible = "arm,armv8-pmuv3"; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + spe_pmu: spe_pmu { + compatible = "arm,statistical-profiling-extension-v1"; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; + + psci { + compatible = "arm,psci-1.0"; + method = "smc"; + }; + + pdc: pdc@16000000 { + compatible = "cix,sky1-pdc", "syscon"; + reg = <0x0 0x16000000 0x0 0x1000>; + interrupt-controller; + #interrupt-cells = <3>; + interrupt-parent = <&gic>; + }; + + arch_timer: timer { + compatible = "arm,armv8-timer"; + interrupts = , + , + , + ; + clock-frequency = <1000000000>; + interrupt-parent = <&gic>; + arm,no-tick-in-suspend; +#ifdef CONFIG_ARCH_CIX_EMU_FPGA + always-on; /* only on EMU/FPGA */ +#endif + }; + + sky1_fixed_clocks: fixed-clocks { + i2cclk: i2cclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "i2cclk"; + }; + + spi_ref_clk: spi_ref_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "spi_ref_clk"; + }; + + spi_apb_pclk: spi_apb_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "spi_apb_pclk"; + }; + + uartclk: uartclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "uartclk"; + }; + + uart_apb_pclk: uart_apb_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "apb_pclk"; + }; + + i3c_apb_clk: i3c_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "i3c_apb_clk"; + }; + + i3c_sys_clk: i3c_sys_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "i3c_sys_clk"; + }; + + xspi_maclk: xspi_maclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "xspi_maclk"; + }; + + xspi_pclk: xspi_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "xspi_apb_pclk"; + }; + + xspi_funcclk: xspi_funcclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "xspi_funcclk"; + }; + + dma_axi_clk: dma_axi_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "dma_axi_clk"; + }; + + dma_apb_pclk: dma_apb_pclk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "dma_apb_pclk"; + }; + + dfd_clk: dummyclk { + compatible = "fixed-clock"; + clock-frequency = <800000000>; + #clock-cells = <0>; + }; + + fch_timer_apb_clk: fch_timer_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "fch_timer_apb_clk"; + }; + + fch_timer_func_clk: fch_timer_func_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <25000000>; + clock-output-names = "fch_timer_func_pclk"; + }; + + s5_gpio_apb_clk: s5_gpio_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <100000000>; + clock-output-names = "s5_gpio_apb_clk"; + }; + + fch_gpio_apb_clk: fch_gpio_apb_clk { + compatible = "fixed-clock"; + #clock-cells = <0>; + clock-frequency = <200000000>; + clock-output-names = "fch_gpio_apb_clk"; + }; + }; + + soc@0 { + compatible = "simple-bus"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + dma-ranges; + + i2c0: i2c@04010000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04010000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C0_APB>; + resets = <&src_fch SW_I2C0_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c1: i2c@04020000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04020000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C1_APB>; + resets = <&src_fch SW_I2C1_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c2: i2c@04030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04030000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C2_APB>; + resets = <&src_fch SW_I2C2_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c2_slave: i2c_slave@04030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04030000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C2_APB>; + resets = <&src_fch SW_I2C2_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c3: i2c@04040000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04040000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C3_APB>; + resets = <&src_fch SW_I2C3_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c4: i2c@04050000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04050000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C4_APB>; + resets = <&src_fch SW_I2C4_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c5: i2c@04060000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04060000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C5_APB>; + resets = <&src_fch SW_I2C5_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c6: i2c@04070000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04070000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C6_APB>; + resets = <&src_fch SW_I2C6_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + i2c7: i2c@04080000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x04080000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&scmi_clk CLK_TREE_FCH_I2C7_APB>; + resets = <&src_fch SW_I2C7_RST_APB_N>; + reset-names = "i2c_reset"; + interrupts = ; + status = "disabled"; + }; + + spi0: spi@04090000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,spi-r1p6"; + reg = <0x0 0x04090000 0x0 0x10000>; + clocks = <&scmi_clk CLK_TREE_FCH_SPI0_APB>, + <&scmi_clk CLK_TREE_FCH_SPI0_APB>; + clock-names = "pclk", "ref_clk"; + resets = <&src_fch SW_SPI0_RST_APB_N>; + reset-names = "spi_reset"; + interrupts = ; + fifo-width = <32>; + status = "disabled"; + }; + + spi1: spi@040a0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,spi-r1p6"; + reg = <0x0 0x040a0000 0x0 0x10000>; + clocks = <&scmi_clk CLK_TREE_FCH_SPI1_APB>, + <&scmi_clk CLK_TREE_FCH_SPI1_APB>; + clock-names = "pclk", "ref_clk"; + resets = <&src_fch SW_SPI1_RST_APB_N>; + reset-names = "spi_reset"; + interrupts = ; + fifo-width = <32>; + status = "disabled"; + }; + + uart0: uart@040b0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040b0000 0x0 0x1000>; + timeout-enable; + timeout-value = <250000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART0_FUNC>, <&scmi_clk CLK_TREE_FCH_UART0_APB>; + clock-names = "uartclk", "apb_pclk"; + resets = <&src_fch SW_UART0_RST_FUNC_N>, <&src_fch SW_UART0_RST_APB_N>; + reset-names = "uart_func_reset", "uart_apb_reset"; + status = "disabled"; + }; + + uart1: uart@040c0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040c0000 0x0 0x1000>; + timeout-enable; + timeout-value = <250000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART1_FUNC>, <&scmi_clk CLK_TREE_FCH_UART1_APB>; + clock-names = "uartclk", "apb_pclk"; + resets = <&src_fch SW_UART1_RST_FUNC_N>, <&src_fch SW_UART1_RST_APB_N>; + reset-names = "uart_func_reset", "uart_apb_reset"; + status = "disabled"; + }; + + uart2: uart@040d0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040d0000 0x0 0x1000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART2_FUNC>, <&scmi_clk CLK_TREE_FCH_UART2_APB>; + clock-names = "uartclk", "apb_pclk"; + status = "disabled"; + }; + + uart3: uart@040e0000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x040e0000 0x0 0x1000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_UART3_FUNC>, <&scmi_clk CLK_TREE_FCH_UART3_APB>; + clock-names = "uartclk", "apb_pclk"; + status = "disabled"; + }; + + uart4: uart@06540000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x6540000 0x0 0x1000>; + status = "disabled"; + }; + + uart5: uart@05020000 { + compatible = "arm,pl011", "arm,primecell"; + reg = <0x0 0x5020000 0x0 0x1000>; + interrupts = ; + status = "disabled"; + }; + + i3c0: i3c@040f0000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x040f0000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_I3C0_APB>, <&scmi_clk CLK_TREE_FCH_I3C0_FUNC>; + clock-names = "pclk", "sysclk"; + resets = <&src_fch SW_I3C0_RST_FUNC_G_N>, <&src_fch SW_I3C0_RST_FUNC_I_N>, <&src_fch SW_I3C0_RST_APB_N>; + reset-names = "i3c_funcg","i3c_funci","i3c_apb"; + status = "disabled"; + }; + + i3c1: i3c@04100000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x04100000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_I3C1_APB>, <&scmi_clk CLK_TREE_FCH_I3C1_FUNC>; + clock-names = "pclk", "sysclk"; + resets = <&src_fch SW_I3C1_RST_FUNC_G_N>, <&src_fch SW_I3C1_RST_FUNC_I_N>, <&src_fch SW_I3C1_RST_APB_N>; + reset-names = "i3c_funcg","i3c_funci","i3c_apb"; + status = "disabled"; + }; + + xspi: xspi@04180000 { + compatible = "cdns,xspi-nor"; + reg = <0x0 0x04180000 0x0 0x10000>, <0x0 0x10000 0x0 0x4000000>; + reg-names = "io", "sdma"; + #address-cells = <1>; + #size-cells = <0>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_XSPI_APB>, <&scmi_clk CLK_TREE_FCH_XSPI_MACLK>, <&scmi_clk CLK_TREE_FCH_XSPI_FUNC>; + clock-names = "pclk", "maclk", "funcclk"; + resets = <&src_fch SW_XSPI_SYS_RST_N>, <&src_fch SW_XSPI_REG_RST_N>; + reset-names = "xspi_sys_reset", "xspi_reg_reset"; + status = "disabled"; + }; + + fch_cru: fch_cru@0x416009c { + compatible = "sky1,fch_cru", "syscon"; + reg = <0x0 0x0416009c 0x0 0x80>; + }; + + fch_dmac: dma-controller@4190000 { + compatible = "arm,dma350-full"; + reg = <0x0 0x4190000 0x0 0x10000>; + #dma-cells = <2>; + dma-channels = <8>; + dma-requests = <8>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_DMA_ACLK>; + clock-names = "axiclk"; + resets = <&src_fch SW_DMA_RST_AXI_N>; + reset-names = "dma_reset"; + status = "okay"; + }; + + csu_se@05000000 { + compatible = "cix,sky1-se"; + mbox-names = "tx3", "rx3"; + mboxes = <&mbox_ap2se 9>, /* index=9: fifo base channel */ + <&mbox_se2ap 9>; + status = "disabled"; + }; + + csu_pm@06000000 { + compatible = "cix,sky1-pm"; + mbox-names = "tx2", "rx2"; + mboxes = <&mbox_ap2pm 8>, /* index=8: Reg/DB base channel */ + <&mbox_pm2ap 8>; + status = "disabled"; + }; + + sf_i2c0: i2c@08030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x08030000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&i2cclk>; + interrupts = ; + status = "disabled"; + }; + + sf_i2c1: i2c@08040000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,i2c-r1p14"; + reg = <0x0 0x08040000 0x0 0x10000>; + clock-frequency = <400000>; + clocks = <&i2cclk>; + interrupts = ; + status = "disabled"; + }; + + sf_spi: spi@08070000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cdns,spi-r1p6"; + reg = <0x0 0x08070000 0x0 0x10000>; + clocks = <&spi_ref_clk>, <&spi_apb_pclk>; + clock-names = "pclk", "ref_clk"; + interrupts = ; + fifo-width = <32>; + status = "disabled"; + }; + + sf_i3c0: i3c@08050000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x08050000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + i3c-scl-hz = <100000>; + interrupts = ; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + clock-names = "pclk", "sysclk"; + status = "disabled"; + }; + + sf_i3c1: i3c@08060000 { + compatible = "cdns,i3c-master"; + reg = <0x0 0x08060000 0x0 0x10000>; + #address-cells = <3>; + #size-cells = <0>; + i2c-scl-hz = <100000>; + interrupts = ; + clocks = <&i3c_apb_clk>, <&i3c_sys_clk>; + clock-names = "pclk", "sysclk"; + status = "disabled"; + }; + + hifi5: audio-dsp@07000000 { + compatible = "cix,sky1-hifi5"; + reg = <0x0 0x07000000 0x0 0x1000000>; + interrupts = ; /* watchdog interrupt */ + resets = <&src SKY1_AUDIO_HIFI5_RESET_N>, + <&audss_rst AUDSS_MB0_SW_RST_N>, + <&audss_rst AUDSS_MB1_SW_RST_N>; + reset-names = "dsp", "mb0", "mb1"; + clocks = <&audss_clk CLK_DSP_CLK>, + <&audss_clk CLK_DSP_BCLK>, + <&audss_clk CLK_DSP_PBCLK>, + <&audss_clk CLK_SRAM_AXI>, + <&audss_clk CLK_MB_0_APB>, + <&audss_clk CLK_MB_1_APB>; + clock-names = "clk", "bclk", "pbclk", "sramclk", "mb0clk", "mb1clk"; + firmware-name = "dsp_fw.bin"; + mbox-names = "tx0", "rx0"; + mboxes = <&mbox_ap2dsp 9>, /* index=9: fifo base channel */ + <&mbox_dsp2ap 9>; + cix,dsp-ctrl = <&audss_cru>; + status = "disabled"; + }; + + audss_dmac: dma-controller@07010000 { + compatible = "arm,dma350-no-pause"; + reg = <0x0 0x07010000 0x0 0x10000>; + interrupts = ; + #dma-cells = <2>; + dma-channels = <8>; + dma-requests = <20>; + clocks = <&audss_clk CLK_DMAC_AXI>; + clock-names = "axiclk"; + arm,clk-enable-atomic; + arm,reg-map = <0x07010000 0x20000000>; + arm,ram-map = <0xc0000000 0x30000000>; + arm,remote-ctrl = <&audss_cru>; + resets = <&audss_rst AUDSS_DMAC_SW_RST_N>; + reset-names = "dma_reset"; + status = "disabled"; + }; + + i2s0: i2s@07020000 { + compatible = "cdns,sky1-i2s-sc"; + reg = <0x0 0x07020000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S0_APB>, + <&audss_clk CLK_I2S0>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S0_SW_RST_N>; + reset-names = "i2s"; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s1: i2s@07030000 { + compatible = "cdns,sky1-i2s-sc"; + reg = <0x0 0x07030000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S1_APB>, + <&audss_clk CLK_I2S1>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S1_SW_RST_N>; + reset-names = "i2s"; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s2: i2s@07040000 { + compatible = "cdns,sky1-i2s-sc"; + reg = <0x0 0x07040000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S2_APB>, + <&audss_clk CLK_I2S2>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S2_SW_RST_N>; + reset-names = "i2s"; + cdns,cru-ctrl = <&audss_cru>; + #sound-dai-cells = <0>; + status = "disabled"; + }; + + i2s3: i2s@07050000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07050000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S3_APB>, + <&audss_clk CLK_I2S3>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK1>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>, + <&scmi_clk CLK_TREE_AUDIO_CLK3>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk1", + "audio_clk2", "audio_clk3"; + resets = <&audss_rst AUDSS_I2S3_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <6>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s4: i2s@07060000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07060000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S4_APB>, + <&audss_clk CLK_I2S4>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK1>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>, + <&scmi_clk CLK_TREE_AUDIO_CLK3>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk1", + "audio_clk2", "audio_clk3"; + resets = <&audss_rst AUDSS_I2S4_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s5: i2s@07070000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07070000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S5_APB>, + <&audss_clk CLK_I2S5>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S5_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s6: i2s@07080000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07080000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S6_APB>, + <&audss_clk CLK_I2S6>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S6_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s7: i2s@07090000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x07090000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S7_APB>, + <&audss_clk CLK_I2S7>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S7_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s8: i2s@070a0000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x070a0000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S8_APB>, + <&audss_clk CLK_I2S8>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S8_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + i2s9: i2s@070b0000 { + compatible = "cdns,sky1-i2s-mc"; + reg = <0x0 0x070b0000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_I2S9_APB>, + <&audss_clk CLK_I2S9>, + <&scmi_clk CLK_TREE_AUDIO_CLK0>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>; + clock-names = "hst", "i2s", + "audio_clk0", "audio_clk2"; + resets = <&audss_rst AUDSS_I2S9_SW_RST_N>; + reset-names = "i2s"; + cdns,pin-out-num = /bits/ 8 <4>; + #sound-dai-cells = <1>; + status = "disabled"; + }; + + ipb_hda: ipb-hda@070c0000 { + compatible = "cix,sky1-ipbloq-hda"; + reg = <0x0 0x070c0000 0x0 0x10000>; + interrupts = ; + clocks = <&audss_clk CLK_HDA_SYS>, + <&audss_clk CLK_HDA_HDA>; + clock-names = "sysclk", "clk48m"; + resets = <&audss_rst AUDSS_HDA_SW_RST_N>; + reset-names = "hda"; + status = "disabled"; + }; + + mbox_ap2dsp: mailbox@70f0000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x070f0000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_dsp2ap: mailbox@7100000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x07100000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + audss_cru: system-controller@07110000 { + compatible = "cix,audio-ss-cru", "simple-mfd", "syscon"; + reg = <0x0 0x07110000 0x0 0x10000>; + status = "disabled"; + + audss_clk: clock-controller { + compatible = "cix,sky1-audss-clock"; + power-domains = <&smc_devpd SKY1_PD_AUDIO>; + power-domain-names = "audio"; + resets = <&src SKY1_AUDIO_HIFI5_NOC_RESET_N>; + reset-names = "noc"; + clocks = <&scmi_clk CLK_TREE_AUDIO_CLK0>, <&scmi_clk CLK_TREE_AUDIO_CLK1>, + <&scmi_clk CLK_TREE_AUDIO_CLK2>, <&scmi_clk CLK_TREE_AUDIO_CLK3>, + <&scmi_clk CLK_TREE_AUDIO_CLK4>, <&scmi_clk CLK_TREE_AUDIO_CLK5>; + clock-names = "audio_clk0", "audio_clk1", + "audio_clk2", "audio_clk3", + "audio_clk4", "audio_clk5"; + #clock-cells = <1>; + status = "disabled"; + }; + + audss_rst: reset-controller { + compatible = "cix,sky1-audss-reset"; + #reset-cells = <1>; + status = "disabled"; + }; + }; + + sensorhub: sensor-mcu@08000000 { + compatible = "cix,sky1-sfh"; + reg = <0x0 0x08000000 0x0 0x1000000>; + interrupts = , + ; + interrupt-names = "wdt","sw_intr"; + firmware-name = "sfh_fw.bin"; + clocks = <&scmi_clk CLK_TREE_S5_SENSOR_HUB_25M>, + <&scmi_clk CLK_TREE_S5_SENSOR_HUB_400M>; + clock-names = "sensor_hub_25M", "sensor_hub_400M"; + resets = <&src SKY1_SENSORHUB_RESET_N>, + <&src SKY1_SENSORHUB_NOC_RESET_N>; + reset-names = "reset", "noc_reset"; + mbox-names = "tx1", "rx1"; + mboxes = <&mbox_ap2sfh 9>, /* index=9: FIFO based channel */ + <&mbox_sfh2ap 9>; + cix,sfh-ctrl = <&sfh_cru>; + wakeup-source; + status = "disabled"; + }; + + sfh_cru: sfh_cru@08080000 { + compatible = "sky1,sfh_cru", "syscon"; + reg = <0x0 0x08080000 0x0 0x1000>; + }; + + sfh_scp: sfh_scp@08100000 { + compatible = "cix,sfh_scp"; + status = "disabled"; + }; + + cix_se2ap_mbox: cix_se2ap_mbox { + compatible = "cix,cix_se2ap_mbox"; + mbox-names = "tx4", "rx4"; + mboxes = <&mbox_ap2se 10>, <&mbox_se2ap 9>; /* index=9: fifo base channel */ + status = "okay"; + }; + + sky1_crash: cix_se_pm_crash { + compatible = "cix,se_pm_crash"; + status = "disabled"; + }; + + gmac_rcsu: gmac_rcsu@9310000 { + compatible = "sky1,gmac_rcsu", "syscon"; + reg = <0x0 0x09310000 0x0 0x1000>; + }; + + macb0: ethernet@9320000 { + compatible = "cdns,sky1-gem"; + reg = <0x0 0x09320000 0x0 0x10000>; + iommus = <&smmu_syshub 0xC>; + interrupts = , /* Queue 0 */ + , /* Queue 1 */ + , /* Queue 2 */ + , /* Queue 3 */ + , /* Queue 4 */ + , /* Queue 5 */ + , /* Queue 6 */ + ; /* Queue 7 */ + clocks = <&scmi_clk CLK_TREE_GMAC0_ACLK>, + <&scmi_clk CLK_TREE_GMAC0_PCLK>, + <&scmi_clk CLK_TREE_GMAC0_DIV_TXCLK>; + clock-names = "aclk", "pclk", "tx_clk"; + resets = <&src SKY1_GMAC0_RST_N>; + reset-names = "gmac_rstn"; + status = "disabled"; + }; + + macb1: ethernet@9330000 { + compatible = "cdns,sky1-gem"; + reg = <0x0 0x09330000 0x0 0x10000>; + iommus = <&smmu_syshub 0xB>; + interrupts = , /* Queue 0 */ + , /* Queue 1 */ + , /* Queue 2 */ + , /* Queue 3 */ + , /* Queue 4 */ + , /* Queue 5 */ + , /* Queue 6 */ + ; /* Queue 7 */ + clocks = <&scmi_clk CLK_TREE_GMAC1_ACLK>, + <&scmi_clk CLK_TREE_GMAC1_PCLK>, + <&scmi_clk CLK_TREE_GMAC1_DIV_TXCLK>; + clock-names = "aclk", "pclk", "tx_clk"; + resets = <&src SKY1_GMAC1_RST_N>; + reset-names = "gmac_rstn"; + status = "disabled"; + }; + + sky1_usbss_0:usb@9000000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09000310 0x00 0x4>, + <0x00 0x09000400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS0_PRST_N>, + <&src SKY1_USBC_SS0_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_DRD_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_DRD_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_DRD_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_DRD_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_0: usb-controller@9010000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9010000 0x00 0x4000>, + <0x00 0x9014000 0x00 0x4000>, + <0x00 0x9018000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "otg"; + phys = <&usb3_phy0>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + usb2_phy4:usb-phy@9020000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS4_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy0:usb-phy@9030000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x9030000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY0_RST_N>, + <&src SKY1_USB_DP_PHY0_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_DRD_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy0: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc0_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_1:usb@9070000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09070310 0x00 0x4>, + <0x00 0x09070400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS1_PRST_N>, + <&src SKY1_USBC_SS1_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_H0_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_0_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_H0_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_0_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_1: usb-controller@9080000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9080000 0x00 0x4000>, + <0x00 0x9084000 0x00 0x4000>, + <0x00 0x9088000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "host"; + phys = <&usb3_phy1>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + usb2_phy5:usb-phy@9090000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS5_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy1:usb-phy@90A0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x90A0000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY1_RST_N>, + <&src SKY1_USB_DP_PHY1_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_0_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy1: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc1_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_2:usb@90e0000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x090e0310 0x00 0x4>, + <0x00 0x090e0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS4_PRST_N>, + <&src SKY1_USBC_SS4_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_H1_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_1_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_H1_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_1_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_2: usb-controller@90f0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x90f0000 0x00 0x4000>, + <0x00 0x90f4000 0x00 0x4000>, + <0x00 0x90f8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "host"; + status = "disabled"; + phys = <&usb3_phy2>; + phy-names = "cdnsp,usb3-phy"; + }; + }; + + usb2_phy8:usb-phy@9100000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS8_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy2:usb-phy@9110000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x9110000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY2_RST_N>, + <&src SKY1_USB_DP_PHY2_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_1_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy2: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc2_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_3:usb@9150000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09150310 0x00 0x4>, + <0x00 0x09150400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS5_PRST_N>, + <&src SKY1_USBC_SS5_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3C_H2_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3C_2_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3C_H2_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3C_2_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_3: usb-controller@9160000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9160000 0x00 0x4000>, + <0x00 0x9164000 0x00 0x4000>, + <0x00 0x9168000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "host"; + status = "disabled"; + phys = <&usb3_phy3>; + phy-names = "cdnsp,usb3-phy"; + }; + }; + + usb2_phy9:usb-phy@9170000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS9_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usbc_phy3:usb-phy@9180000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usbdp-phy"; + reg = <0x00 0x9180000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USB_DP_PHY3_RST_N>, + <&src SKY1_USB_DP_PHY3_PRST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3C_2_PHY3_GATE>; + clock-names = "pclk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy3: usb-port { + #phy-cells = <0>; + reg = <0x0>; + status = "disabled"; + }; + usbc3_dp_phy: dp-port { + #phy-cells = <0>; + reg = <0x1>; + status = "disabled"; + }; + }; + + sky1_usbss_4:usb@91c0300 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x091c0314 0x00 0x4>, + <0x00 0x091c0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS2_PRST_N>, + <&src SKY1_USBC_SS2_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3A_H0_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3A_0_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3A_H0_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3A_0_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_4: usb-controller@91d0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x91d0000 0x00 0x4000>, + <0x00 0x91d4000 0x00 0x4000>, + <0x00 0x91d8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "otg"; + phys = <&usb3_phy4_0>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + sky1_usbss_5:usb@91c0304 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x091c0324 0x00 0x4>, + <0x00 0x091c0410 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_SS3_PRST_N>, + <&src SKY1_USBC_SS3_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB3A_H1_CLK_SOF>, + <&scmi_clk CLK_TREE_USB3A_1_AXI_GATE>, + <&scmi_clk CLK_TREE_USB3A_H1_CLK_LPM>, + <&scmi_clk CLK_TREE_USB3A_1_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbss_5: usb-controller@91e0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x91e0000 0x00 0x4000>, + <0x00 0x91e4000 0x00 0x4000>, + <0x00 0x91e8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "super-speed-plus"; + dr_mode = "otg"; + phys = <&usb3_phy4_1>; + phy-names = "cdnsp,usb3-phy"; + status = "disabled"; + }; + }; + + usb2_phy6:usb-phy@91f0000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS6_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usb2_phy7:usb-phy@9200000 { + compatible = "cix,sky1-usb2-phy"; + resets = <&src SKY1_USBPHY_HS7_PRST_N>; + reset-names = "preset"; + #phy-cells = <0>; + status = "disabled"; + }; + + usb3_phy4:usb-phy@9210000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-usb3-phy"; + reg = <0x00 0x09210000 0x00 0x40000>; + status = "disabled"; + + resets = <&src SKY1_USBPHY_SS_RST_N>, + <&src SKY1_USBPHY_SS_PST_N>; + reset-names = "reset", "preset"; + + clocks = <&scmi_clk CLK_TREE_USB3A_PHY3_GATE>, + <&scmi_clk CLK_TREE_USB3A_PHY_x2_REF>; + clock-names = "apb_clk", "ref_clk"; + + cix,usbphy_syscon = <&src>; + + usb3_phy4_0: usb-port@0 { + #phy-cells = <0>; + id = <0>; + status = "disabled"; + }; + usb3_phy4_1: usb-port@1 { + #phy-cells = <0>; + id = <1>; + status = "disabled"; + }; + }; + + sky1_usbhs_0:usb@9250000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09250310 0x00 0x4>, + <0x00 0x09250400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS0_PRST_N>, + <&src SKY1_USBC_HS0_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_0_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_0_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_0_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_0_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_0: usb-controller@9260000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9260000 0x00 0x4000>, + <0x00 0x9264000 0x00 0x4000>, + <0x00 0x9268000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + sky1_usbhs_1:usb@9280000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x09280310 0x00 0x4>, + <0x00 0x09280400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS1_PRST_N>, + <&src SKY1_USBC_HS1_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_1_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_1_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_1_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_1_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_1: usb-controller@9290000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x9290000 0x00 0x4000>, + <0x00 0x9294000 0x00 0x4000>, + <0x00 0x9298000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + usb2_phy0:usb-phy@9270000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS0_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + usb2_phy1:usb-phy@92a0000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS1_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + sky1_usbhs_2:usb@92b0000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x092b0310 0x00 0x4>, + <0x00 0x092b0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS2_PRST_N>, + <&src SKY1_USBC_HS2_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_2_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_2_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_2_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_2_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_2: usb-controller@92c0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x92c0000 0x00 0x4000>, + <0x00 0x92c4000 0x00 0x4000>, + <0x00 0x92c8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + usb2_phy2:usb-phy@92d0000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS2_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + sky1_usbhs_3:usb@92e0000 { + compatible = "cix,sky1-usbssp"; + #address-cells = <2>; + #size-cells = <2>; + ranges; + reg = <0x00 0x092e0310 0x00 0x4>, + <0x00 0x092e0400 0x00 0x4>; + reg-names = "axi_property", "controller_status"; + resets = <&src SKY1_USBC_HS3_PRST_N>, + <&src SKY1_USBC_HS3_RST_N>; + reset-names = "usb_preset", "usb_reset"; + clocks = <&scmi_clk CLK_TREE_USB2_3_CLK_SOF>, + <&scmi_clk CLK_TREE_USB2_3_AXI_GATE>, + <&scmi_clk CLK_TREE_USB2_3_CLK_LPM>, + <&scmi_clk CLK_TREE_USB2_3_APB_GATE>; + clock-names = "sof_clk", "usb_aclk", "lpm_clk", "usb_pclk"; + cix,usb_syscon = <&src>; + axi_bmax_value = <0x7>; + status = "disabled"; + usbhs_3: usb-controller@92f0000 { + compatible = "cdns,usbssp"; + reg = <0x00 0x92f0000 0x00 0x4000>, + <0x00 0x92f4000 0x00 0x4000>, + <0x00 0x92f8000 0x00 0x8000>; + reg-names = "otg", "dev", "xhci"; + interrupts = , /* host irq */ + , /* peripheral irq */ + , /* otgirq */ + ; /* wakeup irq */ + interrupt-names = "host", + "peripheral", + "otg", + "wakeup"; + maximum-speed = "high-speed"; + dr_mode = "host"; + status = "disabled"; + }; + }; + + usb2_phy3:usb-phy@9300000 { + compatible = "cix,sky1-usb2-phy"; + #phy-cells = <0>; + resets = <&src SKY1_USBPHY_HS3_PRST_N>; + reset-names = "preset"; + status = "disabled"; + }; + + pcie_x8_rc: pcie@0a010000 { /* X8 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a010000 0x00 0x10000>, + <0x00 0x0a000000 0x00 0x10000>, + <0x00 0x2c000000 0x00 0x4000000>, + <0x00 0x60000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0xc0 0xff>; + max-link-speed = <4>; + num-lanes = <8>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x60100000 0x0 0x60100000 0x0 0x00100000>, + <0x02000000 0x0 0x60200000 0x0 0x60200000 0x0 0x1fe00000>, + <0x43000000 0x18 0x00000000 0x18 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL0_CLK>, + <&scmi_clk CLK_TREE_PCIE_X8CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B0>; + clock-names = "axi_clk", "apb_clk","refclk_b"; + power-domains = <&smc_devpd SKY1_PD_PCIE_CTRL0>; + power-domain-names = "pcie_pd"; + resets = <&src SKY1_PCIE0_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x0>; + msi-map = <0xc000 &its_pcie 0xc000 0x4000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 407 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 408 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 409 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 410 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0xc000 &smmu_pciehub 0xc000 0x3fff>; + phys = <&pcie_x8_phy>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pcie0_phy: pcie_phy@0a020000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-pcie-phy"; + reg = <0x00 0x0a020000 0x00 0x40000>; + status = "disabled"; + clocks =<&scmi_clk CLK_TREE_PCIE_X8_PHY_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_PHY_X8>; + + clock-names = "pclk", "refclk"; + + pcie_x8_phy: link@0 { + #phy-cells = <0>; + reg = <0x0>; + num-lanes = <8>; + status = "disabled"; + }; + }; + + pcie_x4_rc: pcie@0a070000 { /* X4 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a070000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x29000000 0x00 0x3000000>, + <0x00 0x50000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x90 0xbf>; + max-link-speed = <4>; + num-lanes = <4>; + max-payload = <512>; + ranges = <0x01000000 0x00 0x50100000 0x00 0x50100000 0x00 0x00100000>, + <0x02000000 0x00 0x50200000 0x00 0x50200000 0x00 0x0fe00000>, + <0x43000000 0x14 0x00000000 0x14 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL1_CLK>, + <&scmi_clk CLK_TREE_PCIE_X4CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B1>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + resets = <&src SKY1_PCIE1_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x1>; + msi-map = <0x9000 &its_pcie 0x9000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 417 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 418 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 419 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 420 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x9000 &smmu_pciehub 0x9000 0x2fff>; + phys = <&pcie_x4_phy>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pcie1_phy: pcie_phy@0a080000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-pcie-phy"; + reg = <0x00 0x0a080000 0x00 0x40000>; + status = "disabled"; + clocks = <&scmi_clk CLK_TREE_PCIE_X4_PHY_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_PHY_X4>; + + clock-names = "pclk", "refclk"; + + pcie_x4_phy: link@0 { + #phy-cells = <0>; + reg = <0x0>; + num-lanes = <4>; + status = "disabled"; + }; + }; + + pcie_x2_rc: pcie@0a0c0000 { /* X2 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a0c0000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x26000000 0x00 0x3000000>, + <0x00 0x40000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x60 0x8f>; + max-link-speed = <4>; + num-lanes = <2>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x40100000 0x0 0x40100000 0x0 0x00100000>, + <0x02000000 0x0 0x40200000 0x0 0x40200000 0x0 0x0fe00000>, + <0x43000000 0x10 0x00000000 0x10 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL2_CLK>, + <&scmi_clk CLK_TREE_PCIE_X2CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B2>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + + resets = <&src SKY1_PCIE2_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x2>; + msi-map = <0x6000 &its_pcie 0x6000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 427 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 428 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 429 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 430 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x6000 &smmu_pciehub 0x6000 0x2fff>; + phys = <&pcie_x2_phy>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pciex211_phy: pcie_phy@0a0f0000 { + #address-cells = <1>; + #size-cells = <0>; + compatible = "cix,sky1-pcie-phy"; + reg = <0x00 0x0a0f0000 0x00 0x40000>; + status = "disabled"; + clocks = <&scmi_clk CLK_TREE_PCIE_X211_PHY_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_PHY_X211>; + + clock-names = "pclk", "refclk"; + + pcie_x1_phy0: link@0 { + #phy-cells = <0>; + reg = <0x0>; + num-lanes = <1>; + status = "disabled"; + }; + + pcie_x1_phy1: link@1 { + #phy-cells = <0>; + reg = <0x1>; + num-lanes = <1>; + status = "disabled"; + }; + + pcie_x2_phy: link@2 { + #phy-cells = <0>; + reg = <0x2>; + num-lanes = <2>; + status = "disabled"; + }; + }; + + pcie_x1_1_rc: pcie@0a0e0000 { /* X1_1 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a0e0000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x23000000 0x00 0x3000000>, + <0x00 0x38000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x30 0x5f>; + max-link-speed = <4>; + num-lanes = <1>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x38100000 0x0 0x38100000 0x0 0x00100000>, + <0x02000000 0x0 0x38200000 0x0 0x38200000 0x0 0x07e00000>, + <0x43000000 0x0C 0x00000000 0x0C 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL4_CLK>, + <&scmi_clk CLK_TREE_PCIE_X1_1CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B4>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + resets = <&src SKY1_PCIE4_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x3>; + msi-map = <0x3000 &its_pcie 0x3000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 445 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 446 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 447 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 448 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x3000 &smmu_pciehub 0x3000 0x2fff>; + phys = <&pcie_x1_phy1>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + pcie_x1_0_rc: pcie@0a0d0000 { /* X1_0 */ + compatible = "cix,sky1-pcie-host"; + reg-names = "reg", "rcsu", "cfg", "msg"; + reg = <0x00 0x0a0d0000 0x00 0x10000>, + <0x00 0x0a060000 0x00 0x10000>, + <0x00 0x20000000 0x00 0x3000000>, + <0x00 0x30000000 0x00 0x00100000>; + device_type = "pci"; + vendor-id = <0x1f6c>; + device-id = <0x0001>; + #address-cells = <3>; + #size-cells = <2>; + bus-range = <0x00 0x2f>; + max-link-speed = <4>; + num-lanes = <1>; + max-payload = <512>; + ranges = <0x01000000 0x0 0x30100000 0x0 0x30100000 0x0 0x00100000>, + <0x02000000 0x0 0x30200000 0x0 0x30200000 0x0 0x07e00000>, + <0x43000000 0x08 0x00000000 0x08 0x00000000 0x04 0x00000000>; + cdns,no-inbound-bar; + clocks = <&scmi_clk CLK_TREE_PCIE_CTRL3_CLK>, + <&scmi_clk CLK_TREE_PCIE_X1_0CTRL_APB>, + <&scmi_clk CLK_TREE_PCIE_REF_B3>; + clock-names = "axi_clk", "apb_clk", "refclk_b"; + resets = <&src SKY1_PCIE3_RESET_N>; + reset-names = "pcie_reset"; + sky1,pcie-ctrl-id = <0x4>; + msi-map = <0x0000 &its_pcie 0x0000 0x3000>; + #interrupt-cells = <1>; + interrupt-map-mask = <0 0 0 0x7>; + interrupt-map = <0 0 0 1 &gic 0 0 GIC_SPI 436 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 2 &gic 0 0 GIC_SPI 437 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 3 &gic 0 0 GIC_SPI 438 IRQ_TYPE_LEVEL_HIGH>, + <0 0 0 4 &gic 0 0 GIC_SPI 439 IRQ_TYPE_LEVEL_HIGH>; + interrupts = , /* AER (correctable) */ + , /* AER (fatal) */ + , /* AER (non fatal) */ + , /* local (some error status) */ + , /* phy_interrupt (link speed and width change) */ + ; /* phy_state_chg_sts (power status change) */ + interrupt-names = "aer_c", "aer_f", "aer_nf", + "local", "phy_int", "phy_sta"; + sky1,aer-uncor-panic; + iommu-map = <0x0000 &smmu_pciehub 0x0000 0x2fff>; + phys = <&pcie_x1_phy0>; + phy-names = "cdns,pcie-phy"; + status = "disabled"; + }; + + gic: interrupt-controller@0e001000 { + compatible = "arm,gic-700", "arm,gic-v3"; + #address-cells = <2>; + #interrupt-cells = <3>; + #size-cells = <2>; + single-redist; + ranges; + interrupt-controller; +#ifndef CONFIG_ARCH_CIX_EMU_FPGA + #redistributor-regions = <12>; + reg = <0x0 0x0e010000 0 0x10000>, /* GICD */ + <0x0 0x0e090000 0 0x40000>, /* GICR */ + <0x0 0x0e0d0000 0 0x40000>, /* GICR1 */ + <0x0 0x0e110000 0 0x40000>, /* GICR2 */ + <0x0 0x0e150000 0 0x40000>, /* GICR3 */ + <0x0 0x0e190000 0 0x40000>, /* GICR4 */ + <0x0 0x0e1d0000 0 0x40000>, /* GICR5 */ + <0x0 0x0e210000 0 0x40000>, /* GICR6 */ + <0x0 0x0e250000 0 0x40000>, /* GICR7 */ + <0x0 0x0e290000 0 0x40000>, /* GICR8 */ + <0x0 0x0e2d0000 0 0x40000>, /* GICR9 */ + <0x0 0x0e310000 0 0x40000>, /* GICR10 */ + <0x0 0x0e350000 0 0x40000>; /* GICR11 */ +#else + #redistributor-regions = <1>; + reg = <0x0 0x0e010000 0 0x10000>, /* GICD */ + <0x0 0x0e090000 0 0x40000>; /* GICR */ +#endif + interrupts = ; + interrupt-parent = <&gic>; + + its_pcie: its@0e050000 { + compatible = "arm,gic-v3-its"; + msi-controller; + reg = <0x0 0x0e050000 0x0 0x30000>; + }; + }; + + dsu_pmu: dsu_pmu { + compatible = "arm,dsu-pmu"; + interrupts = ; + cpus = <&CPU0>, <&CPU1>, <&CPU2>, <&CPU3>, + <&CPU4>, <&CPU5>, <&CPU6>, <&CPU7>, + <&CPU8>, <&CPU9>, <&CPU10>, <&CPU11>; + status = "okay"; + }; + + cmn_pmu: cmn_pmu@10010000 { + compatible = "arm,ci-700"; + reg = <0x0 0x10010000 0x0 0x3FF0000>; + interrupts = ; + status = "okay"; + }; + + cix_display: cix-display { + compatible = "cix,display"; + //reset-control = <0x4>; + status = "disabled"; + }; + + dpu0: disp-controller@14010000 { + device-id = <0>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x14010000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 0>, <&smmu_mmhub 1>, + <&smmu_mmhub 3>, <&smmu_mmhub 4>; + power-domains = <&smc_devpd SKY1_PD_DPU0>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU0_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU0_RCSU_RESET_N>, + <&src SKY1_DPU_RESET0_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu0_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP0_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu0_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP0_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu1: disp-controller@14080000 { + device-id = <1>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x14080000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 6>, <&smmu_mmhub 7>, + <&smmu_mmhub 9>, <&smmu_mmhub 10>; + power-domains = <&smc_devpd SKY1_PD_DPU1>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU1_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU1_RCSU_RESET_N>, + <&src SKY1_DPU_RESET1_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu1_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP1_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu1_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP1_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu2: disp-controller@140f0000 { + device-id = <2>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x140f0000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 12>, <&smmu_mmhub 13>, + <&smmu_mmhub 15>, <&smmu_mmhub 16>; + power-domains = <&smc_devpd SKY1_PD_DPU2>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU2_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU2_RCSU_RESET_N>, + <&src SKY1_DPU_RESET2_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu2_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP2_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu2_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP2_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu3: disp-controller@14160000 { + device-id = <3>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x14160000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 18>, <&smmu_mmhub 19>, + <&smmu_mmhub 21>, <&smmu_mmhub 22>; + power-domains = <&smc_devpd SKY1_PD_DPU3>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU3_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU3_RCSU_RESET_N>, + <&src SKY1_DPU_RESET3_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu3_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP3_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu3_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP3_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + dpu4: disp-controller@141d0000 { + device-id = <4>; + #address-cells = <1>; + #size-cells = <0>; + compatible = "armchina,linlon-d6"; + reg = <0x0 0x141d0000 0x0 0x20000>; + interrupts = ; + iommus = <&smmu_mmhub 24>, <&smmu_mmhub 25>, + <&smmu_mmhub 27>, <&smmu_mmhub 28>; + power-domains = <&smc_devpd SKY1_PD_DPU4>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU4_ACLK>; + clock-names = "aclk"; + resets = <&src SKY1_DPU4_RCSU_RESET_N>, + <&src SKY1_DPU_RESET4_N>; + reset-names = "rcsu_reset", "ip_reset"; + memory-region = <&dpu_gop>; + enabled_by_gop = <0>; + status = "disabled"; + + dpu4_pipe0: pipeline@0 { + reg = <0>; + clocks = <&scmi_clk CLK_TREE_DP4_PIXEL0>; + clock-names = "pxclk"; + }; + + dpu4_pipe1: pipeline@1 { + reg = <1>; + clocks = <&scmi_clk CLK_TREE_DP4_PIXEL1>; + clock-names = "pxclk"; + }; + }; + + aeu0: aeu@14030000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x14030000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 2>; + power-domains = <&smc_devpd SKY1_PD_DPU0>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU0_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu1: aeu@140a0000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x140a0000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 8>; + power-domains = <&smc_devpd SKY1_PD_DPU1>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU1_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu2: aeu@14110000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x14110000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 14>; + power-domains = <&smc_devpd SKY1_PD_DPU2>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU2_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu3: aeu@14180000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x14180000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 20>; + power-domains = <&smc_devpd SKY1_PD_DPU3>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU3_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + aeu4: aeu@141f0000 { + compatible = "armchina,linlon-aeu"; + reg = <0x0 0x141f0000 0x0 0x20000>; + interrupts = ; + interrupt-names = "AEU"; + iommus = <&smmu_mmhub 26>; + power-domains = <&smc_devpd SKY1_PD_DPU4>; + power-domain-names = "dpu_pd"; + clocks = <&scmi_clk CLK_TREE_DPU4_ACLK>; + clock-names = "aclk"; + status = "disabled"; + }; + + dp0: dp@14060000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x14064000 0x0 0x4000>, + <0x0 0x14068000 0x0 0x4000>, + <0x0 0x1406ff00 0x0 0x0100>, + <0x0 0x14050000 0x0 0x304>; + reg-names = "dp", "dsc", "dp_phy", "dp_rcsu"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC0_APBCLK>, + <&scmi_clk CLK_TREE_DPC0_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC0_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP0_RCSU_RESET_N>, + <&src SKY1_DP_RESET0_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc0_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + dp1: dp@140d0000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x140d4000 0x0 0x4000>, + <0x0 0x140d8000 0x0 0x4000>, + <0x0 0x140dff00 0x0 0x0100>, + <0x0 0x140c0000 0x0 0x304>; + reg-names = "dp", "dsc", "dp_phy", "dp_rcsu"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC1_APBCLK>, + <&scmi_clk CLK_TREE_DPC1_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC1_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP1_RCSU_RESET_N>, + <&src SKY1_DP_RESET1_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc1_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + dp2: dp@14140000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x14144000 0x0 0x4000>, + <0x0 0x14148000 0x0 0x4000>, + <0x0 0x1414c000 0x0 0x4000>, + <0x0 0x14130000 0x0 0x320>; + reg-names = "dp", "dsc", "dp_phy", "dp_rcsu"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC2_APBCLK>, + <&scmi_clk CLK_TREE_DPC2_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC2_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP2_RCSU_RESET_N>, + <&src SKY1_DP_RESET2_N>, + <&src SKY1_DP_PHY_RST_N>; + reset-names = "dp_rcsu_reset", "dp_reset", "phy_reset"; + enabled_by_gop = <0>; + cfg_adapter_port = <2>; + status = "disabled"; + }; + + dp3: dp@141b0000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x141b4000 0x0 0x4000>, + <0x0 0x141b8000 0x0 0x4000>, + <0x0 0x141bff00 0x0 0x0100>, + <0x0 0x141a0000 0x0 0x304>; + reg-names = "dp", "dsc", "dp_phy", "dp_rcsu"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC3_APBCLK>, + <&scmi_clk CLK_TREE_DPC3_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC3_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP3_RCSU_RESET_N>, + <&src SKY1_DP_RESET3_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc2_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + dp4: dp@14220000 { + #address-cells = <1>; + #size-cells = <0>; + #sound-dai-cells = <0>; + compatible = "cix,sky1-dptx"; + reg = <0x0 0x14224000 0x0 0x4000>, + <0x0 0x14228000 0x0 0x4000>, + <0x0 0x1422ff00 0x0 0x0100>, + <0x0 0x14210000 0x0 0x304>; + reg-names = "dp", "dsc", "dp_phy", "dp_rcsu"; + interrupts = ; + + clocks = <&scmi_clk CLK_TREE_DPC4_APBCLK>, + <&scmi_clk CLK_TREE_DPC4_VIDCLK0>, + <&scmi_clk CLK_TREE_DPC4_VIDCLK1>; + clock-names = "apb_clk", "vid_clk0", "vid_clk1"; + resets = <&src SKY1_DP4_RCSU_RESET_N>, + <&src SKY1_DP_RESET4_N>; + reset-names = "dp_rcsu_reset", "dp_reset"; + + phys = <&usbc3_dp_phy>; + phy-names = "dp_phy"; + support_d3_cmd = "yes"; /*yes: support D3 cmd no: not support support D3 cmd*/ + + enabled_by_gop = <0>; + + status = "disabled"; + }; + + vpu: vpu@14230000 { + compatible = "armChina,linlon-v8"; + reg = <0x0 0x14230000 0x0 0x10000>, + <0x0 0x14240000 0x0 0x10000>; + reg-names = "vpu_rcsu", "vpu"; + interrupts = ; + power-domains = <&smc_devpd SKY1_PD_VPU_TOP>, + <&smc_devpd SKY1_PD_VPU_CORE0>, + <&smc_devpd SKY1_PD_VPU_CORE1>, + <&smc_devpd SKY1_PD_VPU_CORE2>, + <&smc_devpd SKY1_PD_VPU_CORE3>, + <&scmi_dvfs VPU_DFS_DOMAIN_ID>; + #power-domain-cells = <2>; + power-domain-names = "vpu_top", "vpu_core0", "vpu_core1", + "vpu_core2", "vpu_core3", "perf"; + clocks = <&scmi_clk CLK_TREE_VPU_APBCLK>; + clock-names = "vpu_clk"; + resets = <&src SKY1_VPU_RESET_N>, + <&src SKY1_VPU_RCSU_RESET_N>; + reset-names = "vpu_reset", "vpu_rcsu_reset"; + status = "disabled"; + }; + + npu: aipu@14260000 { + compatible = "armchina,zhouyi"; + core_mask = <3>; + power-domains = <&smc_devpd SKY1_PD_NPU_CORE0>, + <&smc_devpd SKY1_PD_NPU_CORE1>, + <&smc_devpd SKY1_PD_NPU_CORE2>, + <&scmi_dvfs NPU_DFS_DOMAIN_ID>; + power-domain-names = "pd_core0", "pd_core1", "pd_core2", "perf"; + cluster-partition = <0 0>; /* x2 only: cluster #0 -> partition #0 */ + reg = <0x0 0x14260000 0x0 0x10000>; + iommus = <&smmu_mmhub 0x1e>; + gm-policy = <1>; /* x2 only: 1: shared by tasks of all QoS level */ + interrupts = ; + status = "disabled"; + }; + + i7_isp: armcb_isp@14340000 { + #address-cells = <2>; + #size-cells = <2>; + compatible = "armcb,sky1-isp"; + reg = <0x0 0x14340000 0x0 0x10000>, + <0x0 0x14360000 0x0 0x50000>; + status = "disabled"; + }; + + i7_isp_fake1:isp_fake1{ + compatible = "armcb,isp_fake"; + }; + + i7_isp_fake2:isp_fake2{ + compatible = "armcb,isp_fake"; + }; + + i7_isp_fake3:isp_fake3{ + compatible = "armcb,isp_fake"; + }; + + gpu_physical_memory_group_manager: physical-memory-group-manager { + compatible = "arm,physical-memory-group-manager"; + }; + + gpu_protected_memory_allocator: protected-memory-allocator { + compatible = "arm,protected-memory-allocator"; + memory-region = <&mali_protected>; + }; + + gpu: gpu@15010000 { + compatible = "arm,mali-valhall"; + reg = <0x0 0x15000000 0x0 0x10000>, + <0x0 0x15010000 0x0 0x480000>; + reg-names = "gpu_rcsu", "gpu"; + interrupts = , + , + ; + interrupt-names = "JOB", "MMU", "GPU"; + system-coherency = <0>; + physical-memory-group-manager = <&gpu_physical_memory_group_manager>; + protected-memory-allocator = <&gpu_protected_memory_allocator>; + power-domains = <&smc_devpd SKY1_PD_GPU>, <&scmi_dvfs 0>; + power-domain-names = "pd_gpu", "perf"; + clocks = <&scmi_clk CLK_TREE_GPU_CLK_CORE>, <&scmi_clk CLK_TREE_GPU_CLK_STACKS>, + <&scmi_clk CLK_TREE_GPU_CLK_200M>, <&scmi_clk CLK_TREE_GPU_CLK_400M>; + clock-names = "gpu_clk_core", "gpu_clk_stacks", + "gpu_clk_200M", "gpu_clk_400M"; + resets = <&src SKY1_GPU_RCSU_RESET_N>, + <&src SKY1_GPU_RESET_N>; + reset-names = "gpu_rcsu_reset", "gpu_reset"; + gpu-microvolt = <820000>; + #cooling-cells = <2>; /* Requested by cooling device state */ + power_model@0 { + /*Note: it was designed for the Juno platform, and may not be suitable for sky1.*/ + compatible = "arm,mali-simple-power-model"; + static-coefficient = <2427750>; + dynamic-coefficient = <4687>; + ts = <20000 2000 (-20) 2>; + thermal-zone = "gpu-avg-thermal"; + }; + pbha { + int_id_override = <2 0x23>, <4 0x23>, <16 0x22>, <17 0x32>, + <18 0x52>, <21 0x32>, <22 0x52>, <24 0x22>, <28 0x32>; + }; + }; + + hwclock: hwspinlock@06510000 { + compatible = "sky1,hwspinlock"; + reg = <0x0 0x06510000 0x0 0x1000>; + #hwlock-cells = <1>; + status = "disabled"; + }; + + gpt_timer0: gpt_timer@04110000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04110000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "disabled"; + }; + + gpt_timer1: gpt_timer@04112000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04112000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "disabled"; + }; + + gpt_timer2: gpt_timer@04114000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04114000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "disabled"; + }; + + gpt_timer3: gpt_timer@04116000 { + compatible = "cix,sky1-gpt"; + reg = <0x0 0x04116000 0x0 0x2000>; + interrupts = ; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_timer_apb_clk", "fch_timer_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + status = "okay"; + }; + + pwm0: pwm0@04110000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04110000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + pwm1: pwm1@04111000 { + compatible = "cix,sky1-pwm"; + reg = <0x0 0x04111000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_TIMER_APB>, + <&scmi_clk CLK_TREE_FCH_TIMER_FUN>; + clock-names = "fch_pwm_apb_clk", "fch_pwm_func_clk"; + resets = <&src_fch SW_TIMER_RST_FUNC_N>; + reset-names = "func_reset"; + #pwm-cells = <2>; + status = "disabled"; + }; + + watchdog: watchdog@16003000 { + compatible = "cix,sky1-wdt"; + reg = <0x0 0x16003000 0x0 0x1000 + 0x0 0x16008000 0x0 0x1000>; + interrupts = ; + status = "disabled"; + }; + + src: reset-controller@16000000 { + compatible = "cix,sky1-src", "syscon"; + reg = <0x0 0x16000000 0x0 0x1000>; + #reset-cells = <1>; + status = "okay"; + }; + + src_fch: reset-controller@04160000 { + compatible = "cix,sky1-src-fch", "syscon"; + reg = <0x0 0x04160000 0x0 0x90>; + #reset-cells = <1>; + status = "okay"; + }; + + s5_gpio0: gpio-controller@16004000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x16004000 0x0 0x1000>; + clocks = <&s5_gpio_apb_clk>; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + s5_gpio1: gpio-controller@16005000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x16005000 0x0 0x1000>; + clocks = <&s5_gpio_apb_clk>; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <10>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + s5_gpio2: gpio-controller@16006000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x16006000 0x0 0x1000>; + clocks = <&s5_gpio_apb_clk>; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <10>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio0: gpio-controller@4120000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4120000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio1: gpio-controller@4130000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4130000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio2: gpio-controller@4140000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4140000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <32>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + fch_gpio3: gpio-controller@4150000 { + compatible = "cdns,gpio-r1p02"; + reg = <0x0 0x4150000 0x0 0x1000>; + clocks = <&scmi_clk CLK_TREE_FCH_GPIO_APB>; + clock-names = "fch_gpio_apb_clk"; + + resets = <&src_fch SW_GPIO_RST_APB_N>; + reset-names = "apb_reset"; + + interrupts = ; + + gpio-controller; + #gpio-cells = <2>; + ngpios = <17>; + + interrupt-controller; + #interrupt-cells = <2>; + status = "disabled"; + }; + + iomuxc_s5: pinctrl_s5_sky1 { + compatible = "cix,sky1-iomuxc-s5"; + reg = <0x0 0x16007000 0x0 0x1000>; + }; + + iomuxc: pinctrl_sky1 { + compatible = "cix,sky1-iomuxc"; + reg = <0x0 0x04170000 0x0 0x1000>; + }; + + nvmem: nvmem_fw { + compatible = "cix,sky1-nvmem-fw"; + #address-cells = <1>; + #size-cells = <1>; + status = "okay"; + + npu_harvest_0: npu_harveset_0@1 { + reg = <0x1 0x1>; + bits = <7 1>; + }; + + opn: opn@4c7 { + reg = <0x4dc 0x8>; + bits = <0 64>; + }; + }; + + sky1_top: sky1_top { + compatible = "cix,sky1-top"; + reg = <0x0 0x83E01000 0x0 0x2000>; + nvmem-cells = <&opn>; + nvmem-cell-names = "opn"; + status = "okay"; + }; + + cix_csi_rcsu_0: cix_csi_rcsu@14270000 { + compatible = "cix,cix-csi-rcsu-hw"; + reg = <0x0 0x14270000 0x0 0x10000>; + status = "disabled"; + }; + + cix_csi_rcsu_1: cix_csi_rcsu@142D0000 { + compatible = "cix,cix-csi-rcsu-hw"; + reg = <0x0 0x142D0000 0x0 0x10000>; + status = "disabled"; + }; + + cix_bridge_0: cix_bridge@142B0000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA0_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE0_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x142B0000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_0>; + interrupts = ; + interface = <0 0>; + axi-uid = <0x21>; + iommus = <&smmu_mmhub 0x21>; + status = "disabled"; + }; + + cix_bridge_1: cix_bridge@142C0000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA1_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE1_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x142C0000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_0>; + interrupts = ; + interface = <0 0>; + axi-uid= <0x21>; + status = "disabled"; + }; + + cix_bridge_2: cix_bridge@14310000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA2_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE2_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x14310000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_1>; + interrupts = ; + interface = <0 0>; + axi-uid= <0x22>; + iommus = <&smmu_mmhub 0x22>; + status = "disabled"; + }; + + cix_bridge_3: cix_bridge@14320000 { + compatible = "cix,cix-bridge"; + clocks = <&scmi_clk CLK_TREE_CSI_DMA3_PCLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "dma_pclk", "dma_sclk"; + resets = <&src SKY1_CSIBRDGE3_RST_N>; + reset-names = "csibridge_reset"; + reg = <0x0 0x14320000 0x0 0x10000>; + cix,hw = <&cix_csi_rcsu_1>; + interrupts = ; + interface = <0 0>; + axi-uid = <0x21>; + status = "disabled"; + }; + + cix_mipi_csi_0: csi@14280000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL0_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL3_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk", + "csi_p1clk", "csi_p2clk", "csi_p3clk"; + resets = <&src SKY1_CSI_RCSU0_RESET_N>, + <&src SKY1_CSI0_RST_N>; + reset-names = "rcsu_reset", "csi_reset"; + reg = <0x0 0x14280000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_mipi_csi_1: csi@14290000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL1_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_PIXEL0_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk"; + resets = <&src SKY1_CSI1_RST_N>; + reset-names = "csi_reset"; + reg = <0x0 0x14290000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_mipi_csi_2: csi@142E0000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL2_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL3_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk", + "csi_p1clk", "csi_p2clk", "csi_p3clk"; + resets = <&src SKY1_CSI_RCSU1_RESET_N>, + <&src SKY1_CSI2_RST_N>; + reset-names = "rcsu_reset", "csi_reset"; + reg = <0x0 0x142E0000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_mipi_csi_3: csi@142F0000 { + compatible = "cix,cix-mipi-csi2"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_CTRL3_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_PIXEL0_CLK>; + clock-names = "csi_pclk", "csi_sclk", "csi_p0clk"; + resets = <&src SKY1_CSI3_RST_N>; + reset-names = "csi_reset"; + reg = <0x0 0x142F0000 0x0 0x10000>; + interrupts = , + ; + status = "disabled"; + }; + + cix_dphy_0: cix_dph_0 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_0>; + status = "disabled"; + }; + + cix_dphy_1: cix_dph_1 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_0>; + status = "disabled"; + }; + + cix_dphy_2: cix_dph_2 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_0>; + status = "disabled"; + }; + + cix_dphy_3: cix_dph_3 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_1>; + status = "disabled"; + }; + + cix_dphy_4: cix_dph_4 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_1>; + status = "disabled"; + }; + + cix_dphy_5: cix_dph_5 { + compatible = "cix,cix-mipi-dphy-rx"; + cix,hw = <&cix_dphy_hw_1>; + status = "disabled"; + }; + + cix_dphy_hw_0: phy@142A0000 { + compatible = "cix,cix-mipi-dphy-hw"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_PHY0_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY0_APBCLK>; + clock-names = "phy_psmclk", "phy_apbclk"; + resets = <&src SKY1_CSIDPHY_PRST0_N>, + <&src SKY1_CSIDPHY_CMNRST0_N>; + reset-names = "phy_prst", "phy_cmnrst"; + reg = <0x0 0x142A0000 0x0 0x10000>; + status = "disabled"; + }; + + cix_dphy_hw_1: phy@14300000 { + compatible = "cix,cix-mipi-dphy-hw"; + #address-cells = <2>; + #size-cells = <2>; + clocks = <&scmi_clk CLK_TREE_CSI_PHY1_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY1_APBCLK>; + clock-names = "phy_psmclk", "phy_apbclk"; + resets = <&src SKY1_CSIDPHY_PRST1_N>, + <&src SKY1_CSIDPHY_CMNRST1_N>; + reset-names = "phy_prst", "phy_cmnrst"; + reg = <0x0 0x14300000 0x0 0x10000>; + status = "disabled"; + }; + }; + + mbox_sfh2ap: mailbox@8090000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x08090000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "okay"; + }; + + mbox_ap2sfh: mailbox@80a0000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x080a0000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "okay"; + }; + + mbox_ap2pm: mailbox@6590000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x06590000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_pm2ap: mailbox@65a0000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x065a0000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_ap2se: mailbox@5060000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x05060000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <0>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + mbox_se2ap: mailbox@5070000 { + compatible = "cix,sky1-mbox"; + reg = <0x0 0x05070000 0x0 0x10000>; + interrupts = ; + #mbox-cells = <1>; + cix,mbox_dir = <1>; /* 0:tx; 1:rx */ + status = "disabled"; + }; + + ap2pm_scmi_mem: ap2pm-shmem@0 { + compatible = "arm,scmi-shmem"; + #address-cells = <2>; + #size-cells = <2>; + reg = <0x0 0x06590000 0x0 0x80>; + status = "disabled"; + }; + + pm2ap_scmi_mem: pm2pm-shmem@0 { + compatible = "arm,scmi-shmem"; + #address-cells = <2>; + #size-cells = <2>; + reg = <0x0 0x065a0000 0x0 0x80>; + status = "disabled"; + }; + + ap_tfa_scmi_mem: ap2tf-shmem@1 { + compatible = "arm,scmi-shmem"; + reg = <0x0 0x84380000 0x0 0x80>; + status = "disabled"; + }; + + firmware { + ap_to_pm_scmi: scmi { + compatible = "arm,scmi"; + mbox-names = "tx", "rx"; + mboxes = <&mbox_ap2pm 8>, /*index=8: Reg/DB base channel*/ + <&mbox_pm2ap 8>; + shmem = <&ap2pm_scmi_mem &pm2ap_scmi_mem>; + #address-cells = <1>; + #size-cells = <0>; + status = "disabled"; + + scmi_dvfs: protocol@13 { + reg = <0x13>; + #clock-cells = <1>; + #power-domain-cells = <1>; + }; + + scmi_clk: protocol@14 { + reg = <0x14>; + #clock-cells = <1>; + }; + + scmi_sensor: protocol@15 { + reg = <0x15>; + #thermal-sensor-cells = <1>; + }; + + scmi_pm_excp: protocol@81 { + reg = <0x81>; + }; + }; + + ap_to_tfa_scmi:scmi-smc { + compatible = "arm,scmi-smc"; + arm,smc-id = <0xc2000001>; + #address-cells = <1>; + #size-cells = <0>; + shmem = <&ap_tfa_scmi_mem>; + status = "disabled"; + + smc_devpd: protocol@11 { + reg = <0x11>; + #power-domain-cells = <1>; + }; + }; + + sdei: sdei-smc { + compatible = "arm,sdei-1.0"; + method = "smc"; + status = "okay"; + }; + + optee: optee { + compatible = "linaro,optee-tz"; + method = "smc"; + }; + }; + + armcb_config: armcb_config { + compatible = "armcb,sky1-config-i7"; + interrupts = , + ; + status = "disabled"; + }; + + cix_vi_hw: cix_vi_hw { + compatible = "cix,cix-vi-hw"; + clocks = <&scmi_clk CLK_TREE_CSI_PHY0_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY0_APBCLK>, + <&scmi_clk CLK_TREE_CSI_PHY1_PSM>, + <&scmi_clk CLK_TREE_CSI_PHY1_APBCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL0_PIXEL3_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL1_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL1_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL2_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL2_PIXEL3_CLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_PCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_SYSCLK>, + <&scmi_clk CLK_TREE_CSI_CTRL3_PIXEL0_CLK>, + <&scmi_clk CLK_TREE_CSI_DMA0_PCLK>, + <&scmi_clk CLK_TREE_CSI_DMA1_PCLK>, + <&scmi_clk CLK_TREE_CSI_DMA2_PCLK>, + <&scmi_clk CLK_TREE_CSI_DMA3_PCLK>; + clock-names = "phy0_psmclk", "phy0_apbclk", + "phy1_psmclk", "phy1_apbclk", + "csi0_pclk", "csi0_sclk", "csi0_p0clk", + "csi0_p1clk", "csi0_p2clk", "csi0_p3clk", + "csi1_pclk", "csi1_sclk", "csi1_p0clk", + "csi2_pclk", "csi2_sclk", "csi2_p0clk", + "csi2_p1clk", "csi2_p2clk", "csi2_p3clk", + "csi3_pclk", "csi3_sclk", "csi3_p0clk", + "dma0_pclk", "dma1_pclk", + "dma2_pclk", "dma3_pclk"; + + resets = <&src SKY1_CSIDPHY_PRST0_N>, + <&src SKY1_CSIDPHY_CMNRST0_N>, + <&src SKY1_CSIDPHY_PRST1_N>, + <&src SKY1_CSIDPHY_CMNRST1_N>, + <&src SKY1_CSI_RCSU0_RESET_N>, + <&src SKY1_CSI_RCSU1_RESET_N>, + <&src SKY1_CSI0_RST_N>, + <&src SKY1_CSI1_RST_N>, + <&src SKY1_CSI2_RST_N>, + <&src SKY1_CSI3_RST_N>, + <&src SKY1_CSIBRDGE0_RST_N>, + <&src SKY1_CSIBRDGE1_RST_N>, + <&src SKY1_CSIBRDGE2_RST_N>, + <&src SKY1_CSIBRDGE3_RST_N>; + + reset-names = "phy0_prst", "phy0_cmnrst", + "phy1_prst", "phy1_cmnrst", + "rcsu0_reset", "rcsu1_reset", + "csi0_reset", "csi1_reset", + "csi2_reset", "csi3_reset", + "csibridge0_reset", + "csibridge1_reset", + "csibridge2_reset", + "csibridge3_reset"; + ahb-dphy0-base = <0x142A0000>; + ahb-dphy0-size = <0x10000>; + ahb-dphy1-base = <0x14300000>; + ahb-dphy1-size = <0x10000>; + ahb-csi0-base = <0x14280000>; + ahb-csi0-size = <0x10000>; + ahb-csi1-base = <0x14290000>; + ahb-csi1-size = <0x10000>; + ahb-csi2-base = <0x142E0000>; + ahb-csi2-size = <0x10000>; + ahb-csi3-base = <0x142F0000>; + ahb-csi3-size = <0x10000>; + ahb-csidma0-base = <0x142B0000>; + ahb-csidma0-size = <0x10000>; + ahb-csidma1-base = <0x142C0000>; + ahb-csidma1-size = <0x10000>; + ahb-csidma2-base = <0x14310000>; + ahb-csidma2-size = <0x10000>; + ahb-csidma3-base = <0x14320000>; + ahb-csidma3-size = <0x10000>; + ahb-csircsu0-base = <0x14270000>; + ahb-csircsu0-size = <0x10000>; + ahb-csircsu1-base = <0x142D0000>; + ahb-csircsu1-size = <0x10000>; + interrupts =, + , + , + , + , + , + , + ; + status = "disabled"; + }; + + armcb_ispmem: armcb_ispmem { + compatible = "armcb,isp-mem"; + power-domains = <&smc_devpd SKY1_PD_ISP0>; + power-domain-names = "pd_isp0"; + clocks = <&scmi_clk CLK_TREE_ISP_ACLK>, + <&scmi_clk CLK_TREE_ISP_SCLK>; + clock-names = "isp_aclk", "isp_sclk"; + resets = <&src SKY1_ISP_RCSU0_RESET_N>, + <&src SKY1_ISP_SRESET_N>, + <&src SKY1_ISP_ARESET_N>, + <&src SKY1_ISP_HRESET_N>, + <&src SKY1_ISP_GDCRESET_N>; + reset-names = "rcsu_reset", "isp_sreset", "isp_areset", + "isp_hreset", "isp_gdcreset"; + + ahb-pmctrl-res-base = <0x16000404>; + ahb-pmctrl-res-size = <0x1>; + ahb-rcsuisp0-res-base = <0x14330000>; + ahb-rcsuisp0-res-size = <0x1000>; + ahb-rcsuisp1-res-base = <0x14350000>; + ahb-rcsuisp1-res-size = <0x1000>; + iommus = <&smmu_mmhub 0x1F>; + status = "disabled"; + }; + + reg_definition: reg-definition@05040100 { + compatible = "sky1,csu_se_pub", "syscon"; + reg = <0x0 0x05040000 0x0 0x1000>; + }; + + sky1_rng: sky1-rng@05055300 { + compatible = "cix,sky1-rng"; + reg = <0x0 0x05055300 0x0 0x30>; + status = "disabled"; + }; + + cix_reboot{ + compatible = "cix,reboot"; + arm,smc-id = <0xc2000002>; + /*need to add register to record reason*/ + status = "disabled"; + }; + + cix_pmu_ci700: cix_pmu_ci700 { + compatible = "cix,pmu"; + reg = <0x00 0x0a00032c 0x00 0x4>, + <0x00 0x0a000330 0x00 0x4>, + <0x00 0x0a000334 0x00 0x4>, + <0x00 0x0a00033c 0x00 0x4>; + status = "disabled"; + }; + + cix_pmu_ni700: cix_pmu_ni700 { + compatible = "cix,pmu"; + reg = <0x00 0x0a06032c 0x00 0x4>, + <0x00 0x0a060330 0x00 0x4>, + <0x00 0x0a060334 0x00 0x4>, + <0x00 0x0a06033c 0x00 0x4>; + status = "disabled"; + }; + + cix_bus_ci700: cix_bus_ci700 { + compatible = "cix,bus-ci700"; + power-domain-names = "perf"; + power-domains = <&scmi_dvfs CI700_DFS_DOMAIN_ID>; + devfreq-events = <&cix_pmu_ci700>; + status = "disabled"; + }; + + cix_bus_ni700: cix_bus_ni700 { + compatible = "cix,bus-ni700"; + power-domain-names = "perf"; + power-domains = <&scmi_dvfs NI700_DFS_DOMAIN_ID>; + devfreq-events = <&cix_pmu_ni700>; + status = "disabled"; + }; + + cix_ipa: cix_cpu_ipa { + compatible = "cix,cpu-ipa"; + reg = <0x00 0x83bf0300 0x00 0x300>; + status = "disabled"; + }; + + cix_ddrlp: cix_ddr_lp { + compatible = "cix,ddr-lp"; + status = "disabled"; + }; + + thermal_zones:thermal-zones { + vpu-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor VPU_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + gpu0-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor GPU_BOTTOM_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + gpu1-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor GPU_TOP_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + brc-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor SOC_BRC_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + ddr0-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor DDR_BOTTOM4_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + ddr1-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor DDR_TOP_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + ci700-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor CI700_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + npu-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor NPU_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + trc-thermal { + polling-delay-passive = <250>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor SOC_TRC_TEMP_SENSOR_ID>; + + trips { + trip-point-0 { + temperature = <95000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + }; + + gpu-avg-thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + thermal-sensors = <&scmi_sensor GPU_AVERAGE_TEMP_SENSOR_ID>; + sustainable-power = <15000>; + + trips { + switch_on:trip-point-0 { + temperature = <70000>; + hysteresis = <1000>; + type = "passive"; + }; + + target_on:trip-point-1 { + temperature = <85000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&switch_on>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + map1 { + trip = <&target_on>; + cooling-device = <&gpu THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + }; + }; + }; + }; + + cix_dst: cix_dst { + compatible = "cix,dst", "simple-bus"; + ramlog_addr = <0x0 0x83DA0000>; + ramlog_size = <0x0 0x00040000>; + memory-region = <&rdr_res_region>; + rdr-log-max-size = <0x800000>; + rdr_area_num = <15>; + rdr_area_sizes = <0x100000 0x10000 0x10000 0x10000 0x10000 0x10000 + 0x10000 0x10000 0x10000 0x10000 0x10000 0x10000 + 0x10000 0x10000 0x10000>; + rdr-log-max-nums = <6>; + wait-dumplog-timeout = <1000>; + unexpected-max-reboot-times = <1>; + rdr-dumpctl="1111111111"; + status = "disabled"; + + exception_trace: exception_trace { + compatible = "rdr,exceptiontrace"; + area_num = <1>; + area_sizes = < 0x1000 >; + status = "disabled"; + }; + + ap_adapter: ap_adapter{ + compatible = "rdr,rdr_ap_adapter"; + /* reg-dump-regions = <3>; */ + /* reg = <0 0x61080000 0 0x10000>, */ + /* <0 0x61090000 0 0x10000>, */ + /* <0 0x610a0000 0 0x10000>; */ + /* reg-names = "test1", "test2", "test3"; */ + ap_trace_irq_size = <0x10000>; + ap_trace_task_size = <0x10000>; + ap_trace_cpu_idle_size = <0x10000>; + ap_trace_worker_size = <0x10000>; + ap_trace_time_size = <0x10000>; + ap_trace_cpu_on_off_size = <0x10000>; + ap_trace_syscall_size = <0x10000>; + ap_trace_hung_task_size = <0x10000>; + ap_trace_tasklet_size = <0x10000>; + ap_dump_mem_modu_test_size = <1024>; + ap_dump_mem_modu_idm_size = <0x1000>; + ap_dump_mem_modu_tzc400_size = <0x1000>; + ap_dump_mem_modu_smmu_size = <0x1000>; + ap_dump_mem_modu_tfa_size = <0x4000>; + ap_dump_mem_modu_gap_size = <256>; + ap_log_console_size = <0xc000>; + ap_log_dmesg_size = <0xc000>; + status = "disabled"; + }; + }; + + ddr_ctrl0: ddr_ctrl@0C010000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C010000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x0>; + status = "disabled"; + }; + + ddr_ctrl1: ddr_ctrl@0C030000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C030000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x1>; + status = "disabled"; + }; + + ddr_ctrl2: ddr_ctrl@0C050000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C050000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x2>; + status = "disabled"; + }; + + ddr_ctrl3: ddr_ctrl@0C070000 { + compatible = "cadence,ddr_ctrl"; + reg = <0x0 0x0C070000 0x0 0x20000>, + <0x0 0x83c00000 0x0 0x1000>; + interrupts = ; + channel_id = <0x3>; + status = "disabled"; + }; + +#ifdef SKY1_CORESIGHT_SUPPORT + ete0: ete0 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU0>; + status = "okay"; +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port0: endpoint { + remote-endpoint = <&dsu_funnel_in_port0>; + }; + }; + }; +#endif + }; + + ete1: ete1 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU1>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port1: endpoint { + remote-endpoint = <&dsu_funnel_in_port1>; + }; + }; + }; +#endif + }; + + ete2: ete2 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU2>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port2: endpoint { + remote-endpoint = <&dsu_funnel_in_port2>; + }; + }; + }; +#endif + }; + + ete3: ete3 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU3>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port3: endpoint { + remote-endpoint = <&dsu_funnel_in_port3>; + }; + }; + }; +#endif + }; + + ete4: ete4 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU4>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port4: endpoint { + remote-endpoint = <&dsu_funnel_in_port4>; + }; + }; + }; +#endif + }; + + ete5: ete5 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU5>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port5: endpoint { + remote-endpoint = <&dsu_funnel_in_port5>; + }; + }; + }; +#endif + }; + + ete6: ete6 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU6>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port6: endpoint { + remote-endpoint = <&dsu_funnel_in_port6>; + }; + }; + }; +#endif + }; + + ete7: ete7 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU7>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port7: endpoint { + remote-endpoint = <&dsu_funnel_in_port7>; + }; + }; + }; +#endif + }; + + ete8: ete8 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU8>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port8: endpoint { + remote-endpoint = <&dsu_funnel_in_port8>; + }; + }; + }; +#endif + }; + + ete9: ete9 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU9>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port9: endpoint { + remote-endpoint = <&dsu_funnel_in_port9>; + }; + }; + }; +#endif + }; + + ete10: ete10 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU10>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port10: endpoint { + remote-endpoint = <&dsu_funnel_in_port10>; + }; + }; + }; +#endif + }; + + ete11: ete11 { + compatible = "arm,embedded-trace-extension"; + cpu = <&CPU11>; + status = "okay"; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + out-ports { + port { + ete_out_port11: endpoint { + remote-endpoint = <&dsu_funnel_in_port11>; + }; + }; + }; +#endif + }; + +#ifndef SKY1_CORESIGHT_TRBE_SUPPORT + funnel_dsu: funnel@dsu { + compatible = "arm,coresight-static-funnel"; + status = "okay"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@0 { + reg = <0>; + dsu_funnel_in_port0: endpoint { + remote-endpoint = <&ete_out_port0>; + }; + }; + + port@1 { + reg = <1>; + dsu_funnel_in_port1: endpoint { + remote-endpoint = <&ete_out_port1>; + }; + }; + + port@2 { + reg = <2>; + dsu_funnel_in_port2: endpoint { + remote-endpoint = <&ete_out_port2>; + }; + }; + + port@3 { + reg = <3>; + dsu_funnel_in_port3: endpoint { + remote-endpoint = <&ete_out_port3>; + }; + }; + + port@4 { + reg = <4>; + dsu_funnel_in_port4: endpoint { + remote-endpoint = <&ete_out_port4>; + }; + }; + + port@5 { + reg = <5>; + dsu_funnel_in_port5: endpoint { + remote-endpoint = <&ete_out_port5>; + }; + }; + + port@6 { + reg = <6>; + dsu_funnel_in_port6: endpoint { + remote-endpoint = <&ete_out_port6>; + }; + }; + + port@7 { + reg = <7>; + dsu_funnel_in_port7: endpoint { + remote-endpoint = <&ete_out_port7>; + }; + }; + + port@8 { + reg = <8>; + dsu_funnel_in_port8: endpoint { + remote-endpoint = <&ete_out_port8>; + }; + }; + + port@9 { + reg = <9>; + dsu_funnel_in_port9: endpoint { + remote-endpoint = <&ete_out_port9>; + }; + }; + + port@10 { + reg = <10>; + dsu_funnel_in_port10: endpoint { + remote-endpoint = <&ete_out_port10>; + }; + }; + + port@11 { + reg = <11>; + dsu_funnel_in_port11: endpoint { + remote-endpoint = <&ete_out_port11>; + }; + }; + }; + + out-ports { + port { + dsu_funnel_out_port: endpoint { + remote-endpoint = <&cpu_etf_in_port>; + }; + }; + }; + }; + + etf_cpu: etf@cpu { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x18060000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9ea>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + cpu_etf_in_port: endpoint { + remote-endpoint = <&dsu_funnel_out_port>; + }; + }; + }; + + out-ports { + port { + cpu_etf_out_port: endpoint { + remote-endpoint = <&soc_funnel_in_port2>; + }; + }; + }; + }; + + stm: stm@18010000 { + compatible = "arm,coresight-stm", "arm,primecell"; + reg = <0 0x18010000 0 0x10000>, + <0x0000001C 0xB0000000 0 0x1000000>; + reg-names = "stm-base", "stm-stimulus-base"; + arm,primecell-periphid = <0x000bb963>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + out-ports { + port { + stm0_out_port: endpoint { + remote-endpoint = <&stm_etf_in_port>; + }; + }; + }; + }; + + etf_stm: etf@stm { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x180A0000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9ea>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + stm_etf_in_port: endpoint { + remote-endpoint = <&stm0_out_port>; + }; + }; + }; + + out-ports { + port { + stm_etf_out_port: endpoint { + remote-endpoint = <&soc_funnel_in_port6>; + }; + }; + }; + }; + + funnel_soc: funnel@soc { + compatible = "arm,coresight-dynamic-funnel", "arm,primecell"; + reg = <0x0 0x180B0000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9eb>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + #address-cells = <1>; + #size-cells = <0>; + + port@2 { + reg = <2>; + soc_funnel_in_port2: endpoint { + remote-endpoint = <&cpu_etf_out_port>; + }; + }; + + port@6 { + reg = <6>; + soc_funnel_in_port6: endpoint { + remote-endpoint = <&stm_etf_out_port>; + }; + }; + + }; + + out-ports { + port { + soc_funnel_out_port: endpoint { + remote-endpoint = <&soc_etf_in_port>; + }; + }; + }; + }; + + etf_soc: etf@soc { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x19000000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9ea>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + soc_etf_in_port: endpoint { + remote-endpoint = <&soc_funnel_out_port>; + }; + }; + }; + + out-ports { + port { + soc_etf_out_port: endpoint { + remote-endpoint = <&etr_in_port>; + }; + }; + }; + }; + + etr0: etr@180c0000 { + compatible = "arm,coresight-tmc", "arm,primecell"; + reg = <0x0 0x180c0000 0x0 0x10000>; + arm,primecell-periphid = <0x000bb9e8>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + etr_in_port: endpoint { + remote-endpoint = <&soc_etf_out_port>; + }; + }; + }; + + out-ports { + port { + etr_out_port: endpoint { + remote-endpoint = <&catu_in_port>; + }; + }; + }; + }; + + catu0: catu@180d0000 { + compatible = "arm,coresight-catu", "arm,primecell"; + reg = <0 0x180d0000 0 0x10000>; + /* interrupts = ; */ + arm,primecell-periphid = <0x000bb9ee>; + clocks = <&dfd_clk>; + clock-names = "apb_pclk"; + status = "okay"; + + in-ports { + port { + catu_in_port: endpoint { + remote-endpoint = <&etr_out_port>; + }; + }; + }; + }; +#endif + +#ifdef SKY1_CORESIGHT_TRBE_SUPPORT + trbe { + compatible = "arm,trace-buffer-extension"; + interrupts = ; + interrupt-parent = <&gic>; + status = "okay"; + }; +#endif +#endif +}; + diff --git a/arch/arm64/configs/cix.config b/arch/arm64/configs/cix.config new file mode 100755 index 000000000000..37d742473137 --- /dev/null +++ b/arch/arm64/configs/cix.config @@ -0,0 +1,554 @@ +# Cix specific options +# +# overlay configs +CONFIG_FORCE_MAX_ZONEORDER=14 + +# disable other ARCH +CONFIG_ARCH_AGILEX=n +CONFIG_ARCH_SUNXI=n +CONFIG_ARCH_ALPINE=n +CONFIG_ARCH_BCM2835=n +CONFIG_ARCH_BCM_IPROC=n +CONFIG_ARCH_BERLIN=n +CONFIG_ARCH_BRCMSTB=n +CONFIG_ARCH_EXYNOS=n +CONFIG_ARCH_K3=n +CONFIG_ARCH_LAYERSCAPE=n +CONFIG_ARCH_LG1K=n +CONFIG_ARCH_HISI=n +CONFIG_ARCH_MEDIATEK=n +CONFIG_ARCH_MESON=n +CONFIG_ARCH_MVEBU=n +CONFIG_ARCH_MXC=n +CONFIG_ARCH_QCOM=n +CONFIG_ARCH_RENESAS=n +CONFIG_ARCH_ROCKCHIP=n +CONFIG_ARCH_S32=n +CONFIG_ARCH_SEATTLE=n +CONFIG_ARCH_STRATIX10=n +CONFIG_ARCH_SYNQUACER=n +CONFIG_ARCH_TEGRA=n +CONFIG_ARCH_SPRD=n +CONFIG_ARCH_THUNDER=n +CONFIG_ARCH_THUNDER2=n +CONFIG_ARCH_UNIPHIER=n +CONFIG_ARCH_VEXPRESS=n +CONFIG_ARCH_VISCONTI=n +CONFIG_ARCH_XGENE=n +CONFIG_ARCH_ZX=n +CONFIG_ARCH_ZYNQMP=n + +CONFIG_LOCALVERSION="-cix-build" +CONFIG_LOCALVERSION_AUTO=n + +# Arm64 feature +CONFIG_ARM64_VHE=n +CONFIG_ARM64_MTE=n + +# cix configs +CONFIG_ARCH_CIX=y + +# Protocols +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_RAM_COUNT=16 +CONFIG_BLK_DEV_RAM_SIZE=40960 + +# mtd device +CONFIG_MTD_SLRAM=m +CONFIG_MTD_PHRAM=y + +# for dmabuf related heaps +CONFIG_DMABUF_HEAPS=y +CONFIG_DMABUF_HEAPS_DSP=y +CONFIG_DMABUF_HEAPS_SYSTEM=y +CONFIG_DMABUF_HEAPS_CMA=y +CONFIG_DMABUF_HEAPS_VPU=y + +# GMAC +CONFIG_MACB=y +CONFIG_PHYLINK=y + +# realtek ethernet driver +CONFIG_R8125=m +CONFIG_R8126=m +CONFIG_R8127=m +CONFIG_PG_DRV=m + +# ethernet phy driver +CONFIG_REALTEK_PHY=y + +# for mbox driver +CONFIG_CIX_MBOX=y +CONFIG_ARM_MHU=n + +CONFIG_CIX_AP2SE_IPC=y + +# for watchdog driver +CONFIG_SKY1_WATCHDOG=y +CONFIG_WATCHDOG_SYSFS=y + +# for timer driver +CONFIG_TIMER_SKY1_GPT=y + +# for pwm driver +CONFIG_PWM_SKY1=y + +# for reset driver +CONFIG_RESET_SKY1=y + +# for pinctrl driver +CONFIG_PINCTRL_SKY1_BASE=y +CONFIG_PINCTRL_SKY1=y + +# for gpio driver +CONFIG_GPIO_CADENCE=y +CONFIG_GPIO_SYSFS=y + +# for rpmsg +CONFIG_RPMSG_CHAR=y +CONFIG_RPMSG_CTRL=y +CONFIG_RPMSG_NS=y +CONFIG_RPMSG_VIRTIO=y + +# for dsp remoteproc driver +CONFIG_CIX_DSP_REMOTEPROC=m + +# for sfh remoteproc driver +CONFIG_CIX_SHF_REMOTEPROC=m + +# for VPU driver +CONFIG_MEDIA_SUPPORT=y +CONFIG_VIDEO_CAFE_CCIC=y + +# ASoC +CONFIG_SOUND=y +CONFIG_SND=y +CONFIG_SND_DEBUG=y +CONFIG_SND_DEBUG_VERBOSE=y +CONFIG_SND_PCM_XRUN_DEBUG=y +CONFIG_SND_TIMER=y +CONFIG_SND_PCM=y +CONFIG_SND_JACK=y +CONFIG_SND_JACK_INPUT_DEV=y +CONFIG_SND_PCM_TIMER=y +CONFIG_SND_PROC_FS=y +CONFIG_SND_SOC=y +CONFIG_SND_HDA_HWDEP=y + +# ASoC Card driver +CONFIG_SND_SOC_CIX=m + +# ASoC Codec driver +CONFIG_SND_SOC_RT5682S=m +CONFIG_SND_SOC_SN6040=m +CONFIG_SND_SOC_ES8326=m + +# ASoC driver +CONFIG_SND_SOC_CDNS_I2S_SC=m +CONFIG_SND_SOC_CDNS_I2S_MC=m + +#ASoC IPBLOQ HDA driver +CONFIG_SND_HDA_CIX_IPBLOQ=m + +# REALTEK HDA CODEC driver +CONFIG_SND_HDA_CODEC_REALTEK=m + +#SOF +CONFIG_CIX_DSP=m +CONFIG_SND_SOC_SOF_TOPLEVEL=y +CONFIG_SND_SOC_SOF_OF=m +CONFIG_SND_SOC_SOF_COMPRESS=y +CONFIG_SND_SOC_SOF_CIX_TOPLEVEL=y +CONFIG_SND_SOC_SOF_CIX_SKY1=m + +# USB audio support +CONFIG_SND_USB=y +CONFIG_SND_USB_AUDIO=y + +# Audio Subsystem clock driver +CONFIG_CLK_SKY1_AUDSS=m + +# Audio Subsystem reset driver +CONFIG_RESET_SKY1_AUDSS=m + +# Dummy Codec Driver +CONFIG_SND_SOC_DUMMY_CODEC=y + +# HDMI Codec Driver +CONFIG_SND_SOC_HDMI_CODEC=m + +# ISP driver +CONFIG_CAMERA_ARMCB=m + +# DRM feature +CONFIG_DRM=y +# ARM D71 driver +CONFIG_DRM_KOMEDA=m +# ARM Linlon-DP driver +CONFIG_DRM_LINLONDP=m +# CONFIG_DRM_LINLONDP_CLOCK_FIXED=y +# virtual KMS driver +CONFIG_DRM_VKMS=m +# CIX DRM driver +CONFIG_DRM_CIX=y +CONFIG_DRM_CIX_VIRTUAL=y +CONFIG_LINLON_AEU=m +CONFIG_DRM_NOUVEAU=n + +# for usb driver +CONFIG_USB_CDNS_SUPPORT=y +CONFIG_USB_CDNSP=y +CONFIG_USB_CDNSP_SKY1=y +CONFIG_USB_CDNSP_GADGET=y +CONFIG_USB_CDNSP_HOST=y +CONFIG_TYPEC=y +CONFIG_PHY_CIX_USBDP=y +CONFIG_PHY_CIX_USB2=y +CONFIG_PHY_CIX_USB3=y +CONFIG_TYPEC_RTS5453=y +# for usb uas +CONFIG_USB_UAS=y + +# for QCOM lte 4g module support +CONFIG_USB_SERIAL=y +CONFIG_USB_SERIAL_GENERIC=y +CONFIG_USB_SERIAL_QUALCOMM=y +CONFIG_USB_SERIAL_WWAN=y +CONFIG_USB_SERIAL_QT2=y +CONFIG_USB_NET_RNDIS_HOST=y +CONFIG_USB_SERIAL_OPTION=y +CONFIG_USB_USBNET=y +CONFIG_USB_NET_CDCETHER=y + +# for usb test +CONFIG_USB_TEST=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_LB_SS=y + +# LT7911UXC driver +CONFIG_VIDEO_LT7911UXC=m + +# required by GPU +CONFIG_FW_LOADER=y +CONFIG_DMA_SHARED_BUFFER=y + +# bluetooth driver +CONFIG_BT_RTKBTUSB=m +CONFIG_BT=y +CONFIG_BT_RFCOMM=y +CONFIG_BT_RFCOMM_TTY=y +CONFIG_BT_BNEP=y +CONFIG_BT_BNEP_MC_FILTER=y +CONFIG_BT_BNEP_PROTO_FILTER=y +CONFIG_BT_HIDP=y +CONFIG_BT_LE=y +CONFIG_BT_DEBUGFS=y +CONFIG_BT_HCIUART=y +CONFIG_UHID=m + +# wlan driver +CONFIG_CFG80211=m +CONFIG_MAC80211=y +CONFIG_RFKILL=y +CONFIG_RFKILL_WLAN=y +CONFIG_RFKILL_BT=m + +# Cadence I2C driver +CONFIG_I2C_CADENCE=y +CONFIG_IIO=y +CONFIG_MMC5633_I2C=n +# Cadence I3C driver +CONFIG_I3C=y +CONFIG_CDNS_I3C_MASTER=y +CONFIG_MMC5633_I3C=n +CONFIG_I3CDEV=y +#Power management configs +CONFIG_ARM_SCMI_PROTOCOL=y +CONFIG_RESET_SCMI=n +CONFIG_CIX_CLK_DEBUG=y +CONFIG_COMMON_CLK_CIX=y +#CONFIG_ARM_CIX_CPUFREQ is not set +CONFIG_ARM_SCMI_CPUFREQ=y +CONFIG_CPU_FREQ_GOV_ONDEMAND=n +CONFIG_COMMON_CLK_SCMI=y +CONFIG_CIX_SOC_ACPI=y +CONFIG_CIX_ACPI_CLK=y +CONFIG_CIX_ACPI_POWER_DOMAIN=y +CONFIG_ACPI_CPPC_CPUFREQ=y +CONFIG_PM=n +CONFIG_CPU_FREQ=y +CONFIG_CPU_PM=n +CONFIG_NO_HZ_IDLE=y +CONFIG_POWER_RESET_CIX=y +CONFIG_PM_DEBUG=y +CONFIG_PM_SLEEP_DEBUG=y +CONFIG_DVFS_BOARD_CHECK=y +# CIX Devfreq +CONFIG_DEVFREQ_GOV_USERSPACE=y +CONFIG_DEVFREQ_GOV_SIMPLE_ONDEMAND=y +CONFIG_DEVFREQ_GOV_PERFORMANCE=y +CONFIG_PM_DEVFREQ_EVENT=y +CONFIG_DEVFREQ_EVENT_CIX_PMU=y +CONFIG_ARM_CIX_BUS_DEVFREQ=y + + +# ARM dma350 driver +CONFIG_ARM_DMA350=m +CONFIG_DMATEST=y + +# XSPI driver +CONFIG_SPI_CADENCE_XSPI=y + +# SSPI driver +CONFIG_SPI_MASTER=y +CONFIG_SPI_SPIDEV=y +CONFIG_SPI_CADENCE=y + +# csi-dma driver +CONFIG_CSI_DMA=m +CONFIG_VIDEO_CADENCE=y +CONFIG_VIDEO_CADENCE_CSI2RX=y +CONFIG_PHY_CADENCE_DPHY_RX=y + +#pcie +CONFIG_PCIE_CADENCE=y +CONFIG_PCIE_CADENCE_HOST=y +CONFIG_PCI_SKY1=y +CONFIG_PCI_SKY1_HOST=y +CONFIG_PHY_CIX_PCIE=y +CONFIG_PCIEASPM_POWERSAVE=y + +# dp +CONFIG_DRM_TRILIN_DPSUB=m +CONFIG_DRM_CIX_EDP_PANEL=m + +#hwmon +CONFIG_SENSORS_ARM_SCMI=y +CONFIG_SENSORS_PWM_FAN=y + +# for ci-700 pmu +CONFIG_ARM_CMN=y + +# for softlockup detector +CONFIG_DEBUG_KERNEL=y +CONFIG_DEBUG_INFO_REDUCED=n +CONFIG_LOCKUP_DETECTOR=y +CONFIG_SOFTLOCKUP_DETECTOR=y + +# for hung_task +CONFIG_DETECT_HUNG_TASK=y +CONFIG_DFX_HUNGTASK=y +CONFIG_DFX_HUNGTASK_USER=y + +#for nvme support +CONFIG_NVME_CORE=y +CONFIG_BLK_DEV_NVME=y + +# for pstore +CONFIG_PSTORE=y +CONFIG_PSTORE_CONSOLE=y +CONFIG_PSTORE_RAM=y +CONFIG_PSTORE_PMSG=y + +# for arm sde driver +CONFIG_ARM_SDE_INTERFACE=y + +# for cix dst support +CONFIG_SOC_CIX=y +CONFIG_CIX_CPU_INSTPIPE_FRESH=y +CONFIG_CIX_DST=y +CONFIG_PLAT_PRINTK_EXT=y +CONFIG_PLAT_BOOT_TIME=y +CONFIG_PLAT_BOOT_POSTCODE=y +CONFIG_PLAT_REBOOT_REASON=y +CONFIG_SKY1_REBOOT_REASON=y +CONFIG_PLAT_MNTNDUMP=y +CONFIG_PLAT_KERNELDUMP=y +# Blackbox configs +CONFIG_PLAT_BBOX=y +# CONFIG_PLAT_BBOX_TEST=y +# CONFIG_PLAT_TEE_EXCEPTIONS=y +CONFIG_PLAT_AP_HOOK=y +CONFIG_PLAT_SDEI_EXCEPTIONS=y +CONFIG_PLAT_FDLEAK=y +CONFIG_PLAT_LOGGER=y +CONFIG_PLAT_DSM=y +CONFIG_PLAT_IDM_DETECT=y +CONFIG_PLAT_TFA_TRACE=y +CONFIG_PLAT_TZC400_DETECT=y +CONFIG_PLAT_SKY1_AUDIO_TIMEOUT=y +CONFIG_PLAT_SKY1_RCSU_GASKET_ERROR=y +CONFIG_PLAT_SKY1_SE_PM_CRASH=y +CONFIG_PLAT_HW_BREAKPOINT=y +# pmic exception +CONFIG_PM_EXCEPTION_DRIVER=y +CONFIG_PM_EXCP_DSM_DRIVER=y +# ddr exception +CONFIG_PLAT_DDR_EXCEPTION_DETECT=y +# cache exception monitor +CONFIG_PLAT_CACHE_EXCEPTION_MONITOR=y + +# for fd over check +CONFIG_FD_OVER_CHECK=y +CONFIG_PLAT_WAKEUP_SOURCE=y + +# add coresight hw tracing support +#CONFIG_CORESIGHT=y +#CONFIG_CORESIGHT_LINK_AND_SINK_TMC=y +#CONFIG_CORESIGHT_LINKS_AND_SINKS=y +#CONFIG_CORESIGHT_SOURCE_ETM4X=y +#CONFIG_CORESIGHT_CATU=y +# add trbe support +#CONFIG_CORESIGHT_TRBE=y + +# logbuf size 1Mb +CONFIG_LOG_BUF_SHIFT=20 + +# dsu partial powerdown +CONFIG_ARM64_DSU_PCTRL_DEVFREQ=y + +# for pmu events +CONFIG_ARM_PMU=y +CONFIG_PERF_EVENTS=y +CONFIG_HW_PERF_EVENTS=y + +# for dsu pmu +CONFIG_ARM_DSU_PMU=y + +# for arm smmu pmu +CONFIG_ARM_SMMU_PMU=y + +# for hwspinlock +CONFIG_HWSPINLOCK_SKY1=y + +# for third party rtc driver +CONFIG_RTC_DRV_RX8900=y + +# for acpi i2c hid driver +CONFIG_I2C_HID_ACPI=y + +# for spe pmu +CONFIG_ARM_SPE_PMU=y + +# for cix sky1 fuse driver +CONFIG_NVMEM_SKY1=y + +# for cix sky1 socinfo driver +CONFIG_CIX_SKY1_SOCINFO=y + +# for cix sensorhub driver +CONFIG_CIX_SENSORHUB=y + +# for mpam feature +CONFIG_ARM64_MPAM=n +CONFIG_MPAM_ARCH=n +CONFIG_MPAM_POLICY=n + +#for BPF +CONFIG_BPF_SYSCALL=n + +# for hw trng feature +CONFIG_HW_RANDOM_OPTEE=n +CONFIG_HW_RANDOM_SKY1=n +CONFIG_HW_RANDOM=n + +# for ec drivers +CONFIG_CIX_EC=y +CONFIG_PWM_CROS_EC=y + + +# for dynamic debug +CONFIG_DEBUG_FS=y +CONFIG_DYNAMIC_DEBUG=y + +CONFIG_ISO9660_FS=y + +# for cloud book e shutter feature +CONFIG_CIX_SKY1_E_SHUTTER=y + +# EAS +CONFIG_SCHED_DEBUG=y + +#Thermal +CONFIG_THERMAL_WRITABLE_TRIPS=y + +#for i2c slave mode test +CONFIG_I2C_SLAVE_EEPROM=y + +#for sensorhub framework +CONFIG_CIX_KERNEL_SENSORHUB=y +CONFIG_CIX_SF_SCP_SUPPORT=y +CONFIG_CIX_HF_TEST_CASE=y + +# +# Scheduler features +# +CONFIG_UCLAMP_TASK=y +CONFIG_UCLAMP_BUCKETS_COUNT=20 +CONFIG_UCLAMP_TASK_GROUP=y +CONFIG_CFS_BANDWIDTH=y +# end of Scheduler features +CONFIG_PSI=y +CONFIG_BLK_CGROUP_IOLATENCY=y +CONFIG_BLK_CGROUP_IOCOST=y +CONFIG_BLK_CGROUP_IOPRIO=y + +#Input subsystem +CONFIG_INPUT_UINPUT=y + +#ARM SCMI supports both DT and ACPI, default only support DT +CONFIG_ARM_SCMI_SUPPORT_DT_ACPI=y +CONFIG_NET_VENDOR_STMICRO=n +CONFIG_NET_VENDOR_BROADCOM=n +CONFIG_NET_VENDOR_ATHEROS=n +CONFIG_NET_VENDOR_QUALCOMM=n +CONFIG_NET_VENDOR_MELLANOX=n + + +# for ftrace +CONFIG_NOP_TRACER=y +CONFIG_HAVE_FUNCTION_TRACER=y +CONFIG_HAVE_FUNCTION_GRAPH_TRACER=y +CONFIG_HAVE_DYNAMIC_FTRACE=y +CONFIG_HAVE_DYNAMIC_FTRACE_WITH_REGS=y +CONFIG_HAVE_FTRACE_MCOUNT_RECORD=y +CONFIG_HAVE_SYSCALL_TRACEPOINTS=y +CONFIG_HAVE_C_RECORDMCOUNT=y +CONFIG_TRACE_CLOCK=y +CONFIG_RING_BUFFER=y +CONFIG_EVENT_TRACING=y +CONFIG_CONTEXT_SWITCH_TRACER=y +CONFIG_TRACING=y +CONFIG_TRACING_SUPPORT=y +CONFIG_FTRACE=y + +#thermal +CONFIG_THERMAL_DEFAULT_GOV_POWER_ALLOCATOR=y +CONFIG_THERMAL_GOV_STEP_WISE=y +CONFIG_CIX_THERMAL=y + +# add vendor hook support +CONFIG_CIX_VENDOR_HOOKS=y + +# for amdgpu +CONFIG_DRM_AMDGPU=m +CONFIG_DRM_AMDGPU_SI=y +CONFIG_DRM_AMDGPU_CIK=y +CONFIG_DRM_TTM=m +CONFIG_DRM_TTM_HELPER=m +CONFIG_DRM_KMS_HELPER=m +CONFIG_DRM_VRAM_HELPER=m +# add hiview driver support +CONFIG_HIEVENT=y +CONFIG_HISYSEVENT=y + +# add exfat fs support +CONFIG_EXFAT_FS=y +CONFIG_CIX_SE_CONFIG=y + +# add panfrost support +CONFIG_DRM_PANTHOR=m + +CONFIG_BINFMT_ELF=y +CONFIG_BINFMT_SCRIPT=y +CONFIG_BINFMT_MISC=y diff --git a/arch/arm64/configs/cix_cloudbook.config b/arch/arm64/configs/cix_cloudbook.config new file mode 100644 index 000000000000..5df5278e1b11 --- /dev/null +++ b/arch/arm64/configs/cix_cloudbook.config @@ -0,0 +1 @@ +CONFIG_ARCH_FORCE_MAX_ORDER=14 diff --git a/arch/arm64/configs/cix_debug.config b/arch/arm64/configs/cix_debug.config new file mode 100755 index 000000000000..de65844e2add --- /dev/null +++ b/arch/arm64/configs/cix_debug.config @@ -0,0 +1,3 @@ +# Cix specific options +# +# overlay configs diff --git a/arch/arm64/configs/cix_emu.config b/arch/arm64/configs/cix_emu.config new file mode 100644 index 000000000000..71b674db9533 --- /dev/null +++ b/arch/arm64/configs/cix_emu.config @@ -0,0 +1,2 @@ +CONFIG_ARCH_CIX_EMU=y +CONFIG_ARM_CMN=n diff --git a/arch/arm64/configs/cix_fpga.config b/arch/arm64/configs/cix_fpga.config new file mode 100644 index 000000000000..5275124f8cb5 --- /dev/null +++ b/arch/arm64/configs/cix_fpga.config @@ -0,0 +1,2 @@ +CONFIG_ARCH_CIX_FPGA=y +CONFIG_ARM_CMN=n diff --git a/arch/arm64/configs/cix_redroid.config b/arch/arm64/configs/cix_redroid.config new file mode 100644 index 000000000000..18ce211945cd --- /dev/null +++ b/arch/arm64/configs/cix_redroid.config @@ -0,0 +1,221 @@ +CONFIG_VETH=y +CONFIG_PSI=y +CONFIG_BLK_DEV_LOOP_MIN_COUNT=16 +CONFIG_DM_VERITY=y +CONFIG_NETFILTER_XT_MATCH_ADDRTYPE=y +CONFIG_BRIDGE=y +CONFIG_BRIDGE_NETFILTER=y +CONFIG_ANDROID_BINDERFS=y +CONFIG_ANDROID_DEBUG_SYMBOLS=y +CONFIG_ANDROID_VENDOR_HOOKS=y +CONFIG_ANDROID_DEBUG_KINFO=y +CONFIG_FUSE_FS=y +CONFIG_WERROR=n +CONFIG_INPUT_UINPUT=y +CONFIG_HID_MULTITOUCH=y +CONFIG_HID_BATTERY_STRENGTH=y +CONFIG_HIDRAW=y +CONFIG_UHID=y +CONFIG_USB_HIDDEV=y +CONFIG_USB_CONFIGFS_UEVENT=y +CONFIG_HID_STEAM=y +CONFIG_MD=y +CONFIG_BLK_DEV_DM=y +CONFIG_BLK_DEV_DM_BUILTIN=y +CONFIG_USERFAULTFD=y + +# Enable bpf +CONFIG_BPF_SYSCALL=y +CONFIG_BPFILTER=y +CONFIG_BPF_JIT=y + +# Enable nf_tables +CONFIG_NF_TABLES=m +CONFIG_NF_TABLES_INET=y +CONFIG_NF_TABLES_NETDEV=y +CONFIG_NFT_NUMGEN=m +CONFIG_NFT_CT=m +CONFIG_NFT_FLOW_OFFLOAD=m +CONFIG_NFT_COUNTER=m +CONFIG_NFT_CONNLIMIT=m +CONFIG_NFT_LOG=m +CONFIG_NFT_LIMIT=m +CONFIG_NFT_MASQ=m +CONFIG_NFT_REDIR=m +CONFIG_NFT_NAT=m +CONFIG_NFT_TUNNEL=m +CONFIG_NFT_OBJREF=m +CONFIG_NFT_QUEUE=m +CONFIG_NFT_QUOTA=m +CONFIG_NFT_REJECT=m +CONFIG_NFT_COMPAT=m +CONFIG_NFT_HASH=m +CONFIG_NFT_XFRM=m +CONFIG_NFT_SOCKET=m +CONFIG_NFT_OSF=m +CONFIG_NFT_TPROXY=m +CONFIG_NFT_DUP_NETDEV=m +CONFIG_NFT_FWD_NETDEV=m +CONFIG_NF_FLOW_TABLE_INET=m +CONFIG_NF_FLOW_TABLE=m + +########## portting from android-base.config ########### +# KEEP ALPHABETICALLY SORTED +# CONFIG_DEVMEM is not set +# CONFIG_FHANDLE is not set +# CONFIG_INET_LRO is not set +# CONFIG_NFSD is not set +# CONFIG_NFS_FS is not set +# CONFIG_OABI_COMPAT is not set +# CONFIG_SYSVIPC is not set +# CONFIG_USELIB is not set +CONFIG_ANDROID_BINDER_IPC=y +CONFIG_ANDROID_BINDER_DEVICES=binder,hwbinder,vndbinder +CONFIG_ANDROID_LOW_MEMORY_KILLER=y +CONFIG_ARMV8_DEPRECATED=y +CONFIG_ASHMEM=y +CONFIG_AUDIT=y +CONFIG_BLK_DEV_INITRD=y +CONFIG_CGROUPS=y +CONFIG_CGROUP_BPF=y +CONFIG_CGROUP_CPUACCT=y +CONFIG_CGROUP_DEBUG=y +CONFIG_CGROUP_FREEZER=y +CONFIG_CGROUP_SCHED=y +CONFIG_CP15_BARRIER_EMULATION=y +CONFIG_DEFAULT_SECURITY_SELINUX=y +CONFIG_EMBEDDED=y +CONFIG_FB=y +CONFIG_HARDENED_USERCOPY=y +CONFIG_HIGH_RES_TIMERS=y +CONFIG_IKCONFIG=y +CONFIG_IKCONFIG_PROC=y +CONFIG_INET6_AH=y +CONFIG_INET6_ESP=y +CONFIG_INET6_IPCOMP=y +CONFIG_INET=y +CONFIG_INET_DIAG_DESTROY=y +CONFIG_INET_ESP=y +CONFIG_INET_XFRM_MODE_TUNNEL=y +CONFIG_IP6_NF_FILTER=y +CONFIG_IP6_NF_IPTABLES=y +CONFIG_IP6_NF_MANGLE=y +CONFIG_IP6_NF_RAW=y +CONFIG_IP6_NF_TARGET_REJECT=y +CONFIG_IPV6=y +CONFIG_IPV6_MIP6=y +CONFIG_IPV6_MULTIPLE_TABLES=y +CONFIG_IPV6_OPTIMISTIC_DAD=y +CONFIG_IPV6_ROUTER_PREF=y +CONFIG_IPV6_ROUTE_INFO=y +CONFIG_IP_ADVANCED_ROUTER=y +CONFIG_IP_MULTICAST=y +CONFIG_IP_MULTIPLE_TABLES=y +CONFIG_IP_NF_ARPFILTER=y +CONFIG_IP_NF_ARPTABLES=y +CONFIG_IP_NF_ARP_MANGLE=y +CONFIG_IP_NF_FILTER=y +CONFIG_IP_NF_IPTABLES=y +CONFIG_IP_NF_MANGLE=y +CONFIG_IP_NF_MATCH_AH=y +CONFIG_IP_NF_MATCH_ECN=y +CONFIG_IP_NF_MATCH_TTL=y +CONFIG_IP_NF_NAT=y +CONFIG_IP_NF_RAW=y +CONFIG_IP_NF_SECURITY=y +CONFIG_IP_NF_TARGET_MASQUERADE=y +CONFIG_IP_NF_TARGET_NETMAP=y +CONFIG_IP_NF_TARGET_REDIRECT=y +CONFIG_IP_NF_TARGET_REJECT=y +CONFIG_MODULES=y +CONFIG_MODULE_UNLOAD=y +CONFIG_MODVERSIONS=y +CONFIG_NET=y +CONFIG_NETDEVICES=y +CONFIG_NETFILTER=y +CONFIG_NETFILTER_TPROXY=y +CONFIG_NETFILTER_XT_MATCH_COMMENT=y +CONFIG_NETFILTER_XT_MATCH_CONNLIMIT=y +CONFIG_NETFILTER_XT_MATCH_CONNMARK=y +CONFIG_NETFILTER_XT_MATCH_CONNTRACK=y +CONFIG_NETFILTER_XT_MATCH_HASHLIMIT=y +CONFIG_NETFILTER_XT_MATCH_HELPER=y +CONFIG_NETFILTER_XT_MATCH_IPRANGE=y +CONFIG_NETFILTER_XT_MATCH_LENGTH=y +CONFIG_NETFILTER_XT_MATCH_LIMIT=y +CONFIG_NETFILTER_XT_MATCH_MAC=y +CONFIG_NETFILTER_XT_MATCH_MARK=y +CONFIG_NETFILTER_XT_MATCH_PKTTYPE=y +CONFIG_NETFILTER_XT_MATCH_POLICY=y +CONFIG_NETFILTER_XT_MATCH_QUOTA=y +CONFIG_NETFILTER_XT_MATCH_SOCKET=y +CONFIG_NETFILTER_XT_MATCH_STATE=y +CONFIG_NETFILTER_XT_MATCH_STATISTIC=y +CONFIG_NETFILTER_XT_MATCH_STRING=y +CONFIG_NETFILTER_XT_MATCH_TIME=y +CONFIG_NETFILTER_XT_MATCH_U32=y +CONFIG_NETFILTER_XT_TARGET_CLASSIFY=y +CONFIG_NETFILTER_XT_TARGET_CONNMARK=y +CONFIG_NETFILTER_XT_TARGET_CONNSECMARK=y +CONFIG_NETFILTER_XT_TARGET_IDLETIMER=y +CONFIG_NETFILTER_XT_TARGET_MARK=y +CONFIG_NETFILTER_XT_TARGET_NFLOG=y +CONFIG_NETFILTER_XT_TARGET_NFQUEUE=y +CONFIG_NETFILTER_XT_TARGET_SECMARK=y +CONFIG_NETFILTER_XT_TARGET_TCPMSS=y +CONFIG_NETFILTER_XT_TARGET_TPROXY=y +CONFIG_NETFILTER_XT_TARGET_TRACE=y +CONFIG_NET_CLS_ACT=y +CONFIG_NET_CLS_U32=y +CONFIG_NET_EMATCH=y +CONFIG_NET_EMATCH_U32=y +CONFIG_NET_KEY=y +CONFIG_NET_SCHED=y +CONFIG_NET_SCH_HTB=y +CONFIG_NF_CONNTRACK=y +CONFIG_NF_CONNTRACK_AMANDA=y +CONFIG_NF_CONNTRACK_EVENTS=y +CONFIG_NF_CONNTRACK_FTP=y +CONFIG_NF_CONNTRACK_H323=y +CONFIG_NF_CONNTRACK_IPV4=y +CONFIG_NF_CONNTRACK_IPV6=y +CONFIG_NF_CONNTRACK_IRC=y +CONFIG_NF_CONNTRACK_NETBIOS_NS=y +CONFIG_NF_CONNTRACK_PPTP=y +CONFIG_NF_CONNTRACK_SANE=y +CONFIG_NF_CONNTRACK_SECMARK=y +CONFIG_NF_CONNTRACK_TFTP=y +CONFIG_NF_CT_NETLINK=y +CONFIG_NF_CT_PROTO_DCCP=y +CONFIG_NF_CT_PROTO_SCTP=y +CONFIG_NF_CT_PROTO_UDPLITE=y +CONFIG_NF_NAT=y +CONFIG_NO_HZ=y +CONFIG_PACKET=y +CONFIG_PM_AUTOSLEEP=y +CONFIG_PM_WAKELOCKS=y +CONFIG_PPP=y +CONFIG_PPP_BSDCOMP=y +CONFIG_PPP_DEFLATE=y +CONFIG_PPP_MPPE=y +CONFIG_PREEMPT=y +CONFIG_QUOTA=y +CONFIG_RANDOMIZE_BASE=y +CONFIG_RTC_CLASS=y +CONFIG_RT_GROUP_SCHED=y +CONFIG_SECCOMP=y +CONFIG_SECURITY=y +CONFIG_SECURITY_NETWORK=y +CONFIG_SECURITY_SELINUX=y +CONFIG_SETEND_EMULATION=y +CONFIG_STAGING=y +CONFIG_SWP_EMULATION=y +CONFIG_SYNC=y +CONFIG_TUN=y +CONFIG_UNIX=y +CONFIG_USB_GADGET=y +CONFIG_USB_CONFIGFS=y +CONFIG_USB_CONFIGFS_F_FS=y +CONFIG_USB_CONFIGFS_F_MIDI=y +CONFIG_USB_OTG_WAKELOCK=y +CONFIG_XFRM_USER=y \ No newline at end of file diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig index 60af93c04b45..c68d52c8f784 100644 --- a/arch/arm64/configs/defconfig +++ b/arch/arm64/configs/defconfig @@ -89,10 +89,10 @@ CONFIG_ENERGY_MODEL=y CONFIG_ARM_PSCI_CPUIDLE=y CONFIG_CPU_FREQ=y CONFIG_CPU_FREQ_STAT=y -CONFIG_CPU_FREQ_GOV_POWERSAVE=m +#CONFIG_CPU_FREQ_GOV_POWERSAVE is not set CONFIG_CPU_FREQ_GOV_USERSPACE=y -CONFIG_CPU_FREQ_GOV_ONDEMAND=y -CONFIG_CPU_FREQ_GOV_CONSERVATIVE=m +#CONFIG_CPU_FREQ_GOV_ONDEMAND is not set +#CONFIG_CPU_FREQ_GOV_CONSERVATIVE is not set CONFIG_CPUFREQ_DT=y CONFIG_ACPI_CPPC_CPUFREQ=m CONFIG_ARM_ALLWINNER_SUN50I_CPUFREQ_NVMEM=m @@ -420,6 +420,7 @@ CONFIG_WLCORE_SDIO=m CONFIG_WWAN=m CONFIG_MHI_WWAN_CTRL=m CONFIG_MHI_WWAN_MBIM=m +CONFIG_INPUT=y CONFIG_INPUT_EVDEV=y CONFIG_KEYBOARD_ADC=m CONFIG_KEYBOARD_GPIO=y @@ -1349,6 +1350,7 @@ CONFIG_TI_PRUSS=m CONFIG_ARM_IMX_BUS_DEVFREQ=y CONFIG_ARM_IMX8M_DDRC_DEVFREQ=m CONFIG_ARM_MEDIATEK_CCI_DEVFREQ=m +CONFIG_EXTCON=y CONFIG_EXTCON_PTN5150=m CONFIG_EXTCON_USB_GPIO=y CONFIG_EXTCON_USBC_CROS_EC=y diff --git a/arch/arm64/include/asm/acpi.h b/arch/arm64/include/asm/acpi.h index a407f9cd549e..fac9c6a063bf 100644 --- a/arch/arm64/include/asm/acpi.h +++ b/arch/arm64/include/asm/acpi.h @@ -187,5 +187,14 @@ static inline void acpi_map_cpus_to_nodes(void) { } #endif /* CONFIG_ACPI_NUMA */ #define ACPI_TABLE_UPGRADE_MAX_PHYS MEMBLOCK_ALLOC_ACCESSIBLE +static inline unsigned long acpi_get_wakeup_address(void) +{ + return 0; +} + +static inline int acpi_suspend_lowlevel(void) +{ + return 0; +} #endif /*_ASM_ACPI_H*/ diff --git a/arch/arm64/include/asm/el2_setup.h b/arch/arm64/include/asm/el2_setup.h index b7afaa026842..bbeaf14ddd25 100644 --- a/arch/arm64/include/asm/el2_setup.h +++ b/arch/arm64/include/asm/el2_setup.h @@ -22,15 +22,6 @@ isb .endm -.macro __init_el2_hcrx - mrs x0, id_aa64mmfr1_el1 - ubfx x0, x0, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4 - cbz x0, .Lskip_hcrx_\@ - mov_q x0, HCRX_HOST_FLAGS - msr_s SYS_HCRX_EL2, x0 -.Lskip_hcrx_\@: -.endm - /* Check if running in host at EL2 mode, i.e., (h)VHE. Jump to fail if not. */ .macro __check_hvhe fail, tmp mrs \tmp, hcr_el2 @@ -208,6 +199,22 @@ msr spsr_el2, x0 .endm +.macro __init_el2_mpam +#ifdef CONFIG_ARM64_MPAM + /* Memory Partioning And Monitoring: disable EL2 traps */ + mrs x1, id_aa64pfr0_el1 + ubfx x0, x1, #ID_AA64PFR0_MPAM_SHIFT, #4 + cbz x0, .Lskip_mpam_\@ // skip if no MPAM + msr_s SYS_MPAM0_EL1, xzr // use the default partition.. + msr_s SYS_MPAM2_EL2, xzr // ..and disable lower traps + msr_s SYS_MPAM1_EL1, xzr + mrs_s x0, SYS_MPAMIDR_EL1 + tbz x0, #17, .Lskip_mpam_\@ // skip if no MPAMHCR reg + msr_s SYS_MPAMHCR_EL2, xzr // clear TRAP_MPAMIDR_EL1 -> EL2 +.Lskip_mpam_\@: +#endif +.endm + /** * Initialize EL2 registers to sane values. This should be called early on all * cores that were booted in EL2. Note that everything gets initialised as @@ -218,13 +225,13 @@ */ .macro init_el2_state __init_el2_sctlr - __init_el2_hcrx __init_el2_timers __init_el2_debug __init_el2_lor __init_el2_stage2 __init_el2_gicv3 __init_el2_hstr + __init_el2_mpam __init_el2_nvhe_idregs __init_el2_cptr __init_el2_fgt @@ -338,6 +345,14 @@ cbz x1, .Lskip_sme_\@ msr_s SYS_SMPRIMAP_EL2, xzr // Make all priorities equal + + mrs x1, id_aa64mmfr1_el1 // HCRX_EL2 present? + ubfx x1, x1, #ID_AA64MMFR1_EL1_HCX_SHIFT, #4 + cbz x1, .Lskip_sme_\@ + + mrs_s x1, SYS_HCRX_EL2 + orr x1, x1, #HCRX_EL2_SMPME_MASK // Enable priority mapping + msr_s SYS_HCRX_EL2, x1 .Lskip_sme_\@: .endm diff --git a/arch/arm64/include/asm/hw_breakpoint.h b/arch/arm64/include/asm/hw_breakpoint.h index 84055329cd8b..4cad5edf7e56 100644 --- a/arch/arm64/include/asm/hw_breakpoint.h +++ b/arch/arm64/include/asm/hw_breakpoint.h @@ -11,7 +11,17 @@ #include struct arch_hw_breakpoint_ctrl { +#ifdef CONFIG_PLAT_HW_BREAKPOINT + u32 reserved2 : 3, //29~31bit, + mask : 5, //24~28bit, addr mask,mask=0b11111: (mask2^0b11111 the low bit addr), support 8~2G range + reserved1 : 3, //21~23bit, + wt : 1, //20bit, watchpoint type, Unlinked(0)/linked(1) data address match. + lbn : 4, //16~19bit, WT is only required to be set when setting, which is related to link breakpoints + ssc : 2, //14,15bit, Security state control, which controls what state will listen for breakpoint events + hmc : 1, //13bit, Use in conjunction with the above fields +#else u32 __reserved : 19, +#endif len : 8, type : 2, privilege : 2, @@ -32,8 +42,13 @@ struct arch_hw_breakpoint { static inline u32 encode_ctrl_reg(struct arch_hw_breakpoint_ctrl ctrl) { +#ifdef CONFIG_PLAT_HW_BREAKPOINT + u32 val = (ctrl.mask << 24) | (ctrl.len << 5) | (ctrl.type << 3) | + (ctrl.privilege << 1) | ctrl.enabled; +#else u32 val = (ctrl.len << 5) | (ctrl.type << 3) | (ctrl.privilege << 1) | ctrl.enabled; +#endif if (is_kernel_in_hyp_mode() && ctrl.privilege == AARCH64_BREAKPOINT_EL1) val |= DBG_HMC_HYP; @@ -51,6 +66,10 @@ static inline void decode_ctrl_reg(u32 reg, ctrl->type = reg & 0x3; reg >>= 2; ctrl->len = reg & 0xff; +#ifdef CONFIG_PLAT_HW_BREAKPOINT + reg >>= 19; + ctrl->mask = reg & 0x1f; +#endif } /* Breakpoint */ diff --git a/arch/arm64/include/asm/irq.h b/arch/arm64/include/asm/irq.h index fac08e18bcd5..8ba67220aeda 100644 --- a/arch/arm64/include/asm/irq.h +++ b/arch/arm64/include/asm/irq.h @@ -17,5 +17,11 @@ static inline int nr_legacy_irqs(void) return 0; } +#ifdef CONFIG_SMP +extern void arch_trigger_cpumask_backtrace(const cpumask_t *mask, + bool exclude_self); +#define arch_trigger_cpumask_backtrace arch_trigger_cpumask_backtrace +#endif + #endif /* !__ASSEMBLER__ */ #endif diff --git a/arch/arm64/include/asm/ptrace.h b/arch/arm64/include/asm/ptrace.h index 47ec58031f11..8ad1427b813f 100644 --- a/arch/arm64/include/asm/ptrace.h +++ b/arch/arm64/include/asm/ptrace.h @@ -389,5 +389,13 @@ static inline void procedure_link_pointer_set(struct pt_regs *regs, extern unsigned long profile_pc(struct pt_regs *regs); +#ifdef CONFIG_CIX_DST +/* + * Get pt_regs info in handling exception. + * @regs: where to store pt_regs info + */ +extern void plat_get_pt_regs(struct pt_regs *regs); +#endif + #endif /* __ASSEMBLY__ */ #endif diff --git a/arch/arm64/include/asm/smp.h b/arch/arm64/include/asm/smp.h index 9b31e6d0da17..ff2a2053a495 100644 --- a/arch/arm64/include/asm/smp.h +++ b/arch/arm64/include/asm/smp.h @@ -144,6 +144,8 @@ bool cpus_are_stuck_in_kernel(void); extern void crash_smp_send_stop(void); extern bool smp_crash_stop_failed(void); +extern unsigned int g_cpu_in_ipi_stop; + #endif /* ifndef __ASSEMBLY__ */ #endif /* ifndef __ASM_SMP_H */ diff --git a/arch/arm64/include/asm/sysreg.h b/arch/arm64/include/asm/sysreg.h index 38296579a4fd..7c7a7191723b 100644 --- a/arch/arm64/include/asm/sysreg.h +++ b/arch/arm64/include/asm/sysreg.h @@ -356,6 +356,10 @@ #define SYS_MAIR_EL1 sys_reg(3, 0, 10, 2, 0) #define SYS_AMAIR_EL1 sys_reg(3, 0, 10, 3, 0) +#define SYS_MPAMIDR_EL1 sys_reg(3, 0, 10, 4, 4) +#define SYS_MPAM1_EL1 sys_reg(3, 0, 10, 5, 0) +#define SYS_MPAM0_EL1 sys_reg(3, 0, 10, 5, 1) + #define SYS_VBAR_EL1 sys_reg(3, 0, 12, 0, 0) #define SYS_DISR_EL1 sys_reg(3, 0, 12, 1, 1) @@ -519,6 +523,11 @@ #define SYS_RVBAR_EL2 sys_reg(3, 4, 12, 0, 1) #define SYS_RMR_EL2 sys_reg(3, 4, 12, 0, 2) #define SYS_VDISR_EL2 sys_reg(3, 4, 12, 1, 1) + +#define SYS_MPAMHCR_EL2 sys_reg(3, 4, 10, 4, 0) +#define SYS_MPAMVPMV_EL2 sys_reg(3, 4, 10, 4, 1) +#define SYS_MPAM2_EL2 sys_reg(3, 4, 10, 5, 0) + #define __SYS__AP0Rx_EL2(x) sys_reg(3, 4, 12, 8, x) #define SYS_ICH_AP0R0_EL2 __SYS__AP0Rx_EL2(0) #define SYS_ICH_AP0R1_EL2 __SYS__AP0Rx_EL2(1) diff --git a/arch/arm64/kernel/Makefile b/arch/arm64/kernel/Makefile index d95b3d6b471a..e5cf33b1a841 100644 --- a/arch/arm64/kernel/Makefile +++ b/arch/arm64/kernel/Makefile @@ -36,6 +36,7 @@ obj-y := debug-monitors.o entry.o irq.o fpsimd.o \ syscall.o proton-pack.o idreg-override.o idle.o \ patching.o +obj-${CONFIG_ARCH_CIX} += cix_dmi.o obj-$(CONFIG_COMPAT) += sys32.o signal32.o \ sys_compat.o obj-$(CONFIG_COMPAT) += sigreturn32.o diff --git a/arch/arm64/kernel/cix_dmi.c b/arch/arm64/kernel/cix_dmi.c new file mode 100644 index 000000000000..e59f66c77054 --- /dev/null +++ b/arch/arm64/kernel/cix_dmi.c @@ -0,0 +1,54 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#include "cix_dmi.h" + +static char *cpu_name = "Version"; +static bool get_cpu_flag = false; +static void get_cpuname_by_dmi(const struct dmi_header *dm, void *data) +{ + const char *bp; + const u8 *nsp; + char *sm ; + char s; + if(!dm) + return; + if (dm->type != DMI_ENTRY_PROCESSOR) + return; + + bp = ((u8 *) dm) + dm->length; + sm = (char *)dm; + s = sm[0x10]; + + if (s) { + while (--s > 0 && *bp) + bp += strlen(bp) + 1; + + /* Strings containing only spaces are considered empty */ + nsp = bp; + while (*nsp == ' ') + nsp++; + if (*nsp != '\0'){ + cpu_name = dmi_alloc(strlen(bp) + 1); + if (cpu_name != NULL) + strcpy(cpu_name, bp); + + get_cpu_flag = true; + return; + } + } + + return; +} + +char *get_cpu_name(void) +{ + if(!get_cpu_flag) + dmi_walk(get_cpuname_by_dmi, cpu_name); + + if(cpu_name == NULL) { + /* Some BIOS don't support getting CPU name from DMI */ + return "UNKNOWN-CPU"; + } + + return cpu_name; +} + diff --git a/arch/arm64/kernel/cix_dmi.h b/arch/arm64/kernel/cix_dmi.h new file mode 100644 index 000000000000..13ee56a82001 --- /dev/null +++ b/arch/arm64/kernel/cix_dmi.h @@ -0,0 +1,13 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +#ifndef __CIX_DMI_H +#define __CIX_DMI_H +#include +#include + +#ifdef CONFIG_ARCH_CIX +char *get_cpu_name(void); +#else +char *get_cpu_name(void) { return NULL; } +#endif + +#endif /* __CIX_DMI_H */ diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 98fda8500535..15e75b7b1941 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -24,6 +24,7 @@ #include #include #include +#include "cix_dmi.h" /* * In case the boot CPU is hotpluggable, we record its initial state and @@ -193,6 +194,9 @@ static int c_show(struct seq_file *m, void *v) seq_printf(m, "model name\t: ARMv8 Processor rev %d (%s)\n", MIDR_REVISION(midr), COMPAT_ELF_PLATFORM); + else if (get_cpu_name()) + seq_printf(m, "model name\t: %s \n",get_cpu_name()); + seq_printf(m, "BogoMIPS\t: %lu.%02lu\n", loops_per_jiffy / (500000UL/HZ), loops_per_jiffy / (5000UL/HZ) % 100); diff --git a/arch/arm64/kernel/entry.S b/arch/arm64/kernel/entry.S index 7fcbee0f6c0e..d0fd7dc9b39e 100644 --- a/arch/arm64/kernel/entry.S +++ b/arch/arm64/kernel/entry.S @@ -815,6 +815,44 @@ SYM_CODE_END(__bp_harden_el1_vectors) .popsection +#ifdef CONFIG_CIX_DST +SYM_FUNC_START(plat_get_pt_regs) + stp x29, x30, [SP, #-0x30]! + stp x0, x1, [sp, #0x10] + stp x2, x3, [sp, #0x20] + stp x0, x1, [x0] + stp x2, x3, [x0, #0x10]! + stp x4, x5, [x0, #0x10]! + stp x6, x7, [x0, #0x10]! + stp x8, x9, [x0, #0x10]! + stp x10, x11, [x0, #0x10]! + stp x12, x13, [x0, #0x10]! + stp x14, x15, [x0, #0x10]! + stp x16, x17, [x0, #0x10]! + stp x18, x19, [x0, #0x10]! + stp x20, x21, [x0, #0x10]! + stp x22, x23, [x0, #0x10]! + stp x24, x25, [x0, #0x10]! + stp x26, x27, [x0, #0x10]! + stp x28, x29, [x0, #0x10]! + ldr x1, [sp] //get preceding sp + ldr x2, [x1, #0x8] //get preceding lr + str x2, [x0, #0x10]! //set lr + str x1, [x0, #0x8]! //set sp + mrs x1, NZCV //get pstate flag + mrs x2, DAIF + mrs x3, CurrentEL + orr x1, x1, x2 + orr x1, x1, x3 + stp lr, x1, [x0, #0x8]! //set pc,pstate + ldp x2, x3, [sp, #0x20] + ldp x0, x1, [sp, #0x10] + ldp x29,x30,[SP],#0x30 + ret +SYM_FUNC_END(plat_get_pt_regs) +NOKPROBE(plat_get_pt_regs) +#endif + /* * Register switch for AArch64. The callee-saved registers need to be saved * and restored. On entry: diff --git a/arch/arm64/kernel/hibernate.c b/arch/arm64/kernel/hibernate.c index 02870beb271e..633bddc87d64 100644 --- a/arch/arm64/kernel/hibernate.c +++ b/arch/arm64/kernel/hibernate.c @@ -33,6 +33,9 @@ #include #include #include +#ifdef CONFIG_SOC_CIX +#include +#endif /* * Hibernate core relies on this value being 0 on resume, and marks it @@ -341,6 +344,11 @@ int swsusp_arch_suspend(void) /* make the crash dump kernel image visible/saveable */ crash_prepare_suspend(); +#ifdef CONFIG_SOC_CIX + ret = reserve_mem_suspend(); + if (ret) + return ret; +#endif ret = swsusp_mte_save_tags(); if (ret) return ret; @@ -365,6 +373,9 @@ int swsusp_arch_suspend(void) swsusp_mte_restore_tags(); +#ifdef CONFIG_SOC_CIX + reserve_mem_resume(); +#endif /* make the crash dump kernel image protected again */ crash_post_resume(); diff --git a/arch/arm64/kernel/hw_breakpoint.c b/arch/arm64/kernel/hw_breakpoint.c index 35225632d70a..eb2884b91153 100644 --- a/arch/arm64/kernel/hw_breakpoint.c +++ b/arch/arm64/kernel/hw_breakpoint.c @@ -484,6 +484,12 @@ static int arch_build_bp_info(struct perf_event *bp, /* Address */ hw->address = attr->bp_addr; +#ifdef CONFIG_PLAT_HW_BREAKPOINT + if (attr->bp_attr.mask) { + hw->address = attr->bp_attr.start_addr; + hw->ctrl.mask = attr->bp_attr.mask; + } +#endif /* * Privilege @@ -577,7 +583,11 @@ int hw_breakpoint_arch_parse(struct perf_event *bp, * exception level at the register level. * This is used when single-stepping after a breakpoint exception. */ +#ifdef CONFIG_PLAT_HW_BREAKPOINT +void toggle_bp_registers(int reg, enum dbg_active_el el, int enable) +#else static void toggle_bp_registers(int reg, enum dbg_active_el el, int enable) +#endif { int i, max_slots, privilege; u32 ctrl; @@ -651,6 +661,9 @@ static int breakpoint_handler(unsigned long unused, unsigned long esr, goto unlock; counter_arch_bp(bp)->trigger = addr; +#ifdef CONFIG_PLAT_HW_BREAKPOINT + bp->attr.bp_attr.access_type = HW_BREAKPOINT_X; +#endif perf_bp_event(bp, regs); /* Do we need to handle the stepping? */ @@ -797,12 +810,19 @@ static int watchpoint_handler(unsigned long addr, unsigned long esr, if (dist != 0) continue; +#ifdef CONFIG_PLAT_HW_BREAKPOINT + wp->attr.bp_attr.access_type = access; +#endif step = watchpoint_report(wp, addr, regs); } /* No exact match found? */ - if (min_dist > 0 && min_dist != -1) + if (min_dist > 0 && min_dist != -1) { +#ifdef CONFIG_PLAT_HW_BREAKPOINT + slots[closest_match]->attr.bp_attr.access_type = access; +#endif step = watchpoint_report(slots[closest_match], addr, regs); + } rcu_read_unlock(); diff --git a/arch/arm64/kernel/process.c b/arch/arm64/kernel/process.c index 385fb78845d6..816f140a23fe 100644 --- a/arch/arm64/kernel/process.c +++ b/arch/arm64/kernel/process.c @@ -56,6 +56,10 @@ #include #include +#ifdef CONFIG_MPAM_POLICY +#include +#endif + #if defined(CONFIG_STACKPROTECTOR) && !defined(CONFIG_STACKPROTECTOR_PER_TASK) #include unsigned long __stack_chk_guard __ro_after_init; @@ -197,10 +201,70 @@ static void print_pstate(struct pt_regs *regs) } } +/* + * dump a block of kernel memory from around the given address + */ +static void show_data(unsigned long addr, int nbytes, const char *name) +{ + int i, j; + int nlines; + u32 *p; + + /* + * don't attempt to dump non-kernel addresses or + * values that are probably just small negative numbers + */ + if (addr < PAGE_OFFSET || addr > -256UL) + return; + + printk("\n%s: %#lx:\n", name, addr + (int)(nbytes * 0.5)); + + /* + * round address down to a 32 bit boundary + * and always dump a multiple of 32 bytes + */ + p = (u32 *)(addr & ~(sizeof(u32) - 1)); + nbytes += (addr & (sizeof(u32) - 1)); + nlines = (nbytes + 31) / 32; + + for (i = 0; i < nlines; i++) { + /* + * just display low 16 bits of address to keep + * each line of the dump < 80 characters + */ + printk("%04lx ", (unsigned long)p & 0xffff); + for (j = 0; j < 8; j++) { + u32 data; + if (copy_from_kernel_nofault(&data, p, sizeof(data))) { + pr_cont(" ********"); + } else { + pr_cont(" %08x", data); + } + ++p; + } + pr_cont("\n"); + } +} + +static void show_extra_register_data(struct pt_regs *regs, int nbytes) +{ + unsigned int i; + + show_data(regs->pc - nbytes, nbytes * 2, "PC"); + show_data(regs->regs[30] - nbytes, nbytes * 2, "LR"); + show_data(regs->sp - nbytes, nbytes * 2, "SP"); + for (i = 0; i < 30; i++) { + char name[4]; + snprintf(name, sizeof(name), "X%u", i); + show_data(regs->regs[i] - nbytes, nbytes * 2, name); + } +} + void __show_regs(struct pt_regs *regs) { int i, top_reg; u64 lr, sp; + unsigned int mask = 0x1 << get_cpu(); if (compat_user_mode(regs)) { lr = regs->compat_lr; @@ -238,6 +302,13 @@ void __show_regs(struct pt_regs *regs) pr_cont("\n"); } + + if (!user_mode(regs)) { + if (!(g_cpu_in_ipi_stop & mask)) { + show_extra_register_data(regs, 128); + } + } + put_cpu(); } void show_regs(struct pt_regs *regs) @@ -552,6 +623,10 @@ struct task_struct *__switch_to(struct task_struct *prev, if (prev->thread.sctlr_user != next->thread.sctlr_user) update_sctlr_el1(next->thread.sctlr_user); +#ifdef CONFIG_MPAM_POLICY + mpam_sync_task(next); +#endif + /* the actual thread switch */ last = cpu_switch_to(prev, next); diff --git a/arch/arm64/kernel/proton-pack.c b/arch/arm64/kernel/proton-pack.c index ecfbff6991bb..edc4c727783d 100644 --- a/arch/arm64/kernel/proton-pack.c +++ b/arch/arm64/kernel/proton-pack.c @@ -879,10 +879,12 @@ static u8 spectre_bhb_loop_affected(void) static const struct midr_range spectre_bhb_k132_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_X3), MIDR_ALL_VERSIONS(MIDR_NEOVERSE_V2), + {}, }; static const struct midr_range spectre_bhb_k38_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A715), MIDR_ALL_VERSIONS(MIDR_CORTEX_A720), + {}, }; static const struct midr_range spectre_bhb_k32_list[] = { MIDR_ALL_VERSIONS(MIDR_CORTEX_A78), diff --git a/arch/arm64/kernel/smp.c b/arch/arm64/kernel/smp.c index 14365ef84244..853999f8ecbc 100644 --- a/arch/arm64/kernel/smp.c +++ b/arch/arm64/kernel/smp.c @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -73,6 +74,7 @@ enum ipi_msg_type { IPI_TIMER, IPI_IRQ_WORK, IPI_WAKEUP, + IPI_CPU_BACKTRACE, NR_IPI }; @@ -767,6 +769,7 @@ static const char *ipi_types[NR_IPI] __tracepoint_string = { [IPI_TIMER] = "Timer broadcast interrupts", [IPI_IRQ_WORK] = "IRQ work interrupts", [IPI_WAKEUP] = "CPU wake-up interrupts", + [IPI_CPU_BACKTRACE] = "Backtrace interrupts", }; static void smp_cross_call(const struct cpumask *target, unsigned int ipinr); @@ -813,8 +816,19 @@ void arch_irq_work_raise(void) } #endif +/* + * Don't need to call show_extra_register_data when cpu handling IPI_STOP. + * Declared in + */ +unsigned int g_cpu_in_ipi_stop; static void __noreturn local_cpu_stop(void) { + unsigned int mask; + + mask = 0x1 << get_cpu(); + g_cpu_in_ipi_stop |= mask; + put_cpu(); + set_cpu_online(smp_processor_id(), false); local_daif_mask(); @@ -906,7 +920,11 @@ static void do_handle_IPI(int ipinr) cpu); break; #endif - + case IPI_CPU_BACKTRACE: + printk_deferred_enter(); + nmi_cpu_backtrace(get_irq_regs()); + printk_deferred_exit(); + break; default: pr_crit("CPU%u: Unknown IPI message 0x%x\n", cpu, ipinr); break; @@ -1096,3 +1114,13 @@ bool cpus_are_stuck_in_kernel(void) return !!cpus_stuck_in_kernel || smp_spin_tables || is_protected_kvm_enabled(); } + +static void raise_nmi(cpumask_t *mask) +{ + smp_cross_call(mask, IPI_CPU_BACKTRACE); +} + +void arch_trigger_cpumask_backtrace(const cpumask_t *mask, bool exclude_self) +{ + nmi_trigger_cpumask_backtrace(mask, exclude_self, raise_nmi); +} diff --git a/arch/arm64/kernel/syscall.c b/arch/arm64/kernel/syscall.c index f090e39f69bc..38dac68465b1 100644 --- a/arch/arm64/kernel/syscall.c +++ b/arch/arm64/kernel/syscall.c @@ -14,6 +14,9 @@ #include #include #include +#ifdef CONFIG_PLAT_AP_HOOK +#include +#endif long compat_arm_syscall(struct pt_regs *regs, int scno); long sys_ni_syscall(void); @@ -131,7 +134,13 @@ static void el0_svc_common(struct pt_regs *regs, int scno, int sc_nr, goto trace_exit; } +#ifdef CONFIG_PLAT_AP_HOOK + syscalls_hook(scno, 0); +#endif invoke_syscall(regs, scno, sc_nr, syscall_table); +#ifdef CONFIG_PLAT_AP_HOOK + syscalls_hook(scno, 1); +#endif /* * The tracing status may have changed under our feet, so we have to diff --git a/arch/arm64/kernel/traps.c b/arch/arm64/kernel/traps.c index 8b70759cdbb9..1f40771305bc 100644 --- a/arch/arm64/kernel/traps.c +++ b/arch/arm64/kernel/traps.c @@ -48,6 +48,15 @@ #include #include #include +#ifdef CONFIG_PLAT_AP_HOOK +#include +#endif +#ifdef CONFIG_PLAT_SKY1_AUDIO_TIMEOUT +#include +#endif +#ifdef CONFIG_PLAT_SKY1_RCSU_GASKET_ERROR +#include +#endif static bool __kprobes __check_eq(unsigned long pstate) { @@ -205,6 +214,10 @@ static int __die(const char *str, long err, struct pt_regs *regs) static DEFINE_RAW_SPINLOCK(die_lock); +#ifdef CONFIG_PLAT_KERNELDUMP +extern void plat_set_cpu_regs(int coreid, struct pt_regs* reg); +#endif + /* * This function is protected against re-entrancy. */ @@ -219,6 +232,11 @@ void die(const char *str, struct pt_regs *regs, long err) console_verbose(); bust_spinlocks(1); + +#ifdef CONFIG_PLAT_KERNELDUMP + plat_set_cpu_regs(raw_smp_processor_id(), regs); +#endif + ret = __die(str, err, regs); if (regs && kexec_should_crash(current)) @@ -953,12 +971,26 @@ void __noreturn panic_bad_stack(struct pt_regs *regs, unsigned long esr, unsigne void __noreturn arm64_serror_panic(struct pt_regs *regs, unsigned long esr) { + unsigned long far; console_verbose(); + far = read_sysreg(far_el1); + pr_crit("SError Interrupt on CPU%d, code 0x%016lx -- %s\n", smp_processor_id(), esr, esr_get_class_string(esr)); - if (regs) + if (regs) { __show_regs(regs); +#ifdef CONFIG_PLAT_KERNELDUMP + plat_set_cpu_regs(raw_smp_processor_id(), regs); +#endif + } + +#ifdef CONFIG_PLAT_SKY1_AUDIO_TIMEOUT + sky1_check_audio_timeout_error(far, regs); +#endif +#ifdef CONFIG_PLAT_SKY1_RCSU_GASKET_ERROR + sky1_check_rcsu_gasket_error(); +#endif nmi_panic(regs, "Asynchronous SError Interrupt"); diff --git a/arch/arm64/mm/fault.c b/arch/arm64/mm/fault.c index 2e5d1e238af9..f6ea55f938f0 100644 --- a/arch/arm64/mm/fault.c +++ b/arch/arm64/mm/fault.c @@ -42,6 +42,12 @@ #include #include #include +#ifdef CONFIG_PLAT_SKY1_AUDIO_TIMEOUT +#include +#endif +#ifdef CONFIG_PLAT_SKY1_RCSU_GASKET_ERROR +#include +#endif struct fault_info { int (*fn)(unsigned long far, unsigned long esr, @@ -127,6 +133,7 @@ static inline unsigned long mm_to_pgd_phys(struct mm_struct *mm) return (unsigned long)virt_to_phys(mm->pgd); } +#ifdef CONFIG_MMU /* * Dump out the page tables associated with 'addr' in the currently active mm. */ @@ -198,7 +205,10 @@ static void show_pte(unsigned long addr) pr_cont("\n"); } - +#else /* CONFIG_MMU */ +void show_pte(unsigned long addr) +{ } +#endif /* CONFIG_MMU */ /* * This function sets the access flags (dirty, accessed), as well as write * permission, and only to a more permissive setting. @@ -753,6 +763,14 @@ static int do_sea(unsigned long far, unsigned long esr, struct pt_regs *regs) */ siaddr = untagged_addr(far); } + +#ifdef CONFIG_PLAT_SKY1_AUDIO_TIMEOUT + sky1_check_audio_timeout_error(far, regs); +#endif +#ifdef CONFIG_PLAT_SKY1_RCSU_GASKET_ERROR + sky1_check_rcsu_gasket_error(); +#endif + arm64_notify_die(inf->name, regs, inf->sig, inf->code, siaddr, esr); return 0; diff --git a/arch/arm64/mm/init.c b/arch/arm64/mm/init.c index 8a0f8604348b..572469beb5b9 100644 --- a/arch/arm64/mm/init.c +++ b/arch/arm64/mm/init.c @@ -46,6 +46,10 @@ #include #include +#ifdef CONFIG_PLAT_KERNELDUMP +void __init kernel_dump_mem_reserve(void); +#endif + /* * We need to be able to catch inadvertent references to memstart_addr * that occur (potentially in generic code) before arm64_memblock_init() @@ -353,6 +357,10 @@ void __init arm64_memblock_init(void) memblock_remove(0, memstart_addr); } +#ifdef CONFIG_PLAT_KERNELDUMP + kernel_dump_mem_reserve(); +#endif + /* * If we are running with a 52-bit kernel VA config on a system that * does not support it, we have to place the available physical diff --git a/drivers/Makefile b/drivers/Makefile index 1bec7819a837..72f1fa863bae 100644 --- a/drivers/Makefile +++ b/drivers/Makefile @@ -199,3 +199,6 @@ obj-$(CONFIG_DRM_ACCEL) += accel/ obj-$(CONFIG_CDX_BUS) += cdx/ obj-$(CONFIG_S390) += s390/ + +# Arm ISP Driver +obj-$(CONFIG_MOST) += most/ diff --git a/drivers/acpi/Kconfig b/drivers/acpi/Kconfig index cee82b473dc5..72963e7e54ac 100644 --- a/drivers/acpi/Kconfig +++ b/drivers/acpi/Kconfig @@ -232,6 +232,13 @@ config ACPI_FAN To compile this driver as a module, choose M here: the module will be called fan. +config CIX_ACPI_POWER_DOMAIN + bool "CIX Power Domain Management API for acpi" + depends on ARCH_CIX + help + This enables the power domain API for CIX Technologies,Inc. + Say Y if you want to supprot ACPI power domain. + config ACPI_TAD tristate "ACPI Time and Alarm (TAD) Device Support" depends on SYSFS && PM_SLEEP diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile index eaa09bf52f17..8e536a46f0b2 100644 --- a/drivers/acpi/Makefile +++ b/drivers/acpi/Makefile @@ -29,7 +29,7 @@ acpi-y += nvs.o # Power management related files acpi-y += wakeup.o acpi-$(CONFIG_ACPI_SYSTEM_POWER_STATES_SUPPORT) += sleep.o -acpi-y += device_sysfs.o device_pm.o +acpi-y += device_sysfs.o device_pm.o device_perf.o acpi-$(CONFIG_ACPI_SLEEP) += proc.o @@ -73,6 +73,7 @@ acpi-$(CONFIG_ACPI_FFH) += acpi_ffh.o acpi-$(CONFIG_ACPI_ADXL) += acpi_adxl.o # These are (potentially) separate modules +obj-$(CONFIG_CIX_ACPI_POWER_DOMAIN) += cix_acpi_pd.o # IPMI may be used by other drivers, so it has to initialise before them obj-$(CONFIG_ACPI_IPMI) += acpi_ipmi.o diff --git a/drivers/acpi/acpi_platform.c b/drivers/acpi/acpi_platform.c index 48d15dd785f6..7ed7e8df0c96 100644 --- a/drivers/acpi/acpi_platform.c +++ b/drivers/acpi/acpi_platform.c @@ -22,6 +22,7 @@ /* Exclude devices that have no _CRS resources provided */ #define ACPI_ALLOW_WO_RESOURCES BIT(0) +#define MAX_ACPI_FIBIDDEN_ID_LIST 16 static const struct acpi_device_id forbidden_id_list[] = { {"ACPI0009", 0}, /* IOxAPIC */ @@ -33,6 +34,23 @@ static const struct acpi_device_id forbidden_id_list[] = { { } }; +struct acpi_forbidden_ext { + int len; + struct acpi_device_id *id_list[MAX_ACPI_FIBIDDEN_ID_LIST]; +} acpi_forbidden_ext; + +/* Here just concern one case the early phase to register forbidden ids. */ +int forbidden_ids_register(struct acpi_device_id *ids) { + if (ids && acpi_forbidden_ext.len < MAX_ACPI_FIBIDDEN_ID_LIST) { + acpi_forbidden_ext.id_list[acpi_forbidden_ext.len] = ids; + acpi_forbidden_ext.len++; + } else { + return -EINVAL; + } + return 0; +} +EXPORT_SYMBOL_GPL(forbidden_ids_register); + static struct platform_device *acpi_platform_device_find_by_companion(struct acpi_device *adev) { struct device *dev; @@ -124,6 +142,14 @@ struct platform_device *acpi_create_platform_device(struct acpi_device *adev, return NULL; match = acpi_match_acpi_device(forbidden_id_list, adev); + if (!match) { + for (int i = 0; i < acpi_forbidden_ext.len; i++) { + match = acpi_match_acpi_device(acpi_forbidden_ext.id_list[i], adev); + if (match) { + break; + } + } + } if (match) { if (match->driver_data & ACPI_ALLOW_WO_RESOURCES) { bool has_resources = false; diff --git a/drivers/acpi/cix_acpi_pd.c b/drivers/acpi/cix_acpi_pd.c new file mode 100644 index 000000000000..d769ba6c127f --- /dev/null +++ b/drivers/acpi/cix_acpi_pd.c @@ -0,0 +1,144 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + * + **/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define GET_POWER_STATE 0x00000001 +#define SET_POWER_STATE 0X00000002 + +#define POWER_REVISION_ID 1 +#define PD_MASK (0xffffffff) +#define SUCCESS 0 + +static const guid_t cix_pd_guid = + GUID_INIT(0x854bcf86, 0x4dbf, 0x4f3d, 0xa1, 0x9a, 0xfb, 0xef, 0x3c, 0x7c, 0xe7, 0x31); + +static int acpi_pd_config_set(struct device *dev, u32 pd_id, u32 state) +{ + acpi_handle handle = ACPI_HANDLE(dev); + union acpi_object *out_obj,in_obj; + u32 *buf_val; + int ret = 0; + union acpi_object args[2] = { + { .type = ACPI_TYPE_INTEGER, }, + { .type = ACPI_TYPE_INTEGER, }, + }; + + args[0].integer.value = pd_id; + args[1].integer.value = state; + + in_obj.type = ACPI_TYPE_PACKAGE; + in_obj.package.count = 2; + in_obj.package.elements = args; + out_obj = acpi_evaluate_dsm_typed(handle, &cix_pd_guid, + POWER_REVISION_ID, SET_POWER_STATE, + &in_obj, ACPI_TYPE_BUFFER); + if (!out_obj) { + ret = -EINVAL; + dev_err(dev, "Failed to evaluate DSM object,err:%d!\n", ret); + return ret; + } + + if (out_obj->buffer.type == ACPI_TYPE_BUFFER) { + buf_val = (u32 *)out_obj->buffer.pointer; + } else { + ret = AE_ERROR; + goto free_acpi_buffer; + } + + if(buf_val[0] != SUCCESS) { + ret = AE_NOT_FOUND; + dev_err(dev, "ACPI return err:%d,buf_val:%d\n", ret, buf_val[0]); + goto free_acpi_buffer; + } + +free_acpi_buffer: + ACPI_FREE(out_obj); + return ret; +} + +static int acpi_get_pd_state(struct device *dev, u32 pd_id) +{ + acpi_handle handle = ACPI_HANDLE(dev); + union acpi_object *out_obj, in_obj; + u64 ret; + u32 *buf_val; + union acpi_object args[1] = { + { .type = ACPI_TYPE_INTEGER, }, + }; + + args[0].integer.value = pd_id; + in_obj.type = ACPI_TYPE_PACKAGE; + in_obj.package.count = 1; + in_obj.package.elements = args; + + out_obj = acpi_evaluate_dsm_typed(handle, &cix_pd_guid, + POWER_REVISION_ID, GET_POWER_STATE, + &in_obj, ACPI_TYPE_BUFFER); + if (!out_obj) { + ret = -EINVAL; + dev_err(dev, "Failed to evaluate DSM object,err!\n"); + return ret; + } + + if (out_obj->buffer.type == ACPI_TYPE_BUFFER) { + buf_val = (u32 *) out_obj->buffer.pointer; + } else { + ret = AE_ERROR; + goto free_acpi_buffer; + } + + if(buf_val[0] == SUCCESS) + ret = buf_val[1] & PD_MASK; + +free_acpi_buffer: + ACPI_FREE(out_obj); + return ret; +} + +static int acpi_pd_power(struct device *dev, u32 pd_id, bool power_on) +{ + u32 ret_state, state; + int ret; + + if (power_on) + state = ACPI_PD_ON; + else + state = ACPI_PD_OFF; + + ret = acpi_pd_config_set(dev, pd_id, state); + + if (!ret) + ret_state = acpi_get_pd_state(dev, pd_id); + if (state != ret_state) + return -EIO; + return ret; +} + +int acpi_pd_off(struct device *dev, u32 pd_id) +{ + return acpi_pd_power(dev, pd_id, false); +} +EXPORT_SYMBOL_GPL(acpi_pd_off); + +int acpi_pd_on(struct device *dev, u32 pd_id) +{ + return acpi_pd_power(dev, pd_id, true); +} +EXPORT_SYMBOL_GPL(acpi_pd_on); diff --git a/drivers/acpi/cppc_acpi.c b/drivers/acpi/cppc_acpi.c index ed02a2a9970a..bce112b83b76 100644 --- a/drivers/acpi/cppc_acpi.c +++ b/drivers/acpi/cppc_acpi.c @@ -509,6 +509,7 @@ int acpi_get_psd_map(unsigned int cpu, struct cppc_cpudata *cpu_data) else if (pdomain->coord_type == DOMAIN_COORD_TYPE_SW_ANY) cpu_data->shared_type = CPUFREQ_SHARED_TYPE_ANY; + cpu_data->perf_domain = pdomain->domain; for_each_possible_cpu(i) { if (i == cpu) continue; diff --git a/drivers/acpi/device_perf.c b/drivers/acpi/device_perf.c new file mode 100644 index 000000000000..cb4c29803bb4 --- /dev/null +++ b/drivers/acpi/device_perf.c @@ -0,0 +1,544 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2023 Linaro + */ + +#include +#include +#include +#include +#include + +struct dpc_reg { + u8 descriptor; + u16 length; + u8 space_id; + u8 bit_width; + u8 bit_offset; + u8 access_width; + u64 address; +} __packed; + +struct dpc_register_resource { + acpi_object_type type; + void __iomem *sys_mem_vaddr; + union { + struct dpc_reg reg; + u64 int_value; + } buffer; +}; + +struct acpi_dev_perf_level { + u64 level; /* abstract unit */ + u64 power; /* milli Watts */ + u64 latency; /* micro Seconds */ +}; + +enum dpc_regs { + NOMINAL_PERF, + NOMINAL_FREQ, + DESIRED_PERF, + DELIVERED_PERF, + SUSTAINED_PERF, + POWER_DOMAIN_INDEX, + MAX_DPC_REGS +}; + +struct acpi_dpc_ctxt { + u64 num_entries; + u64 revision; + unsigned int num_perf_levels; + struct acpi_dev_perf_level *perf_levels; + struct dpc_register_resource regs[MAX_DPC_REGS]; +}; + +struct acpi_dev_pd_ctxt { + u64 perf_level; /* Aggreegrate performance level */ + u64 domain_id; /* Index for the domain */ + struct list_head + ctrl_list; /* List of acpi_dev_pstates_ctrl in this domain */ + struct list_head list; /* List of acpi_dev_pd_ctxt */ +}; + +struct acpi_dev_pstates_ctrl { + struct device *dev; + struct acpi_dpc_ctxt dpc; + u64 nominal_freq; + u64 nominal_perf; + u64 sustained_perf; + u64 perf_to_freq_factor; + struct list_head list; /* List of acpi_dev_pstates_ctrl */ + struct list_head + list_domain; /* List of acpi_dev_pstates_ctrl in same performance domain */ + u64 perf_level; + struct acpi_dev_pd_ctxt *domain; +}; + +/* Evaluates to True if reg is a NULL register descriptor */ +#define IS_NULL_REG(reg) ((reg)->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY && \ + (reg)->address == 0 && \ + (reg)->bit_width == 0 && \ + (reg)->bit_offset == 0 && \ + (reg)->access_width == 0) + +static LIST_HEAD(dev_perf_ctrl_list); +static DEFINE_MUTEX(dev_perf_ctrl_list_mutex); + +static LIST_HEAD(dev_perf_domain_list); +static DEFINE_MUTEX(dev_perf_domain_list_mutex); + +static struct acpi_dev_pd_ctxt *find_perf_domain_ctxt(unsigned int domain_id) +{ + struct acpi_dev_pd_ctxt *ctxt; + + mutex_lock(&dev_perf_domain_list_mutex); + + list_for_each_entry(ctxt, &dev_perf_domain_list, list) { + if (ctxt->domain_id == domain_id) { + mutex_unlock(&dev_perf_domain_list_mutex); + return ctxt; + } + } + + mutex_unlock(&dev_perf_domain_list_mutex); + + /* No perf ctxt found yet, allocate a new one */ + ctxt = kzalloc(sizeof(struct acpi_dev_pd_ctxt), GFP_KERNEL); + + /* Initialize */ + INIT_LIST_HEAD(&ctxt->list); + INIT_LIST_HEAD(&ctxt->ctrl_list); + + ctxt->domain_id = domain_id; + ctxt->perf_level = 0; + + /* Add to perf domain ctxt list */ + mutex_lock(&dev_perf_domain_list_mutex); + list_add_tail(&ctxt->list, &dev_perf_domain_list); + mutex_unlock(&dev_perf_domain_list_mutex); + + return ctxt; +} + +static struct acpi_dev_pstates_ctrl *find_perf_ctrl_desc(struct device *dev) +{ + struct acpi_dev_pstates_ctrl *ctrl; + + mutex_lock(&dev_perf_ctrl_list_mutex); + + list_for_each_entry(ctrl, &dev_perf_ctrl_list, list) { + if (!strcmp(dev_name(dev), dev_name(ctrl->dev))) { + /* Matched on device name */ + mutex_unlock(&dev_perf_ctrl_list_mutex); + return ctrl; + } + } + + mutex_unlock(&dev_perf_ctrl_list_mutex); + + return NULL; +} + +// TODO: refactor arm64 ffh implementation into a seperate file +static int dpc_ffh_read(struct dpc_reg *reg, u64 *val) +{ + struct arm_smccc_res res; + + // ARM64 FFH Spec. for DPC - if top 32 bits are set, it is an SMC call + if (reg->address >> 32 & 0xffffffff) { + arm_smccc_smc(reg->address & 0xffffffff, 0, 0, 0, 0, 0, 0, 0, + &res); + *val = res.a0; + return 0; + } + + return -EFAULT; +} + +static int dpc_ffh_write(struct dpc_reg *reg, u64 val) +{ + struct arm_smccc_res res; + + // ARM64 FFH Spec. for DPC - if top 32 bits are set, it is an SMC call + if (reg->address >> 32 & 0xffffffff) { + arm_smccc_smc(reg->address & 0xffffffff, val, 0, 0, 0, 0, 0, 0, + &res); + return 0; + } + + return -EFAULT; +} + +static int dpc_read(struct dpc_register_resource *reg_res, u64 *val) +{ + void __iomem *vaddr = NULL; + struct dpc_reg *reg = ®_res->buffer.reg; + int ret = 0; + + if (reg_res->type == ACPI_TYPE_INTEGER) { + *val = reg_res->buffer.int_value; + return 0; + } + + *val = 0; + + if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) + return dpc_ffh_read(reg, val); + else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + vaddr = reg_res->sys_mem_vaddr; + else { + pr_debug("DPC Register resource type (%d) not yet supported \n", + reg_res->type); + return -ENODEV; + } + + switch (reg->bit_width) { + case 8: + *val = readb_relaxed(vaddr); + break; + case 16: + *val = readw_relaxed(vaddr); + break; + case 32: + *val = readl_relaxed(vaddr); + break; + case 64: + *val = readq_relaxed(vaddr); + break; + default: + pr_debug("Error: Cannot write %u bit width to DPC\n", + reg->bit_width); + ret = -EFAULT; + break; + } + + return ret; +} + +static int dpc_write(struct dpc_register_resource *reg_res, u64 val) +{ + void __iomem *vaddr = NULL; + struct dpc_reg *reg = ®_res->buffer.reg; + int ret = 0; + + if (reg->space_id == ACPI_ADR_SPACE_FIXED_HARDWARE) + return dpc_ffh_write(reg, val); + else if (reg->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) + vaddr = reg_res->sys_mem_vaddr; + else { + pr_debug("DPC Register resource type (%d) not yet supported \n", + reg_res->type); + return -ENODEV; + } + + switch (reg->bit_width) { + case 8: + writeb_relaxed(val, vaddr); + break; + case 16: + writew_relaxed(val, vaddr); + break; + case 32: + writel_relaxed(val, vaddr); + break; + case 64: + writeq_relaxed(val, vaddr); + break; + default: + pr_debug("Error: Cannot write %u bit width to DPC\n", + reg->bit_width); + ret = -EFAULT; + break; + } + + return ret; +} + +// Derive delivered performance rate for device from delivered performance state +u64 acpi_dev_perf_current_rate(struct device *dev) +{ + struct acpi_dev_pstates_ctrl *ctrl; + u64 perf_level; + int ret; + + ctrl = find_perf_ctrl_desc(dev); + + ret = dpc_read(&ctrl->dpc.regs[DELIVERED_PERF], &perf_level); + if (ret < 0) + return 0; + + return perf_level * ctrl->perf_to_freq_factor; +} + +int acpi_dev_perf_set_state(struct device *dev, unsigned long target_rate) +{ + struct acpi_dev_pstates_ctrl *ctrl; + unsigned int state; + int ret; + + ctrl = find_perf_ctrl_desc(dev); + if (ctrl == NULL) { + pr_debug("Failed to find perf control for device %s \n", + dev_name(dev)); + return -ENODEV; + } + + /* Convert freq rate to state */ + state = target_rate / ctrl->perf_to_freq_factor; + + /* we can't go higher than guaranteed perf */ + if (state > ctrl->sustained_perf) + state = ctrl->sustained_perf; + + if (state == ctrl->domain->perf_level) + return 0; + + ret = dpc_write(&(ctrl->dpc.regs[DESIRED_PERF]), state); + + ctrl->domain->perf_level = state; + ctrl->perf_level = state; + + return ret; +} + +static int acpi_xtract_performance_levels(struct device *dev, + unsigned int *num_levels, + struct acpi_dev_perf_level **levels) +{ + unsigned int ret = 0; + int i; + acpi_status status; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + struct acpi_buffer state = { 0, NULL }; + struct acpi_buffer format = { sizeof("NNN"), "NNN" }; + union acpi_object *dps = NULL; + + status = acpi_evaluate_object_typed(ACPI_HANDLE(dev), "_DPS", NULL, + &buffer, ACPI_TYPE_PACKAGE); + + if (ACPI_FAILURE(status)) + return -ENODEV; + + dps = buffer.pointer; + + *levels = devm_kzalloc( + dev, dps->package.count * sizeof(struct acpi_dev_perf_level), + GFP_KERNEL); + + state.length = sizeof(struct acpi_dev_perf_level); + + for (i = 0; i < dps->package.count; i++) { + state.pointer = &(*levels)[i]; + + status = acpi_extract_package(&(dps->package.elements[i]), + &format, &state); + + if (ACPI_FAILURE(status)) { + ret = -EFAULT; + kfree(*levels); + goto out; + } + } + + *num_levels = dps->package.count; + +out: + kfree(buffer.pointer); + return ret; +} + +static int acpi_parse_dpc_resource(union acpi_object *obj, + struct dpc_register_resource *reg) +{ + struct dpc_reg *gas_t; + + switch (obj->type) { + case ACPI_TYPE_INTEGER: + reg->type = ACPI_TYPE_INTEGER; + reg->buffer.int_value = obj->integer.value; + return 0; + case ACPI_TYPE_BUFFER: + reg->type = ACPI_TYPE_BUFFER; + memcpy(®->buffer.reg, obj->buffer.pointer, + sizeof(struct dpc_reg)); + gas_t = ®->buffer.reg; + + if (gas_t->space_id == ACPI_ADR_SPACE_SYSTEM_MEMORY) { + if (gas_t->address) { + void __iomem *addr; + + addr = ioremap(gas_t->address, gas_t->bit_width/8); + if (!addr) + return -EINVAL; + reg->sys_mem_vaddr = addr; + } + } + + return 0; + default: + return -EINVAL; + } +} + +int acpi_dev_perf_attach(struct device *dev) +{ + struct acpi_dev_pstates_ctrl *ctrl; + acpi_handle handle = ACPI_HANDLE(dev); + struct acpi_buffer output = { ACPI_ALLOCATE_BUFFER, NULL }; + struct dpc_register_resource *nominal_reg, *sustained_reg, + *domain_index_reg, *nom_freq_reg = NULL; + union acpi_object *out_obj, *dpc_obj; + unsigned int i, num_ent; + acpi_status status; + int ret = -ENODATA, res_index = 0; + u64 domain_index = 0; + + if (!acpi_has_method(handle, "_DPC") || !acpi_has_method(handle, "_DPS")) + return 0; + + /* Parse ACPI _DPC object for this device. */ + status = acpi_evaluate_object_typed(handle, "_DPC", NULL, &output, + ACPI_TYPE_PACKAGE); + + if (ACPI_FAILURE(status)) { + ret = -ENODEV; + goto out_buf_free; + } + + ctrl = devm_kzalloc(dev, sizeof(struct acpi_dev_pstates_ctrl), + GFP_KERNEL); + + /* Initialize */ + ctrl->dev = dev; + ctrl->domain = NULL; + INIT_LIST_HEAD(&ctrl->list_domain); + INIT_LIST_HEAD(&ctrl->list); + + out_obj = (union acpi_object *)output.pointer; + + /* First entry is NumEntries. */ + dpc_obj = &out_obj->package.elements[res_index++]; + if (dpc_obj->type == ACPI_TYPE_INTEGER) { + num_ent = dpc_obj->integer.value; + if (num_ent <= 1) { + pr_debug( + "Unexpected _DPC NumEntries value (%d) for device:%s\n", + num_ent, dev_name(dev)); + goto out_free; + } + ctrl->dpc.num_entries = num_ent; + } else { + pr_debug( + "Unexpected _DPC NumEntries entry type (%d) for device:%s\n", + dpc_obj->type, dev_name(dev)); + goto out_free; + } + + /* Second entry should be revision. */ + dpc_obj = &out_obj->package.elements[res_index++]; + if (dpc_obj->type == ACPI_TYPE_INTEGER) { + ctrl->dpc.revision = dpc_obj->integer.value; + } else { + pr_debug( + "Unexpected _DPC Revision entry type (%d) for Device:%s\n", + dpc_obj->type, dev_name(dev)); + goto out_free; + } + + ret = acpi_xtract_performance_levels(dev, &ctrl->dpc.num_perf_levels, + &ctrl->dpc.perf_levels); + if (ret < 0) + goto out_free; + + /* Iterate over rest of the resources from _DPC */ + for (i = 0; res_index < num_ent; i++, res_index++) { + ret = acpi_parse_dpc_resource( + &out_obj->package.elements[res_index], + &ctrl->dpc.regs[i]); + if (ret < 0) + goto out_free; + } + + /* Initialize the remaining dpc register as unsupported. */ + for (; i < MAX_DPC_REGS; i++) { + ctrl->dpc.regs[i].type = ACPI_TYPE_INTEGER; + ctrl->dpc.regs[i].buffer.int_value = 0; + } + + nominal_reg = &ctrl->dpc.regs[NOMINAL_PERF]; + sustained_reg = &ctrl->dpc.regs[SUSTAINED_PERF]; + domain_index_reg = &ctrl->dpc.regs[POWER_DOMAIN_INDEX]; + nom_freq_reg = &ctrl->dpc.regs[NOMINAL_FREQ]; + + ret = dpc_read(domain_index_reg, &domain_index); + if (ret < 0) + goto out_free; + + if (domain_index > 0) { + ctrl->domain = find_perf_domain_ctxt(domain_index); + if (ctrl->domain == NULL) { + pr_debug( + "Cannot locate performance domain index (%lld) for device %s\n", + domain_index, dev_name(dev)); + goto out_free; + } + + /* Add perf ctrl object to performance domain descriptor */ + mutex_lock(&dev_perf_domain_list_mutex); + list_add_tail(&ctrl->list_domain, &ctrl->domain->ctrl_list); + mutex_unlock(&dev_perf_domain_list_mutex); + } + + ret = dpc_read(nom_freq_reg, &ctrl->nominal_freq); + if (ret < 0) + goto out_free; + + ret = dpc_read(nominal_reg, &ctrl->nominal_perf); + if (ret < 0) + goto out_free; + + if (nom_freq_reg->type != ACPI_TYPE_BUFFER || + IS_NULL_REG(&nom_freq_reg->buffer.reg)) { + ctrl->sustained_perf = ctrl->nominal_perf; + } else { + ret = dpc_read(sustained_reg, &ctrl->sustained_perf); + if (ret < 0) + goto out_free; + } + + /* Multiplication factor for converting performance level to frequency */ + ctrl->perf_to_freq_factor = + (ctrl->nominal_freq * 1000) / ctrl->nominal_perf; + + /* Add device OPPs */ + for (i = 0; i < ctrl->dpc.num_perf_levels; i++) { + ret = dev_pm_opp_add(dev, + ctrl->dpc.perf_levels[i].level * + ctrl->perf_to_freq_factor, + ctrl->dpc.perf_levels[i].power); + } + + /* Add perf ctrl object to end of list */ + mutex_lock(&dev_perf_ctrl_list_mutex); + list_add_tail(&ctrl->list, &dev_perf_ctrl_list); + mutex_unlock(&dev_perf_ctrl_list_mutex); + + kfree(output.pointer); + + return 0; + +out_free: + kfree(ctrl); + +out_buf_free: + kfree(output.pointer); + + return ret; +} + +int acpi_dev_perf_detach(struct device *dev) +{ + // TODO: free device performance control descriptor + dev_pm_opp_remove_table(dev); + return 0; +} diff --git a/drivers/acpi/device_pm.c b/drivers/acpi/device_pm.c index 3b4d048c4941..7346178deef7 100644 --- a/drivers/acpi/device_pm.c +++ b/drivers/acpi/device_pm.c @@ -876,11 +876,13 @@ static int __acpi_device_wakeup_enable(struct acpi_device *adev, if (wakeup->enable_count > 0) goto inc; - status = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); - if (ACPI_FAILURE(status)) { - acpi_disable_wakeup_device_power(adev); - error = -EIO; - goto out; + if (!acpi_gbl_reduced_hardware) { + status = acpi_enable_gpe(wakeup->gpe_device, wakeup->gpe_number); + if (ACPI_FAILURE(status)) { + acpi_disable_wakeup_device_power(adev); + error = -EIO; + goto out; + } } acpi_handle_debug(adev->handle, "GPE%2X enabled for wakeup\n", diff --git a/drivers/acpi/device_sysfs.c b/drivers/acpi/device_sysfs.c index 6ed5e9e56be2..3c2df914348c 100644 --- a/drivers/acpi/device_sysfs.c +++ b/drivers/acpi/device_sysfs.c @@ -121,12 +121,12 @@ static void acpi_hide_nondev_subnodes(struct acpi_device_data *data) } /** - * create_pnp_modalias - Create hid/cid(s) string for modalias and uevent + * create_pnp_modalias - Create hid/uid or hid/cid(s) string for modalias and uevent * @acpi_dev: ACPI device object. * @modalias: Buffer to print into. * @size: Size of the buffer. * - * Creates hid/cid(s) string needed for modalias and uevent + * Creates hid/uid or hid/cid(s) string needed for modalias and uevent * e.g. on a device with hid:IBM0001 and cid:ACPI0001 you get: * char *modalias: "acpi:IBM0001:ACPI0001" * Return: 0: no _HID and no _CID @@ -139,6 +139,9 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia int len; int count; struct acpi_hardware_id *id; + struct acpi_device_info *info; + acpi_status status; + u16 acpi_valid=0; /* Avoid unnecessarily loading modules for non present devices. */ if (!acpi_device_is_present(acpi_dev)) @@ -163,11 +166,15 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia size -= len; - list_for_each_entry(id, &acpi_dev->pnp.ids, list) { - if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID)) - continue; - - count = snprintf(&modalias[len], size, "%s:", id->id); + status=acpi_get_object_info(acpi_dev->handle, &info); + if(ACPI_SUCCESS(status)){ + acpi_valid=info->valid; + ACPI_FREE(info); + } + if (acpi_valid & ACPI_VALID_UID) { + count = snprintf(&modalias[len], size, "%s:%s", + acpi_device_hid((struct acpi_device*)acpi_dev), + acpi_dev->pnp.unique_id); if (count < 0) return -EINVAL; @@ -176,7 +183,30 @@ static int create_pnp_modalias(const struct acpi_device *acpi_dev, char *modalia len += count; size -= count; + } else { + list_for_each_entry(id, &acpi_dev->pnp.ids, list) { + if (!strcmp(id->id, ACPI_DT_NAMESPACE_HID)) + continue; + + count = snprintf(&modalias[len], size, "%s:", id->id); + if (count < 0) + return -EINVAL; + + if (count >= size) + return -ENOMEM; + + len += count; + size -= count; + } + /* If acpi device has _CID objects, here should trim the suffix colon. + * such as, acpi:IBM0001:ACPI0001: ---> acpi:IBM0001:ACPI0001 + */ + + if ((acpi_valid & ACPI_VALID_CID)) { + len--; + } } + modalias[len] = '\0'; return len; } diff --git a/drivers/acpi/internal.h b/drivers/acpi/internal.h index 1e8ee97fc85f..c8329736b2f8 100644 --- a/drivers/acpi/internal.h +++ b/drivers/acpi/internal.h @@ -275,5 +275,4 @@ void acpi_init_lpit(void); #else static inline void acpi_init_lpit(void) { } #endif - #endif /* _ACPI_INTERNAL_H_ */ diff --git a/drivers/acpi/processor_thermal.c b/drivers/acpi/processor_thermal.c index b7c6287eccca..3d5d200569c4 100644 --- a/drivers/acpi/processor_thermal.c +++ b/drivers/acpi/processor_thermal.c @@ -16,6 +16,7 @@ #include #include #include +#include #ifdef CONFIG_CPU_FREQ @@ -26,10 +27,19 @@ */ #define CPUFREQ_THERMAL_MIN_STEP 0 + +#ifdef CONFIG_ARCH_CIX +#define CPUFREQ_THERMAL_MAX_STEP 10 +#else #define CPUFREQ_THERMAL_MAX_STEP 3 +#endif static DEFINE_PER_CPU(unsigned int, cpufreq_thermal_reduction_pctg); +#ifdef CONFIG_ARCH_CIX +#define reduction_pctg(cpu) \ + per_cpu(cpufreq_thermal_reduction_pctg, cpu) +#else #define reduction_pctg(cpu) \ per_cpu(cpufreq_thermal_reduction_pctg, phys_package_first_cpu(cpu)) @@ -50,6 +60,89 @@ static int phys_package_first_cpu(int cpu) return i; return 0; } +#endif + +#ifdef CONFIG_CIX_THERMAL +static unsigned int cix_get_static_power(int cpu) +{ + int pcpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 1); + unsigned long long temp; + struct acpi_object_list arg_list; + union acpi_object arg; + acpi_status status; + + /* One argument, integer_argument; One return integer value expected */ + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = (u64)pcpu; + if (pcpu > 12) { + pr_err("CIX: Invalid CPU[%d %d] for SPRG\n", pcpu, cpu); + return 0; + } + + status = acpi_evaluate_integer(NULL, "\\_SB.SPRG", &arg_list, &temp); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + pr_err("failed to evaluate SPRG %s\n", + acpi_format_exception(status)); + return 0; + } + + return (unsigned int)(temp & 0xFFFFFFFF); +} + +static unsigned int cix_get_dynamic_power(int cpu) +{ + int pcpu = MPIDR_AFFINITY_LEVEL(cpu_logical_map(cpu), 1); + unsigned long long temp; + struct acpi_object_list arg_list; + union acpi_object arg; + acpi_status status; + + /* One argument, integer_argument; One return integer value expected */ + arg_list.count = 1; + arg_list.pointer = &arg; + arg.type = ACPI_TYPE_INTEGER; + arg.integer.value = (u64)pcpu; + if (pcpu > 12) { + pr_err("CIX: Invalid CPU[%d %d] for DPRG\n", pcpu, cpu); + return 0; + } + + status = acpi_evaluate_integer(NULL, "\\_SB.DPRG", &arg_list, &temp); + if (ACPI_FAILURE(status) && status != AE_NOT_FOUND) { + pr_err("failed to evaluate DPRG %s\n", + acpi_format_exception(status)); + return 0; + } + + return (unsigned int)(temp & 0xFFFFFFFF); +} + +static int processor_get_static_power_cpus(cpumask_var_t cpus) +{ + int cpu; + int total_power = 0; + + for_each_cpu(cpu, cpus) { + total_power += cix_get_static_power(cpu); + } + + return total_power; +} + +static int processor_get_dynamic_power_cpus(cpumask_var_t cpus) +{ + int cpu; + int total_power = 0; + + for_each_cpu(cpu, cpus) { + total_power += cix_get_dynamic_power(cpu); + } + + return total_power; +} +#endif static int cpu_has_cpufreq(unsigned int cpu) { @@ -68,9 +161,10 @@ static int cpu_has_cpufreq(unsigned int cpu) static int cpufreq_get_max_state(unsigned int cpu) { +#ifndef CONFIG_ARCH_CIX if (!cpu_has_cpufreq(cpu)) return 0; - +#endif return CPUFREQ_THERMAL_MAX_STEP; } @@ -112,9 +206,15 @@ static int cpufreq_set_cur_state(unsigned int cpu, int state) policy = cpufreq_cpu_get(i); if (!policy) return -EINVAL; - +#ifdef CONFIG_ARCH_CIX + if (policy != cpufreq_cpu_get(cpu)) { + cpufreq_cpu_put(policy); + continue; + } + max_freq = (policy->cpuinfo.max_freq * (100 - reduction_pctg(i) * 5)) / 100; +#else max_freq = (policy->cpuinfo.max_freq * (100 - reduction_pctg(i) * 20)) / 100; - +#endif cpufreq_cpu_put(policy); ret = freq_qos_update_request(&pr->thermal_req, max_freq); @@ -269,10 +369,190 @@ processor_set_cur_state(struct thermal_cooling_device *cdev, return result; } +static int processor_get_requested_power(struct thermal_cooling_device *cdev, + u32 *power) +{ + struct acpi_device *device = cdev->devdata; + struct cpufreq_policy *policy; + struct acpi_processor *pr; + + if (!device) + return -EINVAL; + + pr = acpi_driver_data(device); + if (!pr) + return -EINVAL; + if(pr->id >= num_possible_cpus()) { + pr_err("Invalid CPU device or CPU ID %d\n", pr->id); + return -EINVAL; + } + + policy = cpufreq_cpu_get(pr->id); + if (!policy) + return -EINVAL; + *power = processor_get_static_power_cpus(policy->cpus) + + processor_get_dynamic_power_cpus(policy->cpus); + cpufreq_cpu_put(policy); + + return 0; +} + +/** + * processor_state2power() - convert a cpu cdev state to power consumed + * @cdev: &thermal_cooling_device pointer + * @state: cooling device state to be converted + * @power: pointer in which to store the resulting power + * + * Convert cooling device state @state into power consumption in + * milliwatts assuming 100% load. Store the calculated power in + * @power. + * + * Return: 0 on success, -EINVAL if the cooling device state is bigger + * than maximum allowed. + */ +static int processor_state2power(struct thermal_cooling_device *cdev, + unsigned long state, u32 *power) +{ + unsigned int freq, opp_power, num_cpus, idx; + struct cpufreq_policy *policy = NULL; + struct cppc_cpudata *cpu_data; + struct em_perf_domain *em; + struct acpi_device *device = cdev->devdata; + struct acpi_processor *pr; + int ret = 0; + + if (!device) + return -EINVAL; + + pr = acpi_driver_data(device); + if (!pr) + return -EINVAL; + if(pr->id >= num_possible_cpus()) { + pr_err("Invalid CPU device or CPU ID %d\n", pr->id); + return -EINVAL; + } + + policy = cpufreq_cpu_get(pr->id); + if (!policy) + return -EINVAL; + cpu_data = policy->driver_data; + if (!cpu_data) { + pr_warn("No CPU data for CPU%d\n", policy->cpu); + ret = -ENODEV; + goto EXIT; + } + + /* Request state should be less than max_level */ + if (state > cpu_data->opp_level_num) { + pr_err("Invalid state %lu for cooling device %s\n", + state, cdev->type); + ret = -EINVAL; + goto EXIT; + } + + em = em_cpu_get(policy->cpu); + if (!em) { + pr_warn("No energy model for CPU%d\n", policy->cpu); + ret = -ENODEV; + goto EXIT; + } + num_cpus = cpumask_weight(policy->cpus); + idx = cpu_data->opp_level_num - state - 1; + freq = em->table[idx].frequency; + opp_power = em->table[idx].power; + *power = opp_power * num_cpus; + *power += processor_get_static_power_cpus(policy->cpus); + +EXIT: + cpufreq_cpu_put(policy); + return ret; +} + +/** + * processor_power2state() - convert power to a cooling device state + * @cdev: &thermal_cooling_device pointer + * @power: power in milliwatts to be converted + * @state: pointer in which to store the resulting state + * + * Calculate a cooling device state for the cpus described by @cdev + * that would allow them to consume at most @power mW and store it in + * @state. Note that this calculation depends on external factors + * such as the CPUs load. Calling this function with the same power + * as input can yield different cooling device states depending on those + * external factors. + * + * Return: 0 on success, this function doesn't fail. + */ +static int processor_power2state(struct thermal_cooling_device *cdev, + u32 power, unsigned long *state) +{ + struct cpufreq_policy *policy; + struct cppc_cpudata *cpu_data; + struct em_perf_domain *em; + unsigned int target_freq; + u32 normalised_power; + u32 em_power_mw; + u32 static_power; + int i; + + struct acpi_device *device = cdev->devdata; + struct acpi_processor *pr; + + if (!device) + return -EINVAL; + + pr = acpi_driver_data(device); + if (!pr) + return -EINVAL; + + policy = cpufreq_cpu_get(pr->id); + if (!policy) + return -EINVAL; + cpu_data = policy->driver_data; + if (!cpu_data) { + pr_warn("No CPU data for CPU%d\n", policy->cpu); + cpufreq_cpu_put(policy); + return -ENODEV; + } + + static_power = processor_get_static_power_cpus(policy->cpus); + if (power > static_power) + normalised_power = power - static_power; + else + normalised_power = 0; + + em = em_cpu_get(policy->cpu); + if (!em) { + pr_warn("No energy model for CPU%d\n", policy->cpu); + cpufreq_cpu_put(policy); + return -ENODEV; + } + cpufreq_cpu_put(policy); + + for (i = cpu_data->opp_level_num - 1; i >= 0; i--) { + em_power_mw = em->table[i].power; + if (normalised_power >= em_power_mw) + break; + } + if (i < 0) { + pr_warn("No level found for power %u\n", power); + *state = cpu_data->opp_level_num - 1; + return 0; + } + target_freq = em->table[i].frequency; + + *state = cpu_data->opp_level_num - i - 1; + return 0; +} + + const struct thermal_cooling_device_ops processor_cooling_ops = { .get_max_state = processor_get_max_state, .get_cur_state = processor_get_cur_state, .set_cur_state = processor_set_cur_state, + .get_requested_power = processor_get_requested_power, + .power2state = processor_power2state, + .state2power = processor_state2power, }; int acpi_processor_thermal_init(struct acpi_processor *pr, diff --git a/drivers/acpi/property.c b/drivers/acpi/property.c index dca5682308cb..9819c6b8e8d4 100644 --- a/drivers/acpi/property.c +++ b/drivers/acpi/property.c @@ -970,6 +970,64 @@ int __acpi_node_get_property_reference(const struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(__acpi_node_get_property_reference); +int __acpi_node_count_property_reference(const struct fwnode_handle *fwnode, + const char *propname) +{ + const union acpi_object *element, *end; + const union acpi_object *obj; + const struct acpi_device_data *data; + struct acpi_device *device; + int ret, idx = 0; + + data = acpi_device_data_of_node(fwnode); + if (!data) + return -ENOENT; + + ret = acpi_data_get_property(data, propname, ACPI_TYPE_ANY, &obj); + if (ret) + return ret == -EINVAL ? -ENOENT : -EINVAL; + + switch (obj->type) { + case ACPI_TYPE_LOCAL_REFERENCE: + return 1; + case ACPI_TYPE_PACKAGE: + break; + default: + return -EINVAL; + } + + element = obj->package.elements; + end = element + obj->package.count; + + while (element < end) { + switch (element->type) { + case ACPI_TYPE_LOCAL_REFERENCE: + device = acpi_fetch_acpi_dev(element->reference.handle); + if (!device) + return -EINVAL; + + element++; + + ret = acpi_get_ref_args(NULL, acpi_fwnode_handle(device), + &element, end, NR_FWNODE_REFERENCE_ARGS); + if (ret < 0) + return ret; + + break; + case ACPI_TYPE_INTEGER: + element++; + break; + default: + return -EINVAL; + } + + idx++; + } + + return idx; +} +EXPORT_SYMBOL_GPL(__acpi_node_count_property_reference); + static int acpi_data_prop_read_single(const struct acpi_device_data *data, const char *propname, enum dev_prop_type proptype, void *val) @@ -1497,6 +1555,13 @@ acpi_fwnode_get_reference_args(const struct fwnode_handle *fwnode, args_count, args); } +static int +acpi_fwnode_count_reference_with_args(const struct fwnode_handle *fwnode, + const char *list_name, const char *cells_name) +{ + return __acpi_node_count_property_reference(fwnode, list_name); +} + static const char *acpi_fwnode_get_name(const struct fwnode_handle *fwnode) { const struct acpi_device *adev; @@ -1602,6 +1667,7 @@ static int acpi_fwnode_irq_get(const struct fwnode_handle *fwnode, .graph_get_port_parent = acpi_fwnode_get_parent, \ .graph_parse_endpoint = acpi_fwnode_graph_parse_endpoint, \ .irq_get = acpi_fwnode_irq_get, \ + .property_count_reference_with_args = acpi_fwnode_count_reference_with_args, \ }; \ EXPORT_SYMBOL_GPL(ops) diff --git a/drivers/acpi/scan.c b/drivers/acpi/scan.c index c0c5c5c58ae1..f9b3f88a2ad3 100644 --- a/drivers/acpi/scan.c +++ b/drivers/acpi/scan.c @@ -956,8 +956,14 @@ static bool acpi_wakeup_gpe_init(struct acpi_device *device) return true; } - status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device, - wakeup->gpe_number); + if (!acpi_gbl_reduced_hardware) { + status = acpi_setup_gpe_for_wake(device->handle, wakeup->gpe_device, + wakeup->gpe_number); + } else { + device_set_wakeup_capable(&device->dev, true); + status = AE_OK; + } + return ACPI_SUCCESS(status); } diff --git a/drivers/acpi/sleep.c b/drivers/acpi/sleep.c index 728acfeb774d..e324564dd143 100644 --- a/drivers/acpi/sleep.c +++ b/drivers/acpi/sleep.c @@ -33,6 +33,9 @@ bool acpi_no_s5; static u8 sleep_states[ACPI_S_STATE_COUNT]; +static const struct acpi_fw_sleep_ops *fw_sleep_ops; +static DEFINE_MUTEX(fw_sleep_ops_lock); + static void acpi_sleep_tts_switch(u32 acpi_state) { acpi_status status; @@ -70,7 +73,8 @@ static int acpi_sleep_prepare(u32 acpi_state) unsigned long acpi_wakeup_address; /* do we have a wakeup address for S2 and S3? */ - if (acpi_state == ACPI_STATE_S3 && !acpi_skip_set_wakeup_address()) { + if (acpi_state == ACPI_STATE_S3 && !acpi_skip_set_wakeup_address() + && !acpi_gbl_reduced_hardware) { acpi_wakeup_address = acpi_get_wakeup_address(); if (!acpi_wakeup_address) return -EFAULT; @@ -89,10 +93,29 @@ bool acpi_sleep_state_supported(u8 sleep_state) acpi_status status; u8 type_a, type_b; - status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b); - return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware + if (fw_sleep_ops && fw_sleep_ops->valid) { + return fw_sleep_ops->valid(sleep_state); + } else { + status = acpi_get_sleep_type_data(sleep_state, &type_a, &type_b); + return ACPI_SUCCESS(status) && (!acpi_gbl_reduced_hardware || (acpi_gbl_FADT.sleep_control.address && acpi_gbl_FADT.sleep_status.address)); + } +} + +void acpi_set_fw_sleep_ops(const struct acpi_fw_sleep_ops *ops) +{ + mutex_lock(&fw_sleep_ops_lock); + fw_sleep_ops = ops; + mutex_unlock(&fw_sleep_ops_lock); +} + +acpi_status acpi_enter_sleep_state_toplevel(u8 acpi_state) +{ + if (fw_sleep_ops && fw_sleep_ops->enter) + return fw_sleep_ops->enter(acpi_state); + else + return acpi_enter_sleep_state(acpi_state); } #ifdef CONFIG_ACPI_SLEEP @@ -581,12 +604,16 @@ static int acpi_suspend_enter(suspend_state_t pm_state) switch (acpi_state) { case ACPI_STATE_S1: barrier(); - status = acpi_enter_sleep_state(acpi_state); + status = acpi_enter_sleep_state_toplevel(acpi_state); break; case ACPI_STATE_S3: + if (fw_sleep_ops && fw_sleep_ops->enter) + return fw_sleep_ops->enter(acpi_state); +#ifdef CONFIG_X86_64 if (!acpi_suspend_lowlevel) return -ENOSYS; +#endif error = acpi_suspend_lowlevel(); if (error) return error; @@ -654,7 +681,6 @@ static int acpi_suspend_state_valid(suspend_state_t pm_state) case PM_SUSPEND_STANDBY: case PM_SUSPEND_MEM: acpi_state = acpi_suspend_states[pm_state]; - return sleep_states[acpi_state]; default: return 0; @@ -840,7 +866,6 @@ static void __init acpi_sleep_suspend_setup(void) { bool suspend_ops_needed = false; int i; - for (i = ACPI_STATE_S1; i < ACPI_STATE_S4; i++) if (acpi_sleep_state_supported(i)) { sleep_states[i] = 1; @@ -922,7 +947,7 @@ static int acpi_hibernation_enter(void) acpi_status status = AE_OK; /* This shouldn't return. If it returns, we have a problem */ - status = acpi_enter_sleep_state(ACPI_STATE_S4); + status = acpi_enter_sleep_state_toplevel(ACPI_STATE_S4); /* Reprogram control registers */ acpi_leave_sleep_state_prep(ACPI_STATE_S4); @@ -1066,7 +1091,7 @@ static int acpi_power_off(struct sys_off_data *data) /* acpi_sleep_prepare(ACPI_STATE_S5) should have already been called */ pr_debug("%s called\n", __func__); local_irq_disable(); - acpi_enter_sleep_state(ACPI_STATE_S5); + acpi_enter_sleep_state_toplevel(ACPI_STATE_S5); return NOTIFY_DONE; } diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 8263508415a8..7bc72d773981 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -30,6 +30,7 @@ #include #include #include +#include #define ACPI_THERMAL_CLASS "thermal_zone" #define ACPI_THERMAL_DEVICE_NAME "Thermal Zone" @@ -55,6 +56,8 @@ ACPI_TRIPS_PASSIVE | ACPI_TRIPS_ACTIVE | \ ACPI_TRIPS_DEVICES) +#define TEMP_MIN_DECIK 2180 + /* * This exception is thrown out in two cases: * 1.An invalid trip point becomes invalid or a valid trip point becomes invalid @@ -94,6 +97,8 @@ static struct workqueue_struct *acpi_thermal_pm_queue; struct acpi_thermal_trip { unsigned long temperature; + /* Some thermal governor need a switch-on temperature, such as IPA */ + unsigned long switch_on_temp; bool valid; }; @@ -132,12 +137,28 @@ struct acpi_thermal { struct work_struct thermal_check_work; struct mutex thermal_check_lock; refcount_t thermal_check_count; + unsigned long sustainable_power; }; /* -------------------------------------------------------------------------- - Thermal Zone Management + Thermal Zone Management -------------------------------------------------------------------------- */ +struct thermal_zone_device *thermal_acpi_get_thermal_zone_by_name(struct acpi_device *adev, const char *name) +{ + struct thermal_zone_device *tzd = NULL; + if (adev) { + struct fwnode_handle *fwnode = fwnode_find_reference(&adev->fwnode, name, 0); + if (!IS_ERR(fwnode)) { + struct acpi_thermal *athermal = (struct acpi_thermal *)to_acpi_device_node(fwnode)->driver_data; + if (!IS_ERR_OR_NULL(athermal)) + tzd = athermal->thermal_zone; + } + } + return tzd; +} +EXPORT_SYMBOL(thermal_acpi_get_thermal_zone_by_name); + static int acpi_thermal_get_temperature(struct acpi_thermal *tz) { acpi_status status = AE_OK; @@ -160,6 +181,28 @@ static int acpi_thermal_get_temperature(struct acpi_thermal *tz) return 0; } +static int acpi_thermal_get_sustainable_power(struct acpi_thermal *tz) +{ + acpi_status status = AE_OK; + unsigned long long tmp; + + if (!tz) + return -EINVAL; + + tz->last_temperature = tz->temperature; + + status = acpi_evaluate_integer(tz->device->handle, "SSTP", NULL, &tmp); + if (ACPI_FAILURE(status)) + return -ENODEV; + + tz->sustainable_power = tmp; + + acpi_handle_debug(tz->device->handle, "Sustainable power is %lu mW\n", + tz->sustainable_power); + + return 0; +} + static int acpi_thermal_get_polling_frequency(struct acpi_thermal *tz) { acpi_status status = AE_OK; @@ -292,6 +335,15 @@ static void __acpi_thermal_trips_update(struct acpi_thermal *tz, int flag) tz->trips.passive.trip.valid = false; else tz->trips.passive.tsp = tmp; + + status = acpi_evaluate_integer(tz->device->handle, + "SWIT", NULL, &tmp); + if (ACPI_FAILURE(status) + || tmp > tz->trips.passive.trip.temperature + || tmp < TEMP_MIN_DECIK) + tz->trips.passive.trip.switch_on_temp = THERMAL_TEMP_INVALID; + else + tz->trips.passive.trip.switch_on_temp = tmp; } } } @@ -557,6 +609,14 @@ static void acpi_thermal_zone_device_critical(struct thermal_zone_device *therma thermal_zone_device_critical(thermal); } +static bool check_cdev_type(struct thermal_cooling_device *cdev, const char *type) +{ + if (cdev->type && !strncmp(cdev->type, type, strlen(type))) + return true; + else + return false; +} + static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev, bool bind) @@ -570,6 +630,11 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, int trip = -1; int result = 0; + if (check_cdev_type(cdev, "devfreq")) { + struct devfreq_cooling_device *dfc = (struct devfreq_cooling_device *)cdev->devdata; + device = to_acpi_device_node(dfc->devfreq->dev.parent->fwnode); + } + if (tz->trips.critical.valid) trip++; @@ -682,6 +747,7 @@ static void acpi_thermal_zone_sysfs_remove(struct acpi_thermal *tz) static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) { struct acpi_thermal_trip *acpi_trip; + struct thermal_zone_params tzp = {}; struct thermal_trip *trip; int passive_delay = 0; int trip_count = 0; @@ -697,11 +763,16 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) if (tz->trips.passive.trip.valid) { trip_count++; passive_delay = tz->trips.passive.tsp * 100; + if (tz->trips.passive.trip.switch_on_temp != THERMAL_TEMP_INVALID) + trip_count++; } for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE && tz->trips.active[i].trip.valid; i++) trip_count++; - + dev_dbg(&tz->device->dev, "%s:%d, trip_count %d switch on temp: %ld, target: %ld\n", + __func__, __LINE__, trip_count, + tz->trips.passive.trip.switch_on_temp, + tz->trips.passive.trip.temperature); trip = kcalloc(trip_count, sizeof(*trip), GFP_KERNEL); if (!trip) return -ENOMEM; @@ -728,6 +799,14 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) trip++; } + acpi_trip = &tz->trips.passive.trip; + if (acpi_trip->valid) { + trip->type = THERMAL_TRIP_PASSIVE; + trip->temperature = acpi_thermal_temp(tz, acpi_trip->switch_on_temp); + trip->priv = acpi_trip; + trip++; + } + for (i = 0; i < ACPI_THERMAL_MAX_ACTIVE; i++) { acpi_trip = &tz->trips.active[i].trip; @@ -740,12 +819,13 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) trip++; } + tzp.sustainable_power = tz->sustainable_power; tz->thermal_zone = thermal_zone_device_register_with_trips("acpitz", tz->trip_table, trip_count, 0, tz, &acpi_thermal_zone_ops, - NULL, + &tzp, passive_delay, tz->polling_frequency * 100); if (IS_ERR(tz->thermal_zone)) { @@ -786,7 +866,7 @@ static void acpi_thermal_unregister_thermal_zone(struct acpi_thermal *tz) /* -------------------------------------------------------------------------- - Driver Interface + Driver Interface -------------------------------------------------------------------------- */ static void acpi_thermal_notify(acpi_handle handle, u32 event, void *data) @@ -863,6 +943,11 @@ static int acpi_thermal_get_info(struct acpi_thermal *tz) if (result) return result; + /* Get susptainable power [SSTP] (required) */ + result = acpi_thermal_get_sustainable_power(tz); + if (result) + return result; + /* Set the cooling mode [_SCP] to active cooling (default) */ acpi_execute_simple_method(tz->device->handle, "_SCP", ACPI_THERMAL_MODE_ACTIVE); @@ -1046,7 +1131,8 @@ static struct acpi_driver acpi_thermal_driver = { .drv.pm = &acpi_thermal_pm, }; -static int thermal_act(const struct dmi_system_id *d) { +static int thermal_act(const struct dmi_system_id *d) +{ if (act == 0) { pr_notice("%s detected: disabling all active thermal trip points\n", d->ident); @@ -1054,13 +1140,15 @@ static int thermal_act(const struct dmi_system_id *d) { } return 0; } -static int thermal_nocrt(const struct dmi_system_id *d) { +static int thermal_nocrt(const struct dmi_system_id *d) +{ pr_notice("%s detected: disabling all critical thermal trip point actions.\n", d->ident); crt = -1; return 0; } -static int thermal_tzp(const struct dmi_system_id *d) { +static int thermal_tzp(const struct dmi_system_id *d) +{ if (tzp == 0) { pr_notice("%s detected: enabling thermal zone polling\n", d->ident); @@ -1068,7 +1156,8 @@ static int thermal_tzp(const struct dmi_system_id *d) { } return 0; } -static int thermal_psv(const struct dmi_system_id *d) { +static int thermal_psv(const struct dmi_system_id *d) +{ if (psv == 0) { pr_notice("%s detected: disabling all passive thermal trip points\n", d->ident); diff --git a/drivers/acpi/thermal.h b/drivers/acpi/thermal.h new file mode 100644 index 000000000000..cbf868053985 --- /dev/null +++ b/drivers/acpi/thermal.h @@ -0,0 +1,90 @@ +/* SPDX-License-Identifier: GPL-2.0-or-later */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define ACPI_THERMAL_MAX_ACTIVE 10 + +struct acpi_thermal_state { + u8 critical:1; + u8 hot:1; + u8 passive:1; + u8 active:1; + u8 reserved:4; + int active_index; +}; + +struct acpi_thermal_state_flags { + u8 valid:1; + u8 enabled:1; + u8 reserved:6; +}; + +struct acpi_thermal_critical { + struct acpi_thermal_state_flags flags; + unsigned long temperature; +}; + +struct acpi_thermal_hot { + struct acpi_thermal_state_flags flags; + unsigned long temperature; +}; + +struct acpi_thermal_passive { + struct acpi_thermal_state_flags flags; + unsigned long temperature; + unsigned long tc1; + unsigned long tc2; + unsigned long tsp; + struct acpi_handle_list devices; +}; + +struct acpi_thermal_active { + struct acpi_thermal_state_flags flags; + unsigned long temperature; + struct acpi_handle_list devices; +}; + +struct acpi_thermal_trips { + struct acpi_thermal_critical critical; + struct acpi_thermal_hot hot; + struct acpi_thermal_passive passive; + struct acpi_thermal_active active[ACPI_THERMAL_MAX_ACTIVE]; +}; + +struct acpi_thermal_flags { + u8 cooling_mode:1; /* _SCP */ + u8 devices:1; /* _TZD */ + u8 reserved:6; +}; + +struct acpi_thermal { + struct acpi_device *device; + acpi_bus_id name; + unsigned long temperature; + unsigned long last_temperature; + unsigned long polling_frequency; + volatile u8 zombie; + struct acpi_thermal_flags flags; + struct acpi_thermal_state state; + struct acpi_thermal_trips trips; + struct acpi_handle_list devices; + struct thermal_zone_device *thermal_zone; + int kelvin_offset; /* in millidegrees */ + struct work_struct thermal_check_work; + struct mutex thermal_check_lock; + refcount_t thermal_check_count; +}; diff --git a/drivers/android/Kconfig b/drivers/android/Kconfig index 07aa8ae0a058..e85378cde313 100644 --- a/drivers/android/Kconfig +++ b/drivers/android/Kconfig @@ -47,4 +47,11 @@ config ANDROID_BINDER_IPC_SELFTEST exhaustively with combinations of various buffer sizes and alignments. +config MPAM_ARCH + tristate "MPAM module based architecture driver" + +config MPAM_POLICY + tristate "MPAM policy module" + depends on ANDROID_MPAM_ARCH + endmenu diff --git a/drivers/android/Makefile b/drivers/android/Makefile index c9d3d0c99c25..75fa5190347d 100644 --- a/drivers/android/Makefile +++ b/drivers/android/Makefile @@ -4,3 +4,4 @@ ccflags-y += -I$(src) # needed for trace events obj-$(CONFIG_ANDROID_BINDERFS) += binderfs.o obj-$(CONFIG_ANDROID_BINDER_IPC) += binder.o binder_alloc.o obj-$(CONFIG_ANDROID_BINDER_IPC_SELFTEST) += binder_alloc_selftest.o +obj-$(CONFIG_MPAM_ARCH) += mpam_arch.o diff --git a/drivers/android/mpam_arch.c b/drivers/android/mpam_arch.c new file mode 100644 index 000000000000..43ce10c5ef47 --- /dev/null +++ b/drivers/android/mpam_arch.c @@ -0,0 +1,697 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Module-based hack to drive MPAM functionality + * + * NOTICE: This circumvents existing infrastructure to discover and enable CPU + * features and attempts to contain everything within a loadable module. This is + * *not* the right way to do things, but it is one way to start testing MPAM on + * real hardware. + * + * Copyright (C) 2022 Arm Ltd. + */ + +#define DEBUG + +#define pr_fmt(fmt) "MPAM_arch: " fmt + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include "mpam_arch.h" +#include "mpam_arch_internal.h" + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Valentin Schneider "); + +#define FIELD_SET(reg, field, val) (reg = (reg & ~field) | FIELD_PREP(field, val)) + +struct msc_part_kobj { + struct mpam_msc *msc; + unsigned int partid; + struct kobject kobj; +}; + +struct mpam_msc { + struct platform_device *pdev; + + void __iomem *base; + spinlock_t lock; + + unsigned int partid_count; + unsigned int cpbm_nbits; + unsigned int cmax_nbits; + unsigned int cmax_shift; + + int has_ris; + union { + struct { + bool has_cpor; + bool has_ccap; + }; + u8 part_feats; + }; + + struct kobject ko_root; + struct kobject ko_part_dir; + struct msc_part_kobj *ko_parts; +}; + +static __read_mostly unsigned int mpam_partid_count = UINT_MAX; + +/* The MPAM0_EL1.PARTID_D in use by a given CPU */ +static DEFINE_PER_CPU(unsigned int, mpam_local_partid) = MPAM_PARTID_DEFAULT; + +unsigned int mpam_get_partid_count(void) +{ + /* + * XXX: this should check the driver has probed all matching devices + * first + */ + return mpam_partid_count; +} +EXPORT_SYMBOL_GPL(mpam_get_partid_count); + +static void mpam_set_el0_partid(unsigned int inst_id, unsigned int data_id) +{ + u64 reg; + + cant_migrate(); + + reg = read_sysreg_s(SYS_MPAM0_EL1); + + FIELD_SET(reg, MPAM0_EL1_PARTID_I, inst_id); + FIELD_SET(reg, MPAM0_EL1_PARTID_D, data_id); + + write_sysreg_s(reg, SYS_MPAM0_EL1); + /* + * Note: if the scope is limited to userspace, we'll get an EL switch + * before getting back to US which will be our context synchronization + * event, so this won't be necessary. + */ + isb(); +} + +/* + * Write the PARTID to use on the local CPU. + */ +void mpam_write_partid(unsigned int partid) +{ + WARN_ON_ONCE(preemptible()); + WARN_ON_ONCE(partid >= mpam_partid_count); + + if (partid == this_cpu_read(mpam_local_partid)) + return; + + this_cpu_write(mpam_local_partid, partid); + mpam_set_el0_partid(partid, partid); +} +EXPORT_SYMBOL_GPL(mpam_write_partid); + +static void mpam_msc_sel_partid(struct mpam_msc *msc, unsigned int id) +{ + u32 reg; + + lockdep_assert_held(&msc->lock); + + reg = readl_relaxed(msc->base + MPAMCFG_PART_SEL); + + FIELD_SET(reg, MPAMCFG_PART_SEL_PARTID_SEL, id); + if (msc->has_ris) + FIELD_SET(reg, MPAMCFG_PART_SEL_RIS, 0); + + writel_relaxed(reg, msc->base + MPAMCFG_PART_SEL); + pr_debug("PART_SEL: 0x%x\n", reg); +} + +static unsigned int mpam_msc_get_partid_max(struct mpam_msc *msc) +{ + lockdep_assert_held(&msc->lock); + + return FIELD_GET(MPAMF_IDR_PARTID_MAX, readq_relaxed(msc->base + MPAMF_IDR)); +} + +static void mpam_msc_set_cpbm(struct mpam_msc *msc, + unsigned int id, + const unsigned long *bitmap) +{ + void __iomem *addr = msc->base + MPAMCFG_CPBM_n; + unsigned int bit = 0, n = 0; + u32 acc = 0; + + lockdep_assert_held(&msc->lock); + + mpam_msc_sel_partid(msc, id); + + /* Single write every reg boundary */ + while (n++ < BITS_TO_U32(msc->cpbm_nbits)) { + for_each_set_bit(bit, bitmap, min_t(unsigned int, + (n * BITS_PER_TYPE(u32)), + msc->cpbm_nbits)) + acc |= 1 << bit % BITS_PER_TYPE(u32); + + writel_relaxed(acc, addr); + pr_debug("CPBM: 0x%x @%px\n", acc, addr); + addr += sizeof(acc); + bit = n*BITS_PER_TYPE(u32); + acc = 0; + } +} + +static void mpam_msc_get_cpbm(struct mpam_msc *msc, + unsigned int id, + unsigned long *bitmap) +{ + void __iomem *addr = msc->base + MPAMCFG_CPBM_n; + size_t regsize = BITS_PER_TYPE(u32); + unsigned int bit; + int n; + + lockdep_assert_held(&msc->lock); + + mpam_msc_sel_partid(msc, id); + + for (n = 0; (n * regsize) < msc->cpbm_nbits; n++) { + unsigned long tmp = readl_relaxed(addr); + + for_each_set_bit(bit, &tmp, min(regsize, msc->cpbm_nbits - (n * regsize))) + bitmap_set(bitmap, bit + (n * regsize), 1); + + addr += regsize; + } +} + +static u16 mpam_msc_get_cmax(struct mpam_msc *msc, unsigned int id) +{ + u32 reg; + u16 res; + + lockdep_assert_held(&msc->lock); + + mpam_msc_sel_partid(msc, id); + + reg = readl_relaxed(msc->base + MPAMCFG_CMAX); + res = FIELD_GET(MPAMCFG_CMAX_CMAX, reg); + return res << msc->cmax_shift; +} + +static void mpam_msc_set_cmax(struct mpam_msc *msc, unsigned int id, u16 val) +{ + lockdep_assert_held(&msc->lock); + + mpam_msc_sel_partid(msc, id); + writel_relaxed(FIELD_PREP(MPAMCFG_CMAX_CMAX, val >> msc->cmax_shift), + msc->base + MPAMCFG_CMAX); +} + +struct mpam_validation_masks { + cpumask_var_t visited_cpus; + cpumask_var_t supported_cpus; + spinlock_t lock; +}; + +static void mpam_validate_cpu(void *info) +{ + struct mpam_validation_masks *masks = (struct mpam_validation_masks *)info; + unsigned int partid_count; + bool valid = true; + + if (!FIELD_GET(ID_AA64PFR0_MPAM, read_sysreg_s(SYS_ID_AA64PFR0_EL1))) { + valid = false; + goto out; + } + + if (!FIELD_GET(MPAM1_EL1_MPAMEN, read_sysreg_s(SYS_MPAM1_EL1))) { + valid = false; + goto out; + } + + partid_count = FIELD_GET(MPAMIDR_EL1_PARTID_MAX, read_sysreg_s(SYS_MPAMIDR_EL1)) + 1; + + spin_lock(&masks->lock); + mpam_partid_count = min(partid_count, mpam_partid_count); + spin_unlock(&masks->lock); +out: + + cpumask_set_cpu(smp_processor_id(), masks->visited_cpus); + if (valid) + cpumask_set_cpu(smp_processor_id(), masks->supported_cpus); +} + +/* + * Does the system support MPAM, and if so is it actually usable? + */ +static int mpam_validate_sys(void) +{ + struct mpam_validation_masks masks; + int ret = 0; + + if (!zalloc_cpumask_var(&masks.visited_cpus, GFP_KERNEL)) + return -ENOMEM; + + if (!zalloc_cpumask_var(&masks.supported_cpus, GFP_KERNEL)) { + ret = -ENOMEM; + goto out_free_visited; + } + spin_lock_init(&masks.lock); + + on_each_cpu_cond_mask(NULL, mpam_validate_cpu, &masks, true, cpu_present_mask); + + if (!cpumask_equal(masks.visited_cpus, cpu_present_mask)) { + pr_warn("Could not check all CPUs for MPAM settings (visited %*pbl)\n", + cpumask_pr_args(masks.visited_cpus)); + ret = -ENODATA; + goto out; + } + + if (!cpumask_equal(masks.visited_cpus, masks.supported_cpus)) { + pr_warn("MPAM only supported on CPUs [%*pbl]\n", + cpumask_pr_args(masks.supported_cpus)); + ret = -EOPNOTSUPP; + } +out: + free_cpumask_var(masks.supported_cpus); +out_free_visited: + free_cpumask_var(masks.visited_cpus); + + return ret; +} + +static ssize_t mpam_msc_cpbm_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct msc_part_kobj *mpk = container_of(kobj, struct msc_part_kobj, kobj); + unsigned long *bitmap; + unsigned long flags; + size_t size; + + bitmap = bitmap_zalloc(mpk->msc->cpbm_nbits, GFP_KERNEL); + if (!bitmap) + return -ENOMEM; + + spin_lock_irqsave(&mpk->msc->lock, flags); + mpam_msc_get_cpbm(mpk->msc, mpk->partid, bitmap); + spin_unlock_irqrestore(&mpk->msc->lock, flags); + + size = bitmap_print_to_pagebuf(true, buf, bitmap, mpk->msc->cpbm_nbits); + + bitmap_free(bitmap); + return size; +} + +static ssize_t mpam_msc_cpbm_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t size) +{ + struct msc_part_kobj *mpk = container_of(kobj, struct msc_part_kobj, kobj); + unsigned long *bitmap; + unsigned long flags; + int ret; + + bitmap = bitmap_zalloc(mpk->msc->cpbm_nbits, GFP_KERNEL); + if (!bitmap) + return -ENOMEM; + + ret = bitmap_parselist(buf, bitmap, mpk->msc->cpbm_nbits); + if (ret) + goto out_free; + + spin_lock_irqsave(&mpk->msc->lock, flags); + mpam_msc_set_cpbm(mpk->msc, mpk->partid, bitmap); + spin_unlock_irqrestore(&mpk->msc->lock, flags); +out_free: + bitmap_free(bitmap); + return ret ?: size; +} + +static ssize_t mpam_msc_cmax_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct msc_part_kobj *mpk = container_of(kobj, struct msc_part_kobj, kobj); + unsigned long flags; + u16 val; + + spin_lock_irqsave(&mpk->msc->lock, flags); + val = mpam_msc_get_cmax(mpk->msc, mpk->partid); + spin_unlock_irqrestore(&mpk->msc->lock, flags); + + return sprintf(buf, "0x%04x\n", val); +} + +static ssize_t mpam_msc_cmax_store(struct kobject *kobj, struct kobj_attribute *attr, + const char *buf, size_t size) +{ + struct msc_part_kobj *mpk = container_of(kobj, struct msc_part_kobj, kobj); + unsigned long flags; + u16 val; + int ret; + + ret = kstrtou16(buf, 0, &val); + if (ret) + return ret; + + spin_lock_irqsave(&mpk->msc->lock, flags); + mpam_msc_set_cmax(mpk->msc, mpk->partid, val); + spin_unlock_irqrestore(&mpk->msc->lock, flags); + + return size; +} + +static struct kobj_attribute mpam_msc_cpbm_attr = + __ATTR(cpbm, 0644, mpam_msc_cpbm_show, mpam_msc_cpbm_store); + +static struct kobj_attribute mpam_msc_cmax_attr = + __ATTR(cmax, 0644, mpam_msc_cmax_show, mpam_msc_cmax_store); + +static struct attribute *mpam_msc_ctrl_attrs[] = { + &mpam_msc_cpbm_attr.attr, + &mpam_msc_cmax_attr.attr, + NULL, +}; + +static umode_t mpam_msc_ctrl_attr_visible(struct kobject *kobj, + struct attribute *attr, + int n) +{ + struct msc_part_kobj *mpk; + + mpk = container_of(kobj, struct msc_part_kobj, kobj); + + if (attr == &mpam_msc_cpbm_attr.attr && + mpk->msc->has_cpor) + goto visible; + + if (attr == &mpam_msc_cmax_attr.attr && + mpk->msc->has_ccap) + goto visible; + + return 0; + +visible: + return attr->mode; +} + +static struct attribute_group mpam_msc_ctrl_attr_group = { + .attrs = mpam_msc_ctrl_attrs, + .is_visible = mpam_msc_ctrl_attr_visible, +}; + + +static ssize_t mpam_msc_cpbm_nbits_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct mpam_msc *msc = container_of(kobj, struct mpam_msc, ko_root); + + return sprintf(buf, "%u\n", msc->cpbm_nbits); +} + +static ssize_t mpam_msc_cmax_nbits_show(struct kobject *kobj, struct kobj_attribute *attr, + char *buf) +{ + struct mpam_msc *msc = container_of(kobj, struct mpam_msc, ko_root); + + return sprintf(buf, "%u\n", msc->cmax_nbits); +} + +static struct kobj_attribute mpam_msc_cpbm_nbits_attr = + __ATTR(cpbm_nbits, 0444, mpam_msc_cpbm_nbits_show, NULL); +static struct kobj_attribute mpam_msc_cmax_nbits_attr = + __ATTR(cmax_nbits, 0444, mpam_msc_cmax_nbits_show, NULL); + +static struct attribute *mpam_msc_info_attrs[] = { + &mpam_msc_cpbm_nbits_attr.attr, + &mpam_msc_cmax_nbits_attr.attr, + NULL, +}; + +static umode_t mpam_msc_info_attr_visible(struct kobject *kobj, + struct attribute *attr, + int n) +{ + struct mpam_msc *msc = container_of(kobj, struct mpam_msc, ko_root); + + if (attr == &mpam_msc_cpbm_nbits_attr.attr && + msc->has_cpor) + goto visible; + + if (attr == &mpam_msc_cmax_nbits_attr.attr && + msc->has_ccap) + goto visible; + + return 0; + +visible: + return attr->mode; +} + +static struct attribute_group mpam_msc_info_attr_group = { + .attrs = mpam_msc_info_attrs, + .is_visible = mpam_msc_info_attr_visible, +}; + +static struct kobj_type mpam_kobj_ktype = { + .sysfs_ops = &kobj_sysfs_ops, +}; + +/* + * msc-foo/ + * mpam/ + * cpbm_nbits + * partitions/ + * 0/cpbm + * 1/cpbm + * ... + */ +static int mpam_msc_create_sysfs(struct mpam_msc *msc) +{ + unsigned int partid_count = min(mpam_partid_count, msc->partid_count); + unsigned int part, tmp; + int ret; + + kobject_init(&msc->ko_root, &mpam_kobj_ktype); + ret = kobject_add(&msc->ko_root, &msc->pdev->dev.kobj, "mpam"); + if (ret) + goto err_root; + + kobject_init(&msc->ko_part_dir, &mpam_kobj_ktype); + ret = kobject_add(&msc->ko_part_dir, &msc->ko_root, "partitions"); + if (ret) + goto err_part_dir; + + msc->ko_parts = devm_kzalloc(&msc->pdev->dev, + sizeof(*msc->ko_parts) * partid_count, + GFP_KERNEL); + if (!msc->ko_parts) { + ret = -ENOMEM; + goto err_part_dir; + } + + ret = sysfs_create_group(&msc->ko_root, &mpam_msc_info_attr_group); + if (ret) + goto err_info_grp; + + for (part = 0; part < partid_count; part++) { + kobject_init(&msc->ko_parts[part].kobj, &mpam_kobj_ktype); + msc->ko_parts[part].msc = msc; + msc->ko_parts[part].partid = part; + + ret = kobject_add(&msc->ko_parts[part].kobj, &msc->ko_part_dir, "%d", part); + if (ret) + goto err_parts_add; + } + + for (part = 0; part < partid_count; part++) { + ret = sysfs_create_group(&msc->ko_parts[part].kobj, &mpam_msc_ctrl_attr_group); + if (ret) + goto err_parts_grp; + } + return 0; + +err_parts_grp: + for (tmp = 0; tmp < part; tmp++) + sysfs_remove_group(&msc->ko_parts[part].kobj, &mpam_msc_ctrl_attr_group); + part = partid_count - 1; + +err_parts_add: + for (tmp = 0; tmp < part; tmp++) + kobject_put(&msc->ko_parts[tmp].kobj); + + sysfs_remove_group(&msc->ko_root, &mpam_msc_info_attr_group); + +err_info_grp: + devm_kfree(&msc->pdev->dev, msc->ko_parts); +err_part_dir: + kobject_put(&msc->ko_part_dir); +err_root: + kobject_put(&msc->ko_root); + return ret; +} + +static void mpam_msc_cmax_shift_set(struct mpam_msc *msc) +{ + u16 val; + /* + * Note: The TRM says the implemented bits are the most significant ones, + * but the model doesn't seem to agree with it... + * Handle that in the background, dropping a warning case needed + */ + lockdep_assert_held(&msc->lock); + + if (!(msc->cmax_nbits < 16)) + return; + /* + * Unimplemented bits within the field are RAZ/WI + * At this point the MPAM_CMAX.CMAX will not be adjusted with the shift + * so this operates on an unmodified reg content. + * Also, the default value for CMAX will be set further down the init + * so there is no need for reset here. + */ + mpam_msc_set_cmax(msc, MPAM_PARTID_DEFAULT, GENMASK(15, 0)); + val = mpam_msc_get_cmax(msc, MPAM_PARTID_DEFAULT); + + if (val & GENMASK(15 - msc->cmax_nbits, 0)) { + msc->cmax_shift = 16 - msc->cmax_nbits; + pr_warn("MPAM_CMAX: implemented bits are the least-significant ones!"); + } +} + +static int mpam_msc_initialize(struct mpam_msc *msc) +{ + static unsigned long *bitmap; + int partid; + u64 reg; + + /* + * We're using helpers that expect the lock to be held, but we're + * setting things up and there is no interface yet, so nothing can + * race with us. Make lockdep happy, and save ourselves from a couple + * of lock/unlock. + */ + spin_acquire(&msc->lock.dep_map, 0, 0, _THIS_IP_); + + reg = readq_relaxed(msc->base + MPAMF_IDR); + + msc->has_cpor = FIELD_GET(MPAMF_IDR_HAS_CPOR_PART, reg); + msc->has_ccap = FIELD_GET(MPAMF_IDR_HAS_CCAP_PART, reg); + pr_err("%s %d msc->has_cpor = 0x%x msc->has_ccap = 0x%x msc->part_feats = 0x%x\n", __func__, __LINE__, msc->has_cpor, msc->has_ccap, msc->part_feats); + /* Detect more features here */ + + if (!msc->part_feats) { + pr_err("MSC does not support any recognized partitionning feature\n"); + return -EOPNOTSUPP; + } + + /* Check for features that aren't supported, disable those we can */ + if (FIELD_GET(MPAMF_IDR_HAS_PRI_PART, reg)) { + pr_err("Priority partitionning present but not supported\n"); + return -EOPNOTSUPP; + } + + msc->has_ris = FIELD_GET(MPAMF_IDR_HAS_RIS, reg); + if (msc->has_ris) + pr_warn("RIS present but not supported, only instance 0 will be used\n"); + + /* Error interrupts aren't handled */ + reg = readl_relaxed(msc->base + MPAMF_ECR); + FIELD_SET(reg, MPAMF_ECR_INTEN, 0); + writel_relaxed(reg, msc->base + MPAMF_ECR); + + msc->partid_count = mpam_msc_get_partid_max(msc) + 1; + pr_debug("%d partitions supported\n", msc->partid_count); + if (msc->partid_count > mpam_partid_count) + pr_debug("System limited to %d partitions\n", mpam_partid_count); + + reg = readl_relaxed(msc->base + MPAMF_CPOR_IDR); + msc->cpbm_nbits = FIELD_GET(MPAMF_CPOR_IDR_CPBM_WD, reg); + pr_debug("%d portions supported\n", msc->cpbm_nbits); + + reg = readl_relaxed(msc->base + MPAMF_CCAP_IDR); + msc->cmax_nbits = FIELD_GET(MPAMF_CCAP_IDR_CMAX_WD, reg); + mpam_msc_cmax_shift_set(msc); + + bitmap = bitmap_alloc(mpam_partid_count, GFP_KERNEL); + if (!bitmap) + return -ENOMEM; + + /* + * Make all partitions have a sane default setting. The reference manual + * "suggests" sane defaults, be paranoid. + */ + bitmap_fill(bitmap, mpam_partid_count); + for (partid = 0; partid < mpam_partid_count; partid++) { + mpam_msc_set_cpbm(msc, partid, bitmap); + mpam_msc_set_cmax(msc, partid, + GENMASK(15, 15 - (msc->cmax_nbits -1))); + } + bitmap_free(bitmap); + + spin_release(&msc->lock.dep_map, _THIS_IP_); + + return mpam_msc_create_sysfs(msc); +} + +static int mpam_probe(struct platform_device *pdev) +{ + struct mpam_msc *msc; + struct resource *mem; + void __iomem *base; + int ret; + + msc = devm_kzalloc(&pdev->dev, sizeof(*msc), GFP_KERNEL); + if (!msc) + return -ENOMEM; + + msc->pdev = pdev; + + base = devm_platform_get_and_ioremap_resource(pdev, 0, &mem); + if (IS_ERR(base)) { + devm_kfree(&pdev->dev, msc); + return PTR_ERR(base); + } + + msc->base = base; + spin_lock_init(&msc->lock); + platform_set_drvdata(pdev, msc); + + ret = mpam_msc_initialize(msc); + + return ret; +} + +static const struct of_device_id of_mpam_match[] = { + { + .compatible = "arm,mpam-msc" + }, + { /* end */ }, +}; + +static struct platform_driver mpam_arch_driver = { + .probe = mpam_probe, + .driver = { + .name = "mpam", + .of_match_table = of_mpam_match + }, +}; + +static int __init mpam_arch_driver_init(void) +{ + int ret; + + /* Does the system support MPAM at all? */ + ret = mpam_validate_sys(); + if (ret) + return -EOPNOTSUPP; + + return platform_driver_register(&mpam_arch_driver); +} + +module_init(mpam_arch_driver_init); diff --git a/drivers/android/mpam_arch.h b/drivers/android/mpam_arch.h new file mode 100644 index 000000000000..c27b0bfa2a06 --- /dev/null +++ b/drivers/android/mpam_arch.h @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: GPL-2.0+ +#ifndef MPAM_ARCH_H +#define MPAM_ARCH_H + +#define MPAM_PARTID_DEFAULT 0 + +extern void mpam_write_partid(unsigned int partid); +extern unsigned int mpam_get_partid_count(void); + +#endif \ No newline at end of file diff --git a/drivers/android/mpam_arch_internal.h b/drivers/android/mpam_arch_internal.h new file mode 100644 index 000000000000..5bf0fd0a2e79 --- /dev/null +++ b/drivers/android/mpam_arch_internal.h @@ -0,0 +1,54 @@ +// SPDX-License-Identifier: GPL-2.0+ +#ifndef MPAM_ARCH_INTERNAL_H +#define MPAM_ARCH_INTERNAL_H + +#define ID_AA64PFR0_MPAM BIT(40) + +#define MPAMF_IDR 0x0000 +#define MPAMF_CPOR_IDR 0x0030 +#define MPAMF_CCAP_IDR 0x0038 +#define MPAMF_ECR 0x00F0 + +#define MPAMCFG_PART_SEL 0x0100 +#define MPAMCFG_CMAX 0x0108 +#define MPAMCFG_CPBM_n 0x1000 + +/* Sysregs */ + +/* MPAM0_EL1 */ +#define MPAM0_EL1_PARTID_I GENMASK(15, 0) +#define MPAM0_EL1_PARTID_D GENMASK(31, 16) + +/* MPAM1_EL1 */ +#define MPAM1_EL1_PARTID_I GENMASK(15, 0) +#define MPAM1_EL1_PARTID_D GENMASK(31, 16) +#define MPAM1_EL1_MPAMEN BIT(63) + +/* MPAMIDR_EL1 */ +#define MPAMIDR_EL1_PARTID_MAX GENMASK(15, 0) + +/* MSC MMRs */ + +/* MPAMF_IDR */ +#define MPAMF_IDR_PARTID_MAX GENMASK(15, 0) +#define MPAMF_IDR_HAS_CCAP_PART BIT(24) +#define MPAMF_IDR_HAS_CPOR_PART BIT(25) +#define MPAMF_IDR_HAS_PRI_PART BIT(27) +#define MPAMF_IDR_HAS_RIS GENMASK(32, 31) + +/* MPAMF_CPOR_IDR */ +#define MPAMF_CPOR_IDR_CPBM_WD GENMASK(15, 0) + +/* MPMAMF_CCAP_IDR */ +#define MPAMF_CCAP_IDR_CMAX_WD GENMASK(5, 0) + +/* MPAMF_ECR */ +#define MPAMF_ECR_INTEN BIT(0) + +/* MPAMCFG_PART_SEL */ +#define MPAMCFG_PART_SEL_PARTID_SEL GENMASK(15, 0) +#define MPAMCFG_PART_SEL_RIS GENMASK(27, 24) + +#define MPAMCFG_CMAX_CMAX GENMASK(15, 0) + +#endif \ No newline at end of file diff --git a/drivers/base/cpu.c b/drivers/base/cpu.c index ef427ee787a9..9176f5fb6d7a 100644 --- a/drivers/base/cpu.c +++ b/drivers/base/cpu.c @@ -400,6 +400,7 @@ int register_cpu(struct cpu *cpu, int num) cpu->dev.offline_disabled = !cpu->hotpluggable; cpu->dev.offline = !cpu_online(num); cpu->dev.of_node = of_get_cpu_node(num, NULL); + cpu->dev.fwnode = of_fwnode_handle(cpu->dev.of_node); cpu->dev.groups = common_cpu_attr_groups; if (cpu->hotpluggable) cpu->dev.groups = hotplugable_cpu_attr_groups; diff --git a/drivers/base/power/domain.c b/drivers/base/power/domain.c index d9d339b8b571..3c27b37da911 100644 --- a/drivers/base/power/domain.c +++ b/drivers/base/power/domain.c @@ -22,6 +22,7 @@ #include #include #include +#include #include "power.h" @@ -130,6 +131,7 @@ static const struct genpd_lock_ops genpd_spin_ops = { #define genpd_is_active_wakeup(genpd) (genpd->flags & GENPD_FLAG_ACTIVE_WAKEUP) #define genpd_is_cpu_domain(genpd) (genpd->flags & GENPD_FLAG_CPU_DOMAIN) #define genpd_is_rpm_always_on(genpd) (genpd->flags & GENPD_FLAG_RPM_ALWAYS_ON) +#define genpd_is_opp_table_fw(genpd) (genpd->flags & GENPD_FLAG_OPP_TABLE_FW) static inline bool irq_safe_dev_in_sleep_domain(struct device *dev, const struct generic_pm_domain *genpd) @@ -2329,7 +2331,7 @@ int of_genpd_add_provider_simple(struct device_node *np, genpd->dev.of_node = np; /* Parse genpd OPP table */ - if (genpd->set_performance_state) { + if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { ret = dev_pm_opp_of_add_table(&genpd->dev); if (ret) return dev_err_probe(&genpd->dev, ret, "Failed to add OPP table\n"); @@ -2344,7 +2346,7 @@ int of_genpd_add_provider_simple(struct device_node *np, ret = genpd_add_provider(np, genpd_xlate_simple, genpd); if (ret) { - if (genpd->set_performance_state) { + if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { dev_pm_opp_put_opp_table(genpd->opp_table); dev_pm_opp_of_remove_table(&genpd->dev); } @@ -2388,7 +2390,7 @@ int of_genpd_add_provider_onecell(struct device_node *np, genpd->dev.of_node = np; /* Parse genpd OPP table */ - if (genpd->set_performance_state) { + if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); if (ret) { dev_err_probe(&genpd->dev, ret, @@ -2424,7 +2426,7 @@ error: genpd->provider = NULL; genpd->has_provider = false; - if (genpd->set_performance_state) { + if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { dev_pm_opp_put_opp_table(genpd->opp_table); dev_pm_opp_of_remove_table(&genpd->dev); } @@ -2456,7 +2458,7 @@ void of_genpd_del_provider(struct device_node *np) if (gpd->provider == &np->fwnode) { gpd->has_provider = false; - if (!gpd->set_performance_state) + if (genpd_is_opp_table_fw(gpd) || !gpd->set_performance_state) continue; dev_pm_opp_put_opp_table(gpd->opp_table); @@ -2657,7 +2659,8 @@ EXPORT_SYMBOL_GPL(of_genpd_remove_last); static void genpd_release_dev(struct device *dev) { - of_node_put(dev->of_node); + fwnode_handle_put(dev->fwnode); + kfree(dev); } @@ -3374,6 +3377,90 @@ DEFINE_SHOW_ATTRIBUTE(total_idle_time); DEFINE_SHOW_ATTRIBUTE(devices); DEFINE_SHOW_ATTRIBUTE(perf_state); +#ifdef CONFIG_ARCH_CIX +static ssize_t genpd_control_store(struct file *file, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct generic_pm_domain *genpd = file->private_data; + int ret; + char *input; + unsigned int on = 0; + + input = kzalloc(count, GFP_KERNEL); + if (!input) { + kfree(input); + return -ENOMEM; + } + if (copy_from_user(input, buffer, count)) { + kfree(input); + return -EFAULT; + } + + ret = kstrtouint(input, 0, &on); + if (ret) { + kfree(input); + return -EINVAL; + } + + if (on) + genpd_power_on(genpd, 0); + else + genpd_power_off(genpd, true, 0); + + kfree(input); + return count; +} + +static const struct file_operations genpd_control_fops = { + .open = simple_open, + .write = genpd_control_store, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; + +static ssize_t genpd_always_on_store(struct file *file, + const char __user *buffer, + size_t count, loff_t *ppos) +{ + struct generic_pm_domain *genpd = file->private_data; + int ret; + char *input; + unsigned int flags = 0; + + input = kzalloc(count, GFP_KERNEL); + if (!input) { + kfree(input); + return -ENOMEM; + } + if (copy_from_user(input, buffer, count)) { + kfree(input); + return -EFAULT; + } + + ret = kstrtouint(input, 0, &flags); + if (ret) { + kfree(input); + return -EINVAL; + } + + if (flags) + genpd->flags |= GENPD_FLAG_ALWAYS_ON; + else + genpd->flags &= (~GENPD_FLAG_ALWAYS_ON); + + kfree(input); + return count; +} + +static const struct file_operations genpd_always_on_fops = { + .open = simple_open, + .write = genpd_always_on_store, + .owner = THIS_MODULE, + .llseek = default_llseek, +}; +#endif + static void genpd_debug_add(struct generic_pm_domain *genpd) { struct dentry *d; @@ -3395,6 +3482,10 @@ static void genpd_debug_add(struct generic_pm_domain *genpd) d, genpd, &total_idle_time_fops); debugfs_create_file("devices", 0444, d, genpd, &devices_fops); +#ifdef CONFIG_ARCH_CIX + debugfs_create_file("on", 044, d, genpd, &genpd_control_fops); + debugfs_create_file("always_on", 044, d, genpd, &genpd_always_on_fops); +#endif if (genpd->set_performance_state) debugfs_create_file("perf_state", 0444, d, genpd, &perf_state_fops); @@ -3422,3 +3513,344 @@ static void __exit genpd_debug_exit(void) } __exitcall(genpd_debug_exit); #endif /* CONFIG_DEBUG_FS */ + +#ifdef CONFIG_ARM_SCMI_SUPPORT_DT_ACPI +struct fwnode_genpd_provider { + struct list_head link; + struct fwnode_handle *fwnode; + fwnode_genpd_xlate_t xlate; + void *data; +}; + +/* List of registered PM domain providers. */ +static LIST_HEAD(fwnode_genpd_providers); +/* Mutex to protect the list above. */ +static DEFINE_MUTEX(fwnode_genpd_mutex); + +static struct generic_pm_domain *fwnode_genpd_xlate_onecell( + struct fwnode_reference_args *fwnode_args, + void *data) +{ + struct genpd_onecell_data *genpd_data = data; + unsigned int idx = fwnode_args->args[0]; + + if (fwnode_args->nargs != 1) + return ERR_PTR(-EINVAL); + + if (idx >= genpd_data->num_domains) { + pr_err("%s: invalid domain index %u\n", __func__, idx); + return ERR_PTR(-EINVAL); + } + + if (!genpd_data->domains[idx]) + return ERR_PTR(-ENOENT); + + return genpd_data->domains[idx]; +} + +static int fwnode_genpd_add_provider(struct fwnode_handle *np, fwnode_genpd_xlate_t xlate, + void *data) +{ + struct fwnode_genpd_provider *cp; + + cp = kzalloc(sizeof(*cp), GFP_KERNEL); + if (!cp) + return -ENOMEM; + + cp->fwnode = fwnode_handle_get(np); + cp->data = data; + cp->xlate = xlate; + fwnode_dev_initialized(np, true); + + mutex_lock(&fwnode_genpd_mutex); + list_add(&cp->link, &fwnode_genpd_providers); + mutex_unlock(&fwnode_genpd_mutex); + + return 0; +} + +int fwnode_genpd_add_provider_onecell(struct fwnode_handle *np, + struct genpd_onecell_data *data) +{ + struct generic_pm_domain *genpd; + unsigned int i; + int ret = -EINVAL; + + if (!np || !data) + return -EINVAL; + + if (!data->fwnode_xlate) + data->fwnode_xlate = fwnode_genpd_xlate_onecell; + + for (i = 0; i < data->num_domains; i++) { + genpd = data->domains[i]; + + if (!genpd) + continue; + if (!genpd_present(genpd)) + goto error; + + genpd->dev.fwnode = np; + + /* Parse genpd OPP table */ + + if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { + ret = dev_pm_opp_of_add_table_indexed(&genpd->dev, i); + if (ret) { + dev_err_probe(&genpd->dev, ret, + "Failed to add OPP table for index %d\n", i); + goto error; + } + + /* + * Save table for faster processing while setting + * performance state. + */ + genpd->opp_table = dev_pm_opp_get_opp_table(&genpd->dev); + WARN_ON(IS_ERR(genpd->opp_table)); + } + + genpd->provider = np; + genpd->has_provider = true; + } + + ret = fwnode_genpd_add_provider(np, data->fwnode_xlate, data); + if (ret < 0) + goto error; + + return 0; + +error: + while (i--) { + genpd = data->domains[i]; + + if (!genpd) + continue; + + genpd->provider = NULL; + genpd->has_provider = false; + + if (!genpd_is_opp_table_fw(genpd) && genpd->set_performance_state) { + dev_pm_opp_put_opp_table(genpd->opp_table); + dev_pm_opp_of_remove_table(&genpd->dev); + } + } + + return ret; +} +EXPORT_SYMBOL_GPL(fwnode_genpd_add_provider_onecell); + +void fwnode_genpd_del_provider(struct fwnode_handle *fwnode) +{ + struct fwnode_genpd_provider *cp, *tmp; + struct generic_pm_domain *gpd; + + mutex_lock(&gpd_list_lock); + mutex_lock(&fwnode_genpd_mutex); + list_for_each_entry_safe(cp, tmp, &fwnode_genpd_providers, link) { + if (cp->fwnode == fwnode) { + /* + * For each PM domain associated with the + * provider, set the 'has_provider' to false + * so that the PM domain can be safely removed. + */ + list_for_each_entry(gpd, &gpd_list, gpd_list_node) { + if (gpd->provider == fwnode) { + gpd->has_provider = false; + + if (genpd_is_opp_table_fw(gpd) || !gpd->set_performance_state) + continue; + + dev_pm_opp_put_opp_table(gpd->opp_table); + dev_pm_opp_of_remove_table(&gpd->dev); + } + } + + fwnode_dev_initialized(cp->fwnode, false); + list_del(&cp->link); + fwnode_handle_put(cp->fwnode); + kfree(cp); + break; + } + } + mutex_unlock(&fwnode_genpd_mutex); + mutex_unlock(&gpd_list_lock); +} +EXPORT_SYMBOL_GPL(fwnode_genpd_del_provider); + +static struct generic_pm_domain *fwnode_genpd_get_from_provider( + struct fwnode_reference_args *fwnode_args) +{ + struct generic_pm_domain *genpd = ERR_PTR(-ENOENT); + struct fwnode_genpd_provider *provider; + + if (!fwnode_args) + return ERR_PTR(-EINVAL); + + mutex_lock(&fwnode_genpd_mutex); + /* Check if we have such a provider in our array */ + list_for_each_entry(provider, &fwnode_genpd_providers, link) { + if (provider->fwnode == fwnode_args->fwnode) { + genpd = provider->xlate(fwnode_args, provider->data); + } + + if (!IS_ERR(genpd)) + break; + } + mutex_unlock(&fwnode_genpd_mutex); + + return genpd; +} + +static int __fwnode_genpd_dev_pm_attach(struct device *dev, struct device *base_dev, + unsigned int index, bool power_on) +{ + struct fwnode_reference_args fwnode_args; + struct generic_pm_domain *pd; + int pstate; + int ret; + + if (!dev->fwnode) + return -ENOENT; + + ret = fwnode_property_get_reference_args(dev->fwnode, "power-domains", "#power-domain-cells", + 1, index, &fwnode_args); + + if (ret < 0) + return ret; + + mutex_lock(&gpd_list_lock); + + pd = fwnode_genpd_get_from_provider(&fwnode_args); + + fwnode_handle_put(fwnode_args.fwnode); + + if (IS_ERR(pd)) { + mutex_unlock(&gpd_list_lock); + dev_dbg(dev, "%s() failed to find PM domain: %ld\n", + __func__, PTR_ERR(pd)); + return driver_deferred_probe_check_state(base_dev); + } + + dev_dbg(dev, "adding to PM domain %s\n", pd->name); + + ret = genpd_add_device(pd, dev, base_dev); + mutex_unlock(&gpd_list_lock); + + if (ret < 0) + return dev_err_probe(dev, ret, "failed to add to PM domain %s\n", pd->name); + + dev->pm_domain->detach = genpd_dev_pm_detach; + dev->pm_domain->sync = genpd_dev_pm_sync; + + /* Set the default performance state */ + pstate = of_get_required_opp_performance_state(dev->of_node, index); + if (pstate < 0 && pstate != -ENODEV && pstate != -EOPNOTSUPP) { + ret = pstate; + goto err; + } else if (pstate > 0) { + ret = dev_pm_genpd_set_performance_state(dev, pstate); + if (ret) + goto err; + dev_gpd_data(dev)->default_pstate = pstate; + } + + if (power_on) { + genpd_lock(pd); + ret = genpd_power_on(pd, 0); + genpd_unlock(pd); + } + + if (ret) { + /* Drop the default performance state */ + if (dev_gpd_data(dev)->default_pstate) { + dev_pm_genpd_set_performance_state(dev, 0); + dev_gpd_data(dev)->default_pstate = 0; + } + + genpd_remove_device(pd, dev); + return -EPROBE_DEFER; + } + + return 1; + +err: + dev_err(dev, "failed to set required performance state for power-domain %s: %d\n", + pd->name, ret); + genpd_remove_device(pd, dev); + return ret; +} + +struct device *fwnode_genpd_dev_pm_attach_by_id(struct device *dev, + unsigned int index) +{ + struct device *virt_dev; + int num_domains; + int ret; + + if (!dev->fwnode) + return NULL; + + /* Verify that the index is within a valid range. */ + num_domains = fwnode_count_reference_with_args(dev->fwnode, "power-domains", "#power-domain-cells"); + if (index >= num_domains) + return NULL; + + /* Allocate and register device on the genpd bus. */ + virt_dev = kzalloc(sizeof(*virt_dev), GFP_KERNEL); + if (!virt_dev) + return ERR_PTR(-ENOMEM); + + dev_set_name(virt_dev, "genpd:%u:%s", index, dev_name(dev)); + virt_dev->bus = &genpd_bus_type; + virt_dev->release = genpd_release_dev; + virt_dev->fwnode = fwnode_handle_get(dev->fwnode); + + if (!has_acpi_companion(dev)) { + virt_dev->of_node = of_node_get(dev->of_node); + } + + ret = device_register(virt_dev); + if (ret) { + put_device(virt_dev); + return ERR_PTR(ret); + } + + /* Try to attach the device to the PM domain at the specified index. */ + ret = __fwnode_genpd_dev_pm_attach(virt_dev, dev, index, false); + if (ret < 1) { + device_unregister(virt_dev); + return ret ? ERR_PTR(ret) : NULL; + } + + pm_runtime_enable(virt_dev); + genpd_queue_power_off_work(dev_to_genpd(virt_dev)); + + return virt_dev; +} +EXPORT_SYMBOL_GPL(fwnode_genpd_dev_pm_attach_by_id); + +struct device *fwnode_genpd_dev_pm_attach_by_name(struct device *dev, const char *name) +{ + int index; + if (!dev->fwnode) + return NULL; + + index = fwnode_property_match_string(dev_fwnode(dev), "power-domain-names", name); + + if (index < 0) + return NULL; + + return fwnode_genpd_dev_pm_attach_by_id(dev, index); +} + +struct device *fwnode_dev_pm_domain_attach_by_name(struct device *dev, + const char *name) +{ + if (!has_acpi_companion(dev) && dev->pm_domain) + return ERR_PTR(-EEXIST); + + return fwnode_genpd_dev_pm_attach_by_name(dev, name); +} +EXPORT_SYMBOL_GPL(fwnode_dev_pm_domain_attach_by_name); +#endif diff --git a/drivers/base/power/runtime.c b/drivers/base/power/runtime.c index 0af26cf8c005..2011af22731d 100644 --- a/drivers/base/power/runtime.c +++ b/drivers/base/power/runtime.c @@ -923,6 +923,10 @@ static int rpm_resume(struct device *dev, int rpmflags) } wake_up_all(&dev->power.wait_queue); +#ifdef CONFIG_ARCH_CIX + if (retval == -ETIMEDOUT || retval == -EAGAIN) + dev->power.runtime_error = 0; +#endif if (retval >= 0) rpm_idle(dev, RPM_ASYNC); diff --git a/drivers/base/property.c b/drivers/base/property.c index 8c40abed7852..80e146ef05b4 100644 --- a/drivers/base/property.c +++ b/drivers/base/property.c @@ -543,6 +543,16 @@ int fwnode_property_get_reference_args(const struct fwnode_handle *fwnode, } EXPORT_SYMBOL_GPL(fwnode_property_get_reference_args); +int fwnode_count_reference_with_args(const struct fwnode_handle *fwnode, + const char *list_name, const char *cells_name) { + + if (IS_ERR_OR_NULL(fwnode)) + return -ENOENT; + + return fwnode_call_int_op(fwnode, property_count_reference_with_args, list_name, cells_name); +} +EXPORT_SYMBOL_GPL(fwnode_count_reference_with_args); + /** * fwnode_find_reference - Find named reference to a fwnode_handle * @fwnode: Firmware node where to look for the reference diff --git a/drivers/bluetooth/Kconfig b/drivers/bluetooth/Kconfig index bc211c324206..0e950a943739 100644 --- a/drivers/bluetooth/Kconfig +++ b/drivers/bluetooth/Kconfig @@ -56,6 +56,12 @@ config BT_HCIBTUSB_POLL_SYNC Say Y here to enable USB poll_sync for Bluetooth USB devices by default. +config BT_RTKBTUSB + tristate "RTK HCI USB driver" + depends on USB + help + RTK Bluetooth HCI USB driver + config BT_HCIBTUSB_BCM bool "Broadcom protocol support" depends on BT_HCIBTUSB diff --git a/drivers/bluetooth/Makefile b/drivers/bluetooth/Makefile index 7a5967e9ac48..5ed32810d664 100644 --- a/drivers/bluetooth/Makefile +++ b/drivers/bluetooth/Makefile @@ -34,6 +34,7 @@ obj-$(CONFIG_BT_NXPUART) += btnxpuart.o obj-$(CONFIG_BT_HCIUART_NOKIA) += hci_nokia.o obj-$(CONFIG_BT_HCIRSI) += btrsi.o +obj-$(CONFIG_BT_RTKBTUSB) += rtk_btusb.o btmrvl-y := btmrvl_main.o btmrvl-$(CONFIG_DEBUG_FS) += btmrvl_debugfs.o diff --git a/drivers/bluetooth/rtk_btusb.c b/drivers/bluetooth/rtk_btusb.c new file mode 100644 index 000000000000..b7d941564af8 --- /dev/null +++ b/drivers/bluetooth/rtk_btusb.c @@ -0,0 +1,4881 @@ +/* + * + * Realtek Bluetooth USB driver + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#include "rtk_btusb.h" + +#define RTKBT_RELEASE_NAME "20220111_BT_ANDROID_11.0" +#define VERSION "5.2.1" + +#define SUSPNED_DW_FW 0 +#define SET_WAKEUP_DEVICE 0 + + +static spinlock_t queue_lock; +static spinlock_t running_flag_lock; +static volatile uint16_t driver_state = 0; + +#if SUSPNED_DW_FW +static firmware_info *fw_info_4_suspend = NULL; +#endif + +static uint32_t usb_info; + +static patch_info fw_patch_table[] = { +/* { vid, pid, lmp_sub_default, lmp_sub, everion, mp_fw_name, fw_name, config_name, fw_cache, fw_len, mac_offset } */ +{ 0x0BDA, 0x1724, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723A */ +{ 0x0BDA, 0x8723, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE */ +{ 0x0BDA, 0xA723, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE for LI */ +{ 0x0BDA, 0x0723, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE */ +{ 0x13D3, 0x3394, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AE for Azurewave*/ + +{ 0x0BDA, 0x0724, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AU */ +{ 0x0BDA, 0x8725, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AU */ +{ 0x0BDA, 0x872A, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AU */ +{ 0x0BDA, 0x872B, 0x1200, 0, 0, "mp_rtl8723a_fw", "rtl8723a_fw", "rtl8723a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* 8723AU */ + +{ 0x0BDA, 0xb720, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723bu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BU */ +{ 0x0BDA, 0xb72A, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723bu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BU */ +{ 0x0BDA, 0xb728, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE for LC */ +{ 0x0BDA, 0xb723, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE */ +{ 0x0BDA, 0xb72B, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE */ +{ 0x0BDA, 0xb001, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE for HP */ +{ 0x0BDA, 0xb002, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE */ +{ 0x0BDA, 0xb003, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE */ +{ 0x0BDA, 0xb004, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE */ +{ 0x0BDA, 0xb005, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE */ + +{ 0x13D3, 0x3410, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE for Azurewave */ +{ 0x13D3, 0x3416, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE for Azurewave */ +{ 0x13D3, 0x3459, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE for Azurewave */ +{ 0x0489, 0xE085, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE for Foxconn */ +{ 0x0489, 0xE08B, 0x8723, 0, 0, "mp_rtl8723b_fw", "rtl8723b_fw", "rtl8723b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8723BE for Foxconn */ + +{ 0x0BDA, 0x2850, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761au_fw", "rtl8761a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AU */ +{ 0x0BDA, 0xA761, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761au_fw", "rtl8761a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AU only */ +{ 0x0BDA, 0x818B, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761aw8192eu_fw", "rtl8761aw8192eu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AW + 8192EU */ +{ 0x0BDA, 0x818C, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761aw8192eu_fw", "rtl8761aw8192eu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AW + 8192EU */ +{ 0x0BDA, 0x8760, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761au8192ee_fw", "rtl8761a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AU + 8192EE */ +{ 0x0BDA, 0xB761, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761au_fw", "rtl8761a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AUV only */ +{ 0x0BDA, 0x8761, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761au8192ee_fw", "rtl8761a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AU + 8192EE for LI */ +{ 0x0BDA, 0x8A60, 0x8761, 0, 0, "mp_rtl8761a_fw", "rtl8761au8812ae_fw", "rtl8761a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8761AU + 8812AE */ +{ 0x0BDA, 0x8771, 0x8761, 0, 0, "mp_rtl8761b_fw", "rtl8761b_fw", "rtl8761b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8761BU */ +{ 0x0BDA, 0xa725, 0x8761, 0, 0, "mp_rtl8725a_fw", "rtl8725a_fw", "rtl8725a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8725AU */ +{ 0x0BDA, 0xa72A, 0x8761, 0, 0, "mp_rtl8725a_fw", "rtl8725a_fw", "rtl8725a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8725AU BT only */ + +{ 0x0BDA, 0x8821, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ +{ 0x0BDA, 0x0821, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ +{ 0x0BDA, 0x0823, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AU */ +{ 0x13D3, 0x3414, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ +{ 0x13D3, 0x3458, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ +{ 0x13D3, 0x3461, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ +{ 0x13D3, 0x3462, 0x8821, 0, 0, "mp_rtl8821a_fw", "rtl8821a_fw", "rtl8821a_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_1_2, MAX_PATCH_SIZE_24K}, /* RTL8821AE */ + +{ 0x0BDA, 0xB822, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_25K}, /* RTL8822BE */ +{ 0x0BDA, 0xB82C, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_25K}, /* RTL8822BU */ +{ 0x0BDA, 0xB81D, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_25K}, /* RTL8822BU BT only */ +{ 0x0BDA, 0xB82E, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_25K}, /* RTL8822BU-VN */ +{ 0x0BDA, 0xB023, 0x8822, 0, 0, "mp_rtl8822b_fw", "rtl8822b_fw", "rtl8822b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_25K}, /* RTL8822BE */ +{ 0x0BDA, 0xB703, 0x8703, 0, 0, "mp_rtl8723c_fw", "rtl8723c_fw", "rtl8723c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_24K}, /* RTL8723CU */ +/* todo: RTL8703BU */ + +{ 0x0BDA, 0xD723, 0x8723, 0, 0, "mp_rtl8723d_fw", "rtl8723d_fw", "rtl8723d_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723DU */ +{ 0x0BDA, 0xD72A, 0x8723, 0, 0, "mp_rtl8723d_fw", "rtl8723d_fw", "rtl8723d_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723DU BT only */ +{ 0x0BDA, 0xD720, 0x8723, 0, 0, "mp_rtl8723d_fw", "rtl8723d_fw", "rtl8723d_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723DE */ +{ 0x0BDA, 0xB733, 0x8723, 0, 0, "mp_rtl8733b_fw", "rtl8733b_fw", "rtl8733b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723FU */ +{ 0x0BDA, 0xB73A, 0x8723, 0, 0, "mp_rtl8733b_fw", "rtl8733b_fw", "rtl8733b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723FU */ +{ 0x0BDA, 0xF72B, 0x8723, 0, 0, "mp_rtl8733b_fw", "rtl8733b_fw", "rtl8733b_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8723FU */ +{ 0x0BDA, 0xB820, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8821CU */ +{ 0x0BDA, 0xC820, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8821CU */ +{ 0x0BDA, 0xC82A, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8821CU BT only */ +{ 0x0BDA, 0xC821, 0x8821, 0, 0, "mp_rtl8821c_fw", "rtl8821c_fw", "rtl8821c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_3PLUS, MAX_PATCH_SIZE_40K}, /* RTL8821CE */ +/* todo: RTL8703CU */ +{ 0x0BDA, 0xC82C, 0x8822, 0, 0, "mp_rtl8822c_fw", "rtl8822c_fw", "rtl8822c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8822CU */ +{ 0x0BDA, 0xC82E, 0x8822, 0, 0, "mp_rtl8822c_fw", "rtl8822c_fw", "rtl8822c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8822CU-VN */ +{ 0x0BDA, 0xC81D, 0x8822, 0, 0, "mp_rtl8822c_fw", "rtl8822c_fw", "rtl8822c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8822CU BT only */ +{ 0x0BDA, 0xC82F, 0x8822, 0, 0, "mp_rtl8822c_fw", "rtl8822c_fw", "rtl8822c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8822CE-VS */ +{ 0x0BDA, 0xC822, 0x8822, 0, 0, "mp_rtl8822c_fw", "rtl8822c_fw", "rtl8822c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8822CE */ +{ 0x0BDA, 0xB00C, 0x8822, 0, 0, "mp_rtl8822c_fw", "rtl8822c_fw", "rtl8822c_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /* RTL8822CE */ +{ 0x0BDA, 0x885A, 0x8852, 0, 0, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", NULL, 0,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852AU */ +{ 0x0BDA, 0x8852, 0x8852, 0, 0, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", NULL, 0,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852AE */ +{ 0x0BDA, 0x885C, 0x8852, 0, 0, "mp_rtl8852au_fw", "rtl8852au_fw", "rtl8852au_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852AU */ +{ 0x0BDA, 0xB852, 0x8852, 0, 0, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852B */ +{ 0x0BDA, 0xA85B, 0x8852, 0, 0, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852B */ +{ 0x13D3, 0x3570, 0x8852, 0, 0, "mp_rtl8852bu_fw", "rtl8852bu_fw", "rtl8852bu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852B */ +{ 0x0BDA, 0xC85A, 0x8852, 0, 0, "mp_rtl8852cu_fw", "rtl8852cu_fw", "rtl8852cu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852C */ +{ 0x0BDA, 0xA85C, 0x8852, 0, 0, "mp_rtl8852bpu_fw", "rtl8852bpu_fw", "rtl8852bpu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852BP */ +{ 0x0BDA, 0xA850, 0x8852, 0, 0, "mp_rtl8852bpu_fw", "rtl8852bpu_fw", "rtl8852bpu_config", NULL, 0 ,CONFIG_MAC_OFFSET_GEN_4PLUS, MAX_PATCH_SIZE_40K}, /*RTL8852BPE */ + +/* NOTE: must append patch entries above the null entry */ +{ 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL, 0, 0, 0 } +}; + +struct btusb_data { + struct hci_dev *hdev; + struct usb_device *udev; + struct usb_interface *intf; + struct usb_interface *isoc; + + spinlock_t lock; + + unsigned long flags; + + struct work_struct work; + struct work_struct waker; + + struct usb_anchor tx_anchor; + struct usb_anchor intr_anchor; + struct usb_anchor bulk_anchor; + struct usb_anchor isoc_anchor; + struct usb_anchor deferred; + int tx_in_flight; + spinlock_t txlock; + + struct usb_endpoint_descriptor *intr_ep; + struct usb_endpoint_descriptor *bulk_tx_ep; + struct usb_endpoint_descriptor *bulk_rx_ep; + struct usb_endpoint_descriptor *isoc_tx_ep; + struct usb_endpoint_descriptor *isoc_rx_ep; + + __u8 cmdreq_type; + + unsigned int sco_num; + int isoc_altsetting; + int suspend_count; + uint16_t sco_handle; +//#ifdef CONFIG_HAS_EARLYSUSPEND +#if 0 + struct early_suspend early_suspend; +#else + struct notifier_block pm_notifier; + struct notifier_block reboot_notifier; +#endif + firmware_info *fw_info; + +#ifdef CONFIG_SCO_OVER_HCI + RTK_sco_card_t *pSCOSnd; +#endif +}; + +int download_patch(firmware_info *fw_info, int cached); +int reset_controller(firmware_info* fw_info); + + +/******************************************************** +** this function first check the value, if true then set value +** +*********************************************************/ +static inline bool check_set_driver_state_value(uint16_t check_value, uint16_t change_value) +{ + bool res; + spin_lock(&running_flag_lock); + if((driver_state & check_value) != check_value) { + res = false; + } + else { + driver_state |= change_value; + res = true; + } + spin_unlock(&running_flag_lock); + return res; +} + +static inline uint16_t get_driver_state_value(void) +{ + uint16_t state; + spin_lock(&running_flag_lock); + state = driver_state; + spin_unlock(&running_flag_lock); + return state; +} + +static inline void clear_driver_state(uint16_t clear_value) +{ + spin_lock(&running_flag_lock); + driver_state &= (~clear_value); + spin_unlock(&running_flag_lock); +} + +static inline void set_driver_state_value(uint16_t change_value) +{ + spin_lock(&running_flag_lock); + driver_state |= change_value; + spin_unlock(&running_flag_lock); +} + +#if SUSPNED_DW_FW +static int download_suspend_patch(firmware_info *fw_info, int cached); +#endif +#if SET_WAKEUP_DEVICE +static void set_wakeup_device_from_conf(firmware_info *fw_info); +int set_wakeup_device(firmware_info* fw_info, uint8_t* wakeup_bdaddr); +#endif + +static void rtk_free( struct btusb_data *data) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 1) + kfree(data); +#endif + return; +} + +static struct btusb_data *rtk_alloc(struct usb_interface *intf) +{ + struct btusb_data *data; +#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 7, 1) + data = kzalloc(sizeof(*data), GFP_KERNEL); +#else + data = devm_kzalloc(&intf->dev, sizeof(*data), GFP_KERNEL); +#endif + return data; +} + +static void print_acl(struct sk_buff *skb, int direction) +{ +#if PRINT_ACL_DATA + uint wlength = skb->len; + u16 *handle = (u16 *)(skb->data); + u16 len = *(handle+1); + u8 *acl_data = (u8 *)(skb->data); + + RTK_INFO("%s: direction %d, handle %04x, len %d", + __func__, direction, *handle, len); +#endif +} + +static void print_sco(struct sk_buff *skb, int direction) +{ +#if PRINT_SCO_DATA + uint wlength = skb->len; + u16 *handle = (u16 *)(skb->data); + u8 len = *(u8 *)(handle+1); + u8 *sco_data =(u8 *)(skb->data); + + RTKBT_INFO("%s: direction %d, handle %04x, len %d", + __func__, direction, *handle, len); +#endif +} + +static void print_error_command(struct sk_buff *skb) +{ + uint wlength = skb->len; + uint icount = 0; + u16 *opcode = (u16*)(skb->data); + u8 *cmd_data = (u8*)(skb->data); + u8 len = *(cmd_data+2); + + switch (*opcode) { + case HCI_OP_INQUIRY: + printk("HCI_OP_INQUIRY"); + break; + case HCI_OP_INQUIRY_CANCEL: + printk("HCI_OP_INQUIRY_CANCEL"); + break; + case HCI_OP_EXIT_PERIODIC_INQ: + printk("HCI_OP_EXIT_PERIODIC_INQ"); + break; + case HCI_OP_CREATE_CONN: + printk("HCI_OP_CREATE_CONN"); + break; + case HCI_OP_DISCONNECT: + printk("HCI_OP_DISCONNECT"); + break; + case HCI_OP_CREATE_CONN_CANCEL: + printk("HCI_OP_CREATE_CONN_CANCEL"); + break; + case HCI_OP_ACCEPT_CONN_REQ: + printk("HCI_OP_ACCEPT_CONN_REQ"); + break; + case HCI_OP_REJECT_CONN_REQ: + printk("HCI_OP_REJECT_CONN_REQ"); + break; + case HCI_OP_AUTH_REQUESTED: + printk("HCI_OP_AUTH_REQUESTED"); + break; + case HCI_OP_SET_CONN_ENCRYPT: + printk("HCI_OP_SET_CONN_ENCRYPT"); + break; + case HCI_OP_REMOTE_NAME_REQ: + printk("HCI_OP_REMOTE_NAME_REQ"); + break; + case HCI_OP_READ_REMOTE_FEATURES: + printk("HCI_OP_READ_REMOTE_FEATURES"); + break; + case HCI_OP_SNIFF_MODE: + printk("HCI_OP_SNIFF_MODE"); + break; + case HCI_OP_EXIT_SNIFF_MODE: + printk("HCI_OP_EXIT_SNIFF_MODE"); + break; + case HCI_OP_SWITCH_ROLE: + printk("HCI_OP_SWITCH_ROLE"); + break; + case HCI_OP_SNIFF_SUBRATE: + printk("HCI_OP_SNIFF_SUBRATE"); + break; + case HCI_OP_RESET: + printk("HCI_OP_RESET"); + break; + case HCI_OP_Write_Extended_Inquiry_Response: + printk("HCI_Write_Extended_Inquiry_Response"); + break; + + default: + printk("CMD"); + break; + } + printk(":%04x,len:%d,", *opcode,len); + for (icount = 3; (icount < wlength) && (icount < 24); icount++) + printk("%02x ", *(cmd_data+icount)); + printk("\n"); +} + +static void print_command(struct sk_buff *skb) +{ +#if PRINT_CMD_EVENT + print_error_command(skb); +#endif +} + +#if CONFIG_BLUEDROID +/* Global parameters for bt usb char driver */ +#define BT_CHAR_DEVICE_NAME "rtkbt_dev" +static struct sk_buff_head btchr_readq; +static wait_queue_head_t btchr_read_wait; +static wait_queue_head_t bt_drv_state_wait; +static dev_t bt_devid; /* bt char device number */ +static struct cdev bt_char_dev; /* bt character device structure */ +static struct class *bt_char_class; /* device class for usb char driver */ +static int bt_reset = 0; +/* HCI device & lock */ +DEFINE_RWLOCK(hci_dev_lock); +struct hci_dev *ghdev = NULL; + +static void print_event(struct sk_buff *skb) +{ +#if PRINT_CMD_EVENT + uint wlength = skb->len; + uint icount = 0; + u8 *opcode = (u8*)(skb->data); + u8 len = *(opcode+1); + + switch (*opcode) { + case HCI_EV_INQUIRY_COMPLETE: + printk("HCI_EV_INQUIRY_COMPLETE"); + break; + case HCI_EV_INQUIRY_RESULT: + printk("HCI_EV_INQUIRY_RESULT"); + break; + case HCI_EV_CONN_COMPLETE: + printk("HCI_EV_CONN_COMPLETE"); + break; + case HCI_EV_CONN_REQUEST: + printk("HCI_EV_CONN_REQUEST"); + break; + case HCI_EV_DISCONN_COMPLETE: + printk("HCI_EV_DISCONN_COMPLETE"); + break; + case HCI_EV_AUTH_COMPLETE: + printk("HCI_EV_AUTH_COMPLETE"); + break; + case HCI_EV_REMOTE_NAME: + printk("HCI_EV_REMOTE_NAME"); + break; + case HCI_EV_ENCRYPT_CHANGE: + printk("HCI_EV_ENCRYPT_CHANGE"); + break; + case HCI_EV_CHANGE_LINK_KEY_COMPLETE: + printk("HCI_EV_CHANGE_LINK_KEY_COMPLETE"); + break; + case HCI_EV_REMOTE_FEATURES: + printk("HCI_EV_REMOTE_FEATURES"); + break; + case HCI_EV_REMOTE_VERSION: + printk("HCI_EV_REMOTE_VERSION"); + break; + case HCI_EV_QOS_SETUP_COMPLETE: + printk("HCI_EV_QOS_SETUP_COMPLETE"); + break; + case HCI_EV_CMD_COMPLETE: + printk("HCI_EV_CMD_COMPLETE"); + break; + case HCI_EV_CMD_STATUS: + printk("HCI_EV_CMD_STATUS"); + break; + case HCI_EV_ROLE_CHANGE: + printk("HCI_EV_ROLE_CHANGE"); + break; + case HCI_EV_NUM_COMP_PKTS: + printk("HCI_EV_NUM_COMP_PKTS"); + break; + case HCI_EV_MODE_CHANGE: + printk("HCI_EV_MODE_CHANGE"); + break; + case HCI_EV_PIN_CODE_REQ: + printk("HCI_EV_PIN_CODE_REQ"); + break; + case HCI_EV_LINK_KEY_REQ: + printk("HCI_EV_LINK_KEY_REQ"); + break; + case HCI_EV_LINK_KEY_NOTIFY: + printk("HCI_EV_LINK_KEY_NOTIFY"); + break; + case HCI_EV_CLOCK_OFFSET: + printk("HCI_EV_CLOCK_OFFSET"); + break; + case HCI_EV_PKT_TYPE_CHANGE: + printk("HCI_EV_PKT_TYPE_CHANGE"); + break; + case HCI_EV_PSCAN_REP_MODE: + printk("HCI_EV_PSCAN_REP_MODE"); + break; + case HCI_EV_INQUIRY_RESULT_WITH_RSSI: + printk("HCI_EV_INQUIRY_RESULT_WITH_RSSI"); + break; + case HCI_EV_REMOTE_EXT_FEATURES: + printk("HCI_EV_REMOTE_EXT_FEATURES"); + break; + case HCI_EV_SYNC_CONN_COMPLETE: + printk("HCI_EV_SYNC_CONN_COMPLETE"); + break; + case HCI_EV_SYNC_CONN_CHANGED: + printk("HCI_EV_SYNC_CONN_CHANGED"); + break; + case HCI_EV_SNIFF_SUBRATE: + printk("HCI_EV_SNIFF_SUBRATE"); + break; + case HCI_EV_EXTENDED_INQUIRY_RESULT: + printk("HCI_EV_EXTENDED_INQUIRY_RESULT"); + break; + case HCI_EV_IO_CAPA_REQUEST: + printk("HCI_EV_IO_CAPA_REQUEST"); + break; + case HCI_EV_SIMPLE_PAIR_COMPLETE: + printk("HCI_EV_SIMPLE_PAIR_COMPLETE"); + break; + case HCI_EV_REMOTE_HOST_FEATURES: + printk("HCI_EV_REMOTE_HOST_FEATURES"); + break; + default: + printk("event"); + break; + } + printk(":%02x,len:%d,", *opcode,len); + for (icount = 2; (icount < wlength) && (icount < 24); icount++) + printk("%02x ", *(opcode+icount)); + printk("\n"); +#endif +} + +static inline ssize_t usb_put_user(struct sk_buff *skb, + char __user *buf, int count) +{ + char __user *ptr = buf; + int len = min_t(unsigned int, skb->len, count); + + if (copy_to_user(ptr, skb->data, len)) + return -EFAULT; + + return len; +} + +static struct sk_buff *rtk_skb_queue[QUEUE_SIZE]; +static int rtk_skb_queue_front = 0; +static int rtk_skb_queue_rear = 0; + +static void rtk_enqueue(struct sk_buff *skb) +{ + unsigned long flags; + spin_lock_irqsave(&queue_lock, flags); + if (rtk_skb_queue_front == (rtk_skb_queue_rear + 1) % QUEUE_SIZE) { + /* + * If queue is full, current solution is to drop + * the following entries. + */ + RTKBT_WARN("%s: Queue is full, entry will be dropped", __func__); + } else { + rtk_skb_queue[rtk_skb_queue_rear] = skb; + + rtk_skb_queue_rear++; + rtk_skb_queue_rear %= QUEUE_SIZE; + + } + spin_unlock_irqrestore(&queue_lock, flags); +} + +static struct sk_buff *rtk_dequeue_try(unsigned int deq_len) +{ + struct sk_buff *skb; + struct sk_buff *skb_copy; + + if (rtk_skb_queue_front == rtk_skb_queue_rear) { + RTKBT_WARN("%s: Queue is empty", __func__); + return NULL; + } + + skb = rtk_skb_queue[rtk_skb_queue_front]; + if (deq_len >= skb->len) { + rtk_skb_queue[rtk_skb_queue_front] = NULL; + rtk_skb_queue_front++; + rtk_skb_queue_front %= QUEUE_SIZE; + + /* + * Return skb addr to be dequeued, and the caller + * should free the skb eventually. + */ + return skb; + } else { + skb_copy = pskb_copy(skb, GFP_ATOMIC); + skb_pull(skb, deq_len); + /* Return its copy to be freed */ + return skb_copy; + } +} + +static inline int is_queue_empty(void) +{ + return (rtk_skb_queue_front == rtk_skb_queue_rear) ? 1 : 0; +} + +static void rtk_clear_queue(void) +{ + struct sk_buff *skb; + unsigned long flags; + spin_lock_irqsave(&queue_lock, flags); + while(!is_queue_empty()) { + skb = rtk_skb_queue[rtk_skb_queue_front]; + rtk_skb_queue[rtk_skb_queue_front] = NULL; + rtk_skb_queue_front++; + rtk_skb_queue_front %= QUEUE_SIZE; + if (skb) { + kfree_skb(skb); + } + } + spin_unlock_irqrestore(&queue_lock, flags); +} + +/* + * Realtek - Integrate from hci_core.c + */ + +/* Get HCI device by index. + * Device is held on return. */ +static struct hci_dev *hci_dev_get(int index) +{ + if (index != 0) + return NULL; + + return ghdev; +} + +/* ---- HCI ioctl helpers ---- */ +static int hci_dev_open(__u16 dev) +{ + struct hci_dev *hdev; + int ret = 0; + + RTKBT_DBG("%s: dev %d", __func__, dev); + + hdev = hci_dev_get(dev); + if (!hdev) { + RTKBT_ERR("%s: Failed to get hci dev[Null]", __func__); + return -ENODEV; + } + + if (test_bit(HCI_UNREGISTER, &hdev->flags)) { + ret = -ENODEV; + goto done; + } + + if (test_bit(HCI_UP, &hdev->flags)) { + ret = -EALREADY; + goto done; + } + +done: + return ret; +} + +static int hci_dev_do_close(struct hci_dev *hdev) +{ + if (hdev->flush) + hdev->flush(hdev); + /* After this point our queues are empty + * and no tasks are scheduled. */ + hdev->close(hdev); + /* Clear flags */ + hdev->flags = 0; + memset(&hdev->conn_hash, 0, sizeof(struct hci_conn_hash)); + return 0; +} + +static int hci_dev_close(__u16 dev) +{ + struct hci_dev *hdev; + int err; + hdev = hci_dev_get(dev); + if (!hdev) { + RTKBT_ERR("%s: failed to get hci dev[Null]", __func__); + return -ENODEV; + } + + err = hci_dev_do_close(hdev); + + return err; +} + +static struct hci_dev *hci_alloc_dev(void) +{ + struct hci_dev *hdev; + + hdev = kzalloc(sizeof(struct hci_dev), GFP_KERNEL); + if (!hdev) + return NULL; + + return hdev; +} + +/* Free HCI device */ +static void hci_free_dev(struct hci_dev *hdev) +{ + kfree(hdev); +} + +/* Register HCI device */ +static int hci_register_dev(struct hci_dev *hdev) +{ + int i, id; + + RTKBT_DBG("%s: %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus); + /* Do not allow HCI_AMP devices to register at index 0, + * so the index can be used as the AMP controller ID. + */ + id = (hdev->dev_type == HCI_BREDR) ? 0 : 1; + + write_lock(&hci_dev_lock); + + sprintf(hdev->name, "hci%d", id); + hdev->id = id; + hdev->flags = 0; + mutex_init(&hdev->lock); + + RTKBT_DBG("%s: id %d, name %s", __func__, hdev->id, hdev->name); + + + for (i = 0; i < NUM_REASSEMBLY; i++) + hdev->reassembly[i] = NULL; + + memset(&hdev->stat, 0, sizeof(struct hci_dev_stats)); + atomic_set(&hdev->promisc, 0); + + if (ghdev) { + write_unlock(&hci_dev_lock); + RTKBT_ERR("%s: Hci device has been registered already", __func__); + return -1; + } else + ghdev = hdev; + + write_unlock(&hci_dev_lock); + + return id; +} + +/* Unregister HCI device */ +static void hci_unregister_dev(struct hci_dev *hdev) +{ + int i; + + RTKBT_DBG("%s: hdev %p name %s bus %d", __func__, hdev, hdev->name, hdev->bus); + set_bit(HCI_UNREGISTER, &hdev->flags); + + write_lock(&hci_dev_lock); + ghdev = NULL; + write_unlock(&hci_dev_lock); + + hci_dev_do_close(hdev); + for (i = 0; i < NUM_REASSEMBLY; i++) + kfree_skb(hdev->reassembly[i]); +} + + +#ifdef CONFIG_SCO_OVER_HCI +/* copy data from the URB buffer into the ALSA ring buffer */ +static bool rtk_copy_capture_data_to_alsa(struct btusb_data *data, uint8_t* p_data, unsigned int frames) +{ + struct snd_pcm_runtime *runtime; + unsigned int frame_bytes, frames1; + u8 *dest; + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + + runtime = pSCOSnd->capture.substream->runtime; + frame_bytes = 2; + + dest = runtime->dma_area + pSCOSnd->capture.buffer_pos * frame_bytes; + if (pSCOSnd->capture.buffer_pos + frames <= runtime->buffer_size) { + memcpy(dest, p_data, frames * frame_bytes); + } else { + /* wrap around at end of ring buffer */ + frames1 = runtime->buffer_size - pSCOSnd->capture.buffer_pos; + memcpy(dest, p_data, frames1 * frame_bytes); + memcpy(runtime->dma_area, + p_data + frames1 * frame_bytes, + (frames - frames1) * frame_bytes); + } + + pSCOSnd->capture.buffer_pos += frames; + if (pSCOSnd->capture.buffer_pos >= runtime->buffer_size) { + pSCOSnd->capture.buffer_pos -= runtime->buffer_size; + } + + if((pSCOSnd->capture.buffer_pos%runtime->period_size) == 0) { + snd_pcm_period_elapsed(pSCOSnd->capture.substream); + } + + return false; +} + + +static void hci_send_to_alsa_ringbuffer(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + uint8_t* p_data; + int sco_length = skb->len - HCI_SCO_HDR_SIZE; + + RTKBT_DBG("%s", __func__); + + if (!hdev) { + RTKBT_ERR("%s: Frame for unknown HCI device", __func__); + return; + } + + if (!test_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states)) { + //RTKBT_WARN("%s: ALSA is not running", __func__); + return; + } + + p_data = (uint8_t *)skb->data + HCI_SCO_HDR_SIZE; + rtk_copy_capture_data_to_alsa(data, p_data, sco_length/2); +} + +#endif + +static void hci_send_to_stack(struct hci_dev *hdev, struct sk_buff *skb) +{ + struct sk_buff *rtk_skb_copy = NULL; + + RTKBT_DBG("%s", __func__); + + if (!hdev) { + RTKBT_ERR("%s: Frame for unknown HCI device", __func__); + return; + } + + if (!test_bit(HCI_RUNNING, &hdev->flags)) { + RTKBT_ERR("%s: HCI not running", __func__); + return; + } + + rtk_skb_copy = pskb_copy(skb, GFP_ATOMIC); + if (!rtk_skb_copy) { + RTKBT_ERR("%s: Copy skb error", __func__); + return; + } + + memcpy(skb_push(rtk_skb_copy, 1), &bt_cb(skb)->pkt_type, 1); + rtk_enqueue(rtk_skb_copy); + + /* Make sure bt char device existing before wakeup read queue */ + hdev = hci_dev_get(0); + if (hdev) { + RTKBT_DBG("%s: Try to wakeup read queue", __func__); + wake_up_interruptible(&btchr_read_wait); + } + + return; +} + +/* Receive frame from HCI drivers */ +static int hci_recv_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + + if (!hdev || !test_bit(HCI_UP, &hdev->flags)) { + kfree_skb(skb); + return -ENXIO; + } + + /* Incomming skb */ + bt_cb(skb)->incoming = 1; + + /* Time stamp */ + __net_timestamp(skb); + + if (atomic_read(&hdev->promisc)) { +#ifdef CONFIG_SCO_OVER_HCI + if(bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) + hci_send_to_alsa_ringbuffer(hdev, skb); +#endif + /* Send copy to the sockets */ + hci_send_to_stack(hdev, skb); + } + + kfree_skb(skb); + return 0; +} + +/* Receive frame from HCI drivers */ +static int hci_recv_sco_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + + if (!hdev || !test_bit(HCI_UP, &hdev->flags)) { + kfree_skb(skb); + return -ENXIO; + } + + /* Incomming skb */ + bt_cb(skb)->incoming = 1; + + /* Time stamp */ + __net_timestamp(skb); + + if (atomic_read(&hdev->promisc)) { +#ifdef CONFIG_SCO_OVER_HCI + if(bt_cb(skb)->pkt_type == HCI_SCODATA_PKT) + hci_send_to_alsa_ringbuffer(hdev, skb); +#endif + /* Send copy to the sockets */ + hci_send_to_stack(hdev, skb); + } + + kfree_skb(skb); + return 0; +} + +static int hci_reassembly(struct hci_dev *hdev, int type, void *data, + int count, __u8 index) +{ + int len = 0; + int hlen = 0; + int remain = count; + struct sk_buff *skb; + struct bt_skb_cb *scb; + + RTKBT_DBG("%s", __func__); + + if ((type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) || + index >= NUM_REASSEMBLY) + return -EILSEQ; + + skb = hdev->reassembly[index]; + + if (!skb) { + switch (type) { + case HCI_ACLDATA_PKT: + len = HCI_MAX_FRAME_SIZE; + hlen = HCI_ACL_HDR_SIZE; + break; + case HCI_EVENT_PKT: + len = HCI_MAX_EVENT_SIZE; + hlen = HCI_EVENT_HDR_SIZE; + break; + case HCI_SCODATA_PKT: + len = HCI_MAX_SCO_SIZE; + hlen = HCI_SCO_HDR_SIZE; + break; + } + + skb = bt_skb_alloc(len, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + + scb = (void *) skb->cb; + scb->expect = hlen; + scb->pkt_type = type; + + skb->dev = (void *) hdev; + hdev->reassembly[index] = skb; + + } + + while (count) { + scb = (void *) skb->cb; + len = min_t(uint, scb->expect, count); + + memcpy(skb_put(skb, len), data, len); + + count -= len; + data += len; + scb->expect -= len; + remain = count; + + switch (type) { + case HCI_EVENT_PKT: + if (skb->len == HCI_EVENT_HDR_SIZE) { + struct hci_event_hdr *h = hci_event_hdr(skb); + scb->expect = h->plen; + + if (skb_tailroom(skb) < scb->expect) { + kfree_skb(skb); + hdev->reassembly[index] = NULL; + return -ENOMEM; + } + } + break; + + case HCI_ACLDATA_PKT: + if (skb->len == HCI_ACL_HDR_SIZE) { + struct hci_acl_hdr *h = hci_acl_hdr(skb); + scb->expect = __le16_to_cpu(h->dlen); + + if (skb_tailroom(skb) < scb->expect) { + kfree_skb(skb); + hdev->reassembly[index] = NULL; + return -ENOMEM; + } + } + break; + + case HCI_SCODATA_PKT: + if (skb->len == HCI_SCO_HDR_SIZE) { + struct hci_sco_hdr *h = hci_sco_hdr(skb); + scb->expect = h->dlen; + + if (skb_tailroom(skb) < scb->expect) { + kfree_skb(skb); + hdev->reassembly[index] = NULL; + return -ENOMEM; + } + } + break; + } + + if (scb->expect == 0) { + /* Complete frame */ + if(HCI_ACLDATA_PKT == type) + print_acl(skb,0); + if(HCI_SCODATA_PKT == type) + print_sco(skb,0); + if(HCI_EVENT_PKT == type) + print_event(skb); + + bt_cb(skb)->pkt_type = type; + if(type == HCI_SCODATA_PKT) { + hci_recv_sco_frame(skb); + } + else + hci_recv_frame(skb); + + hdev->reassembly[index] = NULL; + return remain; + } + } + + return remain; +} + +static int hci_recv_fragment(struct hci_dev *hdev, int type, void *data, int count) +{ + int rem = 0; + + if (type < HCI_ACLDATA_PKT || type > HCI_EVENT_PKT) + return -EILSEQ; + + while (count) { + rem = hci_reassembly(hdev, type, data, count, type - 1); + if (rem < 0) + return rem; + + data += (count - rem); + count = rem; + } + + return rem; +} + +void hci_hardware_error(void) +{ + struct sk_buff *rtk_skb_copy = NULL; + int len = 4; + uint8_t hardware_err_pkt[4] = {HCI_EVENT_PKT, 0x10, 0x01, HCI_VENDOR_USB_DISC_HARDWARE_ERROR}; + + rtk_skb_copy = alloc_skb(len, GFP_ATOMIC); + if (!rtk_skb_copy) { + RTKBT_ERR("%s: Failed to allocate mem", __func__); + return; + } + + memcpy(skb_put(rtk_skb_copy, len), hardware_err_pkt, len); + rtk_enqueue(rtk_skb_copy); + + wake_up_interruptible(&btchr_read_wait); +} + +static int btchr_open(struct inode *inode_p, struct file *file_p) +{ + struct btusb_data *data; + struct hci_dev *hdev; + struct sk_buff *skb; + int i; + + RTKBT_INFO("%s: BT usb char device is opening", __func__); + + if(!check_set_driver_state_value(DEVICE_PROBED, CHAR_OPENED)) { + RTKBT_ERR("%s: Device not probed", __func__); + return -ENODEV; + } + + + hdev = hci_dev_get(0); + if (!hdev) { + RTKBT_ERR("%s: Failed to get hci dev[NULL]", __func__); + return -ENODEV; + } + + set_bit(HCI_UP, &hdev->flags); + data = GET_DRV_DATA(hdev); + + atomic_inc(&hdev->promisc); + /* + * As bt device is not re-opened when hotplugged out, we cannot + * trust on file's private data(may be null) when other file ops + * are invoked. + */ + file_p->private_data = data; + + hci_dev_open(0); + rtk_clear_queue(); + for(i = 0; i < NUM_REASSEMBLY; i++) { + skb = hdev->reassembly[i]; + if(skb) { + hdev->reassembly[i] = NULL; + kfree_skb(skb); + } + } + return nonseekable_open(inode_p, file_p); +} + +static int btchr_close(struct inode *inode_p, struct file *file_p) +{ + struct btusb_data *data; + struct hci_dev *hdev; + + RTKBT_INFO("%s: BT usb char device is closing", __func__); + + data = file_p->private_data; + file_p->private_data = NULL; + +#if CONFIG_BLUEDROID + /* + * If the upper layer closes bt char interfaces, no reset + * action required even bt device hotplugged out. + */ + bt_reset = 0; +#endif + + + hdev = hci_dev_get(0); + if (hdev) { + atomic_set(&hdev->promisc, 0); + hci_dev_close(0); + clear_bit(HCI_UP, &hdev->flags); + } + + clear_driver_state(CHAR_OPENED); + //if the state is not probed, the driver may be in the disconnecting state + //and waitting for signal to wake up + if((get_driver_state_value() & DEVICE_PROBED) == 0) + wake_up_interruptible(&bt_drv_state_wait); + return 0; +} + +static ssize_t btchr_read(struct file *file_p, + char __user *buf_p, + size_t count, + loff_t *pos_p) +{ + struct hci_dev *hdev; + struct sk_buff *skb; + ssize_t ret = 0; + + RTKBT_DBG("%s: BT usb char device is reading", __func__); + + while (count) { + hdev = hci_dev_get(0); + if (!hdev) { + /* + * Note: Only when BT device hotplugged out, we wil get + * into such situation. In order to keep the upper layer + * stack alive (blocking the read), we should never return + * EFAULT or break the loop. + */ + RTKBT_ERR("%s: Failed to get hci dev[Null]", __func__); + } + + ret = wait_event_interruptible(btchr_read_wait, !is_queue_empty()); + if (ret < 0) { + RTKBT_ERR("%s: wait event is signaled %ld", __func__, ret); + break; + } + + skb = rtk_dequeue_try(count); + if (skb) { + ret = usb_put_user(skb, buf_p, count); + if (ret < 0) + RTKBT_ERR("%s: Failed to put data to user space", __func__); + kfree_skb(skb); + break; + } + } + + return ret; +} + +static ssize_t btchr_write(struct file *file_p, + const char __user *buf_p, + size_t count, + loff_t *pos_p) +{ + struct btusb_data *data = file_p->private_data; + struct hci_dev *hdev; + struct sk_buff *skb; + + RTKBT_DBG("%s: BT usb char device is writing", __func__); + + if((get_driver_state_value() & DEVICE_PROBED) == 0) { + RTKBT_ERR("%s: Device not probed", __func__); + return POLLERR | POLLHUP; + } + + hdev = hci_dev_get(0); + if (!hdev) { + RTKBT_WARN("%s: Failed to get hci dev[Null]", __func__); + /* + * Note: we bypass the data from the upper layer if bt device + * is hotplugged out. Fortunatelly, H4 or H5 HCI stack does + * NOT check btchr_write's return value. However, returning + * count instead of EFAULT is preferable. + */ + /* return -EFAULT; */ + return count; + } + + /* Never trust on btusb_data, as bt device may be hotplugged out */ + data = GET_DRV_DATA(hdev); + if (!data) { + RTKBT_WARN("%s: Failed to get bt usb driver data[Null]", __func__); + return count; + } + + if (count > HCI_MAX_FRAME_SIZE) + return -EINVAL; + + skb = bt_skb_alloc(count, GFP_ATOMIC); + if (!skb) + return -ENOMEM; + skb_reserve(skb, -1); // Add this line + + if (copy_from_user(skb_put(skb, count), buf_p, count)) { + RTKBT_ERR("%s: Failed to get data from user space", __func__); + kfree_skb(skb); + return -EFAULT; + } + + skb->dev = (void *)hdev; + bt_cb(skb)->pkt_type = *((__u8 *)skb->data); + skb_pull(skb, 1); + data->hdev->send(skb); + + return count; +} + +static unsigned int btchr_poll(struct file *file_p, poll_table *wait) +{ + struct btusb_data *data = file_p->private_data; + struct hci_dev *hdev; + + RTKBT_DBG("%s: BT usb char device is polling", __func__); + + if((get_driver_state_value() & DRIVER_ON) == 0 || + (get_driver_state_value() & DEVICE_PROBED) == 0) { + RTKBT_ERR("%s: Device not probed", __func__); + return POLLERR | POLLHUP; + } + + poll_wait(file_p, &btchr_read_wait, wait); + + hdev = hci_dev_get(0); + if (!hdev) { + RTKBT_ERR("%s: Failed to get hci dev[Null]", __func__); + mdelay(URB_CANCELING_DELAY_MS); + return POLLOUT | POLLWRNORM; + } + + /* Never trust on btusb_data, as bt device may be hotplugged out */ + data = GET_DRV_DATA(hdev); + if (!data) { + /* + * When bt device is hotplugged out, btusb_data will + * be freed in disconnect. + */ + RTKBT_ERR("%s: Failed to get bt usb driver data[Null]", __func__); + mdelay(URB_CANCELING_DELAY_MS); + return POLLOUT | POLLWRNORM; + } + + if (!is_queue_empty()) + return POLLIN | POLLRDNORM; + + return POLLOUT | POLLWRNORM; +} + +static long btchr_ioctl(struct file *file_p, unsigned int cmd, unsigned long arg){ + int ret = 0; + struct hci_dev *hdev; + struct btusb_data *data; + firmware_info *fw_info; + + if((get_driver_state_value() & DRIVER_ON) == 0 || + (get_driver_state_value() & DEVICE_PROBED) == 0) { + RTKBT_ERR("%s bt controller is disconnect!", __func__); + return -ENODEV; + } + + hdev = hci_dev_get(0); + if(!hdev) { + RTKBT_ERR("%s device is NULL!", __func__); + return 0; + } + data = GET_DRV_DATA(hdev); + fw_info = data->fw_info; + + RTKBT_INFO(" btchr_ioctl with Cmd:%d",cmd); + switch (cmd) { + case DOWN_FW_CFG: + ret = usb_autopm_get_interface(data->intf); + if (ret < 0){ + goto failed; + } + + ret = download_patch(fw_info,1); + usb_autopm_put_interface(data->intf); + if(ret < 0){ + RTKBT_ERR("%s:Failed in download_patch with ret:%d",__func__,ret); + goto failed; + } + + ret = hdev->open(hdev); + if(ret < 0){ + RTKBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret); + goto failed; + } + ret = 1; + break; + +#ifdef CONFIG_SCO_OVER_HCI + case SET_ISO_CFG: + if(get_user(hdev->voice_setting, (__u16 __user*)arg)) { + ret = -EFAULT; + } + RTKBT_INFO(" voice settings = 0x%04x", hdev->voice_setting); + break; +#endif + + case GET_USB_INFO: + ret = hdev->open(hdev); + if(ret < 0){ + RTKBT_ERR("%s:Failed in hdev->open(hdev):%d",__func__,ret); + //goto done; + } + put_user(usb_info, (__u32 __user*)arg); + ret = 1; + break; + case RESET_CONTROLLER: + reset_controller(fw_info); + ret = 1; + break; + + case DWFW_CMPLT: + { + uint16_t lmp_sub = 0; + if(get_user(lmp_sub, (__u16 __user*)arg)) { + ret = -EFAULT; + } + else if(lmp_sub != 0) { + fw_info->patch_entry->lmp_sub = lmp_sub; + } + RTKBT_INFO("%s lmp_sub = 0x%x, patch_entry->lmp_sub = 0x%x", __func__, + lmp_sub, fw_info->patch_entry->lmp_sub); + } + break; + + default: + RTKBT_ERR("%s:Failed with wrong Cmd:%d",__func__,cmd); + goto failed; + } +failed: + return ret; + +} + +#ifdef CONFIG_COMPAT +static long compat_btchr_ioctl (struct file *filp, unsigned int cmd, unsigned long arg) +{ + return btchr_ioctl(filp, cmd, (unsigned long) compat_ptr(arg)); +} +#endif + +static struct file_operations bt_chrdev_ops = { + open : btchr_open, + release : btchr_close, + read : btchr_read, + write : btchr_write, + poll : btchr_poll, + unlocked_ioctl : btchr_ioctl, +#ifdef CONFIG_COMPAT + compat_ioctl : compat_btchr_ioctl, +#endif +}; + +static int btchr_init(void) +{ + int res = 0; + struct device *dev; + + RTKBT_INFO("Register usb char device interface for BT driver"); + skb_queue_head_init(&btchr_readq); + init_waitqueue_head(&btchr_read_wait); + init_waitqueue_head(&bt_drv_state_wait); + + bt_char_class = class_create(BT_CHAR_DEVICE_NAME); + if (IS_ERR(bt_char_class)) { + RTKBT_ERR("Failed to create bt char class"); + return PTR_ERR(bt_char_class); + } + + res = alloc_chrdev_region(&bt_devid, 0, 1, BT_CHAR_DEVICE_NAME); + if (res < 0) { + RTKBT_ERR("Failed to allocate bt char device"); + goto err_alloc; + } + + dev = device_create(bt_char_class, NULL, bt_devid, NULL, BT_CHAR_DEVICE_NAME); + if (IS_ERR(dev)) { + RTKBT_ERR("Failed to create bt char device"); + res = PTR_ERR(dev); + goto err_create; + } + + cdev_init(&bt_char_dev, &bt_chrdev_ops); + res = cdev_add(&bt_char_dev, bt_devid, 1); + if (res < 0) { + RTKBT_ERR("Failed to add bt char device"); + goto err_add; + } + + return 0; + +err_add: + device_destroy(bt_char_class, bt_devid); +err_create: + unregister_chrdev_region(bt_devid, 1); +err_alloc: + class_destroy(bt_char_class); + return res; +} + +static void btchr_exit(void) +{ + RTKBT_INFO("Unregister usb char device interface for BT driver"); + + device_destroy(bt_char_class, bt_devid); + cdev_del(&bt_char_dev); + unregister_chrdev_region(bt_devid, 1); + class_destroy(bt_char_class); + + return; +} +#endif + +int send_hci_cmd(firmware_info *fw_info) +{ + int i = 0; + int ret_val = -1; + while((ret_val<0)&&(i++<10)) + { + ret_val = usb_control_msg( + fw_info->udev, fw_info->pipe_out, + 0, USB_TYPE_CLASS, 0, 0, + (void *)(fw_info->send_pkt), + fw_info->pkt_len, MSG_TO); + } + return ret_val; +} + +int rcv_hci_evt(firmware_info *fw_info) +{ + int ret_len = 0, ret_val = 0; + int i; + + while (1) { + for(i = 0; i < 5; i++) { + ret_val = usb_interrupt_msg( + fw_info->udev, fw_info->pipe_in, + (void *)(fw_info->rcv_pkt), PKT_LEN, + &ret_len, MSG_TO); + if (ret_val >= 0) + break; + } + + if (ret_val < 0) + return ret_val; + + if (CMD_CMP_EVT == fw_info->evt_hdr->evt) { + if (fw_info->cmd_hdr->opcode == fw_info->cmd_cmp->opcode) + return ret_len; + } + } +} + +int set_bt_onoff(firmware_info *fw_info, uint8_t onoff) +{ + patch_info *patch_entry; + int ret_val; + + RTKBT_INFO("%s: %s", __func__, onoff != 0 ? "on" : "off"); + + patch_entry = fw_info->patch_entry; + if (!patch_entry) + return -1; + + fw_info->cmd_hdr->opcode = cpu_to_le16(BTOFF_OPCODE); + fw_info->cmd_hdr->plen = 1; + fw_info->pkt_len = CMD_HDR_LEN + 1; + fw_info->send_pkt[CMD_HDR_LEN] = onoff; + + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send bt %s cmd, errno %d", + __func__, onoff != 0 ? "on" : "off", ret_val); + return ret_val; + } + + return ret_val; +} + +static patch_info *get_fw_table_entry(struct usb_device* udev) +{ + patch_info *patch_entry = fw_patch_table; + uint16_t vid = le16_to_cpu(udev->descriptor.idVendor); + uint16_t pid = le16_to_cpu(udev->descriptor.idProduct); + uint32_t entry_size = sizeof(fw_patch_table) / sizeof(fw_patch_table[0]); + uint32_t i; + + RTKBT_INFO("%s: Product id = 0x%04x, fw table entry size %d", __func__, pid, entry_size); + usb_info = (uint32_t)(vid<<16) | pid; + + for (i = 0; i < entry_size; i++, patch_entry++) { + if ((vid == patch_entry->vid)&&(pid == patch_entry->pid)) + break; + } + + if (i == entry_size) { + RTKBT_ERR("%s: No fw table entry found", __func__); + return NULL; + } + + return patch_entry; +} + +#if SUSPNED_DW_FW +static patch_info *get_suspend_fw_table_entry(struct usb_device* udev) +{ + patch_info *patch_entry = fw_patch_table; + patch_info *patch_entry_real = NULL; + uint16_t vid = le16_to_cpu(udev->descriptor.idVendor); + uint16_t pid = le16_to_cpu(udev->descriptor.idProduct); + uint32_t entry_size = sizeof(fw_patch_table) / sizeof(fw_patch_table[0]); + uint32_t i; + + RTKBT_INFO("%s: Product id = 0x%04x, fw table entry size %d", __func__, pid, entry_size); + + for (i = 0; i < entry_size; i++, patch_entry++) { + if ((vid == patch_entry->vid)&&(pid == patch_entry->pid)) + break; + } + + if (i == entry_size) { + RTKBT_ERR("%s: No fw table entry found", __func__); + return NULL; + } + patch_entry_real = kmalloc(sizeof(fw_patch_table[0]), GFP_KERNEL); + if(!patch_entry_real) + return NULL; + memcpy(patch_entry_real, patch_entry, sizeof(fw_patch_table[0])); + return patch_entry_real; +} +#endif + +static struct rtk_epatch_entry *get_fw_patch_entry(struct rtk_epatch *epatch_info, uint16_t eco_ver) +{ + int patch_num = epatch_info->number_of_total_patch; + uint8_t *epatch_buf = (uint8_t *)epatch_info; + struct rtk_epatch_entry *p_entry = NULL; + int coex_date; + int coex_ver; + int i; + + for (i = 0; i < patch_num; i++) { + if (*(uint16_t *)(epatch_buf + 14 + 2*i) == eco_ver + 1) { + p_entry = kzalloc(sizeof(*p_entry), GFP_KERNEL); + if (!p_entry) { + RTKBT_ERR("%s: Failed to allocate mem for patch entry", __func__); + return NULL; + } + p_entry->chip_id = eco_ver + 1; + p_entry->patch_length = *(uint16_t*)(epatch_buf + 14 + 2*patch_num + 2*i); + p_entry->start_offset = *(uint32_t*)(epatch_buf + 14 + 4*patch_num + 4*i); + p_entry->coex_version = *(uint32_t*)(epatch_buf + p_entry->start_offset + p_entry->patch_length - 12); + p_entry->svn_version = *(uint32_t*)(epatch_buf + p_entry->start_offset + p_entry->patch_length - 8); + p_entry->fw_version = *(uint32_t*)(epatch_buf + p_entry->start_offset + p_entry->patch_length - 4); + + coex_date = ((p_entry->coex_version >> 16) & 0x7ff) + ((p_entry->coex_version >> 27) * 10000); + coex_ver = p_entry->coex_version & 0xffff; + + RTKBT_INFO("BTCOEX:20%06d-0x%04x svn version:0x%08x fw version:0x%08x rtk_btusb version:%s Cut:%d, patch length:0x%04x, patch offset:0x%08x\n", \ + coex_date, coex_ver, p_entry->svn_version, p_entry->fw_version, VERSION, p_entry->chip_id, p_entry->patch_length, p_entry->start_offset); + break; + } + } + + return p_entry; +} + +/*reset_controller is aimed to reset_bt_fw before updata Fw patch*/ +int reset_controller(firmware_info* fw_info) +{ + int ret_val; + RTKBT_ERR("reset_controller"); + + if (!fw_info) + return -ENODEV; + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_FORCE_RESET_AND_PATCHABLE); + fw_info->cmd_hdr->plen = 0; + fw_info->pkt_len = CMD_HDR_LEN; + ret_val = send_hci_cmd(fw_info); + + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send hci cmd 0x%04x, errno %d", + __func__, fw_info->cmd_hdr->opcode, ret_val); + return ret_val; + } + + //sleep 1s for firmware reset. + msleep(1000); + RTKBT_INFO("%s: Wait fw reset for 1000ms",__func__); + + return ret_val; +} +/*reset_controller is aimed to reset_bt_fw before updata Fw patch*/ + +/* + * check the return value + * 1: need to download fw patch + * 0: no need to download fw patch + * <0: failed to check lmp version + */ +int check_fw_version(firmware_info* fw_info, bool resume_check) +{ + struct hci_rp_read_local_version *read_ver_rsp; + patch_info *patch_entry = NULL; + int ret_val = -1, i, ret_len = 0; + struct sk_buff *rtk_skb_copy = NULL; + unsigned char pkt_type = HCI_EVENT_PKT; + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_OP_READ_LOCAL_VERSION); + fw_info->cmd_hdr->plen = 0; + fw_info->pkt_len = CMD_HDR_LEN; + + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send hci cmd 0x%04x, errno %d", + __func__, fw_info->cmd_hdr->opcode, ret_val); + return ret_val; + } + + while (1) { + for(i = 0; i < 5; i++) { + ret_val = usb_interrupt_msg( + fw_info->udev, fw_info->pipe_in, + (void *)(fw_info->rcv_pkt), PKT_LEN, + &ret_len, MSG_TO); + if (ret_val >= 0) + break; + } + + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to receive hci event, errno %d", + __func__, ret_val); + return ret_val; + } + + if ((CMD_CMP_EVT == fw_info->evt_hdr->evt) && + (fw_info->cmd_hdr->opcode == fw_info->cmd_cmp->opcode)) { + break; + } + else if(resume_check) { + rtk_skb_copy = bt_skb_alloc((ret_len), GFP_ATOMIC); + if (!rtk_skb_copy) { + RTKBT_ERR("%s: Failed to allocate mem", __func__); + return 2; + } + + memcpy(skb_put(rtk_skb_copy, ret_len), fw_info->rcv_pkt, ret_len); + memcpy(skb_push(rtk_skb_copy, 1), &pkt_type, 1); + rtk_enqueue(rtk_skb_copy); + + rtk_skb_copy = NULL; + wake_up_interruptible(&btchr_read_wait); + } + } + + patch_entry = fw_info->patch_entry; + read_ver_rsp = (struct hci_rp_read_local_version *)(fw_info->rsp_para); + + RTKBT_INFO("%s: Controller lmp = 0x%04x, patch lmp = 0x%04x, default patch lmp = 0x%04x", + __func__, read_ver_rsp->lmp_subver, patch_entry->lmp_sub, patch_entry->lmp_sub_default); + + if (read_ver_rsp->lmp_subver == patch_entry->lmp_sub_default) { + RTKBT_INFO("%s: Cold BT controller startup", __func__); + + return 2; + + } else if (read_ver_rsp->lmp_subver != patch_entry->lmp_sub) { + RTKBT_INFO("%s: Warm BT controller startup with updated lmp", __func__); + return 1; + } else { + RTKBT_INFO("%s: Warm BT controller startup with same lmp", __func__); + return 0; + } +} + +#if SET_WAKEUP_DEVICE +int set_wakeup_device(firmware_info* fw_info, uint8_t* wakeup_bdaddr) +{ + struct rtk_eversion_evt *ever_evt; + int ret_val; + + if (!fw_info) + return -ENODEV; + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_ADD_WAKE_UP_DEVICE); + fw_info->cmd_hdr->plen = 7; + memcpy(fw_info->req_para, wakeup_bdaddr, 7); + fw_info->pkt_len = CMD_HDR_LEN + 7; + + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send hci cmd 0x%04x, errno %d\n", + __func__, fw_info->cmd_hdr->opcode, ret_val); + return ret_val; + } + + ret_val = rcv_hci_evt(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to receive hci event, errno %d\n",__func__, ret_val); + return ret_val; + } + + ever_evt = (struct rtk_eversion_evt *)(fw_info->rsp_para); + + RTKBT_DBG("%s: status %d, eversion %d", __func__, ever_evt->status, ever_evt->version); + return ret_val; +} +#endif + +/*reset_channel to recover the communication between wifi 8192eu with 8761 bt controller in case of geteversion error*/ + +int reset_channel(firmware_info* fw_info) +{ + struct rtk_reset_evt *ever_evt; + int ret_val; + + if (!fw_info) + return -ENODEV; + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_RESET); + fw_info->cmd_hdr->plen = 0; + fw_info->pkt_len = CMD_HDR_LEN; + + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send hci cmd 0x%04x, errno %d", + __func__, fw_info->cmd_hdr->opcode, ret_val); + return ret_val; + } + + ret_val = rcv_hci_evt(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to receive hci event, errno %d", + __func__, ret_val); + return ret_val; + } + + ever_evt = (struct rtk_reset_evt *)(fw_info->rsp_para); + + RTKBT_INFO("%s: status %d ", __func__, ever_evt->status); + + //sleep 300ms for channel reset. + msleep(300); + RTKBT_INFO("%s: Wait channel reset for 300ms",__func__); + + return ret_val; +} + + +//sometimes the controller is in warm resume,and still send message to host +//we should reset controller and clean the hardware buffer +bool reset_and_clean_hw_buffer(firmware_info* fw_info) +{ + int ret_val; + int ret_len = 0; + bool event_recv = false; + + if (!fw_info) + return -ENODEV; + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_RESET); + fw_info->cmd_hdr->plen = 0; + fw_info->pkt_len = CMD_HDR_LEN; + + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send hci cmd 0x%04x, errno %d", + __func__, fw_info->cmd_hdr->opcode, ret_val); + return ret_val; + } + + //we need to clean the hardware buffer + while (1) { + ret_val = usb_interrupt_msg( + fw_info->udev, fw_info->pipe_in, + (void *)(fw_info->rcv_pkt), PKT_LEN, + &ret_len, (MSG_TO/4)); + + if(ret_val >= 0) { + if(event_recv) { + RTKBT_INFO("%s: clear hardware event", __func__); + continue; + } + } + else { + return event_recv; + } + + if (CMD_CMP_EVT == fw_info->evt_hdr->evt) { + if (fw_info->cmd_hdr->opcode == fw_info->cmd_cmp->opcode) { + event_recv = true; + } + } + } + return ret_val; +} + +int read_localversion(firmware_info* fw_info) +{ + struct rtk_localversion_evt *ever_evt; + int ret_val; + + if (!fw_info) + return -ENODEV; + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_READ_LMP_VERISION); + fw_info->cmd_hdr->plen = 0; + fw_info->pkt_len = CMD_HDR_LEN; + + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send hci cmd 0x%04x, errno %d", + __func__, fw_info->cmd_hdr->opcode, ret_val); + return ret_val; + } + + ret_val = rcv_hci_evt(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to receive hci event, errno %d", + __func__, ret_val); + return ret_val; + } + + ever_evt = (struct rtk_localversion_evt *)(fw_info->rsp_para); + + RTKBT_INFO("%s: status %d ", __func__, ever_evt->status); + RTKBT_INFO("%s: hci_version %d ", __func__, ever_evt->hci_version); + RTKBT_INFO("%s: hci_revision %d ", __func__, ever_evt->hci_revision); + RTKBT_INFO("%s: lmp_version %d ", __func__, ever_evt->lmp_version); + RTKBT_INFO("%s: lmp_subversion %d ", __func__, ever_evt->lmp_subversion); + RTKBT_INFO("%s: lmp_manufacture %d ", __func__, ever_evt->lmp_manufacture); + //sleep 300ms for channel reset. + msleep(300); + RTKBT_INFO("%s: Wait channel reset for 300ms",__func__); + + return ret_val; +} + +int get_eversion(firmware_info* fw_info) +{ + struct rtk_eversion_evt *ever_evt; + int ret_val; + + if (!fw_info) + return -ENODEV; + + fw_info->cmd_hdr->opcode = cpu_to_le16(HCI_VENDOR_READ_RTK_ROM_VERISION); + fw_info->cmd_hdr->plen = 0; + fw_info->pkt_len = CMD_HDR_LEN; + + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to send hci cmd 0x%04x, errno %d", + __func__, fw_info->cmd_hdr->opcode, ret_val); + return ret_val; + } + + ret_val = rcv_hci_evt(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to receive hci event, errno %d", + __func__, ret_val); + return ret_val; + } + + ever_evt = (struct rtk_eversion_evt *)(fw_info->rsp_para); + + RTKBT_INFO("%s: status %d, eversion %d", __func__, ever_evt->status, ever_evt->version); + + if (ever_evt->status) + fw_info->patch_entry->eversion = 0; + else + fw_info->patch_entry->eversion = ever_evt->version; + + return ret_val; +} + +void rtk_update_altsettings(patch_info *patch_entry, const unsigned char* org_config_buf, int org_config_len, unsigned char ** new_config_buf_ptr, int *new_config_len_ptr) +{ + static unsigned char config_buf[1024]; + unsigned short offset[256]; + unsigned char val[256]; + + struct rtk_bt_vendor_config* config = (struct rtk_bt_vendor_config*) config_buf; + struct rtk_bt_vendor_config_entry* entry = config->entry; + + int count = 0,temp = 0, i = 0, j; + + memset(config_buf, 0, sizeof(config_buf)); + memset(offset, 0, sizeof(offset)); + memset(val, 0, sizeof(val)); + + memcpy(config_buf, org_config_buf, org_config_len); + *new_config_buf_ptr = config_buf; + *new_config_len_ptr = org_config_len; + + count = getAltSettings(patch_entry, offset, sizeof(offset)/sizeof(unsigned short)); + if(count <= 0){ + RTKBT_INFO("rtk_update_altsettings: No AltSettings"); + return; + }else{ + RTKBT_INFO("rtk_update_altsettings: %d AltSettings", count); + } + + RTKBT_INFO("ORG Config len=%08x:\n", org_config_len); + for(i=0;i<=org_config_len;i+=0x10) + { + RTKBT_INFO("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i, \ + config_buf[i], config_buf[i+1], config_buf[i+2], config_buf[i+3], config_buf[i+4], config_buf[i+5], config_buf[i+6], config_buf[i+7], \ + config_buf[i+8], config_buf[i+9], config_buf[i+10], config_buf[i+11], config_buf[i+12], config_buf[i+13], config_buf[i+14], config_buf[i+15]); + } + + if (config->data_len != org_config_len - sizeof(struct rtk_bt_vendor_config)) + { + RTKBT_ERR("rtk_update_altsettings: config len(%x) is not right(%lx)", + config->data_len, (org_config_len-sizeof(struct rtk_bt_vendor_config))); + return; + } + + for (i=0; idata_len;) + { + for(j = 0; j < count;j++) + { + if(entry->offset == offset[j]) + offset[j] = 0; + } + if(getAltSettingVal(patch_entry, entry->offset, val) == entry->entry_len){ + RTKBT_INFO("rtk_update_altsettings: replace %04x[%02x]", entry->offset, entry->entry_len); + memcpy(entry->entry_data, val, entry->entry_len); + } + temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry); + i += temp; + entry = (struct rtk_bt_vendor_config_entry*)((uint8_t*)entry + temp); + } + for(j = 0; j < count;j++){ + if(offset[j] == 0) + continue; + entry->entry_len = getAltSettingVal(patch_entry, offset[j], val); + if(entry->entry_len <= 0) + continue; + entry->offset = offset[j]; + memcpy(entry->entry_data, val, entry->entry_len); + RTKBT_INFO("rtk_update_altsettings: add %04x[%02x]", entry->offset, entry->entry_len); + temp = entry->entry_len + sizeof(struct rtk_bt_vendor_config_entry); + i += temp; + entry = (struct rtk_bt_vendor_config_entry*)((uint8_t*)entry + temp); + } + config->data_len = i; + *new_config_buf_ptr = config_buf; + *new_config_len_ptr = config->data_len+sizeof(struct rtk_bt_vendor_config); + + return; +} + +int load_firmware(firmware_info *fw_info, uint8_t **buff) +{ + const struct firmware *fw, *cfg; + struct usb_device *udev; + patch_info *patch_entry; + char *config_name, *fw_name; + int fw_len = 0; + int ret_val; + + int config_len = 0, buf_len = -1; + uint8_t *buf = *buff, *config_file_buf = NULL; + uint8_t *epatch_buf = NULL; + + struct rtk_epatch *epatch_info = NULL; + uint8_t need_download_fw = 1; + struct rtk_extension_entry patch_lmp = {0}; + struct rtk_epatch_entry *p_epatch_entry = NULL; + uint16_t lmp_version; + //uint8_t use_mp_fw = 0; + RTKBT_DBG("%s: start", __func__); + + udev = fw_info->udev; + patch_entry = fw_info->patch_entry; + lmp_version = patch_entry->lmp_sub_default; + config_name = patch_entry->config_name; +/* 1 Mptool Fw; 0 Normal Fw */ + if(DRV_MP_MODE == mp_drv_mode){ + fw_name = patch_entry->mp_patch_name; + }else{ + fw_name = patch_entry->patch_name; + } + + RTKBT_INFO("%s: Default lmp version = 0x%04x, config file name[%s], " + "fw file name[%s]", __func__, lmp_version,config_name, fw_name); + + ret_val = request_firmware(&cfg, config_name, &udev->dev); + if (ret_val < 0) + config_len = 0; + else { + int i; + rtk_update_altsettings(patch_entry, cfg->data, cfg->size, &config_file_buf, &config_len); + + RTKBT_INFO("Final Config len=%08x:\n", config_len); + for(i=0;i<=config_len;i+=0x10) + { + RTKBT_INFO("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i, \ + config_file_buf[i], config_file_buf[i+1], config_file_buf[i+2], config_file_buf[i+3], config_file_buf[i+4], config_file_buf[i+5], config_file_buf[i+6], config_file_buf[i+7], \ + config_file_buf[i+8], config_file_buf[i+9], config_file_buf[i+10], config_file_buf[i+11], config_file_buf[i+12], config_file_buf[i+13], config_file_buf[i+14], config_file_buf[i+15]); + } + + release_firmware(cfg); + } + + ret_val = request_firmware(&fw, fw_name, &udev->dev); + if (ret_val < 0) + goto fw_fail; + else { + epatch_buf = vmalloc(fw->size); + RTKBT_INFO("%s: epatch_buf = vmalloc(fw->size, GFP_KERNEL)", __func__); + if (!epatch_buf) { + release_firmware(fw); + goto fw_fail; + } + memcpy(epatch_buf, fw->data, fw->size); + fw_len = fw->size; + buf_len = fw_len + config_len; + release_firmware(fw); + } + + if (lmp_version == ROM_LMP_8723a) { + RTKBT_DBG("%s: 8723a -> use old style patch", __func__); + if (!memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8)) { + RTKBT_ERR("%s: 8723a check signature error", __func__); + need_download_fw = 0; + } else { + if (!(buf = kzalloc(buf_len, GFP_KERNEL))) { + RTKBT_ERR("%s: Failed to allocate mem for fw&config", __func__); + buf_len = -1; + } else { + RTKBT_DBG("%s: 8723a -> fw copy directly", __func__); + memcpy(buf, epatch_buf, buf_len); + patch_entry->lmp_sub = *(uint16_t *)(buf + buf_len - config_len - 4); + RTKBT_DBG("%s: Config lmp version = 0x%04x", __func__, + patch_entry->lmp_sub); + vfree(epatch_buf); + RTKBT_INFO("%s:ROM_LMP_8723a vfree(epatch_buf)", __func__); + epatch_buf = NULL; + if (config_len) + memcpy(buf + buf_len - config_len, config_file_buf, config_len); + } + } + } else { + RTKBT_DBG("%s: Not 8723a -> use new style patch", __func__); + + RTKBT_DBG("%s: reset_channel before get_eversion from bt controller", __func__); + ret_val = reset_channel(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to reset_channel, errno %d", __func__, ret_val); + goto fw_fail; + } +// read_localversion(fw_info); + RTKBT_DBG("%s: get_eversion from bt controller", __func__); + + ret_val = get_eversion(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to get eversion, errno %d", __func__, ret_val); + goto fw_fail; + } + RTKBT_DBG("%s: Get eversion =%d", __func__, patch_entry->eversion); + if (memcmp(epatch_buf + buf_len - config_len - 4 , EXTENSION_SECTION_SIGNATURE, 4)) { + RTKBT_ERR("%s: Failed to check extension section signature", __func__); + need_download_fw = 0; + } else { + uint8_t *temp; + temp = epatch_buf+buf_len-config_len - 5; + do { + if (*temp == 0x00) { + patch_lmp.opcode = *temp; + patch_lmp.length = *(temp-1); + if ((patch_lmp.data = kzalloc(patch_lmp.length, GFP_KERNEL))) { + int k; + for (k = 0; k < patch_lmp.length; k++) { + *(patch_lmp.data+k) = *(temp-2-k); + RTKBT_DBG("data = 0x%x", *(patch_lmp.data+k)); + } + } + RTKBT_DBG("%s: opcode = 0x%x, length = 0x%x, data = 0x%x", __func__, + patch_lmp.opcode, patch_lmp.length, *(patch_lmp.data)); + break; + } + temp -= *(temp-1) + 2; + } while (*temp != 0xFF); + + if (lmp_version != project_id[*(patch_lmp.data)]) { + RTKBT_ERR("%s: Default lmp_version 0x%04x, project_id[%d] 0x%04x " + "-> not match", __func__, lmp_version, *(patch_lmp.data),project_id[*(patch_lmp.data)]); + if (patch_lmp.data) + kfree(patch_lmp.data); + need_download_fw = 0; + } else { + RTKBT_INFO("%s: Default lmp_version 0x%04x, project_id[%d] 0x%04x " + "-> match", __func__, lmp_version, *(patch_lmp.data), project_id[*(patch_lmp.data)]); + if (patch_lmp.data) + kfree(patch_lmp.data); + if (memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8)) { + RTKBT_ERR("%s: Check signature error", __func__); + need_download_fw = 0; + } else { + epatch_info = (struct rtk_epatch*)epatch_buf; + patch_entry->lmp_sub = (uint16_t)epatch_info->fw_version; + + RTKBT_DBG("%s: lmp version 0x%04x, fw_version 0x%x, " + "number_of_total_patch %d", __func__, + patch_entry->lmp_sub, epatch_info->fw_version, + epatch_info->number_of_total_patch); + + /* Get right epatch entry */ + p_epatch_entry = get_fw_patch_entry(epatch_info, patch_entry->eversion); + if (p_epatch_entry == NULL) { + RTKBT_WARN("%s: Failed to get fw patch entry", __func__); + ret_val = -1; + goto fw_fail ; + } + + buf_len = p_epatch_entry->patch_length + config_len; + RTKBT_DBG("buf_len = 0x%x", buf_len); + + if (!(buf = kzalloc(buf_len, GFP_KERNEL))) { + RTKBT_ERR("%s: Can't alloc memory for fw&config", __func__); + buf_len = -1; + kfree(p_epatch_entry); + } else { + memcpy(buf, &epatch_buf[p_epatch_entry->start_offset], p_epatch_entry->patch_length); + memcpy(&buf[p_epatch_entry->patch_length-4], &epatch_info->fw_version, 4); + kfree(p_epatch_entry); + } + vfree(epatch_buf); + RTKBT_INFO("%s: vfree(epatch_buf)", __func__); + epatch_buf = NULL; + + if (config_len) + memcpy(&buf[buf_len - config_len], config_file_buf, config_len); + } + } + } + } + + RTKBT_INFO("%s: fw%s exists, config file%s exists", __func__, + (buf_len > 0) ? "" : " not", (config_len > 0) ? "":" not"); + + if (buf && buf_len > 0 && need_download_fw) + *buff = buf; + + RTKBT_DBG("%s: done", __func__); + + return buf_len; + +fw_fail: + return ret_val; +} + +void load_firmware_info(firmware_info *fw_info) +{ + const struct firmware *fw; + struct usb_device *udev; + patch_info *patch_entry; + char *fw_name; + int ret_val; + + int buf_len = -1; + uint8_t *epatch_buf = NULL; + + struct rtk_epatch *epatch_info = NULL; + struct rtk_extension_entry patch_lmp = {0}; + uint16_t lmp_version; + RTKBT_DBG("%s: start", __func__); + + udev = fw_info->udev; + patch_entry = fw_info->patch_entry; + lmp_version = patch_entry->lmp_sub_default; + + if(DRV_MP_MODE == mp_drv_mode){ + fw_name = patch_entry->mp_patch_name; + } else { + fw_name = patch_entry->patch_name; + } + + RTKBT_INFO("%s: Default lmp version = 0x%04x, fw file name[%s]", __func__, lmp_version, fw_name); + + ret_val = request_firmware(&fw, fw_name, &udev->dev); + if (ret_val < 0) + goto fw_fail; + else { + epatch_buf = vmalloc(fw->size); + RTKBT_INFO("%s: epatch_buf = vmalloc(fw->size, GFP_KERNEL)", __func__); + if (!epatch_buf) { + release_firmware(fw); + goto fw_fail; + } + memcpy(epatch_buf, fw->data, fw->size); + buf_len = fw->size; + release_firmware(fw); + } + + ret_val = reset_and_clean_hw_buffer(fw_info); + + if (lmp_version != ROM_LMP_8723a) { + RTKBT_DBG("%s: Not 8723a -> use new style patch", __func__); + ret_val = get_eversion(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to get eversion, errno %d", __func__, ret_val); + goto fw_fail; + } + RTKBT_DBG("%s: Get eversion =%d", __func__, patch_entry->eversion); + if (memcmp(epatch_buf + buf_len - 4 , EXTENSION_SECTION_SIGNATURE, 4)) { + RTKBT_ERR("%s: Failed to check extension section signature", __func__); + } else { + uint8_t *temp; + temp = epatch_buf + buf_len - 5; + do { + if (*temp == 0x00) { + patch_lmp.opcode = *temp; + patch_lmp.length = *(temp-1); + if ((patch_lmp.data = vmalloc(patch_lmp.length))) { + int k; + for (k = 0; k < patch_lmp.length; k++) { + *(patch_lmp.data+k) = *(temp-2-k); + RTKBT_DBG("data = 0x%x", *(patch_lmp.data+k)); + } + } + else + goto fw_fail; + RTKBT_DBG("%s: opcode = 0x%x, length = 0x%x, data = 0x%x", __func__, + patch_lmp.opcode, patch_lmp.length, *(patch_lmp.data)); + break; + } + temp -= *(temp-1) + 2; + } while (*temp != 0xFF); + + if (lmp_version != project_id[*(patch_lmp.data)]) { + RTKBT_ERR("%s: Default lmp_version 0x%04x, project_id[%d] 0x%04x " + "-> not match", __func__, lmp_version, *(patch_lmp.data),project_id[*(patch_lmp.data)]); + } else { + RTKBT_INFO("%s: Default lmp_version 0x%04x, project_id[%d] 0x%04x " + "-> match", __func__, lmp_version, *(patch_lmp.data), project_id[*(patch_lmp.data)]); + if (memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8)) { + RTKBT_ERR("%s: Check signature error", __func__); + } else { + epatch_info = (struct rtk_epatch*)epatch_buf; + patch_entry->lmp_sub = (uint16_t)epatch_info->fw_version; + + RTKBT_DBG("%s: lmp version 0x%04x, fw_version 0x%x, " + "number_of_total_patch %d", __func__, + patch_entry->lmp_sub, epatch_info->fw_version, + epatch_info->number_of_total_patch); + } + } + } + } + + RTKBT_DBG("%s: done", __func__); +fw_fail: + if(epatch_buf) + vfree(epatch_buf); + if (patch_lmp.data) + vfree(patch_lmp.data); +} + +#if SUSPNED_DW_FW +static int load_suspend_firmware(firmware_info *fw_info, uint8_t **buff) +{ + const struct firmware *fw, *cfg; + struct usb_device *udev; + patch_info *patch_entry; + char config_name[100] = {0}; + char fw_name[100] = {0}; + int fw_len = 0; + int ret_val; + + int config_len = 0, buf_len = -1; + uint8_t *buf = *buff, *config_file_buf = NULL; + uint8_t *epatch_buf = NULL; + + struct rtk_epatch *epatch_info = NULL; + uint8_t need_download_fw = 1; + struct rtk_extension_entry patch_lmp = {0}; + struct rtk_epatch_entry *p_epatch_entry = NULL; + uint16_t lmp_version; + RTKBT_DBG("%s: start", __func__); + + udev = fw_info->udev; + patch_entry = fw_info->patch_entry; + lmp_version = patch_entry->lmp_sub_default; + sprintf(config_name, "%s_suspend", patch_entry->config_name); + sprintf(fw_name, "%s_suspend", patch_entry->patch_name); + + RTKBT_INFO("%s: Default lmp version = 0x%04x, config file name[%s], " + "fw file name[%s]", __func__, lmp_version,config_name, fw_name); + + ret_val = request_firmware(&cfg, config_name, &udev->dev); + if (ret_val < 0) + config_len = 0; + else { + int i; + rtk_update_altsettings(patch_entry, cfg->data, cfg->size, &config_file_buf, &config_len); + + RTKBT_INFO("Final Config len=%08x:\n", config_len); + for(i=0;i<=config_len;i+=0x10) + { + RTKBT_INFO("%08x: %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x %02x\n", i, \ + config_file_buf[i], config_file_buf[i+1], config_file_buf[i+2], config_file_buf[i+3], config_file_buf[i+4], config_file_buf[i+5], config_file_buf[i+6], config_file_buf[i+7], \ + config_file_buf[i+8], config_file_buf[i+9], config_file_buf[i+10], config_file_buf[i+11], config_file_buf[i+12], config_file_buf[i+13], config_file_buf[i+14], config_file_buf[i+15]); + } + + release_firmware(cfg); + } + + ret_val = request_firmware(&fw, fw_name, &udev->dev); + if (ret_val < 0) + goto fw_fail; + else { + epatch_buf = vmalloc(fw->size); + RTKBT_INFO("%s: epatch_buf = vmalloc(fw->size, GFP_KERNEL)", __func__); + if (!epatch_buf) { + release_firmware(fw); + goto fw_fail; + } + memcpy(epatch_buf, fw->data, fw->size); + fw_len = fw->size; + buf_len = fw_len + config_len; + release_firmware(fw); + } + + RTKBT_DBG("%s: Not 8723a -> use new style patch", __func__); + + RTKBT_DBG("%s: get_eversion from bt controller", __func__); + + ret_val = get_eversion(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to get eversion, errno %d", __func__, ret_val); + goto fw_fail; + } + RTKBT_DBG("%s: Get eversion =%d", __func__, patch_entry->eversion); + if (memcmp(epatch_buf + buf_len - config_len - 4 , EXTENSION_SECTION_SIGNATURE, 4)) { + RTKBT_ERR("%s: Failed to check extension section signature", __func__); + need_download_fw = 0; + } else { + uint8_t *temp; + temp = epatch_buf+buf_len-config_len - 5; + do { + if (*temp == 0x00) { + patch_lmp.opcode = *temp; + patch_lmp.length = *(temp-1); + if ((patch_lmp.data = kzalloc(patch_lmp.length, GFP_KERNEL))) { + int k; + for (k = 0; k < patch_lmp.length; k++) { + *(patch_lmp.data+k) = *(temp-2-k); + RTKBT_DBG("data = 0x%x", *(patch_lmp.data+k)); + } + } + RTKBT_DBG("%s: opcode = 0x%x, length = 0x%x, data = 0x%x", __func__, + patch_lmp.opcode, patch_lmp.length, *(patch_lmp.data)); + break; + } + temp -= *(temp-1) + 2; + } while (*temp != 0xFF); + + if (lmp_version != project_id[*(patch_lmp.data)]) { + RTKBT_ERR("%s: Default lmp_version 0x%04x, project_id[%d] 0x%04x " + "-> not match", __func__, lmp_version, *(patch_lmp.data),project_id[*(patch_lmp.data)]); + if (patch_lmp.data) + kfree(patch_lmp.data); + need_download_fw = 0; + } else { + RTKBT_INFO("%s: Default lmp_version 0x%04x, project_id[%d] 0x%04x " + "-> match", __func__, lmp_version, *(patch_lmp.data), project_id[*(patch_lmp.data)]); + if (patch_lmp.data) + kfree(patch_lmp.data); + if (memcmp(epatch_buf, RTK_EPATCH_SIGNATURE, 8)) { + RTKBT_ERR("%s: Check signature error", __func__); + need_download_fw = 0; + } else { + epatch_info = (struct rtk_epatch*)epatch_buf; + patch_entry->lmp_sub = (uint16_t)epatch_info->fw_version; + + RTKBT_DBG("%s: lmp version 0x%04x, fw_version 0x%x, " + "number_of_total_patch %d", __func__, + patch_entry->lmp_sub, epatch_info->fw_version, + epatch_info->number_of_total_patch); + + /* Get right epatch entry */ + p_epatch_entry = get_fw_patch_entry(epatch_info, patch_entry->eversion); + if (p_epatch_entry == NULL) { + RTKBT_WARN("%s: Failed to get fw patch entry", __func__); + ret_val = -1; + goto fw_fail ; + } + + buf_len = p_epatch_entry->patch_length + config_len; + RTKBT_DBG("buf_len = 0x%x", buf_len); + + if (!(buf = kzalloc(buf_len, GFP_KERNEL))) { + RTKBT_ERR("%s: Can't alloc memory for fw&config", __func__); + buf_len = -1; + kfree(p_epatch_entry); + } else { + memcpy(buf, &epatch_buf[p_epatch_entry->start_offset], p_epatch_entry->patch_length); + memcpy(&buf[p_epatch_entry->patch_length-4], &epatch_info->fw_version, 4); + kfree(p_epatch_entry); + } + vfree(epatch_buf); + RTKBT_INFO("%s: vfree(epatch_buf)", __func__); + epatch_buf = NULL; + + if (config_len) + memcpy(&buf[buf_len - config_len], config_file_buf, config_len); + } + } + } + + RTKBT_INFO("%s: fw%s exists, config file%s exists", __func__, + (buf_len > 0) ? "" : " not", (config_len > 0) ? "":" not"); + + if (buf && buf_len > 0 && need_download_fw) + *buff = buf; + + RTKBT_DBG("%s: done", __func__); + + return buf_len; + +fw_fail: + return ret_val; +} +#endif + +int get_firmware(firmware_info *fw_info, int cached) +{ + patch_info *patch_entry = fw_info->patch_entry; + + RTKBT_INFO("%s: start, cached %d,patch_entry->fw_len= %d", __func__, cached,patch_entry->fw_len); + + if (cached > 0) { + if (patch_entry->fw_len > 0) { + fw_info->fw_data = kzalloc(patch_entry->fw_len, GFP_KERNEL); + if (!fw_info->fw_data) + return -ENOMEM; + memcpy(fw_info->fw_data, patch_entry->fw_cache, patch_entry->fw_len); + fw_info->fw_len = patch_entry->fw_len; + } else { + fw_info->fw_len = load_firmware(fw_info, &fw_info->fw_data); + if (fw_info->fw_len <= 0) + return -1; + } + } else { + fw_info->fw_len = load_firmware(fw_info, &fw_info->fw_data); + if (fw_info->fw_len <= 0) + return -1; + } + + return 0; +} + +#if SUSPNED_DW_FW +static int get_suspend_firmware(firmware_info *fw_info, int cached) +{ + patch_info *patch_entry = fw_info->patch_entry; + + RTKBT_INFO("%s: start, cached %d,patch_entry->fw_len= %d", __func__, cached,patch_entry->fw_len); + + if (cached > 0) { + if (patch_entry->fw_len > 0) { + fw_info->fw_data = kzalloc(patch_entry->fw_len, GFP_KERNEL); + if (!fw_info->fw_data) + return -ENOMEM; + memcpy(fw_info->fw_data, patch_entry->fw_cache, patch_entry->fw_len); + fw_info->fw_len = patch_entry->fw_len; + } else { + fw_info->fw_len = load_suspend_firmware(fw_info, &fw_info->fw_data); + if (fw_info->fw_len <= 0) + return -1; + } + } else { + fw_info->fw_len = load_suspend_firmware(fw_info, &fw_info->fw_data); + if (fw_info->fw_len <= 0) + return -1; + } + + return 0; +} +#endif + +/* + * Open the log message only if in debugging, + * or it will decelerate download procedure. + */ +int download_data(firmware_info *fw_info) +{ + download_cp *cmd_para; + download_rp *evt_para; + uint8_t *pcur; + int pkt_len, frag_num, frag_len; + int i, ret_val; + int ncmd = 1, step = 1; + + RTKBT_DBG("%s: start", __func__); + + cmd_para = (download_cp *)fw_info->req_para; + evt_para = (download_rp *)fw_info->rsp_para; + pcur = fw_info->fw_data; + pkt_len = CMD_HDR_LEN + sizeof(download_cp); + frag_num = fw_info->fw_len / PATCH_SEG_MAX + 1; + frag_len = PATCH_SEG_MAX; + + for (i = 0; i < frag_num; i++) { + cmd_para->index = i?((i-1)%0x7f+1):0; + if (i == (frag_num - 1)) { + cmd_para->index |= DATA_END; + frag_len = fw_info->fw_len % PATCH_SEG_MAX; + pkt_len -= (PATCH_SEG_MAX - frag_len); + } + fw_info->cmd_hdr->opcode = cpu_to_le16(DOWNLOAD_OPCODE); + fw_info->cmd_hdr->plen = sizeof(uint8_t) + frag_len; + fw_info->pkt_len = pkt_len; + memcpy(cmd_para->data, pcur, frag_len); + + if (step > 0) { + ret_val = send_hci_cmd(fw_info); + if (ret_val < 0) { + RTKBT_DBG("%s: Failed to send frag num %d", __func__, cmd_para->index); + return ret_val; + } else + RTKBT_DBG("%s: Send frag num %d", __func__, cmd_para->index); + + if (--step > 0 && i < frag_num - 1) { + RTKBT_DBG("%s: Continue to send frag num %d", __func__, cmd_para->index + 1); + pcur += PATCH_SEG_MAX; + continue; + } + } + + while (ncmd > 0) { + ret_val = rcv_hci_evt(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val); + return ret_val; + } else { + RTKBT_DBG("%s: Receive acked frag num %d", __func__, evt_para->index); + ncmd--; + } + + if (0 != evt_para->status) { + RTKBT_ERR("%s: Receive acked frag num %d, err status %d", + __func__, ret_val, evt_para->status); + return -1; + } + + if ((evt_para->index & DATA_END) || (evt_para->index == frag_num - 1)) { + RTKBT_DBG("%s: Receive last acked index %d", __func__, evt_para->index); + goto end; + } + } + + ncmd = step = fw_info->cmd_cmp->ncmd; + pcur += PATCH_SEG_MAX; + RTKBT_DBG("%s: HCI command packet num %d", __func__, ncmd); + } + + /* + * It is tricky that Host cannot receive DATA_END index from BT + * controller, at least for 8723au. We are doomed if failed. + */ +#if 0 + /* Continue to receive the responsed events until last index occurs */ + if (i == frag_num) { + RTKBT_DBG("%s: total frag count %d", __func__, frag_num); + while (!(evt_para->index & DATA_END)) { + ret_val = rcv_hci_evt(fw_info); + if (ret_val < 0) { + RTKBT_ERR("%s: rcv_hci_evt err %d", __func__, ret_val); + return ret_val; + } + if (0 != evt_para->status) + return -1; + RTKBT_DBG("%s: continue to receive acked frag num %d", __func__, evt_para->index); + } + } +#endif +end: + RTKBT_INFO("%s: done, sent %d frag pkts, received %d frag events", + __func__, cmd_para->index, evt_para->index); + return fw_info->fw_len; +} + +int download_patch(firmware_info *fw_info, int cached) +{ + int ret_val = 0; + + RTKBT_DBG("%s: Download fw patch start, cached %d", __func__, cached); + + if (!fw_info || !fw_info->patch_entry) { + RTKBT_ERR("%s: No patch entry exists(fw_info %p)", __func__, fw_info); + ret_val = -1; + goto end; + } + + /* + * step1: get local firmware if existed + * step2: check firmware version + * step3: download firmware if updated + */ + ret_val = get_firmware(fw_info, cached); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to get firmware", __func__); + goto end; + } + +#if SUSPNED_DW_FW + if(fw_info_4_suspend) { + RTKBT_DBG("%s: get suspend fw first cached %d", __func__, cached); + ret_val = get_suspend_firmware(fw_info_4_suspend, cached); + if (ret_val < 0) { + RTKBT_ERR("%s: Failed to get suspend firmware", __func__); + goto end; + } + } +#endif + + /*check the length of fw to be download*/ + RTKBT_DBG("%s: Check fw_info->fw_len:%d max_patch_size %d", __func__, fw_info->fw_len, fw_info->patch_entry->max_patch_size); + if (fw_info->fw_len > fw_info->patch_entry->max_patch_size) { + RTKBT_ERR("%s: Total length of fw&config(%08x) larger than max_patch_size 0x%08x", __func__, fw_info->fw_len, fw_info->patch_entry->max_patch_size); + ret_val = -1; + goto free; + } + + ret_val = check_fw_version(fw_info, false); + + if (2 == ret_val) { + RTKBT_ERR("%s: Cold reset bt chip only download", __func__); + ret_val = download_data(fw_info); + if (ret_val > 0) + RTKBT_ERR("%s: Download fw patch done, fw len %d", __func__, ret_val); + } else if(1 == ret_val){ + // reset bt chip to update Fw patch + ret_val = reset_controller(fw_info); + RTKBT_ERR("%s: reset bt chip to update Fw patch, fw len %d", __func__, ret_val); + ret_val = download_data(fw_info); + if (ret_val > 0) + RTKBT_ERR("%s: Download fw patch done, fw len %d", __func__, ret_val); + } + + +free: + /* Free fw data after download finished */ + kfree(fw_info->fw_data); + fw_info->fw_data = NULL; + +end: + return ret_val; +} + +#if SUSPNED_DW_FW +static int download_suspend_patch(firmware_info *fw_info, int cached) +{ + int ret_val = 0; + + RTKBT_DBG("%s: Download fw patch start, cached %d", __func__, cached); + + if (!fw_info || !fw_info->patch_entry) { + RTKBT_ERR("%s: No patch entry exists(fw_info %p)", __func__, fw_info); + ret_val = -1; + goto end; + } + + /*check the length of fw to be download*/ + RTKBT_DBG("%s:Check RTK_PATCH_LENGTH fw_info->fw_len:%d", __func__,fw_info->fw_len); + if (fw_info->fw_len > fw_info->patch_entry->max_patch_size || fw_info->fw_len == 0) { + RTKBT_ERR("%s: Total length of fw&config(%08x) larger than max_patch_size 0x%08x", __func__, fw_info->fw_len, fw_info->patch_entry->max_patch_size); + ret_val = -1; + goto free; + } + + ret_val = check_fw_version(fw_info, false); + + if (2 == ret_val) { + RTKBT_ERR("%s: Cold reset bt chip only download", __func__); + ret_val = download_data(fw_info); + if (ret_val > 0) + RTKBT_ERR("%s: Download fw patch done, fw len %d", __func__, ret_val); + } else if(1 == ret_val){ + // reset bt chip to update Fw patch + ret_val = reset_controller(fw_info); + RTKBT_ERR("%s: reset bt chip to update Fw patch, fw len %d", __func__, ret_val); + ret_val = download_data(fw_info); + if (ret_val > 0) + RTKBT_ERR("%s: Download fw patch done, fw len %d", __func__, ret_val); + } + + +free: + /* Free fw data after download finished */ + kfree(fw_info->fw_data); + fw_info->fw_data = NULL; + +end: + return ret_val; +} + +static void suspend_firmware_info_init(firmware_info *fw_info) +{ + RTKBT_DBG("%s: start", __func__); + if(!fw_info) + return; + + fw_info_4_suspend= kzalloc(sizeof(*fw_info), GFP_KERNEL); + if (!fw_info_4_suspend) + goto error; + + fw_info_4_suspend->send_pkt = kzalloc(PKT_LEN, GFP_KERNEL); + if (!fw_info_4_suspend->send_pkt) { + kfree(fw_info_4_suspend); + goto error; + } + + fw_info_4_suspend->rcv_pkt = kzalloc(PKT_LEN, GFP_KERNEL); + if (!fw_info_4_suspend->rcv_pkt) { + kfree(fw_info_4_suspend->send_pkt); + kfree(fw_info_4_suspend); + goto error; + } + + fw_info_4_suspend->patch_entry = get_suspend_fw_table_entry(fw_info->udev); + if (!fw_info_4_suspend->patch_entry) { + kfree(fw_info_4_suspend->rcv_pkt); + kfree(fw_info_4_suspend->send_pkt); + kfree(fw_info_4_suspend); + goto error; + } + + fw_info_4_suspend->intf = fw_info->intf; + fw_info_4_suspend->udev = fw_info->udev; + fw_info_4_suspend->cmd_hdr = (struct hci_command_hdr *)(fw_info_4_suspend->send_pkt); + fw_info_4_suspend->evt_hdr = (struct hci_event_hdr *)(fw_info_4_suspend->rcv_pkt); + fw_info_4_suspend->cmd_cmp = (struct hci_ev_cmd_complete *)(fw_info_4_suspend->rcv_pkt + EVT_HDR_LEN); + fw_info_4_suspend->req_para = fw_info_4_suspend->send_pkt + CMD_HDR_LEN; + fw_info_4_suspend->rsp_para = fw_info_4_suspend->rcv_pkt + EVT_HDR_LEN + CMD_CMP_LEN; + fw_info_4_suspend->pipe_in = fw_info->pipe_in; + fw_info_4_suspend->pipe_out = fw_info->pipe_out; + + return; +error: + RTKBT_DBG("%s: fail !", __func__); + fw_info_4_suspend = NULL; + return; +} +#endif + +#if SET_WAKEUP_DEVICE +static void set_wakeup_device_from_conf(firmware_info *fw_info) +{ + uint8_t paired_wakeup_bdaddr[7]; + uint8_t num = 0; + int i; + struct file *fp; + mm_segment_t fs; + loff_t pos; + + memset(paired_wakeup_bdaddr, 0, 7); + fp = filp_open(SET_WAKEUP_DEVICE_CONF, O_RDWR, 0); + if (!IS_ERR(fp)) { + fs = get_fs(); + set_fs(KERNEL_DS); + pos = 0; + //read number + vfs_read(fp, &num, 1, &pos); + RTKBT_DBG("read number = %d", num); + if(num) { + for(i = 0; i < num; i++) { + vfs_read(fp, paired_wakeup_bdaddr, 7, &pos); + RTKBT_DBG("paired_wakeup_bdaddr: 0x%02x:0x%02x:0x%02x:0x%02x:0x%02x:0x%02x", + paired_wakeup_bdaddr[1],paired_wakeup_bdaddr[2],paired_wakeup_bdaddr[3], + paired_wakeup_bdaddr[4],paired_wakeup_bdaddr[5],paired_wakeup_bdaddr[6]); + set_wakeup_device(fw_info, paired_wakeup_bdaddr); + } + } + filp_close(fp, NULL); + set_fs(fs); + } + else { + RTKBT_ERR("open wakeup config file fail! errno = %ld", PTR_ERR(fp)); + } +} +#endif + +firmware_info *firmware_info_init(struct usb_interface *intf) +{ + struct usb_device *udev = interface_to_usbdev(intf); + firmware_info *fw_info; + + RTKBT_DBG("%s: start", __func__); + + fw_info = kzalloc(sizeof(*fw_info), GFP_KERNEL); + if (!fw_info) + return NULL; + + fw_info->send_pkt = kzalloc(PKT_LEN, GFP_KERNEL); + if (!fw_info->send_pkt) { + kfree(fw_info); + return NULL; + } + + fw_info->rcv_pkt = kzalloc(PKT_LEN, GFP_KERNEL); + if (!fw_info->rcv_pkt) { + kfree(fw_info->send_pkt); + kfree(fw_info); + return NULL; + } + + fw_info->patch_entry = get_fw_table_entry(udev); + if (!fw_info->patch_entry) { + kfree(fw_info->rcv_pkt); + kfree(fw_info->send_pkt); + kfree(fw_info); + return NULL; + } + + fw_info->intf = intf; + fw_info->udev = udev; + fw_info->pipe_in = usb_rcvintpipe(fw_info->udev, INTR_EP); + fw_info->pipe_out = usb_sndctrlpipe(fw_info->udev, CTRL_EP); + fw_info->cmd_hdr = (struct hci_command_hdr *)(fw_info->send_pkt); + fw_info->evt_hdr = (struct hci_event_hdr *)(fw_info->rcv_pkt); + fw_info->cmd_cmp = (struct hci_ev_cmd_complete *)(fw_info->rcv_pkt + EVT_HDR_LEN); + fw_info->req_para = fw_info->send_pkt + CMD_HDR_LEN; + fw_info->rsp_para = fw_info->rcv_pkt + EVT_HDR_LEN + CMD_CMP_LEN; + +#if SUSPNED_DW_FW + suspend_firmware_info_init(fw_info); +#endif + +#if BTUSB_RPM + RTKBT_INFO("%s: Auto suspend is enabled", __func__); + usb_enable_autosuspend(udev); + pm_runtime_set_autosuspend_delay(&(udev->dev), 2000); +#else + RTKBT_INFO("%s: Auto suspend is disabled", __func__); + usb_disable_autosuspend(udev); +#endif + +#if BTUSB_WAKEUP_HOST + device_wakeup_enable(&udev->dev); +#endif + + return fw_info; +} + +void firmware_info_destroy(struct usb_interface *intf) +{ + firmware_info *fw_info; + struct usb_device *udev; + struct btusb_data *data; + + udev = interface_to_usbdev(intf); + data = usb_get_intfdata(intf); + + fw_info = data->fw_info; + if (!fw_info) + return; + +#if BTUSB_RPM + usb_disable_autosuspend(udev); +#endif + + /* + * In order to reclaim fw data mem, we free fw_data immediately + * after download patch finished instead of here. + */ + kfree(fw_info->rcv_pkt); + kfree(fw_info->send_pkt); + kfree(fw_info); + +#if SUSPNED_DW_FW + if (!fw_info_4_suspend) + return; + + kfree(fw_info_4_suspend->rcv_pkt); + kfree(fw_info_4_suspend->send_pkt); + kfree(fw_info_4_suspend->patch_entry); + kfree(fw_info_4_suspend); + fw_info_4_suspend = NULL; +#endif +} + +static struct usb_driver btusb_driver; + +static struct usb_device_id btusb_table[] = { + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x0bda, + .bInterfaceClass = 0xe0, + .bInterfaceSubClass = 0x01, + .bInterfaceProtocol = 0x01 }, + + { .match_flags = USB_DEVICE_ID_MATCH_VENDOR | + USB_DEVICE_ID_MATCH_INT_INFO, + .idVendor = 0x13d3, + .bInterfaceClass = 0xe0, + .bInterfaceSubClass = 0x01, + .bInterfaceProtocol = 0x01 }, + + { } +}; + +MODULE_DEVICE_TABLE(usb, btusb_table); + +static int inc_tx(struct btusb_data *data) +{ + unsigned long flags; + int rv; + + spin_lock_irqsave(&data->txlock, flags); + rv = test_bit(BTUSB_SUSPENDING, &data->flags); + if (!rv) + data->tx_in_flight++; + spin_unlock_irqrestore(&data->txlock, flags); + + return rv; +} + +void check_sco_event(struct urb *urb) +{ + u8* opcode = (u8*)(urb->transfer_buffer); + u8 status; + uint16_t handle; + struct hci_dev *hdev = urb->context; + struct btusb_data *data = GET_DRV_DATA(hdev); + + switch (*opcode) { + case HCI_EV_SYNC_CONN_COMPLETE: + RTKBT_INFO("%s: HCI_EV_SYNC_CONN_COMPLETE(0x%02x)", __func__, *opcode); + status = *(opcode + 2); + data->sco_handle = *(opcode + 3) | *(opcode + 4) << 8; + //hdev->voice_setting = *(uint16_t*)&opcode[15]; + if (status == 0) { + hdev->conn_hash.sco_num++; + hdev->notify(hdev, 0); + } + break; + case HCI_EV_DISCONN_COMPLETE: + status = *(opcode + 2); + handle = *(opcode + 3) | *(opcode + 4) << 8; + if (status == 0 && data->sco_handle == handle) { + RTKBT_INFO("%s: SCO HCI_EV_DISCONN_COMPLETE(0x%02x)", __func__, *opcode); + hdev->conn_hash.sco_num--; + hdev->notify(hdev, 0); + data->sco_handle = 0; + } + break; + default: + RTKBT_DBG("%s: event 0x%02x", __func__, *opcode); + break; + } +} + +static void btusb_intr_complete(struct urb *urb) +{ + struct hci_dev *hdev = urb->context; + struct btusb_data *data = GET_DRV_DATA(hdev); + int err; + + RTKBT_DBG("%s: urb %p status %d count %d ", __func__, + urb, urb->status, urb->actual_length); + +#ifdef CONFIG_SCO_OVER_HCI + check_sco_event(urb); +#endif + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return; + + + if (urb->status == 0) { + hdev->stat.byte_rx += urb->actual_length; + + if (hci_recv_fragment(hdev, HCI_EVENT_PKT, + urb->transfer_buffer, + urb->actual_length) < 0) { + RTKBT_ERR("%s: Corrupted event packet", __func__); + hdev->stat.err_rx++; + } + } + /* Avoid suspend failed when usb_kill_urb */ + else if(urb->status == -ENOENT) { + return; + } + + + if (!test_bit(BTUSB_INTR_RUNNING, &data->flags)) + return; + + usb_mark_last_busy(data->udev); + usb_anchor_urb(urb, &data->intr_anchor); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + /* EPERM: urb is being killed; + * ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) + RTKBT_ERR("%s: Failed to re-submit urb %p, err %d", + __func__, urb, err); + usb_unanchor_urb(urb); + } +} + +static int btusb_submit_intr_urb(struct hci_dev *hdev, gfp_t mem_flags) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + struct urb *urb; + unsigned char *buf; + unsigned int pipe; + int err, size; + + if (!data->intr_ep) + return -ENODEV; + + urb = usb_alloc_urb(0, mem_flags); + if (!urb) + return -ENOMEM; + + size = le16_to_cpu(data->intr_ep->wMaxPacketSize); + + buf = kmalloc(size, mem_flags); + if (!buf) { + usb_free_urb(urb); + return -ENOMEM; + } + + RTKBT_DBG("%s: mMaxPacketSize %d, bEndpointAddress 0x%02x", + __func__, size, data->intr_ep->bEndpointAddress); + + pipe = usb_rcvintpipe(data->udev, data->intr_ep->bEndpointAddress); + + usb_fill_int_urb(urb, data->udev, pipe, buf, size, + btusb_intr_complete, hdev, + data->intr_ep->bInterval); + + urb->transfer_flags |= URB_FREE_BUFFER; + + usb_anchor_urb(urb, &data->intr_anchor); + + err = usb_submit_urb(urb, mem_flags); + if (err < 0) { + RTKBT_ERR("%s: Failed to submit urb %p, err %d", + __func__, urb, err); + usb_unanchor_urb(urb); + } + + usb_free_urb(urb); + + return err; +} + +static void btusb_bulk_complete(struct urb *urb) +{ + struct hci_dev *hdev = urb->context; + struct btusb_data *data = GET_DRV_DATA(hdev); + int err; + + RTKBT_DBG("%s: urb %p status %d count %d", + __func__, urb, urb->status, urb->actual_length); + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return; + + if (urb->status == 0) { + hdev->stat.byte_rx += urb->actual_length; + + if (hci_recv_fragment(hdev, HCI_ACLDATA_PKT, + urb->transfer_buffer, + urb->actual_length) < 0) { + RTKBT_ERR("%s: Corrupted ACL packet", __func__); + hdev->stat.err_rx++; + } + } + /* Avoid suspend failed when usb_kill_urb */ + else if(urb->status == -ENOENT) { + return; + } + + + if (!test_bit(BTUSB_BULK_RUNNING, &data->flags)) + return; + + usb_anchor_urb(urb, &data->bulk_anchor); + usb_mark_last_busy(data->udev); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) + RTKBT_ERR("btusb_bulk_complete %s urb %p failed to resubmit (%d)", + hdev->name, urb, -err); + usb_unanchor_urb(urb); + } +} + +static int btusb_submit_bulk_urb(struct hci_dev *hdev, gfp_t mem_flags) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + struct urb *urb; + unsigned char *buf; + unsigned int pipe; + int err, size = HCI_MAX_FRAME_SIZE; + + RTKBT_DBG("%s: hdev name %s", __func__, hdev->name); + + if (!data->bulk_rx_ep) + return -ENODEV; + + urb = usb_alloc_urb(0, mem_flags); + if (!urb) + return -ENOMEM; + + buf = kmalloc(size, mem_flags); + if (!buf) { + usb_free_urb(urb); + return -ENOMEM; + } + + pipe = usb_rcvbulkpipe(data->udev, data->bulk_rx_ep->bEndpointAddress); + + usb_fill_bulk_urb(urb, data->udev, pipe, + buf, size, btusb_bulk_complete, hdev); + + urb->transfer_flags |= URB_FREE_BUFFER; + + usb_mark_last_busy(data->udev); + usb_anchor_urb(urb, &data->bulk_anchor); + + err = usb_submit_urb(urb, mem_flags); + if (err < 0) { + RTKBT_ERR("%s: Failed to submit urb %p, err %d", __func__, urb, err); + usb_unanchor_urb(urb); + } + + usb_free_urb(urb); + + return err; +} + +static void btusb_isoc_complete(struct urb *urb) +{ + struct hci_dev *hdev = urb->context; + struct btusb_data *data = GET_DRV_DATA(hdev); + int i, err; + + + RTKBT_DBG("%s: urb %p status %d count %d", + __func__, urb, urb->status, urb->actual_length); + + if (!test_bit(HCI_RUNNING, &hdev->flags) || !test_bit(BTUSB_ISOC_RUNNING, &data->flags)) + return; + + if (urb->status == 0) { + for (i = 0; i < urb->number_of_packets; i++) { + unsigned int offset = urb->iso_frame_desc[i].offset; + unsigned int length = urb->iso_frame_desc[i].actual_length; + + if (urb->iso_frame_desc[i].status) + continue; + + hdev->stat.byte_rx += length; + + if (hci_recv_fragment(hdev, HCI_SCODATA_PKT, + urb->transfer_buffer + offset, + length) < 0) { + RTKBT_ERR("%s: Corrupted SCO packet", __func__); + hdev->stat.err_rx++; + } + } + } + /* Avoid suspend failed when usb_kill_urb */ + else if(urb->status == -ENOENT) { + return; + } + + usb_anchor_urb(urb, &data->isoc_anchor); + i = 0; +retry: + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + /* -EPERM: urb is being killed; + * -ENODEV: device got disconnected */ + if (err != -EPERM && err != -ENODEV) + RTKBT_ERR("%s: Failed to re-sumbit urb %p, retry %d, err %d", + __func__, urb, i, err); + if (i < 10) { + i++; + mdelay(1); + goto retry; + } + + usb_unanchor_urb(urb); + } +} + +static inline void fill_isoc_descriptor(struct urb *urb, int len, int mtu) +{ + int i, offset = 0; + + RTKBT_DBG("%s: len %d mtu %d", __func__, len, mtu); + + for (i = 0; i < BTUSB_MAX_ISOC_FRAMES && len >= mtu; + i++, offset += mtu, len -= mtu) { + urb->iso_frame_desc[i].offset = offset; + urb->iso_frame_desc[i].length = mtu; + } + + if (len && i < BTUSB_MAX_ISOC_FRAMES) { + urb->iso_frame_desc[i].offset = offset; + urb->iso_frame_desc[i].length = len; + i++; + } + + urb->number_of_packets = i; +} + +static int btusb_submit_isoc_urb(struct hci_dev *hdev, gfp_t mem_flags) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + struct urb *urb; + unsigned char *buf; + unsigned int pipe; + int err, size; + + if (!data->isoc_rx_ep) + return -ENODEV; + + urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, mem_flags); + if (!urb) + return -ENOMEM; + + size = le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize) * + BTUSB_MAX_ISOC_FRAMES; + + buf = kmalloc(size, mem_flags); + if (!buf) { + usb_free_urb(urb); + return -ENOMEM; + } + + pipe = usb_rcvisocpipe(data->udev, data->isoc_rx_ep->bEndpointAddress); + + urb->dev = data->udev; + urb->pipe = pipe; + urb->context = hdev; + urb->complete = btusb_isoc_complete; + urb->interval = data->isoc_rx_ep->bInterval; + + urb->transfer_flags = URB_FREE_BUFFER | URB_ISO_ASAP; + urb->transfer_buffer = buf; + urb->transfer_buffer_length = size; + + fill_isoc_descriptor(urb, size, + le16_to_cpu(data->isoc_rx_ep->wMaxPacketSize)); + + usb_anchor_urb(urb, &data->isoc_anchor); + + err = usb_submit_urb(urb, mem_flags); + if (err < 0) { + RTKBT_ERR("%s: Failed to submit urb %p, err %d", __func__, urb, err); + usb_unanchor_urb(urb); + } + + usb_free_urb(urb); + + return err; +} + +static void btusb_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + struct btusb_data *data = GET_DRV_DATA(hdev); + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + goto done; + + if (!urb->status) + hdev->stat.byte_tx += urb->transfer_buffer_length; + else + hdev->stat.err_tx++; + +done: + spin_lock(&data->txlock); + data->tx_in_flight--; + spin_unlock(&data->txlock); + + kfree(urb->setup_packet); + + kfree_skb(skb); +} + +static void btusb_isoc_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + + RTKBT_DBG("%s: urb %p status %d count %d", + __func__, urb, urb->status, urb->actual_length); + + if (skb && hdev) { + if (!test_bit(HCI_RUNNING, &hdev->flags)) + goto done; + + if (!urb->status) + hdev->stat.byte_tx += urb->transfer_buffer_length; + else + hdev->stat.err_tx++; + } else + RTKBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev); + +done: + kfree(urb->setup_packet); + + kfree_skb(skb); +} + +static int btusb_open(struct hci_dev *hdev) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + int i, err = 0; + + firmware_info *fw_info = data->fw_info; + reset_and_clean_hw_buffer(fw_info); + RTKBT_INFO("%s: Start, PM usage count %d", __func__, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) + atomic_read(&data->intf->pm_usage_cnt) +#else + 0 +#endif + ); + + err = usb_autopm_get_interface(data->intf); + if (err < 0) + return err; + + data->intf->needs_remote_wakeup = 1; + for (i = 0; i < NUM_REASSEMBLY; i++) { + if (hdev->reassembly[i]) { + RTKBT_DBG("%s: free ressembly[%d]", __func__, i); + kfree_skb(hdev->reassembly[i]); + hdev->reassembly[i] = NULL; + } + } + + if (test_and_set_bit(HCI_RUNNING, &hdev->flags)) + goto done; + + if (test_and_set_bit(BTUSB_INTR_RUNNING, &data->flags)) + goto done; + + err = btusb_submit_intr_urb(hdev, GFP_KERNEL); + if (err < 0) + goto failed; + + err = btusb_submit_bulk_urb(hdev, GFP_KERNEL); + if (err < 0) { + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->intr_anchor); + goto failed; + } + + set_bit(BTUSB_BULK_RUNNING, &data->flags); + btusb_submit_bulk_urb(hdev, GFP_KERNEL); + +done: + usb_autopm_put_interface(data->intf); + + RTKBT_INFO("%s: End, PM usage count %d", __func__, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) + atomic_read(&data->intf->pm_usage_cnt) +#else + 0 +#endif + ); + return 0; + +failed: + clear_bit(BTUSB_INTR_RUNNING, &data->flags); + clear_bit(HCI_RUNNING, &hdev->flags); + usb_autopm_put_interface(data->intf); + + RTKBT_ERR("%s: Failed, PM usage count %d", __func__, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) + atomic_read(&data->intf->pm_usage_cnt) +#else + 0 +#endif + ); + return err; +} + +static void btusb_stop_traffic(struct btusb_data *data) +{ + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->intr_anchor); + usb_kill_anchored_urbs(&data->bulk_anchor); + usb_kill_anchored_urbs(&data->isoc_anchor); +} + +static int btusb_close(struct hci_dev *hdev) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + int err; + + RTKBT_INFO("%s: hci running %lu", __func__, hdev->flags & HCI_RUNNING); + + if (!test_and_clear_bit(HCI_RUNNING, &hdev->flags)) + return 0; + + cancel_work_sync(&data->work); + cancel_work_sync(&data->waker); + + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + clear_bit(BTUSB_BULK_RUNNING, &data->flags); + clear_bit(BTUSB_INTR_RUNNING, &data->flags); + + btusb_stop_traffic(data); + err = usb_autopm_get_interface(data->intf); + if (err < 0) + goto failed; + + data->intf->needs_remote_wakeup = 0; + usb_autopm_put_interface(data->intf); + +failed: + mdelay(URB_CANCELING_DELAY_MS); + usb_scuttle_anchored_urbs(&data->deferred); + return 0; +} + +static int btusb_flush(struct hci_dev *hdev) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + + RTKBT_DBG("%s", __func__); + + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->tx_anchor); + + return 0; +} + +#ifdef CONFIG_SCO_OVER_HCI +static void btusb_isoc_snd_tx_complete(struct urb *urb); + +static int snd_send_sco_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + + struct btusb_data *data = GET_DRV_DATA(hdev); + //struct usb_ctrlrequest *dr; + struct urb *urb; + unsigned int pipe; + int err; + + RTKBT_DBG("%s:pkt type %d, packet_len : %d", + __func__,bt_cb(skb)->pkt_type, skb->len); + + if (!hdev && !test_bit(HCI_RUNNING, &hdev->flags)) + return -EBUSY; + + if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) { + kfree(skb); + return -ENODEV; + } + + urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); + if (!urb) { + RTKBT_ERR("%s: Failed to allocate mem for sco pkts", __func__); + kfree(skb); + return -ENOMEM; + } + + pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); + + usb_fill_int_urb(urb, data->udev, pipe, + skb->data, skb->len, btusb_isoc_snd_tx_complete, + skb, data->isoc_tx_ep->bInterval); + + urb->transfer_flags = URB_ISO_ASAP; + + fill_isoc_descriptor(urb, skb->len, + le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); + + hdev->stat.sco_tx++; + + usb_anchor_urb(urb, &data->tx_anchor); + + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + RTKBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d", + __func__, urb, bt_cb(skb)->pkt_type, err); + kfree(urb->setup_packet); + usb_unanchor_urb(urb); + } else + usb_mark_last_busy(data->udev); + usb_free_urb(urb); + + return err; + +} + +static bool snd_copy_send_sco_data( RTK_sco_card_t *pSCOSnd) +{ + struct snd_pcm_runtime *runtime = pSCOSnd->playback.substream->runtime; + unsigned int frame_bytes = 2, frames1; + const u8 *source; + + snd_pcm_uframes_t period_size = runtime->period_size; + int i, count; + u8 buffer[period_size * 3]; + int sco_packet_bytes = pSCOSnd->playback.sco_packet_bytes; + struct sk_buff *skb; + + count = frames_to_bytes(runtime, period_size)/sco_packet_bytes; + skb = bt_skb_alloc(((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count), GFP_ATOMIC); + skb->dev = (void *)hci_dev_get(0); + bt_cb(skb)->pkt_type = HCI_SCODATA_PKT; + skb_put(skb, ((sco_packet_bytes + HCI_SCO_HDR_SIZE) * count)); + if(!skb) + return false; + + RTKBT_DBG("%s, buffer_pos: %d", __FUNCTION__, pSCOSnd->playback.buffer_pos); + + source = runtime->dma_area + pSCOSnd->playback.buffer_pos * frame_bytes; + + if (pSCOSnd->playback.buffer_pos + period_size <= runtime->buffer_size) { + memcpy(buffer, source, period_size * frame_bytes); + } else { + /* wrap around at end of ring buffer */ + frames1 = runtime->buffer_size - pSCOSnd->playback.buffer_pos; + memcpy(buffer, source, frames1 * frame_bytes); + memcpy(&buffer[frames1 * frame_bytes], + runtime->dma_area, (period_size - frames1) * frame_bytes); + } + + pSCOSnd->playback.buffer_pos += period_size; + if ( pSCOSnd->playback.buffer_pos >= runtime->buffer_size) + pSCOSnd->playback.buffer_pos -= runtime->buffer_size; + + for(i = 0; i < count; i++) { + *((__u16 *)(skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE))) = pSCOSnd->usb_data->sco_handle; + *((__u8 *)(skb->data + i*(sco_packet_bytes + HCI_SCO_HDR_SIZE) + 2)) = sco_packet_bytes; + memcpy((skb->data + i * (sco_packet_bytes + HCI_SCO_HDR_SIZE) + HCI_SCO_HDR_SIZE), + &buffer[sco_packet_bytes * i], sco_packet_bytes); + } + + if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)) { + snd_pcm_period_elapsed(pSCOSnd->playback.substream); + } + snd_send_sco_frame(skb); + return true; +} + +static void btusb_isoc_snd_tx_complete(struct urb *urb) +{ + struct sk_buff *skb = urb->context; + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + struct btusb_data *data = GET_DRV_DATA(hdev); + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + + RTKBT_DBG("%s: status %d count %d", + __func__,urb->status, urb->actual_length); + + if (skb && hdev) { + if (!test_bit(HCI_RUNNING, &hdev->flags)) + goto done; + + if (!urb->status) + hdev->stat.byte_tx += urb->transfer_buffer_length; + else + hdev->stat.err_tx++; + } else + RTKBT_ERR("%s: skb 0x%p hdev 0x%p", __func__, skb, hdev); + +done: + kfree(urb->setup_packet); + kfree_skb(skb); + if(test_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states)){ + snd_copy_send_sco_data(pSCOSnd); + //schedule_work(&pSCOSnd->send_sco_work); + } +} + +static void playback_work(struct work_struct *work) +{ + RTK_sco_card_t *pSCOSnd = container_of(work, RTK_sco_card_t, send_sco_work); + + snd_copy_send_sco_data(pSCOSnd); +} + +#endif + +static int btusb_send_frame(struct sk_buff *skb) +{ + struct hci_dev *hdev = (struct hci_dev *) skb->dev; + + struct btusb_data *data = GET_DRV_DATA(hdev); + struct usb_ctrlrequest *dr; + struct urb *urb; + unsigned int pipe; + int err; + int retries = 0; + + RTKBT_DBG("%s: hdev %p, btusb data %p, pkt type %d", + __func__, hdev, data, bt_cb(skb)->pkt_type); + + if (!test_bit(HCI_RUNNING, &hdev->flags)) + return -EBUSY; + + switch (bt_cb(skb)->pkt_type) { + case HCI_COMMAND_PKT: + print_command(skb); + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + + dr = kmalloc(sizeof(*dr), GFP_ATOMIC); + if (!dr) { + usb_free_urb(urb); + return -ENOMEM; + } + + dr->bRequestType = data->cmdreq_type; + dr->bRequest = 0; + dr->wIndex = 0; + dr->wValue = 0; + dr->wLength = __cpu_to_le16(skb->len); + + pipe = usb_sndctrlpipe(data->udev, 0x00); + + usb_fill_control_urb(urb, data->udev, pipe, (void *) dr, + skb->data, skb->len, btusb_tx_complete, skb); + + hdev->stat.cmd_tx++; + break; + + case HCI_ACLDATA_PKT: + print_acl(skb, 1); + if (!data->bulk_tx_ep) + return -ENODEV; + + urb = usb_alloc_urb(0, GFP_ATOMIC); + if (!urb) + return -ENOMEM; + + pipe = usb_sndbulkpipe(data->udev, + data->bulk_tx_ep->bEndpointAddress); + + usb_fill_bulk_urb(urb, data->udev, pipe, + skb->data, skb->len, btusb_tx_complete, skb); + + hdev->stat.acl_tx++; + break; + + case HCI_SCODATA_PKT: + print_sco(skb, 1); + if (!data->isoc_tx_ep || hdev->conn_hash.sco_num < 1) { + kfree(skb); + return -ENODEV; + } + + urb = usb_alloc_urb(BTUSB_MAX_ISOC_FRAMES, GFP_ATOMIC); + if (!urb) { + RTKBT_ERR("%s: Failed to allocate mem for sco pkts", __func__); + kfree(skb); + return -ENOMEM; + } + + pipe = usb_sndisocpipe(data->udev, data->isoc_tx_ep->bEndpointAddress); + + usb_fill_int_urb(urb, data->udev, pipe, + skb->data, skb->len, btusb_isoc_tx_complete, + skb, data->isoc_tx_ep->bInterval); + + urb->transfer_flags = URB_ISO_ASAP; + + fill_isoc_descriptor(urb, skb->len, + le16_to_cpu(data->isoc_tx_ep->wMaxPacketSize)); + + hdev->stat.sco_tx++; + goto skip_waking; + + default: + return -EILSEQ; + } + + err = inc_tx(data); + if (err) { + usb_anchor_urb(urb, &data->deferred); + schedule_work(&data->waker); + err = 0; + goto done; + } + +skip_waking: + usb_anchor_urb(urb, &data->tx_anchor); +retry: + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + RTKBT_ERR("%s: Failed to submit urb %p, pkt type %d, err %d, retries %d", + __func__, urb, bt_cb(skb)->pkt_type, err, retries); + if ((bt_cb(skb)->pkt_type != HCI_SCODATA_PKT) && (retries < 10)) { + mdelay(1); + + if (bt_cb(skb)->pkt_type == HCI_COMMAND_PKT) + print_error_command(skb); + retries++; + goto retry; + } + kfree(urb->setup_packet); + usb_unanchor_urb(urb); + } else + usb_mark_last_busy(data->udev); + usb_free_urb(urb); + +done: + return err; +} + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) +static void btusb_destruct(struct hci_dev *hdev) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + + RTKBT_DBG("%s: name %s", __func__, hdev->name); + + kfree(data); +} +#endif + +static void btusb_notify(struct hci_dev *hdev, unsigned int evt) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + + RTKBT_DBG("%s: name %s, evt %d", __func__, hdev->name, evt); + + RTKBT_INFO("%s: hdev->conn_hash.sco_num= %d, data->sco_num = %d", __func__, hdev->conn_hash.sco_num, + data->sco_num); + if (hdev->conn_hash.sco_num != data->sco_num) { + data->sco_num = hdev->conn_hash.sco_num; + schedule_work(&data->work); + } +} + +static inline int set_isoc_interface(struct hci_dev *hdev, int altsetting) +{ + struct btusb_data *data = GET_DRV_DATA(hdev); + struct usb_interface *intf = data->isoc; + struct usb_endpoint_descriptor *ep_desc; + int i, err; + + if (!data->isoc) + return -ENODEV; + + err = usb_set_interface(data->udev, 1, altsetting); + if (err < 0) { + RTKBT_ERR("%s: Failed to set interface, altsetting %d, err %d", + __func__, altsetting, err); + return err; + } + + data->isoc_altsetting = altsetting; + + data->isoc_tx_ep = NULL; + data->isoc_rx_ep = NULL; + + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { + ep_desc = &intf->cur_altsetting->endpoint[i].desc; + + if (!data->isoc_tx_ep && usb_endpoint_is_isoc_out(ep_desc)) { + data->isoc_tx_ep = ep_desc; + continue; + } + + if (!data->isoc_rx_ep && usb_endpoint_is_isoc_in(ep_desc)) { + data->isoc_rx_ep = ep_desc; + continue; + } + } + + if (!data->isoc_tx_ep || !data->isoc_rx_ep) { + RTKBT_ERR("%s: Invalid SCO descriptors", __func__); + return -ENODEV; + } + + return 0; +} + +static int check_controller_support_msbc( struct usb_device *udev) +{ + //fix this in the future,when new card support msbc decode and encode + RTKBT_INFO("%s:pid = 0x%02x, vid = 0x%02x",__func__,udev->descriptor.idProduct, udev->descriptor.idVendor); + switch (udev->descriptor.idProduct) { + + default: + return 0; + } + return 0; +} + +static void btusb_work(struct work_struct *work) +{ + struct btusb_data *data = container_of(work, struct btusb_data, work); + struct hci_dev *hdev = data->hdev; + struct sk_buff *skb; + + int err; + int new_alts; + if (data->sco_num > 0) { + if (!test_bit(BTUSB_DID_ISO_RESUME, &data->flags)) { + err = usb_autopm_get_interface(data->isoc ? data->isoc : data->intf); + if (err < 0) { + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->isoc_anchor); + return; + } + + set_bit(BTUSB_DID_ISO_RESUME, &data->flags); + } + + RTKBT_INFO("%s voice settings = 0x%04x", __func__, hdev->voice_setting); + if (!(hdev->voice_setting & 0x0003)) { + if(data->sco_num == 1) + new_alts = 2; + else { + RTKBT_ERR("%s: we don't support mutiple sco link for cvsd", __func__); + return; + } + } else{ + if(check_controller_support_msbc(data->udev)) { + if(data->sco_num == 1) + new_alts = 4; + else { + RTKBT_ERR("%s: we don't support mutiple sco link for msbc", __func__); + return; + } + } else { + new_alts = 2; + } + } + if (data->isoc_altsetting != new_alts) { + + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->isoc_anchor); + + if(hdev->reassembly[HCI_SCODATA_PKT - 1]) { + skb = hdev->reassembly[HCI_SCODATA_PKT - 1]; + hdev->reassembly[HCI_SCODATA_PKT - 1] = NULL; + kfree_skb(skb); + } + if (set_isoc_interface(hdev, new_alts) < 0) + return; + } + + if (!test_and_set_bit(BTUSB_ISOC_RUNNING, &data->flags)) { + if (btusb_submit_isoc_urb(hdev, GFP_KERNEL) < 0) + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + else + btusb_submit_isoc_urb(hdev, GFP_KERNEL); + } +#ifdef CONFIG_SCO_OVER_HCI + if(test_bit(BTUSB_ISOC_RUNNING, &data->flags)) { + set_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states); + set_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states); + } +#endif + } else { + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); +#ifdef CONFIG_SCO_OVER_HCI + clear_bit(USB_CAPTURE_RUNNING, &data->pSCOSnd->states); + clear_bit(USB_PLAYBACK_RUNNING, &data->pSCOSnd->states); +#endif + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->isoc_anchor); + + set_isoc_interface(hdev, 0); + + if (test_and_clear_bit(BTUSB_DID_ISO_RESUME, &data->flags)) + usb_autopm_put_interface(data->isoc ? data->isoc : data->intf); + } +} + +static void btusb_waker(struct work_struct *work) +{ + struct btusb_data *data = container_of(work, struct btusb_data, waker); + int err; + + RTKBT_DBG("%s: PM usage count %d", __func__, +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 9, 0) + atomic_read(&data->intf->pm_usage_cnt) +#else + 0 +#endif + ); + + err = usb_autopm_get_interface(data->intf); + if (err < 0) + return; + + usb_autopm_put_interface(data->intf); +} + + +//#ifdef CONFIG_HAS_EARLYSUSPEND +#if 0 +static void btusb_early_suspend(struct early_suspend *h) +{ + struct btusb_data *data; + firmware_info *fw_info; + patch_info *patch_entry; + + RTKBT_INFO("%s", __func__); + + data = container_of(h, struct btusb_data, early_suspend); + fw_info = data->fw_info; + patch_entry = fw_info->patch_entry; + + patch_entry->fw_len = load_firmware(fw_info, &patch_entry->fw_cache); + if (patch_entry->fw_len <= 0) { + /* We may encount failure in loading firmware, just give a warning */ + RTKBT_WARN("%s: Failed to load firmware", __func__); + } +} + +static void btusb_late_resume(struct early_suspend *h) +{ + struct btusb_data *data; + firmware_info *fw_info; + patch_info *patch_entry; + + RTKBT_INFO("%s", __func__); + + data = container_of(h, struct btusb_data, early_suspend); + fw_info = data->fw_info; + patch_entry = fw_info->patch_entry; + + /* Reclaim fw buffer when bt usb resumed */ + if (patch_entry->fw_len > 0) { + kfree(patch_entry->fw_cache); + patch_entry->fw_cache = NULL; + patch_entry->fw_len = 0; + } +} +#else +int bt_pm_notify(struct notifier_block *notifier, ulong pm_event, void *unused) +{ + struct btusb_data *data; + firmware_info *fw_info; + patch_info *patch_entry; + struct usb_device *udev; + + RTKBT_INFO("%s: pm event %ld", __func__, pm_event); + + data = container_of(notifier, struct btusb_data, pm_notifier); + fw_info = data->fw_info; + patch_entry = fw_info->patch_entry; + udev = fw_info->udev; + + switch (pm_event) { + case PM_SUSPEND_PREPARE: + case PM_HIBERNATION_PREPARE: +#if 0 + patch_entry->fw_len = load_firmware(fw_info, &patch_entry->fw_cache); + if (patch_entry->fw_len <= 0) { + /* We may encount failure in loading firmware, just give a warning */ + RTKBT_WARN("%s: Failed to load firmware", __func__); + } +#endif + if (!device_may_wakeup(&udev->dev)) { +#if (CONFIG_RESET_RESUME || CONFIG_BLUEDROID) + RTKBT_INFO("%s:remote wakeup not supported, reset resume supported", __func__); +#else + fw_info->intf->needs_binding = 1; + RTKBT_INFO("%s:remote wakeup not supported, binding needed", __func__); +#endif + } + break; + + case PM_POST_SUSPEND: + case PM_POST_HIBERNATION: + case PM_POST_RESTORE: +#if 0 + /* Reclaim fw buffer when bt usb resumed */ + if (patch_entry->fw_len > 0) { + kfree(patch_entry->fw_cache); + patch_entry->fw_cache = NULL; + patch_entry->fw_len = 0; + } +#endif + +#if BTUSB_RPM + usb_disable_autosuspend(udev); + usb_enable_autosuspend(udev); + pm_runtime_set_autosuspend_delay(&(udev->dev), 2000); +#endif + break; + + default: + break; + } + + return NOTIFY_DONE; +} + +int bt_reboot_notify(struct notifier_block *notifier, ulong pm_event, void *unused) +{ + struct btusb_data *data; + firmware_info *fw_info; + patch_info *patch_entry; + struct usb_device *udev; + + RTKBT_INFO("%s: pm event %ld", __func__, pm_event); + + data = container_of(notifier, struct btusb_data, reboot_notifier); + fw_info = data->fw_info; + patch_entry = fw_info->patch_entry; + udev = fw_info->udev; + + switch (pm_event) { + case SYS_DOWN: + RTKBT_DBG("%s:system down or restart", __func__); + break; + + case SYS_HALT: + case SYS_POWER_OFF: +#if SUSPNED_DW_FW + cancel_work_sync(&data->work); + + btusb_stop_traffic(data); + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->tx_anchor); + + + if(fw_info_4_suspend) { + download_suspend_patch(fw_info_4_suspend,1); + } + else + RTKBT_ERR("%s: Failed to download suspend fw", __func__); +#endif + +#if SET_WAKEUP_DEVICE + set_wakeup_device_from_conf(fw_info_4_suspend); +#endif + RTKBT_DBG("%s:system halt or power off", __func__); + break; + + default: + break; + } + + return NOTIFY_DONE; +} + +#endif + +#ifdef CONFIG_SCO_OVER_HCI +static const struct snd_pcm_hardware snd_card_sco_capture_default = +{ + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED | + SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES), + .formats = SNDRV_PCM_FMTBIT_S16_LE | SNDRV_PCM_FMTBIT_S8, + .rates = (SNDRV_PCM_RATE_8000), + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = 8 * 768, + .period_bytes_min = 48, + .period_bytes_max = 768, + .periods_min = 1, + .periods_max = 8, + .fifo_size = 8, + +}; + +static int snd_sco_capture_pcm_open(struct snd_pcm_substream * substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + RTKBT_INFO("%s", __FUNCTION__); + pSCOSnd->capture.substream = substream; + + memcpy(&substream->runtime->hw, &snd_card_sco_capture_default, sizeof(struct snd_pcm_hardware)); + + if(check_controller_support_msbc(pSCOSnd->dev)) { + substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000; + substream->runtime->hw.rate_max = 16000; + substream->runtime->hw.period_bytes_min = 96; + substream->runtime->hw.period_bytes_max = 16 * 96; + substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96; + } + set_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states); + return 0; +} + +static int snd_sco_capture_pcm_close(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + clear_bit(ALSA_CAPTURE_OPEN, &pSCOSnd->states); + return 0; +} + +static int snd_sco_capture_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) +{ + RTKBT_DBG("%s, cmd = %d", __FUNCTION__, cmd); + switch (cmd) + { + default: + return snd_pcm_lib_ioctl(substream, cmd, arg); + } + return 0; +} + +static int snd_sco_capture_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params) +{ + + int err; + struct snd_pcm_runtime *runtime = substream->runtime; + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); + RTKBT_INFO("%s,err : %d, runtime state : %d", __FUNCTION__, err, runtime->status->state); + return err; +} + +static int snd_sco_capture_pcm_hw_free(struct snd_pcm_substream * substream) +{ + RTKBT_DBG("%s", __FUNCTION__); + return snd_pcm_lib_free_vmalloc_buffer(substream);; +} + +static int snd_sco_capture_pcm_prepare(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + + RTKBT_INFO("%s", __FUNCTION__); + if (test_bit(DISCONNECTED, &pSCOSnd->states)) + return -ENODEV; + if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states)) + return -EIO; + + if(runtime->rate == 8000) { + if(pSCOSnd->usb_data->isoc_altsetting != 2) + return -ENOEXEC; + pSCOSnd->capture.sco_packet_bytes = 48; + } + else if(runtime->rate == 16000 && check_controller_support_msbc(pSCOSnd->dev)) { + if(pSCOSnd->usb_data->isoc_altsetting != 4) + return -ENOEXEC; + pSCOSnd->capture.sco_packet_bytes = 96; + } + else if(pSCOSnd->usb_data->isoc_altsetting == 2) { + pSCOSnd->capture.sco_packet_bytes = 48; + } + else if(pSCOSnd->usb_data->isoc_altsetting == 1) { + pSCOSnd->capture.sco_packet_bytes = 24; + } + return 0; +} + +static int snd_sco_capture_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + RTKBT_INFO("%s, cmd : %d", __FUNCTION__, cmd); + + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (!test_bit(USB_CAPTURE_RUNNING, &pSCOSnd->states)) + return -EIO; + set_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states); + return 0; + case SNDRV_PCM_TRIGGER_STOP: + clear_bit(ALSA_CAPTURE_RUNNING, &pSCOSnd->states); + return 0; + default: + return -EINVAL; + } +} + +static snd_pcm_uframes_t snd_sco_capture_pcm_pointer(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + return pSCOSnd->capture.buffer_pos; +} + + +static struct snd_pcm_ops snd_sco_capture_pcm_ops = { + .open = snd_sco_capture_pcm_open, + .close = snd_sco_capture_pcm_close, + .ioctl = snd_sco_capture_ioctl, + .hw_params = snd_sco_capture_pcm_hw_params, + .hw_free = snd_sco_capture_pcm_hw_free, + .prepare = snd_sco_capture_pcm_prepare, + .trigger = snd_sco_capture_pcm_trigger, + .pointer = snd_sco_capture_pcm_pointer, +}; + + +static const struct snd_pcm_hardware snd_card_sco_playback_default = +{ + .info = (SNDRV_PCM_INFO_INTERLEAVED | SNDRV_PCM_INFO_NONINTERLEAVED | + SNDRV_PCM_ACCESS_RW_INTERLEAVED | SNDRV_PCM_INFO_FIFO_IN_FRAMES), + .formats = SNDRV_PCM_FMTBIT_S16_LE, + .rates = (SNDRV_PCM_RATE_8000), + .rate_min = 8000, + .rate_max = 8000, + .channels_min = 1, + .channels_max = 1, + .buffer_bytes_max = 8 * 768, + .period_bytes_min = 48, + .period_bytes_max = 768, + .periods_min = 1, + .periods_max = 8, + .fifo_size = 8, +}; + +static int snd_sco_playback_pcm_open(struct snd_pcm_substream * substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + int err = 0; + + RTKBT_INFO("%s, rate : %d", __FUNCTION__, substream->runtime->rate); + memcpy(&substream->runtime->hw, &snd_card_sco_playback_default, sizeof(struct snd_pcm_hardware)); + if(check_controller_support_msbc(pSCOSnd->dev)) { + substream->runtime->hw.rates |= SNDRV_PCM_RATE_16000; + substream->runtime->hw.rate_max = 16000; + substream->runtime->hw.period_bytes_min = 96; + substream->runtime->hw.period_bytes_max = 16 * 96; + substream->runtime->hw.buffer_bytes_max = 8 * 16 * 96; + } + pSCOSnd->playback.substream = substream; + set_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states); + + return err; +} + +static int snd_sco_playback_pcm_close(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + clear_bit(ALSA_PLAYBACK_OPEN, &pSCOSnd->states); + cancel_work_sync(&pSCOSnd->send_sco_work); + return 0; +} + +static int snd_sco_playback_ioctl(struct snd_pcm_substream *substream, unsigned int cmd, void *arg) +{ + RTKBT_DBG("%s, cmd : %d", __FUNCTION__, cmd); + switch (cmd) + { + default: + return snd_pcm_lib_ioctl(substream, cmd, arg); + break; + } + return 0; +} + +static int snd_sco_playback_pcm_hw_params(struct snd_pcm_substream * substream, struct snd_pcm_hw_params * hw_params) +{ + int err; + err = snd_pcm_lib_alloc_vmalloc_buffer(substream, params_buffer_bytes(hw_params)); + return err; +} + +static int snd_sco_palyback_pcm_hw_free(struct snd_pcm_substream * substream) +{ + RTKBT_DBG("%s", __FUNCTION__); + return snd_pcm_lib_free_vmalloc_buffer(substream); +} + +static int snd_sco_playback_pcm_prepare(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + struct snd_pcm_runtime *runtime = substream->runtime; + + RTKBT_INFO("%s, bound_rate = %d", __FUNCTION__, runtime->rate); + + if (test_bit(DISCONNECTED, &pSCOSnd->states)) + return -ENODEV; + if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) + return -EIO; + + if(runtime->rate == 8000) { + if(pSCOSnd->usb_data->isoc_altsetting != 2) + return -ENOEXEC; + pSCOSnd->playback.sco_packet_bytes = 48; + } + else if(runtime->rate == 16000) { + if(pSCOSnd->usb_data->isoc_altsetting != 4) + return -ENOEXEC; + pSCOSnd->playback.sco_packet_bytes = 96; + } + + return 0; +} + +static int snd_sco_playback_pcm_trigger(struct snd_pcm_substream *substream, int cmd) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + RTKBT_INFO("%s, cmd = %d", __FUNCTION__, cmd); + switch (cmd) { + case SNDRV_PCM_TRIGGER_START: + if (!test_bit(USB_PLAYBACK_RUNNING, &pSCOSnd->states)) + return -EIO; + set_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states); + schedule_work(&pSCOSnd->send_sco_work); + return 0; + case SNDRV_PCM_TRIGGER_STOP: + clear_bit(ALSA_PLAYBACK_RUNNING, &pSCOSnd->states); + return 0; + default: + return -EINVAL; + } +} + +static snd_pcm_uframes_t snd_sco_playback_pcm_pointer(struct snd_pcm_substream *substream) +{ + RTK_sco_card_t *pSCOSnd = substream->private_data; + + return pSCOSnd->playback.buffer_pos; +} + + +static struct snd_pcm_ops snd_sco_playback_pcm_ops = { + .open = snd_sco_playback_pcm_open, + .close = snd_sco_playback_pcm_close, + .ioctl = snd_sco_playback_ioctl, + .hw_params = snd_sco_playback_pcm_hw_params, + .hw_free = snd_sco_palyback_pcm_hw_free, + .prepare = snd_sco_playback_pcm_prepare, + .trigger = snd_sco_playback_pcm_trigger, + .pointer = snd_sco_playback_pcm_pointer, +}; + + +static RTK_sco_card_t* btusb_snd_init(struct usb_interface *intf, const struct usb_device_id *id, struct btusb_data *data) +{ + struct snd_card *card; + RTK_sco_card_t *pSCOSnd; + int err=0; + RTKBT_INFO("%s", __func__); + err = snd_card_new(&intf->dev, + -1, RTK_SCO_ID, THIS_MODULE, + sizeof(RTK_sco_card_t), &card); + if (err < 0) { + RTKBT_ERR("%s: sco snd card create fail", __func__); + return NULL; + } + // private data + pSCOSnd = (RTK_sco_card_t *)card->private_data; + pSCOSnd->card = card; + pSCOSnd->dev = interface_to_usbdev(intf); + pSCOSnd->usb_data = data; + + strcpy(card->driver, RTK_SCO_ID); + strcpy(card->shortname, "Realtek sco snd"); + sprintf(card->longname, "Realtek sco over hci: VID:0x%04x, PID:0x%04x", + id->idVendor, pSCOSnd->dev->descriptor.idProduct); + + err = snd_pcm_new(card, RTK_SCO_ID, 0, 1, 1, &pSCOSnd->pcm); + if (err < 0) { + RTKBT_ERR("%s: sco snd card new pcm fail", __func__); + snd_card_free(card); + return NULL; + } + pSCOSnd->pcm->private_data = pSCOSnd; + sprintf(pSCOSnd->pcm->name, "sco_pcm:VID:0x%04x, PID:0x%04x", + id->idVendor, pSCOSnd->dev->descriptor.idProduct); + + snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_PLAYBACK, &snd_sco_playback_pcm_ops); + snd_pcm_set_ops(pSCOSnd->pcm, SNDRV_PCM_STREAM_CAPTURE, &snd_sco_capture_pcm_ops); + + err = snd_card_register(card); + if (err < 0) { + RTKBT_ERR("%s: sco snd card register card fail", __func__); + snd_card_free(card); + return NULL; + } + + spin_lock_init(&pSCOSnd->capture_lock); + spin_lock_init(&pSCOSnd->playback_lock); + INIT_WORK(&pSCOSnd->send_sco_work, playback_work); + return pSCOSnd; +} + +static void btusb_snd_remove(RTK_sco_card_t *pSCOSnd) +{ + if(!pSCOSnd) { + RTKBT_ERR("%s: sco private data is null", __func__); + return; + } + set_bit(DISCONNECTED, &pSCOSnd->states); + snd_card_disconnect(pSCOSnd->card); + snd_card_free_when_closed(pSCOSnd->card); +} +#endif + +static int btusb_probe(struct usb_interface *intf, const struct usb_device_id *id) +{ + struct usb_device *udev = interface_to_usbdev(intf); + struct usb_endpoint_descriptor *ep_desc; + struct btusb_data *data; + struct hci_dev *hdev; + firmware_info *fw_info; + int i, err=0; + + RTKBT_INFO("%s: usb_interface %p, bInterfaceNumber %d, idVendor 0x%04x, " + "idProduct 0x%04x", __func__, intf, + intf->cur_altsetting->desc.bInterfaceNumber, + id->idVendor, id->idProduct); + + /* interface numbers are hardcoded in the spec */ + if (intf->cur_altsetting->desc.bInterfaceNumber != 0) + return -ENODEV; + + RTKBT_DBG("%s: can wakeup = %x, may wakeup = %x", __func__, + device_can_wakeup(&udev->dev), device_may_wakeup(&udev->dev)); + + data = rtk_alloc(intf); + if (!data) + return -ENOMEM; + + for (i = 0; i < intf->cur_altsetting->desc.bNumEndpoints; i++) { + ep_desc = &intf->cur_altsetting->endpoint[i].desc; + + if (!data->intr_ep && usb_endpoint_is_int_in(ep_desc)) { + data->intr_ep = ep_desc; + continue; + } + + if (!data->bulk_tx_ep && usb_endpoint_is_bulk_out(ep_desc)) { + data->bulk_tx_ep = ep_desc; + continue; + } + + if (!data->bulk_rx_ep && usb_endpoint_is_bulk_in(ep_desc)) { + data->bulk_rx_ep = ep_desc; + continue; + } + } + + if (!data->intr_ep || !data->bulk_tx_ep || !data->bulk_rx_ep) { + rtk_free(data); + return -ENODEV; + } + + data->cmdreq_type = USB_TYPE_CLASS; + + data->udev = udev; + data->intf = intf; + + spin_lock_init(&queue_lock); + spin_lock_init(&running_flag_lock); + spin_lock_init(&data->lock); + + INIT_WORK(&data->work, btusb_work); + INIT_WORK(&data->waker, btusb_waker); + spin_lock_init(&data->txlock); + + init_usb_anchor(&data->tx_anchor); + init_usb_anchor(&data->intr_anchor); + init_usb_anchor(&data->bulk_anchor); + init_usb_anchor(&data->isoc_anchor); + init_usb_anchor(&data->deferred); + + fw_info = firmware_info_init(intf); + if (fw_info) + data->fw_info = fw_info; + else { + RTKBT_WARN("%s: Failed to initialize fw info", __func__); + /* Skip download patch */ + goto end; + } + + hdev = hci_alloc_dev(); + if (!hdev) { + rtk_free(data); + data = NULL; + return -ENOMEM; + } + + HDEV_BUS = HCI_USB; + + data->hdev = hdev; + + SET_HCIDEV_DEV(hdev, &intf->dev); + + hdev->open = btusb_open; + hdev->close = btusb_close; + hdev->flush = btusb_flush; + hdev->send = btusb_send_frame; + hdev->notify = btusb_notify; + +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0) + hci_set_drvdata(hdev, data); +#else + hdev->driver_data = data; + hdev->destruct = btusb_destruct; + hdev->owner = THIS_MODULE; +#endif + + /* Interface numbers are hardcoded in the specification */ + data->isoc = usb_ifnum_to_if(data->udev, 1); + if (data->isoc) { + err = usb_driver_claim_interface(&btusb_driver, + data->isoc, data); + if (err < 0) { + hci_free_dev(hdev); + hdev = NULL; + rtk_free(data); + data = NULL; + return err; + } +#ifdef CONFIG_SCO_OVER_HCI + data->pSCOSnd = btusb_snd_init(intf, id, data); +#endif + } + + err = hci_register_dev(hdev); + if (err < 0) { + hci_free_dev(hdev); + hdev = NULL; + rtk_free(data); + data = NULL; + return err; + } + + usb_set_intfdata(intf, data); + +//#ifdef CONFIG_HAS_EARLYSUSPEND +#if 0 + data->early_suspend.level = EARLY_SUSPEND_LEVEL_BLANK_SCREEN; + data->early_suspend.suspend = btusb_early_suspend; + data->early_suspend.resume = btusb_late_resume; + register_early_suspend(&data->early_suspend); +#else + data->pm_notifier.notifier_call = bt_pm_notify; + data->reboot_notifier.notifier_call = bt_reboot_notify; + register_pm_notifier(&data->pm_notifier); + register_reboot_notifier(&data->reboot_notifier); +#endif + +#if CONFIG_BLUEDROID + RTKBT_INFO("%s: Check bt reset flag %d", __func__, bt_reset); + /* Report hci hardware error after everthing is ready, + * especially hci register is completed. Or, btchr_poll + * will get null hci dev when hotplug in. + */ + if (bt_reset == 1) { + hci_hardware_error(); + bt_reset = 0; + } else + bt_reset = 0; /* Clear and reset it anyway */ +#endif + + load_firmware_info(fw_info); + +end: + set_driver_state_value(DEVICE_PROBED); + return 0; +} + +static void btusb_disconnect(struct usb_interface *intf) +{ + struct btusb_data *data; + struct hci_dev *hdev = NULL; + + if (intf->cur_altsetting->desc.bInterfaceNumber != 0) + return; + + clear_driver_state(DEVICE_PROBED); + if((get_driver_state_value() & CHAR_OPENED) == CHAR_OPENED) + wake_up_interruptible(&btchr_read_wait); + + wait_event_interruptible(bt_drv_state_wait, ((get_driver_state_value() & CHAR_OPENED) == 0)); + + RTKBT_INFO("%s: usb_interface %p, bInterfaceNumber %d", + __func__, intf, intf->cur_altsetting->desc.bInterfaceNumber); + + data = usb_get_intfdata(intf); + + if (data) + hdev = data->hdev; + else { + RTKBT_WARN("%s: Failed to get bt usb data[Null]", __func__); + return; + } + +#ifdef CONFIG_SCO_OVER_HCI + if (intf->cur_altsetting->desc.bInterfaceNumber == 0) { + RTK_sco_card_t *pSCOSnd = data->pSCOSnd; + btusb_snd_remove(pSCOSnd); + } +#endif + +//#ifdef CONFIG_HAS_EARLYSUSPEND +#if 0 + unregister_early_suspend(&data->early_suspend); +#else + unregister_pm_notifier(&data->pm_notifier); + unregister_reboot_notifier(&data->reboot_notifier); +#endif + + firmware_info_destroy(intf); + +#if CONFIG_BLUEDROID + if (test_bit(HCI_RUNNING, &hdev->flags)) { + RTKBT_INFO("%s: Set BT reset flag", __func__); + bt_reset = 1; + } +#endif + + usb_set_intfdata(data->intf, NULL); + + if (data->isoc) + usb_set_intfdata(data->isoc, NULL); + + hci_unregister_dev(hdev); + + if (intf == data->isoc) + usb_driver_release_interface(&btusb_driver, data->intf); + else if (data->isoc) + usb_driver_release_interface(&btusb_driver, data->isoc); + +#if !CONFIG_BLUEDROID +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) + __hci_dev_put(hdev); +#endif +#endif + + hci_free_dev(hdev); + rtk_free(data); + data = NULL; + set_driver_state_value(0); +} + +#ifdef CONFIG_PM +static int btusb_suspend(struct usb_interface *intf, pm_message_t message) +{ + struct btusb_data *data = usb_get_intfdata(intf); + firmware_info *fw_info = data->fw_info; + + RTKBT_INFO("%s: event 0x%x, suspend count %d", __func__, + message.event, data->suspend_count); + + if (intf->cur_altsetting->desc.bInterfaceNumber != 0) + return 0; + + if (!test_bit(HCI_RUNNING, &data->hdev->flags)) + set_bt_onoff(fw_info, 1); + + if (data->suspend_count++) + return 0; + + spin_lock_irq(&data->txlock); + if (!((message.event & PM_EVENT_AUTO) && data->tx_in_flight)) { + set_bit(BTUSB_SUSPENDING, &data->flags); + spin_unlock_irq(&data->txlock); + } else { + spin_unlock_irq(&data->txlock); + data->suspend_count--; + RTKBT_ERR("%s: Failed to enter suspend", __func__); + return -EBUSY; + } + + cancel_work_sync(&data->work); + + btusb_stop_traffic(data); + mdelay(URB_CANCELING_DELAY_MS); + usb_kill_anchored_urbs(&data->tx_anchor); + +#if SUSPNED_DW_FW + if(fw_info_4_suspend) { + download_suspend_patch(fw_info_4_suspend,1); + } + else + RTKBT_ERR("%s: Failed to download suspend fw", __func__); +#endif + +#if SET_WAKEUP_DEVICE + set_wakeup_device_from_conf(fw_info_4_suspend); +#endif + + return 0; +} + +static void play_deferred(struct btusb_data *data) +{ + struct urb *urb; + int err; + + while ((urb = usb_get_from_anchor(&data->deferred))) { + usb_anchor_urb(urb, &data->tx_anchor); + err = usb_submit_urb(urb, GFP_ATOMIC); + if (err < 0) { + RTKBT_ERR("%s: Failed to submit urb %p, err %d", + __func__, urb, err); + kfree(urb->setup_packet); + usb_unanchor_urb(urb); + } else { + usb_mark_last_busy(data->udev); + } + usb_free_urb(urb); + + data->tx_in_flight++; + } + mdelay(URB_CANCELING_DELAY_MS); + usb_scuttle_anchored_urbs(&data->deferred); +} + +static int btusb_resume(struct usb_interface *intf) +{ + struct btusb_data *data = usb_get_intfdata(intf); + struct hci_dev *hdev = data->hdev; + firmware_info *fw_info = data->fw_info; + int err = 0; + + RTKBT_INFO("%s: Suspend count %d", __func__, data->suspend_count); + + if (intf->cur_altsetting->desc.bInterfaceNumber != 0) + return 0; + + if (--data->suspend_count) + return 0; + + /*check_fw_version to check the status of the BT Controller after USB Resume*/ + err = check_fw_version(fw_info, true); + if (err !=0) + { + RTKBT_INFO("%s: BT Controller Power OFF And Return hci_hardware_error:%d", __func__, err); + hci_hardware_error(); + } + + + if (test_bit(BTUSB_INTR_RUNNING, &data->flags)) { + err = btusb_submit_intr_urb(hdev, GFP_NOIO); + if (err < 0) { + clear_bit(BTUSB_INTR_RUNNING, &data->flags); + goto failed; + } + } + + if (test_bit(BTUSB_BULK_RUNNING, &data->flags)) { + err = btusb_submit_bulk_urb(hdev, GFP_NOIO); + if (err < 0) { + clear_bit(BTUSB_BULK_RUNNING, &data->flags); + goto failed; + } + + btusb_submit_bulk_urb(hdev, GFP_NOIO); + } + + if (test_bit(BTUSB_ISOC_RUNNING, &data->flags)) { + if (btusb_submit_isoc_urb(hdev, GFP_NOIO) < 0) + clear_bit(BTUSB_ISOC_RUNNING, &data->flags); + else + btusb_submit_isoc_urb(hdev, GFP_NOIO); + } + + spin_lock_irq(&data->txlock); + play_deferred(data); + clear_bit(BTUSB_SUSPENDING, &data->flags); + spin_unlock_irq(&data->txlock); + schedule_work(&data->work); + + return 0; + +failed: + mdelay(URB_CANCELING_DELAY_MS); + usb_scuttle_anchored_urbs(&data->deferred); + spin_lock_irq(&data->txlock); + clear_bit(BTUSB_SUSPENDING, &data->flags); + spin_unlock_irq(&data->txlock); + + return err; +} +#endif + +static struct usb_driver btusb_driver = { + .name = "rtk_btusb", + .probe = btusb_probe, + .disconnect = btusb_disconnect, +#ifdef CONFIG_PM + .suspend = btusb_suspend, + .resume = btusb_resume, +#endif +#if CONFIG_RESET_RESUME + .reset_resume = btusb_resume, +#endif + .id_table = btusb_table, + .supports_autosuspend = 1, +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 7, 1) + .disable_hub_initiated_lpm = 1, +#endif +}; + +static int __init btusb_init(void) +{ + int err; + + RTKBT_INFO("RTKBT_RELEASE_NAME: %s",RTKBT_RELEASE_NAME); + RTKBT_INFO("Realtek Bluetooth USB driver module init, version %s", VERSION); + driver_state = 0; +#if CONFIG_BLUEDROID + err = btchr_init(); + if (err < 0) { + /* usb register will go on, even bt char register failed */ + RTKBT_ERR("Failed to register usb char device interfaces"); + } + else + driver_state |= DRIVER_ON; +#endif + err = usb_register(&btusb_driver); + if (err < 0) + RTKBT_ERR("Failed to register RTK bluetooth USB driver"); + return err; +} + +static void __exit btusb_exit(void) +{ + struct hci_dev *hdev; + RTKBT_INFO("Realtek Bluetooth USB driver module exit"); +#if CONFIG_BLUEDROID + clear_driver_state(DRIVER_ON); + hdev = hci_dev_get(0); + while(hdev && atomic_read(&hdev->promisc)) { + RTKBT_ERR("%s: rtkbt driver is being removed, but application is still running!", __func__); + RTKBT_ERR("%s: wait bt application to stop, or the driver can't be removed", __func__); + mdelay(100); + } + btchr_exit(); +#endif + usb_deregister(&btusb_driver); +} + +module_init(btusb_init); +module_exit(btusb_exit); + + +module_param(mp_drv_mode, int, 0644); +MODULE_PARM_DESC(mp_drv_mode, "0: NORMAL; 1: MP MODE"); + + +MODULE_AUTHOR("Realtek Corporation"); +MODULE_DESCRIPTION("Realtek Bluetooth USB driver version"); +MODULE_VERSION(VERSION); +MODULE_LICENSE("GPL"); diff --git a/drivers/bluetooth/rtk_btusb.h b/drivers/bluetooth/rtk_btusb.h new file mode 100644 index 000000000000..57960616ab7e --- /dev/null +++ b/drivers/bluetooth/rtk_btusb.h @@ -0,0 +1,759 @@ +/* + * + * Realtek Bluetooth USB driver + * + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#define CONFIG_BLUEDROID 1 /* bleuz 0, bluedroid 1 */ +//#define CONFIG_SCO_OVER_HCI + +#ifdef CONFIG_SCO_OVER_HCI +#include +#include +#include +#include +#include + +#define RTK_SCO_ID "snd_sco_rtk" +enum { + USB_CAPTURE_RUNNING, + USB_PLAYBACK_RUNNING, + ALSA_CAPTURE_OPEN, + ALSA_PLAYBACK_OPEN, + ALSA_CAPTURE_RUNNING, + ALSA_PLAYBACK_RUNNING, + CAPTURE_URB_COMPLETED, + PLAYBACK_URB_COMPLETED, + DISCONNECTED, +}; + +// RTK sound card +typedef struct RTK_sco_card { + struct snd_card *card; + struct snd_pcm *pcm; + struct usb_device *dev; + struct btusb_data *usb_data; + unsigned long states; + struct rtk_sco_stream { + struct snd_pcm_substream *substream; + unsigned int sco_packet_bytes; + snd_pcm_uframes_t buffer_pos; + } capture, playback; + spinlock_t capture_lock; + spinlock_t playback_lock; + struct work_struct send_sco_work; +} RTK_sco_card_t; +#endif +/* Some Android system may use standard Linux kernel, while + * standard Linux may also implement early suspend feature. + * So exclude earysuspend.h from CONFIG_BLUEDROID. + */ +#ifdef CONFIG_HAS_EARLYSUSPEND +#include +#endif + +#if CONFIG_BLUEDROID +#else +#include +#include +#include +#endif + + +/*********************************** +** Realtek - For rtk_btusb driver ** +***********************************/ +#define URB_CANCELING_DELAY_MS 10 +/* when OS suspended, module is still powered,usb is not powered, + * this may set to 1, and must comply with special patch code. + */ +#define CONFIG_RESET_RESUME 1 +#define PRINT_CMD_EVENT 0 +#define PRINT_ACL_DATA 0 +#define PRINT_SCO_DATA 0 + +#define RTKBT_DBG_FLAG 0 + +#if RTKBT_DBG_FLAG +#define RTKBT_DBG(fmt, arg...) printk(KERN_INFO "rtk_btusb: " fmt "\n" , ## arg) +#else +#define RTKBT_DBG(fmt, arg...) +#endif +#define RTKBT_INFO(fmt, arg...) printk(KERN_INFO "rtk_btusb: " fmt "\n" , ## arg) +#define RTKBT_WARN(fmt, arg...) printk(KERN_WARNING "rtk_btusb: " fmt "\n" , ## arg) +#define RTKBT_ERR(fmt, arg...) printk(KERN_ERR "rtk_btusb: " fmt "\n" , ## arg) + + +#if LINUX_VERSION_CODE > KERNEL_VERSION(2, 6, 33) +#define HDEV_BUS hdev->bus +#define USB_RPM 1 +#else +#define HDEV_BUS hdev->type +#define USB_RPM 0 +#endif + +#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 38) +#define NUM_REASSEMBLY 3 +#endif + +#if LINUX_VERSION_CODE > KERNEL_VERSION(3, 4, 0) +#define GET_DRV_DATA(x) hci_get_drvdata(x) +#else +#define GET_DRV_DATA(x) x->driver_data +#endif + +#define BTUSB_RPM (0 * USB_RPM) /* 1 SS enable; 0 SS disable */ +#define BTUSB_WAKEUP_HOST 0 /* 1 enable; 0 disable */ +#define BTUSB_MAX_ISOC_FRAMES 48 +#define BTUSB_INTR_RUNNING 0 +#define BTUSB_BULK_RUNNING 1 +#define BTUSB_ISOC_RUNNING 2 +#define BTUSB_SUSPENDING 3 +#define BTUSB_DID_ISO_RESUME 4 + +#define HCI_CMD_READ_BD_ADDR 0x1009 +#define HCI_VENDOR_CHANGE_BDRATE 0xfc17 +#define HCI_VENDOR_READ_RTK_ROM_VERISION 0xfc6d +#define HCI_VENDOR_READ_LMP_VERISION 0x1001 +#define HCI_VENDOR_FORCE_RESET_AND_PATCHABLE 0xfc66 +#define HCI_VENDOR_RESET 0x0C03 +#define HCI_VENDOR_ADD_WAKE_UP_DEVICE 0xfc7b +#define HCI_VENDOR_REMOVE_WAKE_UP_DEVICE 0xfc7c +#define HCI_VENDOR_CLEAR_POWERON_LIST 0xfc7d + +#define HCI_VENDOR_USB_DISC_HARDWARE_ERROR 0xFF + +#define SET_WAKEUP_DEVICE_CONF "/data/misc/bluedroid/rtkbt_wakeup_ble.conf" + +#define DRV_NORMAL_MODE 0 +#define DRV_MP_MODE 1 +int mp_drv_mode = 0; /* 1 Mptool Fw; 0 Normal Fw */ + +#define ROM_LMP_NONE 0x0000 +#define ROM_LMP_8723a 0x1200 +#define ROM_LMP_8723b 0x8723 +#define ROM_LMP_8821a 0X8821 +#define ROM_LMP_8761a 0X8761 +#define ROM_LMP_8761b 0X8761 +#define ROM_LMP_8703a 0x8723 +#define ROM_LMP_8763a 0x8763 +#define ROM_LMP_8703b 0x8703 +#define ROM_LMP_8723c 0x8703 +#define ROM_LMP_8822b 0x8822 +#define ROM_LMP_8723d 0x8723 +#define ROM_LMP_8821c 0x8821 +#define ROM_LMP_8822c 0x8822 +#define ROM_LMP_8852a 0x8852 +#define ROM_LMP_8723f 0x8723 +#define ROM_LMP_8852b 0x8852 +#define ROM_LMP_8763c 0x8763 +#define ROM_LMP_8773b 0x8773 +#define ROM_LMP_8762a 0x8762 +#define ROM_LMP_8762b 0x8762 +#define ROM_LMP_8852c 0x8852 +#define ROM_LMP_8851a 0x8852 +#define ROM_LMP_8852bp 0x8852 +#define ROM_LMP_8851b 0x8851 + +/* signature: Realtek */ +const uint8_t RTK_EPATCH_SIGNATURE[8] = {0x52,0x65,0x61,0x6C,0x74,0x65,0x63,0x68}; +/* Extension Section IGNATURE:0x77FD0451 */ +const uint8_t EXTENSION_SECTION_SIGNATURE[4] = {0x51,0x04,0xFD,0x77}; + +uint16_t project_id[] = { + ROM_LMP_8723a, + ROM_LMP_8723b, + ROM_LMP_8821a, + ROM_LMP_8761a, + ROM_LMP_8703a, + ROM_LMP_8763a, + ROM_LMP_8703b, + ROM_LMP_8723c, + ROM_LMP_8822b, + ROM_LMP_8723d, + ROM_LMP_8821c, + ROM_LMP_NONE, + ROM_LMP_NONE, + ROM_LMP_8822c, //0x0d + ROM_LMP_8761b, + ROM_LMP_NONE, + ROM_LMP_NONE, //0x10 + ROM_LMP_NONE, + ROM_LMP_8852a, //0x12 + ROM_LMP_8723f, + ROM_LMP_8852b, + ROM_LMP_8763c, //bbpro2 + ROM_LMP_8773b, //bblite + ROM_LMP_8762a, //bee + ROM_LMP_8762b, //bee2 + ROM_LMP_8852c +}; +struct rtk_eversion_evt { + uint8_t status; + uint8_t version; +} __attribute__ ((packed)); + +/*modified by lamparten 1020*/ +struct rtk_reset_evt { + uint8_t status; +} __attribute__ ((packed)); +/*modified by lamparten 1020*/ + +struct rtk_localversion_evt { + uint8_t status; + uint8_t hci_version; + uint16_t hci_revision; + uint8_t lmp_version; + uint16_t lmp_manufacture; + uint16_t lmp_subversion; +} __attribute__ ((packed)); + +struct rtk_epatch_entry { + uint16_t chip_id; + uint16_t patch_length; + uint32_t start_offset; + uint32_t coex_version; + uint32_t svn_version; + uint32_t fw_version; +} __attribute__ ((packed)); + +struct rtk_epatch { + uint8_t signature[8]; + uint32_t fw_version; + uint16_t number_of_total_patch; + struct rtk_epatch_entry entry[0]; +} __attribute__ ((packed)); + +struct rtk_extension_entry { + uint8_t opcode; + uint8_t length; + uint8_t *data; +} __attribute__ ((packed)); + +struct rtk_bt_vendor_config_entry{ + uint16_t offset; + uint8_t entry_len; + uint8_t entry_data[0]; +} __attribute__ ((packed)); + +struct rtk_bt_vendor_config{ + uint32_t signature; + uint16_t data_len; + struct rtk_bt_vendor_config_entry entry[0]; +} __attribute__ ((packed)); + +/* Realtek - For rtk_btusb driver end */ + +#if CONFIG_BLUEDROID +#define QUEUE_SIZE 500 + +/*************************************** +** Realtek - Integrate from bluetooth.h ** +*****************************************/ +/* Reserv for core and drivers use */ +#define BT_SKB_RESERVE 8 + +/* BD Address */ +typedef struct { + __u8 b[6]; +} __packed bdaddr_t; + +/* Skb helpers */ +struct bt_skb_cb { + __u8 pkt_type; + __u8 incoming; + __u16 expect; + __u16 tx_seq; + __u8 retries; + __u8 sar; + __u8 force_active; +}; + +#define bt_cb(skb) ((struct bt_skb_cb *)((skb)->cb)) + +static inline struct sk_buff *bt_skb_alloc(unsigned int len, gfp_t how) +{ + struct sk_buff *skb; + + if ((skb = alloc_skb(len + BT_SKB_RESERVE, how))) { + skb_reserve(skb, BT_SKB_RESERVE); + bt_cb(skb)->incoming = 0; + } + return skb; +} +/* Realtek - Integrate from bluetooth.h end */ + +/*********************************** +** Realtek - Integrate from hci.h ** +***********************************/ +#define HCI_MAX_ACL_SIZE 1024 +#define HCI_MAX_SCO_SIZE 255 +#define HCI_MAX_EVENT_SIZE 260 +#define HCI_MAX_FRAME_SIZE (HCI_MAX_ACL_SIZE + 4) + +/* HCI bus types */ +#define HCI_VIRTUAL 0 +#define HCI_USB 1 +#define HCI_PCCARD 2 +#define HCI_UART 3 +#define HCI_RS232 4 +#define HCI_PCI 5 +#define HCI_SDIO 6 + +/* HCI controller types */ +#define HCI_BREDR 0x00 +#define HCI_AMP 0x01 + +#define DRIVER_ON 1 +#define DEVICE_PROBED 2 +#define CHAR_OPENED 4 +#define CHAR_DLFW 8 + +/* HCI device flags */ +enum { + HCI_UP, //if char device is opened set this flag, clear flag when close + HCI_RUNNING, //if usb transport has opened set this flag, clear flag when close + HCI_UNREGISTER, +}; + +/* HCI data types */ +#define HCI_COMMAND_PKT 0x01 +#define HCI_ACLDATA_PKT 0x02 +#define HCI_SCODATA_PKT 0x03 +#define HCI_EVENT_PKT 0x04 +#define HCI_VENDOR_PKT 0xff + +#define HCI_MAX_NAME_LENGTH 248 +#define HCI_MAX_EIR_LENGTH 240 + +#define HCI_OP_READ_LOCAL_VERSION 0x1001 +struct hci_rp_read_local_version { + __u8 status; + __u8 hci_ver; + __le16 hci_rev; + __u8 lmp_ver; + __le16 manufacturer; + __le16 lmp_subver; +} __packed; + +#define HCI_EV_CMD_COMPLETE 0x0e +struct hci_ev_cmd_complete { + __u8 ncmd; + __le16 opcode; +} __packed; + +/* ---- HCI Packet structures ---- */ +#define HCI_COMMAND_HDR_SIZE 3 +#define HCI_EVENT_HDR_SIZE 2 +#define HCI_ACL_HDR_SIZE 4 +#define HCI_SCO_HDR_SIZE 3 + +struct hci_command_hdr { + __le16 opcode; /* OCF & OGF */ + __u8 plen; +} __packed; + +struct hci_event_hdr { + __u8 evt; + __u8 plen; +} __packed; + +struct hci_acl_hdr { + __le16 handle; /* Handle & Flags(PB, BC) */ + __le16 dlen; +} __packed; + +struct hci_sco_hdr { + __le16 handle; + __u8 dlen; +} __packed; + +static inline struct hci_event_hdr *hci_event_hdr(const struct sk_buff *skb) +{ + return (struct hci_event_hdr *) skb->data; +} + +static inline struct hci_acl_hdr *hci_acl_hdr(const struct sk_buff *skb) +{ + return (struct hci_acl_hdr *) skb->data; +} + +static inline struct hci_sco_hdr *hci_sco_hdr(const struct sk_buff *skb) +{ + return (struct hci_sco_hdr *) skb->data; +} + +/* ---- HCI Ioctl requests structures ---- */ +struct hci_dev_stats { + __u32 err_rx; + __u32 err_tx; + __u32 cmd_tx; + __u32 evt_rx; + __u32 acl_tx; + __u32 acl_rx; + __u32 sco_tx; + __u32 sco_rx; + __u32 byte_rx; + __u32 byte_tx; +}; +/* Realtek - Integrate from hci.h end */ + +/***************************************** +** Realtek - Integrate from hci_core.h ** +*****************************************/ +struct hci_conn_hash { + struct list_head list; + unsigned int acl_num; + unsigned int sco_num; + unsigned int le_num; +}; + +#define HCI_MAX_SHORT_NAME_LENGTH 10 + +#define NUM_REASSEMBLY 4 +struct hci_dev { + struct mutex lock; + + char name[8]; + unsigned long flags; + __u16 id; + __u8 bus; + __u8 dev_type; + + struct sk_buff *reassembly[NUM_REASSEMBLY]; + + struct hci_conn_hash conn_hash; + + struct hci_dev_stats stat; + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) + atomic_t refcnt; + struct module *owner; + void *driver_data; +#endif + + atomic_t promisc; + + struct device *parent; + struct device dev; + + int (*open)(struct hci_dev *hdev); + int (*close)(struct hci_dev *hdev); + int (*flush)(struct hci_dev *hdev); + int (*send)(struct sk_buff *skb); +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) + void (*destruct)(struct hci_dev *hdev); +#endif + __u16 voice_setting; + void (*notify)(struct hci_dev *hdev, unsigned int evt); + int (*ioctl)(struct hci_dev *hdev, unsigned int cmd, unsigned long arg); +}; + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(3, 4, 0) +static inline struct hci_dev *__hci_dev_hold(struct hci_dev *d) +{ + atomic_inc(&d->refcnt); + return d; +} + +static inline void __hci_dev_put(struct hci_dev *d) +{ + if (atomic_dec_and_test(&d->refcnt)) + d->destruct(d); +} +#endif + +static inline void *hci_get_drvdata(struct hci_dev *hdev) +{ + return dev_get_drvdata(&hdev->dev); +} + +static inline void hci_set_drvdata(struct hci_dev *hdev, void *data) +{ + dev_set_drvdata(&hdev->dev, data); +} + +#define SET_HCIDEV_DEV(hdev, pdev) ((hdev)->parent = (pdev)) +/* Realtek - Integrate from hci_core.h end */ + +/* ----- HCI Commands ---- */ +#define HCI_OP_INQUIRY 0x0401 +#define HCI_OP_INQUIRY_CANCEL 0x0402 +#define HCI_OP_EXIT_PERIODIC_INQ 0x0404 +#define HCI_OP_CREATE_CONN 0x0405 +#define HCI_OP_DISCONNECT 0x0406 +#define HCI_OP_ADD_SCO 0x0407 +#define HCI_OP_CREATE_CONN_CANCEL 0x0408 +#define HCI_OP_ACCEPT_CONN_REQ 0x0409 +#define HCI_OP_REJECT_CONN_REQ 0x040a +#define HCI_OP_LINK_KEY_REPLY 0x040b +#define HCI_OP_LINK_KEY_NEG_REPLY 0x040c +#define HCI_OP_PIN_CODE_REPLY 0x040d +#define HCI_OP_PIN_CODE_NEG_REPLY 0x040e +#define HCI_OP_CHANGE_CONN_PTYPE 0x040f +#define HCI_OP_AUTH_REQUESTED 0x0411 +#define HCI_OP_SET_CONN_ENCRYPT 0x0413 +#define HCI_OP_CHANGE_CONN_LINK_KEY 0x0415 +#define HCI_OP_REMOTE_NAME_REQ 0x0419 +#define HCI_OP_REMOTE_NAME_REQ_CANCEL 0x041a +#define HCI_OP_READ_REMOTE_FEATURES 0x041b +#define HCI_OP_READ_REMOTE_EXT_FEATURES 0x041c +#define HCI_OP_READ_REMOTE_VERSION 0x041d +#define HCI_OP_SETUP_SYNC_CONN 0x0428 +#define HCI_OP_ACCEPT_SYNC_CONN_REQ 0x0429 +#define HCI_OP_REJECT_SYNC_CONN_REQ 0x042a +#define HCI_OP_SNIFF_MODE 0x0803 +#define HCI_OP_EXIT_SNIFF_MODE 0x0804 +#define HCI_OP_ROLE_DISCOVERY 0x0809 +#define HCI_OP_SWITCH_ROLE 0x080b +#define HCI_OP_READ_LINK_POLICY 0x080c +#define HCI_OP_WRITE_LINK_POLICY 0x080d +#define HCI_OP_READ_DEF_LINK_POLICY 0x080e +#define HCI_OP_WRITE_DEF_LINK_POLICY 0x080f +#define HCI_OP_SNIFF_SUBRATE 0x0811 +#define HCI_OP_SET_EVENT_MASK 0x0c01 +#define HCI_OP_RESET 0x0c03 +#define HCI_OP_SET_EVENT_FLT 0x0c05 +#define HCI_OP_Write_Extended_Inquiry_Response 0x0c52 + +/* ----- HCI events---- */ +#define HCI_OP_DISCONNECT 0x0406 +#define HCI_EV_INQUIRY_COMPLETE 0x01 +#define HCI_EV_INQUIRY_RESULT 0x02 +#define HCI_EV_CONN_COMPLETE 0x03 +#define HCI_EV_CONN_REQUEST 0x04 +#define HCI_EV_DISCONN_COMPLETE 0x05 +#define HCI_EV_AUTH_COMPLETE 0x06 +#define HCI_EV_REMOTE_NAME 0x07 +#define HCI_EV_ENCRYPT_CHANGE 0x08 +#define HCI_EV_CHANGE_LINK_KEY_COMPLETE 0x09 + +#define HCI_EV_REMOTE_FEATURES 0x0b +#define HCI_EV_REMOTE_VERSION 0x0c +#define HCI_EV_QOS_SETUP_COMPLETE 0x0d +#define HCI_EV_CMD_COMPLETE 0x0e +#define HCI_EV_CMD_STATUS 0x0f + +#define HCI_EV_ROLE_CHANGE 0x12 +#define HCI_EV_NUM_COMP_PKTS 0x13 +#define HCI_EV_MODE_CHANGE 0x14 +#define HCI_EV_PIN_CODE_REQ 0x16 +#define HCI_EV_LINK_KEY_REQ 0x17 +#define HCI_EV_LINK_KEY_NOTIFY 0x18 +#define HCI_EV_CLOCK_OFFSET 0x1c +#define HCI_EV_PKT_TYPE_CHANGE 0x1d +#define HCI_EV_PSCAN_REP_MODE 0x20 + +#define HCI_EV_INQUIRY_RESULT_WITH_RSSI 0x22 +#define HCI_EV_REMOTE_EXT_FEATURES 0x23 +#define HCI_EV_SYNC_CONN_COMPLETE 0x2c +#define HCI_EV_SYNC_CONN_CHANGED 0x2d +#define HCI_EV_SNIFF_SUBRATE 0x2e +#define HCI_EV_EXTENDED_INQUIRY_RESULT 0x2f +#define HCI_EV_IO_CAPA_REQUEST 0x31 +#define HCI_EV_SIMPLE_PAIR_COMPLETE 0x36 +#define HCI_EV_REMOTE_HOST_FEATURES 0x3d + +#define CONFIG_MAC_OFFSET_GEN_1_2 (0x3C) //MAC's OFFSET in config/efuse for realtek generation 1~2 bluetooth chip +#define CONFIG_MAC_OFFSET_GEN_3PLUS (0x44) //MAC's OFFSET in config/efuse for rtk generation 3+ bluetooth chip +#define CONFIG_MAC_OFFSET_GEN_4PLUS (0x30) //MAC's OFFSET in config/efuse for rtk generation 4+ bluetooth chip + +/******************************* +** Reasil patch code +********************************/ +#define CMD_CMP_EVT 0x0e +#define PKT_LEN 300 +#define MSG_TO 1000 +#define PATCH_SEG_MAX 252 +#define DATA_END 0x80 +#define DOWNLOAD_OPCODE 0xfc20 +#define BTOFF_OPCODE 0xfc28 +#define TRUE 1 +#define FALSE 0 +#define CMD_HDR_LEN sizeof(struct hci_command_hdr) +#define EVT_HDR_LEN sizeof(struct hci_event_hdr) +#define CMD_CMP_LEN sizeof(struct hci_ev_cmd_complete) +#define MAX_PATCH_SIZE_24K (1024*24) +#define MAX_PATCH_SIZE_25K (1024*25) +#define MAX_PATCH_SIZE_40K (1024*40) + +enum rtk_endpoit { + CTRL_EP = 0, + INTR_EP = 1, + BULK_EP = 2, + ISOC_EP = 3 +}; + +typedef struct { + uint16_t vid; + uint16_t pid; + uint16_t lmp_sub_default; + uint16_t lmp_sub; + uint16_t eversion; + char *mp_patch_name; + char *patch_name; + char *config_name; + uint8_t *fw_cache; + int fw_len; + uint16_t mac_offset; + uint32_t max_patch_size; +} patch_info; + +typedef struct { + struct usb_interface *intf; + struct usb_device *udev; + patch_info *patch_entry; + int pipe_in, pipe_out; + uint8_t *send_pkt; + uint8_t *rcv_pkt; + struct hci_command_hdr *cmd_hdr; + struct hci_event_hdr *evt_hdr; + struct hci_ev_cmd_complete *cmd_cmp; + uint8_t *req_para, *rsp_para; + uint8_t *fw_data; + int pkt_len; + int fw_len; +} firmware_info; + +typedef struct { + uint8_t index; + uint8_t data[PATCH_SEG_MAX]; +} __attribute__((packed)) download_cp; + +typedef struct { + uint8_t status; + uint8_t index; +} __attribute__((packed)) download_rp; + + +#define DOWN_FW_CFG _IOW('E', 176, int) +#ifdef CONFIG_SCO_OVER_HCI +#define SET_ISO_CFG _IOW('E', 177, int) +#endif +#define RESET_CONTROLLER _IOW('E', 178, int) +#define DWFW_CMPLT _IOW('E', 179, int) + +#define GET_USB_INFO _IOR('E', 180, int) + +/* for altsettings*/ +#include +#define BDADDR_FILE "/data/misc/bluetooth/bdaddr" +#define FACTORY_BT_BDADDR_STORAGE_LEN 17 + +static inline int getmacaddr(uint8_t * vnd_local_bd_addr) +{ +#if LINUX_VERSION_CODE < KERNEL_VERSION(4, 14, 14) + struct file *bdaddr_file; + mm_segment_t oldfs; + char buf[FACTORY_BT_BDADDR_STORAGE_LEN]; + int32_t i = 0; + int ret = -1; + memset(buf, 0, FACTORY_BT_BDADDR_STORAGE_LEN); + bdaddr_file = filp_open(BDADDR_FILE, O_RDONLY, 0); + if (IS_ERR(bdaddr_file)){ + RTKBT_INFO("No Mac Config for BT\n"); + return -1; + } + oldfs = get_fs(); set_fs(KERNEL_DS); + bdaddr_file->f_op->llseek(bdaddr_file, 0, 0); + ret = vfs_read(bdaddr_file, buf, FACTORY_BT_BDADDR_STORAGE_LEN, &bdaddr_file->f_pos); + set_fs(oldfs); + filp_close(bdaddr_file, NULL); + if(ret == FACTORY_BT_BDADDR_STORAGE_LEN) + { + for (i = 0; i < 6; i++) { + if(buf[3*i]>'9') + { + if(buf[3*i]>'Z') + buf[3*i] -=('a'-'A'); //change a to A + buf[3*i] -= ('A'-'9'-1); + } + if(buf[3*i+1]>'9') + { + if(buf[3*i+1]>'Z') + buf[3*i+1] -=('a'-'A'); //change a to A + buf[3*i+1] -= ('A'-'9'-1); + } + vnd_local_bd_addr[5-i] = ((uint8_t)buf[3*i]-'0')*16 + ((uint8_t)buf[3*i+1]-'0'); + } + return 0; + } +#endif + return -1; +} + +static inline int getAltSettings(patch_info *patch_entry, unsigned short *offset, int max_group_cnt) +{ + int n = 0; + if(patch_entry) + offset[n++] = patch_entry->mac_offset; +/* +//sample code, add special settings + + offset[n++] = 0x15B; +*/ + return n; +} +static inline int getAltSettingVal(patch_info *patch_entry, unsigned short offset, unsigned char * val) +{ + int res = 0; + + switch(offset) + { +/* +//sample code, add special settings + case 0x15B: + val[0] = 0x0B; + val[1] = 0x0B; + val[2] = 0x0B; + val[3] = 0x0B; + res = 4; + break; +*/ + default: + res = 0; + break; + } + + if((patch_entry)&&(offset == patch_entry->mac_offset)&&(res == 0)) + { + if(getmacaddr(val) == 0){ + RTKBT_INFO("MAC: %02x:%02x:%02x:%02x:%02x:%02x", val[5], val[4], val[3], val[2], val[1], val[0]); + res = 6; + } + } + return res; +} + +#endif /* CONFIG_BLUEDROID */ diff --git a/drivers/char/hw_random/Kconfig b/drivers/char/hw_random/Kconfig index 8de74dcfa18c..f8aaddf60168 100644 --- a/drivers/char/hw_random/Kconfig +++ b/drivers/char/hw_random/Kconfig @@ -493,6 +493,18 @@ config HW_RANDOM_OPTEE If unsure, say Y. +config HW_RANDOM_SKY1 + tristate "SKY1 Random Number Generator support" + default HW_RANDOM + help + This driver provides kernel-side support for the Random Number + Generator hardware found on SKY1 SoC. + + To compile this driver as a module, choose M here: the + module will be called sky1-rng. + + If unsure, say Y. + config HW_RANDOM_NPCM tristate "NPCM Random Number Generator support" depends on ARCH_NPCM || COMPILE_TEST diff --git a/drivers/char/hw_random/Makefile b/drivers/char/hw_random/Makefile index 32549a1186dc..4393695c3739 100644 --- a/drivers/char/hw_random/Makefile +++ b/drivers/char/hw_random/Makefile @@ -30,6 +30,7 @@ obj-$(CONFIG_HW_RANDOM_PSERIES) += pseries-rng.o obj-$(CONFIG_HW_RANDOM_POWERNV) += powernv-rng.o obj-$(CONFIG_HW_RANDOM_HISI) += hisi-rng.o obj-$(CONFIG_HW_RANDOM_HISTB) += histb-rng.o +obj-$(CONFIG_HW_RANDOM_SKY1) += sky1-rng.o obj-$(CONFIG_HW_RANDOM_BCM2835) += bcm2835-rng.o obj-$(CONFIG_HW_RANDOM_IPROC_RNG200) += iproc-rng200.o obj-$(CONFIG_HW_RANDOM_ST) += st-rng.o diff --git a/drivers/char/hw_random/sky1-rng.c b/drivers/char/hw_random/sky1-rng.c new file mode 100644 index 000000000000..fa35051cab02 --- /dev/null +++ b/drivers/char/hw_random/sky1-rng.c @@ -0,0 +1,160 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +/** + * RNG Pool control registers + */ +#define CE_CFG_BASE_ADDR 0x05050000UL // 0xA0040000 - 0xA0000000 + 0x05010000 +#define RNP_OFS 0x05055300UL // 0x3300 + (0x1000 * 2) +#define RNP_CTRL_OFS 0x00 +#define RNP_STAT_OFS 0x04 +#define RNP_INTR_OFS 0x08 +#define RNP_INTR_MSK_OFS 0x0C +#define RNP_DAT_WORD0_OFS 0x10 + +#define RNP_STAT_AUTOCORR_TEST_ERR (1 << 0U) +#define RNP_MAX_SIZE (32U) +#define RNP_MIN(a, b) ((a) < (b) ? (a) : (b)) + +#define to_sky1_rng(p) container_of(p, struct sky1_rng, rng) + +struct sky1_rng { + void __iomem *base; + struct hwrng rng; +}; + +static inline void trng_rnp_fill(struct sky1_rng *hrng) +{ + uint32_t val; + /** wait for rnp idle */ + readl_poll_timeout(hrng->base + RNP_STAT_OFS, val, + ((val & (0x6)) == 0x0), 100, 1000000); + /** trigger to fill rnp */ + val = readl_relaxed(hrng->base + RNP_CTRL_OFS); + val |= 0x3U; + writel_relaxed(val, hrng->base + RNP_CTRL_OFS); + + /** check fill status */ + readl_poll_timeout(hrng->base + RNP_INTR_OFS, val, + ((val & (0x1)) == 0x1), 100, 1000000); + + /** eoi */ + writel_relaxed(val, hrng->base + RNP_INTR_OFS); +} + +static inline void trng_rnp_read(struct sky1_rng *hrng, uint8_t *buf, size_t len) +{ + uint32_t val; + size_t cp_len; + size_t left_len = len; + size_t i = 0; + + do { + /** assert that len shouldn't over 32 bytes*/ + val = readl_relaxed(hrng->base + RNP_DAT_WORD0_OFS + (sizeof(val) * i++)); + cp_len = RNP_MIN(left_len, sizeof(val)); + memcpy(buf + len - left_len, &val, cp_len); + left_len -= cp_len; + } while (left_len > 0); +} + +static inline void trng_read(struct sky1_rng *hrng, uint8_t *buf, size_t len) +{ + size_t left_len = len; + size_t read_len; + + while (left_len > 0) { + /** trigger RNP to fill random number pool */ + trng_rnp_fill(hrng); + /** read appropriate size of data */ + read_len = RNP_MIN(left_len, RNP_MAX_SIZE); + trng_rnp_read(hrng, buf + len - left_len, read_len); + left_len -= read_len; + } + + printk("trng_read %d:0x%x\n", len, buf[0]); +} + +static int sky1_rng_init(struct hwrng *rng) +{ + return 0; +} + +static void sky1_rng_cleanup(struct hwrng *rng) +{ + +} + +static int sky1_rng_read(struct hwrng *rng, void *buf, size_t max, bool wait) +{ + struct sky1_rng *hrng = to_sky1_rng(rng); + uint8_t *data = buf; + + trng_read(hrng, data, max); + + return max; +} + +static int sky1_rng_probe(struct platform_device *pdev) +{ + struct sky1_rng *rng; + int ret; + + rng = devm_kzalloc(&pdev->dev, sizeof(*rng), GFP_KERNEL); + if (!rng) + return -ENOMEM; + + platform_set_drvdata(pdev, rng); + + rng->base = devm_platform_ioremap_resource(pdev, 0); + if (IS_ERR(rng->base)) + return PTR_ERR(rng->base); + + rng->rng.name = pdev->name; + rng->rng.init = sky1_rng_init; + rng->rng.cleanup = sky1_rng_cleanup; + rng->rng.read = sky1_rng_read; + rng->rng.quality = 20; + + printk("sky1_rng_probe\n"); + + ret = devm_hwrng_register(&pdev->dev, &rng->rng); + if (ret) { + dev_err(&pdev->dev, "failed to register hwrng\n"); + return ret; + } + + return 0; +} + +static const struct of_device_id sky1_rng_dt_ids[] __maybe_unused = { + { .compatible = "cix,sky1-rng" }, + { } +}; +MODULE_DEVICE_TABLE(of, sky1_rng_dt_ids); + +static struct platform_driver sky1_rng_driver = { + .probe = sky1_rng_probe, + .driver = { + .name = "sky1-rng", + .of_match_table = of_match_ptr(sky1_rng_dt_ids), + }, +}; + +module_platform_driver(sky1_rng_driver); + +MODULE_LICENSE("GPL"); +MODULE_AUTHOR("Abel.shuai "); +MODULE_DESCRIPTION("Cix random number generator driver"); diff --git a/drivers/clk/Kconfig b/drivers/clk/Kconfig index c30099866174..ce1099ea0fb0 100644 --- a/drivers/clk/Kconfig +++ b/drivers/clk/Kconfig @@ -471,6 +471,7 @@ source "drivers/clk/actions/Kconfig" source "drivers/clk/analogbits/Kconfig" source "drivers/clk/baikal-t1/Kconfig" source "drivers/clk/bcm/Kconfig" +source "drivers/clk/cix/Kconfig" source "drivers/clk/hisilicon/Kconfig" source "drivers/clk/imgtec/Kconfig" source "drivers/clk/imx/Kconfig" diff --git a/drivers/clk/Makefile b/drivers/clk/Makefile index 18969cbd4bb1..13abc7e74736 100644 --- a/drivers/clk/Makefile +++ b/drivers/clk/Makefile @@ -90,6 +90,7 @@ obj-$(CONFIG_ARC_PLAT_AXS10X) += axs10x/ obj-$(CONFIG_CLK_BAIKAL_T1) += baikal-t1/ obj-y += bcm/ obj-$(CONFIG_ARCH_BERLIN) += berlin/ +obj-$(CONFIG_COMMON_CLK_CIX) += cix/ obj-$(CONFIG_ARCH_DAVINCI) += davinci/ obj-$(CONFIG_ARCH_HISI) += hisilicon/ obj-y += imgtec/ diff --git a/drivers/clk/cix/Kconfig b/drivers/clk/cix/Kconfig new file mode 100644 index 000000000000..1b7790a5e03c --- /dev/null +++ b/drivers/clk/cix/Kconfig @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: GPL-2.0 +# Common clock support for Cixtech SoC family +menu "Clock support for Cixtech" + +comment "Clock options for Cixtech CPUs:" + +config COMMON_CLK_CIX + tristate "Support for Cix's clock controllers" + depends on ARCH_CIX || COMPILE_TEST + select REGMAP_MMIO + select RESET_CONTROLLER + +config CIX_CLK_DEBUG + tristate "Cix SoC Clock Debug Driver" + depends on COMMON_CLK_CIX + help + Support on-line debug soc clocks from the debugfs interface. + +config CLK_SKY1_AUDSS + tristate "Cixtech Sky1 Audio Subsystem Clock Driver" + depends on COMMON_CLK_CIX || COMPILE_TEST + help + Support for the Audio Subsystem clock controller present on + Cixtech Sky1 SoC. Choose M or Y here if you want to build this + driver. + +config CIX_ACPI_CLK + bool "CIX Clock Management API for acpi" + depends on ARCH_CIX && ACPI + help + This provid the clock management API for CIX Technologies,Inc. + Say Y if you want to supprot clock driver. + +endmenu diff --git a/drivers/clk/cix/Makefile b/drivers/clk/cix/Makefile new file mode 100644 index 000000000000..c2bd36619c66 --- /dev/null +++ b/drivers/clk/cix/Makefile @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0 +# CIX clocks + +obj-$(CONFIG_CLK_SKY1_AUDSS) += clk-sky1-audss.o +obj-$(CONFIG_CIX_CLK_DEBUG) += cix-clk-debug.o + +obj-$(CONFIG_CIX_ACPI_CLK) += acpi_clk.o +obj-$(CONFIG_CIX_ACPI_CLK) += acpi_scmi_clk.o +obj-$(CONFIG_COMMON_CLK_CIX) += clk.o diff --git a/drivers/clk/cix/acpi_clk.c b/drivers/clk/cix/acpi_clk.c new file mode 100644 index 000000000000..4cb7c03d16cb --- /dev/null +++ b/drivers/clk/cix/acpi_clk.c @@ -0,0 +1,506 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + *Copyright 2024 Cix Technology Group Co., Ltd. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "acpi_clk.h" + +#define GET_CLOCK_RATE 0x00000001 +#define SET_CLOCK_RATE 0X00000002 +#define SET_CLOCK_CONFIG 0X00000003 + +#define CLOCK_REVISION_ID 1 +#define CLOCK_ENABLE BIT(0) +#define CLOCK_DISABLE 0 +#define CLK_MASK (0xffffffff) +#define SUCCESS 0 + +static LIST_HEAD(aclk_list); +static LIST_HEAD(aclk_hw_list); + +static struct acpi_device *acpi_obj_path_to_adev(union acpi_object *obj) +{ + struct acpi_device *adev = NULL; + char *path; + acpi_handle handle; + acpi_status status; + + if (!obj || !obj->string.length) + return NULL; + + path = obj->string.pointer; + status = acpi_get_handle(NULL, path, &handle); + if (ACPI_FAILURE(status)) { + return NULL; + } + +#if LINUX_VERSION_CODE <= KERNEL_VERSION(6, 0, 0) + adev = acpi_bus_get_acpi_device(handle); +#else + adev = acpi_fetch_acpi_dev(handle); +#endif + + return adev; +} + +static struct acpi_device *acpi_obj_to_adev(union acpi_object *obj) +{ + if (!obj) + return NULL; + + if (obj->type == ACPI_TYPE_LOCAL_REFERENCE) + return acpi_fetch_acpi_dev(obj->reference.handle); + else if (obj->type == ACPI_TYPE_STRING) + return acpi_obj_path_to_adev(obj); + else + return NULL; +} + +static int acpi_clock_config_set(struct device *dev, u32 clk_id, u32 config) +{ + acpi_handle handle = ACPI_HANDLE(dev); + acpi_status status; + u32 buf_val[1]; + int ret = 0; + union acpi_object *package; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object args[2] = { + { .type = ACPI_TYPE_INTEGER, }, + { .type = ACPI_TYPE_INTEGER, }, + }; + + struct acpi_object_list arg_list = { + .pointer = args, + .count = ARRAY_SIZE(args), + }; + + args[0].integer.value = clk_id; + args[1].integer.value = config; + + status = acpi_evaluate_object(handle, "CLKC", &arg_list, &buffer); + if (ACPI_FAILURE(status)) { + dev_err(dev, "ACPI evaluation failed\n"); + ret = -ENODEV; + goto OUT; + } + + package = buffer.pointer; + if (!package || package->type != ACPI_TYPE_BUFFER) { + dev_err(dev, "Couldn't locate correct ACPI buffer\n"); + ret = -ENODEV; + goto OUT; + } + + buf_val[0] = *(u32 *)package->buffer.pointer; + if (buf_val[0] != SUCCESS) { + dev_err(dev, "ACPI clk[%u] set config[%u] err:%d\n", + clk_id, config, buf_val[0]); + ret = -ENODEV; + goto OUT; + } + +OUT: + if (buffer.pointer) + kfree(buffer.pointer); + + return ret; +} + +static int acpi_clk_prepare(struct clk_hw *hw) +{ + struct acpi_clk_hw *aclk = to_acpi_clk_hw(hw); + + if (!aclk) + return -EINVAL; + + return acpi_clock_config_set(aclk->dev, aclk->clk_id, CLOCK_ENABLE); +} + +static void acpi_clk_unprepare(struct clk_hw *hw) +{ + struct acpi_clk_hw *aclk = to_acpi_clk_hw(hw); + + if (!aclk) + return; + + acpi_clock_config_set(aclk->dev, aclk->clk_id, CLOCK_DISABLE); +} + +static unsigned long acpi_cix_clk_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct acpi_clk_hw *aclk_hw = to_acpi_clk_hw(hw); + struct device *dev = aclk_hw->dev; + acpi_handle handle = ACPI_HANDLE(dev); + acpi_status status; + unsigned long clk_rate; + u32 buf_val[3] = {0}; + int ret = 0; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object args[] = { + { .type = ACPI_TYPE_INTEGER, }, + }; + struct acpi_object_list arg_list = { + .pointer = args, + .count = ARRAY_SIZE(args), + }; + union acpi_object *package; + + args[0].integer.value = cpu_to_le32(aclk_hw->clk_id); + status = acpi_evaluate_object(handle, "GClK", &arg_list, &buffer); + if (ACPI_FAILURE(status)) { + dev_err(dev, "ACPI evaluation failed\n"); + ret = -ENODEV; + goto OUT; + } + + package = buffer.pointer; + if (!package || package->type != ACPI_TYPE_BUFFER) { + dev_err(dev, "Couldn't locate correct ACPI buffer\n"); + ret = -ENODEV; + goto OUT; + } + + buf_val[0] = ((u32 *)package->buffer.pointer)[0]; + buf_val[1] = ((u32 *)package->buffer.pointer)[1]; + buf_val[2] = ((u32 *)package->buffer.pointer)[2]; + if (buf_val[0] != SUCCESS) { + dev_err(dev, "ACPI clk[%u] rec rate err:%d\n", + aclk_hw->clk_id, buf_val[0]); + ret = buf_val[0]; + goto OUT; + } + + clk_rate = ((u64)(buf_val[2] & CLK_MASK) << 32) + | (u64)(buf_val[1] & CLK_MASK); + +OUT: + if (buffer.pointer) + kfree(buffer.pointer); + + return ret ? 0 : clk_rate; +} + +static int acpi_cix_clk_set_rate(struct clk_hw *hw, unsigned long rate, + unsigned long parent_rate) +{ + struct acpi_clk_hw *aclk_hw = to_acpi_clk_hw(hw); + struct device *dev = aclk_hw->dev; + acpi_handle handle = ACPI_HANDLE(dev); + acpi_status status; + u32 buf_val[1]; + int ret = 0; + union acpi_object *package; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object args[3] = { + { .type = ACPI_TYPE_INTEGER, }, + { .type = ACPI_TYPE_INTEGER, }, + { .type = ACPI_TYPE_INTEGER, }, + }; + + struct acpi_object_list arg_list = { + .pointer = args, + .count = ARRAY_SIZE(args), + }; + + args[0].integer.value = aclk_hw->clk_id; + args[1].integer.value = (cpu_to_le32(rate & CLK_MASK)); + args[2].integer.value = (cpu_to_le32((rate >> 32) & CLK_MASK)); + + status = acpi_evaluate_object(handle, "SClK", &arg_list, &buffer); + if (ACPI_FAILURE(status)) { + dev_err(dev, "ACPI evaluation failed\n"); + ret = -ENODEV; + goto OUT; + } + + package = buffer.pointer; + if (!package || package->type != ACPI_TYPE_BUFFER) { + dev_err(dev, "Couldn't locate ACPI buffer\n"); + ret = -ENODEV; + goto OUT; + } + + buf_val[0] = *(u32 *)package->buffer.pointer; + if (buf_val[0] != SUCCESS) { + dev_err(dev, "ACPI clk[%u] set rate err:%d\n", + aclk_hw->clk_id, buf_val[0]); + goto OUT; + } + +OUT: + if (buffer.pointer) + kfree(buffer.pointer); + + return ret; +} + +static long cix_acpi_clk_round_rate(struct clk_hw *hw, unsigned long rate, + unsigned long *prate) +{ + /* do not support now */ + return rate; +} + +static const struct clk_ops acpi_clk_ops = { + .prepare = acpi_clk_prepare, + .unprepare = acpi_clk_unprepare, + .recalc_rate = acpi_cix_clk_recalc_rate, + .round_rate = cix_acpi_clk_round_rate, + .set_rate = acpi_cix_clk_set_rate, +}; + +static const char *acpi_clk_get_obj_id(union acpi_object *obj) +{ + if (!obj) + return NULL; + + return obj->string.length ? obj->string.pointer : NULL; +} + +static struct clk_hw *acpi_clk_get_hw(unsigned int clk_id) +{ + struct acpi_clk_hw *aclk_hw; + + list_for_each_entry(aclk_hw, &aclk_hw_list, list) { + if (aclk_hw->clk_id == clk_id) + return &aclk_hw->hw; + } + + return NULL; +} + +static struct clk_hw *devm_acpi_clk_hw_alloc(struct device *dev, + unsigned int clk_id) +{ + struct acpi_clk_hw *aclk_hw = NULL; + + aclk_hw = devm_kzalloc(dev, sizeof(*aclk_hw), GFP_KERNEL); + if (IS_ERR(aclk_hw)) + return ERR_PTR(-ENOMEM); + + aclk_hw->clk_id = clk_id; + INIT_LIST_HEAD(&aclk_hw->list); + list_add_tail(&aclk_hw->list, &aclk_hw_list); + + return &aclk_hw->hw; +} + +static struct clk_hw *acpi_clk_get_or_create_hw(struct device *dev, int clk_id) +{ + struct clk_init_data init; + struct clk_hw *hw; + struct acpi_clk_hw *aclk_hw; + char clk_name[CLK_NAME_LEN]; + int ret; + + hw = acpi_clk_get_hw(clk_id); + if (!hw) { + snprintf(clk_name, CLK_NAME_LEN, "ACLK:%04d", clk_id); + + hw = devm_acpi_clk_hw_alloc(dev, clk_id); + if (!hw) + goto out; + hw->init = &init; + init.name = clk_name; + init.ops = &acpi_clk_ops; + init.num_parents = 0; + init.flags = CLK_GET_RATE_NOCACHE; + + aclk_hw = to_acpi_clk_hw(hw); + aclk_hw->dev = dev; + + /* register hw clk */ + ret = devm_clk_hw_register(dev, hw); + if (ret) + goto out; + } + + return hw; +out: + return NULL; +} + +int cix_acpi_parse_clkt_handle(acpi_handle handle, const char *name, + struct clk_hw *(get_hw)(struct device *, int), + void *data) +{ + struct device *dev = data; + struct acpi_buffer output = {ACPI_ALLOCATE_BUFFER, NULL}; + union acpi_object *out_obj, *clk_obj, *el[ACLK_MAX]; + acpi_status status; + int clk_num, pnum, i, ret=0; + struct acpi_device *adev; + struct acpi_clk *acpi_clks; + struct clk_hw *hw; + const char *con_id, *dname = NULL; + unsigned int clk_id; + + if (!get_hw) + return -EINVAL; + + /* Parse the ACPI CLKT table for this CPU. */ + status = acpi_evaluate_object_typed(handle, + (acpi_string)name, NULL, &output, ACPI_TYPE_PACKAGE); + if (ACPI_FAILURE(status)) { + ret = -ENODEV; + goto out_free; + } + + out_obj = (union acpi_object *) output.pointer; + clk_num = out_obj->package.count; + acpi_clks = devm_kcalloc(dev, clk_num, sizeof(struct acpi_clk), GFP_KERNEL); + if (!acpi_clks) { + ret = -ENOMEM; + goto out_free; + } + + /* acpi clk register */ + for (i = 0; i < clk_num; i++) { + clk_obj = &out_obj->package.elements[i]; + pnum = clk_obj->package.count; + if (pnum < ACLK_DEV) + continue; + + /* clk package: {id, con_id, [dev_id]} */ + el[0] = &clk_obj->package.elements[0]; + el[1] = &clk_obj->package.elements[1]; + el[2] = pnum > ACLK_DEV ? &clk_obj->package.elements[2] : NULL; + + if ((el[0]->type != ACPI_TYPE_INTEGER) + || (el[1]->type != ACPI_TYPE_STRING) + || (el[2] && el[2]->type != ACPI_TYPE_LOCAL_REFERENCE + && el[2]->type != ACPI_TYPE_STRING)) + continue; + + clk_id = el[0]->integer.value; + con_id = acpi_clk_get_obj_id(el[1]); + adev = el[2] ? acpi_obj_to_adev(el[2]) : NULL; + dname = adev ? dev_name(&adev->dev) : NULL; + + if (!con_id && !adev) + continue; + + hw = get_hw(dev, clk_id); + if (!hw) + continue; + + acpi_clks[i].hw = hw; + acpi_clks[i].cl.dev_id = dname; + acpi_clks[i].cl.con_id = devm_kstrdup(dev, con_id, GFP_KERNEL); + acpi_clks[i].cl.clk = hw->clk; + + clkdev_add(&acpi_clks[i].cl); + INIT_LIST_HEAD(&acpi_clks[i].list); + list_add_tail(&acpi_clks[i].list, &aclk_list); + + dev_dbg(dev, "clk: id[%d] con[%s] dev[%s]\n", + clk_id, con_id, dname); + } + +out_free: + if (output.pointer) + kfree(output.pointer); + + return ret; +} +EXPORT_SYMBOL_GPL(cix_acpi_parse_clkt_handle); + +int cix_acpi_parse_clkt(struct device *dev, const char *cname, + struct clk_hw *(get_hw)(struct device *, int)) +{ + if (!dev) + return -EINVAL; + + return cix_acpi_parse_clkt_handle(ACPI_HANDLE(dev), cname, get_hw, dev); +} +EXPORT_SYMBOL_GPL(cix_acpi_parse_clkt); + +static acpi_status acpi_bus_clk_scan(acpi_handle handle, u32 level, + void *context, void **ret_p) +{ + struct device *dev = context; + acpi_object_type acpi_type; + int ret; + + if (ACPI_FAILURE(acpi_get_type(handle, &acpi_type))) + return AE_OK; + + if (acpi_type != ACPI_TYPE_DEVICE) + return AE_OK; + + if (!dev) + return AE_OK; + + ret = cix_acpi_parse_clkt_handle(handle, "CLKT", + acpi_clk_get_or_create_hw, dev); + + if (ret && ret != -ENODEV) + return AE_ERROR; + + return AE_OK; +} + +static int cix_acpi_clk_probe(struct platform_device *pdev) +{ + acpi_status status; + + status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, acpi_bus_clk_scan, + NULL, &pdev->dev, NULL); + + /* do not ensure every resource since differnt configs */ + return status; +} + +static int cix_acpi_clk_remove(struct platform_device *pdev) +{ + return 0; +} + +static const struct acpi_device_id __maybe_unused cix_acpi_clk_match[] = { + { "CIXHA010", 0 }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, cix_acpi_clk_match); + +static struct platform_driver cix_acpi_clk_driver = { + .driver = { + .name = "cix_acpi_clk", + .acpi_match_table = ACPI_PTR(cix_acpi_clk_match), + }, + .probe = cix_acpi_clk_probe, + .remove = cix_acpi_clk_remove, +}; + +static int __init cix_acpi_clk_init(void) +{ + if (acpi_disabled) + return -ENODEV; + + return platform_driver_register(&cix_acpi_clk_driver); +} +core_initcall(cix_acpi_clk_init); + +static void __exit cix_acpi_clk_exit(void) +{ + platform_driver_unregister(&cix_acpi_clk_driver); +} +module_exit(cix_acpi_clk_exit); + +MODULE_AUTHOR("Copyright 2024 Cix Technology Group Co., Ltd."); +MODULE_DESCRIPTION("Cix acpi clock driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/cix/acpi_clk.h b/drivers/clk/cix/acpi_clk.h new file mode 100644 index 000000000000..d65d17e91103 --- /dev/null +++ b/drivers/clk/cix/acpi_clk.h @@ -0,0 +1,45 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#ifndef __CIX_APCI_CLK_H__ +#define __CIX_APCI_CLK_H__ + +#include + +enum { + ACLK_ID = 0, + ACLK_CON, + ACLK_DEV, + + ACLK_MAX, +}; + +struct acpi_clk { + struct clk_hw *hw; + struct clk_lookup cl; + + struct list_head list; +}; + +struct acpi_clk_hw { + unsigned int clk_id; + struct clk_hw hw; + struct device *dev; + + struct list_head list; +}; + +#define to_acpi_clk_hw(_hw) container_of(_hw, struct acpi_clk_hw, hw) + +#define CLK_NAME_LEN 32 + +int cix_acpi_parse_clkt(struct device *dev, const char *cname, + struct clk_hw *(get_hw)(struct device *, int)); +int cix_acpi_clks_parse(struct device *dev); +int cix_acpi_parse_clkt_handle(acpi_handle handle, const char *name, + struct clk_hw *(get_hw)(struct device *, int), + void *data); + +#endif diff --git a/drivers/clk/cix/acpi_scmi_clk.c b/drivers/clk/cix/acpi_scmi_clk.c new file mode 100644 index 000000000000..557f6a386a27 --- /dev/null +++ b/drivers/clk/cix/acpi_scmi_clk.c @@ -0,0 +1,72 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + *Copyright 2024 Cix Technology Group Co., Ltd. + */ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "acpi_clk.h" + +static struct clk_hw *get_clk_hw_from_provider(struct device *dev, int clk_id) +{ + struct clk_hw_onecell_data *clk_data; + struct clk_hw *hw; + + clk_data = (struct clk_hw_onecell_data *)dev_get_drvdata(dev); + + if (!clk_data || clk_id < 0 || clk_id >= clk_data->num) + return NULL; + + hw = clk_data->hws[clk_id]; + if (!hw) + return NULL; + + return hw; +} + +static acpi_status acpi_bus_scmi_clk_scan(acpi_handle handle, u32 level, + void *context, void **ret_p) +{ + struct device *dev = context; + acpi_object_type acpi_type; + int ret; + + if (ACPI_FAILURE(acpi_get_type(handle, &acpi_type))) + return AE_OK; + + if (acpi_type != ACPI_TYPE_DEVICE) + return AE_OK; + + if (!dev) + return AE_OK; + + ret = cix_acpi_parse_clkt_handle(handle, "CLKT", + get_clk_hw_from_provider, dev); + + if (ret && ret != -ENODEV) + return AE_ERROR; + + return AE_OK; +} + +int cix_acpi_clks_parse(struct device *dev) +{ + acpi_status status; + + status = acpi_walk_namespace(ACPI_TYPE_ANY, ACPI_ROOT_OBJECT, + ACPI_UINT32_MAX, acpi_bus_scmi_clk_scan, + NULL, dev, NULL); + return status; +} +EXPORT_SYMBOL_GPL(cix_acpi_clks_parse); diff --git a/drivers/clk/cix/cix-clk-debug.c b/drivers/clk/cix/cix-clk-debug.c new file mode 100755 index 000000000000..0e01231b2d5d --- /dev/null +++ b/drivers/clk/cix/cix-clk-debug.c @@ -0,0 +1,266 @@ +// SPDX-License-Identifier: GPL-2.0 +/** + * Copyright 2024 Cix Technology Group Co., Ltd. + * All Rights Reserved. + * + * The following programs are the sole property of Copyright 2024 Cix Technology Group Co., Ltd., + * and contain its proprietary and confidential information. + */ + +#include +#include +#include +#include +#include +#include +#include + +#undef pr_fmt +#define pr_fmt(fmt) "clk-debug: " fmt +static struct clk *debug_clk; + +#ifdef MODULE +struct clk *__clk_lookup(const char *name) +{ + static struct clk* (*func)(const char *name); + + if (!func) + func = (void *)kallsyms_lookup_name(__func__); + + if (!func) { + pr_err("can't find symbol: %s\n", __func__); + return NULL; + } + + return func(name); +} +#endif + +static ssize_t parent_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + int ret; + char clk_name[24]; + char input[24]; + struct clk *clk; + + if (count >= sizeof(input)) + return -EINVAL; + + if (copy_from_user(input, buffer, count)) + return -EFAULT; + + input[count] = '\0'; + + ret = sscanf(input, "%s", clk_name); + if (ret != 1) { + pr_err("wrong usage, try: echo clk_name > clk\n"); + return -EINVAL; + } + + clk = __clk_lookup(clk_name); + if (!clk) + pr_err("Can't find the clock, have a look in /sys/kernel/debug/clk\n"); + + if (debug_clk) { + ret = clk_set_parent(debug_clk, clk); + if (ret < 0) + pr_err("failed to set parent for %s\n", + __clk_get_name(debug_clk)); + else + pr_info("now %s parent is %s\n", + __clk_get_name(debug_clk), + __clk_get_name(clk_get_parent(debug_clk))); + } else { + pr_err("try: echo clk_name > clk,echo clk_name > parent\n"); + } + + return count; +} + +static ssize_t enable_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + char buf[4]; + unsigned int len; + + len = sprintf(buf, "%d\n", __clk_is_enabled(debug_clk) ? 1 : 0); + + return simple_read_from_buffer(buffer, count, ppos, buf, len); +} + +static ssize_t enable_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + int ret; + char *input; + unsigned int enable = 0; + + input = kzalloc(count, GFP_KERNEL); + if (!input) { + kfree(input); + return -ENOMEM; + } + if (copy_from_user(input, buffer, count)) { + kfree(input); + return -EFAULT; + } + + ret = kstrtouint(input, 0, &enable); + if (ret) { + kfree(input); + return -EINVAL; + } + + if (enable != 0) + clk_prepare_enable(debug_clk); + else + clk_disable_unprepare(debug_clk); + + kfree(input); + return count; +} + +static ssize_t rate_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + /* + * the rate unit is HZ, need 16 char + */ + char buf[16]; + unsigned int len; + + len = sprintf(buf, "%lu\n", clk_get_rate(debug_clk)); + + return simple_read_from_buffer(buffer, count, ppos, buf, len); +} + +static ssize_t rate_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + int ret; + char *input; + unsigned long rate = 0; + + input = kzalloc(count, GFP_KERNEL); + if (!input) { + kfree(input); + return -ENOMEM; + } + + if (copy_from_user(input, buffer, count)) { + kfree(input); + return -EFAULT; + } + ret = kstrtoul(input, 0, &rate); + if (ret) { + kfree(input); + return -EINVAL; + } + pr_info("input rate = %lu, old rate = %lu\n", rate, + clk_get_rate(debug_clk)); + + ret = clk_set_rate(debug_clk, rate); + if (ret) { + kfree(input); + pr_err("failed to set rate,ret =%d\n", ret); + return ret; + } + + pr_info("current rate = %lu\n", clk_get_rate(debug_clk)); + + kfree(input); + + return count; +} + +static ssize_t clk_read(struct file *file, char __user *buffer, + size_t count, loff_t *ppos) +{ + char buf[48]; + unsigned int len; + + len = sprintf(buf, "get %s clock, its rate = %lu\n", + __clk_get_name(debug_clk), + clk_get_rate(debug_clk)); + + return simple_read_from_buffer(buffer, count, ppos, buf, len); +} + +static ssize_t clk_write(struct file *file, const char __user *buffer, + size_t count, loff_t *ppos) +{ + int ret; + char clk_name[24]; + char input[24]; + struct clk *clk; + + if (count >= sizeof(input)) + return -EINVAL; + + if (copy_from_user(input, buffer, count)) + return -EFAULT; + + input[count] = '\0'; + + ret = sscanf(input, "%s", clk_name); + if (ret != 1) { + pr_err("wrong usage, try: echo clk_name > clk\n"); + return -EINVAL; + } + + clk = __clk_lookup(clk_name); + if (clk) + pr_info("success get %s clock, its rate = %lu, its parent is %s\n", + clk_name, clk_get_rate(clk), + __clk_get_name(clk_get_parent(clk))); + else + pr_err("Can't find the clock, have a look in /sys/kernel/debug/clk.\n"); + + /* store the clk pointer */ + debug_clk = clk; + + return count; +} + +static const struct file_operations parent_file_ops = { + .open = simple_open, + .write = parent_write, +}; + +static const struct file_operations enable_file_ops = { + .open = simple_open, + .read = enable_read, + .write = enable_write, +}; + +static const struct file_operations rate_file_ops = { + .open = simple_open, + .read = rate_read, + .write = rate_write, +}; + +static const struct file_operations clk_file_ops = { + .open = simple_open, + .read = clk_read, + .write = clk_write, +}; + +static int __init clk_debug_init(void) +{ + struct dentry *root; + + root = debugfs_create_dir("clk_debug", NULL); + debugfs_create_file("clk", 0600, root, NULL, &clk_file_ops); + debugfs_create_file("rate", 0600, root, NULL, &rate_file_ops); + debugfs_create_file("enable", 0600, root, NULL, &enable_file_ops); + debugfs_create_file("parent", 0200, root, NULL, &parent_file_ops); + + return 0; +} + +late_initcall_sync(clk_debug_init); + +MODULE_AUTHOR("Cix clock driver owner"); +MODULE_DESCRIPTION("cix clock debug driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/cix/clk-sky1-audss.c b/drivers/clk/cix/clk-sky1-audss.c new file mode 100644 index 000000000000..c48bd67921f9 --- /dev/null +++ b/drivers/clk/cix/clk-sky1-audss.c @@ -0,0 +1,1257 @@ +// SPDX-License-Identifier: GPL-2.0-only +// Copyright 2024 Cix Technology Group Co., Ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include "acpi_clk.h" + +#define INFO_HIFI0 0x00 +#define INFO_CLK_GATE 0x10 +#define INFO_CLK_DIV 0x14 +#define INFO_CLK_MUX 0x18 +#define INFO_MCLK 0x70 + +#define SKY1_AUDSS_CLKS_NUM 6 + +#define SKY1_AUDSS_RCSU_ADDR 0x07000000 +#define SKY1_AUDSS_RCSU_LEN 0x10000 + +#define SKY1_AUDSS_RCSU_REMAP 0x34 +#define SKY1_AUDSS_RCSU_REMAP_VAL 0x20000000 + +#define SKY1_AUDSS_RCSU_TIMEOUT 0x1000 +#define SKY1_AUDSS_RCSU_TIMEOUT_EN BIT(31) +#define SKY1_AUDSS_RCSU_TIMEOUT_MASK GENMASK(15, 0) +#define SKY1_AUDSS_RCSU_TIMEOUT_VAL 0x78 + +struct muxdiv_cfg { + int offset; + u8 shift; + u8 width; + u8 flags; +}; + +struct gate_cfg { + int offset; + u8 shift; + u8 flags; +}; + +struct composite_clk_cfg { + u32 id; + const char *name; + const char * const *parent_names; + int num_parents; + struct muxdiv_cfg *mux_cfg; + struct muxdiv_cfg *div_cfg; + struct gate_cfg *gate_cfg; + unsigned long flags; +}; + +static DEFINE_SPINLOCK(lock); +static struct clk_hw_onecell_data *clk_data; + +static u32 reg_save[][2] = { + { INFO_HIFI0, 0 }, + { INFO_CLK_GATE, 0 }, + { INFO_CLK_DIV, 0 }, + { INFO_CLK_MUX, 0 }, + { INFO_MCLK, 0 }, +}; + +static const char *sky1_audss_clks_names[SKY1_AUDSS_CLKS_NUM] = { + "audio_clk0", "audio_clk1", "audio_clk2", + "audio_clk3", "audio_clk4", "audio_clk5", +}; + +static u32 clk_rate_default[SKY1_AUDSS_CLKS_NUM] = { + SKY1_AUDSS_AUDIO_CLK0_RATE, + SKY1_AUDSS_AUDIO_CLK1_RATE, + SKY1_AUDSS_AUDIO_CLK2_RATE, + SKY1_AUDSS_AUDIO_CLK3_RATE, + SKY1_AUDSS_AUDIO_CLK4_RATE, + SKY1_AUDSS_AUDIO_CLK5_RATE, +}; + +struct sky1_clk_divider { + struct clk_divider div; + struct regmap *regmap; + int offset; +}; + +struct sky1_clk_gate { + struct clk_gate gate; + struct regmap *regmap; + int offset; + struct device *dev; +}; + +struct sky1_clk_mux { + struct clk_mux mux; + struct regmap *regmap; + int offset; +}; + +struct sky1_audss_clks_priv { + struct device *dev; + void __iomem *rcsu_base; + struct regmap *regmap_cru; + struct clk *clks[SKY1_AUDSS_CLKS_NUM]; + struct reset_control *rst_noc; +}; + +/* + * NOTE: + * clock parent names should align to those SoC top clock names + * which feed to audio subsystem. + */ +static const char * const dsp_clk_parent[] = { + "audio_clk4" +}; + +static const char * const dsp_bclk_parent[] = { + "audio_clk4_div2" +}; + +static const char * const dsp_pbclk_parent[] = { + "audio_clk4_div4" +}; + +static const char * const sram_axi_parent[] = { + "audio_clk4_div2" +}; + +static const char * const hda_sys_parent[] = { + "audio_clk4_div2" +}; + +static const char * const hda_hda_parent[] = { + "audio_clk5" +}; + +static const char * const dmac_axi_parent[] = { + "audio_clk4_div2" +}; + +static const char * const wdg_apb_parent[] = { + "audio_clk5_div2" +}; + +static const char * const wdg_wdg_parent[] = { + "audio_clk5_div2" +}; + +static const char * const timer_apb_parent[] = { + "audio_clk4_div4" +}; + +static const char * const timer_timer_parent[] = { + "audio_clk5_div2" +}; + +static const char * const mailbox_apb_parent[] = { + "audio_clk4_div4" +}; + +static const char * const i2s_apb_parent[] = { + "audio_clk4_div4" +}; + +static const char * const i2s0_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s1_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s2_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s3_parents[] = { + "audio_clk0", "audio_clk1", "audio_clk2", "audio_clk3" +}; + +static const char * const i2s4_parents[] = { + "audio_clk0", "audio_clk1", "audio_clk2", "audio_clk3" +}; + +static const char * const i2s5_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s6_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s7_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s8_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const i2s9_parents[] = { + "audio_clk0", "audio_clk2" +}; + +static const char * const mclk_parents[] = { + "audio_clk0", "audio_clk2" +}; + +#define CFG(_id,\ + _name,\ + _parent_names,\ + _mux_offset, _mux_shift, _mux_width, _mux_flags,\ + _div_offset, _div_shift, _div_width, _div_flags,\ + _gate_offset, _gate_shift, _gate_flags,\ + _flags)\ +{\ + .id = _id,\ + .name = _name,\ + .parent_names = _parent_names,\ + .num_parents = ARRAY_SIZE(_parent_names),\ + .mux_cfg = &(struct muxdiv_cfg) { _mux_offset, _mux_shift, _mux_width, _mux_flags },\ + .div_cfg = &(struct muxdiv_cfg) { _div_offset, _div_shift, _div_width, _div_flags },\ + .gate_cfg = &(struct gate_cfg) { _gate_offset, _gate_shift, _gate_flags },\ + .flags = _flags,\ +} + +static const struct composite_clk_cfg audss_clks[] = { + /* dsp */ + CFG(CLK_DSP_CLK, + "audss_dsp_clk", + dsp_clk_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_HIFI0, 0, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_DSP_BCLK, + "audss_dsp_bclk", + dsp_bclk_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + -1, 0, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_DSP_PBCLK, + "audss_dsp_pbclk", + dsp_pbclk_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + -1, 0, 0, + CLK_GET_RATE_NOCACHE), + /* sram */ + CFG(CLK_SRAM_AXI, + "audss_sram_axi", + sram_axi_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 16, 0, + CLK_GET_RATE_NOCACHE), + /* hda */ + CFG(CLK_HDA_SYS, + "audss_hda_sys", + hda_sys_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 14, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_HDA_HDA, + "audss_hda_hda", + hda_hda_parent, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 14, 0, + CLK_GET_RATE_NOCACHE), + /* dmac */ + CFG(CLK_DMAC_AXI, + "audss_dmac_axi", + dmac_axi_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 15, 0, + CLK_GET_RATE_NOCACHE), + /* wdg */ + CFG(CLK_WDG_APB, + "audss_wdg_apb", + wdg_apb_parent, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 10, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_WDG_WDG, + "audss_wdg_wdg", + wdg_wdg_parent, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 10, 0, + CLK_GET_RATE_NOCACHE), + /* timer */ + CFG(CLK_TIMER_APB, + "audss_timer_apb", + timer_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 11, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_TIMER_TIMER, + "audss_timer_timer", + timer_timer_parent, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 11, 0, + CLK_GET_RATE_NOCACHE), + /* mailbox: mb0(ap->dsp), mb1(dsp->ap) */ + CFG(CLK_MB_0_APB, + "audss_mb_0_apb", + mailbox_apb_parent, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 12, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_MB_1_APB, + "audss_mb_1_apb", + mailbox_apb_parent, + -1, 0, 0, 0, + -1, 0, 0, 0, + INFO_CLK_GATE, 13, 0, + CLK_GET_RATE_NOCACHE), + /* i2s */ + CFG(CLK_I2S0_APB, + "audss_i2s0_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 0, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S1_APB, + "audss_i2s1_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 1, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S2_APB, + "audss_i2s2_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 2, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S3_APB, + "audss_i2s3_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 3, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S4_APB, + "audss_i2s4_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 4, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S5_APB, + "audss_i2s5_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 5, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S6_APB, + "audss_i2s6_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 6, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S7_APB, + "audss_i2s7_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 7, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S8_APB, + "audss_i2s8_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 8, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S9_APB, + "audss_i2s9_apb", + i2s_apb_parent, + -1, 0, 0, 0, + INFO_CLK_DIV, 0, 2, 0, + INFO_CLK_GATE, 9, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S0, + "audss_i2s0", + i2s0_parents, + INFO_CLK_MUX, 0, 2, 0, + INFO_CLK_DIV, 2, 2, 0, + INFO_CLK_GATE, 0, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S1, + "audss_i2s1", + i2s1_parents, + INFO_CLK_MUX, 2, 2, 0, + INFO_CLK_DIV, 4, 2, 0, + INFO_CLK_GATE, 1, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S2, + "audss_i2s2", + i2s2_parents, + INFO_CLK_MUX, 4, 2, 0, + INFO_CLK_DIV, 6, 2, 0, + INFO_CLK_GATE, 2, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S3, + "audss_i2s3", + i2s3_parents, + INFO_CLK_MUX, 6, 2, 0, + INFO_CLK_DIV, 8, 2, 0, + INFO_CLK_GATE, 3, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S4, + "audss_i2s4", + i2s4_parents, + INFO_CLK_MUX, 8, 2, 0, + INFO_CLK_DIV, 10, 2, 0, + INFO_CLK_GATE, 4, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S5, + "audss_i2s5", + i2s5_parents, + INFO_CLK_MUX, 10, 2, 0, + INFO_CLK_DIV, 12, 2, 0, + INFO_CLK_GATE, 5, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S6, + "audss_i2s6", + i2s6_parents, + INFO_CLK_MUX, 12, 2, 0, + INFO_CLK_DIV, 14, 2, 0, + INFO_CLK_GATE, 6, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S7, + "audss_i2s7", + i2s7_parents, + INFO_CLK_MUX, 14, 2, 0, + INFO_CLK_DIV, 16, 2, 0, + INFO_CLK_GATE, 7, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S8, + "audss_i2s8", + i2s8_parents, + INFO_CLK_MUX, 16, 2, 0, + INFO_CLK_DIV, 18, 2, 0, + INFO_CLK_GATE, 8, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_I2S9, + "audss_i2s9", + i2s9_parents, + INFO_CLK_MUX, 18, 2, 0, + INFO_CLK_DIV, 20, 2, 0, + INFO_CLK_GATE, 9, 0, + CLK_GET_RATE_NOCACHE), + /* mclk */ + CFG(CLK_MCLK0, + "audss_mclk0", + mclk_parents, + INFO_MCLK, 5, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 0, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_MCLK1, + "audss_mclk1", + mclk_parents, + INFO_MCLK, 6, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 1, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_MCLK2, + "audss_mclk2", + mclk_parents, + INFO_MCLK, 7, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 2, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_MCLK3, + "audss_mclk3", + mclk_parents, + INFO_MCLK, 8, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 3, 0, + CLK_GET_RATE_NOCACHE), + CFG(CLK_MCLK4, + "audss_mclk4", + mclk_parents, + INFO_MCLK, 9, 1, 0, + -1, 0, 0, 0, + INFO_MCLK, 4, 0, + CLK_GET_RATE_NOCACHE), +}; + +static inline struct sky1_clk_mux *to_sky1_clk_mux(struct clk_mux *mux) +{ + return container_of(mux, struct sky1_clk_mux, mux); +} + +static u8 sky1_audss_clk_mux_get_parent(struct clk_hw *hw) +{ + struct clk_mux *mux = to_clk_mux(hw); + struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux); + u32 val; + + regmap_read(sky1_mux->regmap, sky1_mux->offset, &val); + val = val >> mux->shift; + val &= mux->mask; + + return clk_mux_val_to_index(hw, mux->table, mux->flags, val); +} + +static int sky1_audss_clk_mux_set_parent(struct clk_hw *hw, u8 index) +{ + struct clk_mux *mux = to_clk_mux(hw); + struct sky1_clk_mux *sky1_mux = to_sky1_clk_mux(mux); + u32 val = clk_mux_index_to_val(mux->table, mux->flags, index); + unsigned long flags = 0; + u32 reg; + + if (mux->lock) + spin_lock_irqsave(mux->lock, flags); + else + __acquire(mux->lock); + + if (mux->flags & CLK_MUX_HIWORD_MASK) { + reg = mux->mask << (mux->shift + 16); + } else { + regmap_read(sky1_mux->regmap, sky1_mux->offset, ®); + reg &= ~(mux->mask << mux->shift); + } + val = val << mux->shift; + reg |= val; + regmap_write(sky1_mux->regmap, sky1_mux->offset, reg); + + if (mux->lock) + spin_unlock_irqrestore(mux->lock, flags); + else + __release(mux->lock); + + return 0; +} + +static int sky1_audss_clk_mux_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_mux *mux = to_clk_mux(hw); + + return clk_mux_determine_rate_flags(hw, req, mux->flags); +} + +/* Derive from drivers/clk/clk-mux.c clk_mux_ops */ +static const struct clk_ops sky1_audss_clk_mux_ops = { + .get_parent = sky1_audss_clk_mux_get_parent, + .set_parent = sky1_audss_clk_mux_set_parent, + .determine_rate = sky1_audss_clk_mux_determine_rate, +}; + +static inline struct sky1_clk_divider *to_sky1_clk_divider(struct clk_divider *div) +{ + return container_of(div, struct sky1_clk_divider, div); +} + +static unsigned long sky1_audss_clk_divider_recalc_rate(struct clk_hw *hw, + unsigned long parent_rate) +{ + struct clk_divider *divider = to_clk_divider(hw); + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider); + unsigned int val; + + regmap_read(sky1_div->regmap, sky1_div->offset, &val); + val = val >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_recalc_rate(hw, parent_rate, val, divider->table, + divider->flags, divider->width); +} + +static long sky1_audss_clk_divider_round_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long *prate) +{ + struct clk_divider *divider = to_clk_divider(hw); + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider); + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { + u32 val; + + regmap_read(sky1_div->regmap, sky1_div->offset, &val); + val = val >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_ro_round_rate(hw, rate, prate, divider->table, + divider->width, divider->flags, + val); + } + + return divider_round_rate(hw, rate, prate, divider->table, + divider->width, divider->flags); +} + +static int sky1_audss_clk_divider_determine_rate(struct clk_hw *hw, + struct clk_rate_request *req) +{ + struct clk_divider *divider = to_clk_divider(hw); + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider); + + /* if read only, just return current value */ + if (divider->flags & CLK_DIVIDER_READ_ONLY) { + u32 val; + + regmap_read(sky1_div->regmap, sky1_div->offset, &val); + val = val >> divider->shift; + val &= clk_div_mask(divider->width); + + return divider_ro_determine_rate(hw, req, divider->table, + divider->width, + divider->flags, val); + } + + return divider_determine_rate(hw, req, divider->table, divider->width, + divider->flags); +} + +static int sky1_audss_clk_divider_set_rate(struct clk_hw *hw, + unsigned long rate, + unsigned long parent_rate) +{ + struct clk_divider *divider = to_clk_divider(hw); + struct sky1_clk_divider *sky1_div = to_sky1_clk_divider(divider); + int value; + unsigned long flags = 0; + u32 val; + + value = divider_get_val(rate, parent_rate, divider->table, + divider->width, divider->flags); + if (value < 0) + return value; + + if (divider->lock) + spin_lock_irqsave(divider->lock, flags); + else + __acquire(divider->lock); + + if (divider->flags & CLK_DIVIDER_HIWORD_MASK) { + val = clk_div_mask(divider->width) << (divider->shift + 16); + } else { + val = regmap_read(sky1_div->regmap, sky1_div->offset, &val); + val &= ~(clk_div_mask(divider->width) << divider->shift); + } + val |= (u32)value << divider->shift; + regmap_write(sky1_div->regmap, sky1_div->offset, val); + + if (divider->lock) + spin_unlock_irqrestore(divider->lock, flags); + else + __release(divider->lock); + + return 0; +} + +/* Derive from drivers/clk/clk-divider.c clk_div_ops */ +static const struct clk_ops sky1_audss_clk_divider_ops = { + .recalc_rate = sky1_audss_clk_divider_recalc_rate, + .round_rate = sky1_audss_clk_divider_round_rate, + .determine_rate = sky1_audss_clk_divider_determine_rate, + .set_rate = sky1_audss_clk_divider_set_rate, +}; + +static inline struct sky1_clk_gate *to_sky1_clk_gate(struct clk_gate *gate) +{ + return container_of(gate, struct sky1_clk_gate, gate); +} + +static void sky1_audss_clk_gate_endisable(struct clk_hw *hw, int enable) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate); + int set = gate->flags & CLK_GATE_SET_TO_DISABLE ? 1 : 0; + unsigned long flags; + u32 reg; + + set ^= enable; + + if (gate->lock) + spin_lock_irqsave(gate->lock, flags); + else + __acquire(gate->lock); + + if (gate->flags & CLK_GATE_HIWORD_MASK) { + reg = BIT(gate->bit_idx + 16); + if (set) + reg |= BIT(gate->bit_idx); + } else { + regmap_read(sky1_gate->regmap, sky1_gate->offset, ®); + + if (set) + reg |= BIT(gate->bit_idx); + else + reg &= ~BIT(gate->bit_idx); + } + + regmap_write(sky1_gate->regmap, sky1_gate->offset, reg); + + if (gate->lock) + spin_unlock_irqrestore(gate->lock, flags); + else + __release(gate->lock); +} + +static int sky1_audss_clk_gate_enable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate); + unsigned long flags; + + spin_lock_irqsave(&sky1_gate->dev->power.lock, flags); + + if (!pm_runtime_active(sky1_gate->dev)) { + /* Should not happen theoretically, just add a check to + * avoid access harware exceptionally. + */ + dev_err(sky1_gate->dev, "enable clock when audss clock controller in suspended\n"); + return -EPERM; + } else { + if (sky1_gate->offset == INFO_CLK_GATE && BIT(gate->bit_idx) == BIT(15)) { + dev_dbg(sky1_gate->dev, "enable dmac clock\n"); + pm_runtime_get_noresume(sky1_gate->dev); + } + + sky1_audss_clk_gate_endisable(hw, 1); + } + + spin_unlock_irqrestore(&sky1_gate->dev->power.lock, flags); + + return 0; +} + +static void sky1_audss_clk_gate_disable(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate); + unsigned long flags; + + spin_lock_irqsave(&sky1_gate->dev->power.lock, flags); + + if (!pm_runtime_active(sky1_gate->dev)) { + /* Should not happen theoretically, just add a check to + * avoid access harware exceptionally. + */ + dev_err(sky1_gate->dev, "disable clock when audss clock controller in suspended\n"); + return; + } else { + sky1_audss_clk_gate_endisable(hw, 0); + + if (sky1_gate->offset == INFO_CLK_GATE && BIT(gate->bit_idx) == BIT(15)) { + dev_dbg(sky1_gate->dev, "disable dmac clock\n"); + pm_runtime_put_noidle(sky1_gate->dev); + } + } + + spin_unlock_irqrestore(&sky1_gate->dev->power.lock, flags); +} + +static int sky1_audss_clk_gate_is_enabled(struct clk_hw *hw) +{ + u32 reg; + struct clk_gate *gate = to_clk_gate(hw); + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate); + + regmap_read(sky1_gate->regmap, sky1_gate->offset, ®); + + /* if a set bit disables this clk, flip it before masking */ + if (gate->flags & CLK_GATE_SET_TO_DISABLE) + reg ^= BIT(gate->bit_idx); + + reg &= BIT(gate->bit_idx); + + return reg ? 1 : 0; +} + +static int sky1_audss_clk_gate_prepare(struct clk_hw *hw) +{ + struct clk_gate *gate = to_clk_gate(hw); + struct sky1_clk_gate *sky1_gate = to_sky1_clk_gate(gate); + + if (sky1_gate->offset == INFO_CLK_GATE && BIT(gate->bit_idx) == BIT(15)) { + dev_dbg(sky1_gate->dev, "prepare dmac clock\n"); + /* + * Just decrease the power usage_count, would not trigger power management. + * 1) if only enable dmac, power and clk would always keep on. + * 2) if enable i2s + dmac, would depend on i2s do power management. + * Luckily, dmac always work with i2s on audio ss. + */ + pm_runtime_put_noidle(sky1_gate->dev); + } + + return 0; +} + +/* Derive from drivers/clk/clk-gate.c clk_gate_ops */ +static const struct clk_ops sky1_audss_clk_gate_ops = { + .enable = sky1_audss_clk_gate_enable, + .disable = sky1_audss_clk_gate_disable, + .is_enabled = sky1_audss_clk_gate_is_enabled, + .prepare = sky1_audss_clk_gate_prepare, +}; + +static struct clk_hw *sky1_audss_clk_register(struct device *dev, + const char *name, + const char * const *parent_names, + int num_parents, + struct regmap *regmap, + struct muxdiv_cfg *mux_cfg, + struct muxdiv_cfg *div_cfg, + struct gate_cfg *gate_cfg, + unsigned long flags, + spinlock_t *lock) +{ + const struct clk_ops *sky1_mux_ops = NULL; + const struct clk_ops *sky1_div_ops = NULL; + const struct clk_ops *sky1_gate_ops = NULL; + struct clk_hw *hw = ERR_PTR(-ENOMEM); + struct sky1_clk_divider *sky1_div = NULL; + struct sky1_clk_gate *sky1_gate = NULL; + struct sky1_clk_mux *sky1_mux = NULL; + struct clk_parent_data *pdata; + int i; + + pdata = devm_kzalloc(dev, sizeof(*pdata) * num_parents, GFP_KERNEL); + if (!pdata) + return ERR_PTR(-ENOMEM); + for (i = 0; i < num_parents; i++) { + (&pdata[i])->fw_name = *(parent_names + i); + (&pdata[i])->index = 0; + } + + if (mux_cfg->offset >= 0) { + sky1_mux = devm_kzalloc(dev, sizeof(*sky1_mux), GFP_KERNEL); + if (!sky1_mux) + return ERR_PTR(-ENOMEM); + + sky1_mux->mux.reg = NULL; + sky1_mux->mux.shift = mux_cfg->shift; + sky1_mux->mux.mask = BIT(mux_cfg->width) - 1; + sky1_mux->mux.flags = mux_cfg->flags; + sky1_mux->mux.lock = lock; + sky1_mux_ops = &sky1_audss_clk_mux_ops; + sky1_mux->regmap = regmap; + sky1_mux->offset = mux_cfg->offset; + } + + if (div_cfg->offset >= 0) { + sky1_div = devm_kzalloc(dev, sizeof(*sky1_div), GFP_KERNEL); + if (!sky1_div) + return ERR_PTR(-ENOMEM); + + sky1_div->div.reg = NULL; + sky1_div->div.shift = div_cfg->shift; + sky1_div->div.width = div_cfg->width; + sky1_div->div.flags = div_cfg->flags | CLK_DIVIDER_POWER_OF_TWO; + sky1_div->div.lock = lock; + sky1_div_ops = &sky1_audss_clk_divider_ops; + sky1_div->regmap = regmap; + sky1_div->offset = div_cfg->offset; + } + + if (gate_cfg->offset >= 0) { + sky1_gate = devm_kzalloc(dev, sizeof(*sky1_gate), GFP_KERNEL); + if (!sky1_gate) + return ERR_PTR(-ENOMEM); + + sky1_gate->gate.reg = NULL; + sky1_gate->gate.bit_idx = gate_cfg->shift; + sky1_gate->gate.flags = gate_cfg->flags; + sky1_gate->gate.lock = lock; + sky1_gate_ops = &sky1_audss_clk_gate_ops; + sky1_gate->regmap = regmap; + sky1_gate->offset = gate_cfg->offset; + + sky1_gate->dev = dev; + } + + hw = devm_clk_hw_register_composite_pdata(dev, name, + pdata, num_parents, + sky1_mux ? &sky1_mux->mux.hw : NULL, sky1_mux_ops, + sky1_div ? &sky1_div->div.hw : NULL, sky1_div_ops, + sky1_gate ? &sky1_gate->gate.hw : NULL, sky1_gate_ops, + flags); + if (IS_ERR(hw)) { + dev_err(dev, "register %s clock failed with err = %ld\n", + name, PTR_ERR(hw)); + return ERR_CAST(hw); + } + + return hw; +} + +static int sky1_audss_clks_get(struct sky1_audss_clks_priv *priv) +{ + int i; + + for (i = 0; i < SKY1_AUDSS_CLKS_NUM; i++) { + priv->clks[i] = devm_clk_get(priv->dev, sky1_audss_clks_names[i]); + if (IS_ERR(priv->clks[i])) { + dev_err(priv->dev, "failed to get clock %s\n", + sky1_audss_clks_names[i]); + return PTR_ERR(priv->clks[i]); + } + } + + return 0; +} + +static int sky1_audss_clks_enable(struct sky1_audss_clks_priv *priv) +{ + int i, err; + + for (i = 0; i < SKY1_AUDSS_CLKS_NUM; i++) { + err = clk_prepare_enable(priv->clks[i]); + if (err) { + dev_err(priv->dev, "failed to enable clock %s\n", + sky1_audss_clks_names[i]); + goto err_clks; + } + } + + return 0; + +err_clks: + while (--i >= 0) + clk_disable_unprepare(priv->clks[i]); + + return err; +} + +static void sky1_audss_clks_disable(struct sky1_audss_clks_priv *priv) +{ + int i; + + for(i = 0; i < SKY1_AUDSS_CLKS_NUM; i++) + clk_disable_unprepare(priv->clks[i]); +} + +static int sky1_audss_clks_set_rate(struct sky1_audss_clks_priv *priv) +{ + int i, err; + + for (i = 0; i < SKY1_AUDSS_CLKS_NUM; i++) { + err = clk_set_rate(priv->clks[i], clk_rate_default[i]); + if (err) { + dev_err(priv->dev, "failed to set clock rate %s\n", + sky1_audss_clks_names[i]); + return err; + } + } + + return 0; +} + +static void sky1_audss_clks_get_rate(struct sky1_audss_clks_priv *priv) +{ + int i; + u32 rate; + + /* + * audio_clk0/1 feeded by audio_pll0, and audio_clk2/3 feeded by audio_pll1, + * need get clk rate after all clocks configed, since they have depenency. + */ + for (i = 0; i < SKY1_AUDSS_CLKS_NUM; i++) { + rate = clk_get_rate(priv->clks[i]); + dev_info(priv->dev, "%s: set rate = %d, get rate = %d\n", + sky1_audss_clks_names[i], clk_rate_default[i], rate); + } +} + +static struct clk_hw *acpi_audss_get_clk_hw(struct device *dev, int clk_id) +{ + if (clk_data && (clk_data->num >= clk_id)) + return clk_data->hws[clk_id]; + + return NULL; +} + +/* register sky1 audio subsystem clocks */ +static int sky1_audss_clk_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct reset_control *rst_noc; + struct sky1_audss_clks_priv *priv; + struct clk_hw **clk_table; + void __iomem *rcsu_base; + struct device_node *parent_np; + struct regmap *regmap_cru; + int i, ret; + + parent_np = of_get_parent(pdev->dev.of_node); + regmap_cru = syscon_node_to_regmap(parent_np); + of_node_put(parent_np); + + if (IS_ERR_OR_NULL(regmap_cru)) + regmap_cru = device_syscon_regmap_lookup_by_property(dev, + "audss_cru"); + if (IS_ERR_OR_NULL(regmap_cru)) + return -EINVAL; + + clk_data = devm_kzalloc(&pdev->dev, + struct_size(clk_data, hws, AUDSS_MAX_CLKS), + GFP_KERNEL); + if (!clk_data) + return -ENOMEM; + + clk_data->num = AUDSS_MAX_CLKS; + clk_table = clk_data->hws; + + priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL); + if (!priv) + return -ENOMEM; + + priv->dev = dev; + priv->regmap_cru = regmap_cru; + + + ret = sky1_audss_clks_get(priv); + if (ret) { + dev_err(dev, "failed to get clocks\n"); + return ret; + } + + platform_set_drvdata(pdev, priv); + + /* + * Enable runtime PM here to allow the clock core using runtime PM + * for the registered clocks. + */ + pm_runtime_get_noresume(dev); + pm_runtime_set_active(dev); + pm_runtime_enable(dev); + + /* + * enable audio ss clocks since rcsu slave end feeded by + * audio ss internal clocks, but rcsu master end feeded by + * cgc module. + */ + ret = sky1_audss_clks_enable(priv); + if (ret) { + dev_err(dev, "failed to enable clocks\n"); + goto fail_clks_enable; + } + + ret = sky1_audss_clks_set_rate(priv); + if (ret) { + dev_err(dev, "failed to set clocks rate\n"); + goto fail_clks_set; + } + + sky1_audss_clks_get_rate(priv); + + /* reset audio subsystem */ + rst_noc = devm_reset_control_get(dev, "noc"); + if (IS_ERR(rst_noc)) { + dev_err(dev, "failed to get noc reset\n"); + ret = PTR_ERR(rst_noc); + goto fail_reset; + } + priv->rst_noc = rst_noc; + + /* reset */ + reset_control_assert(rst_noc); + usleep_range(1, 2); + + /* release reset */ + reset_control_deassert(rst_noc); + + rcsu_base = ioremap(SKY1_AUDSS_RCSU_ADDR, SKY1_AUDSS_RCSU_LEN); + priv->rcsu_base = rcsu_base; + + /* set audio ss address remap */ + writel(SKY1_AUDSS_RCSU_REMAP_VAL, rcsu_base + SKY1_AUDSS_RCSU_REMAP); + + /* set and enable audio ss timeout */ + writel(SKY1_AUDSS_RCSU_TIMEOUT_EN | + FIELD_PREP(SKY1_AUDSS_RCSU_TIMEOUT_MASK, SKY1_AUDSS_RCSU_TIMEOUT_VAL), + rcsu_base + SKY1_AUDSS_RCSU_TIMEOUT); + + /* audio_clk4 clock fixed divider */ + clk_table[CLK_AUD_CLK4_DIV2] = + devm_clk_hw_register_fixed_factor(dev, + "audio_clk4_div2", + "audio_clk4", + CLK_GET_RATE_NOCACHE, + 1, 2); + clk_table[CLK_AUD_CLK4_DIV4] = + devm_clk_hw_register_fixed_factor(dev, + "audio_clk4_div4", + "audio_clk4", + CLK_GET_RATE_NOCACHE, + 1, 4); + + /* audio_clk5 clock fixed divider */ + clk_table[CLK_AUD_CLK5_DIV2] = + devm_clk_hw_register_fixed_factor(dev, + "audio_clk5_div2", + "audio_clk5", + CLK_GET_RATE_NOCACHE, + 1, 2); + + for (i = 0; i < ARRAY_SIZE(audss_clks); i++) + clk_table[audss_clks[i].id] = sky1_audss_clk_register(dev, + audss_clks[i].name, + audss_clks[i].parent_names, + audss_clks[i].num_parents, + regmap_cru, + audss_clks[i].mux_cfg, + audss_clks[i].div_cfg, + audss_clks[i].gate_cfg, + audss_clks[i].flags, + &lock); + + for (i = 0; i < clk_data->num; i++) { + if (IS_ERR(clk_table[i])) { + ret = PTR_ERR(clk_table[i]); + dev_err(dev, "failed to register clock %d, ret:%d\n", i, ret); + goto fail; + } + } + + if (ACPI_COMPANION(dev)) + ret = cix_acpi_parse_clkt(dev, "CLKA", acpi_audss_get_clk_hw); + else + ret = devm_of_clk_add_hw_provider(dev, + of_clk_hw_onecell_get, clk_data); + if (ret) { + dev_err(dev, "failed to add clock provider: %d\n", ret); + goto fail; + } + + pm_runtime_put_sync(dev); + + return 0; + +fail: + iounmap(rcsu_base); +fail_reset: + pm_runtime_put_sync(dev); +fail_clks_enable: +fail_clks_set: + pm_runtime_disable(dev); + return ret; +} + +static int sky1_audss_clk_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev); + + iounmap(priv->rcsu_base); + + if (!pm_runtime_status_suspended(dev)) + pm_runtime_force_suspend(dev); + + pm_runtime_disable(dev); + + return 0; +} + +static int __maybe_unused sky1_audss_clk_runtime_suspend(struct device *dev) +{ + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev); + int i; + + for (i = 0; i < ARRAY_SIZE(reg_save); i++) + regmap_read(priv->regmap_cru, reg_save[i][0], ®_save[i][1]); + + sky1_audss_clks_disable(priv); + + return 0; +} + +static int __maybe_unused sky1_audss_clk_runtime_resume(struct device *dev) +{ + struct sky1_audss_clks_priv *priv = dev_get_drvdata(dev); + int i, ret; + + ret = sky1_audss_clks_enable(priv); + if (ret) { + dev_err(dev, "failed to enable clocks\n"); + return ret; + } + + /* release reset */ + reset_control_deassert(priv->rst_noc); + + writel(SKY1_AUDSS_RCSU_REMAP_VAL, priv->rcsu_base + SKY1_AUDSS_RCSU_REMAP); + + for (i = 0; i < ARRAY_SIZE(reg_save); i++) + regmap_write(priv->regmap_cru, reg_save[i][0], reg_save[i][1]); + + return 0; +} + +static const struct dev_pm_ops sky1_audss_clk_pm_ops = { + SET_RUNTIME_PM_OPS(sky1_audss_clk_runtime_suspend, + sky1_audss_clk_runtime_resume, NULL) + SET_LATE_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, + pm_runtime_force_resume) +}; + +static const struct acpi_device_id sky1_audss_clk_acpi_match[] = { + { "CIXH6061", 0 }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, sky1_audss_clk_acpi_match); + +static const struct of_device_id sky1_audss_clk_of_match[] = { + { .compatible = "cix,sky1-audss-clock",}, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, sky1_audss_clk_of_match); + +static struct platform_driver sky1_audss_clk_driver = { + .probe = sky1_audss_clk_probe, + .remove = sky1_audss_clk_remove, + .driver = { + .name = "sky1-audss-clk", + .suppress_bind_attrs = true, + .of_match_table = sky1_audss_clk_of_match, + .acpi_match_table = ACPI_PTR(sky1_audss_clk_acpi_match), + .pm = &sky1_audss_clk_pm_ops, + }, +}; +module_platform_driver(sky1_audss_clk_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Joakim Zhang "); +MODULE_DESCRIPTION("Cixtech Sky1 Audio Subsystem Clock Controller Driver"); diff --git a/drivers/clk/cix/clk.c b/drivers/clk/cix/clk.c new file mode 100644 index 000000000000..ab7e5b5aeaa7 --- /dev/null +++ b/drivers/clk/cix/clk.c @@ -0,0 +1,82 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + *Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include "clk.h" + +#ifndef MODULE + +static bool cix_uart_clocks_keep; +static int cix_uart_clocks_enabled; +static struct clk **cix_uart_clocks; + +static int __init cix_uart_clocks_keep_param(char *str) +{ + cix_uart_clocks_keep = 1; + + return 0; +} +early_param("earlycon", cix_uart_clocks_keep_param); + +void cix_uart_clocks_register(void) +{ + unsigned int i, clk_count = 0; + cix_uart_clocks_enabled = 0; + +#ifdef CONFIG_OF + if (!of_stdout || !cix_uart_clocks_keep) + return; + + clk_count = of_clk_get_parent_count(of_stdout); + pr_info("%s: uart clock count=%d!\n", __func__, clk_count); + + if (!clk_count) { + pr_err("%s: uart clock no need to register, count=%d!\n", + __func__, clk_count); + return; + } + + + cix_uart_clocks = kcalloc(clk_count, sizeof(struct clk *), GFP_KERNEL); + if (!cix_uart_clocks) + return; + + for (i = 0; i < clk_count; i++) { + cix_uart_clocks[cix_uart_clocks_enabled] = of_clk_get(of_stdout, i); + + if (IS_ERR(cix_uart_clocks[cix_uart_clocks_enabled])) + return; + + if (cix_uart_clocks[cix_uart_clocks_enabled]) + clk_prepare_enable(cix_uart_clocks[cix_uart_clocks_enabled++]); + } +#endif +} +EXPORT_SYMBOL_GPL(cix_uart_clocks_register); + +static int __init cix_clk_disable_uart(void) +{ + if (cix_uart_clocks_keep && cix_uart_clocks_enabled) { + int i; + + for (i = 0; i < cix_uart_clocks_enabled; i++) { + clk_disable_unprepare(cix_uart_clocks[i]); + clk_put(cix_uart_clocks[i]); + } + kfree(cix_uart_clocks); + } + + return 0; +} +late_initcall_sync(cix_clk_disable_uart); +#endif + +MODULE_AUTHOR("Copyright 2024 Cix Technology Group Co., Ltd."); +MODULE_DESCRIPTION("Cix clock driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/clk/cix/clk.h b/drivers/clk/cix/clk.h new file mode 100644 index 000000000000..59c9b9275baf --- /dev/null +++ b/drivers/clk/cix/clk.h @@ -0,0 +1,18 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#ifndef __CIX_CLK_H__ +#define __CIX_CLK_H__ + +#include + +#ifndef MODULE +void cix_uart_clocks_register(void); +#else +static inline void cix_uart_clocks_register(void) +{ +} +#endif +#endif diff --git a/drivers/clk/clk-composite.c b/drivers/clk/clk-composite.c index 66759fe28fad..fecbd88eb699 100644 --- a/drivers/clk/clk-composite.c +++ b/drivers/clk/clk-composite.c @@ -234,6 +234,17 @@ static void clk_composite_disable(struct clk_hw *hw) gate_ops->disable(gate_hw); } +static int clk_composite_prepare(struct clk_hw *hw) +{ + struct clk_composite *composite = to_clk_composite(hw); + const struct clk_ops *gate_ops = composite->gate_ops; + struct clk_hw *gate_hw = composite->gate_hw; + + __clk_hw_set_clk(gate_hw, hw); + + return gate_ops->prepare(gate_hw); +} + static struct clk_hw *__clk_hw_register_composite(struct device *dev, const char *name, const char * const *parent_names, const struct clk_parent_data *pdata, int num_parents, @@ -324,6 +335,9 @@ static struct clk_hw *__clk_hw_register_composite(struct device *dev, clk_composite_ops->is_enabled = clk_composite_is_enabled; clk_composite_ops->enable = clk_composite_enable; clk_composite_ops->disable = clk_composite_disable; + + if (gate_ops->prepare) + clk_composite_ops->prepare = clk_composite_prepare; } init.ops = clk_composite_ops; @@ -490,3 +504,4 @@ struct clk_hw *devm_clk_hw_register_composite_pdata(struct device *dev, rate_hw, rate_ops, gate_hw, gate_ops, flags); } +EXPORT_SYMBOL_GPL(devm_clk_hw_register_composite_pdata); diff --git a/drivers/clk/clk-scmi.c b/drivers/clk/clk-scmi.c index fdec715c9ba9..41c172722960 100644 --- a/drivers/clk/clk-scmi.c +++ b/drivers/clk/clk-scmi.c @@ -12,6 +12,12 @@ #include #include #include +#include + +#ifdef CONFIG_ARCH_CIX +#include "./cix/clk.h" +#include "./cix/acpi_clk.h" +#endif static const struct scmi_clk_proto_ops *scmi_proto_clk_ops; @@ -174,7 +180,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev) struct clk_hw **hws; struct clk_hw_onecell_data *clk_data; struct device *dev = &sdev->dev; - struct device_node *np = dev->of_node; + struct fwnode_handle *fwnode = dev->fwnode; const struct scmi_handle *handle = sdev->handle; struct scmi_protocol_handle *ph; @@ -188,7 +194,7 @@ static int scmi_clocks_probe(struct scmi_device *sdev) count = scmi_proto_clk_ops->count_get(ph); if (count < 0) { - dev_err(dev, "%pOFn: invalid clock output count\n", np); + dev_err(dev, "%pFWn: invalid clock output count\n", fwnode); return -EINVAL; } @@ -245,8 +251,26 @@ static int scmi_clocks_probe(struct scmi_device *sdev) } } - return devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, - clk_data); + err = devm_of_clk_add_hw_provider(dev, of_clk_hw_onecell_get, + clk_data); + if (err) + return err; + +#ifdef CONFIG_ARCH_CIX + if (has_acpi_companion(dev)) { + void *driver_data = dev_get_drvdata(dev); + + dev_set_drvdata(dev, clk_data); + err = cix_acpi_clks_parse(dev); + + if (!IS_ERR_OR_NULL(driver_data)) + dev_set_drvdata(dev, driver_data); + } + + if (!err) + cix_uart_clocks_register(); +#endif + return err; } static const struct scmi_device_id scmi_id_table[] = { @@ -260,7 +284,16 @@ static struct scmi_driver scmi_clocks_driver = { .probe = scmi_clocks_probe, .id_table = scmi_id_table, }; + +#ifdef CONFIG_ARCH_CIX +static int __init scmi_clocks_init(void) +{ + return scmi_register(&scmi_clocks_driver); +} +subsys_initcall_sync(scmi_clocks_init); +#else module_scmi_driver(scmi_clocks_driver); +#endif MODULE_AUTHOR("Sudeep Holla "); MODULE_DESCRIPTION("ARM SCMI clock driver"); diff --git a/drivers/clocksource/Kconfig b/drivers/clocksource/Kconfig index 8208a3d89563..a039335b56a9 100644 --- a/drivers/clocksource/Kconfig +++ b/drivers/clocksource/Kconfig @@ -134,6 +134,12 @@ config RDA_TIMER help Enables the support for the RDA Micro timer driver. +config TIMER_SKY1_GPT + bool "SKY1 timer driver" + select CLKSRC_MMIO + help + Enables the support for the cix sky1 timer driver. + config SUN4I_TIMER bool "Sun4i timer driver" if COMPILE_TEST depends on HAS_IOMEM diff --git a/drivers/clocksource/Makefile b/drivers/clocksource/Makefile index 368c3461dab8..b1b16decf07f 100644 --- a/drivers/clocksource/Makefile +++ b/drivers/clocksource/Makefile @@ -59,6 +59,7 @@ obj-$(CONFIG_MILBEAUT_TIMER) += timer-milbeaut.o obj-$(CONFIG_SPRD_TIMER) += timer-sprd.o obj-$(CONFIG_NPCM7XX_TIMER) += timer-npcm7xx.o obj-$(CONFIG_RDA_TIMER) += timer-rda.o +obj-$(CONFIG_TIMER_SKY1_GPT) += timer-sky1-gpt.o obj-$(CONFIG_ARC_TIMERS) += arc_timer.o obj-$(CONFIG_ARM_ARCH_TIMER) += arm_arch_timer.o diff --git a/drivers/clocksource/arm_arch_timer.c b/drivers/clocksource/arm_arch_timer.c index 071b04f1ee73..19a200ec7eff 100644 --- a/drivers/clocksource/arm_arch_timer.c +++ b/drivers/clocksource/arm_arch_timer.c @@ -1753,7 +1753,11 @@ static int __init arch_timer_acpi_init(struct acpi_table_header *table) * When probing via ACPI, we have no mechanism to override the sysreg * CNTFRQ value. This *must* be correct. */ +#ifdef CONFIG_ARCH_CIX_EMU + arch_timer_rate = 1000000000; +#else arch_timer_rate = arch_timer_get_cntfrq(); +#endif ret = validate_timer_rate(); if (ret) { pr_err(FW_BUG "frequency not available.\n"); diff --git a/drivers/clocksource/timer-sky1-gpt.c b/drivers/clocksource/timer-sky1-gpt.c new file mode 100644 index 000000000000..5e6a15e94d13 --- /dev/null +++ b/drivers/clocksource/timer-sky1-gpt.c @@ -0,0 +1,396 @@ +// SPDX-License-Identifier: GPL-2.0+ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define TIMER_NAME "sky1_timer" +/*timer registers */ +#define LDINIT_RW 0x0000 /*Contains 32bit initial value to be loaded to Timer*/ +#define CAPT_CNT_0 0x0004 /*Contains 32bit to store the count value from Timer when captured */ +#define CAPT_CNT_1 0x0008 /*Contains 32bit to store the count value from Timer when captured */ +#define CAPT_CNT_2 0x000C /*Contains 32bit to store the count value from Timer when captured */ +#define CAPT_CNT_3 0x0010 /*Contains 32bit to store the count value from Timer when captured */ +#define CAPT_CNT_4 0x0014 /*Contains 32bit to store the count value from Timer when captured */ +#define PULSE_CNT 0x0018 /*Reserved*/ +#define FREE_CNT 0x001C /*Contains 32bit to store real-time Free-running count value*/ +#define COMP 0x0020 /*Contains 32bit to store the compare value in Free-running mode*/ +#define TCTL 0x0024 /*Control register for Timer*/ +#define PWMH 0x0028 /*Contains PWM_HIGH_TIME value to be loaded to Timer*/ +#define PWMPRD 0x002C /*Contains PWM_PERIOD value to be loaded to timer*/ +#define INTSTAT 0x0030 /*Interrupt status register*/ +#define INTCLR 0x0034 /*Clear interrupt status*/ + +/*timer function mode */ +#define GENER_MODE 0x0 /*Generate mode (default)*/ +#define CAP_MODE 0x1 /*Capture mode*/ +#define FREERUN_MODE 0x2 /*Free-running mode*/ +#define PWM_MODE 0x3 /*PWM mode*/ +#define PULSE_MODE 0x4 /*Pulse monitor mode*/ + +/*TCTL register */ +#define ENABLE (1 << 17) /*Enable Timer (This bit should be set finally)*/ +#define FREEENABLE (1 << 15) /*Free-running compare enabled*/ +#define TWID (1 << 12) /*Timer WIDTH 0:32bit 1:64bit */ +#define UPENABLE (0 << 7) /*Count up mode */ +#define INTENABLE (1 << 6) /*Interrupt enabled*/ +#define LOADENABLE (1 << 5) /*load LDINIT value to Timer*/ +#define RELOADENABLE (1 << 4) /*Reload generate value*/ + +/*timer width register*/ +#define TWIDENABLE (1 << 12) /*64-bit timer enable*/ + +/*INTCLR register*/ +#define FREE_INTCLEAR (1 << 5) /*clear free-running mode interrupt status*/ + +/*INTSTATUS register*/ +#define FREE_INTSTATUS (1 << 5) /*free-running mode interrupt status*/ + +/* OFFSET between odd timer and even timer*/ +#define TIMER_OFFSET 0x1000 + +struct sky1_timer { + void __iomem *base; + int irq; + struct clock_event_device ced; + struct clk *pclk, *tclk; + struct reset_control *func_reset; +}; + +static inline struct sky1_timer *to_sky1_timer(struct clock_event_device *ced) +{ + return container_of(ced, struct sky1_timer, ced); +} + +static void sky1_gpt_irq_disable(struct sky1_timer *sky1tm) +{ + u32 tmp; + + tmp = readl_relaxed(sky1tm->base + TIMER_OFFSET + TCTL); + writel_relaxed(tmp & ~INTENABLE, sky1tm->base + TIMER_OFFSET + TCTL); +} + +static void sky1_gpt_irq_enable(struct sky1_timer *sky1tm) +{ + u32 tmp; + + tmp = readl_relaxed(sky1tm->base + TIMER_OFFSET + TCTL); + writel_relaxed(tmp | INTENABLE, sky1tm->base + TIMER_OFFSET + TCTL); +} + +static void sky1_gpt_irq_acknowledge(struct sky1_timer *sky1tm) +{ + writel_relaxed(FREE_INTCLEAR, sky1tm->base + TIMER_OFFSET + INTCLR); +} + +static void sky1_gpt_setup_tctl(struct sky1_timer *sky1tm) +{ + u32 tctl_val; + + tctl_val = FREEENABLE | FREERUN_MODE | INTENABLE; + writel_relaxed(tctl_val, sky1tm->base + TCTL); + + tctl_val = FREEENABLE | TWID | FREERUN_MODE | INTENABLE; + writel_relaxed(tctl_val, sky1tm->base + TIMER_OFFSET + TCTL); + + /* + * Enable bit should be set no earlier than + * any other bits or registers + */ + tctl_val = ENABLE | FREEENABLE | FREERUN_MODE | INTENABLE; + writel_relaxed(tctl_val, sky1tm->base + TCTL); + + tctl_val = ENABLE | FREEENABLE | TWID | FREERUN_MODE | INTENABLE; + writel_relaxed(tctl_val, sky1tm->base + TIMER_OFFSET + TCTL); +} + + +static void __iomem *sched_clock_reg; + +/* + * To get the value from the Global Timer Counter register proceed as follows: + * 1. Read the upper 32-bit timer counter register + * 2. Read the lower 32-bit timer counter register + * 3. Read the upper 32-bit timer counter register again. If the value is + * different to the 32-bit upper value read previously, go back to step 2. + * Otherwise the 64-bit timer counter value is correct. + */ +static u64 notrace _sky1_gt_counter_read(void) +{ + u64 counter; + u32 lower; + u32 upper, old_upper; + + upper = readl_relaxed(sched_clock_reg + TIMER_OFFSET); + do { + old_upper = upper; + lower = readl_relaxed(sched_clock_reg); + upper = readl_relaxed(sched_clock_reg + TIMER_OFFSET); + } while (upper != old_upper); + + counter = upper; + counter <<= 32; + counter |= lower; + return counter; +} + +static u64 notrace sky1_read_sched_clock(void) +{ + return sched_clock_reg ? _sky1_gt_counter_read() : 0; +} + +static u64 sky1_gt_clocksource_read(struct clocksource *cs) +{ + return _sky1_gt_counter_read(); +} + +static struct clocksource clocksource_gpt = { + .name = "sky1_counter", + .rating = 200, + .read = sky1_gt_clocksource_read, + .mask = CLOCKSOURCE_MASK(64), + .flags = CLOCK_SOURCE_IS_CONTINUOUS, +}; + +static int __init sky1_clocksource_init(struct sky1_timer *sky1tm) +{ + unsigned int c = clk_get_rate(sky1tm->tclk); + void __iomem *reg = sky1tm->base + FREE_CNT; + + sched_clock_reg = reg; + + sched_clock_register(sky1_read_sched_clock, 64, c); + + return clocksource_register_hz(&clocksource_gpt, c); +} + +/* + * clock event + * To ensure that updates to comparator value register do not set the + * Interrupt Status Register proceed as follows: + * 1. Clear the Comp Enable bit in the Timer Control Register. + * 2. Write the lower 32-bit Comparator Value Register. + * 3. Write the upper 32-bit Comparator Value Register. + * 4. Set the Comp Enable bit and, if necessary, the IRQ enable bit. + */ +static int sky1_set_next_event(unsigned long evt, struct clock_event_device *ced) +{ + struct sky1_timer *sky1tm = to_sky1_timer(ced); + u64 tcn; + + tcn = _sky1_gt_counter_read(); + tcn = tcn + evt; + + /* Set event time into far-far future */ + writel_relaxed(tcn >> 32, sky1tm->base + COMP + TIMER_OFFSET); + writel_relaxed((u32)tcn, sky1tm->base + COMP); + + return tcn < _sky1_gt_counter_read() ? -ETIME : 0; +} + +static int sky1_shutdown(struct clock_event_device *ced) +{ + struct sky1_timer *sky1tm = to_sky1_timer(ced); + u64 tcn; + + /* Disable interrupt */ + sky1_gpt_irq_disable(sky1tm); + + tcn = _sky1_gt_counter_read(); + + /* Set event time into far-far future */ + writel_relaxed((tcn - 3) >> 32, sky1tm->base + COMP + TIMER_OFFSET); + writel_relaxed((u32)(tcn - 3), sky1tm->base + COMP); + + /* Clear pending interrupt */ + sky1_gpt_irq_acknowledge(sky1tm); + + return 0; +} + +static int sky1_tick_resume(struct clock_event_device *ced) +{ + struct sky1_timer *sky1tm = to_sky1_timer(ced); + + /* reset timer */ + if (!screen_info.lfb_linelength) + reset_control_reset(sky1tm->func_reset); + + sky1_gpt_setup_tctl(sky1tm); + + sky1_shutdown(ced); + + return 0; +} + +static int sky1_set_oneshot(struct clock_event_device *ced) +{ + struct sky1_timer *sky1tm = to_sky1_timer(ced); + u64 tcn; + + /* Disable interrupt */ + sky1_gpt_irq_disable(sky1tm); + + if (!clockevent_state_oneshot(ced)) { + tcn = _sky1_gt_counter_read(); + /* Set event time into far-far future */ + writel_relaxed((tcn - 3) >> 32, sky1tm->base + COMP + TIMER_OFFSET); + writel_relaxed((u32)(tcn - 3), sky1tm->base + COMP); + + /* Clear pending interrupt */ + sky1_gpt_irq_acknowledge(sky1tm); + } + +#ifdef DEBUG + printk(KERN_INFO "%s: changing mode\n", __func__); +#endif + + /* + * Do not put overhead of interrupt enable/disable into + * sky1_set_next_event(), the core has about 4 minutes + * to call sky1_set_next_event() or shutdown clock after + * mode switching + */ + sky1_gpt_irq_enable(sky1tm); + return 0; +} + +/* + * IRQ handler for the timer + */ +static irqreturn_t sky1_timer_interrupt(int irq, void *dev_id) +{ + struct clock_event_device *ced = dev_id; + struct sky1_timer *sky1tm = to_sky1_timer(ced); + + sky1_gpt_irq_acknowledge(sky1tm); + + ced->event_handler(ced); + + return IRQ_HANDLED; +} + +static int __init sky1_clockevent_init(struct sky1_timer *sky1tm) +{ + struct clock_event_device *ced = &sky1tm->ced; + + ced->name = TIMER_NAME; + ced->features = CLOCK_EVT_FEAT_ONESHOT | CLOCK_EVT_FEAT_DYNIRQ; + ced->set_next_event = sky1_set_next_event; + ced->set_state_shutdown = sky1_shutdown; + ced->set_state_oneshot = sky1_set_oneshot; + ced->set_state_oneshot_stopped = sky1_shutdown; + ced->tick_resume = sky1_tick_resume; + ced->rating = 200; + ced->cpumask = cpu_possible_mask; + ced->irq = sky1tm->irq; + clockevents_config_and_register(ced, clk_get_rate(sky1tm->tclk), 1, UINT_MAX); + + return request_irq(sky1tm->irq, sky1_timer_interrupt, + IRQF_TIMER, TIMER_NAME, ced); +} + +static int sky1_timer_probe(struct platform_device *pdev) +{ + struct sky1_timer *sky1tm; + static int initialized; + int ret = 0; + + /* Support one instance only */ + if (initialized) + return 0; + + sky1tm = devm_kzalloc(&pdev->dev, sizeof(*sky1tm), GFP_KERNEL); + if (!sky1tm) + return -ENOMEM; + + /* Acpi resource parse */ + sky1tm->base = devm_platform_ioremap_resource(pdev, 0); + if (!sky1tm->base) + return -ENXIO; + + sky1tm->irq = platform_get_irq(pdev, 0); + if (sky1tm->irq <= 0) + return -EINVAL; + + sky1tm->pclk = devm_clk_get(&pdev->dev, "fch_timer_apb_clk"); + if (IS_ERR(sky1tm->pclk)) + return -EINVAL; + + sky1tm->tclk = devm_clk_get(&pdev->dev, "fch_timer_func_clk"); + if (IS_ERR(sky1tm->tclk)) + return -EINVAL; + + clk_prepare_enable(sky1tm->pclk); + clk_prepare_enable(sky1tm->tclk); + + sky1tm->func_reset = devm_reset_control_get_optional_shared(&pdev->dev, "func_reset"); + if (IS_ERR(sky1tm->func_reset)) { + dev_err(&pdev->dev, "[%s:%d]get reset error\n", __func__, __LINE__); + ret = PTR_ERR(sky1tm->func_reset); + goto err_clk_dis; + } + + /* reset timer */ + if (!screen_info.lfb_linelength) /* already init in uefi */ + reset_control_reset(sky1tm->func_reset); + + sky1_gpt_setup_tctl(sky1tm); + + platform_set_drvdata(pdev, sky1tm); + + /* init and register the timer to the framework */ + ret = sky1_clocksource_init(sky1tm); + if (ret) + return ret; + + sky1_clockevent_init(sky1tm); + + initialized = 1; + + dev_info(&pdev->dev, "sky1 gpt timer init done\n"); + + return 0; + +err_clk_dis: + clk_disable_unprepare(sky1tm->pclk); + clk_disable_unprepare(sky1tm->tclk); + return ret; +} + +static const struct of_device_id sky1_timer_match_table[] = { + { .compatible = "cix,sky1-gpt" }, + { /* sentinel */ }, +}; + +static const struct acpi_device_id sky1_timer_acpi_match[] = { + { "CIXH1007", }, + { }, +}; +MODULE_DEVICE_TABLE(acpi, sky1_timer_acpi_match); + +static struct platform_driver sky1_timer_driver = { + .driver = { + .name = TIMER_NAME, + .of_match_table = sky1_timer_match_table, + .acpi_match_table = ACPI_PTR(sky1_timer_acpi_match), + }, + .probe = sky1_timer_probe, +}; +module_platform_driver(sky1_timer_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Jerry Zhu "); diff --git a/drivers/cpufreq/Kconfig b/drivers/cpufreq/Kconfig index 7e773c47a4fc..19a7431cd734 100644 --- a/drivers/cpufreq/Kconfig +++ b/drivers/cpufreq/Kconfig @@ -27,6 +27,11 @@ config CPU_FREQ_GOV_COMMON select IRQ_WORK bool +config DVFS_BOARD_CHECK + depends on ARCH_CIX + bool "config board check for dvfs" + default n + config CPU_FREQ_STAT bool "CPU frequency transition statistics" help diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index c5cecbd89ba9..dff9fa75caae 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -286,3 +286,10 @@ config ARM_PXA2xx_CPUFREQ This add the CPUFreq driver support for Intel PXA2xx SOCs. If in doubt, say N. + +config ARM_CIX_CPUFREQ + bool "CIX CPUFreq driver" + depends on CPU_FREQ + help + This enables the CPUFreq driver for cix Technologies, Inc. CPUs. + Say Y if you want to support CPUFreq SW. diff --git a/drivers/cpufreq/Makefile b/drivers/cpufreq/Makefile index ef8510774913..295de05a5303 100644 --- a/drivers/cpufreq/Makefile +++ b/drivers/cpufreq/Makefile @@ -85,6 +85,7 @@ obj-$(CONFIG_ARM_TEGRA186_CPUFREQ) += tegra186-cpufreq.o obj-$(CONFIG_ARM_TEGRA194_CPUFREQ) += tegra194-cpufreq.o obj-$(CONFIG_ARM_TI_CPUFREQ) += ti-cpufreq.o obj-$(CONFIG_ARM_VEXPRESS_SPC_CPUFREQ) += vexpress-spc-cpufreq.o +obj-$(CONFIG_ARM_CIX_CPUFREQ) += cix-cpufreq-dt.o ################################################################################## diff --git a/drivers/cpufreq/cix-cpufreq-dt.c b/drivers/cpufreq/cix-cpufreq-dt.c new file mode 100644 index 000000000000..dad54512bc69 --- /dev/null +++ b/drivers/cpufreq/cix-cpufreq-dt.c @@ -0,0 +1,272 @@ +// SPDX-License-Identifier: GPL-2.0 +// Copyright 2024 Cix Technology Group Co., Ltd. + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +struct cix_cpufreq_data { + void __iomem *base; + struct resource *res; +}; + +static int cix_cpufreq_read_lut(struct device *cpu_dev, + struct cpufreq_policy *policy) +{ + int ret; + + ret = dev_pm_opp_of_add_table(cpu_dev); + if (ret) { + dev_err(cpu_dev, "failed to parse cpufreq table: %d\n", ret); + return ret; + } + + ret = dev_pm_opp_init_cpufreq_table(cpu_dev, &policy->freq_table); + if (ret) { + dev_err(cpu_dev, "failed to init cpufreq table: %d\n", ret); + return ret; + } + + return 0; +} + +static unsigned int cix_cpufreq_get(unsigned int cpu) +{ + struct cpufreq_policy *policy; + unsigned int freq; + struct cix_cpufreq_data *data; + + policy = cpufreq_cpu_get_raw(cpu); + if (!policy) { + pr_err("%s: failed to get cpu%d cpufreq policy\n", __func__, + policy->cpu); + return 0; + } + + data = policy->driver_data; + if (policy->cur) + return policy->cur; + else + return policy->min; +} + +static int cix_cpufreq_target_index(struct cpufreq_policy *policy, + unsigned int index) +{ + return 0; +} + +static void cix_get_related_cpus(int index, struct cpumask *m) +{ + struct device_node *cpu_np; + struct of_phandle_args args; + int cpu, ret; + + for_each_possible_cpu(cpu) { + cpu_np = of_cpu_device_node_get(cpu); + if (!cpu_np) + continue; + + ret = of_parse_phandle_with_args(cpu_np, "cix,freq-domain", + "#freq-domain-cells", 0, + &args); + of_node_put(cpu_np); + if (ret < 0) + continue; + + if (index == args.args[0]) + cpumask_set_cpu(cpu, m); + } +} + +static int cix_cpufreq_cpu_init(struct cpufreq_policy *policy) +{ + struct platform_device *pdev = cpufreq_get_driver_data(); + struct device *dev = &pdev->dev; + struct device *cpu_dev; + struct of_phandle_args args; + struct resource *res; + void __iomem *base; + struct cix_cpufreq_data *data; + struct device_node *cpu_np; + int ret, index; + + cpu_dev = get_cpu_device(policy->cpu); + if (!cpu_dev) { + pr_err("%s: failed to get cpu%d device\n", __func__, + policy->cpu); + return -ENODEV; + } + + cpu_np = of_cpu_device_node_get(policy->cpu); + if (!cpu_np) { + pr_err("%s: failed to get cpu%d device node\n", __func__, + policy->cpu); + return -EINVAL; + } + + ret = of_parse_phandle_with_args(cpu_np, "cix,freq-domain", + "#freq-domain-cells", 0, &args); + if (ret) { + pr_err("%s: failed to parse cpu%d freq-domain\n", __func__, + policy->cpu); + return ret; + } + of_node_put(cpu_np); + + index = args.args[0]; + + res = platform_get_resource(pdev, IORESOURCE_MEM, index); + if (!res) { + dev_err(dev, "failed to get mem resource %d\n", index); + return -ENODEV; + } + + if (!request_mem_region(res->start, resource_size(res), res->name)) { + dev_err(dev, "failed to request resource %pR\n", res); + return -EBUSY; + } + + base = ioremap(res->start, resource_size(res)); + if (!base) { + dev_err(dev, "failed to map resource %pR\n", res); + ret = -ENOMEM; + goto release_region; + } + + data = kzalloc(sizeof(*data), GFP_KERNEL); + if (!data) { + ret = -ENOMEM; + goto unmap_base; + } + + data->base = base; + data->res = res; + + cix_get_related_cpus(index, policy->cpus); + if (!cpumask_weight(policy->cpus)) { + dev_err(dev, "Domain-%d failed to get related CPUs\n", index); + ret = -ENOENT; + goto error; + } + + policy->driver_data = data; + policy->dvfs_possible_from_any_cpu = true; + + ret = cix_cpufreq_read_lut(cpu_dev, policy); + if (ret) { + dev_err(cpu_dev, "Failed to read LUT\n"); + return -EINVAL; + } + ret = dev_pm_opp_get_opp_count(cpu_dev); + if (ret <= 0) { + dev_err(cpu_dev, "Failed to add OPPs\n"); + ret = -ENODEV; + goto error; + } + + if (policy_has_boost_freq(policy)) { + ret = cpufreq_enable_boost_support(); + if (ret) + dev_warn(cpu_dev, "failed to enable boost: %d\n", ret); + } + + return 0; +error: + kfree(data); +unmap_base: + iounmap(base); +release_region: + release_mem_region(res->start, resource_size(res)); + return ret; +} + +static int cix_cpufreq_cpu_exit(struct cpufreq_policy *policy) +{ + struct device *cpu_dev = get_cpu_device(policy->cpu); + struct cix_cpufreq_data *data = policy->driver_data; + struct resource *res = data->res; + void __iomem *base = data->base; + + dev_pm_opp_remove_all_dynamic(cpu_dev); + dev_pm_opp_of_cpumask_remove_table(policy->related_cpus); + kfree(policy->freq_table); + kfree(data); + iounmap(base); + release_mem_region(res->start, resource_size(res)); + + return 0; +} + +static struct freq_attr *cix_cpufreq_attrs[] = { + &cpufreq_freq_attr_scaling_available_freqs, + NULL +}; + +static struct cpufreq_driver cpufreq_cix_driver = { + .flags = CPUFREQ_NEED_INITIAL_FREQ_CHECK | + CPUFREQ_HAVE_GOVERNOR_PER_POLICY | + CPUFREQ_IS_COOLING_DEV, + .verify = cpufreq_generic_frequency_table_verify, + .target_index = cix_cpufreq_target_index, + .get = cix_cpufreq_get, + .init = cix_cpufreq_cpu_init, + .exit = cix_cpufreq_cpu_exit, + .name = "cix-cpufreq", + .attr = cix_cpufreq_attrs, +}; + +static int cix_cpufreq_driver_probe(struct platform_device *pdev) +{ + int ret; + + cpufreq_cix_driver.driver_data = pdev; + ret = cpufreq_register_driver(&cpufreq_cix_driver); + + return ret; +} + +static int cix_cpufreq_driver_remove(struct platform_device *pdev) +{ + return cpufreq_unregister_driver(&cpufreq_cix_driver); +} + +static const struct of_device_id cix_cpufreq_match[] = { + { .compatible = "cix,cpufreq"}, + {} +}; +MODULE_DEVICE_TABLE(of, cix_cpufreq_match); + +static struct platform_driver cix_cpufreq_driver = { + .probe = cix_cpufreq_driver_probe, + .remove = cix_cpufreq_driver_remove, + .driver = { + .name = "cix-cpufreq", + .of_match_table = cix_cpufreq_match, + }, +}; + +static int __init cix_cpufreq_init(void) +{ + return platform_driver_register(&cix_cpufreq_driver); +} +postcore_initcall(cix_cpufreq_init); + +static void __exit cix_cpufreq_exit(void) +{ + platform_driver_unregister(&cix_cpufreq_driver); +} +module_exit(cix_cpufreq_exit); +MODULE_AUTHOR("xinglong yang "); +MODULE_DESCRIPTION("CIX CPUFREQ DT Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/cpufreq/cppc_cpufreq.c b/drivers/cpufreq/cppc_cpufreq.c index aa34af940cb5..3852d575b7ed 100644 --- a/drivers/cpufreq/cppc_cpufreq.c +++ b/drivers/cpufreq/cppc_cpufreq.c @@ -21,7 +21,7 @@ #include #include #include - +#include #include #include @@ -173,16 +173,14 @@ static void cppc_cpufreq_cpu_fie_init(struct cpufreq_policy *policy) init_irq_work(&cppc_fi->irq_work, cppc_irq_work); ret = cppc_get_perf_ctrs(cpu, &cppc_fi->prev_perf_fb_ctrs); - if (ret) { + /* + * Don't abort if the CPU was offline while the driver + * was getting registered or during resume from S3 state. + */ + if (ret && cpu_online(cpu)) { pr_warn("%s: failed to read perf counters for cpu:%d: %d\n", __func__, cpu, ret); - - /* - * Don't abort if the CPU was offline while the driver - * was getting registered. - */ - if (cpu_online(cpu)) - return; + return; } } @@ -331,7 +329,7 @@ static unsigned int cppc_cpufreq_fast_switch(struct cpufreq_policy *policy, if (ret) { pr_debug("Failed to set target on CPU:%d. ret:%d\n", - cpu, ret); + cpu, ret); return 0; } @@ -377,6 +375,7 @@ static unsigned int cppc_cpufreq_get_transition_delay_us(unsigned int cpu) #if defined(CONFIG_ARM64) && defined(CONFIG_ENERGY_MODEL) +#ifndef CONFIG_CIX_THERMAL static DEFINE_PER_CPU(unsigned int, efficiency_class); static void cppc_cpufreq_register_em(struct cpufreq_policy *policy); @@ -561,6 +560,71 @@ static void cppc_cpufreq_register_em(struct cpufreq_policy *policy) get_perf_level_count(policy), &em_cb, cpu_data->shared_cpu_map, 0); } +#else +static unsigned int get_perf_level_count(struct cpufreq_policy *policy) +{ + struct cppc_cpudata *cpu_data; + int cpu = policy->cpu; + + cpu_data = policy->driver_data; + if (cpu_data == NULL) { + pr_warn("No CPU data for CPU%d\n", cpu); + return 0; + } + return cpu_data->opp_level_num; +} + +static int cix_cppc_get_cpu_power(struct device *cpu_dev, + unsigned long *power, unsigned long *KHz) +{ + u32 level_num; + struct cpufreq_policy *policy; + struct cppc_perf_caps *perf_caps; + struct cppc_cpudata *cpu_data; + struct cppc_opp *opp; + + policy = cpufreq_cpu_get(cpu_dev->id); + if (!policy) + return -EINVAL; + + cpu_data = policy->driver_data; + perf_caps = &cpu_data->perf_caps; + + opp = cpu_data->opp; + level_num = cpu_data->opp_level_num; + + for (int i = 0; i < level_num; i++) { + if (*KHz > opp[i].freq) + continue; + + *KHz = opp[i].freq; + *power = opp[i].power; + pr_debug("cix_cppc_get_cpu_power: cpu:%d, level:%d, KHz:%lu, power:%lu\n", + cpu_dev->id, i, *KHz, *power); + break; + } + + return 0; +} + +static void cix_cppc_cpufreq_register_em(struct cpufreq_policy *policy) +{ + struct cppc_cpudata *cpu_data; + struct em_data_callback em_cb = EM_DATA_CB(cix_cppc_get_cpu_power); + + cpu_data = policy->driver_data; + em_dev_register_perf_domain(get_cpu_device(policy->cpu), + get_perf_level_count(policy), &em_cb, + cpu_data->shared_cpu_map, 0); +} + +static int populate_efficiency_class(void) +{ + cppc_cpufreq_driver.register_em = cix_cppc_cpufreq_register_em; + + return 0; +} +#endif #else static int populate_efficiency_class(void) @@ -615,6 +679,87 @@ static void cppc_cpufreq_put_cpu_data(struct cpufreq_policy *policy) policy->driver_data = NULL; } +static int cppc_opp_init(struct cpufreq_policy *policy) +{ + struct acpi_object_list input; + union acpi_object params[2]; + struct acpi_buffer buffer = { ACPI_ALLOCATE_BUFFER, NULL }; + acpi_status status; + struct cppc_perf_caps *perf_caps; + struct cppc_cpudata *cpu_data; + struct device *cpu_dev; + acpi_handle handle; + union acpi_object *package; + u32 level_index = 0; + u32 *data; + + pr_debug("cppc_opp_init: Initializing OPPs for CPU:%d\n", policy->cpu); + cpu_data = policy->driver_data; + if (!cpu_data) { + pr_warn("No CPU data for CPU%d\n", policy->cpu); + cpufreq_cpu_put(policy); + return -ENODEV; + } + + perf_caps = &cpu_data->perf_caps; + + params[0].type = ACPI_TYPE_INTEGER; + params[0].integer.value = cpu_data->perf_domain; + params[1].type = ACPI_TYPE_INTEGER; + params[1].integer.value = level_index; + + input.count = 2; + input.pointer = params; + + cpu_dev = get_cpu_device(policy->cpu); + handle = ACPI_HANDLE(cpu_dev); + if (!handle) { + pr_err("No ACPI handle for CPU:%d\n", cpu_dev->id); + return -EINVAL; + } + + status = acpi_evaluate_object(handle, "\\_SB.PMMX.PEFG", &input, &buffer); + if (ACPI_FAILURE(status)) { + pr_err("Failed to call _PEFG: %s\n", acpi_format_exception(status)); + goto OUT; + } + + package = buffer.pointer; + if (!package || package->type != ACPI_TYPE_BUFFER) { + pr_err("cppc_opp_init: cpu:%d, no buffer returned\n", + cpu_dev->id); + goto OUT; + } + + data = (u32 *)package->buffer.pointer; + + cpu_data->opp_level_num = data[1] & 0xfff; + if (cpu_data->opp_level_num == 0) { + pr_warn("cppc_opp_init: cpu:%d, no performance levels found\n", + cpu_dev->id); + goto OUT; + } + if (cpu_data->opp_level_num > MAX_OPP_LEVELS) { + pr_warn("cppc_opp_init: cpu:%d, too many performance levels: %d\n", + cpu_dev->id, cpu_data->opp_level_num); + goto OUT; + } + for (int i = 0; i < cpu_data->opp_level_num; i++) { + cpu_data->opp[i].perf = data[2 + i * 3]; + cpu_data->opp[i].power = data[3 + i * 3]; + cpu_data->opp[i].freq = cppc_perf_to_khz(perf_caps, + cpu_data->opp[i].perf); + pr_debug("cppc_opp_init: cpu:%d, level:%d, perf:%u, freq:%u\n", + cpu_dev->id, i, cpu_data->opp[i].perf, cpu_data->opp[i].freq); + } + +OUT: + /* Free the buffer allocated by acpi_evaluate_object */ + if (buffer.pointer) + kfree(buffer.pointer); + return 0; +} + static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) { unsigned int cpu = policy->cpu; @@ -690,6 +835,7 @@ static int cppc_cpufreq_cpu_init(struct cpufreq_policy *policy) } cppc_cpufreq_cpu_fie_init(policy); + cppc_opp_init(policy); return 0; out: @@ -703,6 +849,12 @@ static int cppc_cpufreq_cpu_exit(struct cpufreq_policy *policy) struct cppc_perf_caps *caps = &cpu_data->perf_caps; unsigned int cpu = policy->cpu; int ret; + struct device *dev; + struct acpi_device *device; + struct acpi_processor *pr = per_cpu(processors, cpu); + + dev = get_cpu_device(pr->id); + device = ACPI_COMPANION(dev); cppc_cpufreq_cpu_fie_exit(policy); @@ -714,6 +866,10 @@ static int cppc_cpufreq_cpu_exit(struct cpufreq_policy *policy) caps->lowest_perf, cpu, ret); cppc_cpufreq_put_cpu_data(policy); + +#ifdef CONFIG_ARM64 + acpi_processor_thermal_exit(pr, device); +#endif return 0; } @@ -749,6 +905,29 @@ static int cppc_perf_from_fbctrs(struct cppc_cpudata *cpu_data, return (reference_perf * delta_delivered) / delta_reference; } +#ifdef CONFIG_ARCH_CIX +/* + * On CIX platform, perf calculation is inaccurate from delivered performance + * counter and reference performance counter. We reuse the desired performance + * register to store the real performance calculated by the platform. + */ + static unsigned int cix_cppc_cpufreq_get_rate(unsigned int cpu) + { + struct cpufreq_policy *policy = cpufreq_cpu_get(cpu); + struct cppc_cpudata *cpu_data = policy->driver_data; + struct cppc_perf_caps *perf_caps = &cpu_data->perf_caps; + u64 desired_perf; + int ret; + + cpufreq_cpu_put(policy); + + ret = cppc_get_desired_perf(cpu, &desired_perf); + if (ret < 0) + return -EIO; + + return cppc_perf_to_khz(perf_caps, desired_perf); +} +#else static int cppc_get_perf_ctrs_sample(int cpu, struct cppc_perf_fb_ctrs *fb_ctrs_t0, struct cppc_perf_fb_ctrs *fb_ctrs_t1) @@ -808,6 +987,7 @@ out_invalid_counters: return cppc_perf_to_khz(&cpu_data->perf_caps, delivered_perf); } +#endif static int cppc_cpufreq_set_boost(struct cpufreq_policy *policy, int state) { @@ -847,10 +1027,14 @@ static struct freq_attr *cppc_cpufreq_attr[] = { }; static struct cpufreq_driver cppc_cpufreq_driver = { - .flags = CPUFREQ_CONST_LOOPS, + .flags = CPUFREQ_IS_COOLING_DEV | CPUFREQ_CONST_LOOPS, .verify = cppc_verify_policy, .target = cppc_cpufreq_set_target, +#ifdef CONFIG_ARCH_CIX + .get = cix_cppc_cpufreq_get_rate, +#else .get = cppc_cpufreq_get_rate, +#endif .fast_switch = cppc_cpufreq_fast_switch, .init = cppc_cpufreq_cpu_init, .exit = cppc_cpufreq_cpu_exit, diff --git a/drivers/cpufreq/scmi-cpufreq.c b/drivers/cpufreq/scmi-cpufreq.c index e4989764efe2..62538c681884 100644 --- a/drivers/cpufreq/scmi-cpufreq.c +++ b/drivers/cpufreq/scmi-cpufreq.c @@ -20,6 +20,7 @@ #include #include #include +#include struct scmi_data { int domain_id; @@ -31,6 +32,10 @@ struct scmi_data { static struct scmi_protocol_handle *ph; static const struct scmi_perf_proto_ops *perf_ops; +#ifdef CONFIG_DVFS_BOARD_CHECK +#define CIX_SIP_CPUFREQ_SUPPORT 0xc200000d +#endif + static unsigned int scmi_cpufreq_get_rate(unsigned int cpu) { struct cpufreq_policy *policy; @@ -298,6 +303,25 @@ static struct cpufreq_driver scmi_cpufreq_driver = { .exit = scmi_cpufreq_exit, .register_em = scmi_cpufreq_register_em, }; +#ifdef CONFIG_DVFS_BOARD_CHECK +static int check_cpufreq_support(void) +{ + struct arm_smccc_res res; + bool board_support; + + arm_smccc_smc(CIX_SIP_CPUFREQ_SUPPORT, 0, 0, 0, 0, 0, 0, 0, &res); + + if (res.a0) + board_support = false; + else + board_support = true; + + if (!board_support) + pr_info("This board not supports cpu dvfs"); + + return board_support; +} +#endif static int scmi_cpufreq_probe(struct scmi_device *sdev) { @@ -307,6 +331,15 @@ static int scmi_cpufreq_probe(struct scmi_device *sdev) handle = sdev->handle; + if (!dev->of_node) + return -ENODEV; + +#ifdef CONFIG_DVFS_BOARD_CHECK + ret = check_cpufreq_support(); + if (!ret) + return -EINVAL; +#endif + if (!handle) return -ENODEV; diff --git a/drivers/devfreq/Kconfig b/drivers/devfreq/Kconfig index 3c4862a752b5..f89b2ab4615a 100644 --- a/drivers/devfreq/Kconfig +++ b/drivers/devfreq/Kconfig @@ -150,6 +150,33 @@ config ARM_SUN8I_A33_MBUS_DEVFREQ This adds the DEVFREQ driver for the MBUS controller in some Allwinner sun8i (A33 through H3) and sun50i (A64 and H5) SoCs. +config ARM64_DSU_PCTRL_DEVFREQ + tristate "ARM DSU Cache Portion Control DEVFREQ Driver" + depends on ARM64 + select PM_OPP + help + This adds the DevFreq driver for energy-cost-justified demand-driven + portion control of the ARM DSU cache. + This driver does not control frequency. + + It uses architecture specific instructions which might cause + fault when some ARM64 platform does not support it. + Make sure this driver works with your ARM64 platform. + + If unsure, say N. + +config ARM_CIX_BUS_DEVFREQ + tristate "ARM Cix Generic Bus DEVFREQ Driver" + depends on ARCH_CIX || COMPILE_TEST + select DEVFREQ_GOV_SIMPLE_ONDEMAND + select DEVFREQ_GOV_USERSPACE + help + This adds the common DEVFREQ driver for Cix Memory bus. Cix bus has + one more group of bus (e.g, CI-700 and NI-700 block).Each bus group + could contain many memoby bus block.adjusts the operating frequencies + and voltages with OPP support. + This does not yet operate with optimal voltages. + source "drivers/devfreq/event/Kconfig" endif # PM_DEVFREQ diff --git a/drivers/devfreq/Makefile b/drivers/devfreq/Makefile index bf40d04928d0..44f9883234ce 100644 --- a/drivers/devfreq/Makefile +++ b/drivers/devfreq/Makefile @@ -15,6 +15,8 @@ obj-$(CONFIG_ARM_MEDIATEK_CCI_DEVFREQ) += mtk-cci-devfreq.o obj-$(CONFIG_ARM_RK3399_DMC_DEVFREQ) += rk3399_dmc.o obj-$(CONFIG_ARM_SUN8I_A33_MBUS_DEVFREQ) += sun8i-a33-mbus.o obj-$(CONFIG_ARM_TEGRA_DEVFREQ) += tegra30-devfreq.o +obj-$(CONFIG_ARM64_DSU_PCTRL_DEVFREQ) += dsu-pctrl-devfreq.o +obj-$(CONFIG_ARM_CIX_BUS_DEVFREQ) += cix-bus.o # DEVFREQ Event Drivers obj-$(CONFIG_PM_DEVFREQ_EVENT) += event/ diff --git a/drivers/devfreq/cix-bus.c b/drivers/devfreq/cix-bus.c new file mode 100644 index 000000000000..dbe02a203323 --- /dev/null +++ b/drivers/devfreq/cix-bus.c @@ -0,0 +1,281 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Generic Cix Bus frequency driver with DEVFREQ Framework + * + * Copyright 2024 Cix Technology Group Co., Ltd.All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define EVENT_ENABLE 1 +#define UP_THRESHOLD (80) +#define DOWN_THRESHOLD (20) +#define MS_PER_SEC (1000) +#define PERIOD_RATIO (10) + +struct cix_bus { + struct device *dev; + struct devfreq *devfreq; + struct devfreq_event_dev *edev; + struct devfreq_simple_ondemand_data ondemand_data; + struct mutex lock; + unsigned long curr_freq; +}; + +/* + * devfreq function for both simple-ondemand and passive governor + */ +static int cix_bus_target(struct device *dev, unsigned long *freq, u32 flags) +{ + struct cix_bus *bus = dev_get_drvdata(dev); + struct dev_pm_opp *new_opp; + int ret = 0; + + /* Get correct frequency for bus. */ + new_opp = devfreq_recommended_opp(dev, freq, flags); + if (IS_ERR(new_opp)) { + dev_err(dev, "failed to get recommended opp instance\n"); + return PTR_ERR(new_opp); + } + + dev_pm_opp_put(new_opp); + + /* Change voltage and frequency according to new OPP level */ + mutex_lock(&bus->lock); + ret = scmi_device_set_freq(dev, *freq); + if (!ret) + bus->curr_freq = *freq; + + mutex_unlock(&bus->lock); + + return ret; +} + +static int cix_bus_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) +{ + struct cix_bus *bus = dev_get_drvdata(dev); + struct devfreq_event_data edata; + int ret; + + stat->current_frequency = bus->curr_freq; + +#if EVENT_ENABLE + ret = devfreq_event_get_event(bus->edev, &edata); + if (ret < 0) { + dev_err(dev, "failed to get event from devfreq-event devices\n"); + stat->total_time = stat->busy_time = 0; + return ret; + } + + stat->busy_time = edata.load_count; + /* get normal bw */ + edata.total_count = bus->curr_freq * + bus->devfreq->profile->polling_ms / + (MS_PER_SEC * PERIOD_RATIO); + stat->total_time = edata.total_count; + + stat->busy_time = min(stat->busy_time, stat->total_time); + dev_dbg(dev, "Usage of devfreq-event : %lu/%lu\n", stat->busy_time, + stat->total_time); + +#endif + return ret; +} + +static int cix_bus_get_cur_freq(struct device *dev, unsigned long *freq) +{ + struct cix_bus *bus = dev_get_drvdata(dev); + + mutex_lock(&bus->lock); + *freq = scmi_device_get_freq(dev); + mutex_unlock(&bus->lock); + + return 0; +} + +static void cix_bus_exit(struct device *dev) +{ + struct cix_bus *bus = dev_get_drvdata(dev); + int ret; +#if EVENT_ENABLE + ret = devfreq_event_disable_edev(bus->edev); + if (ret < 0) + dev_warn(dev, "failed to disable the devfreq-event devices\n"); +#endif + dev_pm_opp_of_remove_table(dev); +} + +static struct devfreq_dev_profile cix_bus_devfreq_profile = { + .polling_ms = 50, + .target = cix_bus_target, + .get_dev_status = cix_bus_get_dev_status, + .get_cur_freq = cix_bus_get_cur_freq, + .exit = cix_bus_exit, +}; + +static int cix_bus_events_parse_of(struct device_node *np, + struct cix_bus *bus) +{ + struct device *dev = bus->dev; + int ret; +#if EVENT_ENABLE + bus->edev = devfreq_event_get_edev_by_phandle(dev, + "devfreq-events", 0); + if (IS_ERR(bus->edev)) { + ret = -EPROBE_DEFER; + return ret; + } + ret = devfreq_event_enable_edev(bus->edev); + if (ret < 0) { + dev_err(dev, "failed to enable devfreq-event devices\n"); + return ret; + } +#endif + return 0; +} + +static int cix_bus_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + const char *gov = DEVFREQ_GOV_USERSPACE; + struct cix_bus *bus; + int ret, nr_opp; + + bus = devm_kzalloc(&pdev->dev, sizeof(*bus), GFP_KERNEL); + if (!bus) + return -ENOMEM; + + mutex_init(&bus->lock); + bus->dev = &pdev->dev; + platform_set_drvdata(pdev, bus); + ret = cix_bus_events_parse_of(dev->of_node, bus); + if (ret < 0) + return ret; + + nr_opp = dev_pm_opp_get_opp_count(dev); + if (nr_opp <= 0) { + ret = scmi_device_opp_table_parse(dev); + if (ret) { + dev_warn(dev, "failed to add opps to the device\n"); + return ret; + } + }; + + bus->ondemand_data.upthreshold = UP_THRESHOLD; + bus->ondemand_data.downdifferential = DOWN_THRESHOLD; + bus->devfreq = devm_devfreq_add_device(dev, &cix_bus_devfreq_profile, + gov, &bus->ondemand_data); + if (IS_ERR(bus->devfreq)) { + dev_err(dev, "failed to add devfreq device\n"); + return PTR_ERR(bus->devfreq); + } + + /* Register opp_notifier to catch the change of OPP */ + ret = devm_devfreq_register_opp_notifier(dev, bus->devfreq); + if (ret < 0) { + dev_err(dev, "failed to register opp notifier\n"); + goto err; + } + return 0; + +err: + dev_pm_opp_of_remove_table(dev); + devfreq_event_disable_edev(bus->edev); + + return ret; +} + +static void cix_bus_shutdown(struct platform_device *pdev) +{ + struct cix_bus *bus = dev_get_drvdata(&pdev->dev); + int ret = 0; + + ret = devfreq_event_disable_edev(bus->edev); + if (ret < 0) { + dev_err(&pdev->dev, "failed to disable the devfreq-event devices\n"); + return; + } + + ret = devfreq_suspend_device(bus->devfreq); + if (ret < 0) { + dev_err(&pdev->dev, "failed to suspend the devfreq devices\n"); + return; + } + +} + +#ifdef CONFIG_PM_SLEEP +static int cix_bus_resume(struct device *dev) +{ + struct cix_bus *bus = dev_get_drvdata(dev); + int ret; + + ret = devfreq_event_enable_edev(bus->edev); + if (ret < 0) { + dev_err(dev, "failed to enable the devfreq-event devices\n"); + return ret; + } + + ret = devfreq_resume_device(bus->devfreq); + if (ret < 0) { + dev_err(dev, "failed to resume the devfreq devices\n"); + return ret; + } + return 0; +} + +static int cix_bus_suspend(struct device *dev) +{ + struct cix_bus *bus = dev_get_drvdata(dev); + int ret; + + ret = devfreq_event_disable_edev(bus->edev); + if (ret < 0) { + dev_err(dev, "failed to disable the devfreq-event devices\n"); + return ret; + } + + ret = devfreq_suspend_device(bus->devfreq); + if (ret < 0) { + dev_err(dev, "failed to suspend the devfreq devices\n"); + return ret; + } + return 0; +} +#endif + +static const struct dev_pm_ops cix_bus_pm = { + SET_SYSTEM_SLEEP_PM_OPS(cix_bus_suspend, cix_bus_resume) +}; + +static const struct of_device_id cix_bus_of_match[] = { + { .compatible = "cix,bus-ci700", }, + { .compatible = "cix,bus-ni700", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, cix_bus_of_match); + +static struct platform_driver cix_bus_platdrv = { + .probe = cix_bus_probe, + .shutdown = cix_bus_shutdown, + .driver = { + .name = "cix-bus", + .pm = &cix_bus_pm, + .of_match_table = of_match_ptr(cix_bus_of_match), + }, +}; +module_platform_driver(cix_bus_platdrv); + +MODULE_DESCRIPTION("Generic Cix Bus frequency driver"); +MODULE_AUTHOR("Cixtech,Inc."); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/devfreq/dsu-pctrl-devfreq.c b/drivers/devfreq/dsu-pctrl-devfreq.c new file mode 100644 index 000000000000..43d532a4cd2f --- /dev/null +++ b/drivers/devfreq/dsu-pctrl-devfreq.c @@ -0,0 +1,938 @@ +/* + * A devfreq driver for ARM DynamIQ Shared Unit (DSU) CPU memory power + * managemnt. + * + * Copyright (c) 2015-2017 ARM Ltd. + * + * This program is free software; you can redistribute it and/or modify it + * under the terms and conditions of the GNU General Public License, + * version 2, as published by the Free Software Foundation. + * + * This program is distributed in the hope it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + * + * Authors: + * Sean McGoogan + * Lukasz Luba + * Ionela Voinescu + * David Guillen Fandos, ARM Ltd. + * + * The cache in DSU supports partial power down by splitting the cache into an + * implementation-specific number of portions. This driver provides an + * energy-cost justified demand-driven policy for controlling the number of + * portions enabled. + * + * The policy maps the number of portions enabled to frequency (1 portion == + * 1Hz) and provides total/busy time statistics such that + * busy_time = (total_time * hit_count) / access_count. + * + * This also provides a specific DevFreq governor that will implement the + * desired energy-cost-justification policy as this version is not suitable + * for use with the simple_ondemand governor. + * DevFreq min/max/governor controls work as usual. + * + * + * There is no relation to actual frequency control of the cache device. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "governor.h" + +#define CREATE_TRACE_POINTS +#include + +#include + +#define DSU_PCTRL_PLATFORM_DEVICE_NAME "dsu_pctrl" +#define DSU_PCTRL_GOVERNOR_NAME "dsu_pc_governor" + +#define DSU_PCTRL_DEFAULT_POLLING_MS 10 +#define POLLING_DOWN_INTERVAL 10 +/* Required polling time in miliseconds */ +#define DSU_PCTRL_DEFAULT_REQUIRED_GOV_POLLING 10000 + +/* Default cache line size */ +#define DSU_PCTRL_DEFAULT_LINE_SIZE 64 + +/* Default size of the cache: 1MB */ +#define DSU_PCTRL_DEFAULT_SIZE_KB (8 * 1024) + +/* Default static energy leaked by the cache per MB */ +#define DSU_PCTRL_DEFAULT_CACHE_LEAKAGE 10000 + +#define CIX_SIP_DSU_HW_CTL 0xc2000003 +#define CIX_SIP_DSU_SET_PD 0xc2000004 +#define CIX_SIP_DSU_GET_PD 0xc2000005 +#define CIX_SIP_DSU_SET_TH 0xc2000006 +#define CIX_SIP_DSU_GET_HITCNT 0xc2000007 +#define CIX_SIP_DSU_GET_MISSCNT 0xc2000008 + +/* Default size of the cache: 1MB */ +#define CIX_L3_SIZE 8 +#define CIX_DSU_T 8 +#define CIX_DSU_L (CIX_L3_SIZE * dsu->static_leakage_per_mb) +#define CIX_DSU_D (dsu->dram_energy_per_mb) + +#define CLUSTER_L3_DN_TH0_DEFAULT (12288 * CIX_DSU_T * CIX_DSU_L / CIX_DSU_D / 1000) +#define CLUSTER_L3_DN_TH1_DEFAULT (4096 * CIX_DSU_T * CIX_DSU_L / CIX_DSU_D / 1000) +#define CLUSTER_L3_UP_TH0_DEFAULT (4096 * CIX_DSU_T * CIX_DSU_L / CIX_DSU_D / 1000) +#define CLUSTER_L3_UP_TH1_DEFAULT (4096 * CIX_DSU_T * CIX_DSU_L / CIX_DSU_D / 1000) +#define CLUSTER_L3_UP_TH2_DEFAULT (24576 * CIX_DSU_T * CIX_DSU_L / CIX_DSU_D / 1000) + +/* + * Amount of energy used by the DRAM system per MB + * of transferred data (on average) expressed in uJ/MB + */ +#define DSU_PCTRL_DEFAULT_DRAM_ENERGY_PER_MB 130 + +#define SZ_1KB (1ULL << 10) +#define SZ_1MB (1ULL << 20) +#define ROUNDING_INTEGER_MUL SZ_1MB +#define PERCENT_MAX 100 + +/* + * Portion threshold to use for down-sizing (Td) + * between 0 and 100 + * 90 for 90% + */ +#define DOWNSIZE_PORTION_THRESHOLD 90 + +/* + * Portion threshold to use for up-sizing (Tu) + * between 0 and 100 + * 90 for 90% + */ +#define UPSIZE_PORTION_THRESHOLD 90 + +/* Bit-field positions for the CLUSTERPWRCTLR_EL1 register */ +#define PORTION_1 4 +#define PORTION_2 5 +#define PORTION_3 6 +#define PORTION_4 7 +/* Bit-masks for the CLUSTERPWRCTLR_EL1 register */ +#define PORTION_BITS ((1UL << PORTION_1) | \ + (1UL << PORTION_2) | \ + (1UL << PORTION_3) | \ + (1UL << PORTION_4)) +#define PORTION_MASK (~(PORTION_BITS)) + +#if defined(CONFIG_ARM64) +/* + * Read the system register 'sysreg' (using MRS), and then + * explicitly clear it, by writing zero to it (using MSR). + * Put the value read into 'result'. + */ +#define SYS_REG_READ_THEN_CLEAR(sysreg, result) \ +do { \ + __asm__ __volatile__( \ + "mrs %0, " #sysreg "\n\t" \ + "msr " #sysreg ", XZR" \ + : "=r" (result) /* only one output */ \ + /* no inputs */ \ + /* no clobbers */ \ + ); \ +} while (0) + +/* + * Read the system register 'sysreg' (using MRS). + * Put the value read into 'result'. + */ +#define SYS_REG_READ(sysreg, result) \ +do { \ + __asm__ __volatile__( \ + "mrs %0, " #sysreg \ + : "=r" (result) /* only one output */ \ + /* no inputs */ \ + /* no clobbers */ \ + ); \ +} while (0) + +/* + * Write 'value' to the system register 'sysreg' (using MSR). + */ +#define SYS_REG_WRITE(sysreg, value) \ +do { \ + __asm__ __volatile__( \ + "msr " #sysreg ", %0" \ + : /* no outputs */ \ + : "r" (value) /* only one input */ \ + /* no clobbers */ \ + ); \ +} while (0) + +#else + +#define SYS_REG_READ_THEN_CLEAR(sysreg, result) do {} while (0) +#define SYS_REG_READ(sysreg, result) do {} while (0) +#define SYS_REG_READ_THEN_CLEAR(sysreg, result) do {} while (0) +#define SYS_REG_WRITE(sysreg, result) do {} while (0) + +#endif + +enum arm_dsu_version { + ARM_DSU_R0 = 0, +}; + +struct dsu_pctrl_data { + u32 portion_min; + u32 portion_max; +}; + +struct dsu_pctrl { + int id; + struct dsu_pctrl_data *dsu_data; + struct devfreq *devfreq; + struct platform_device *pdev; + struct devfreq_dev_profile *devfreq_profile; + u32 portions; + u32 size; + u32 line_size; + u32 up_polling_ms; + u32 down_polling_ms; + u32 initial_freq; + u32 static_leakage_per_mb; + u32 dram_energy_per_mb; + + unsigned long *freq_table; + int freq_table_len; + + struct workqueue_struct *update_wq; + struct work_struct update_handle; + struct mutex lock; + struct hrtimer poll_timer; + + /* Leakage (static power) for a single portion (in uW) */ + unsigned long static_leakage; + unsigned long downsize_threshold; + unsigned long upsize_threshold; + unsigned long max_threshold; + unsigned long cur_num_portions; + + bool hw_control; + unsigned int cluster_l3_dn_th0; + unsigned int cluster_l3_dn_th1; + unsigned int cluster_l3_up_th0; + unsigned int cluster_l3_up_th1; + unsigned int cluster_l3_up_th2; + unsigned int cluster_l3_auto_interval; + + /* Contains state for the algorithm. It is clean during resume */ + struct { + unsigned long accesses_up; + unsigned long misses_up; + unsigned long accesses_down; + unsigned long misses_down; + unsigned long usec_up; + unsigned long usec_down; + unsigned int last_update; + } alg; +}; + +static atomic_t dsu_pctrl_device_id = ATOMIC_INIT(0); + +static const struct dsu_pctrl_data device_data[] = { + {.portion_min = 1, .portion_max = 3}, +}; + +static const struct of_device_id dsu_pctrl_devfreq_id[] = { + {.compatible = "arm,dsu_pctrl_r0", .data = + (void *)&device_data[ARM_DSU_R0]}, + {} +}; + +static int dsu_pctrl_set_active_portions(struct device *dev, + unsigned long portions) +{ + struct dsu_pctrl *dsu = dev_get_drvdata(dev); + struct dsu_pctrl_data *data = dsu->dsu_data; + unsigned long portion_active; + unsigned long portion_control; + struct arm_smccc_res res; + + if (portions < data->portion_min || portions > data->portion_max) { + dev_warn(dev, "%s: Target of %lu-portions is " + "outside range of %u..%u\n", __func__, portions, + data->portion_min, data->portion_max); + + return -EINVAL; + } + + /* + * Set the number of portions in the DSU to portions + * + * portions Set of bit-fields to Enable + * --------- --------------------------- + * 4 PORTION_1|PORTION_2|PORTION_3|PORTION_4 + * 3 PORTION_1|PORTION_2|PORTION_3 + * 2 PORTION_1|PORTION_2 + * 1 PORTION_1 + * 0 + */ + portion_active = ((1UL << portions) - 1) << PORTION_1; + + arm_smccc_smc(CIX_SIP_DSU_GET_PD, 0, 0, 0, 0, 0, 0, 0, &res); + if (res.a0) + portion_control = res.a0; + + portion_control &= PORTION_MASK; + portion_control |= portion_active; + + arm_smccc_smc(CIX_SIP_DSU_SET_PD, portion_control, 0, 0, 0, 0, 0, 0, &res); + + /* Update current number of portions */ + dsu->cur_num_portions = portions; + + return 0; +} + +static int dsu_pctrl_devfreq_target(struct device *dev, + unsigned long *portions, u32 flags) +{ + /* Set requested portions */ + return dsu_pctrl_set_active_portions(dev, *portions); +} + +static int dsu_pctrl_devfreq_get_dev_status(struct device *dev, + struct devfreq_dev_status *stat) +{ + struct dsu_pctrl *dsu = dev_get_drvdata(dev); + unsigned int const usec = ktime_to_us(ktime_get()); + unsigned int delta; + unsigned long hits = 0; + unsigned long misses = 0; + unsigned long accesses; + struct arm_smccc_res res; + + delta = usec - dsu->alg.last_update; + dsu->alg.last_update = usec; + + stat->current_frequency = dsu->cur_num_portions; + + arm_smccc_smc(CIX_SIP_DSU_GET_HITCNT, 0, 0, 0, 0, 0, 0, 0, &res); + if (res.a0) + hits = res.a0; + + arm_smccc_smc(CIX_SIP_DSU_GET_MISSCNT, 0, 0, 0, 0, 0, 0, 0, &res); + if (res.a0) + misses = res.a0; + + accesses = hits + misses; + + dsu->alg.accesses_up += accesses; + dsu->alg.accesses_down += accesses; + dsu->alg.misses_up += misses; + dsu->alg.misses_down += misses; + dsu->alg.usec_up += delta; + dsu->alg.usec_down += delta; + + if (!accesses) + accesses = 1; + + /* + * Although this is not yet suitable for use with the simple ondemand + * governor we'll fill these usage statistics. + */ + stat->total_time = delta; + stat->busy_time = stat->total_time * hits / accesses; + + trace_dsu_pctrl_dev_status(dsu->id, hits, misses, + dsu->cur_num_portions, stat->busy_time, + stat->total_time); + + return 0; +} + +static int dsu_pctrl_up_size_check(struct dsu_pctrl *dsu) +{ + struct dsu_pctrl_data *data = dsu->dsu_data; + unsigned long cache_miss_bw; + int ret = 0; + + /* + * If we are at the maximum number of active portions and we know + * there won't be a downsize attempt due to polling time constraints, + * we can skip calculations that won't lead to any action. + */ + if ((dsu->cur_num_portions >= data->portion_max) && + (dsu->alg.usec_down < dsu->down_polling_ms)) + goto cleanup; + + cache_miss_bw = dsu->line_size * dsu->alg.misses_up; + cache_miss_bw *= ROUNDING_INTEGER_MUL; + cache_miss_bw /= dsu->alg.usec_up; + + if (cache_miss_bw > dsu->upsize_threshold) + ret = 1; + +cleanup: + dsu->alg.usec_up = 0; + dsu->alg.misses_up = 0; + dsu->alg.accesses_up = 0; + + return ret; +} + +static int dsu_pctrl_down_size_check(struct dsu_pctrl *dsu) +{ + struct dsu_pctrl_data *data = dsu->dsu_data; + unsigned long cache_hit_bw; + int ret = 0; + + if (dsu->cur_num_portions <= data->portion_min) + goto cleanup; + + cache_hit_bw = dsu->alg.accesses_down - dsu->alg.misses_down; + cache_hit_bw *= dsu->line_size; + cache_hit_bw *= ROUNDING_INTEGER_MUL; + cache_hit_bw /= dsu->alg.usec_down; + + if (cache_hit_bw < (dsu->max_threshold * dsu->cur_num_portions - + dsu->downsize_threshold)) + ret = 1; + +cleanup: + dsu->alg.usec_down = 0; + dsu->alg.misses_down = 0; + dsu->alg.accesses_down = 0; + + return ret; +} + +static unsigned long dsu_pctrl_calc_next_portions(struct dsu_pctrl *dsu) +{ + unsigned long portions = dsu->cur_num_portions; + int up = 0, down = 0; + + up = dsu_pctrl_up_size_check(dsu); + if (up > 0) + return dsu->cur_num_portions + up; + + if (dsu->alg.usec_down >= dsu->down_polling_ms) { + down = dsu_pctrl_down_size_check(dsu); + if (down > 0) + portions = dsu->cur_num_portions - down; + } + + return portions; +} + +static int dsu_pctrl_governor_get_target_portions(struct devfreq *df, + unsigned long *portions) +{ + struct dsu_pctrl *dsu = dev_get_drvdata(df->dev.parent); + int err; + + err = devfreq_update_stats(df); + if (err) + return err; + + *portions = dsu_pctrl_calc_next_portions(dsu); + + return 0; +} + +static int dsu_pctrl_governor_event_handler(struct devfreq *devfreq, + unsigned int event, void *data) +{ + int ret = 0; + + switch (event) { + case DEVFREQ_GOV_START: + devfreq_monitor_start(devfreq); + break; + + case DEVFREQ_GOV_STOP: + devfreq_monitor_stop(devfreq); + break; + + case DEVFREQ_GOV_SUSPEND: + devfreq_monitor_suspend(devfreq); + break; + + case DEVFREQ_GOV_RESUME: + devfreq_monitor_resume(devfreq); + break; + } + + return ret; +} + +static struct devfreq_governor dsu_pctrl_devfreq_governor = { + .name = DSU_PCTRL_GOVERNOR_NAME, + .get_target_freq = dsu_pctrl_governor_get_target_portions, + .event_handler = dsu_pctrl_governor_event_handler, + .flags = DEVFREQ_GOV_FLAG_IMMUTABLE | DEVFREQ_GOV_FLAG_IRQ_DRIVEN, +}; + +static void dsu_pctrl_handle_update(struct work_struct *work) +{ + struct dsu_pctrl *dsu = container_of(work, struct dsu_pctrl, + update_handle); + + mutex_lock(&dsu->devfreq->lock); + update_devfreq(dsu->devfreq); + mutex_unlock(&dsu->devfreq->lock); +} + +static enum hrtimer_restart dsu_pctrl_polling(struct hrtimer *hrtimer) +{ + struct dsu_pctrl *dsu = container_of(hrtimer, struct dsu_pctrl, + poll_timer); + + queue_work(dsu->update_wq, &dsu->update_handle); + + hrtimer_forward_now(&dsu->poll_timer, + ms_to_ktime(dsu->up_polling_ms)); + return HRTIMER_RESTART; +} + +static int dsu_pctrl_reinit_device(struct device *dev) +{ + struct dsu_pctrl *dsu = dev_get_drvdata(dev); + + /* Clean the algorithm statistics and start from scrach */ + memset(&dsu->alg, 0, sizeof(dsu->alg)); + dsu->alg.last_update = ktime_to_us(ktime_get()); + + return dsu_pctrl_set_active_portions(dev, dsu->initial_freq); +} + +static int dsu_pctrl_setup_devfreq_profile(struct platform_device *pdev) +{ + struct dsu_pctrl *dsu = platform_get_drvdata(pdev); + struct devfreq_dev_profile *df_profile; + + dsu->devfreq_profile = devm_kzalloc(&pdev->dev, + sizeof(struct devfreq_dev_profile), GFP_KERNEL); + if (IS_ERR(dsu->devfreq_profile)) { + dev_dbg(&pdev->dev, "no memory.\n"); + return PTR_ERR(dsu->devfreq_profile); + } + + df_profile = dsu->devfreq_profile; + + df_profile->target = dsu_pctrl_devfreq_target; + df_profile->get_dev_status = dsu_pctrl_devfreq_get_dev_status; + df_profile->freq_table = dsu->freq_table; + df_profile->max_state = dsu->freq_table_len; + df_profile->polling_ms = DSU_PCTRL_DEFAULT_REQUIRED_GOV_POLLING; + df_profile->initial_freq = dsu->initial_freq; + + return 0; +} + +static int dsu_pctrl_parse_dt(struct platform_device *pdev) +{ + const struct of_device_id *of_id; + struct device_node *node = pdev->dev.of_node; + struct dsu_pctrl *dsu = platform_get_drvdata(pdev); + int ret = 0; + + of_node_get(node); + + of_id = of_match_node(dsu_pctrl_devfreq_id, node); + dsu->dsu_data = (struct dsu_pctrl_data *)of_id->data; + + ret = of_property_read_u32(node, "static-leakage-per-mb", + &dsu->static_leakage_per_mb); + if (ret) + dsu->static_leakage_per_mb = DSU_PCTRL_DEFAULT_CACHE_LEAKAGE; + + ret = of_property_read_u32(node, "dram-energy-per-mb", + &dsu->dram_energy_per_mb); + if (ret) + dsu->dram_energy_per_mb = DSU_PCTRL_DEFAULT_DRAM_ENERGY_PER_MB; + + ret = of_property_read_u32(node, "size", &dsu->size); + if (ret) + dsu->size = DSU_PCTRL_DEFAULT_SIZE_KB; + + ret = of_property_read_u32(node, "line-size", &dsu->line_size); + if (ret) + dsu->line_size = DSU_PCTRL_DEFAULT_LINE_SIZE; + + ret = of_property_read_u32(node, "polling", &dsu->up_polling_ms); + if (ret) + dsu->up_polling_ms = DSU_PCTRL_DEFAULT_POLLING_MS; + dsu->down_polling_ms = POLLING_DOWN_INTERVAL * dsu->up_polling_ms; + + dsu->hw_control = of_property_read_bool(node, "hw-automatic-control"); + if (dsu->hw_control) { + ret = of_property_read_u32(node, "cluster-l3-dn-th0", + &dsu->cluster_l3_dn_th0); + if (ret) + dsu->cluster_l3_dn_th0 = CLUSTER_L3_DN_TH0_DEFAULT; + + ret = of_property_read_u32(node, "cluster-l3-dn-th1", + &dsu->cluster_l3_dn_th1); + if (ret) + dsu->cluster_l3_dn_th1 = CLUSTER_L3_DN_TH1_DEFAULT; + + ret = of_property_read_u32(node, "cluster-l3-up-th0", + &dsu->cluster_l3_up_th0); + if (ret) + dsu->cluster_l3_up_th0 = CLUSTER_L3_UP_TH0_DEFAULT; + + ret = of_property_read_u32(node, "cluster-l3-up-th1", + &dsu->cluster_l3_up_th1); + if (ret) + dsu->cluster_l3_up_th1 = CLUSTER_L3_UP_TH1_DEFAULT; + + ret = of_property_read_u32(node, "cluster-l3-up-th2", + &dsu->cluster_l3_up_th2); + if (ret) + dsu->cluster_l3_up_th2 = CLUSTER_L3_UP_TH2_DEFAULT; + + ret = of_property_read_u32(node, "cluster-l3-auto-interval", + &dsu->cluster_l3_auto_interval); + if (ret) + dsu->cluster_l3_auto_interval = CIX_DSU_T; + } + + of_node_put(node); + + return 0; +} + +static int dsu_pctrl_create_configuration(struct platform_device *pdev) +{ + struct dsu_pctrl *dsu = platform_get_drvdata(pdev); + struct dsu_pctrl_data *data = dsu->dsu_data; + int i; + unsigned long portion; + + dsu->initial_freq = data->portion_max; + dsu->cur_num_portions = dsu->initial_freq; + + dsu->freq_table_len = data->portion_max - data->portion_min + 1; + dsu->freq_table = devm_kcalloc(&pdev->dev, dsu->freq_table_len, + sizeof(*dsu->freq_table), + GFP_KERNEL); + if (IS_ERR(dsu->freq_table)) + return -ENOMEM; + + portion = data->portion_min; + for (i = 0; portion <= data->portion_max; i++) + dsu->freq_table[i] = portion++; + + /* Leakage (static power) for a single portion (in uW) */ + dsu->static_leakage = dsu->static_leakage_per_mb * dsu->size; + dsu->static_leakage /= SZ_1KB; + dsu->static_leakage /= data->portion_max; + + /* Downsize and upsize thresholds are given in percentages */ + dsu->downsize_threshold = DOWNSIZE_PORTION_THRESHOLD; + dsu->downsize_threshold *= ROUNDING_INTEGER_MUL / PERCENT_MAX; + dsu->downsize_threshold *= dsu->static_leakage; + dsu->downsize_threshold /= dsu->dram_energy_per_mb; + + dsu->upsize_threshold = PERCENT_MAX - UPSIZE_PORTION_THRESHOLD; + dsu->upsize_threshold *= ROUNDING_INTEGER_MUL / PERCENT_MAX; + dsu->upsize_threshold *= dsu->static_leakage; + dsu->upsize_threshold /= dsu->dram_energy_per_mb; + + dsu->max_threshold = ROUNDING_INTEGER_MUL; + dsu->max_threshold *= dsu->static_leakage; + dsu->max_threshold /= dsu->dram_energy_per_mb; + + return 0; +} + +static void dsu_pctrl_remove_opps(struct platform_device *pdev) +{ + struct dev_pm_opp *opp; + int i, count; + unsigned long freq; + + count = dev_pm_opp_get_opp_count(&pdev->dev); + if (count <= 0) + return; + + rcu_read_lock(); + for (i = 0, freq = 0; i < count; i++, freq++) { + opp = dev_pm_opp_find_freq_ceil(&pdev->dev, &freq); + if (!IS_ERR(opp)) + dev_pm_opp_remove(&pdev->dev, freq); + } + rcu_read_unlock(); +} + +static int dsu_pctrl_enable_opps(struct platform_device *pdev) +{ + struct dsu_pctrl *dsu = platform_get_drvdata(pdev); + int i, ret; + int opp_count = 0; + + if (dsu->freq_table_len <= 0) + return -EINVAL; + + for (i = 0; i < dsu->freq_table_len; i++) { + ret = dev_pm_opp_add(&pdev->dev, dsu->freq_table[i], + dsu->freq_table[i]); + if (ret) + dev_warn(&pdev->dev, "cannot add a new OPP.\n"); + else + opp_count++; + } + + if (opp_count == 0) { + dev_err(&pdev->dev, "device has no OPP registered.\n"); + return -ENODEV; + } + + return 0; +} + +static int dsu_pctrl_setup(struct platform_device *pdev) +{ + struct dsu_pctrl *dsu = platform_get_drvdata(pdev); + struct dsu_pctrl_data *data = dsu->dsu_data; + int ret = 0; + + dsu->update_wq = create_workqueue("arm_dsu_pctrl_wq"); + if (IS_ERR(dsu->update_wq)) { + dev_err(&pdev->dev, "cannot create workqueue.\n"); + return PTR_ERR(dsu->update_wq); + } + INIT_WORK(&dsu->update_handle, dsu_pctrl_handle_update); + + mutex_init(&dsu->lock); + + ret = dsu_pctrl_create_configuration(pdev); + if (ret) { + dev_err(&pdev->dev, "cannot create frequency table.\n"); + return ret; + } + + ret = dsu_pctrl_enable_opps(pdev); + if (ret) { + dev_dbg(&pdev->dev, "device setup failed.\n"); + return ret; + } + + ret = dsu_pctrl_setup_devfreq_profile(pdev); + if (ret) { + dev_dbg(&pdev->dev, "device setup failed.\n"); + return ret; + } + + dsu->alg.last_update = ktime_to_us(ktime_get()); + + dsu->devfreq = devm_devfreq_add_device(&pdev->dev, + dsu->devfreq_profile, + DSU_PCTRL_GOVERNOR_NAME, NULL); + + if (IS_ERR(dsu->devfreq)) { + dev_err(&pdev->dev, "registering to devfreq failed.\n"); + return PTR_ERR(dsu->devfreq); + } + + mutex_lock(&dsu->devfreq->lock); + dsu->devfreq->scaling_min_freq = data->portion_min; + dsu->devfreq->scaling_max_freq = data->portion_max; + mutex_unlock(&dsu->devfreq->lock); + + return 0; +} + + +static int dsu_pctrl_init_device(struct platform_device *pdev) +{ + struct dsu_pctrl *dsu = platform_get_drvdata(pdev); + + dsu_pctrl_reinit_device(&pdev->dev); + + hrtimer_init(&dsu->poll_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); + dsu->poll_timer.function = dsu_pctrl_polling; + hrtimer_start(&dsu->poll_timer, ms_to_ktime(dsu->up_polling_ms), + HRTIMER_MODE_REL); + + return 0; +} + +static int dsu_pctrl_suspend(struct device *dev) +{ + struct dsu_pctrl *dsu = dev_get_drvdata(dev); + struct dsu_pctrl_data *data = dsu->dsu_data; + int ret = 0; + + if (dsu->hw_control) + return 0; + + if (hrtimer_active(&dsu->poll_timer)) + hrtimer_cancel(&dsu->poll_timer); + + ret = devfreq_suspend_device(dsu->devfreq); + if (ret < 0) { + dev_err(dev, "failed to suspend devfreq device.\n"); + return ret; + } + + /* Set the number of active portions to minimum during suspend */ + ret = dsu_pctrl_set_active_portions(dev, data->portion_min); + if (ret < 0) { + dev_err(dev, "failed to set portions to minimum.\n"); + return ret; + } + + return ret; +} + +static int dsu_pctrl_resume(struct device *dev) +{ + + struct dsu_pctrl *dsu = dev_get_drvdata(dev); + int ret = 0; + + if (dsu->hw_control) + return 0; + + dsu_pctrl_reinit_device(dev); + + ret = devfreq_resume_device(dsu->devfreq); + if (ret < 0) + dev_err(dev, "failed to resume devfreq device.\n"); + + if (!hrtimer_active(&dsu->poll_timer)) + hrtimer_start(&dsu->poll_timer, ms_to_ktime(dsu->up_polling_ms), + HRTIMER_MODE_REL); + + return ret; +} + +static SIMPLE_DEV_PM_OPS(dsu_pctrl_pm, dsu_pctrl_suspend, dsu_pctrl_resume); + +static int dsu_pctrl_devfreq_probe(struct platform_device *pdev) +{ + struct dsu_pctrl *dsu; + int ret = 0; + struct arm_smccc_res res; + + dev_info(&pdev->dev, "registering DSU portion control device.\n"); + + dsu = devm_kzalloc(&pdev->dev, sizeof(*dsu), GFP_KERNEL); + if (!dsu) + return -ENOMEM; + + platform_set_drvdata(pdev, dsu); + dsu->pdev = pdev; + dsu->id = atomic_inc_return(&dsu_pctrl_device_id); + + ret = dsu_pctrl_parse_dt(pdev); + if (ret) + goto failed; + + if (dsu->hw_control) { + arm_smccc_smc(CIX_SIP_DSU_SET_TH, dsu->cluster_l3_dn_th0, + dsu->cluster_l3_dn_th1, dsu->cluster_l3_up_th0, + dsu->cluster_l3_up_th1, dsu->cluster_l3_up_th2, + 0, 0, &res); + if (!res.a0) { + arm_smccc_smc(CIX_SIP_DSU_HW_CTL, + dsu->cluster_l3_auto_interval, 0, 0, 0, 0, + 0, 0, &res); + if (!res.a0) + return 0; + } + } + + ret = dsu_pctrl_setup(pdev); + if (ret) + goto failed; + + ret = dsu_pctrl_init_device(pdev); + if (ret) + goto failed; + + return 0; +failed: + dev_err(&pdev->dev, "failed to register driver, err %d.\n", ret); + kfree(dsu); + return ret; +} + +static int dsu_pctrl_devfreq_remove(struct platform_device *pdev) +{ + struct dsu_pctrl *dsu = platform_get_drvdata(pdev); + int ret = 0; + + dev_info(&pdev->dev, "unregistering DSU portion control device.\n"); + + ret = dsu_pctrl_set_active_portions(&pdev->dev, dsu->initial_freq); + + /* Cancel hrtimer */ + if (hrtimer_active(&dsu->poll_timer)) + hrtimer_cancel(&dsu->poll_timer); + /* Wait for pending work */ + flush_workqueue(dsu->update_wq); + /* Destroy workqueue */ + destroy_workqueue(dsu->update_wq); + + devm_devfreq_remove_device(&pdev->dev, dsu->devfreq); + dsu_pctrl_remove_opps(pdev); + + return ret; +} + +MODULE_DEVICE_TABLE(of, dsu_pctrl_devfreq_id); + +static struct platform_driver dsu_pctrl_devfreq_driver = { + .probe = dsu_pctrl_devfreq_probe, + .remove = dsu_pctrl_devfreq_remove, + .driver = { + .name = DSU_PCTRL_PLATFORM_DEVICE_NAME, + .of_match_table = dsu_pctrl_devfreq_id, + .pm = &dsu_pctrl_pm, + .owner = THIS_MODULE, + }, +}; + +static int __init dsu_pctrl_devfreq_init(void) +{ + int ret = 0; + + ret = devfreq_add_governor(&dsu_pctrl_devfreq_governor); + if (ret) { + pr_err("%s: failed to add governor: %d.\n", __func__, ret); + return ret; + } + + ret = platform_driver_register(&dsu_pctrl_devfreq_driver); + if (ret) + devfreq_remove_governor(&dsu_pctrl_devfreq_governor); + + return ret; +} + +static void __exit dsu_pctrl_devfreq_exit(void) +{ + int ret; + + ret = devfreq_remove_governor(&dsu_pctrl_devfreq_governor); + if (ret) + pr_err("%s: failed to remove governor: %d.\n", __func__, ret); + + platform_driver_unregister(&dsu_pctrl_devfreq_driver); +} + +module_init(dsu_pctrl_devfreq_init) +module_exit(dsu_pctrl_devfreq_exit) + +MODULE_LICENSE("GPL v2"); +MODULE_DESCRIPTION("ARM DSU PCTRL devfreq driver"); +MODULE_AUTHOR("ARM Ltd."); +MODULE_VERSION("1.0"); diff --git a/drivers/devfreq/event/Kconfig b/drivers/devfreq/event/Kconfig index 878825372f6f..8549b5079d21 100644 --- a/drivers/devfreq/event/Kconfig +++ b/drivers/devfreq/event/Kconfig @@ -39,4 +39,11 @@ config DEVFREQ_EVENT_ROCKCHIP_DFI This add the devfreq-event driver for Rockchip SoC. It provides DFI (DDR Monitor Module) driver to count ddr load. +config DEVFREQ_EVENT_CIX_PMU + tristate "CIX PMU DEVFREQ event Driver" + depends on ARCH_CIX || COMPILE_TEST + help + This add the devfreq-event driver for Cix SoC. It provides PMU + driver to count ci/ni-700 load. + endif # PM_DEVFREQ_EVENT diff --git a/drivers/devfreq/event/Makefile b/drivers/devfreq/event/Makefile index 3c847e5d5a35..8208bf6c5e24 100644 --- a/drivers/devfreq/event/Makefile +++ b/drivers/devfreq/event/Makefile @@ -4,3 +4,4 @@ obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_NOCP) += exynos-nocp.o obj-$(CONFIG_DEVFREQ_EVENT_EXYNOS_PPMU) += exynos-ppmu.o obj-$(CONFIG_DEVFREQ_EVENT_ROCKCHIP_DFI) += rockchip-dfi.o +obj-$(CONFIG_DEVFREQ_EVENT_CIX_PMU) += cix-pmu.o diff --git a/drivers/devfreq/event/cix-pmu.c b/drivers/devfreq/event/cix-pmu.c new file mode 100644 index 000000000000..f264545c9482 --- /dev/null +++ b/drivers/devfreq/event/cix-pmu.c @@ -0,0 +1,152 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Generic Cix Bus frequency driver with DEVFREQ Framework + * + * Copyright 2024 Cix Technology Group Co., Ltd.All Rights Reserved. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define PMU_EVENT_L_MASK 0xffffff +#define PMU_EVENT_H_SHIFT 24 + +enum REG_PMU { + REG_EVENT1_H, + REG_EVENT1_L, + REG_EVENT2_H, + REG_EVENT2_L, + REG_CNT, +}; + +struct cix_bus_usage { + u64 access; + u64 total; +}; + +struct cix_pmu { + struct devfreq_event_dev *edev; + struct devfreq_event_desc *desc; + struct cix_bus_usage usage; + struct device *dev; + void __iomem *regs[REG_CNT]; +}; + +static int cix_pmu_get_data(struct devfreq_event_dev *edev) +{ + struct cix_pmu *info = devfreq_event_get_drvdata(edev); + u64 pmu_event1_count_h, pmu_event1_count_l, pmu_event1_count; + u64 pmu_event2_count_h, pmu_event2_count_l, pmu_event2_count; + + pmu_event1_count_l = readl_relaxed(info->regs[REG_EVENT1_L]); + pmu_event1_count_h = readl_relaxed(info->regs[REG_EVENT1_H]); + pmu_event2_count_l = readl_relaxed(info->regs[REG_EVENT2_L]); + pmu_event2_count_h = readl_relaxed(info->regs[REG_EVENT2_H]); + + pmu_event1_count = (pmu_event1_count_h << PMU_EVENT_H_SHIFT) | + (pmu_event1_count_l & PMU_EVENT_L_MASK); + pmu_event2_count = (pmu_event2_count_h << PMU_EVENT_H_SHIFT) | + (pmu_event2_count_l & PMU_EVENT_L_MASK); + info->usage.access = pmu_event1_count + pmu_event2_count; + return 0; +} + +static int cix_pmu_disable(struct devfreq_event_dev *edev) +{ + return 0; +} + +static int cix_pmu_enable(struct devfreq_event_dev *edev) +{ + return 0; +} + +static int cix_pmu_set_event(struct devfreq_event_dev *edev) +{ + return 0; +} + +static int cix_pmu_get_event(struct devfreq_event_dev *edev, + struct devfreq_event_data *edata) +{ + struct cix_pmu *info = devfreq_event_get_drvdata(edev); + + cix_pmu_get_data(edev); + edata->load_count = info->usage.access; + edata->total_count = info->usage.total; + + return 0; +} + +static const struct devfreq_event_ops cix_pmu_ops = { + .disable = cix_pmu_disable, + .enable = cix_pmu_enable, + .get_event = cix_pmu_get_event, + .set_event = cix_pmu_set_event, +}; + +static const struct of_device_id cix_pmu_id_match[] = { + { .compatible = "cix,pmu" }, + { }, +}; +MODULE_DEVICE_TABLE(of, cix_pmu_id_match); + +static int cix_pmu_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cix_pmu *data; + struct devfreq_event_desc *desc; + int i; + + data = devm_kzalloc(dev, sizeof(struct cix_pmu), GFP_KERNEL); + if (!data) + return -ENOMEM; + + for ( i = 0; i < REG_CNT; i++) { + data->regs[i] = devm_platform_ioremap_resource(pdev, i); + if (IS_ERR(data->regs[i])) + return PTR_ERR(data->regs[i]); + } + + data->dev = dev; + + desc = devm_kzalloc(dev, sizeof(*desc), GFP_KERNEL); + if (!desc) + return -ENOMEM; + + desc->ops = &cix_pmu_ops; + desc->driver_data = data; + desc->name = "cix_pmu"; + data->desc = desc; + + data->edev = devm_devfreq_event_add_edev(&pdev->dev, desc); + if (IS_ERR(data->edev)) { + dev_err(&pdev->dev, + "failed to add devfreq-event device\n"); + return PTR_ERR(data->edev); + } + + platform_set_drvdata(pdev, data); + return 0; +} + +static struct platform_driver cix_pmu_driver = { + .probe = cix_pmu_probe, + .driver = { + .name = "cix-pmu", + .of_match_table = cix_pmu_id_match, + }, +}; +module_platform_driver(cix_pmu_driver); + +MODULE_LICENSE("GPL v2"); +MODULE_AUTHOR("Cixtech,Inc."); +MODULE_DESCRIPTION("Cix pmu driver"); diff --git a/drivers/dma-buf/dma-buf.c b/drivers/dma-buf/dma-buf.c index 21916bba77d5..a687a2680a8d 100644 --- a/drivers/dma-buf/dma-buf.c +++ b/drivers/dma-buf/dma-buf.c @@ -32,8 +32,9 @@ #include #include "dma-buf-sysfs-stats.h" - -static inline int is_dma_buf_file(struct file *); +#ifdef CONFIG_PLAT_FDLEAK +#include +#endif struct dma_buf_list { struct list_head head; @@ -42,6 +43,39 @@ struct dma_buf_list { static struct dma_buf_list db_list; +/** + * dma_buf_get_each - Helps in traversing the db_list and calls the + * callback function which can extract required info out of each + * dmabuf. + * The db_list needs to be locked to prevent the db_list from being + * dynamically updated during the traversal process. + * + * @callback: [in] Handle for each dmabuf buffer in db_list. + * @private: [in] User-defined, used to pass in when callback is + * called. + * + * Returns 0 on success, otherwise returns a non-zero value for + * mutex_lock_interruptible or callback. + */ +int dma_buf_get_each(int (*callback)(const struct dma_buf *dmabuf, + void *private), void *private) +{ + struct dma_buf *buf; + int ret = mutex_lock_interruptible(&db_list.lock); + + if (ret) + return ret; + + list_for_each_entry(buf, &db_list.head, list_node) { + ret = callback(buf, private); + if (ret) + break; + } + mutex_unlock(&db_list.lock); + return ret; +} +EXPORT_SYMBOL_NS_GPL(dma_buf_get_each, MINIDUMP); + static char *dmabuffs_dname(struct dentry *dentry, char *buffer, int buflen) { struct dma_buf *dmabuf; @@ -101,6 +135,10 @@ static int dma_buf_file_release(struct inode *inode, struct file *file) mutex_unlock(&db_list.lock); } +#ifdef CONFIG_PLAT_FDLEAK + fdleak_report(FDLEAK_WP_DMABUF, 1); +#endif + return 0; } @@ -131,6 +169,7 @@ static struct file_system_type dma_buf_fs_type = { static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) { struct dma_buf *dmabuf; + bool ignore_bounds = false; if (!is_dma_buf_file(file)) return -EINVAL; @@ -142,8 +181,8 @@ static int dma_buf_mmap_internal(struct file *file, struct vm_area_struct *vma) return -EINVAL; /* check for overflowing the buffer's size */ - if (vma->vm_pgoff + vma_pages(vma) > - dmabuf->size >> PAGE_SHIFT) + if ((vma->vm_pgoff + vma_pages(vma) > + dmabuf->size >> PAGE_SHIFT) && !ignore_bounds) return -EINVAL; return dmabuf->ops->mmap(dmabuf, vma); @@ -304,6 +343,16 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) return events; } +static long _dma_buf_set_name(struct dma_buf *dmabuf, const char *name) +{ + spin_lock(&dmabuf->name_lock); + kfree(dmabuf->name); + dmabuf->name = name; + spin_unlock(&dmabuf->name_lock); + + return 0; +} + /** * dma_buf_set_name - Set a name to a specific dma_buf to track the usage. * It could support changing the name of the dma-buf if the same @@ -317,19 +366,35 @@ static __poll_t dma_buf_poll(struct file *file, poll_table *poll) * devices, return -EBUSY. * */ -static long dma_buf_set_name(struct dma_buf *dmabuf, const char __user *buf) +long dma_buf_set_name(struct dma_buf *dmabuf, const char *name) +{ + long ret = 0; + char *buf = kstrndup(name, DMA_BUF_NAME_LEN, GFP_KERNEL); + + if (!buf) + return -ENOMEM; + + ret = _dma_buf_set_name(dmabuf, buf); + if (ret) + kfree(buf); + + return ret; +} +EXPORT_SYMBOL_GPL(dma_buf_set_name); + +static long dma_buf_set_name_user(struct dma_buf *dmabuf, const char __user *buf) { char *name = strndup_user(buf, DMA_BUF_NAME_LEN); + long ret = 0; if (IS_ERR(name)) return PTR_ERR(name); - spin_lock(&dmabuf->name_lock); - kfree(dmabuf->name); - dmabuf->name = name; - spin_unlock(&dmabuf->name_lock); + ret = _dma_buf_set_name(dmabuf, name); + if (ret) + kfree(name); - return 0; + return ret; } #if IS_ENABLED(CONFIG_SYNC_FILE) @@ -478,7 +543,7 @@ static long dma_buf_ioctl(struct file *file, case DMA_BUF_SET_NAME_A: case DMA_BUF_SET_NAME_B: - return dma_buf_set_name(dmabuf, (const char __user *)arg); + return dma_buf_set_name_user(dmabuf, (const char __user *)arg); #if IS_ENABLED(CONFIG_SYNC_FILE) case DMA_BUF_IOCTL_EXPORT_SYNC_FILE: @@ -519,10 +584,11 @@ static const struct file_operations dma_buf_fops = { /* * is_dma_buf_file - Check if struct file* is associated with dma_buf */ -static inline int is_dma_buf_file(struct file *file) +int is_dma_buf_file(struct file *file) { return file->f_op == &dma_buf_fops; } +EXPORT_SYMBOL_NS_GPL(is_dma_buf_file, DMA_BUF); static struct file *dma_buf_getfile(size_t size, int flags) { @@ -676,6 +742,10 @@ struct dma_buf *dma_buf_export(const struct dma_buf_export_info *exp_info) list_add(&dmabuf->list_node, &db_list.head); mutex_unlock(&db_list.lock); +#ifdef CONFIG_PLAT_FDLEAK + fdleak_report(FDLEAK_WP_DMABUF, 2); +#endif + return dmabuf; err_dmabuf: @@ -710,6 +780,10 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags) fd_install(fd, dmabuf->file); +#ifdef CONFIG_PLAT_FDLEAK + fdleak_report(FDLEAK_WP_DMABUF, 0); +#endif + return fd; } EXPORT_SYMBOL_NS_GPL(dma_buf_fd, DMA_BUF); @@ -1412,6 +1486,30 @@ int dma_buf_begin_cpu_access(struct dma_buf *dmabuf, } EXPORT_SYMBOL_NS_GPL(dma_buf_begin_cpu_access, DMA_BUF); +int dma_buf_begin_cpu_access_partial(struct dma_buf *dmabuf, + enum dma_data_direction direction, + unsigned int offset, unsigned int len) +{ + int ret = 0; + + if (WARN_ON(!dmabuf)) + return -EINVAL; + + if (dmabuf->ops->begin_cpu_access_partial) + ret = dmabuf->ops->begin_cpu_access_partial(dmabuf, direction, + offset, len); + + /* Ensure that all fences are waited upon - but we first allow + * the native handler the chance to do so more efficiently if it + * chooses. A double invocation here will be reasonably cheap no-op. + */ + if (ret == 0) + ret = __dma_buf_begin_cpu_access(dmabuf, direction); + + return ret; +} +EXPORT_SYMBOL_GPL(dma_buf_begin_cpu_access_partial); + /** * dma_buf_end_cpu_access - Must be called after accessing a dma_buf from the * cpu in the kernel context. Calls end_cpu_access to allow exporter-specific @@ -1440,6 +1538,21 @@ int dma_buf_end_cpu_access(struct dma_buf *dmabuf, } EXPORT_SYMBOL_NS_GPL(dma_buf_end_cpu_access, DMA_BUF); +int dma_buf_end_cpu_access_partial(struct dma_buf *dmabuf, + enum dma_data_direction direction, + unsigned int offset, unsigned int len) +{ + int ret = 0; + + WARN_ON(!dmabuf); + + if (dmabuf->ops->end_cpu_access_partial) + ret = dmabuf->ops->end_cpu_access_partial(dmabuf, direction, + offset, len); + + return ret; +} +EXPORT_SYMBOL_GPL(dma_buf_end_cpu_access_partial); /** * dma_buf_mmap - Setup up a userspace mmap with the given vma @@ -1602,6 +1715,20 @@ void dma_buf_vunmap_unlocked(struct dma_buf *dmabuf, struct iosys_map *map) } EXPORT_SYMBOL_NS_GPL(dma_buf_vunmap_unlocked, DMA_BUF); +int dma_buf_get_flags(struct dma_buf *dmabuf, unsigned long *flags) +{ + int ret = 0; + + if (WARN_ON(!dmabuf) || !flags) + return -EINVAL; + + if (dmabuf->ops->get_flags) + ret = dmabuf->ops->get_flags(dmabuf, flags); + + return ret; +} +EXPORT_SYMBOL_GPL(dma_buf_get_flags); + #ifdef CONFIG_DEBUG_FS static int dma_buf_debug_show(struct seq_file *s, void *unused) { diff --git a/drivers/dma-buf/dma-heap.c b/drivers/dma-buf/dma-heap.c index 84ae708fafe7..e87cafe84cf4 100644 --- a/drivers/dma-buf/dma-heap.c +++ b/drivers/dma-buf/dma-heap.c @@ -31,6 +31,7 @@ * @heap_devt heap device node * @list list head connecting to list of heaps * @heap_cdev heap char device + * @heap_dev heap device struct * * Represents a heap of memory from which buffers can be made. */ @@ -41,6 +42,8 @@ struct dma_heap { dev_t heap_devt; struct list_head list; struct cdev heap_cdev; + struct kref refcount; + struct device *heap_dev; }; static LIST_HEAD(heap_list); @@ -49,22 +52,60 @@ static dev_t dma_heap_devt; static struct class *dma_heap_class; static DEFINE_XARRAY_ALLOC(dma_heap_minors); -static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, - unsigned int fd_flags, - unsigned int heap_flags) +struct dma_heap *dma_heap_find(const char *name) { - struct dma_buf *dmabuf; - int fd; + struct dma_heap *h; + mutex_lock(&heap_list_lock); + list_for_each_entry(h, &heap_list, list) { + if (!strcmp(h->name, name)) { + kref_get(&h->refcount); + mutex_unlock(&heap_list_lock); + return h; + } + } + mutex_unlock(&heap_list_lock); + return NULL; +} +EXPORT_SYMBOL_GPL(dma_heap_find); + + +void dma_heap_buffer_free(struct dma_buf *dmabuf) +{ + dma_buf_put(dmabuf); +} +EXPORT_SYMBOL_GPL(dma_heap_buffer_free); + +struct dma_buf *dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, + unsigned int fd_flags, + unsigned int heap_flags) +{ + if (fd_flags & ~DMA_HEAP_VALID_FD_FLAGS) + return ERR_PTR(-EINVAL); + + if (heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS) + return ERR_PTR(-EINVAL); /* * Allocations from all heaps have to begin * and end on page boundaries. */ len = PAGE_ALIGN(len); if (!len) - return -EINVAL; + return ERR_PTR(-EINVAL); + + return heap->ops->allocate(heap, len, fd_flags, heap_flags); +} +EXPORT_SYMBOL_GPL(dma_heap_buffer_alloc); + +int dma_heap_bufferfd_alloc(struct dma_heap *heap, size_t len, + unsigned int fd_flags, + unsigned int heap_flags) +{ + struct dma_buf *dmabuf; + int fd; + + dmabuf = dma_heap_buffer_alloc(heap, len, fd_flags, heap_flags); - dmabuf = heap->ops->allocate(heap, len, fd_flags, heap_flags); if (IS_ERR(dmabuf)) return PTR_ERR(dmabuf); @@ -74,7 +115,9 @@ static int dma_heap_buffer_alloc(struct dma_heap *heap, size_t len, /* just return, as put will call release and that will free */ } return fd; + } +EXPORT_SYMBOL_GPL(dma_heap_bufferfd_alloc); static int dma_heap_open(struct inode *inode, struct file *file) { @@ -102,15 +145,9 @@ static long dma_heap_ioctl_allocate(struct file *file, void *data) if (heap_allocation->fd) return -EINVAL; - if (heap_allocation->fd_flags & ~DMA_HEAP_VALID_FD_FLAGS) - return -EINVAL; - - if (heap_allocation->heap_flags & ~DMA_HEAP_VALID_HEAP_FLAGS) - return -EINVAL; - - fd = dma_heap_buffer_alloc(heap, heap_allocation->len, - heap_allocation->fd_flags, - heap_allocation->heap_flags); + fd = dma_heap_bufferfd_alloc(heap, heap_allocation->len, + heap_allocation->fd_flags, + heap_allocation->heap_flags); if (fd < 0) return fd; @@ -203,6 +240,47 @@ void *dma_heap_get_drvdata(struct dma_heap *heap) { return heap->priv; } +EXPORT_SYMBOL_GPL(dma_heap_get_drvdata); + +static void dma_heap_release(struct kref *ref) +{ + struct dma_heap *heap = container_of(ref, struct dma_heap, refcount); + int minor = MINOR(heap->heap_devt); + + /* Note, we already holding the heap_list_lock here */ + list_del(&heap->list); + + device_destroy(dma_heap_class, heap->heap_devt); + cdev_del(&heap->heap_cdev); + xa_erase(&dma_heap_minors, minor); + + kfree(heap); +} + +void dma_heap_put(struct dma_heap *h) +{ + /* + * Take the heap_list_lock now to avoid racing with code + * scanning the list and then taking a kref. + */ + mutex_lock(&heap_list_lock); + kref_put(&h->refcount, dma_heap_release); + mutex_unlock(&heap_list_lock); +} +EXPORT_SYMBOL_GPL(dma_heap_put); + +/** + * dma_heap_get_dev() - get device struct for the heap + * @heap: DMA-Heap to retrieve device struct from + * + * Returns: + * The device struct for the heap. + */ +struct device *dma_heap_get_dev(struct dma_heap *heap) +{ + return heap->heap_dev; +} +EXPORT_SYMBOL_GPL(dma_heap_get_dev); /** * dma_heap_get_name() - get heap name @@ -215,11 +293,11 @@ const char *dma_heap_get_name(struct dma_heap *heap) { return heap->name; } +EXPORT_SYMBOL_GPL(dma_heap_get_name); struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) { struct dma_heap *heap, *h, *err_ret; - struct device *dev_ret; unsigned int minor; int ret; @@ -237,6 +315,7 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) if (!heap) return ERR_PTR(-ENOMEM); + kref_init(&heap->refcount); heap->name = exp_info->name; heap->ops = exp_info->ops; heap->priv = exp_info->priv; @@ -261,17 +340,20 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) goto err1; } - dev_ret = device_create(dma_heap_class, - NULL, - heap->heap_devt, - NULL, - heap->name); - if (IS_ERR(dev_ret)) { + heap->heap_dev = device_create(dma_heap_class, + NULL, + heap->heap_devt, + NULL, + heap->name); + if (IS_ERR(heap->heap_dev)) { pr_err("dma_heap: Unable to create device\n"); - err_ret = ERR_CAST(dev_ret); + err_ret = ERR_CAST(heap->heap_dev); goto err2; } + /* Make sure it doesn't disappear on us */ + heap->heap_dev = get_device(heap->heap_dev); + mutex_lock(&heap_list_lock); /* check the name is unique */ list_for_each_entry(h, &heap_list, list) { @@ -280,6 +362,7 @@ struct dma_heap *dma_heap_add(const struct dma_heap_export_info *exp_info) pr_err("dma_heap: Already registered heap named %s\n", exp_info->name); err_ret = ERR_PTR(-EINVAL); + put_device(heap->heap_dev); goto err3; } } @@ -300,27 +383,88 @@ err0: kfree(heap); return err_ret; } +EXPORT_SYMBOL_GPL(dma_heap_add); static char *dma_heap_devnode(const struct device *dev, umode_t *mode) { return kasprintf(GFP_KERNEL, "dma_heap/%s", dev_name(dev)); } +static ssize_t total_pools_kb_show(struct kobject *kobj, + struct kobj_attribute *attr, char *buf) +{ + struct dma_heap *heap; + u64 total_pool_size = 0; + + mutex_lock(&heap_list_lock); + list_for_each_entry(heap, &heap_list, list) { + if (heap->ops->get_pool_size) + total_pool_size += heap->ops->get_pool_size(heap); + } + mutex_unlock(&heap_list_lock); + + return sysfs_emit(buf, "%llu\n", total_pool_size / 1024); +} + +static struct kobj_attribute total_pools_kb_attr = + __ATTR_RO(total_pools_kb); + +static struct attribute *dma_heap_sysfs_attrs[] = { + &total_pools_kb_attr.attr, + NULL, +}; + +ATTRIBUTE_GROUPS(dma_heap_sysfs); + +static struct kobject *dma_heap_kobject; + +static int dma_heap_sysfs_setup(void) +{ + int ret; + + dma_heap_kobject = kobject_create_and_add("dma_heap", kernel_kobj); + if (!dma_heap_kobject) + return -ENOMEM; + + ret = sysfs_create_groups(dma_heap_kobject, dma_heap_sysfs_groups); + if (ret) { + kobject_put(dma_heap_kobject); + return ret; + } + + return 0; +} + +static void dma_heap_sysfs_teardown(void) +{ + kobject_put(dma_heap_kobject); +} + static int dma_heap_init(void) { int ret; - ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME); + ret = dma_heap_sysfs_setup(); if (ret) return ret; + ret = alloc_chrdev_region(&dma_heap_devt, 0, NUM_HEAP_MINORS, DEVNAME); + if (ret) + goto err_chrdev; + dma_heap_class = class_create(DEVNAME); if (IS_ERR(dma_heap_class)) { - unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS); - return PTR_ERR(dma_heap_class); + ret = PTR_ERR(dma_heap_class); + goto err_class; } dma_heap_class->devnode = dma_heap_devnode; return 0; + +err_class: + unregister_chrdev_region(dma_heap_devt, NUM_HEAP_MINORS); +err_chrdev: + dma_heap_sysfs_teardown(); + return ret; } subsys_initcall(dma_heap_init); diff --git a/drivers/dma-buf/heaps/Kconfig b/drivers/dma-buf/heaps/Kconfig index a5eef06c4226..aaae950e8000 100644 --- a/drivers/dma-buf/heaps/Kconfig +++ b/drivers/dma-buf/heaps/Kconfig @@ -1,14 +1,41 @@ +menuconfig DMABUF_HEAPS_DEFERRED_FREE + bool "DMA-BUF heaps deferred-free library" + help + Choose this option to enable the DMA-BUF heaps deferred-free library. + +menuconfig DMABUF_HEAPS_PAGE_POOL + bool "DMA-BUF heaps page-pool library" + help + Choose this option to enable the DMA-BUF heaps page-pool library. + config DMABUF_HEAPS_SYSTEM - bool "DMA-BUF System Heap" + tristate "DMA-BUF System Heap" depends on DMABUF_HEAPS + select DMABUF_HEAPS_PAGE_POOL help Choose this option to enable the system dmabuf heap. The system heap is backed by pages from the buddy allocator. If in doubt, say Y. config DMABUF_HEAPS_CMA - bool "DMA-BUF CMA Heap" + tristate "DMA-BUF CMA Heap" depends on DMABUF_HEAPS && DMA_CMA help Choose this option to enable dma-buf CMA heap. This heap is backed by the Contiguous Memory Allocator (CMA). If your system has these regions, you should say Y here. + +config DMABUF_HEAPS_DSP + bool "DMA-BUF DSP Heap" + depends on DMABUF_HEAPS + help + Choose this option to enable the dsp dmabuf heap. The dsp heap is + allocated by gen allocater, it's allocated according the dts. If in + doubt, say Y here. + +config DMABUF_HEAPS_VPU + bool "DMA-BUF VPU Heap" + depends on DMABUF_HEAPS + help + Choose this option to enable VPU dma-buf heap. The VPU heap is + internally managed. It's allocated according to the dts. If in + doubt, say Y. diff --git a/drivers/dma-buf/heaps/Makefile b/drivers/dma-buf/heaps/Makefile index 974467791032..007f6255e25b 100644 --- a/drivers/dma-buf/heaps/Makefile +++ b/drivers/dma-buf/heaps/Makefile @@ -1,3 +1,7 @@ # SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_DMABUF_HEAPS_DEFERRED_FREE) += deferred-free-helper.o +obj-$(CONFIG_DMABUF_HEAPS_PAGE_POOL) += page_pool.o obj-$(CONFIG_DMABUF_HEAPS_SYSTEM) += system_heap.o obj-$(CONFIG_DMABUF_HEAPS_CMA) += cma_heap.o +obj-$(CONFIG_DMABUF_HEAPS_DSP) += dsp_heap.o +obj-$(CONFIG_DMABUF_HEAPS_VPU) += vpu_heap.o diff --git a/drivers/dma-buf/heaps/cma_heap.c b/drivers/dma-buf/heaps/cma_heap.c index bea7e574f916..8521c7052f56 100644 --- a/drivers/dma-buf/heaps/cma_heap.c +++ b/drivers/dma-buf/heaps/cma_heap.c @@ -99,9 +99,10 @@ static struct sg_table *cma_heap_map_dma_buf(struct dma_buf_attachment *attachme { struct dma_heap_attachment *a = attachment->priv; struct sg_table *table = &a->table; + int attrs = attachment->dma_map_attrs; int ret; - ret = dma_map_sgtable(attachment->dev, table, direction, 0); + ret = dma_map_sgtable(attachment->dev, table, direction, attrs); if (ret) return ERR_PTR(-ENOMEM); a->mapped = true; @@ -113,9 +114,10 @@ static void cma_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction direction) { struct dma_heap_attachment *a = attachment->priv; + int attrs = attachment->dma_map_attrs; a->mapped = false; - dma_unmap_sgtable(attachment->dev, table, direction, 0); + dma_unmap_sgtable(attachment->dev, table, direction, attrs); } static int cma_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, @@ -404,3 +406,5 @@ static int add_default_cma_heap(void) } module_init(add_default_cma_heap); MODULE_DESCRIPTION("DMA-BUF CMA Heap"); +MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(DMA_BUF); diff --git a/drivers/dma-buf/heaps/deferred-free-helper.c b/drivers/dma-buf/heaps/deferred-free-helper.c new file mode 100644 index 000000000000..bae271720011 --- /dev/null +++ b/drivers/dma-buf/heaps/deferred-free-helper.c @@ -0,0 +1,138 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Deferred dmabuf freeing helper + * + * Copyright (C) 2020 Linaro, Ltd. + * + * Based on the ION page pool code + * Copyright (C) 2011 Google, Inc. + */ + +#include +#include +#include +#include +#include + +#include "deferred-free-helper.h" + +static LIST_HEAD(free_list); +static size_t list_nr_pages; +wait_queue_head_t freelist_waitqueue; +struct task_struct *freelist_task; +static DEFINE_SPINLOCK(free_list_lock); + +void deferred_free(struct deferred_freelist_item *item, + void (*free)(struct deferred_freelist_item*, + enum df_reason), + size_t nr_pages) +{ + unsigned long flags; + + INIT_LIST_HEAD(&item->list); + item->nr_pages = nr_pages; + item->free = free; + + spin_lock_irqsave(&free_list_lock, flags); + list_add(&item->list, &free_list); + list_nr_pages += nr_pages; + spin_unlock_irqrestore(&free_list_lock, flags); + wake_up(&freelist_waitqueue); +} +EXPORT_SYMBOL_GPL(deferred_free); + +static size_t free_one_item(enum df_reason reason) +{ + unsigned long flags; + size_t nr_pages; + struct deferred_freelist_item *item; + + spin_lock_irqsave(&free_list_lock, flags); + if (list_empty(&free_list)) { + spin_unlock_irqrestore(&free_list_lock, flags); + return 0; + } + item = list_first_entry(&free_list, struct deferred_freelist_item, list); + list_del(&item->list); + nr_pages = item->nr_pages; + list_nr_pages -= nr_pages; + spin_unlock_irqrestore(&free_list_lock, flags); + + item->free(item, reason); + return nr_pages; +} + +static unsigned long get_freelist_nr_pages(void) +{ + unsigned long nr_pages; + unsigned long flags; + + spin_lock_irqsave(&free_list_lock, flags); + nr_pages = list_nr_pages; + spin_unlock_irqrestore(&free_list_lock, flags); + return nr_pages; +} + +static unsigned long freelist_shrink_count(struct shrinker *shrinker, + struct shrink_control *sc) +{ + return get_freelist_nr_pages(); +} + +static unsigned long freelist_shrink_scan(struct shrinker *shrinker, + struct shrink_control *sc) +{ + unsigned long total_freed = 0; + + if (sc->nr_to_scan == 0) + return 0; + + while (total_freed < sc->nr_to_scan) { + size_t pages_freed = free_one_item(DF_UNDER_PRESSURE); + + if (!pages_freed) + break; + + total_freed += pages_freed; + } + + return total_freed; +} + +static struct shrinker freelist_shrinker = { + .count_objects = freelist_shrink_count, + .scan_objects = freelist_shrink_scan, + .seeks = DEFAULT_SEEKS, + .batch = 0, +}; + +static int deferred_free_thread(void *data) +{ + while (true) { + wait_event_freezable(freelist_waitqueue, + get_freelist_nr_pages() > 0); + + free_one_item(DF_NORMAL); + } + + return 0; +} + +static int deferred_freelist_init(void) +{ + list_nr_pages = 0; + + init_waitqueue_head(&freelist_waitqueue); + freelist_task = kthread_run(deferred_free_thread, NULL, + "%s", "dmabuf-deferred-free-worker"); + if (IS_ERR(freelist_task)) { + pr_err("Creating thread for deferred free failed\n"); + return -1; + } + sched_set_normal(freelist_task, 19); + + return register_shrinker(&freelist_shrinker, "dmabuf-deferred-free-shrinker"); +} +module_init(deferred_freelist_init); +MODULE_LICENSE("GPL v2"); + diff --git a/drivers/dma-buf/heaps/deferred-free-helper.h b/drivers/dma-buf/heaps/deferred-free-helper.h new file mode 100644 index 000000000000..11940328ce3f --- /dev/null +++ b/drivers/dma-buf/heaps/deferred-free-helper.h @@ -0,0 +1,55 @@ +/* SPDX-License-Identifier: GPL-2.0 */ + +#ifndef DEFERRED_FREE_HELPER_H +#define DEFERRED_FREE_HELPER_H + +/** + * df_reason - enum for reason why item was freed + * + * This provides a reason for why the free function was called + * on the item. This is useful when deferred_free is used in + * combination with a pagepool, so under pressure the page can + * be immediately freed. + * + * DF_NORMAL: Normal deferred free + * + * DF_UNDER_PRESSURE: Free was called because the system + * is under memory pressure. Usually + * from a shrinker. Avoid allocating + * memory in the free call, as it may + * fail. + */ +enum df_reason { + DF_NORMAL, + DF_UNDER_PRESSURE, +}; + +/** + * deferred_freelist_item - item structure for deferred freelist + * + * This is to be added to the structure for whatever you want to + * defer freeing on. + * + * @nr_pages: number of pages used by item to be freed + * @free: function pointer to be called when freeing the item + * @list: list entry for the deferred list + */ +struct deferred_freelist_item { + size_t nr_pages; + void (*free)(struct deferred_freelist_item *i, + enum df_reason reason); + struct list_head list; +}; + +/** + * deferred_free - call to add item to the deferred free list + * + * @item: Pointer to deferred_freelist_item field of a structure + * @free: Function pointer to the free call + * @nr_pages: number of pages to be freed + */ +void deferred_free(struct deferred_freelist_item *item, + void (*free)(struct deferred_freelist_item *i, + enum df_reason reason), + size_t nr_pages); +#endif diff --git a/drivers/dma-buf/heaps/dsp_heap.c b/drivers/dma-buf/heaps/dsp_heap.c new file mode 100644 index 000000000000..80a13dd87acd --- /dev/null +++ b/drivers/dma-buf/heaps/dsp_heap.c @@ -0,0 +1,164 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMABUF DSP heap exporter + * + * Copyright 2021 NXP. + * Copyright 2024 Cix Technology Group Co., Ltd. + * + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct dsp_heap_buffer { + struct dma_heap *heap; + struct list_head attachments; + struct mutex lock; /* mutex lock */ +}; + +struct dsp_heap { + struct dma_heap *heap; + phys_addr_t base; + phys_addr_t size; +}; + +static int dsp_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct dsp_heap_buffer *buffer = dmabuf->priv; + struct dsp_heap *dsp_heap = dma_heap_get_drvdata(buffer->heap); + unsigned long pfn; + size_t size; + int ret; + + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + + size = dmabuf->size; + pfn = dsp_heap->base >> PAGE_SHIFT; + + ret = remap_pfn_range(vma, vma->vm_start, pfn, size, vma->vm_page_prot); + if (ret < 0) + return ret; + + return 0; +} + +static void dsp_heap_dma_buf_release(struct dma_buf *dmabuf) +{ + struct dsp_heap_buffer *buffer = dmabuf->priv; + + kfree(buffer); +} + +static struct sg_table *dsp_heap_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + return NULL; +} + +static void dsp_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ +} + +static const struct dma_buf_ops dsp_heap_buf_ops = { + .mmap = dsp_heap_mmap, + .map_dma_buf = dsp_heap_map_dma_buf, + .unmap_dma_buf = dsp_heap_unmap_dma_buf, + .release = dsp_heap_dma_buf_release, +}; + +static struct dma_buf *dsp_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags) +{ + struct dsp_heap *dsp_heap = dma_heap_get_drvdata(heap); + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + struct dsp_heap_buffer *buffer; + struct dma_buf *dmabuf; + int ret; + + if (len > dsp_heap->size) + return ERR_PTR(-ENOMEM); + + buffer = kzalloc(sizeof(*buffer), GFP_KERNEL); + if (!buffer) + return ERR_PTR(-ENOMEM); + + INIT_LIST_HEAD(&buffer->attachments); + mutex_init(&buffer->lock); + buffer->heap = heap; + + /* create the dmabuf */ + exp_info.ops = &dsp_heap_buf_ops; + exp_info.size = len; + exp_info.flags = fd_flags; + exp_info.priv = buffer; + dmabuf = dma_buf_export(&exp_info); + if (IS_ERR(dmabuf)) { + ret = PTR_ERR(dmabuf); + return ERR_PTR(ret); + } + + return dmabuf; +} + +static const struct dma_heap_ops dsp_heap_ops = { + .allocate = dsp_heap_allocate, +}; + +static int dsp_heap_create(void) +{ + struct dma_heap_export_info exp_info; + struct dsp_heap *dsp_heap; + struct reserved_mem *rmem; + struct device_node np; + + np.full_name = "dsp_reserved_heap"; + np.name = "dsp_reserved_heap"; + rmem = of_reserved_mem_lookup(&np); + if (!rmem) { + pr_err("of_reserved_mem_lookup() returned NULL\n"); + return 0; + } + + if (rmem->base == 0 || rmem->size == 0) { + pr_err("dsp_reserved_heap base or size is not correct\n"); + return -EINVAL; + } + + dsp_heap = kzalloc(sizeof(*dsp_heap), GFP_KERNEL); + if (!dsp_heap) + return -ENOMEM; + + dsp_heap->base = rmem->base; + dsp_heap->size = rmem->size; + + exp_info.name = "dsp"; + exp_info.ops = &dsp_heap_ops; + exp_info.priv = dsp_heap; + dsp_heap->heap = dma_heap_add(&exp_info); + if (IS_ERR(dsp_heap->heap)) { + int ret = PTR_ERR(dsp_heap->heap); + + kfree(dsp_heap); + return ret; + } + + return 0; +} +module_init(dsp_heap_create); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma-buf/heaps/page_pool.c b/drivers/dma-buf/heaps/page_pool.c new file mode 100644 index 000000000000..56e6a6f032b7 --- /dev/null +++ b/drivers/dma-buf/heaps/page_pool.c @@ -0,0 +1,294 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMA BUF page pool system + * + * Copyright (C) 2020 Linaro Ltd. + * + * Based on the ION page pool code + * Copyright (C) 2011 Google, Inc. + */ + +#include "page_pool.h" + +#include +#include +#include +#include +#include + +/* page types we track in the pool */ +enum { + POOL_LOWPAGE, /* Clean lowmem pages */ + POOL_HIGHPAGE, /* Clean highmem pages */ + + POOL_TYPE_SIZE, +}; + +/** + * struct dmabuf_page_pool - pagepool struct + * @count[]: array of number of pages of that type in the pool + * @items[]: array of list of pages of the specific type + * @lock: lock protecting this struct and especially the count + * item list + * @gfp_mask: gfp_mask to use from alloc + * @order: order of pages in the pool + * @list: list node for list of pools + * + * Allows you to keep a pool of pre allocated pages to use + */ +struct dmabuf_page_pool { + int count[POOL_TYPE_SIZE]; + struct list_head items[POOL_TYPE_SIZE]; + spinlock_t lock; + gfp_t gfp_mask; + unsigned int order; + struct list_head list; +}; + +static LIST_HEAD(pool_list); +static DEFINE_MUTEX(pool_list_lock); + +static inline +struct page *dmabuf_page_pool_alloc_pages(struct dmabuf_page_pool *pool) +{ + if (fatal_signal_pending(current)) + return NULL; + return alloc_pages(pool->gfp_mask, pool->order); +} + +static inline void dmabuf_page_pool_free_pages(struct dmabuf_page_pool *pool, + struct page *page) +{ + __free_pages(page, pool->order); +} + +static void dmabuf_page_pool_add(struct dmabuf_page_pool *pool, struct page *page) +{ + int index; + + if (PageHighMem(page)) + index = POOL_HIGHPAGE; + else + index = POOL_LOWPAGE; + + spin_lock(&pool->lock); + list_add_tail(&page->lru, &pool->items[index]); + pool->count[index]++; + spin_unlock(&pool->lock); + mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, + 1 << pool->order); +} + +static struct page *dmabuf_page_pool_remove(struct dmabuf_page_pool *pool, int index) +{ + struct page *page; + + spin_lock(&pool->lock); + page = list_first_entry_or_null(&pool->items[index], struct page, lru); + if (page) { + pool->count[index]--; + list_del(&page->lru); + spin_unlock(&pool->lock); + mod_node_page_state(page_pgdat(page), NR_KERNEL_MISC_RECLAIMABLE, + -(1 << pool->order)); + goto out; + } + spin_unlock(&pool->lock); +out: + return page; +} + +static struct page *dmabuf_page_pool_fetch(struct dmabuf_page_pool *pool) +{ + struct page *page = NULL; + + page = dmabuf_page_pool_remove(pool, POOL_HIGHPAGE); + if (!page) + page = dmabuf_page_pool_remove(pool, POOL_LOWPAGE); + + return page; +} + +struct page *dmabuf_page_pool_alloc(struct dmabuf_page_pool *pool) +{ + struct page *page = NULL; + + if (WARN_ON(!pool)) + return NULL; + + page = dmabuf_page_pool_fetch(pool); + + if (!page) + page = dmabuf_page_pool_alloc_pages(pool); + return page; +} +EXPORT_SYMBOL_GPL(dmabuf_page_pool_alloc); + +void dmabuf_page_pool_free(struct dmabuf_page_pool *pool, struct page *page) +{ + if (WARN_ON(pool->order != compound_order(page))) + return; + + dmabuf_page_pool_add(pool, page); +} +EXPORT_SYMBOL_GPL(dmabuf_page_pool_free); + +static int dmabuf_page_pool_total(struct dmabuf_page_pool *pool, bool high) +{ + int count = pool->count[POOL_LOWPAGE]; + + if (high) + count += pool->count[POOL_HIGHPAGE]; + + return count << pool->order; +} + +struct dmabuf_page_pool *dmabuf_page_pool_create(gfp_t gfp_mask, unsigned int order) +{ + struct dmabuf_page_pool *pool = kmalloc(sizeof(*pool), GFP_KERNEL); + int i; + + if (!pool) + return NULL; + + for (i = 0; i < POOL_TYPE_SIZE; i++) { + pool->count[i] = 0; + INIT_LIST_HEAD(&pool->items[i]); + } + pool->gfp_mask = gfp_mask | __GFP_COMP; + pool->order = order; + spin_lock_init(&pool->lock); + + mutex_lock(&pool_list_lock); + list_add(&pool->list, &pool_list); + mutex_unlock(&pool_list_lock); + + return pool; +} +EXPORT_SYMBOL_GPL(dmabuf_page_pool_create); + +void dmabuf_page_pool_destroy(struct dmabuf_page_pool *pool) +{ + struct page *page; + int i; + + /* Remove us from the pool list */ + mutex_lock(&pool_list_lock); + list_del(&pool->list); + mutex_unlock(&pool_list_lock); + + /* Free any remaining pages in the pool */ + for (i = 0; i < POOL_TYPE_SIZE; i++) { + while ((page = dmabuf_page_pool_remove(pool, i))) + dmabuf_page_pool_free_pages(pool, page); + } + + kfree(pool); +} +EXPORT_SYMBOL_GPL(dmabuf_page_pool_destroy); + +unsigned long dmabuf_page_pool_get_size(struct dmabuf_page_pool *pool) +{ + int i; + unsigned long num_pages = 0; + + spin_lock(&pool->lock); + for (i = 0; i < POOL_TYPE_SIZE; ++i) + num_pages += pool->count[i]; + spin_unlock(&pool->lock); + num_pages <<= pool->order; /* pool order is immutable */ + + return num_pages * PAGE_SIZE; +} +EXPORT_SYMBOL_GPL(dmabuf_page_pool_get_size); + +static int dmabuf_page_pool_do_shrink(struct dmabuf_page_pool *pool, gfp_t gfp_mask, + int nr_to_scan) +{ + int freed = 0; + bool high; + + if (current_is_kswapd()) + high = true; + else + high = !!(gfp_mask & __GFP_HIGHMEM); + + if (nr_to_scan == 0) + return dmabuf_page_pool_total(pool, high); + + while (freed < nr_to_scan) { + struct page *page; + + /* Try to free low pages first */ + page = dmabuf_page_pool_remove(pool, POOL_LOWPAGE); + if (!page) + page = dmabuf_page_pool_remove(pool, POOL_HIGHPAGE); + + if (!page) + break; + + dmabuf_page_pool_free_pages(pool, page); + freed += (1 << pool->order); + } + + return freed; +} + +static int dmabuf_page_pool_shrink(gfp_t gfp_mask, int nr_to_scan) +{ + struct dmabuf_page_pool *pool; + int nr_total = 0; + int nr_freed; + int only_scan = 0; + + if (!nr_to_scan) + only_scan = 1; + + mutex_lock(&pool_list_lock); + list_for_each_entry(pool, &pool_list, list) { + if (only_scan) { + nr_total += dmabuf_page_pool_do_shrink(pool, + gfp_mask, + nr_to_scan); + } else { + nr_freed = dmabuf_page_pool_do_shrink(pool, + gfp_mask, + nr_to_scan); + nr_to_scan -= nr_freed; + nr_total += nr_freed; + if (nr_to_scan <= 0) + break; + } + } + mutex_unlock(&pool_list_lock); + + return nr_total; +} + +static unsigned long dmabuf_page_pool_shrink_count(struct shrinker *shrinker, + struct shrink_control *sc) +{ + return dmabuf_page_pool_shrink(sc->gfp_mask, 0); +} + +static unsigned long dmabuf_page_pool_shrink_scan(struct shrinker *shrinker, + struct shrink_control *sc) +{ + if (sc->nr_to_scan == 0) + return 0; + return dmabuf_page_pool_shrink(sc->gfp_mask, sc->nr_to_scan); +} + +struct shrinker pool_shrinker = { + .count_objects = dmabuf_page_pool_shrink_count, + .scan_objects = dmabuf_page_pool_shrink_scan, + .seeks = DEFAULT_SEEKS, + .batch = 0, +}; + +static int dmabuf_page_pool_init_shrinker(void) +{ + return register_shrinker(&pool_shrinker, "dmabuf-page-pool-shrinker"); +} +module_init(dmabuf_page_pool_init_shrinker); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma-buf/heaps/page_pool.h b/drivers/dma-buf/heaps/page_pool.h new file mode 100644 index 000000000000..5f6f938fa5d9 --- /dev/null +++ b/drivers/dma-buf/heaps/page_pool.h @@ -0,0 +1,27 @@ +/* SPDX-License-Identifier: GPL-2.0 */ +/* + * DMA BUF PagePool implementation + * Based on earlier ION code by Google + * + * Copyright (C) 2011 Google, Inc. + * Copyright (C) 2020 Linaro Ltd. + */ + +#ifndef _DMABUF_PAGE_POOL_H +#define _DMABUF_PAGE_POOL_H + +#include +#include + +struct dmabuf_page_pool; + +struct dmabuf_page_pool *dmabuf_page_pool_create(gfp_t gfp_mask, + unsigned int order); +void dmabuf_page_pool_destroy(struct dmabuf_page_pool *pool); +struct page *dmabuf_page_pool_alloc(struct dmabuf_page_pool *pool); +void dmabuf_page_pool_free(struct dmabuf_page_pool *pool, struct page *page); + +/* get pool size in bytes */ +unsigned long dmabuf_page_pool_get_size(struct dmabuf_page_pool *pool); + +#endif /* _DMABUF_PAGE_POOL_H */ diff --git a/drivers/dma-buf/heaps/system_heap.c b/drivers/dma-buf/heaps/system_heap.c index 9076d47ed2ef..bba9ef9abd61 100644 --- a/drivers/dma-buf/heaps/system_heap.c +++ b/drivers/dma-buf/heaps/system_heap.c @@ -21,7 +21,10 @@ #include #include +#include "page_pool.h" + static struct dma_heap *sys_heap; +static struct dma_heap *sys_uncached_heap; struct system_heap_buffer { struct dma_heap *heap; @@ -31,6 +34,8 @@ struct system_heap_buffer { struct sg_table sg_table; int vmap_cnt; void *vaddr; + + bool uncached; }; struct dma_heap_attachment { @@ -38,6 +43,8 @@ struct dma_heap_attachment { struct sg_table *table; struct list_head list; bool mapped; + + bool uncached; }; #define LOW_ORDER_GFP (GFP_HIGHUSER | __GFP_ZERO) @@ -53,6 +60,7 @@ static gfp_t order_flags[] = {HIGH_ORDER_GFP, HIGH_ORDER_GFP, LOW_ORDER_GFP}; */ static const unsigned int orders[] = {8, 4, 0}; #define NUM_ORDERS ARRAY_SIZE(orders) +struct dmabuf_page_pool *pools[NUM_ORDERS]; static struct sg_table *dup_sg_table(struct sg_table *table) { @@ -100,7 +108,7 @@ static int system_heap_attach(struct dma_buf *dmabuf, a->dev = attachment->dev; INIT_LIST_HEAD(&a->list); a->mapped = false; - + a->uncached = buffer->uncached; attachment->priv = a; mutex_lock(&buffer->lock); @@ -130,9 +138,13 @@ static struct sg_table *system_heap_map_dma_buf(struct dma_buf_attachment *attac { struct dma_heap_attachment *a = attachment->priv; struct sg_table *table = a->table; + int attr = attachment->dma_map_attrs; int ret; - ret = dma_map_sgtable(attachment->dev, table, direction, 0); + if (a->uncached) + attr |= DMA_ATTR_SKIP_CPU_SYNC; + + ret = dma_map_sgtable(attachment->dev, table, direction, attr); if (ret) return ERR_PTR(ret); @@ -145,9 +157,12 @@ static void system_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, enum dma_data_direction direction) { struct dma_heap_attachment *a = attachment->priv; + int attr = attachment->dma_map_attrs; + if (a->uncached) + attr |= DMA_ATTR_SKIP_CPU_SYNC; a->mapped = false; - dma_unmap_sgtable(attachment->dev, table, direction, 0); + dma_unmap_sgtable(attachment->dev, table, direction, attr); } static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, @@ -161,10 +176,12 @@ static int system_heap_dma_buf_begin_cpu_access(struct dma_buf *dmabuf, if (buffer->vmap_cnt) invalidate_kernel_vmap_range(buffer->vaddr, buffer->len); - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; - dma_sync_sgtable_for_cpu(a->dev, a->table, direction); + if (!buffer->uncached) { + list_for_each_entry(a, &buffer->attachments, list) { + if (!a->mapped) + continue; + dma_sync_sgtable_for_cpu(a->dev, a->table, direction); + } } mutex_unlock(&buffer->lock); @@ -182,10 +199,12 @@ static int system_heap_dma_buf_end_cpu_access(struct dma_buf *dmabuf, if (buffer->vmap_cnt) flush_kernel_vmap_range(buffer->vaddr, buffer->len); - list_for_each_entry(a, &buffer->attachments, list) { - if (!a->mapped) - continue; - dma_sync_sgtable_for_device(a->dev, a->table, direction); + if (!buffer->uncached) { + list_for_each_entry(a, &buffer->attachments, list) { + if (!a->mapped) + continue; + dma_sync_sgtable_for_device(a->dev, a->table, direction); + } } mutex_unlock(&buffer->lock); @@ -200,6 +219,9 @@ static int system_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) struct sg_page_iter piter; int ret; + if (buffer->uncached) + vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); + for_each_sgtable_page(table, &piter, vma->vm_pgoff) { struct page *page = sg_page_iter_page(&piter); @@ -221,17 +243,21 @@ static void *system_heap_do_vmap(struct system_heap_buffer *buffer) struct page **pages = vmalloc(sizeof(struct page *) * npages); struct page **tmp = pages; struct sg_page_iter piter; + pgprot_t pgprot = PAGE_KERNEL; void *vaddr; if (!pages) return ERR_PTR(-ENOMEM); + if (buffer->uncached) + pgprot = pgprot_writecombine(PAGE_KERNEL); + for_each_sgtable_page(table, &piter, 0) { WARN_ON(tmp - pages >= npages); *tmp++ = sg_page_iter_page(&piter); } - vaddr = vmap(pages, npages, VM_MAP, PAGE_KERNEL); + vaddr = vmap(pages, npages, VM_MAP, pgprot); vfree(pages); if (!vaddr) @@ -281,18 +307,43 @@ static void system_heap_vunmap(struct dma_buf *dmabuf, struct iosys_map *map) iosys_map_clear(map); } +static int system_heap_zero_buffer(struct system_heap_buffer *buffer) +{ + struct sg_table *sgt = &buffer->sg_table; + struct sg_page_iter piter; + struct page *p; + void *vaddr; + int ret = 0; + + for_each_sgtable_page(sgt, &piter, 0) { + p = sg_page_iter_page(&piter); + vaddr = kmap_local_page(p); + memset(vaddr, 0, PAGE_SIZE); + kunmap_local(vaddr); + } + + return ret; +} + static void system_heap_dma_buf_release(struct dma_buf *dmabuf) { struct system_heap_buffer *buffer = dmabuf->priv; struct sg_table *table; struct scatterlist *sg; - int i; + int i, j; + + /* Zero the buffer pages before adding back to the pool */ + system_heap_zero_buffer(buffer); table = &buffer->sg_table; for_each_sgtable_sg(table, sg, i) { struct page *page = sg_page(sg); - __free_pages(page, compound_order(page)); + for (j = 0; j < NUM_ORDERS; j++) { + if (compound_order(page) == orders[j]) + break; + } + dmabuf_page_pool_free(pools[j], page); } sg_free_table(table); kfree(buffer); @@ -322,8 +373,7 @@ static struct page *alloc_largest_available(unsigned long size, continue; if (max_order < orders[i]) continue; - - page = alloc_pages(order_flags[i], orders[i]); + page = dmabuf_page_pool_alloc(pools[i]); if (!page) continue; return page; @@ -331,10 +381,11 @@ static struct page *alloc_largest_available(unsigned long size, return NULL; } -static struct dma_buf *system_heap_allocate(struct dma_heap *heap, - unsigned long len, - unsigned long fd_flags, - unsigned long heap_flags) +static struct dma_buf *system_heap_do_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags, + bool uncached) { struct system_heap_buffer *buffer; DEFINE_DMA_BUF_EXPORT_INFO(exp_info); @@ -355,6 +406,7 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap, mutex_init(&buffer->lock); buffer->heap = heap; buffer->len = len; + buffer->uncached = uncached; INIT_LIST_HEAD(&pages); i = 0; @@ -400,6 +452,18 @@ static struct dma_buf *system_heap_allocate(struct dma_heap *heap, ret = PTR_ERR(dmabuf); goto free_pages; } + + /* + * For uncached buffers, we need to initially flush cpu cache, since + * the __GFP_ZERO on the allocation means the zeroing was done by the + * cpu and thus it is likely cached. Map (and implicitly flush) and + * unmap it now so we don't get corruption later on. + */ + if (buffer->uncached) { + dma_map_sgtable(dma_heap_get_dev(heap), table, DMA_BIDIRECTIONAL, 0); + dma_unmap_sgtable(dma_heap_get_dev(heap), table, DMA_BIDIRECTIONAL, 0); + } + return dmabuf; free_pages: @@ -417,13 +481,69 @@ free_buffer: return ERR_PTR(ret); } +static struct dma_buf *system_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags) +{ + return system_heap_do_allocate(heap, len, fd_flags, heap_flags, false); +} + +static long system_get_pool_size(struct dma_heap *heap) +{ + unsigned long num_bytes = 0; + struct dmabuf_page_pool **pool = pools; + + for (int i = 0; i < NUM_ORDERS; i++, pool++) + num_bytes += dmabuf_page_pool_get_size(*pool); + + return num_bytes; +} + static const struct dma_heap_ops system_heap_ops = { .allocate = system_heap_allocate, + .get_pool_size = system_get_pool_size, +}; + +static struct dma_buf *system_uncached_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags) +{ + return system_heap_do_allocate(heap, len, fd_flags, heap_flags, true); +} + +/* Dummy function to be used until we can call coerce_mask_and_coherent */ +static struct dma_buf *system_uncached_heap_not_initialized(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags) +{ + return ERR_PTR(-EBUSY); +} + +static struct dma_heap_ops system_uncached_heap_ops = { + /* After system_heap_create is complete, we will swap this */ + .allocate = system_uncached_heap_not_initialized, }; static int system_heap_create(void) { struct dma_heap_export_info exp_info; + int i; + + for (i = 0; i < NUM_ORDERS; i++) { + pools[i] = dmabuf_page_pool_create(order_flags[i], orders[i]); + + if (IS_ERR(pools[i])) { + int j; + + pr_err("%s: page pool creation failed!\n", __func__); + for (j = 0; j < i; j++) + dmabuf_page_pool_destroy(pools[j]); + return PTR_ERR(pools[i]); + } + } exp_info.name = "system"; exp_info.ops = &system_heap_ops; @@ -433,6 +553,20 @@ static int system_heap_create(void) if (IS_ERR(sys_heap)) return PTR_ERR(sys_heap); + exp_info.name = "system-uncached"; + exp_info.ops = &system_uncached_heap_ops; + exp_info.priv = NULL; + + sys_uncached_heap = dma_heap_add(&exp_info); + if (IS_ERR(sys_uncached_heap)) + return PTR_ERR(sys_uncached_heap); + + dma_coerce_mask_and_coherent(dma_heap_get_dev(sys_uncached_heap), DMA_BIT_MASK(64)); + mb(); /* make sure we only set allocate after dma_mask is set */ + system_uncached_heap_ops.allocate = system_uncached_heap_allocate; + return 0; } module_init(system_heap_create); +MODULE_LICENSE("GPL v2"); +MODULE_IMPORT_NS(DMA_BUF); diff --git a/drivers/dma-buf/heaps/vpu_heap.c b/drivers/dma-buf/heaps/vpu_heap.c new file mode 100644 index 000000000000..a5c55fe3999c --- /dev/null +++ b/drivers/dma-buf/heaps/vpu_heap.c @@ -0,0 +1,316 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * DMABUF vpu heap exporter + * + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include + +struct vpu_heap { + struct dma_heap *heap; + phys_addr_t base; + phys_addr_t size; + unsigned long npages; + struct mutex page_map_lock; + unsigned long *page_map; +}; + +struct vpu_buffer { + struct dma_heap *heap; + struct dma_buf *dmabuf; + phys_addr_t *pages; + size_t size; + pgoff_t pagecount; + struct sg_table table; +}; + +struct vpu_heaps_attachment { + struct sg_table table; +}; + +static int vpu_heap_attach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct vpu_heaps_attachment *a; + struct vpu_buffer *buffer = dmabuf->priv; + struct scatterlist *s; + int i; + int ret; + + a = kzalloc(sizeof(*a), GFP_KERNEL); + if (!a) + return -ENOMEM; + + ret = sg_alloc_table(&a->table, + buffer->pagecount, GFP_KERNEL); + if (ret) + return ret; + + for_each_sgtable_sg(&a->table, s, i) { + sg_dma_address(s) = buffer->pages[i]; + sg_dma_len(s) = PAGE_SIZE; + s->length = PAGE_SIZE; + } + + attachment->priv = a; + + return 0; +} + +static void vpu_heap_detach(struct dma_buf *dmabuf, + struct dma_buf_attachment *attachment) +{ + struct vpu_heaps_attachment *a = attachment->priv; + sg_free_table(&a->table); + kfree(a); +} + +static +struct sg_table *vpu_heap_map_dma_buf(struct dma_buf_attachment *attachment, + enum dma_data_direction direction) +{ + struct vpu_heaps_attachment *a = attachment->priv; + return &a->table; +} + +static void vpu_heap_unmap_dma_buf(struct dma_buf_attachment *attachment, + struct sg_table *table, + enum dma_data_direction direction) +{ +} + +static phys_addr_t vpu_heap_alloc_page(struct vpu_heap *vpu_heap) +{ + unsigned long id; + phys_addr_t pa; + mutex_lock(&vpu_heap->page_map_lock); + id = find_first_zero_bit(vpu_heap->page_map, vpu_heap->npages); + if (id >= vpu_heap->npages) { + mutex_unlock(&vpu_heap->page_map_lock); + return 0; + } + set_bit(id, vpu_heap->page_map); + mutex_unlock(&vpu_heap->page_map_lock); + pa = vpu_heap->base + (id << PAGE_SHIFT); + return pa; +} + +static int vpu_heap_mmap(struct dma_buf *dmabuf, struct vm_area_struct *vma) +{ + struct vpu_buffer *buffer = dmabuf->priv; + int ret; + + /* Make sure its contiguous memory before calling vm_iomap_memory() */ + int i; + for (i = 1; i < buffer->pagecount; i++) { + if (buffer->pages[i] - buffer->pages[i-1] != PAGE_SIZE) + return -EINVAL; + } + + ret = vm_iomap_memory(vma, buffer->pages[0], buffer->size); + if (ret < 0) + return ret; + + return 0; +} + +static void vpu_heap_free_page(struct vpu_heap *vpu_heap, + phys_addr_t page) +{ + phys_addr_t pa = page; + unsigned long id = (pa - vpu_heap->base) >> PAGE_SHIFT; + mutex_lock(&vpu_heap->page_map_lock); + clear_bit(id, vpu_heap->page_map); + mutex_unlock(&vpu_heap->page_map_lock); +} + +static void vpu_heap_free(struct vpu_buffer *buffer) +{ + struct vpu_heap *vpu_heap = dma_heap_get_drvdata(buffer->heap); + pgoff_t pg; + + for (pg = 0; pg < buffer->pagecount; pg++) + vpu_heap_free_page(vpu_heap, buffer->pages[pg]); + kfree(buffer->pages); + kfree(buffer); +} + +static void vpu_heap_dma_buf_release(struct dma_buf *dmabuf) +{ + struct vpu_buffer *buffer = dmabuf->priv; + + vpu_heap_free(buffer); +} + +static const struct dma_buf_ops vpu_heap_dma_ops = { + .map_dma_buf = vpu_heap_map_dma_buf, + .unmap_dma_buf = vpu_heap_unmap_dma_buf, + .mmap = vpu_heap_mmap, + .release = vpu_heap_dma_buf_release, + .attach = vpu_heap_attach, + .detach = vpu_heap_detach, +}; + +static struct dma_buf *vpu_heap_export_dmabuf(struct vpu_buffer *buffer, + int fd_flags) +{ + DEFINE_DMA_BUF_EXPORT_INFO(exp_info); + + exp_info.ops = &vpu_heap_dma_ops; + exp_info.size = buffer->size; + exp_info.flags = fd_flags; + exp_info.priv = buffer; + + return dma_buf_export(&exp_info); +} + +static struct dma_buf *vpu_heap_allocate(struct dma_heap *heap, + unsigned long len, + unsigned long fd_flags, + unsigned long heap_flags) +{ + struct vpu_heap *vpu_heap = dma_heap_get_drvdata(heap); + struct vpu_buffer *vpu_buffer; + struct dma_buf *dmabuf; + int ret = -ENOMEM; + pgoff_t pg; + + vpu_buffer = kzalloc(sizeof(*vpu_buffer), GFP_KERNEL); + if (!vpu_buffer) + return ERR_PTR(-ENOMEM); + + vpu_buffer->heap = heap; + vpu_buffer->size = len; + vpu_buffer->pagecount = len / PAGE_SIZE; + vpu_buffer->pages = kmalloc_array(vpu_buffer->pagecount, + sizeof(*vpu_buffer->pages), + GFP_KERNEL); + if (!vpu_buffer->pages) { + dmabuf = ERR_PTR(-ENOMEM); + goto err0; + } + + for (pg = 0; pg < vpu_buffer->pagecount; pg++) { + /* + * Avoid trying to allocate memory if the process + * has been killed by by SIGKILL + */ + if (fatal_signal_pending(current)) + goto err1; + + vpu_buffer->pages[pg] = vpu_heap_alloc_page(vpu_heap); + if (!vpu_buffer->pages[pg]) + goto err1; + } + + /* create the dmabuf */ + dmabuf = vpu_heap_export_dmabuf(vpu_buffer, fd_flags); + if (IS_ERR(dmabuf)) + goto err1; + + vpu_buffer->dmabuf = dmabuf; + + ret = dma_buf_fd(dmabuf, fd_flags); + if (ret < 0) { + dma_buf_put(dmabuf); + /* just return, as put will call release and that will free */ + return ERR_PTR(ret); + } + + return dmabuf; + +err1: + while (pg > 0) + vpu_heap_free_page(vpu_heap, vpu_buffer->pages[--pg]); + kfree(vpu_buffer->pages); +err0: + kfree(vpu_buffer); + + return dmabuf; +} + +static const struct dma_heap_ops vpu_heap_ops = { + .allocate = vpu_heap_allocate, +}; + +static int vpu_heap_create_single(const char *name) +{ + struct dma_heap_export_info exp_info; + struct vpu_heap *vpu_heap; + struct reserved_mem *rmem; + struct device_node np; + unsigned int npages; + + np.full_name = name; + np.name = name; + rmem = of_reserved_mem_lookup(&np); + if (!rmem) { + pr_err("of_reserved_mem_lookup() returned NULL\n"); + return -EINVAL; + } + + if (rmem->base == 0 || rmem->size == 0) { + pr_err("%s base or size is not correct\n", name); + return -EINVAL; + } + + vpu_heap = kzalloc(sizeof(*vpu_heap), GFP_KERNEL); + if (!vpu_heap) + return -ENOMEM; + + npages = DIV_ROUND_UP(rmem->size, PAGE_SIZE); + vpu_heap->page_map = kcalloc(BITS_TO_LONGS(npages), + sizeof(*vpu_heap->page_map), + GFP_KERNEL); + if (!vpu_heap->page_map) { + kfree(vpu_heap); + return -ENOMEM; + } + + vpu_heap->base = rmem->base; + vpu_heap->size = rmem->size; + vpu_heap->npages = npages; + mutex_init(&vpu_heap->page_map_lock); + + exp_info.name = name; + exp_info.ops = &vpu_heap_ops; + exp_info.priv = vpu_heap; + vpu_heap->heap = dma_heap_add(&exp_info); + if (IS_ERR(vpu_heap->heap)) { + int ret = PTR_ERR(vpu_heap->heap); + + kfree(vpu_heap->page_map); + kfree(vpu_heap); + return ret; + } + + return 0; +} + +static int vpu_heap_create(void) +{ + int ret = 0; + + ret = vpu_heap_create_single("vpu_private"); + if (ret) + return ret; + + ret = vpu_heap_create_single("vpu_protected"); + if (ret) + return ret; + + ret = vpu_heap_create_single("media_protected"); + if (ret) + return ret; + + return 0; +} +module_init(vpu_heap_create); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/dma-buf/sw_sync.c b/drivers/dma-buf/sw_sync.c index f0a35277fd84..e4e0f690f8c3 100644 --- a/drivers/dma-buf/sw_sync.c +++ b/drivers/dma-buf/sw_sync.c @@ -15,7 +15,9 @@ #define CREATE_TRACE_POINTS #include "sync_trace.h" - +#ifdef CONFIG_PLAT_FDLEAK +#include +#endif /* * SW SYNC validation framework * @@ -363,6 +365,10 @@ static long sw_sync_ioctl_create_fence(struct sync_timeline *obj, fd_install(fd, sync_file->file); +#ifdef CONFIG_PLAT_FDLEAK + fdleak_report(FDLEAK_WP_SYNCFENCE, 0); +#endif + return 0; err: diff --git a/drivers/dma-buf/sync_file.c b/drivers/dma-buf/sync_file.c index 2e9a316c596a..62f52b41f6e7 100644 --- a/drivers/dma-buf/sync_file.c +++ b/drivers/dma-buf/sync_file.c @@ -17,6 +17,9 @@ #include #include #include +#ifdef CONFIG_PLAT_FDLEAK +#include +#endif static const struct file_operations sync_file_fops; @@ -185,6 +188,10 @@ static int sync_file_release(struct inode *inode, struct file *file) dma_fence_put(sync_file->fence); kfree(sync_file); +#ifdef CONFIG_PLAT_FDLEAK + fdleak_report(FDLEAK_WP_SYNCFENCE, 1); +#endif + return 0; } diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig index e36506471a4f..9d3ce5248772 100644 --- a/drivers/dma/Kconfig +++ b/drivers/dma/Kconfig @@ -733,6 +733,13 @@ config XILINX_ZYNQMP_DPDMA driver provides the dmaengine required by the DisplayPort subsystem display driver. +config ARM_DMA350 + tristate "ARM DMA350 support" + select DMA_ENGINE + select DMA_VIRTUAL_CHANNELS + help + Enable support for ARM DMA350 controller. + # driver files source "drivers/dma/bestcomm/Kconfig" diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile index 83553a97a010..cdbc448e1630 100644 --- a/drivers/dma/Makefile +++ b/drivers/dma/Makefile @@ -82,6 +82,7 @@ obj-$(CONFIG_XGENE_DMA) += xgene-dma.o obj-$(CONFIG_ST_FDMA) += st_fdma.o obj-$(CONFIG_FSL_DPAA2_QDMA) += fsl-dpaa2-qdma/ obj-$(CONFIG_INTEL_LDMA) += lgm/ +obj-$(CONFIG_ARM_DMA350) += arm_dma350.o obj-y += mediatek/ obj-y += qcom/ diff --git a/drivers/dma/arm_dma350.c b/drivers/dma/arm_dma350.c new file mode 100755 index 000000000000..e4bcefdd23ca --- /dev/null +++ b/drivers/dma/arm_dma350.c @@ -0,0 +1,1529 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + *Driver for ARM DMA-350 controller + * + *Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "dma350_ch_drv.h" +#include "virt-dma.h" + +#define DRIVER_NAME "arm-dma350" +#define DMA_ALIGN 4 +#define DMA_MAX_SIZE (0xFFFFFFFF) +#define MAX_BURST_LEN 0xF +#define LLI_BLOCK_SIZE (4 * PAGE_SIZE) +#define CHANNEL_IDX(id) (0x1000 + id * 0x100) +#define CMD_LINK_LEN (512) +#define MAX_DESC_NUM 16 +#define MAX_CHAN_NUM 8 +#define RCSU_OFFSET 0x10000 +#define ARM_DMA350_PM_TIMEOUT_MS 500 + +#define AUDSS_DMAC_INFO_AP_IRQ 0x54 +#define AUDSS_OFFSET (0x30000000-0xc0000000) +#define DMA350_DYNAMIC_CH(ch) (ch == 0xFF) + +enum arm_dma350_burst_width_t { + DMA350_DMA_WIDTH_8BIT = 0, + DMA350_DMA_WIDTH_16BIT = 1, + DMA350_DMA_WIDTH_32BIT = 2, + DMA350_DMA_WIDTH_64BIT = 3 +}; + +struct dma350_desc_hw { + dma_addr_t saddr; + dma_addr_t daddr; + u32 x_len; + u32 dest_addr_inc; + u32 src_addr_inc; + u32 trig_sel; + u32 burst_size; +} __aligned(32); + +struct arm_dma350_desc_sw { + struct virt_dma_desc vd; + dma_addr_t desc_hw_lli; + size_t desc_num; + size_t size; + struct dma350_desc_hw *desc_hw; +}; + +struct arm_dma350_phy; + +struct arm_dma350_chan { + struct dma_slave_config slave_cfg; + u32 id; /* Request phy chan id */ + u32 req_line; + u32 priority; + u32 cyclic; + u32 transize; + bool is_dynamic; + struct virt_dma_chan vc; + struct arm_dma350_phy *phy; + struct list_head node; + dma_addr_t dev_addr; + enum dma_status status; + bool is_used_runtime; +}; + +struct arm_dma350_phy { + u32 idx; + void __iomem *base; + struct arm_dma350_chan *vchan; + struct arm_dma350_desc_sw *ds_run; + struct arm_dma350_desc_sw *ds_done; +}; + +struct host_remote_map { + u32 reg_host_addr; + u32 reg_remote_addr; + u32 ram_host_addr; + u32 ram_remote_addr; +}; + +struct arm_dma350_drvdata { + bool is_exist_pause; +}; + +struct arm_dma350_dev { + struct dma_device slave; + void __iomem *base; + spinlock_t lock; /* lock for ch and phy */ + struct list_head chan_pending; + struct arm_dma350_phy *phy; + struct arm_dma350_chan *chans; + struct clk *clk; + struct dma_pool *pool; + u32 max_channels; + u32 max_requests; + int irq; + struct host_remote_map map; + struct regmap *regmap; + struct arm_dma350_drvdata *drvdata; + struct reset_control *dma_reset; + bool is_clk_enable_atomic; +}; + +#define to_arm_dma350(dmadev) container_of(dmadev, struct arm_dma350_dev, slave) + +static u32 dmachan[MAX_CHAN_NUM]; +static u32 desnum[MAX_CHAN_NUM]; + +struct dma350_cmdlink_gencfg_t *cmdlink_cfg[MAX_CHAN_NUM]; +static u32 *cmd0[MAX_CHAN_NUM]; + +static dma_addr_t phy_cmd0[MAX_CHAN_NUM]; + +static atomic_t vaild_chan_id[MAX_CHAN_NUM]; + +static struct arm_dma350_chan *to_dma350_chan(struct dma_chan *chan) +{ + return container_of(chan, struct arm_dma350_chan, vc.chan); +} + +static u32 *dma350_cmdlink_generate(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + u32 *buffer, u32 *bit) +{ + u32 *cfg; + u32 header_sel; + + cfg = (u32 *) &cmdlink_cfg->cfg; + *(buffer) = cmdlink_cfg->header; + buffer++; + /* + *Note: REGCLEAR (Bit 0) has no associated field and Bit 1 is reserved, + *cfg starts from Bit 2 + */ + for (header_sel = (0x1UL << 2); header_sel; header_sel <<= 1) { + if (cmdlink_cfg->header & header_sel) { + (*bit)++; + *(buffer) = *(cfg); + buffer++; + cfg++; + } else { + cfg++; + } + } + return buffer; +} + +static void dma350_cmdlink_init(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + static const struct dma350_cmdlink_gencfg_t default_cmdlink = { + .header = 0, + .cfg = {.intren = DMA350_CH_INTREN_RESET_VALUE, + .ctrl = DMA350_CH_CTRL_RESET_VALUE, + .srcaddr = 0, + .srcaddrhi = 0, + .desaddr = 0, + .desaddrhi = 0, + .xsize = 0, + .xsizehi = 0, + .srctranscfg = DMA350_CH_SRCTRANSCFG_RESET_VALUE, + .destranscfg = DMA350_CH_DESTRANSCFG_RESET_VALUE, + .xaddrinc = 0, + .yaddrstride = 0, + .fillval = 0, + .ysize = 0, + .tmpltcfg = 0, + .srctmplt = 0, + .destmplt = 0, + .srctrigincfg = 0, + .destrigincfg = 0, + .trigoutcfg = 0, + .gpoen0 = 0, + .reserved0 = 0, + .gpoval0 = 0, + .reserved1 = 0, + .streamintcfg = 0, + .reserved2 = 0, + .linkattr = 0, + .autocfg = DMA350_CH_AUTOCFG_RESET_VALUE, + .linkaddr = DMA350_CH_LINKADDR_RESET_VALUE, + .linkaddrhi = 0 } + }; + *cmdlink_cfg = default_cmdlink; +} + +static void arm_dma350_terminate_chan(struct arm_dma350_phy *phy) +{ + dma350_ch_cmd(phy->base + DMA350_REG_CMD, DMA350_CH_CMD_STOPCMD); +} + +static void arm_dma350_nonsec_intren(struct arm_dma350_dev *d) +{ + writel_relaxed(INTREN_ANYCHINTR_ENABLE, d->base + DMA350_REG_CHINTRSTATUS0 + DMA350_NONSSEC_CTRL); +} + +static void arm_dma350_clear_chan(struct arm_dma350_phy *phy) +{ + dma350_ch_cmd(phy->base + DMA350_REG_CMD, DMA350_CH_CMD_CLEARCMD); +} + +static void arm_dma350_set_xsize(struct arm_dma350_phy *phy, u32 xsize) +{ + u32 val = 0; + + val = ((xsize & 0x0000FFFFUL) << 16U) | (xsize & 0x0000FFFFUL); + writel_relaxed(val, phy->base + DMA350_REG_XSIZE); + val = (xsize & 0xFFFF0000UL) | ((xsize & 0xFFFF0000UL) >> 16U); + writel_relaxed(val, phy->base + DMA350_REG_XSIZEHI); +} + +static void arm_dma350_set_desc(struct arm_dma350_phy *phy, struct dma350_desc_hw *hw) +{ + writel_relaxed(hw->saddr, phy->base + DMA350_REG_SRCADDR); + writel_relaxed(hw->daddr, phy->base + DMA350_REG_DESADDR); + arm_dma350_set_xsize(phy, hw->x_len); + dma350_ch_cmd(phy->base + DMA350_REG_CMD, DMA350_CH_CMD_ENABLECMD); +} + +static void arm_dma350_init_state(struct arm_dma350_phy *phy) +{ + dma350_ch_enable_intr(phy->base + DMA350_REG_INTREN, + DMA350_CH_INTREN_DONE | DMA350_CH_INTREN_ERR | + DMA350_CH_INTREN_DISABLED | + DMA350_CH_INTREN_STOPPED); +} + +static int arm_dma350_start_txd(struct arm_dma350_chan *c) +{ + struct virt_dma_desc *vd = vchan_next_desc(&c->vc); + struct dma_slave_config *cfg = &c->slave_cfg; + u32 timeout = 0; + + if (!c->phy) + return -EAGAIN; + if (vd) { + struct arm_dma350_desc_sw *ds = container_of(vd, struct arm_dma350_desc_sw, vd); + /* + * fetch and remove request from vc->desc_issued + * so vc->desc_issued only contains desc pending + */ + if (!c->cyclic) + list_del(&ds->vd.node); + + c->phy->ds_run = ds; + c->phy->ds_done = NULL; + + /* start dma */ + if (c->cyclic) { + dma350_ch_set_xsize32(c->phy->base + DMA350_REG_XSIZE, 0, 0); + writel_relaxed(0, c->phy->base + DMA350_REG_INTREN); + dma350_ch_cmd(c->phy->base + DMA350_REG_CMD, DMA350_CH_CMD_ENABLECMD); + dma350_ch_set_linkaddr32(c->phy->base + DMA350_REG_LINKADDR, + (u32)(phy_cmd0[c->id] + AUDSS_OFFSET)); + dma350_ch_enable_linkaddr(c->phy->base + DMA350_REG_LINKADDR); + dma350_ch_cmd(c->phy->base + DMA350_REG_CMD, DMA350_CH_CMD_ENABLECMD); + if (cfg->direction == DMA_MEM_TO_DEV) { + timeout = 0; + while ((!(readl_relaxed(c->phy->base + DMA350_REG_STATUS) & + DMA350_CH_STATUS_STAT_DESTRIGINWAIT_Msk))) { + udelay(10); + timeout++; + if (timeout > 10) { + pr_info("channel %d timeout\n", c->id); + break; + } + } + } + if (cfg->direction == DMA_DEV_TO_MEM) { + timeout = 0; + while ((!(readl_relaxed(c->phy->base + DMA350_REG_STATUS) & + DMA350_CH_STATUS_STAT_SRCTRIGINWAIT_Msk))) { + udelay(10); + timeout++; + if (timeout > 10) { + pr_info("channel %d timeout\n", c->id); + break; + } + } + } + } else { + arm_dma350_set_desc(c->phy, ds->desc_hw); + } + return 0; + } + c->phy->ds_done = NULL; + c->phy->ds_run = NULL; + + return -EAGAIN; +} + +static void arm_dma350_task(struct arm_dma350_dev *d) +{ + struct arm_dma350_phy *p; + struct arm_dma350_chan *c; + unsigned int pch, pch_alloc = 0; + unsigned long flags; + + /* check new channel request in d->chan_pending */ + spin_lock_irqsave(&d->lock, flags); + while (!list_empty(&d->chan_pending)) { + c = list_first_entry(&d->chan_pending, + struct arm_dma350_chan, node); + p = &d->phy[c->id]; + /* remove from d->chan_pending */ + list_del_init(&c->node); + pch_alloc |= 1 << c->id; + /* Mark this channel allocated */ + p->vchan = c; + c->phy = p; + } + spin_unlock_irqrestore(&d->lock, flags); + for (pch = 0; pch < d->max_channels; pch++) { + + if (pch_alloc & (1 << pch)) { + p = &d->phy[pch]; + c = p->vchan; + if (c) { + spin_lock_irqsave(&c->vc.lock, flags); + arm_dma350_start_txd(c); + spin_unlock_irqrestore(&c->vc.lock, flags); + } + } + } +} + +static u32 arm_dma_ch_getstatus(struct arm_dma350_dev *d, u32 ch_id) +{ + return readl_relaxed(d->base + DMA350_REG_STATUS + CHANNEL_IDX(ch_id)); +} + +static u32 arm_dma_ch_clrstatus(struct arm_dma350_dev *d, u32 ch_id) +{ + u32 val = arm_dma_ch_getstatus(d, ch_id); + + val &= DMA350_CH_INTREN_DONE | DMA350_CH_INTREN_ERR | DMA350_CH_INTREN_DISABLED | DMA350_CH_INTREN_STOPPED; + writel_relaxed(val << 16, d->base + DMA350_REG_STATUS + CHANNEL_IDX(ch_id)); + return 0; +} + +static irqreturn_t arm_dma350_int_handler(int irq, void *dev_id) +{ + struct arm_dma350_dev *d = (struct arm_dma350_dev *)dev_id; + struct arm_dma350_phy *p; + struct arm_dma350_chan *c; + u32 chstatus = 0, ch_idx = 0; + + while (ch_idx < MAX_CHAN_NUM) { + chstatus = arm_dma_ch_getstatus(d, ch_idx); + if (chstatus == 0) { + ch_idx++; + continue; + } + if (chstatus & DMA350_CH_STATUS_INTR_ERR) { + writel_relaxed(DMA350_CH_STATUS_STAT_ERR, d->base + DMA350_REG_STATUS + CHANNEL_IDX(ch_idx)); + pr_err("transfer error!!!\n"); + } + if ((chstatus & DMA350_CH_STATUS_INTR_DONE) == 0) { + ch_idx++; + continue; + } + + arm_dma_ch_clrstatus(d, ch_idx); + p = &d->phy[ch_idx]; + if (p == NULL) { + ch_idx++; + continue; + } + c = p->vchan; + if (c) { + spin_lock(&c->vc.lock); + if (c->cyclic) { + desnum[ch_idx]++; + if (dmachan[ch_idx] == (desnum[ch_idx] - 1)) + desnum[ch_idx] = 1; + if (p->ds_run != NULL) + vchan_cyclic_callback(&p->ds_run->vd); + } else { + if (p->ds_run != NULL) { + vchan_cookie_complete(&p->ds_run->vd); + p->ds_done = p->ds_run; + p->ds_run = NULL; + } + } + spin_unlock(&c->vc.lock); + } + ch_idx++; + } + return IRQ_HANDLED; +} + +static void arm_dma350_free_chan_resources(struct dma_chan *chan) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + unsigned long flags; + + spin_lock_irqsave(&d->lock, flags); + list_del_init(&c->node); + spin_unlock_irqrestore(&d->lock, flags); + + vchan_free_chan_resources(&c->vc); +} + +static u32 get_bytes_in_phy_channel(struct arm_dma350_phy *phy) +{ + u32 witdth; + u32 bytes; + u32 byteslo, byteshi; + + byteslo = readl_relaxed(phy->base + DMA350_REG_XSIZE) & 0xFFFF; + byteshi = (readl_relaxed(phy->base + DMA350_REG_XSIZE) & 0xFFFF0000) >> 16; + if (byteslo > byteshi) + bytes = byteshi; + else + bytes = byteslo; + witdth = readl_relaxed(phy->base + DMA350_REG_CTRL) & DMA350_CH_CTRL_TRANSIZE_Msk; + switch (witdth) { + case DMA350_DMA_WIDTH_8BIT: + break; + case DMA350_DMA_WIDTH_16BIT: + bytes *= 2; + break; + case DMA350_DMA_WIDTH_32BIT: + bytes *= 4; + break; + } + return bytes; +} + +static enum dma_status arm_dma350_tx_status(struct dma_chan *chan, + dma_cookie_t cookie, + struct dma_tx_state *state) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_phy *p; + struct virt_dma_desc *vd; + unsigned long flags; + enum dma_status ret; + size_t bytes = 0; + size_t residue = 0; + + ret = dma_cookie_status(&c->vc.chan, cookie, state); + + if (ret == DMA_COMPLETE || !state) + return ret; + + spin_lock_irqsave(&c->vc.lock, flags); + p = c->phy; + ret = c->status; + + /* + * If the cookie is on our issue queue, then the residue is + * its total size. + */ + if (c->cyclic) { + vd = vchan_find_desc(&c->vc, cookie); + if (vd) { + bytes = container_of(vd, struct arm_dma350_desc_sw, vd)->size; + residue = bytes - bytes / dmachan[c->id] * desnum[c->id]; + } + } else { + residue = get_bytes_in_phy_channel(p); + } + spin_unlock_irqrestore(&c->vc.lock, flags); + dma_set_residue(state, residue); + return ret; +} + +static void arm_dma350_issue_pending(struct dma_chan *chan) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + unsigned long flags; + int issue = 0; + + spin_lock_irqsave(&c->vc.lock, flags); + /* add request to vc->desc_issued */ + if (vchan_issue_pending(&c->vc)) { + spin_lock(&d->lock); + if (list_empty(&c->node)) { + /* if new channel, add chan_pending */ + list_add_tail(&c->node, &d->chan_pending); + issue = 1; + } + spin_unlock(&d->lock); + } else { + dev_info(d->slave.dev, "nothing to issue\n"); + } + spin_unlock_irqrestore(&c->vc.lock, flags); + if (issue) + arm_dma350_task(d); +} + +static void arm_dma350_fill_desc(struct arm_dma350_desc_sw *ds, dma_addr_t dst, + dma_addr_t src, size_t len, u32 num) +{ + ds->desc_hw[num].saddr = src; + ds->desc_hw[num].daddr = dst; + ds->desc_hw[num].x_len = len; +} + +static struct arm_dma350_desc_sw *arm_dma350_alloc_desc_resource(int num, + struct dma_chan *chan) +{ + struct arm_dma350_desc_sw *ds; + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + int lli_limit = LLI_BLOCK_SIZE / sizeof(struct dma350_desc_hw); + + if (num > lli_limit) { + dev_err(chan->device->dev, "sg num %d exceed max %d\n", num, lli_limit); + return NULL; + } + ds = kzalloc(sizeof(*ds), GFP_ATOMIC); + if (!ds) + return NULL; + + ds->desc_hw = dma_pool_zalloc(d->pool, GFP_ATOMIC, &ds->desc_hw_lli); + if (!ds->desc_hw) { + dev_err(chan->device->dev, "dma alloc fail\n"); + kfree(ds); + return NULL; + } + ds->desc_num = num; + return ds; +} + +static int arm_dma350_pre_config_sg(struct arm_dma350_chan *c, enum dma_transfer_direction dir) +{ + + struct arm_dma350_dev *dev = to_arm_dma350(c->vc.chan.device); + struct arm_dma350_phy *p = &dev->phy[c->id]; + struct dma_slave_config *cfg = &c->slave_cfg; + u32 maxburst = 0, ret = 0; + + if (!c->is_used_runtime) { + ret = pm_runtime_resume_and_get(dev->slave.dev); + if (!ret) { + c->is_used_runtime = true; + } else { + dev_err(dev->slave.dev, "%s, pm get err, %d, c->id = %d\n", + __func__, ret, c->id); + return ret; + } + } + + arm_dma350_nonsec_intren(dev); + dma350_ch_set_xtype(p->base + DMA350_REG_CTRL, DMA350_CH_XTYPE_CONTINUE); + + switch (dir) { + case DMA_MEM_TO_DEV: + dma350_ch_enable_intr(p->base + DMA350_REG_INTREN, DMA350_CH_INTREN_DONE | DMA350_CH_INTREN_ERR); + c->dev_addr = cfg->dst_addr - RCSU_OFFSET; + c->transize = cfg->dst_addr_width; + /* dst len is calculated from src width, len and dst width. + * We need make sure dst len not exceed MAX LEN. + * Trailing single transaction that does not fill a full + * burst also require identical src/dst data width. + */ + maxburst = cfg->dst_maxburst - 1; + maxburst = maxburst < MAX_BURST_LEN ? maxburst : MAX_BURST_LEN; + dma350_ch_set_desmaxburstlen(p->base + DMA350_REG_DESTRANSCFG, maxburst); + dma350_ch_set_transize(p->base + DMA350_REG_CTRL, ffs(cfg->dst_addr_width) - 1); + dma350_ch_enable_destrigin(p->base + DMA350_REG_CTRL); + dma350_ch_src_memattr(p->base + DMA350_REG_SRCTRANSCFG, 4, 4); + dma350_ch_des_memattr(p->base + DMA350_REG_DESTRANSCFG, 0, 0); + dma350_ch_set_destrigintype(p->base + DMA350_REG_DESTRIGINCFG, DMA350_CH_DESTRIGINTYPE_HW); + dma350_ch_set_destriginmode(p->base + DMA350_REG_DESTRIGINCFG, + DMA350_CH_DESTRIGINMODE_PERIPH_FLOW_CTRL); + dma350_ch_set_destriginsel(p->base + DMA350_REG_DESTRIGINCFG, c->req_line); + dma350_ch_set_xaddr_inc(p->base + DMA350_REG_XADDRINC, 1, 0); + + break; + case DMA_DEV_TO_MEM: + dma350_ch_enable_intr(p->base + DMA350_REG_INTREN, DMA350_CH_INTREN_DONE | DMA350_CH_INTREN_ERR); + c->dev_addr = cfg->src_addr - RCSU_OFFSET; + c->transize = cfg->src_addr_width; + maxburst = cfg->src_maxburst - 1; + maxburst = maxburst < MAX_BURST_LEN ? maxburst : MAX_BURST_LEN; + dma350_ch_set_srcmaxburstlen(p->base + DMA350_REG_DESTRANSCFG, maxburst); + dma350_ch_set_transize(p->base + DMA350_REG_CTRL, ffs(cfg->src_addr_width) - 1); + dma350_ch_enable_srctrigin(p->base + DMA350_REG_CTRL); + + dma350_ch_src_memattr(p->base + DMA350_REG_SRCTRANSCFG, 0, 0); + + /*set des attribute to device memory,to fix the SOCHW-1449 bug */ + dma350_ch_des_memattr(p->base + DMA350_REG_DESTRANSCFG, 0, 0); + dma350_ch_set_srctrigintype(p->base + DMA350_REG_SRCTRIGINCFG, DMA350_CH_SRCTRIGINTYPE_HW); + dma350_ch_set_srctriginmode(p->base + DMA350_REG_SRCTRIGINCFG, + DMA350_CH_SRCTRIGINMODE_PERIPH_FLOW_CTRL); + dma350_ch_set_srctriginsel(p->base + DMA350_REG_SRCTRIGINCFG, c->req_line); + dma350_ch_set_xaddr_inc(p->base + DMA350_REG_XADDRINC, 0, 1); + break; + default: + return -EINVAL; + } + + return 0; +} + +static int arm_dma350_pre_config_cyclic(struct arm_dma350_chan *c, enum dma_transfer_direction dir) +{ + + struct arm_dma350_dev *dev = to_arm_dma350(c->vc.chan.device); + struct arm_dma350_phy *p = &dev->phy[c->id]; + struct dma_slave_config *cfg = &c->slave_cfg; + u32 maxburst = 0; + + if (dev->regmap) + regmap_update_bits(dev->regmap, AUDSS_DMAC_INFO_AP_IRQ, + 1 << c->id, 1 << c->id); + + arm_dma350_clear_chan(p); + dma350_ch_set_xtype(p->base + DMA350_REG_CTRL, DMA350_CH_XTYPE_CONTINUE); + dma350_ch_set_chprio(p->base + DMA350_REG_CTRL, c->priority); + + /* Setup first */ + dma350_cmdlink_init(&cmdlink_cfg[c->id][0]); + /* Clear DMA registers upon loading this command */ + dma350_cmdlink_set_regclear(&cmdlink_cfg[c->id][0]); + dma350_cmdlink_set_xtype(&cmdlink_cfg[c->id][0], DMA350_CH_XTYPE_CONTINUE); + switch (dir) { + case DMA_MEM_TO_DEV: + c->dev_addr = cfg->dst_addr; + c->transize = cfg->dst_addr_width; + + /* dst len is calculated from src width, len and dst width. + * We need make sure dst len not exceed MAX LEN. + * Trailing single transaction that does not fill a full + * burst also require identical src/dst data width. + */ + maxburst = cfg->dst_maxburst - 1; + maxburst = maxburst < MAX_BURST_LEN ? maxburst : MAX_BURST_LEN; + dma350_ch_set_transize(p->base + DMA350_REG_CTRL, ffs(cfg->dst_addr_width) - 1); + + /*generate cmd link list*/ + dma350_cmdlink_set_desaddr32(&cmdlink_cfg[c->id][0], c->dev_addr); + dma350_cmdlink_set_transize(&cmdlink_cfg[c->id][0], ffs(cfg->dst_addr_width) - 1); + dma350_cmdlink_set_srcmemattrhi(&cmdlink_cfg[c->id][0], 4); + dma350_cmdlink_set_srcmemattrlo(&cmdlink_cfg[c->id][0], 4); + dma350_cmdlink_set_desmemattrhi(&cmdlink_cfg[c->id][0], 0); + dma350_cmdlink_set_desmemattrlo(&cmdlink_cfg[c->id][0], 0); + dma350_cmdlink_set_desmaxburstlen(&cmdlink_cfg[c->id][0], maxburst); + dma350_cmdlink_enable_intr(&cmdlink_cfg[c->id][0], DMA350_CH_INTREN_DONE | + DMA350_CH_INTREN_ERR | DMA350_CH_INTREN_DISABLED | DMA350_CH_INTREN_STOPPED); + dma350_cmdlink_enable_destrigin(&cmdlink_cfg[c->id][0]); + dma350_cmdlink_set_destriginmode(&cmdlink_cfg[c->id][0], DMA350_CH_DESTRIGINMODE_PERIPH_FLOW_CTRL); + dma350_cmdlink_set_destrigintype(&cmdlink_cfg[c->id][0], DMA350_CH_DESTRIGINTYPE_HW); + dma350_cmdlink_set_xaddrinc(&cmdlink_cfg[c->id][0], 1, 0); + dma350_cmdlink_set_destriginsel(&cmdlink_cfg[c->id][0], c->req_line); + break; + case DMA_DEV_TO_MEM: + c->dev_addr = cfg->src_addr; + c->transize = cfg->src_addr_width; + maxburst = cfg->src_maxburst - 1; + maxburst = maxburst < MAX_BURST_LEN ? maxburst : MAX_BURST_LEN; + dma350_ch_set_transize(p->base + DMA350_REG_CTRL, ffs(cfg->src_addr_width) - 1); + + /*generate cmd link list*/ + dma350_cmdlink_set_srcaddr32(&cmdlink_cfg[c->id][0], c->dev_addr); + dma350_cmdlink_set_transize(&cmdlink_cfg[c->id][0], ffs(cfg->src_addr_width) - 1); + dma350_cmdlink_set_desmemattrhi(&cmdlink_cfg[c->id][0], 4); + dma350_cmdlink_set_desmemattrlo(&cmdlink_cfg[c->id][0], 4); + dma350_cmdlink_set_srcmemattrhi(&cmdlink_cfg[c->id][0], 0); + dma350_cmdlink_set_srcmemattrlo(&cmdlink_cfg[c->id][0], 0); + dma350_cmdlink_set_srcmaxburstlen(&cmdlink_cfg[c->id][0], maxburst); + dma350_cmdlink_enable_intr(&cmdlink_cfg[c->id][0], + DMA350_CH_INTREN_DONE|DMA350_CH_INTREN_ERR | DMA350_CH_INTREN_DISABLED | DMA350_CH_INTREN_STOPPED); + dma350_cmdlink_enable_srctrigin(&cmdlink_cfg[c->id][0]); + dma350_cmdlink_set_srctriginmode(&cmdlink_cfg[c->id][0], DMA350_CH_SRCTRIGINMODE_PERIPH_FLOW_CTRL); + dma350_cmdlink_set_srctrigintype(&cmdlink_cfg[c->id][0], DMA350_CH_SRCTRIGINTYPE_HW); + dma350_cmdlink_set_xaddrinc(&cmdlink_cfg[c->id][0], 0, 1); + dma350_cmdlink_set_srctriginsel(&cmdlink_cfg[c->id][0], c->req_line); + break; + default: + return -EINVAL; + } + + return 0; +} + +static struct dma_async_tx_descriptor *arm_dma350_prep_memcpy(struct dma_chan *chan, + dma_addr_t dst, dma_addr_t src, size_t len, unsigned long flags) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_desc_sw *ds; + struct arm_dma350_dev *dev = to_arm_dma350(c->vc.chan.device); + struct arm_dma350_phy *p; + struct dma_slave_config *cfg = &c->slave_cfg; + size_t copy = 0; + int num = 0, ret = 0; + + c->id = chan->chan_id; + p = &dev->phy[c->id]; + + if (!cfg->src_addr_width) + cfg->src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE; + + if (!len) + return NULL; + + if (!c->is_used_runtime) { + ret = pm_runtime_resume_and_get(dev->slave.dev); + if (!ret) { + c->is_used_runtime = true; + } else { + dev_err(dev->slave.dev, "%s, pm get err, %d, c->id = %d\n", + __func__, ret, c->id); + return NULL; + } + } + + arm_dma350_nonsec_intren(dev); + arm_dma350_init_state(p); + c->dev_addr = cfg->src_addr; + dma350_ch_set_transize(p->base + DMA350_REG_CTRL, ffs(cfg->src_addr_width) - 1); + dma350_ch_src_memattr(p->base + DMA350_REG_SRCTRANSCFG, 4, 4); + dma350_ch_des_memattr(p->base + DMA350_REG_DESTRANSCFG, 4, 4); + dma350_ch_set_xaddr_inc(p->base + DMA350_REG_XADDRINC, 1, 1); + num = DIV_ROUND_UP(len, DMA_MAX_SIZE); + ds = arm_dma350_alloc_desc_resource(num, chan); + if (!ds) + return NULL; + ds->size = len; + num = 0; + do { + copy = min_t(size_t, len, DMA_MAX_SIZE); + arm_dma350_fill_desc(ds, dst, src, copy / cfg->src_addr_width, num++); + + src += copy; + dst += copy; + len -= copy; + } while (len); + + c->cyclic = 0; + return vchan_tx_prep(&c->vc, &ds->vd, flags); +} + +static struct dma_async_tx_descriptor *arm_dma350_prep_slave_sg( + struct dma_chan *chan, struct scatterlist *sgl, unsigned int sglen, + enum dma_transfer_direction dir, unsigned long flags, void *context) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_desc_sw *ds; + size_t len, avail, total = 0; + struct scatterlist *sg; + dma_addr_t addr, src = 0, dst = 0; + int num = sglen, i; + + if (!sgl) + return NULL; + if (arm_dma350_pre_config_sg(c, dir)) + return NULL; + + for_each_sg(sgl, sg, sglen, i) { + avail = sg_dma_len(sg); + + if (avail > DMA_MAX_SIZE) + num += DIV_ROUND_UP(avail, DMA_MAX_SIZE) - 1; + } + ds = arm_dma350_alloc_desc_resource(num, chan); + if (!ds) + return NULL; + c->cyclic = 0; + num = 0; + for_each_sg(sgl, sg, sglen, i) { + addr = sg_dma_address(sg); + avail = sg_dma_len(sg); + total += avail; + do { + + len = min_t(size_t, avail, DMA_MAX_SIZE); + + if (dir == DMA_MEM_TO_DEV) { + src = addr; + dst = c->dev_addr; + } else if (dir == DMA_DEV_TO_MEM) { + src = c->dev_addr; + dst = addr; + } + arm_dma350_fill_desc(ds, dst, src, (len / c->transize), num++); + addr += len; + avail -= len; + } while (avail); + } + ds->size = total; + return vchan_tx_prep(&c->vc, &ds->vd, flags); +} + +static int arm_dma350_find_idle_channel(struct dma_chan *chan) +{ + u32 ch_idx = 0; + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + + for (ch_idx = 0; ch_idx < MAX_CHAN_NUM; ch_idx++) { + if (atomic_read(&vaild_chan_id[ch_idx]) == 1) + continue; + + if (atomic_cmpxchg(&vaild_chan_id[ch_idx], 0, 1) == 0) { + dev_info(d->slave.dev, "use dynamic channel-%d \n", ch_idx); + c->id = ch_idx; + break; + } + } + + if (c->id >= MAX_CHAN_NUM) { + dev_err(d->slave.dev, "there is no idle channel to alloc\n"); + return -EINVAL; + } + + return 0; +} + +static int arm_dma350_cmdlink_cfg_create(u32 chan_id, u32 periods) +{ + if (chan_id < 0 || chan_id >= MAX_CHAN_NUM) { + pr_err("Invalid channel ID: %d\n", chan_id); + return -EINVAL; + } + + cmdlink_cfg[chan_id] = kzalloc( + sizeof(struct dma350_cmdlink_gencfg_t) * periods, GFP_ATOMIC); + if (!cmdlink_cfg[chan_id]) { + pr_err("Failed to allocate periods for channel %d\n", chan_id); + return -ENOMEM; + } + + pr_info("Channel %d initialized with %d periods\n", chan_id, periods); + return 0; +} + +static void arm_dma350_cmdlink_cfg_destory(u32 chan_id) +{ + if (chan_id < 0 || chan_id >= MAX_CHAN_NUM || !cmdlink_cfg[chan_id]) + return; + + kfree(cmdlink_cfg[chan_id]); + cmdlink_cfg[chan_id] = NULL; +} + +static struct dma_async_tx_descriptor *arm_dma350_prep_dma_cyclic(struct dma_chan *chan, dma_addr_t dma_addr, + size_t buf_len, size_t period_len, enum dma_transfer_direction dir, unsigned long flags) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + struct arm_dma350_desc_sw *ds; + dma_addr_t src = 0, dst = 0; + size_t num_periods = buf_len / period_len; + size_t buf = 0, cmd_num = 0; + u32 offset = 0, bit = 0; + int ret = 0; + + if (period_len > DMA_MAX_SIZE) { + dev_err(chan->device->dev, "maximum period size exceeded\n"); + return NULL; + } + + if (!c->is_used_runtime) { + ret = pm_runtime_resume_and_get(d->slave.dev); + if (!ret) { + c->is_used_runtime = true; + } else { + dev_err(d->slave.dev, "%s, pm get err, %d, c->id = %d\n", + __func__, ret, c->id); + return NULL; + } + } + + /*if channel id is 0xFF,it means we should use dynamic channel*/ + if ((DMA350_DYNAMIC_CH(c->id)) && (arm_dma350_find_idle_channel(chan))) { + pm_runtime_put_noidle(d->slave.dev); + return NULL; + } + + ret = arm_dma350_cmdlink_cfg_create(c->id, num_periods); + if (ret) { + pr_err("cmdlink_cfg create failed\n"); + return NULL; + } + + if (arm_dma350_pre_config_cyclic(c, dir)) { + pm_runtime_put_noidle(d->slave.dev); + return NULL; + } + + ds = arm_dma350_alloc_desc_resource(num_periods, chan); + if (!ds) { + pm_runtime_put_noidle(d->slave.dev); + return NULL; + } + + c->cyclic = 1; + while (buf < buf_len) { + if (cmd_num > 0) + dma350_cmdlink_init(&cmdlink_cfg[c->id][cmd_num]); + if (dir == DMA_MEM_TO_DEV) { + src = dma_addr; + + if (d->map.ram_host_addr && d->map.ram_remote_addr) { + offset = src - d->map.ram_host_addr; + src = d->map.ram_remote_addr + offset; + } + + dst = c->dev_addr; + if (d->map.reg_host_addr && d->map.reg_remote_addr) { + offset = dst - d->map.reg_host_addr; + dst = d->map.reg_remote_addr + offset; + } + + } else if (dir == DMA_DEV_TO_MEM) { + src = c->dev_addr; + if (d->map.reg_host_addr && d->map.reg_remote_addr) { + offset = src - d->map.reg_host_addr; + src = d->map.reg_remote_addr + offset; + } + + dst = dma_addr; + if (d->map.ram_host_addr && d->map.ram_remote_addr) { + offset = dst - d->map.ram_host_addr; + dst = d->map.ram_remote_addr + offset; + } + + } + dma_addr += period_len; + buf += period_len; + + dma350_cmdlink_set_desaddr32(&cmdlink_cfg[c->id][cmd_num], dst); + dma350_cmdlink_set_srcaddr32(&cmdlink_cfg[c->id][cmd_num], src); + dma350_cmdlink_enable_linkaddr(&cmdlink_cfg[c->id][cmd_num]); + dma350_cmdlink_set_xsize32(&cmdlink_cfg[c->id][cmd_num], + (period_len / c->transize), + (period_len / c->transize)); + cmd_num++; + } + cmd0[c->id] = dma_alloc_coherent(chan->device->dev, CMD_LINK_LEN * sizeof(u32), &phy_cmd0[c->id], GFP_ATOMIC); + cmd_num = 0; + while (cmd_num < num_periods) { + /* cmd linklist prepare*/ + dma350_cmdlink_generate(&cmdlink_cfg[c->id][cmd_num], cmd0[c->id] + cmd_num+bit, &bit); + /* + *if not the last command,then fill the next command address to the linkaddr domain + *if the last command, then fill the next command address with the first linkaddr + */ + if (cmd_num == (num_periods - 1)) + *(cmd0[c->id] + bit + cmd_num) = (u32)(phy_cmd0[c->id] + AUDSS_OFFSET) + + DMA350_CH_LINKADDR_LINKADDREN; + else + *(cmd0[c->id] + bit + cmd_num) = (u32)(phy_cmd0[c->id] + (bit + cmd_num + 1) * 4 + + AUDSS_OFFSET) + DMA350_CH_LINKADDR_LINKADDREN; + cmd_num++; + } + dmachan[c->id] = num_periods; + ds->size = buf_len; + + return vchan_tx_prep(&c->vc, &ds->vd, flags); +} + +static int arm_dma350_config(struct dma_chan *chan, + struct dma_slave_config *cfg) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + + if (!cfg) + return -EINVAL; + + memcpy(&c->slave_cfg, cfg, sizeof(*cfg)); + + return 0; +} + +static int arm_dma350_terminate_all(struct dma_chan *chan) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + struct arm_dma350_phy *p = NULL; + struct dma_slave_config *cfg = &c->slave_cfg; + int ret; + unsigned long flags; + LIST_HEAD(head); + + dev_dbg(d->slave.dev, "channel-%d terminate all\n", c->id); + + /* cannot find an idle channel when use channel dynamicly allocate */ + if (c->id >= d->max_channels) { + dev_warn(d->slave.dev, "invalid c->id, c->id = %d\n", c->id); + return 0; + } + + p = &d->phy[c->id]; + + desnum[c->id] = 0; + + /* Prevent this channel being scheduled */ + spin_lock(&d->lock); + list_del_init(&c->node); + spin_unlock(&d->lock); + + /* Clear the tx descriptor lists */ + spin_lock_irqsave(&c->vc.lock, flags); + vchan_get_all_descriptors(&c->vc, &head); + if (p) { + /* vchan is assigned to a pchan - stop the channel */ + arm_dma350_terminate_chan(p); + dma350_ch_disable_linkaddr(p->base + DMA350_REG_LINKADDR); + arm_dma350_clear_chan(p); + if ((cfg->direction == DMA_DEV_TO_MEM) && !c->cyclic && p->ds_run) + vchan_vdesc_fini(&p->ds_run->vd); + c->phy = NULL; + if (c->cyclic) + c->vc.cyclic = NULL; + p->vchan = NULL; + if (p->ds_run) { + vchan_terminate_vdesc(&p->ds_run->vd); + p->ds_run = NULL; + } + p->ds_done = NULL; + } + spin_unlock_irqrestore(&c->vc.lock, flags); + + if (c->cyclic) { + dma_free_coherent(chan->device->dev, CMD_LINK_LEN * sizeof(u32), cmd0[c->id], phy_cmd0[c->id]); + arm_dma350_cmdlink_cfg_destory(c->id); + } + + /*dynamic channel should mark the flag is_dynamic, at the same time,c->id should clear to 0xFF*/ + if ((c->is_dynamic) && (c->cyclic)) { + atomic_xchg(&vaild_chan_id[c->id], 0); + c->id = 0xFF; + } + + if (c->is_used_runtime) { + pm_runtime_mark_last_busy(d->slave.dev); + ret = pm_runtime_put_autosuspend(d->slave.dev); + if (ret) + dev_warn(d->slave.dev, "%s pm_runtime_put_autosuspend failed, ret =%d,c->id =%d.\n", + __func__, ret, c->id); + + c->is_used_runtime = false; + } + + return 0; +} + +static void arm_dma350_synchronize(struct dma_chan *chan) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + + vchan_synchronize(&c->vc); +} + +static int arm_dma350_transfer_pause(struct dma_chan *chan) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + struct arm_dma350_phy *p = &d->phy[c->id]; + + dma350_ch_cmd(p->base + DMA350_REG_CMD, DMA350_CH_CMD_PAUSECMD); + + c->status = DMA_PAUSED; + + return 0; +} + +static int arm_dma350_transfer_resume(struct dma_chan *chan) +{ + struct arm_dma350_chan *c = to_dma350_chan(chan); + struct arm_dma350_dev *d = to_arm_dma350(chan->device); + struct arm_dma350_phy *p = &d->phy[c->id]; + + dma350_ch_cmd(p->base + DMA350_REG_CMD, DMA350_CH_CMD_RESUMECMD); + + c->status = DMA_IN_PROGRESS; + + return 0; +} + +static void arm_dma350_free_desc(struct virt_dma_desc *vd) +{ + struct arm_dma350_desc_sw *ds = + container_of(vd, struct arm_dma350_desc_sw, vd); + struct arm_dma350_dev *d = to_arm_dma350(vd->tx.chan->device); + + if (ds != NULL) { + dma_pool_free(d->pool, ds->desc_hw, ds->desc_hw_lli); + kfree(ds); + } +} + +static const struct arm_dma350_drvdata arm_dma350_no_pause = { + .is_exist_pause = false, +}; + +static const struct arm_dma350_drvdata arm_dma350_full = { + .is_exist_pause = true, +}; + +static const struct of_device_id arm_dma350_dt_ids[] = { + {.compatible = "arm,dma350-no-pause", .data = &arm_dma350_no_pause }, + {.compatible = "arm,dma350-full", .data = &arm_dma350_full }, + { } +}; + +MODULE_DEVICE_TABLE(of, arm_dma350_dt_ids); + +static const struct acpi_device_id arm_dma350_acpi_ids[] = { + { "CIXH1006", .driver_data = (kernel_ulong_t) &arm_dma350_no_pause }, + { "CIXHA014", .driver_data = (kernel_ulong_t) &arm_dma350_full }, + { }, +}; + +MODULE_DEVICE_TABLE(acpi, arm_dma350_acpi_ids); + +static struct dma_chan *arm_dma350_of_xlate(struct of_phandle_args *dma_spec, + struct of_dma *ofdma) +{ + struct arm_dma350_dev *d = ofdma->of_dma_data; + unsigned int channel_pri = 0; + unsigned int channel_id = 0; + unsigned int request = 0; + struct dma_chan *chan; + struct arm_dma350_chan *c; + + if (dma_spec->args_count == 1) + request = dma_spec->args[0]; + else if (dma_spec->args_count == 2) { + request = dma_spec->args[0]; + channel_id = dma_spec->args[1]; + } else if (dma_spec->args_count == 3) { + request = dma_spec->args[0]; + channel_id = dma_spec->args[1]; + channel_pri = dma_spec->args[2]; + } else { + dev_err(d->slave.dev, "para invalid %s %d\n", __func__, __LINE__); + } + + if ((!DMA350_DYNAMIC_CH(channel_id)) && (channel_id >= d->max_channels)) { + dev_err(d->slave.dev, "channel id invalid %s %d\n", __func__, __LINE__); + return NULL; + } + + if (request >= d->max_requests) { + dev_err(d->slave.dev, "request id invalid %s %d\n", __func__, __LINE__); + return NULL; + } + chan = dma_get_any_slave_channel(&d->slave); + if (!chan) { + dev_err(d->slave.dev, "get channel fail in %s.\n", __func__); + return NULL; + } + c = to_dma350_chan(chan); + c->id = channel_id; + c->req_line = request; + c->priority = channel_pri; + if (DMA350_DYNAMIC_CH(channel_id)) + c->is_dynamic = true; + else + c->is_dynamic = false; + return chan; +} + +static struct dma_chan *arm_dma350_acpi_xlate(struct acpi_dma_spec *dma_spec, + struct acpi_dma *adma) +{ + struct arm_dma350_dev *d = adma->data; + unsigned int request, channel_id; + struct dma_chan *chan; + struct arm_dma350_chan *c; + + request = dma_spec->slave_id; + channel_id = dma_spec->chan_id; + + dev_dbg(d->slave.dev, "dma xlate request[%d] channel[%d]\n", + request, channel_id); + + if (request >= d->max_requests) { + dev_err(d->slave.dev, "request or channel_id overflow\n"); + return NULL; + } + chan = dma_get_any_slave_channel(&d->slave); + if (!chan) { + dev_err(d->slave.dev, "get channel fail in %s.\n", __func__); + return NULL; + } + c = to_dma350_chan(chan); + c->id = channel_id; + c->req_line = request; + return chan; +} + +static int arm_dma350_probe(struct platform_device *op) +{ + struct arm_dma350_dev *d; + struct arm_dma350_drvdata *drvdata = NULL; + struct reset_control *dma_reset; + int i, ret = 0; + u32 out_val[2]; + u32 autosuspend_delay = ARM_DMA350_PM_TIMEOUT_MS; + + d = devm_kzalloc(&op->dev, sizeof(*d), GFP_KERNEL); + if (!d) + return -ENOMEM; + + drvdata = (struct arm_dma350_drvdata *)device_get_match_data(&op->dev); + if (!drvdata) { + dev_err(&op->dev, "unable to find driver data\n"); + return -EINVAL; + } + d->drvdata = drvdata; + d->base = devm_platform_ioremap_resource(op, 0); + if (IS_ERR(d->base)) + return PTR_ERR(d->base); + + device_property_read_u32(&op->dev, "dma-channels", &d->max_channels); + device_property_read_u32(&op->dev, "dma-requests", &d->max_requests); + if (!d->max_requests || !d->max_channels) + return -EINVAL; + if (!device_property_read_u32_array(&op->dev, "arm,reg-map", + out_val, ARRAY_SIZE(out_val))) { + d->map.reg_host_addr = out_val[0]; + d->map.reg_remote_addr = out_val[1]; + } + if (!device_property_read_u32_array(&op->dev, "arm,ram-map", + out_val, ARRAY_SIZE(out_val))) { + d->map.ram_host_addr = out_val[0]; + d->map.ram_remote_addr = out_val[1]; + } + + if (device_property_present(&op->dev, "arm,clk-enable-atomic")) + d->is_clk_enable_atomic = true; + else + d->is_clk_enable_atomic = false; + + d->regmap = device_syscon_regmap_lookup_by_property(&op->dev, + "arm,remote-ctrl"); + if (PTR_ERR(d->regmap) == -ENODEV) + d->regmap = NULL; + else if (IS_ERR(d->regmap)) + return PTR_ERR(d->regmap); + + ret = dma_set_mask_and_coherent(&op->dev, DMA_BIT_MASK(32)); + if (ret) { + dev_err(&op->dev, "Failed to set DMA Mask\n"); + return ret; + } + if (!ACPI_COMPANION(&op->dev)) { + ret = of_reserved_mem_device_init(&op->dev); + if (ret && ret != -ENODEV) { + dev_err(&op->dev, "Failed to init reserved mem for DMA\n"); + return ret; + } + } + d->clk = devm_clk_get(&op->dev, NULL); + if (IS_ERR(d->clk)) { + dev_err(&op->dev, "no dma clk\n"); + return PTR_ERR(d->clk); + } + + d->irq = platform_get_irq(op, 0); + ret = devm_request_irq(&op->dev, d->irq, arm_dma350_int_handler, + 0, DRIVER_NAME, d); + if (ret) + return ret; + + /* A DMA memory pool for LLIs, align on 32-byte boundary */ + d->pool = dmam_pool_create(DRIVER_NAME, &op->dev, + LLI_BLOCK_SIZE, 32, 0); + if (!d->pool) { + dev_err(&op->dev, "alloc dma pool failed\n"); + return -ENOMEM; + } + + /* init phy channel */ + d->phy = devm_kcalloc(&op->dev, + d->max_channels, sizeof(struct arm_dma350_phy), GFP_KERNEL); + if (!d->phy) + return -ENOMEM; + + /* Enable clock before accessing registers */ + ret = clk_prepare_enable(d->clk); + if (ret < 0) { + dev_err(&op->dev, "clk_prepare_enable failed: %d\n", ret); + return ret; + } + dma_reset = devm_reset_control_get(&op->dev, "dma_reset"); + if (IS_ERR(dma_reset)) { + dev_err(&op->dev, "get dma reset error\n"); + ret = PTR_ERR(dma_reset); + if (ret != -ENOENT) + goto clk_dis; + } else { + /* reset */ + reset_control_assert(dma_reset); + /* release reset */ + reset_control_deassert(dma_reset); + } + d->dma_reset = dma_reset; + + for (i = 0; i < d->max_channels; i++) { + struct arm_dma350_phy *p = &d->phy[i]; + + p->idx = i; + p->base = d->base + CHANNEL_IDX(i); + desnum[i] = 0; + } + + INIT_LIST_HEAD(&d->slave.channels); + dma_cap_set(DMA_SLAVE, d->slave.cap_mask); + dma_cap_set(DMA_MEMCPY, d->slave.cap_mask); + dma_cap_set(DMA_CYCLIC, d->slave.cap_mask); + dma_cap_set(DMA_PRIVATE, d->slave.cap_mask); + d->slave.dev = &op->dev; + d->slave.device_free_chan_resources = arm_dma350_free_chan_resources; + d->slave.device_tx_status = arm_dma350_tx_status; + d->slave.device_prep_dma_memcpy = arm_dma350_prep_memcpy; + d->slave.device_prep_slave_sg = arm_dma350_prep_slave_sg; + d->slave.device_prep_dma_cyclic = arm_dma350_prep_dma_cyclic; + d->slave.device_issue_pending = arm_dma350_issue_pending; + d->slave.device_config = arm_dma350_config; + d->slave.device_terminate_all = arm_dma350_terminate_all; + d->slave.device_synchronize = arm_dma350_synchronize; + if (d->drvdata->is_exist_pause == true) { + d->slave.device_pause = arm_dma350_transfer_pause; + d->slave.device_resume = arm_dma350_transfer_resume; + } + d->slave.copy_align = DMA_ALIGN; + d->slave.src_addr_widths = ARM_DMA350_BUSWIDTHS; + d->slave.dst_addr_widths = ARM_DMA350_BUSWIDTHS; + d->slave.directions = BIT(DMA_MEM_TO_MEM) | BIT(DMA_MEM_TO_DEV) + | BIT(DMA_DEV_TO_MEM); + d->slave.residue_granularity = DMA_RESIDUE_GRANULARITY_SEGMENT; + /* init virtual channel */ + d->chans = devm_kcalloc(&op->dev, + d->max_requests, sizeof(struct arm_dma350_chan), GFP_KERNEL); + if (!d->chans) + return -ENOMEM; + + for (i = 0; i < d->max_requests; i++) { + struct arm_dma350_chan *c = &d->chans[i]; + + c->status = DMA_IN_PROGRESS; + INIT_LIST_HEAD(&c->node); + c->vc.desc_free = arm_dma350_free_desc; + vchan_init(&c->vc, &d->slave); + c->is_used_runtime = false; + } + + spin_lock_init(&d->lock); + INIT_LIST_HEAD(&d->chan_pending); + platform_set_drvdata(op, d); + ret = dma_async_device_register(&d->slave); + if (ret) + goto clk_dis; + + if (d->is_clk_enable_atomic) + autosuspend_delay = 0; + + pm_runtime_irq_safe(&op->dev); + pm_runtime_set_autosuspend_delay(&op->dev, autosuspend_delay); + pm_runtime_use_autosuspend(&op->dev); + pm_runtime_get_noresume(&op->dev); + pm_runtime_set_active(&op->dev); + pm_runtime_enable(&op->dev); + + if (ACPI_COMPANION(&op->dev)) + ret = acpi_dma_controller_register(&op->dev, + arm_dma350_acpi_xlate, d); + else + ret = of_dma_controller_register((&op->dev)->of_node, + arm_dma350_of_xlate, d); + if (ret) + goto of_dma_register_fail; + + pm_runtime_mark_last_busy(&op->dev); + pm_runtime_put_autosuspend(&op->dev); + dev_info(&op->dev, "initialized\n"); + + return 0; + +of_dma_register_fail: + dma_async_device_unregister(&d->slave); +clk_dis: + if (d->is_clk_enable_atomic) + clk_disable(d->clk); + else + clk_disable_unprepare(d->clk); + return ret; +} + +static int arm_dma350_remove(struct platform_device *op) +{ + struct arm_dma350_chan *c, *cn; + struct arm_dma350_dev *d = platform_get_drvdata(op); + + /* explicitly free the irq */ + devm_free_irq(&op->dev, d->irq, d); + + dma_async_device_unregister(&d->slave); + of_dma_controller_free((&op->dev)->of_node); + + list_for_each_entry_safe(c, cn, &d->slave.channels, vc.chan.device_node) { + list_del(&c->vc.chan.device_node); + } + if (d->is_clk_enable_atomic) + clk_disable(d->clk); + else + clk_disable_unprepare(d->clk); + + return 0; +} + +static int arm_dma350_runtime_suspend_dev(struct device *dev) +{ + struct arm_dma350_dev *d = dev_get_drvdata(dev); + + if (d->is_clk_enable_atomic) + clk_disable(d->clk); + else + clk_disable_unprepare(d->clk); + + return 0; +} + +static int arm_dma350_runtime_resume_dev(struct device *dev) +{ + struct arm_dma350_dev *d = dev_get_drvdata(dev); + int ret = 0; + + if (d->is_clk_enable_atomic) + ret = clk_enable(d->clk); + else + ret = clk_prepare_enable(d->clk); + if (ret < 0) { + dev_err(d->slave.dev, "clk_prepare_enable failed: %d\n", ret); + return ret; + } + + if (d->drvdata->is_exist_pause == false) { + reset_control_assert(d->dma_reset); + udelay(2); + reset_control_deassert(d->dma_reset); + } + + return 0; +} + +#ifdef CONFIG_PM_SLEEP +static int arm_dma350_suspend_dev(struct device *dev) +{ + int ret = 0; + + ret = pm_runtime_force_suspend(dev); + if (ret) { + dev_err(dev, "Force suspend error.\n"); + return ret; + } + + return 0; +} + +static int arm_dma350_resume_dev(struct device *dev) +{ + int ret = 0; + struct arm_dma350_dev *d = dev_get_drvdata(dev); + + if (d->drvdata->is_exist_pause == true) { + reset_control_assert(d->dma_reset); + udelay(2); + reset_control_deassert(d->dma_reset); + } + + ret = pm_runtime_force_resume(dev); + if (ret) { + dev_err(dev, "Force resume error.\n"); + return ret; + } + + return 0; +} +#endif + +static const struct dev_pm_ops arm_dma350_pmops = { + SET_SYSTEM_SLEEP_PM_OPS(arm_dma350_suspend_dev, + arm_dma350_resume_dev) + SET_RUNTIME_PM_OPS(arm_dma350_runtime_suspend_dev, + arm_dma350_runtime_resume_dev, NULL) +}; + +static struct platform_driver arm_dma350_driver = { + .driver = { + .name = DRIVER_NAME, + .pm = &arm_dma350_pmops, + .of_match_table = arm_dma350_dt_ids, + .acpi_match_table = ACPI_PTR(arm_dma350_acpi_ids), + }, + .probe = arm_dma350_probe, + .remove = arm_dma350_remove, +}; + +module_platform_driver(arm_dma350_driver); + +MODULE_AUTHOR("Hongliang yang "); +MODULE_DESCRIPTION("API Driver for ARM DMA350 controller"); +MODULE_LICENSE("GPL"); diff --git a/drivers/dma/dma350_ch_drv.h b/drivers/dma/dma350_ch_drv.h new file mode 100755 index 000000000000..5d21e6e0bf9f --- /dev/null +++ b/drivers/dma/dma350_ch_drv.h @@ -0,0 +1,2012 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0 + * + * Copyright (c) 2022 Arm Limited. All rights reserved. + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#ifndef __DMA350_CH_DRV_H +#define __DMA350_CH_DRV_H + +#include "dma350_regdef.h" +#include +#include +#ifdef __cplusplus +extern "C" { +#endif + +/* DMA350_CH register mask definitions */ + +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_MAX 0x1FUL +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_MAX 0x1FUL + +#define DMA350_CH_CTRL_RESET_VALUE 0x00200200 +#define DMA350_CH_INTREN_RESET_VALUE 0x00000000 +#define DMA350_CH_LINKADDR_RESET_VALUE 0x00000000 +#define DMA350_CH_DESTRANSCFG_RESET_VALUE 0x000F0400 +#define DMA350_CH_SRCTRANSCFG_RESET_VALUE 0x000F0400 +#define DMA350_CH_AUTOCFG_RESET_VALUE 0x00000000 + +#define DMA350_CMDLINK_CLEAR_SET (0x1UL) +#define DMA350_CMDLINK_INTREN_SET (0x1UL << 2) +#define DMA350_CMDLINK_CTRL_SET (0x1UL << 3) +#define DMA350_CMDLINK_SRC_ADDR_SET (0x1UL << 4) +#define DMA350_CMDLINK_SRC_ADDRHI_SET (0x1UL << 5) +#define DMA350_CMDLINK_DES_ADDR_SET (0x1UL << 6) +#define DMA350_CMDLINK_DES_ADDRHI_SET (0x1UL << 7) +#define DMA350_CMDLINK_XSIZE_SET (0x1UL << 8) +#define DMA350_CMDLINK_XSIZEHI_SET (0x1UL << 9) +#define DMA350_CMDLINK_SRCTRANSCFG_SET (0x1UL << 10) +#define DMA350_CMDLINK_DESTRANSCFG_SET (0x1UL << 11) +#define DMA350_CMDLINK_XADDRINC_SET (0x1UL << 12) +#define DMA350_CMDLINK_YADDRSTRIDE_SET (0x1UL << 13) +#define DMA350_CMDLINK_FILLVAL_SET (0x1UL << 14) +#define DMA350_CMDLINK_YSIZE_SET (0x1UL << 15) +#define DMA350_CMDLINK_TMPLTCFG_SET (0x1UL << 16) +#define DMA350_CMDLINK_SRCTMPLT_SET (0x1UL << 17) +#define DMA350_CMDLINK_DESTMPLT_SET (0x1UL << 18) +#define DMA350_CMDLINK_SRCTRIGINCFG_SET (0x1UL << 19) +#define DMA350_CMDLINK_DESTRIGINCFG_SET (0x1UL << 20) +#define DMA350_CMDLINK_TRIGOUTCFG_SET (0x1UL << 21) +#define DMA350_CMDLINK_GPOEN0_SET (0x1UL << 22) +#define DMA350_CMDLINK_GPOVAL0_SET (0x1UL << 24) +#define DMA350_CMDLINK_STREAMINTCFG_SET (0x1UL << 26) +#define DMA350_CMDLINK_LINKATTR_SET (0x1UL << 28) +#define DMA350_CMDLINK_AUTOCFG_SET (0x1UL << 29) +#define DMA350_CMDLINK_LINKADDR_SET (0x1UL << 30) +#define DMA350_CMDLINK_LINKADDRHI_SET (0x1UL << 31) + +#define ARM_DMA350_BUSWIDTHS \ + (BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \ + BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \ + BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \ + BIT(DMA_SLAVE_BUSWIDTH_8_BYTES)) + +/*Update a addrister (addr) at position (POS) with value (VAL). + *Affected bits are defined by a mask (MSK) + */ +#define SET_FIELD(addr, VAL, POS, MSK) \ + writel((readl(addr) & ~MSK) | (((uint32_t)(VAL) << POS) & MSK), addr) + +/* ARM DMA350 DMA Channel status bits */ +enum dma350_ch_stat_t { + DMA350_CH_STAT_DONE = DMA350_CH_STATUS_STAT_DONE, + DMA350_CH_STAT_ERR = DMA350_CH_STATUS_STAT_ERR, + DMA350_CH_STAT_DISABLED = DMA350_CH_STATUS_STAT_DISABLED, + DMA350_CH_STAT_STOPPED = DMA350_CH_STATUS_STAT_STOPPED, + DMA350_CH_STAT_SRCTRIGINWAIT = DMA350_CH_STATUS_STAT_SRCTRIGINWAIT, + DMA350_CH_STAT_DESTRIGINWAIT = DMA350_CH_STATUS_STAT_DESTRIGINWAIT, + DMA350_CH_STAT_TRIGOUTACKWAIT = DMA350_CH_STATUS_STAT_TRIGOUTACKWAIT, + DMA350_CH_STAT_ALL = + DMA350_CH_STATUS_STAT_DONE | DMA350_CH_STATUS_STAT_ERR | + DMA350_CH_STATUS_STAT_DISABLED | DMA350_CH_STATUS_STAT_STOPPED | + DMA350_CH_STATUS_STAT_SRCTRIGINWAIT | DMA350_CH_STATUS_STAT_DESTRIGINWAIT | + DMA350_CH_STATUS_STAT_TRIGOUTACKWAIT +}; + +/* ARM DMA350 DMA Channel interrupt bits */ +enum dma350_ch_intr_t { + DMA350_CH_INTREN_DONE = DMA350_CH_INTREN_INTREN_DONE, + DMA350_CH_INTREN_ERR = DMA350_CH_INTREN_INTREN_ERR, + DMA350_CH_INTREN_DISABLED = DMA350_CH_INTREN_INTREN_DISABLED, + DMA350_CH_INTREN_STOPPED = DMA350_CH_INTREN_INTREN_STOPPED, + DMA350_CH_INTREN_SRCTRIGINWAIT = DMA350_CH_INTREN_INTREN_SRCTRIGINWAIT, + DMA350_CH_INTREN_DESTRIGINWAIT = DMA350_CH_INTREN_INTREN_DESTRIGINWAIT, + DMA350_CH_INTREN_TRIGOUTACKWAIT = DMA350_CH_INTREN_INTREN_TRIGOUTACKWAIT, + DMA350_CH_INTREN_ALL = + DMA350_CH_INTREN_INTREN_DONE | DMA350_CH_INTREN_INTREN_ERR | + DMA350_CH_INTREN_INTREN_DISABLED | DMA350_CH_INTREN_INTREN_STOPPED | + DMA350_CH_INTREN_INTREN_SRCTRIGINWAIT | + DMA350_CH_INTREN_INTREN_DESTRIGINWAIT | DMA350_CH_INTREN_INTREN_TRIGOUTACKWAIT +}; + + +/* ARM DMA350 DMA Channel XTYPE */ +enum dma350_ch_xtype_t { + DMA350_CH_XTYPE_DISABLE = 0, + DMA350_CH_XTYPE_CONTINUE = DMA350_CH_CTRL_XTYPE_0, + DMA350_CH_XTYPE_WRAP = DMA350_CH_CTRL_XTYPE_1, + DMA350_CH_XTYPE_FILL = DMA350_CH_CTRL_XTYPE_1 | DMA350_CH_CTRL_XTYPE_0 +}; + +/* ARM DMA350 DMA Channel Done type */ +enum dma350_ch_donetype_t { + DMA350_CH_DONETYPE_NONE = 0, + DMA350_CH_DONETYPE_END_OF_CMD = DMA350_CH_CTRL_DONETYPE_0, + DMA350_CH_DONETYPE_END_OF_AUTORESTART = + DMA350_CH_CTRL_DONETYPE_1 | DMA350_CH_CTRL_DONETYPE_0 +}; + +/* ARM DMA350 DMA Channel Source Trigger Input Type */ +enum dma350_ch_srctrigintype_t { + DMA350_CH_SRCTRIGINTYPE_SOFTWARE_ONLY = 0, + DMA350_CH_SRCTRIGINTYPE_HW = DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_1, + DMA350_CH_SRCTRIGINTYPE_INTERNAL = DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_1 | + DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_0 +}; + +/* ARM DMA350 DMA Channel Source Trigger Input Mode */ +enum dma350_ch_srctriginmode_t { + DMA350_CH_SRCTRIGINMODE_CMD = 0, + DMA350_CH_SRCTRIGINMODE_DMA_FLOW_CTRL = DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_1, + DMA350_CH_SRCTRIGINMODE_PERIPH_FLOW_CTRL = + DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_1 | + DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_0 +}; + +/* ARM DMA350 DMA Channel Destination Trigger Input Type */ +enum dma350_ch_destrigintype_t { + DMA350_CH_DESTRIGINTYPE_SOFTWARE_ONLY = 0, + DMA350_CH_DESTRIGINTYPE_HW = DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_1, + DMA350_CH_DESTRIGINTYPE_INTERNAL = DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_1 | + DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_0 +}; + +/* ARM DMA350 DMA Channel Destination Trigger Input Mode */ +enum dma350_ch_destriginmode_t { + DMA350_CH_DESTRIGINMODE_CMD = 0, + DMA350_CH_DESTRIGINMODE_DMA_FLOW_CTRL = DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_1, + DMA350_CH_DESTRIGINMODE_PERIPH_FLOW_CTRL = + DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_1 | + DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_0 +}; + + +/* ARM DMA350 DMA Command link addrister structure */ +/* Note: Field order must match the order of the bits in the header */ +struct dma350_cmdlink_addr_t { + /* Note: addrCLEAR (Bit 0) has no associated field and Bit 1 is reserved */ + uint32_t intren; /* Bit 2 */ + uint32_t ctrl; /* Bit 3 */ + uint32_t srcaddr; /* Bit 4 */ + uint32_t srcaddrhi; /* Bit 5 */ + uint32_t desaddr; /* Bit 6 */ + uint32_t desaddrhi; /* Bit 7 */ + uint32_t xsize; /* Bit 8 */ + uint32_t xsizehi; /* Bit 9 */ + uint32_t srctranscfg; /* Bit 10 */ + uint32_t destranscfg; /* Bit 11 */ + uint32_t xaddrinc; /* Bit 12 */ + uint32_t yaddrstride; /* Bit 13 */ + uint32_t fillval; /* Bit 14 */ + uint32_t ysize; /* Bit 15 */ + uint32_t tmpltcfg; /* Bit 16 */ + uint32_t srctmplt; /* Bit 17 */ + uint32_t destmplt; /* Bit 18 */ + uint32_t srctrigincfg; /* Bit 19 */ + uint32_t destrigincfg; /* Bit 20 */ + uint32_t trigoutcfg; /* Bit 21 */ + uint32_t gpoen0; /* Bit 22 */ + uint32_t reserved0; /* Bit 23 */ + uint32_t gpoval0; /* Bit 24 */ + uint32_t reserved1; /* Bit 25 */ + uint32_t streamintcfg; /* Bit 26 */ + uint32_t reserved2; /* Bit 27 */ + uint32_t linkattr; /* Bit 28 */ + uint32_t autocfg; /* Bit 29 */ + uint32_t linkaddr; /* Bit 30 */ + uint32_t linkaddrhi; /* Bit 31 */ +}; + +/* ARM DMA350 DMA Command link generator config structure */ +struct dma350_cmdlink_gencfg_t { + uint32_t header; + struct dma350_cmdlink_addr_t cfg; +}; + + +/** + * \brief Sets source address[31:0] of channel + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] src_addr source address, where to copy from + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_set_src(void __iomem *addr, uint32_t src_addr); + +/** + * \brief Sets destination address[31:0] of channel + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] des_addr destination address, where to copy to + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_set_des(void __iomem *addr, uint32_t des_addr); + +/** + * \brief Sets Channel Priority + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] chprio Number of priority + * + * \return void + */ +static inline +void dma350_ch_set_chprio(void __iomem *addr, uint8_t chprio); + +/** + * \brief Sets number of copies in the x dimension + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] src_xsize number of source elements in the x dimension + * \param[in] des_xsize number of destination elements in the x dimension + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_set_xsize32(void __iomem *addr, uint32_t src_xsize, + uint32_t des_xsize); + +/** + * \brief Sets size of each transfer + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] transize size of each transfer \ref dma350_ch_transize_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_set_transize(void __iomem *addr, uint32_t transize); + +/** + * \brief Sets type of operation in the x dimension + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] xtype type of operation in the x dimension + * \ref dma350_ch_xtype_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_set_xtype(void __iomem *addr, + enum dma350_ch_xtype_t xtype); + +/** + * \brief Configures when STAT_DONE flag is asserted for this command + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] donetype donetype of command \ref dma350_ch_donetype_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_set_donetype(void __iomem *addr, + enum dma350_ch_donetype_t donetype); + +/** + * \brief Enables Source Trigger Input use for this command + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_enable_srctrigin(void __iomem *addr); + +/** + * \brief Disables Source Trigger Input use for this command + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_disable_srctrigin(void __iomem *addr); + +/** + * \brief Enables Destination Trigger Input use for this command + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_enable_destrigin(void __iomem *addr); + +/** + * \brief Disables Destination Trigger Input use for this command + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_disable_destrigin(void __iomem *addr); + + +/** + * \brief Sets Source Transfer Memory Attribute field[3:0] + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] memattrlo Attribute field (4 bits) + * + * \return void + */ +static inline +void dma350_ch_set_srcmemattrlo(void __iomem *addr, uint8_t memattrlo); + +/** + * \brief Sets Source Transfer Memory Attribute field[7:4] + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] memattrhi Attribute field (4 bits) + * + * \return void + */ +static inline +void dma350_ch_set_srcmemattrhi(void __iomem *addr, uint8_t memattrhi); + +/** + * \brief Sets Destination Transfer Memory Attribute field[3:0] + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] memattrlo Attribute field (4 bits) + * + * \return void + */ +static inline +void dma350_ch_set_desmemattrlo(void __iomem *addr, uint8_t memattrlo); + +/** + * \brief Sets Destination Transfer Memory Attribute field[7:4] + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] memattrhi Attribute field (4 bits) + * + * \return void + */ +static inline +void dma350_ch_set_desmemattrhi(void __iomem *addr, uint8_t memattrhi); + +static inline +void dma350_ch_set_srcmaxburstlen(void __iomem *addr, uint8_t length); + +/** + * \brief Sets Destination Max Burst Length + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] length Value of max burst length + * + * \return void + */ +static inline +void dma350_ch_set_desmaxburstlen(void __iomem *addr, uint8_t length); + +/** + * \brief Sets source and destination address increment after each transfer + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] src_xaddr_inc increment of source address + * \param[in] des_xaddr_inc increment of destination address + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_set_xaddr_inc(void __iomem *addr, int32_t src_xaddr_inc, + int32_t des_xaddr_inc); + +/** + * \brief Commands a channel of DMA350 DMA. + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] cmd DMA350 DMA channel command \ref dma350_ch_cmd_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_cmd(void __iomem *addr, uint32_t cmd); + +/** + * \brief Enables Interrupt for DMA350 DMA channel + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] intr Interrupt(s) to enable \ref dma350_ch_intr_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_enable_intr(void __iomem *addr, enum dma350_ch_intr_t intr); + +/** + * \brief Disables Interrupt for DMA350 DMA channel + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] intr Interrupt(s) to disable \ref dma350_ch_intr_t + * + * \return void + * + * \note This function doesn't check if dev is NULL or if it has been init. + */ +static inline +void dma350_ch_disable_intr(void __iomem *addr, enum dma350_ch_intr_t intr); +/** + * \brief Sets Source Trigger Input Select + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] srctriginsel Input Select value + * + * \return void + */ +static inline +void dma350_ch_set_srctriginsel(void __iomem *addr, + uint8_t srctriginsel); + +/** + * \brief Sets Source Trigger Input Type + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] type Input type \ref dma350_ch_srctrigintype_t + * + * \return void + */ +static inline +void dma350_ch_set_srctrigintype(void __iomem *addr, + enum dma350_ch_srctrigintype_t type); + +/** + * \brief Sets Source Trigger Input Mode + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] mode Mode \ref dma350_ch_srctriginmode_t + * + * \return void + */ +static inline +void dma350_ch_set_srctriginmode(void __iomem *addr, + enum dma350_ch_srctriginmode_t mode); + +/** + * \brief Sets Source Trigger Input Default Transfer Size + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] blksize Size value + * + * \return void + */ +static inline +void dma350_ch_set_srctriginblksize(void __iomem *addr, uint8_t blksize); + +/** + * \brief Sets Destination Trigger Input Select + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] destriginsel Input Select value + * + * \return void + */ +static inline +void dma350_ch_set_destriginsel(void __iomem *addr, uint8_t destriginsel); + +/** + * \brief Sets Destination Trigger Input Type + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] type Input type \ref dma350_ch_destrigintype_t + * + * \return void + */ +static inline +void dma350_ch_set_destrigintype(void __iomem *addr, + enum dma350_ch_destrigintype_t type); + +/** + * \brief Sets Destination Trigger Input Mode + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] mode Mode \ref dma350_ch_destriginmode_t + * + * \return void + */ +static inline +void dma350_ch_set_destriginmode(void __iomem *addr, + enum dma350_ch_destriginmode_t mode); + +/** + * \brief Sets Destination Trigger Input Default Transfer Size + * + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] blksize Size value + * + * \return void + */ +static inline +void dma350_ch_set_destriginblksize(void __iomem *addr, uint8_t blksize); + +/** + * \brief Sets Link Address Read Transfer Memory Attribute[3:0] field + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] memattrlo Attribute field + * + * \return void + */ +static inline +void dma350_ch_set_linkmemattrlo(void __iomem *addr, uint8_t memattrlo); + +/** + * \brief Sets Link Address Read Transfer Memory Attribute[7:4] field + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] memattrlo Attribute field + * + * \return void + */ +static inline +void dma350_ch_set_linkmemattrhi(void __iomem *addr, uint8_t memattrhi); + +/** + * \brief Sets Link Address Transfer Shareability Attribute + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] shareattr Attribute field + * + * \return void + */ +static inline +void dma350_ch_set_linkshareattr(void __iomem *addr, uint8_t shareattr); + +/** + * \brief Enables Link Address + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * + * \return void + */ +static inline +void dma350_ch_enable_linkaddr(void __iomem *addr); + +/** + * \brief Disables Link Address + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * + * \return void + */ +static inline +void dma350_ch_disable_linkaddr(void __iomem *addr); + +/** + * \brief Sets Link Address Pointer [31:2] + * + * \param[in] dev DMA350 channel device struct \ref dma350_ch_dev_t + * \param[in] linkaddr Memory location of the destination + * + * \return void + */ +static inline +void dma350_ch_set_linkaddr32(void __iomem *addr, uint32_t linkaddr); + + +/** + * \brief Sets addrCLEAR header bit in the command structure which clears all + * previous settings from the channel addristers + * + * \param[in] cmldink_cfg Command structure for DMA350 DMA command linking + * feature \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_regclear(struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Enables Interrupt for DMA350 DMA channel in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] intr Interrupt(s) to enable \ref dma350_ch_intr_t + * + * \return void + */ +static inline +void dma350_cmdlink_enable_intr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_intr_t intr); + +/** + * \brief Disables Interrupt for DMA350 DMA channel in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] intr Interrupt(s) to disable \ref dma350_ch_intr_t + * + * \return void + */ +static inline +void dma350_cmdlink_disable_intr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_intr_t intr); + +/** + * \brief Sets Transfer Enitity Size in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] transize size in bytes \ref dma350_ch_transize_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_transize(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t transize); + +/** + * \brief Sets Channel Priority in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] chprio Number of priority + * + * \return void + */ +static inline +void dma350_cmdlink_set_chprio(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint8_t chprio); + +/** + * \brief Sets operation type for X direction in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] xtype type \ref dma350_ch_xtype_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_xtype(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_xtype_t xtype); + +/** + * \brief Sets when the STAT_DONE status flag is asserted during the command + * operation in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] donetype Done type selection \ref dma350_ch_donetype_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_donetype(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_donetype_t donetype); + +/** + * \brief Enables the automatic pause request for the current DMA operation + * if the STAT_DONE flag is asserted in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_enable_donepause( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Disables the automatic pause request for the current DMA operation + * if the STAT_DONE flag is asserted in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_disable_donepause( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Enables Source Trigger Input use in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_enable_srctrigin( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Disables Source Trigger Input use in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_disable_srctrigin( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Enables Destination Trigger Input use in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_enable_destrigin( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Disables Destination Trigger Input use in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_disable_destrigin( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Source Address[31:0] in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] src_addr Memory location of the source + * + * \return void + */ +static inline +void dma350_cmdlink_set_srcaddr32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t src_addr); + +/** + * \brief Sets Destination Address[31:0] in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] des_addr Memory location of the destination + * + * \return void + */ +static inline +void dma350_cmdlink_set_desaddr32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t des_addr); + +/** + * \brief Sets the number of data in the command structure units + * copied during the DMA command up to 16 bits in the X dimension + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] src_xsize Source number of transfers + * \param[in] des_xsize Destination number of transfers + * + * \return void + */ +static inline +void dma350_cmdlink_set_xsize16(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint16_t src_xsize, uint16_t des_xsize); + +/** + * \brief Sets the number of data in the command structure units + * copied during the DMA command up to 32 bits in the X dimension + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] src_xsize Source number of transfers + * \param[in] des_xsize Destination number of transfers + * + * \return void + */ +static inline +void dma350_cmdlink_set_xsize32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t src_xsize, uint32_t des_xsize); + +/** + * \brief Sets Source Transfer Memory Attribute field[3:0] + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] memattrlo Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_srcmemattrlo( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrlo); + +/** + * \brief Sets Source Transfer Memory Attribute field[7:4] + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] memattrhi Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_srcmemattrhi( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrhi); + +/** + * \brief Sets Source Transfer Shareability Attribute in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] shareattr Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_srcshareattr( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t shareattr); + +/** + * \brief Sets Destination Transfer Memory Attribute field[3:0] in the command + * structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] memattrlo Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_desmemattrlo( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrlo); + +/** + * \brief Sets Destination Transfer Memory Attribute field[7:4] in the command + * structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] memattrhi Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_desmemattrhi( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrhi); + +/** + * \brief Sets Destination Transfer Shareability Attribute in the command + * structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] shareattr Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_desshareattr( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t shareattr); + +/** + * \brief Sets Source Transfer Attribute to secure in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_src_trans_secure( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Source Transfer Attribute to non secure in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_src_trans_nonsecure( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Destination Transfer Attribute to secure in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_des_trans_secure( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Destination Transfer Attribute to non secure + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_des_trans_nonsecure( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Source Transfer Privilege to privileged + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_src_trans_privileged( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Source Transfer Privilege to unprivileged + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_src_trans_unprivileged( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Destination Transfer Privilege to privileged + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_des_trans_privileged( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Destination Transfer Privilege to unprivileged + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_des_trans_unprivileged( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Source Max Burst Length in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] length Value of max burst length + * + * \return void + */ +static inline +void dma350_cmdlink_set_srcmaxburstlen( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t length); + +/** + * \brief Sets Destination Max Burst Length in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] length Value of max burst length + * + * \return void + */ +static inline +void dma350_cmdlink_set_desmaxburstlen( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t length); + +/** + * \brief Sets the increment value in the command structure that is used to + * update the source and the destination addresses after each + * transferred data unit + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] src_xaddrinc Source X dimension address increment value + * \param[in] des_xaddrinc Destination X dimension address increment value + * + * \return void + */ +static inline +void dma350_cmdlink_set_xaddrinc(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint16_t src_xaddrinc, uint16_t des_xaddrinc); + +/** + * \brief Sets Source Trigger Input Select in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] srctriginsel Input Select value + * + * \return void + */ +static inline +void dma350_cmdlink_set_srctriginsel( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t srctriginsel); + +/** + * \brief Sets Source Trigger Input Type in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] type Input type \ref dma350_ch_srctrigintype_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_srctrigintype( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_srctrigintype_t type); + +/** + * \brief Sets Source Trigger Input Mode in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] mode Mode \ref dma350_ch_srctriginmode_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_srctriginmode( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_srctriginmode_t mode); + +/** + * \brief Sets Source Trigger Input Default Transfer Size + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] blksize Size value + * + * \return void + */ +static inline +void dma350_cmdlink_set_srctriginblksize( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t blksize); + +/** + * \brief Sets Destination Trigger Input Select in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] destriginsel Input Select value + * + * \return void + */ +static inline +void dma350_cmdlink_set_destriginsel( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t destriginsel); + +/** + * \brief Sets Destination Trigger Input Type in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] type Input type \ref dma350_ch_destrigintype_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_destrigintype( + struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_destrigintype_t type); + +/** + * \brief Sets Destination Trigger Input Mode in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] mode Mode \ref dma350_ch_destriginmode_t + * + * \return void + */ +static inline +void dma350_cmdlink_set_destriginmode(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_destriginmode_t mode); + +/** + * \brief Sets Destination Trigger Input Default Transfer Size + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] blksize Size value + * + * \return void + */ +static inline +void dma350_cmdlink_set_destriginblksize(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t blksize); + +/** + * \brief Sets Link Address Read Transfer Memory Attribute[3:0] field + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] memattrlo Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_linkmemattrlo(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrlo); + +/** + * \brief Sets Link Address Read Transfer Memory Attribute[7:4] field + * in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] memattrlo Attribute field + * + * \return void + */ +static inline +void dma350_cmdlink_set_linkmemattrhi(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrhi); + +/** + * \brief Enables Infinite Automatic Command Restart in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_enable_cmdrestartinfen(struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Disables Infinite Automatic Command Restart in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_disable_cmdrestartinfen(struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Enables Link Address in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_enable_linkaddr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Disables Link Address in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static inline +void dma350_cmdlink_disable_linkaddr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +/** + * \brief Sets Link Address Pointer [31:2] in the command structure + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * \param[in] linkaddr Memory location of the destination + * + * \return void + */ +static inline +void dma350_cmdlink_set_linkaddr32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t linkaddr); +/** + * \brief Initialize command structure for dma command linking feature + * + * \param[in] cmldink_cfg DMA350 command structure for command linking feature + * \ref dma350_cmdlink_gencfg_t + * + * \return void + */ +static void dma350_cmdlink_init(struct dma350_cmdlink_gencfg_t *cmdlink_cfg); + +static inline +void dma350_ch_set_src(void __iomem *addr, uint32_t src_addr) +{ + writel(src_addr, addr); +} + +static inline +void dma350_ch_set_des(void __iomem *addr, uint32_t des_addr) +{ + writel(des_addr, addr); +} + +static inline +void dma350_ch_set_xsize32(void __iomem *addr, uint32_t src_xsize, uint32_t des_xsize) +{ + writel(((des_xsize & 0x0000FFFFUL) << 16U) | (src_xsize & 0x0000FFFFUL), addr); + writel((des_xsize & 0xFFFF0000UL) | ((src_xsize & 0xFFFF0000UL) >> 16U), addr + 0x4); +} + +static inline +void dma350_ch_set_transize(void __iomem *addr, uint32_t transize) +{ + SET_FIELD(addr, transize, DMA350_CH_CTRL_TRANSIZE_Pos, + DMA350_CH_CTRL_TRANSIZE_Msk); +} + +static inline +void dma350_ch_set_chprio(void __iomem *addr, uint8_t chprio) +{ + SET_FIELD(addr, chprio, DMA350_CH_CTRL_CHPRIO_Pos, + DMA350_CH_CTRL_CHPRIO_Msk); +} + +static inline +void dma350_ch_set_xtype(void __iomem *addr, enum dma350_ch_xtype_t xtype) +{ + writel((readl(addr) & ~DMA350_CH_CTRL_XTYPE_Msk) | ((uint32_t)(xtype)), addr); +} + + +static inline +void dma350_ch_set_donetype(void __iomem *addr, + enum dma350_ch_donetype_t donetype) +{ + SET_FIELD(addr, donetype, DMA350_CH_CTRL_DONETYPE_Pos, + DMA350_CH_CTRL_DONETYPE_Msk); +} + + +static inline +void dma350_ch_enable_srctrigin(void __iomem *addr) +{ + writel(readl(addr) | DMA350_CH_CTRL_USESRCTRIGIN_Msk, addr); +} + +static inline +void dma350_ch_disable_srctrigin(void __iomem *addr) +{ + writel(readl(addr) & (~DMA350_CH_CTRL_USESRCTRIGIN_Msk), addr); +} + +static inline +void dma350_ch_enable_destrigin(void __iomem *addr) +{ + writel(readl(addr) | DMA350_CH_CTRL_USEDESTRIGIN_Msk, addr); +} + +static inline +void dma350_ch_disable_destrigin(void __iomem *addr) +{ + writel(readl(addr) & (~DMA350_CH_CTRL_USEDESTRIGIN_Msk), addr); +} + +static inline +void dma350_ch_set_srcmemattrlo(void __iomem *addr, uint8_t memattrlo) +{ + SET_FIELD(addr, memattrlo, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Msk); +} + +static inline +void dma350_ch_set_srcmemattrhi(void __iomem *addr, uint8_t memattrhi) +{ + SET_FIELD(addr, memattrhi, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Msk); +} + +static inline +void dma350_ch_src_memattr(void __iomem *addr, u32 memattrhi, u32 memattrlo) +{ + SET_FIELD(addr, memattrhi, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Msk); + SET_FIELD(addr, memattrlo, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos, + DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Msk); +} + +static inline +void dma350_ch_set_desmemattrlo(void __iomem *addr, uint8_t memattrlo) +{ + SET_FIELD(addr, memattrlo, + DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos, + DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Msk); +} + +static inline +void dma350_ch_set_desmemattrhi(void __iomem *addr, uint8_t memattrhi) +{ + SET_FIELD(addr, memattrhi, + DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos, + DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Msk); +} + +static inline +void dma350_ch_des_memattr(void __iomem *addr, u32 memattrhi, u32 memattrlo) +{ + SET_FIELD(addr, memattrhi, + DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos, + DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Msk); + + SET_FIELD(addr, memattrlo, + DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos, + DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Msk); +} + +static inline +void dma350_ch_set_srcmaxburstlen(void __iomem *addr, uint8_t length) +{ + SET_FIELD(addr, length, + DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos, + DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Msk); +} + +static inline +void dma350_ch_set_desmaxburstlen(void __iomem *addr, uint8_t length) +{ + SET_FIELD(addr, length, + DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos, + DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Msk); +} + + +static inline +void dma350_ch_set_xaddr_inc(void __iomem *addr, int32_t src_xaddr_inc, + int32_t des_xaddr_inc) +{ + writel(((des_xaddr_inc & 0x0000FFFFUL) << DMA350_CH_XADDRINC_DESXADDRINC_Pos) | + (src_xaddr_inc & 0x0000FFFFUL), addr); +} + +static inline +void dma350_ch_set_srctriginsel(void __iomem *addr, uint8_t srctriginsel) +{ + SET_FIELD(addr, srctriginsel, + DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos, + DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Msk); +} + +static inline +void dma350_ch_set_srctrigintype(void __iomem *addr, enum dma350_ch_srctrigintype_t type) +{ + writel((readl(addr) & ~DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Msk) | ((uint32_t)(type)), addr); +} + +static inline +void dma350_ch_set_srctriginmode(void __iomem *addr, enum dma350_ch_srctriginmode_t mode) +{ + writel((readl(addr) & ~DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Msk) | ((uint32_t)(mode)), addr); +} + +static inline +void dma350_ch_set_srctriginblksize(void __iomem *addr, uint8_t blksize) +{ + SET_FIELD(addr, blksize, + DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos, + DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Msk); +} + +static inline +void dma350_ch_set_destriginsel(void __iomem *addr, uint8_t destriginsel) +{ + SET_FIELD(addr, destriginsel, + DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos, + DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Msk); +} + +static inline +void dma350_ch_set_destrigintype(void __iomem *addr, enum dma350_ch_destrigintype_t type) +{ + writel((readl(addr) & ~DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Msk) | ((uint32_t)(type)), addr); +} + +static inline +void dma350_ch_set_destriginmode(void __iomem *addr, enum dma350_ch_destriginmode_t mode) +{ + writel((readl(addr) & ~DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Msk) | ((uint32_t)(mode)), addr); +} + +static inline +void dma350_ch_set_destriginblksize(void __iomem *addr, uint8_t blksize) +{ + SET_FIELD(addr, blksize, + DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos, + DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Msk); +} + +static inline +void dma350_ch_set_linkmemattrlo(void __iomem *addr, uint8_t memattrlo) +{ + SET_FIELD(addr, memattrlo, + DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos, + DMA350_CH_LINKATTR_LINKMEMATTRLO_Msk); +} + +static inline +void dma350_ch_set_linkmemattrhi(void __iomem *addr, uint8_t memattrhi) +{ + SET_FIELD(addr, memattrhi, + DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos, + DMA350_CH_LINKATTR_LINKMEMATTRHI_Msk); +} + +static inline +void dma350_ch_set_linkshareattr(void __iomem *addr, uint8_t shareattr) +{ + SET_FIELD(addr, shareattr, + DMA350_CH_LINKATTR_LINKSHAREATTR_Pos, + DMA350_CH_LINKATTR_LINKSHAREATTR_Msk); +} + +static inline +void dma350_ch_enable_linkaddr(void __iomem *addr) +{ + writel(readl(addr) | DMA350_CH_LINKADDR_LINKADDREN_Msk, addr); +} + +static inline +void dma350_ch_set_linkaddr32(void __iomem *addr, uint32_t linkaddr) +{ + writel(linkaddr, addr); +} + +static inline +void dma350_ch_disable_linkaddr(void __iomem *addr) +{ + writel(0, addr); +} + +static inline +void dma350_cmdlink_set_regclear(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CLEAR_SET; +} + +static inline +void dma350_cmdlink_enable_intr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_intr_t intr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_INTREN_SET; + cmdlink_cfg->cfg.intren |= intr; +} + +static inline +void dma350_cmdlink_disable_intr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_intr_t intr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_INTREN_SET; + cmdlink_cfg->cfg.intren &= (~intr); +} + +static inline +void dma350_cmdlink_set_transize(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint32_t transize) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl = + (cmdlink_cfg->cfg.ctrl & (~DMA350_CH_CTRL_TRANSIZE_Msk)) | + (transize & DMA350_CH_CTRL_TRANSIZE_Msk); +} + +static inline +void dma350_cmdlink_set_chprio(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint8_t chprio) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl = + (cmdlink_cfg->cfg.ctrl & (~DMA350_CH_CTRL_CHPRIO_Msk)) | + (((chprio & 0x000000FFUL) << DMA350_CH_CTRL_CHPRIO_Pos) & + DMA350_CH_CTRL_CHPRIO_Msk); +} + +static inline +void dma350_cmdlink_set_xtype(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_xtype_t xtype) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl = (cmdlink_cfg->cfg.ctrl & (~DMA350_CH_CTRL_XTYPE_Msk)) | + (xtype & DMA350_CH_CTRL_XTYPE_Msk); +} + +static inline +void dma350_cmdlink_set_donetype(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + enum dma350_ch_donetype_t donetype) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl = + (cmdlink_cfg->cfg.ctrl & (~DMA350_CH_CTRL_DONETYPE_Msk)) | + (donetype & DMA350_CH_CTRL_DONETYPE_Msk); +} + +static inline +void dma350_cmdlink_enable_donepause(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl |= DMA350_CH_CTRL_DONEPAUSEEN_Msk; +} + +static inline +void dma350_cmdlink_disable_donepause(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl &= (~DMA350_CH_CTRL_DONEPAUSEEN_Msk); +} + +static inline +void dma350_cmdlink_enable_srctrigin(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl |= DMA350_CH_CTRL_USESRCTRIGIN_Msk; +} + +static inline +void dma350_cmdlink_disable_srctrigin(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl &= (~DMA350_CH_CTRL_USESRCTRIGIN_Msk); +} + +static inline +void dma350_cmdlink_enable_destrigin(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl |= DMA350_CH_CTRL_USEDESTRIGIN_Msk; +} + +static inline +void dma350_cmdlink_disable_destrigin(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl &= (~DMA350_CH_CTRL_USEDESTRIGIN_Msk); +} + +static inline +void dma350_cmdlink_enable_trigout(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl |= DMA350_CH_CTRL_USETRIGOUT_Msk; +} + +static inline +void dma350_cmdlink_disable_trigout(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl &= (~DMA350_CH_CTRL_USETRIGOUT_Msk); +} + +static inline +void dma350_cmdlink_enable_gpo(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl |= DMA350_CH_CTRL_USEGPO_Msk; +} + +static inline +void dma350_cmdlink_disable_gpo(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl &= (~DMA350_CH_CTRL_USEGPO_Msk); +} + +static inline +void dma350_cmdlink_enable_stream(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl |= DMA350_CH_CTRL_USESTREAM_Msk; +} + +static inline +void dma350_cmdlink_disable_stream(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_CTRL_SET; + cmdlink_cfg->cfg.ctrl &= (~DMA350_CH_CTRL_USESTREAM_Msk); +} + +static inline +void dma350_cmdlink_set_srcaddr32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t src_addr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRC_ADDR_SET; + cmdlink_cfg->header &= (~DMA350_CMDLINK_SRC_ADDRHI_SET); + cmdlink_cfg->cfg.srcaddr = src_addr; +} + +static inline +void dma350_cmdlink_set_desaddr32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t des_addr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DES_ADDR_SET; + cmdlink_cfg->header &= (~DMA350_CMDLINK_DES_ADDRHI_SET); + cmdlink_cfg->cfg.desaddr = des_addr; +} + +static inline +void dma350_cmdlink_set_xsize16(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint16_t src_xsize, uint16_t des_xsize) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_XSIZE_SET; + cmdlink_cfg->header &= (~DMA350_CMDLINK_XSIZEHI_SET); + cmdlink_cfg->cfg.xsize = (des_xsize & 0x0000FFFFUL) + << DMA350_CH_XSIZE_DESXSIZE_Pos; + cmdlink_cfg->cfg.xsize |= (src_xsize & 0x0000FFFFUL) + << DMA350_CH_XSIZE_SRCXSIZE_Pos; +} + +static inline +void dma350_cmdlink_set_xsize32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint32_t src_xsize, uint32_t des_xsize) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_XSIZE_SET; + cmdlink_cfg->header |= DMA350_CMDLINK_XSIZEHI_SET; + cmdlink_cfg->cfg.xsize = (des_xsize & 0x0000FFFFUL) + << DMA350_CH_XSIZE_DESXSIZE_Pos; + cmdlink_cfg->cfg.xsize |= (src_xsize & 0x0000FFFFUL) + << DMA350_CH_XSIZE_SRCXSIZE_Pos; + cmdlink_cfg->cfg.xsizehi = (des_xsize & 0xFFFF0000UL); + cmdlink_cfg->cfg.xsizehi |= (src_xsize & 0xFFFF0000UL) >> 16; +} + +static inline +void dma350_cmdlink_set_srcmemattrlo(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrlo) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRANSCFG_SET; + cmdlink_cfg->cfg.srctranscfg = (cmdlink_cfg->cfg.srctranscfg & + (~DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Msk)) | + (((memattrlo & 0x000000FFUL) << DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos) & + DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Msk); +} + +static inline +void dma350_cmdlink_set_srcmemattrhi(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrhi) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRANSCFG_SET; + cmdlink_cfg->cfg.srctranscfg = (cmdlink_cfg->cfg.srctranscfg & + (~DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Msk)) | + (((memattrhi & 0x000000FFUL) << DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos) & + DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Msk); +} + +static inline +void dma350_cmdlink_set_srcshareattr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t shareattr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRANSCFG_SET; + cmdlink_cfg->cfg.srctranscfg = (cmdlink_cfg->cfg.srctranscfg & + (~DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Msk)) | + (((shareattr & 0x000000FFUL) << DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Pos) & + DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Msk); +} + +static inline +void dma350_cmdlink_set_desmemattrlo(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrlo) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRANSCFG_SET; + cmdlink_cfg->cfg.destranscfg = (cmdlink_cfg->cfg.destranscfg & + (~DMA350_CH_DESTRANSCFG_DESSHAREATTR_Msk)) | + (((memattrlo & 0x000000FFUL) << DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos) & + DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Msk); +} + +static inline +void dma350_cmdlink_set_desmemattrhi(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrhi) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRANSCFG_SET; + cmdlink_cfg->cfg.destranscfg = (cmdlink_cfg->cfg.destranscfg & + (~DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Msk)) | + (((memattrhi & 0x000000FFUL) << DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos) & + DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Msk); +} + +static inline +void dma350_cmdlink_set_desshareattr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t shareattr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRANSCFG_SET; + cmdlink_cfg->cfg.destranscfg = (cmdlink_cfg->cfg.destranscfg & + (~DMA350_CH_DESTRANSCFG_DESSHAREATTR_Msk)) | + (((shareattr & 0x000000FFUL) << DMA350_CH_DESTRANSCFG_DESSHAREATTR_Pos) & + DMA350_CH_DESTRANSCFG_DESSHAREATTR_Msk); +} + +static inline +void dma350_cmdlink_set_src_trans_secure(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRANSCFG_SET; + cmdlink_cfg->cfg.srctranscfg &= (~DMA350_CH_SRCTRANSCFG_SRCNONSECATTR_Msk); +} + +static inline +void dma350_cmdlink_set_src_trans_nonsecure(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->cfg.srctranscfg |= DMA350_CH_SRCTRANSCFG_SRCNONSECATTR_Msk; + if (cmdlink_cfg->cfg.srctranscfg == DMA350_CH_SRCTRANSCFG_RESET_VALUE) + cmdlink_cfg->header &= (~DMA350_CMDLINK_SRCTRANSCFG_SET); +} + +static inline +void dma350_cmdlink_set_des_trans_secure(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRANSCFG_SET; + cmdlink_cfg->cfg.destranscfg &= (~DMA350_CH_DESTRANSCFG_DESNONSECATTR_Msk); +} + +static inline +void dma350_cmdlink_set_des_trans_nonsecure(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->cfg.destranscfg |= DMA350_CH_DESTRANSCFG_DESNONSECATTR_Msk; + if (cmdlink_cfg->cfg.destranscfg == DMA350_CH_DESTRANSCFG_RESET_VALUE) + cmdlink_cfg->header &= (~DMA350_CMDLINK_DESTRANSCFG_SET); +} + +static inline +void dma350_cmdlink_set_src_trans_privileged(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRANSCFG_SET; + cmdlink_cfg->cfg.srctranscfg |= DMA350_CH_SRCTRANSCFG_SRCPRIVATTR_Msk; +} + +static inline +void dma350_cmdlink_set_src_trans_unprivileged(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->cfg.srctranscfg &= (~DMA350_CH_SRCTRANSCFG_SRCPRIVATTR_Msk); + if (cmdlink_cfg->cfg.srctranscfg == DMA350_CH_SRCTRANSCFG_RESET_VALUE) + cmdlink_cfg->header &= (~DMA350_CMDLINK_SRCTRANSCFG_SET); +} + +static inline +void dma350_cmdlink_set_des_trans_privileged(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRANSCFG_SET; + cmdlink_cfg->cfg.destranscfg |= DMA350_CH_DESTRANSCFG_DESPRIVATTR_Msk; +} + +static inline +void dma350_cmdlink_set_des_trans_unprivileged(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->cfg.destranscfg &= (~DMA350_CH_DESTRANSCFG_DESPRIVATTR_Msk); + if (cmdlink_cfg->cfg.destranscfg == DMA350_CH_DESTRANSCFG_RESET_VALUE) + cmdlink_cfg->header &= (~DMA350_CMDLINK_DESTRANSCFG_SET); +} + +static inline +void dma350_cmdlink_set_srcmaxburstlen(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t length) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRANSCFG_SET; + cmdlink_cfg->cfg.srctranscfg = (cmdlink_cfg->cfg.srctranscfg & + (~DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Msk)) | + (((length & 0x000000FFUL) << DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos) & + DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Msk); +} + +static inline +void dma350_cmdlink_set_desmaxburstlen(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t length) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRANSCFG_SET; + cmdlink_cfg->cfg.destranscfg = (cmdlink_cfg->cfg.destranscfg & + (~DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Msk)) | + (((length & 0x000000FFUL) << DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos) & + DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Msk); +} + +static inline +void dma350_cmdlink_set_xaddrinc(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, + uint16_t src_xaddrinc, uint16_t des_xaddrinc) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_XADDRINC_SET; + cmdlink_cfg->cfg.xaddrinc = (des_xaddrinc & 0x0000FFFFUL) + << DMA350_CH_XADDRINC_DESXADDRINC_Pos; + cmdlink_cfg->cfg.xaddrinc |= (src_xaddrinc & 0x0000FFFFUL) + << DMA350_CH_XADDRINC_SRCXADDRINC_Pos; +} + + +static inline +void dma350_cmdlink_set_srctriginsel(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t srctriginsel) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRIGINCFG_SET; + cmdlink_cfg->cfg.srctrigincfg = (cmdlink_cfg->cfg.srctrigincfg & + (~DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Msk)) | + (((srctriginsel & 0x000000FFUL) + << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) & + DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Msk); +} + +static inline +void dma350_cmdlink_set_srctrigintype(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, enum dma350_ch_srctrigintype_t type) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRIGINCFG_SET; + cmdlink_cfg->cfg.srctrigincfg = (cmdlink_cfg->cfg.srctrigincfg & + (~DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Msk)) | + (type & DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Msk); +} + +static inline +void dma350_cmdlink_set_srctriginmode(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, enum dma350_ch_srctriginmode_t mode) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRIGINCFG_SET; + cmdlink_cfg->cfg.srctrigincfg = (cmdlink_cfg->cfg.srctrigincfg & + (~DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Msk)) | + (mode & DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Msk); +} + +static inline +void dma350_cmdlink_set_srctriginblksize(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t blksize) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_SRCTRIGINCFG_SET; + cmdlink_cfg->cfg.srctrigincfg = (cmdlink_cfg->cfg.srctrigincfg & + (~DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Msk)) | (((blksize & 0x000000FFUL) + << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) & + DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Msk); +} + +static inline +void dma350_cmdlink_set_destriginsel(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t destriginsel) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRIGINCFG_SET; + cmdlink_cfg->cfg.destrigincfg = (cmdlink_cfg->cfg.destrigincfg & + (~DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Msk)) | + (((destriginsel & 0x000000FFUL) << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) & + DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Msk); +} + +static inline +void dma350_cmdlink_set_destrigintype(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, enum dma350_ch_destrigintype_t type) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRIGINCFG_SET; + cmdlink_cfg->cfg.destrigincfg = (cmdlink_cfg->cfg.destrigincfg & + (~DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Msk)) | + (type & DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Msk); +} + +static inline +void dma350_cmdlink_set_destriginmode(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, enum dma350_ch_destriginmode_t mode) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRIGINCFG_SET; + cmdlink_cfg->cfg.destrigincfg = (cmdlink_cfg->cfg.destrigincfg & + (~DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Msk)) | (mode & DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Msk); +} + +static inline +void dma350_cmdlink_set_destriginblksize(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t blksize) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_DESTRIGINCFG_SET; + cmdlink_cfg->cfg.destrigincfg = (cmdlink_cfg->cfg.destrigincfg & + (~DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Msk)) | (((blksize & 0x000000FFUL) + << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) & DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Msk); +} + + +static inline +void dma350_cmdlink_set_linkmemattrlo(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrlo) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_LINKATTR_SET; + cmdlink_cfg->cfg.linkattr = (cmdlink_cfg->cfg.linkattr & (~DMA350_CH_LINKATTR_LINKMEMATTRLO_Msk)) | + (((memattrlo & 0x000000FFUL) << DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos) & + DMA350_CH_LINKATTR_LINKMEMATTRLO_Msk); +} + +static inline +void dma350_cmdlink_set_linkmemattrhi(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t memattrhi) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_LINKATTR_SET; + cmdlink_cfg->cfg.linkattr = (cmdlink_cfg->cfg.linkattr & (~DMA350_CH_LINKATTR_LINKMEMATTRHI_Msk)) | + (((memattrhi & 0x000000FFUL) << DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos) & + DMA350_CH_LINKATTR_LINKMEMATTRHI_Msk); +} + +static inline +void dma350_cmdlink_set_linkshareattr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint8_t shareattr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_LINKATTR_SET; + cmdlink_cfg->cfg.linkattr = (cmdlink_cfg->cfg.linkattr & (~DMA350_CH_LINKATTR_LINKSHAREATTR_Msk)) | + (((shareattr & 0x000000FFUL) << DMA350_CH_LINKATTR_LINKSHAREATTR_Pos) & + DMA350_CH_LINKATTR_LINKSHAREATTR_Msk); +} + + +static inline +void dma350_cmdlink_enable_cmdrestartinfen(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_AUTOCFG_SET; + cmdlink_cfg->cfg.autocfg |= DMA350_CH_AUTOCFG_CMDRESTARTINFEN_Msk; +} + +static inline +void dma350_cmdlink_disable_cmdrestartinfen(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_AUTOCFG_SET; + cmdlink_cfg->cfg.autocfg &= (~DMA350_CH_AUTOCFG_CMDRESTARTINFEN_Msk); +} + +static inline +void dma350_cmdlink_enable_linkaddr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_LINKADDR_SET; + cmdlink_cfg->cfg.linkaddr |= DMA350_CH_LINKADDR_LINKADDREN_Msk; +} + +static inline +void dma350_cmdlink_disable_linkaddr(struct dma350_cmdlink_gencfg_t *cmdlink_cfg) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_LINKADDR_SET; + cmdlink_cfg->cfg.linkaddr &= ~(DMA350_CH_LINKADDR_LINKADDREN_Msk); +} + +static inline +void dma350_cmdlink_set_linkaddr32(struct dma350_cmdlink_gencfg_t *cmdlink_cfg, uint32_t linkaddr) +{ + cmdlink_cfg->header |= DMA350_CMDLINK_LINKADDR_SET; + cmdlink_cfg->header &= ~(DMA350_CMDLINK_LINKADDRHI_SET); + cmdlink_cfg->cfg.linkaddr = (cmdlink_cfg->cfg.linkaddr & (~DMA350_CH_LINKADDR_LINKADDR_Msk)) | + (linkaddr & DMA350_CH_LINKADDR_LINKADDR_Msk); +} + +static inline +void dma350_ch_cmd(void __iomem *addr, uint32_t cmd) +{ + writel(cmd, addr); +} + +static inline +void dma350_ch_enable_intr(void __iomem *addr, uint32_t intr) +{ + writel(readl(addr) | intr, addr); +} + +static inline +void dma350_ch_disable_intr(void __iomem *addr, uint32_t intr) +{ + writel(readl(addr) & (~intr), addr); +} + +#ifdef __cplusplus +} +#endif +#endif /* __DMA350_CH_DRV_H */ diff --git a/drivers/dma/dma350_regdef.h b/drivers/dma/dma350_regdef.h new file mode 100755 index 000000000000..2dc313c0a29c --- /dev/null +++ b/drivers/dma/dma350_regdef.h @@ -0,0 +1,1148 @@ +/* SPDX-License-Identifier: Apache-2.0 OR GPL-2.0*/ +/* + * Copyright (c) 2022 Arm Limited. All rights reserved. + * Copyright 2024 Cix Technology Group Co., Ltd. + */ +#ifndef __DMA350_REGDEF_H +#define __DMA350_REGDEF_H + +/*DMA350 register define*/ +/*DMACH register summary*/ + +#define DMA350_REG_CMD 0x000 /* Channel DMA Command Register */ +#define DMA350_REG_STATUS 0x004 /* Channel Status Register */ +#define DMA350_REG_INTREN 0x008 /*Channel Interrupt Enable Register */ +#define DMA350_REG_CTRL 0x00C /*Channel Control Register */ +#define DMA350_REG_SRCADDR 0x010 /*Channel Source Address Register */ +#define DMA350_REG_DESADDR 0x018 /*Channel Destination Address Register */ +#define DMA350_REG_XSIZE 0x020 /*Channel X Dimension Size Register, Lower Bits [15:0] */ +#define DMA350_REG_XSIZEHI 0x024 /*Channel X Dimension Size Register, Lower Bits [31:16] */ +#define DMA350_REG_SRCTRANSCFG 0x028 /*Channel Source Transfer Configuration Register */ +#define DMA350_REG_DESTRANSCFG 0x02C /*Channel Destination Transfer Configuration Register */ +#define DMA350_REG_XADDRINC 0x030 /*Channel X Dimension Address Increment Register */ +#define DMA350_REG_YADDRSTRIDE 0x034 /*Channel Y Dimension Address Stride Register */ +#define DMA350_REG_FILLVAL 0x038 /*Channel Fill Pattern Value Register */ +#define DMA350_REG_YSIZE 0x03C /*Channel Y Dimensions Size Register */ +#define DMA350_REG_TMPLTCFG 0x040 /*Channel Template Configuration Register */ +#define DMA350_REG_SRCTMPLT 0x044 /*Channel Source Template Pattern Register */ +#define DMA350_REG_DESTMPLT 0x048 /*Channel Destination Template Pattern Register */ +#define DMA350_REG_SRCTRIGINCFG 0x04C /*Channel Source Trigger In Configuration Register */ +#define DMA350_REG_DESTRIGINCFG 0x050 /*Channel Destination Trigger In Configuration Register */ +#define DMA350_REG_LINKATTR 0x070 /* Channel Link Address Memory Attributes Register */ +#define DMA350_REG_AUTOCFG 0x074 /*Channel Automatic Command Restart Configuration Register */ +#define DMA350_REG_LINKADDR 0x078 /* Channel Link Address Register */ +#define DMA350_REG_LINKADDRHI 0x07C /* Channel Link Address Register, High Bits [63:32] */ +#define DMA350_REG_GPOREAD0 0x080 /* Channel GPO Read Value Register 0 */ +#define DMA350_REG_WRKREGPTR 0x088 /* Channel Working Register Pointer Register */ +#define DMA350_REG_WRKREGVAL 0x08C /* Channel - Working Register Value Register */ +#define DMA350_REG_ERRINFO 0x090 /* Channel Error Information Register */ +#define DMA350_REG_IIDR 0x0C8 /* Channel Implementation Identification Register */ +#define DMA350_REG_AIDR 0x0CC /* Channel Architecture Identification Register */ +#define DMA350_REG_ISSUECAP 0x0E8 /* Used for setting issuing capability threshold. */ + +#define DMA350_REG_CHINTRSTATUS0 0x200 /*Collated Non-Secure Channel Interrupt flags for channel 0 to channel 31*/ +#define DMA350_NONSSEC_CTRL 0xC + +/******************************************************************************/ +/* Field Definitions of Registers */ +/******************************************************************************/ +/******************************************************************************/ +/* DMACH */ +/******************************************************************************/ +/****************** Field definitions for CH_CMD register *******************/ +#define DMA350_CH_CMD_ENABLECMD_Pos (0U) +#define DMA350_CH_CMD_ENABLECMD_Msk (0x1UL << DMA350_CH_CMD_ENABLECMD_Pos) +#define CMD_ENABLECMD_Msk (1) +#define DMA350_CH_CMD_ENABLECMD (CMD_ENABLECMD_Msk) +/*!< ENABLECMD bit Channel Enable. When set to '1', enables the channel to + * run its programmed task. When set to '1', it cannot be set back to zero, + * and this field will automatically clear to zero when a DMA process is completed. + * To force the DMA to stop prematurely, you must use CH_CMD.STOPCMD instead. + */ + +#define DMA350_CH_CMD_CLEARCMD_Pos (1U) +#define DMA350_CH_CMD_CLEARCMD_Msk (0x1UL << DMA350_CH_CMD_CLEARCMD_Pos) /*!< 0x00000002UL*/ +#define DMA350_CH_CMD_CLEARCMD DMA350_CH_CMD_CLEARCMD_Msk +/*!< CLEARCMD bit DMA Clear command. When set to '1', it will remain high until all DMA + * channel registers and any internal queues and buffers are cleared, before returning to '0'. + * When set at the same time as ENABLECMD or while the DMA channel is already enabled, + * the clear will only occur after any ongoing DMA operation is either completed, + * stopped or disabled and the ENABLECMD bit is deasserted by the DMA. + */ +#define DMA350_CH_CMD_DISABLECMD_Pos (2U) +#define DMA350_CH_CMD_DISABLECMD_Msk (0x1UL << DMA350_CH_CMD_DISABLECMD_Pos) /*!< 0x00000004UL*/ +#define DMA350_CH_CMD_DISABLECMD DMA350_CH_CMD_DISABLECMD_Msk +/*!< DISABLECMD bit Disable DMA Operation at the end of the current DMA + * command operation. Once set to '1', this field will stay high and the current DMA + * command will be allowed to complete, but the DMA will not fetch the next linked + * command or will it auto-restart the DMA command even if they are set. + * Once the DMA has stopped, it will return to '0' and ENABLECMD is also cleared. + * When set at the same time as ENABLECMD or when the channel is not enabled then + * write to this register is ignored. + */ +#define DMA350_CH_CMD_STOPCMD_Pos (3U) +#define DMA350_CH_CMD_STOPCMD_Msk (0x1UL << DMA350_CH_CMD_STOPCMD_Pos) /*!< 0x00000008UL*/ +#define DMA350_CH_CMD_STOPCMD DMA350_CH_CMD_STOPCMD_Msk +/*!< STOPCMD bit Stop Current DMA Operation. Once set to '1', his will remain high until + * the DMA channel is stopped cleanly. Then this will return to '0' and ENABLECMD is + * also cleared. When set at the same time as ENABLECMD or when the channel is not enabled + * then write to this register is ignored. Note that each DMA channel can have other sources + * of a stop request and this field will not reflect the state of the other sources. + */ +#define DMA350_CH_CMD_PAUSECMD_Pos (4U) +#define DMA350_CH_CMD_PAUSECMD_Msk (0x1UL << DMA350_CH_CMD_PAUSECMD_Pos) /*!< 0x00000010UL*/ +#define DMA350_CH_CMD_PAUSECMD DMA350_CH_CMD_PAUSECMD_Msk +/*!< PAUSECMD bit Pause Current DMA Operation. Once set to '1' the status cannot + * change until the DMA operation reached the paused state indicated by the + * STAT_PAUSED and STAT_RESUMEWAIT bits. The bit can be set by SW by writing it to '1', + * the current active DMA operation will be paused as soon as possible, but the ENABLECMD + * bit will remain HIGH to show that the operation is still active. + * Cleared automatically when STAT_RESUMEWAIT is set and the RESUMECMD bit is written to '1', + * meaning that the SW continues the operation of the channel. + * Note that each DMA channel can have other sources of a pause request and this field will + * not reflect the state of the other sources. When set at the same time as ENABLECMD or + * when the channel is not enabled then write to this register is ignored. + */ +#define DMA350_CH_CMD_RESUMECMD_Pos (5U) +#define DMA350_CH_CMD_RESUMECMD_Msk (0x1UL << DMA350_CH_CMD_RESUMECMD_Pos) /*!< 0x00000020UL*/ +#define DMA350_CH_CMD_RESUMECMD DMA350_CH_CMD_RESUMECMD_Msk +/*!< RESUMECMD bit Resume Current DMA Operation. + * Writing this bit to '1' means that the DMAC can continue + * the operation of a paused channel. Can be set to '1' when + * the PAUSECMD or a STAT_DONE assertion with DONEPAUSEEN set + * HIGH results in pausing the current DMA channel operation + * indicated by the STAT_PAUSED and STAT_RESUMEWAIT bits. + * Otherwise, writes to this bit are ignored. + */ +#define DMA350_CH_CMD_SRCSWTRIGINREQ_Pos (16U) +#define DMA350_CH_CMD_SRCSWTRIGINREQ_Msk (0x1UL << DMA350_CH_CMD_SRCSWTRIGINREQ_Pos) /*!< 0x00010000UL*/ +#define DMA350_CH_CMD_SRCSWTRIGINREQ DMA350_CH_CMD_SRCSWTRIGINREQ_Msk +/*!< SRCSWTRIGINREQ bit Software Generated Source Trigger Input Request. + * Write to '1' to create a SW trigger request to the DMA with the specified type + * in the SRCSWTRIGINTYPE register. Once set to '1', this will remain high until + * the DMA accepted the trigger and will return this to '0'. + * It will also be cleared automatically if the current command is completed + * without expecting another trigger event. + * When the channel is not enabled, write to this register is ignored. + */ +#define DMA350_CH_CMD_SRCSWTRIGINTYPE_Pos (17U) +#define DMA350_CH_CMD_SRCSWTRIGINTYPE_Msk (0x3UL << DMA350_CH_CMD_SRCSWTRIGINTYPE_Pos) /*!< 0x00060000UL*/ +#define DMA350_CH_CMD_SRCSWTRIGINTYPE DMA350_CH_CMD_SRCSWTRIGINTYPE_Msk +/*!< SRCSWTRIGINTYPE[ 1:0] bits Software Generated Source Trigger Input Request Type. + * Selects the trigger request type for the source trigger input when the SW triggers the SRCSWTRIGINREQ bit. + *- 00: Single request + *- 01: Last single request + *- 10: Block request + *- 11: Last block request + *This field cannot be changed while the SRCSWTRIGINREQ bit is set. + */ +#define DMA350_CH_CMD_SRCSWTRIGINTYPE_0 (0x1UL << DMA350_CH_CMD_SRCSWTRIGINTYPE_Pos) /*!< 0x00020000UL*/ +#define DMA350_CH_CMD_SRCSWTRIGINTYPE_1 (0x2UL << DMA350_CH_CMD_SRCSWTRIGINTYPE_Pos) /*!< 0x00040000UL*/ +#define DMA350_CH_CMD_DESSWTRIGINREQ_Pos (20U) +#define DMA350_CH_CMD_DESSWTRIGINREQ_Msk (0x1UL << DMA350_CH_CMD_DESSWTRIGINREQ_Pos) /*!< 0x00100000UL*/ +#define DMA350_CH_CMD_DESSWTRIGINREQ DMA350_CH_CMD_DESSWTRIGINREQ_Msk +/*!< DESSWTRIGINREQ bit Software Generated Destination Trigger Input Request. + * Write to '1' to create a SW trigger request to the DMA with the specified + * type in the DESSWTRIGINTYPE register. Once set to '1', this will remain + * high until the DMA is accepted the trigger and will return this to '0'. + * It will also be cleared automatically if the current command is completed + * without expecting another trigger event. + * When the channel is not enabled, write to this register is ignored. + */ +#define DMA350_CH_CMD_DESSWTRIGINTYPE_Pos (21U) +#define DMA350_CH_CMD_DESSWTRIGINTYPE_Msk (0x3UL << DMA350_CH_CMD_DESSWTRIGINTYPE_Pos) /*!< 0x00600000UL*/ +#define DMA350_CH_CMD_DESSWTRIGINTYPE DMA350_CH_CMD_DESSWTRIGINTYPE_Msk +/*!< DESSWTRIGINTYPE[ 1:0] bits Software Generated Destination Trigger Input Request Type. + * Selects the trigger request type for the destination trigger input when the SW triggers the DESSWTRIGINREQ bit. + * - 00: Single request + * - 01: Last single request + * - 10: Block request + * - 11: Last block request + *This field cannot be changed while the DESSWTRIGINREQ bit is set. + */ +#define DMA350_CH_CMD_DESSWTRIGINTYPE_0 (0x1UL << DMA350_CH_CMD_DESSWTRIGINTYPE_Pos) /*!< 0x00200000UL*/ +#define DMA350_CH_CMD_DESSWTRIGINTYPE_1 (0x2UL << DMA350_CH_CMD_DESSWTRIGINTYPE_Pos) /*!< 0x00400000UL*/ +#define DMA350_CH_CMD_SWTRIGOUTACK_Pos (24U) +#define DMA350_CH_CMD_SWTRIGOUTACK_Msk (0x1UL << DMA350_CH_CMD_SWTRIGOUTACK_Pos) /*!< 0x01000000UL*/ +#define DMA350_CH_CMD_SWTRIGOUTACK DMA350_CH_CMD_SWTRIGOUTACK_Msk +/*!< SWTRIGOUTACK bit Software Generated Trigger Output Acknowledge. + * Write '1' to acknowledge a Trigger Output request from the DMA. + * Once set to '1', this will remain high until the DMA Trigger Output + * is raised (either on the trigger output signal or as an interrupt) and + * the acknowledge is accepted. When the channel is not enabled, write to this register is ignored. + */ +/***************** Field definitions for CH_STATUS register *****************/ +#define DMA350_CH_STATUS_INTR_DONE_Pos (0U) +#define DMA350_CH_STATUS_INTR_DONE_Msk (0x1UL << DMA350_CH_STATUS_INTR_DONE_Pos) +#define DMA350_CH_STATUS_INTR_DONE DMA350_CH_STATUS_INTR_DONE_Msk +/*!< INTR_DONE bit Done Interrupt Flag. This interrupt will be set to HIGH if the INTREN_DONE + * is set and the STAT_DONE status flag gets raised. + * Automatically cleared when STAT_DONE is cleared. + */ +#define DMA350_CH_STATUS_INTR_ERR_Pos (1U) +#define DMA350_CH_STATUS_INTR_ERR_Msk (0x1UL << DMA350_CH_STATUS_INTR_ERR_Pos) +#define DMA350_CH_STATUS_INTR_ERR DMA350_CH_STATUS_INTR_ERR_Msk +/*!< INTR_ERR bit Error Interrupt Flag. This interrupt will be set to HIGH if the INTREN_ERR + * is set and the STAT_ERR status flag gets raised. + * Automatically cleared when STAT_ERR is cleared. + */ +#define DMA350_CH_STATUS_INTR_DISABLED_Pos (2U) +#define DMA350_CH_STATUS_INTR_DISABLED_Msk (0x1UL << DMA350_CH_STATUS_INTR_DISABLED_Pos) +#define DMA350_CH_STATUS_INTR_DISABLED DMA350_CH_STATUS_INTR_DISABLED_Msk +/*!< INTR_DISABLED bit Disabled Interrupt Flag. This interrupt will be set to HIGH if the + * INTREN_DISABLED is set and the STAT_DISABLED flag gets raised. + * Automatically cleared when STAT_DISABLED is cleared. + */ +#define DMA350_CH_STATUS_INTR_STOPPED_Pos (3U) +#define DMA350_CH_STATUS_INTR_STOPPED_Msk (0x1UL << DMA350_CH_STATUS_INTR_STOPPED_Pos) +#define DMA350_CH_STATUS_INTR_STOPPED DMA350_CH_STATUS_INTR_STOPPED_Msk +/*!< INTR_STOPPED bit Stopped Interrupt Flag. This interrupt will be set to HIGH if the INTREN_STOPPED + * is set and the STAT_STOPPED flag gets raised. Automatically cleared when STAT_STOPPED is cleared. + */ +#define DMA350_CH_STATUS_INTR_SRCTRIGINWAIT_Pos (8U) +#define DMA350_CH_STATUS_INTR_SRCTRIGINWAIT_Msk (0x1UL << DMA350_CH_STATUS_INTR_SRCTRIGINWAIT_Pos) +#define DMA350_CH_STATUS_INTR_SRCTRIGINWAIT DMA350_CH_STATUS_INTR_SRCTRIGINWAIT_Msk +/*!< INTR_SRCTRIGINWAIT bit Channel is waiting for Source Trigger Interrupt Flag. + * This interrupt will be set to HIGH if the INTREN_SRCTRIGINWAIT is set and the STAT_SRCTRIGINWAIT + * status flag is asserted. Automatically cleared when STAT_SRCTRIGINWAIT is cleared. + */ +#define DMA350_CH_STATUS_INTR_DESTRIGINWAIT_Pos (9U) +#define DMA350_CH_STATUS_INTR_DESTRIGINWAIT_Msk (0x1UL << DMA350_CH_STATUS_INTR_DESTRIGINWAIT_Pos) +#define DMA350_CH_STATUS_INTR_DESTRIGINWAIT DMA350_CH_STATUS_INTR_DESTRIGINWAIT_Msk +/*!< INTR_DESTRIGINWAIT bit Channel is waiting for Destination Trigger Interrupt Flag. + * This interrupt will be set to HIGH if the INTREN_DESTRIGINWAIT is set and the STAT_DESTRIGINWAIT + * status flag is asserted. Automatically cleared when STAT_DESTRIGINWAIT is cleared. + */ +#define DMA350_CH_STATUS_INTR_TRIGOUTACKWAIT_Pos (10U) +#define DMA350_CH_STATUS_INTR_TRIGOUTACKWAIT_Msk (0x1UL << DMA350_CH_STATUS_INTR_TRIGOUTACKWAIT_Pos) +#define DMA350_CH_STATUS_INTR_TRIGOUTACKWAIT DMA350_CH_STATUS_INTR_TRIGOUTACKWAIT_Msk +/*!< INTR_TRIGOUTACKWAIT bit Channel is waiting for output Trigger Acknowledgment Interrupt Flag. + * This interrupt will be set to HIGH if the INTREN_TRIGOUTACKWAIT is set and the STAT_TRIGOUTACKWAIT + * status flag is asserted. Automatically cleared when STAT_TRIGOUTACKWAIT is cleared. + */ +#define DMA350_CH_STATUS_STAT_DONE_Pos (16U) +#define DMA350_CH_STATUS_STAT_DONE_Msk (0x1UL << DMA350_CH_STATUS_STAT_DONE_Pos) /*!< 0x00010000UL*/ +#define DMA350_CH_STATUS_STAT_DONE DMA350_CH_STATUS_STAT_DONE_Msk +/*!< STAT_DONE bit Done Status Flag. This flag will be set to HIGH when the DMA command + * reaches the state defined by the DONETYPE settings. When DONEPAUSEEN is set the DMA + * command operation is paused when this flag is asserted. + * Write '1' to this bit to clear it. Automatically cleared when the ENABLECMD is set. + */ +#define DMA350_CH_STATUS_STAT_ERR_Pos (17U) +#define DMA350_CH_STATUS_STAT_ERR_Msk (0x1UL << DMA350_CH_STATUS_STAT_ERR_Pos) /*!< 0x00020000UL*/ +#define DMA350_CH_STATUS_STAT_ERR DMA350_CH_STATUS_STAT_ERR_Msk +/*!< STAT_ERR bit Error Status Flag. This flag will be set to HIGH if the DMA encounters an error during its operation. + * The details about the error event can be found in the ERRINFO register. Write '1' to this bit to clear it. + * When cleared, it also clears the ERRINFO register. Automatically cleared when the ENABLECMD is set. + */ +#define DMA350_CH_STATUS_STAT_DISABLED_Pos (18U) +#define DMA350_CH_STATUS_STAT_DISABLED_Msk (0x1UL << DMA350_CH_STATUS_STAT_DISABLED_Pos) /*!< 0x00040000UL*/ +#define DMA350_CH_STATUS_STAT_DISABLED DMA350_CH_STATUS_STAT_DISABLED_Msk +/*!< STAT_DISABLED bit Disabled Status Flag. This flag will be set to HIGH if the DMA channel + * is successfully disabled using the DISABLECMD command. + * Write '1' to this bit to clear it. Automatically cleared when the ENABLECMD is set. + */ +#define DMA350_CH_STATUS_STAT_STOPPED_Pos (19U) +#define DMA350_CH_STATUS_STAT_STOPPED_Msk (0x1UL << DMA350_CH_STATUS_STAT_STOPPED_Pos) /*!< 0x00080000UL*/ +#define DMA350_CH_STATUS_STAT_STOPPED DMA350_CH_STATUS_STAT_STOPPED_Msk +/*!< STAT_STOPPED bit Stopped Status Flag. This flag will be set to HIGH if the DMA channel + * successfully reached the stopped state. The stop request can come from many internal or external sources. + * Write '1' to this bit to clear it. Automatically cleared when the ENABLECMD is set. + */ +#define DMA350_CH_STATUS_STAT_PAUSED_Pos (20U) +#define DMA350_CH_STATUS_STAT_PAUSED_Msk (0x1UL << DMA350_CH_STATUS_STAT_PAUSED_Pos) /*!< 0x00100000UL*/ +#define DMA350_CH_STATUS_STAT_PAUSED DMA350_CH_STATUS_STAT_PAUSED_Msk +/*!< STAT_PAUSED bit Paused Status Flag. This flag will be set to HIGH if the DMA channel + * successfully paused the operation of the command. The pause request can come from many + * internal or external sources. When the request to pause is not asserted anymore the + * bit will be cleared automatically and the command operation can continue. + */ +#define DMA350_CH_STATUS_STAT_RESUMEWAIT_Pos (21U) +#define DMA350_CH_STATUS_STAT_RESUMEWAIT_Msk (0x1UL << DMA350_CH_STATUS_STAT_RESUMEWAIT_Pos) +#define DMA350_CH_STATUS_STAT_RESUMEWAIT DMA350_CH_STATUS_STAT_RESUMEWAIT_Msk +/*!< STAT_RESUMEWAIT bit Waiting for resume from software Flag. + * This flag indicates that the DMA channel successfully paused the operation of the command + * and needs SW acknowledgment to resume the operation. Will be set to HIGH if STAT_PAUSED is + * asserted and the PAUSECMD bit set in the command register or when the STAT_DONE is asserted + * and the DONEPAUSEEN bit is set. Cleared when the RESUMECMD bit is set in the command register. + */ +#define DMA350_CH_STATUS_STAT_SRCTRIGINWAIT_Pos (24U) +#define DMA350_CH_STATUS_STAT_SRCTRIGINWAIT_Msk (0x1UL << DMA350_CH_STATUS_STAT_SRCTRIGINWAIT_Pos) +#define DMA350_CH_STATUS_STAT_SRCTRIGINWAIT DMA350_CH_STATUS_STAT_SRCTRIGINWAIT_Msk +/*!< STAT_SRCTRIGINWAIT bit Channel is waiting for Source Trigger Status. + * This bit is set to HIGH when DMA channel starts waiting for source input trigger request. + * Automatically cleared when the source trigger request is received either from HW or SW source. + */ +#define DMA350_CH_STATUS_STAT_DESTRIGINWAIT_Pos (25U) +#define DMA350_CH_STATUS_STAT_DESTRIGINWAIT_Msk (0x1UL << DMA350_CH_STATUS_STAT_DESTRIGINWAIT_Pos) +#define DMA350_CH_STATUS_STAT_DESTRIGINWAIT DMA350_CH_STATUS_STAT_DESTRIGINWAIT_Msk +/*!< STAT_DESTRIGINWAIT bit Channel is waiting for Destination Trigger Status. + * This bit is set to HIGH when DMA channel starts waiting for destination input trigger request. + * Automatically cleared when the destination trigger request is received either from HW or SW source. + */ +#define DMA350_CH_STATUS_STAT_TRIGOUTACKWAIT_Pos (26U) +#define DMA350_CH_STATUS_STAT_TRIGOUTACKWAIT_Msk (0x1UL << DMA350_CH_STATUS_STAT_TRIGOUTACKWAIT_Pos) +#define DMA350_CH_STATUS_STAT_TRIGOUTACKWAIT DMA350_CH_STATUS_STAT_TRIGOUTACKWAIT_Msk +/*!< STAT_TRIGOUTACKWAIT bit Channel is waiting for output Trigger Acknowledgment Status. + * This bit is set to HIGH when DMA channel starts waiting for output trigger acknowledgment. + * Automatically cleared when the output trigger acknowledgment is received either from HW or SW source. + */ +/***************** Field definitions for CH_INTREN register *****************/ +#define DMA350_CH_INTREN_INTREN_DONE_Pos (0U) +#define DMA350_CH_INTREN_INTREN_DONE_Msk (0x1UL << DMA350_CH_INTREN_INTREN_DONE_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_INTREN_INTREN_DONE DMA350_CH_INTREN_INTREN_DONE_Msk +/*!< INTREN_DONE bit Done Interrupt Enable. When set to HIGH, enables the INTR_DONE + * to be set and raise an interrupt when the STAT_DONE status flag is asserted. + * When set to LOW, it prevents INTR_DONE to be asserted. + * Currently pending interrupts are not affected by clearing this bit. + */ +#define DMA350_CH_INTREN_INTREN_ERR_Pos (1U) +#define DMA350_CH_INTREN_INTREN_ERR_Msk (0x1UL << DMA350_CH_INTREN_INTREN_ERR_Pos) /*!< 0x00000002UL*/ +#define DMA350_CH_INTREN_INTREN_ERR DMA350_CH_INTREN_INTREN_ERR_Msk +/*!< INTREN_ERR bit Error Interrupt Enable. When set to HIGH, enables INTR_ERROR to be + * set and raise an interrupt when the STAT_ERR status flag is asserted. + * When set to LOW, it prevents INTR_ERR to be asserted. + * Currently pending interrupts are not affected by clearing this bit. + */ +#define DMA350_CH_INTREN_INTREN_DISABLED_Pos (2U) +#define DMA350_CH_INTREN_INTREN_DISABLED_Msk (0x1UL << DMA350_CH_INTREN_INTREN_DISABLED_Pos) /*!< 0x00000004UL*/ +#define DMA350_CH_INTREN_INTREN_DISABLED DMA350_CH_INTREN_INTREN_DISABLED_Msk +/*!< INTREN_DISABLED bit Disabled Interrupt Enable. When set to HIGH, enables INTR_DISABLED + * to be set and raise an interrupt when STAT_DISABLED status flag is asserted. + * When set to LOW, it prevents INTR_DISABLED to be asserted. + * Currently pending interrupts are not affected by clearing this bit. + */ +#define DMA350_CH_INTREN_INTREN_STOPPED_Pos (3U) +#define DMA350_CH_INTREN_INTREN_STOPPED_Msk (0x1UL << DMA350_CH_INTREN_INTREN_STOPPED_Pos) /*!< 0x00000008UL*/ +#define DMA350_CH_INTREN_INTREN_STOPPED DMA350_CH_INTREN_INTREN_STOPPED_Msk +/*!< INTREN_STOPPED bit Stopped Interrupt Enable. When set to HIGH, enables INTR_STOPPED to be set + * and raise an interrupt when STAT_STOPPED status flag is asserted. + * When set to LOW, it prevents INTR_STOPPED to be asserted. + * Currently pending interrupts are not affected by clearing this bit. + */ +#define DMA350_CH_INTREN_INTREN_SRCTRIGINWAIT_Pos (8U) +#define DMA350_CH_INTREN_INTREN_SRCTRIGINWAIT_Msk (0x1UL << DMA350_CH_INTREN_INTREN_SRCTRIGINWAIT_Pos) +#define DMA350_CH_INTREN_INTREN_SRCTRIGINWAIT DMA350_CH_INTREN_INTREN_SRCTRIGINWAIT_Msk +/*!< INTREN_SRCTRIGINWAIT bit Channel is waiting for Source Trigger Interrupt Enable. + * When set to HIGH, enables INTR_SRCTRIGINWAIT to be set and raise an interrupt when STAT_SRCTRIGINWAIT + * status flag is asserted. When set to LOW, it prevents INTR_SRCTRIGINWAIT to be asserted. + * Currently pending interrupts are not affected by clearing this bit. + */ +#define DMA350_CH_INTREN_INTREN_DESTRIGINWAIT_Pos (9U) +#define DMA350_CH_INTREN_INTREN_DESTRIGINWAIT_Msk (0x1UL << DMA350_CH_INTREN_INTREN_DESTRIGINWAIT_Pos) +#define DMA350_CH_INTREN_INTREN_DESTRIGINWAIT DMA350_CH_INTREN_INTREN_DESTRIGINWAIT_Msk +/*!< INTREN_DESTRIGINWAIT bit Channel is waiting for destination Trigger Interrupt Enable. + * When set to HIGH, enables INTR_DESTRIGINWAIT to be set and raise an interrupt when STAT_DESTRIGINWAIT + * status flag is asserted. When set to LOW, it prevents INTR_DESTRIGINWAIT to be asserted. + * Currently pending interrupts are not affected by clearing this bit. + */ +#define DMA350_CH_INTREN_INTREN_TRIGOUTACKWAIT_Pos (10U) +#define DMA350_CH_INTREN_INTREN_TRIGOUTACKWAIT_Msk (0x1UL << DMA350_CH_INTREN_INTREN_TRIGOUTACKWAIT_Pos) +#define DMA350_CH_INTREN_INTREN_TRIGOUTACKWAIT DMA350_CH_INTREN_INTREN_TRIGOUTACKWAIT_Msk +/*!< INTREN_TRIGOUTACKWAIT bit Channel is waiting for output Trigger Acknowledgment Interrupt Enable. + * When set to HIGH, enables INTR_TRIGOUTACKWAIT to be set and raise an interrupt when STAT_TRIGOUTACKWAIT + * status flag is asserted. When set to LOW, it prevents INTR_TRIGOUTACKWAIT to be asserted. Currently pending + * interrupts are not affected by clearing this bit. + */ +/****************** Field definitions for CH_CTRL register ******************/ +#define DMA350_CH_CTRL_TRANSIZE_Pos (0U) +#define DMA350_CH_CTRL_TRANSIZE_Msk (0x7UL << DMA350_CH_CTRL_TRANSIZE_Pos) /*!< 0x00000007UL*/ +#define DMA350_CH_CTRL_TRANSIZE DMA350_CH_CTRL_TRANSIZE_Msk +/*!< TRANSIZE[ 2:0] bits Transfer Entity Size. Size in bytes = 2^TRANSIZE. + *- 000: Byte + *- 001: Halfworld + *- 010: Word + *- 011: Doubleword + *- 100: 128bits + *- 101: 256bits + *- 110: 512bits + *- 111: 1024bits + *Note that DATA_WIDTH limits this field. Address will be aligned to TRANSIZE by the DMAC by ignoring the lower bits. + */ +#define DMA350_CH_CTRL_TRANSIZE_0 (0x1UL << DMA350_CH_CTRL_TRANSIZE_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_CTRL_TRANSIZE_1 (0x2UL << DMA350_CH_CTRL_TRANSIZE_Pos) /*!< 0x00000002UL*/ +#define DMA350_CH_CTRL_TRANSIZE_2 (0x4UL << DMA350_CH_CTRL_TRANSIZE_Pos) /*!< 0x00000004UL*/ +#define DMA350_CH_CTRL_CHPRIO_Pos (4U) +#define DMA350_CH_CTRL_CHPRIO_Msk (0xFUL << DMA350_CH_CTRL_CHPRIO_Pos) /*!< 0x000000F0UL*/ +#define DMA350_CH_CTRL_CHPRIO DMA350_CH_CTRL_CHPRIO_Msk +/*!< CHPRIO[ 3:0] bits Channel Priority. + *- 0: Lowest Priority + *- 15: Highest Priority + */ +#define DMA350_CH_CTRL_CHPRIO_0 (0x1UL << DMA350_CH_CTRL_CHPRIO_Pos) /*!< 0x00000010UL*/ +#define DMA350_CH_CTRL_CHPRIO_1 (0x2UL << DMA350_CH_CTRL_CHPRIO_Pos) /*!< 0x00000020UL*/ +#define DMA350_CH_CTRL_CHPRIO_2 (0x4UL << DMA350_CH_CTRL_CHPRIO_Pos) /*!< 0x00000040UL*/ +#define DMA350_CH_CTRL_CHPRIO_3 (0x8UL << DMA350_CH_CTRL_CHPRIO_Pos) /*!< 0x00000080UL*/ +#define DMA350_CH_CTRL_XTYPE_Pos (9U) +#define DMA350_CH_CTRL_XTYPE_Msk (0x7UL << DMA350_CH_CTRL_XTYPE_Pos) /*!< 0x00000E00UL*/ +#define DMA350_CH_CTRL_XTYPE DMA350_CH_CTRL_XTYPE_Msk +/*!< XTYPE[ 2:0] bits Operation type for X direction: + *- 000: "disable" - No data transfer will take place for this command. This mode can be used to create + *empty commands that wait for an event or set GPOs. + *- 001: "continue" - Copy data in a continuous manner from source to the destination. + *For 1D operations it is expected that SRCXSIZE is equal to DESXSIZE, other combinations + *result in UNPREDICTABLE behavior. + *For 2D operations, this mode can be used for simple 2D to 2D copy but it also allows the + *reshaping of the data like 1D to + *2D or 2D to 1D conversions. If the DESXSIZE is smaller than SRCXSIZE then the read data + *from the current source line goes + *to the next destination line. If SRCXSIZE is smaller than DESXSIZE then the reads start + *on the next line and data is written + *to the remainder of the current destination line. Note: For 1D to 2D the SRCYSIZE for 2D + *to 1D conversion the DESYSIZE needs + *to be set to 1 when using this mode. + *- 010: "wrap" - Wrap source data within a destination line when the end of the source line is reached. + *Read starts again from the beginning of the source line and copied to the remainder of the destination line. + *If the DESXSIZE is smaller than SRCXSIZE then the behavior is UNPREDICTABLE. Not supported when HAS_WRAP is 0 in HW + *- 011: "fill" - Fill the remainder of the destination line with FILLVAL when the end of the source line is reached. + *If the DESXSIZE is smaller than SRCXSIZE then the behavior is UNPREDICTABLE. Not supported when HAS_WRAP is 0 in HW. + *- Others: Reserved. + */ +#define DMA350_CH_CTRL_XTYPE_0 (0x1UL << DMA350_CH_CTRL_XTYPE_Pos) /*!< 0x00000200UL*/ +#define DMA350_CH_CTRL_XTYPE_1 (0x2UL << DMA350_CH_CTRL_XTYPE_Pos) /*!< 0x00000400UL*/ +#define DMA350_CH_CTRL_XTYPE_2 (0x4UL << DMA350_CH_CTRL_XTYPE_Pos) /*!< 0x00000800UL*/ +#define DMA350_CH_CTRL_YTYPE_Pos (12U) +#define DMA350_CH_CTRL_YTYPE_Msk (0x7UL << DMA350_CH_CTRL_YTYPE_Pos) /*!< 0x00007000UL*/ +#define DMA350_CH_CTRL_YTYPE DMA350_CH_CTRL_YTYPE_Msk +/*!< YTYPE[ 2:0] bits Operation type for Y direction: + *- 000: "disable" - Only do 1D transfers. When HAS_2D is 0, meaning 2D capability is not supported in HW, + *the YTYPE is always "000". + *- 001: "continue" - Copy 2D data in a continuous manner from source area to the destination area by + *using the YSIZE registers. + *The copy stops when the source runs out of data or the destination runs out of space. Not supported + *when HAS_2D is 0 in HW. + *- 010: "wrap" - Wrap the 2D source area within the destination 2D area by starting to copy data + *from the beginning of the first source line to the remaining space in the destination area. + *If the destination area is smaller than the source area + *then the behavior is UNPREDICTABLE. Not supported when HAS_WRAP or HAS_2D is 0 in HW. + *- 011: Fill the remainder of the destination area with FILLVAL when the source area runs out of data. + *If the destination area is smaller than the source area then the behavior is UNPREDICTABLE. + *Not supported when HAS_WRAP or HAS_2D is 0 in HW + *- Others: Reserved + */ +#define DMA350_CH_CTRL_YTYPE_0 (0x1UL << DMA350_CH_CTRL_YTYPE_Pos) /*!< 0x00001000UL*/ +#define DMA350_CH_CTRL_YTYPE_1 (0x2UL << DMA350_CH_CTRL_YTYPE_Pos) /*!< 0x00002000UL*/ +#define DMA350_CH_CTRL_YTYPE_2 (0x4UL << DMA350_CH_CTRL_YTYPE_Pos) /*!< 0x00004000UL*/ +#define DMA350_CH_CTRL_REGRELOADTYPE_Pos (18U) +#define DMA350_CH_CTRL_REGRELOADTYPE_Msk (0x7UL << DMA350_CH_CTRL_REGRELOADTYPE_Pos) /*!< 0x001C0000UL*/ +#define DMA350_CH_CTRL_REGRELOADTYPE DMA350_CH_CTRL_REGRELOADTYPE_Msk +/*!< REGRELOADTYPE[ 2:0] bits Automatic register reload type. Defines how the DMA command reloads + * initial values at the end of a DMA command before autorestarting, ending or linking to a new DMA command: + *- 000: Reload Disabled. + *- 001: Reload source and destination size registers only. + *- 011: Reload source address only and all source and destination size registers. + *- 101: Reload destination address only and all source and destination size registers. + *- 111: Reload source and destination address and all source and destination size registers. + *- Others: Reserved. + *NOTE: When CLEARCMD is set, the reloaded registers will also be cleared. + */ +#define DMA350_CH_CTRL_REGRELOADTYPE_0 (0x1UL << DMA350_CH_CTRL_REGRELOADTYPE_Pos) /*!< 0x00040000UL*/ +#define DMA350_CH_CTRL_REGRELOADTYPE_1 (0x2UL << DMA350_CH_CTRL_REGRELOADTYPE_Pos) /*!< 0x00080000UL*/ +#define DMA350_CH_CTRL_REGRELOADTYPE_2 (0x4UL << DMA350_CH_CTRL_REGRELOADTYPE_Pos) /*!< 0x00100000UL*/ +#define DMA350_CH_CTRL_DONETYPE_Pos (21U) +#define DMA350_CH_CTRL_DONETYPE_Msk (0x7UL << DMA350_CH_CTRL_DONETYPE_Pos) /*!< 0x00E00000UL*/ +#define DMA350_CH_CTRL_DONETYPE DMA350_CH_CTRL_DONETYPE_Msk +/*!< DONETYPE[ 2:0] bits Done type selection. This field defines when the STAT_DONE status flag + * is asserted during the command operation. + *- 000: STAT_DONE flag is not asserted for this command. + *- 001: End of a command, before jumping to the next linked command. (default) + *- 011: End of an autorestart cycle, before starting the next cycle. + *- Others : Reserved. + */ +#define DMA350_CH_CTRL_DONETYPE_0 (0x1UL << DMA350_CH_CTRL_DONETYPE_Pos) /*!< 0x00200000UL*/ +#define DMA350_CH_CTRL_DONETYPE_1 (0x2UL << DMA350_CH_CTRL_DONETYPE_Pos) /*!< 0x00400000UL*/ +#define DMA350_CH_CTRL_DONETYPE_2 (0x4UL << DMA350_CH_CTRL_DONETYPE_Pos) /*!< 0x00800000UL*/ +#define DMA350_CH_CTRL_DONEPAUSEEN_Pos (24U) +#define DMA350_CH_CTRL_DONEPAUSEEN_Msk (0x1UL << DMA350_CH_CTRL_DONEPAUSEEN_Pos) /*!< 0x01000000UL*/ +#define DMA350_CH_CTRL_DONEPAUSEEN DMA350_CH_CTRL_DONEPAUSEEN_Msk +/*!< DONEPAUSEEN bit Done pause enable. When set to HIGH the assertion of the STAT_DONE flag + * results in an automatic pause request for the current DMA operation. + * When the paused state is reached the STAT_RESUMEWAIT flag is also set. + * When set to LOW the assertion of the STAT_DONE does not pause the progress of the + * command and the next operation of the channel will be started immediately after the STAT_DONE flag is set. + */ +#define DMA350_CH_CTRL_USESRCTRIGIN_Pos (25U) +#define DMA350_CH_CTRL_USESRCTRIGIN_Msk (0x1UL << DMA350_CH_CTRL_USESRCTRIGIN_Pos) /*!< 0x02000000UL*/ +#define DMA350_CH_CTRL_USESRCTRIGIN DMA350_CH_CTRL_USESRCTRIGIN_Msk +/*!< USESRCTRIGIN bit Enable Source Trigger Input use for this command. + *- 0: disable + *- 1: enable + */ +#define DMA350_CH_CTRL_USEDESTRIGIN_Pos (26U) +#define DMA350_CH_CTRL_USEDESTRIGIN_Msk (0x1UL << DMA350_CH_CTRL_USEDESTRIGIN_Pos) /*!< 0x04000000UL*/ +#define DMA350_CH_CTRL_USEDESTRIGIN DMA350_CH_CTRL_USEDESTRIGIN_Msk +/*!< USEDESTRIGIN bit Enable Destination Trigger Input use for this command. + *- 0: disable + *- 1: enable + */ +#define DMA350_CH_CTRL_USETRIGOUT_Pos (27U) +#define DMA350_CH_CTRL_USETRIGOUT_Msk (0x1UL << DMA350_CH_CTRL_USETRIGOUT_Pos) /*!< 0x08000000UL*/ +#define DMA350_CH_CTRL_USETRIGOUT DMA350_CH_CTRL_USETRIGOUT_Msk +/*!< USETRIGOUT bit Enable Trigger Output use for this command. + *- 0: disable + *- 1: enable + */ +#define DMA350_CH_CTRL_USEGPO_Pos (28U) +#define DMA350_CH_CTRL_USEGPO_Msk (0x1UL << DMA350_CH_CTRL_USEGPO_Pos) /*!< 0x10000000UL*/ +#define DMA350_CH_CTRL_USEGPO DMA350_CH_CTRL_USEGPO_Msk +/*!< USEGPO bit Enable GPO use for this command. + *- 0: disable + *- 1: enable + */ +#define DMA350_CH_CTRL_USESTREAM_Pos (29U) +#define DMA350_CH_CTRL_USESTREAM_Msk (0x1UL << DMA350_CH_CTRL_USESTREAM_Pos) /*!< 0x20000000UL*/ +#define DMA350_CH_CTRL_USESTREAM DMA350_CH_CTRL_USESTREAM_Msk +/*!< USESTREAM bit Enable Stream Interface use for this command. + *- 0: disable + *- 1: enable + */ +/**************** Field definitions for CH_SRCADDR register *****************/ +#define DMA350_CH_SRCADDR_SRCADDR_Pos (0U) +#define DMA350_CH_SRCADDR_SRCADDR_Msk (0xFFFFFFFFUL << DMA350_CH_SRCADDR_SRCADDR_Pos) /*!< 0xFFFFFFFFUL*/ +#define DMA350_CH_SRCADDR_SRCADDR DMA350_CH_SRCADDR_SRCADDR_Msk +/*!< SRCADDR[31:0] bits Source Address [31:0]. + */ +/*************** Field definitions for CH_SRCADDRHI register ****************/ +#define DMA350_CH_SRCADDRHI_SRCADDRHI_Pos (0U) +#define DMA350_CH_SRCADDRHI_SRCADDRHI_Msk (0xFFFFFFFFUL << DMA350_CH_SRCADDRHI_SRCADDRHI_Pos) /*!< 0xFFFFFFFFUL*/ +#define DMA350_CH_SRCADDRHI_SRCADDRHI DMA350_CH_SRCADDRHI_SRCADDRHI_Msk +/*!< SRCADDRHI[31:0] bits Source Address [63:32]. Allows 64-bit addressing but the system might + * need less address bits defined by ADDR_WIDTH. The not implemented bits remain reserved. + */ +/**************** Field definitions for CH_DESADDR register *****************/ +#define DMA350_CH_DESADDR_DESADDR_Pos (0U) +#define DMA350_CH_DESADDR_DESADDR_Msk (0xFFFFFFFFUL << DMA350_CH_DESADDR_DESADDR_Pos) /*!< 0xFFFFFFFFUL*/ +#define DMA350_CH_DESADDR_DESADDR DMA350_CH_DESADDR_DESADDR_Msk +/*!< DESADDR[31:0] bits Destination Address[31:0] + */ +/*************** Field definitions for CH_DESADDRHI register ****************/ +#define DMA350_CH_DESADDRHI_DESADDRHI_Pos (0U) +#define DMA350_CH_DESADDRHI_DESADDRHI_Msk (0xFFFFFFFFUL << DMA350_CH_DESADDRHI_DESADDRHI_Pos) /*!< 0xFFFFFFFFUL*/ +#define DMA350_CH_DESADDRHI_DESADDRHI DMA350_CH_DESADDRHI_DESADDRHI_Msk +/*!< DESADDRHI[31:0] bits Destination Address[63:32]. Allows 64-bit addressing but the system might + * need less address bits defined by ADDR_WIDTH. The not implemented bits remain reserved. + */ +/***************** Field definitions for CH_XSIZE register ******************/ +#define DMA350_CH_XSIZE_SRCXSIZE_Pos (0U) +#define DMA350_CH_XSIZE_SRCXSIZE_Msk (0xFFFFUL << DMA350_CH_XSIZE_SRCXSIZE_Pos) /*!< 0x0000FFFFUL*/ +#define DMA350_CH_XSIZE_SRCXSIZE DMA350_CH_XSIZE_SRCXSIZE_Msk +/*!< SRCXSIZE[15:0] bits Source Number of Transfers in the X Dimension lower bits [15:0]. + * This register along with SRCXSIZEHI defines the source data block size of the DMA + * operation for any 1D operation, and defines the X dimension of the 2D source block for 2D operation. + */ +#define DMA350_CH_XSIZE_DESXSIZE_Pos (16U) +#define DMA350_CH_XSIZE_DESXSIZE_Msk (0xFFFFUL << DMA350_CH_XSIZE_DESXSIZE_Pos) /*!< 0xFFFF0000UL*/ +#define DMA350_CH_XSIZE_DESXSIZE DMA350_CH_XSIZE_DESXSIZE_Msk +/*!< DESXSIZE[15:0] bits Destination Number of Transfers in the X Dimension lower bits [15:0]. + * This register along with DESXSIZEHI defines the destination data block size of the DMA operation + * for or any 1D operation, and defines the X dimension of the 2D destination block for a 2D operation. + * HAS_WRAP or HAS_STREAM configuration needs to be set to allow writes to this register, otherwise it + * is read-only and writing to SRCXSIZE will also update the value of this register. + */ +/**************** Field definitions for CH_XSIZEHI register *****************/ +#define DMA350_CH_XSIZEHI_SRCXSIZEHI_Pos (0U) +#define DMA350_CH_XSIZEHI_SRCXSIZEHI_Msk (0xFFFFUL << DMA350_CH_XSIZEHI_SRCXSIZEHI_Pos) /*!< 0x0000FFFFUL*/ +#define DMA350_CH_XSIZEHI_SRCXSIZEHI DMA350_CH_XSIZEHI_SRCXSIZEHI_Msk +/*!< SRCXSIZEHI[15:0] bits Source Number of Transfers in the X Dimension high bits [31:16]. + * This register along with SRCXSIZE defines the source data block size of the DMA operation + * for any 1D operation, and defines the X dimension of the 2D source block for 2D operation. + */ +#define DMA350_CH_XSIZEHI_DESXSIZEHI_Pos (16U) +#define DMA350_CH_XSIZEHI_DESXSIZEHI_Msk (0xFFFFUL << DMA350_CH_XSIZEHI_DESXSIZEHI_Pos) /*!< 0xFFFF0000UL*/ +#define DMA350_CH_XSIZEHI_DESXSIZEHI DMA350_CH_XSIZEHI_DESXSIZEHI_Msk +/*!< DESXSIZEHI[15:0] bits Destination Number of Transfers in the X Dimension high bits [31:16]. + * This register along with DESXSIZE defines the destination data block size of the DMA operation + * for or any 1D operation, and defines the X dimension of the 2D destination block for a 2D operation. + * HAS_WRAP or HAS_STREAM configuration needs to be set to allow writes to this register, otherwise it + * is read-only and writing to SRCXSIZEHI will also update the value of this register. + */ +/************** Field definitions for CH_SRCTRANSCFG register ***************/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos (0U) +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Msk (0xFUL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos) /*!< 0x0000000FUL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Msk +/*!< SRCMEMATTRLO[ 3:0] bits Source Transfer Memory Attribute field [3:0]. + * When SRCMEMATTRHI is Device type (0000) then this field means: + *- 0000: Device-nGnRnE + *- 0100: Device-nGnRE + *- 1000: Device-nGRE + *- 1100: Device-GRE + *- Others: Invalid resulting in UNPREDICTABLE behavior + *When SRCMEMATTRHI is Normal memory type (other than 0000) then this field means: + *- 0000: Reserved + *- 0001: Normal memory, Inner Write allocate, Inner Write-through transient + *- 0010: Normal memory, Inner Read allocate, Inner Write-through transient + *- 0011: Normal memory, Inner Read/Write allocate, Inner Write-through transient + *- 0100: Normal memory, Inner non-cacheable + *- 0101: Normal memory, Inner Write allocate, Inner Write-back transient + *- 0110: Normal memory, Inner Read allocate, Inner Write-back transient + *- 0111: Normal memory, Inner Read/Write allocate, Inner Write-back transient + *- 1000: Normal memory, Inner Write-through non-transient + *- 1001: Normal memory, Inner Write allocate, Inner Write-through non-transient + *- 1010: Normal memory, Inner Read allocate, Inner Write-through non-transient + *- 1011: Normal memory, Inner Read/Write allocate, Inner Write-through non-transient + *- 1100: Normal memory, Inner Write-back non-transient + *- 1101: Normal memory, Inner Write allocate, Inner Write-back non-transient + *- 1110: Normal memory, Inner Read allocate, Inner Write-back non-transient + *- 1111: Normal memory, Inner Read/Write allocate, Inner Write-back non-transient + */ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_0 (0x1UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_1 (0x2UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos) /*!< 0x00000002UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_2 (0x4UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos) /*!< 0x00000004UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_3 (0x8UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRLO_Pos) /*!< 0x00000008UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos (4U) +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Msk (0xFUL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos) /*!< 0x000000F0UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Msk +/*!< SRCMEMATTRHI[ 3:0] bits Source Transfer Memory Attribute field [7:4]. + *- 0000: Device memory + *- 0001: Normal memory, Outer Write allocate, Outer Write-through transient + *- 0010: Normal memory, Outer Read allocate, Outer Write-through transient + *- 0011: Normal memory, Outer Read/Write allocate, Outer Write-through transient + *- 0100: Normal memory, Outer non-cacheable + *- 0101: Normal memory, Outer Write allocate, Outer Write-back transient + *- 0110: Normal memory, Outer Read allocate, Outer Write-back transient + *- 0111: Normal memory, Outer Read/Write allocate, Outer Write-back transient + *- 1000: Normal memory, Outer Write-through non-transient + *- 1001: Normal memory, Outer Write allocate, Outer Write-through non-transient + *- 1010: Normal memory, Outer Read allocate, Outer Write-through non-transient + *- 1011: Normal memory, Outer Read/Write allocate, Outer Write-through non-transient + *- 1100: Normal memory, Outer Write-back non-transient + *- 1101: Normal memory, Outer Write allocate, Outer Write-back non-transient + *- 1110: Normal memory, Outer Read allocate, Outer Write-back non-transient + *- 1111: Normal memory, Outer Read/Write allocate, Outer Write-back non-transient + */ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_0 (0x1UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos) /*!< 0x00000010UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_1 (0x2UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos) /*!< 0x00000020UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_2 (0x4UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos) /*!< 0x00000040UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_3 (0x8UL << DMA350_CH_SRCTRANSCFG_SRCMEMATTRHI_Pos) /*!< 0x00000080UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Pos (8U) +#define DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Msk (0x3UL << DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Pos) /*!< 0x00000300UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCSHAREATTR DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Msk +/*!< SRCSHAREATTR[ 1:0] bits Source Transfer Shareability Attribute. + *- 00: Non-shareable + *- 01: Reserved + *- 10: Outer shareable + *- 11: Inner shareable + */ +#define DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_0 (0x1UL << DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Pos) /*!< 0x00000100UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_1 (0x2UL << DMA350_CH_SRCTRANSCFG_SRCSHAREATTR_Pos) /*!< 0x00000200UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCNONSECATTR_Pos (10U) +#define DMA350_CH_SRCTRANSCFG_SRCNONSECATTR_Msk (0x1UL << DMA350_CH_SRCTRANSCFG_SRCNONSECATTR_Pos) /*!< 0x00000400UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCNONSECATTR DMA350_CH_SRCTRANSCFG_SRCNONSECATTR_Msk +/*!< SRCNONSECATTR bit Source Transfer Non-secure Attribute. + *- 0: Secure + *- 1: Non-secure + *When a channel is Non-secure this bit is tied to 1. + */ +#define DMA350_CH_SRCTRANSCFG_SRCPRIVATTR_Pos (11U) +#define DMA350_CH_SRCTRANSCFG_SRCPRIVATTR_Msk (0x1UL << DMA350_CH_SRCTRANSCFG_SRCPRIVATTR_Pos) /*!< 0x00000800UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCPRIVATTR DMA350_CH_SRCTRANSCFG_SRCPRIVATTR_Msk +/*!< SRCPRIVATTR bit Source Transfer Privilege Attribute. + *- 0: Unprivileged + *- 1: Privileged + *When a channel is unprivileged this bit is tied to 0. + */ +#define DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos (16U) +#define DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Msk (0xFUL << DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos) +#define DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Msk +/*!< SRCMAXBURSTLEN[ 3:0] bits Source Max Burst Length. Hint for the DMA on what is the maximum allowed + * burst size it can use for read transfers. The maximum number of beats sent by the DMA for a read burst + * is equal to SRCMAXBURSTLEN + 1. Default value is 16 beats, which allows the DMA to set all burst sizes. + * Note: Limited by the DATA_BUFF_SIZE so larger settings may not always result in larger bursts. + */ +#define DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_0 (0x1UL << DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos) /*!< 0x00010000UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_1 (0x2UL << DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos) /*!< 0x00020000UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_2 (0x4UL << DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos) /*!< 0x00040000UL*/ +#define DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_3 (0x8UL << DMA350_CH_SRCTRANSCFG_SRCMAXBURSTLEN_Pos) /*!< 0x00080000UL*/ +/************** Field definitions for CH_DESTRANSCFG register ***************/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos (0U) +#define DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Msk (0xFUL << DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos) /*!< 0x0000000FUL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRLO DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Msk +/*!< DESMEMATTRLO[ 3:0] bits Destination Transfer Memory Attribute field [3:0]. + *When DESMEMATTRHI is Device type (0000) then this field means: + *- 0000: Device-nGnRnE + *- 0100: Device-nGnRE + *- 1000: Device-nGRE + *- 1100: Device-GRE + *- Others: Invalid resulting in UNPREDICTABLE behavior + *When DESMEMATTRHI is Normal Memory type (other than 0000) then this field means: + *- 0000: Reserved + *- 0001: Normal memory, Inner Write allocate, Inner Write-through transient + *- 0010: Normal memory, Inner Read allocate, Inner Write-through transient + *- 0011: Normal memory, Inner Read/Write allocate, Inner Write-through transient + *- 0100: Normal memory, Inner non-cacheable + *- 0101: Normal memory, Inner Write allocate, Inner Write-back transient + *- 0110: Normal memory, Inner Read allocate, Inner Write-back transient + *- 0111: Normal memory, Inner Read/Write allocate, Inner Write-back transient + *- 1000: Normal memory, Inner Write-through non-transient + *- 1001: Normal memory, Inner Write allocate, Inner Write-through non-transient + *- 1010: Normal memory, Inner Read allocate, Inner Write-through non-transient + *- 1011: Normal memory, Inner Read/Write allocate, Inner Write-through non-transient + *- 1100: Normal memory, Inner Write-back non-transient + *- 1101: Normal memory, Inner Write allocate, Inner Write-back non-transient + *- 1110: Normal memory, Inner Read allocate, Inner Write-back non-transient + *- 1111: Normal memory, Inner Read/Write allocate, Inner Write-back non-transient + */ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRLO_0 (0x1UL << DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRLO_1 (0x2UL << DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos) /*!< 0x00000002UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRLO_2 (0x4UL << DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos) /*!< 0x00000004UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRLO_3 (0x8UL << DMA350_CH_DESTRANSCFG_DESMEMATTRLO_Pos) /*!< 0x00000008UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos (4U) +#define DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Msk (0xFUL << DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos) /*!< 0x000000F0UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRHI DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Msk +/*!< DESMEMATTRHI[ 3:0] bits Destination Transfer Memory Attribute field [7:4]. + *- 0000: Device memory + *- 0001: Normal memory, Outer Write allocate, Outer Write-through transient + *- 0010: Normal memory, Outer Read allocate, Outer Write-through transient + *- 0011: Normal memory, Outer Read/Write allocate, Outer Write-through transient + *- 0100: Normal memory, Outer non-cacheable + *- 0101: Normal memory, Outer Write allocate, Outer Write-back transient + *- 0110: Normal memory, Outer Read allocate, Outer Write-back transient + *- 0111: Normal memory, Outer Read/Write allocate, Outer Write-back transient + *- 1000: Normal memory, Outer Write-through non-transient + *- 1001: Normal memory, Outer Write allocate, Outer Write-through non-transient + *- 1010: Normal memory, Outer Read allocate, Outer Write-through non-transient + *- 1011: Normal memory, Outer Read/Write allocate, Outer Write-through non-transient + *- 1100: Normal memory, Outer Write-back non-transient + *- 1101: Normal memory, Outer Write allocate, Outer Write-back non-transient + *- 1110: Normal memory, Outer Read allocate, Outer Write-back non-transient + *- 1111: Normal memory, Outer Read/Write allocate, Outer Write-back non-transient + */ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRHI_0 (0x1UL << DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos) /*!< 0x00000010UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRHI_1 (0x2UL << DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos) /*!< 0x00000020UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRHI_2 (0x4UL << DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos) /*!< 0x00000040UL*/ +#define DMA350_CH_DESTRANSCFG_DESMEMATTRHI_3 (0x8UL << DMA350_CH_DESTRANSCFG_DESMEMATTRHI_Pos) /*!< 0x00000080UL*/ +#define DMA350_CH_DESTRANSCFG_DESSHAREATTR_Pos (8U) +#define DMA350_CH_DESTRANSCFG_DESSHAREATTR_Msk (0x3UL << DMA350_CH_DESTRANSCFG_DESSHAREATTR_Pos) /*!< 0x00000300UL*/ +#define DMA350_CH_DESTRANSCFG_DESSHAREATTR DMA350_CH_DESTRANSCFG_DESSHAREATTR_Msk +/*!< DESSHAREATTR[ 1:0] bits Destination Transfer Shareability Attribute. + *- 00: Non-shareable + *- 01: Reserved + *- 10: Outer shareable + *- 11: Inner shareable + */ +#define DMA350_CH_DESTRANSCFG_DESSHAREATTR_0 (0x1UL << DMA350_CH_DESTRANSCFG_DESSHAREATTR_Pos) /*!< 0x00000100UL*/ +#define DMA350_CH_DESTRANSCFG_DESSHAREATTR_1 (0x2UL << DMA350_CH_DESTRANSCFG_DESSHAREATTR_Pos) /*!< 0x00000200UL*/ +#define DMA350_CH_DESTRANSCFG_DESNONSECATTR_Pos (10U) +#define DMA350_CH_DESTRANSCFG_DESNONSECATTR_Msk (0x1UL << DMA350_CH_DESTRANSCFG_DESNONSECATTR_Pos) /*!< 0x00000400UL*/ +#define DMA350_CH_DESTRANSCFG_DESNONSECATTR DMA350_CH_DESTRANSCFG_DESNONSECATTR_Msk +/*!< DESNONSECATTR bit Destination Transfer Non-secure Attribute. + *- 0: Secure + *- 1: Non-secure + *When a channel is Non-secure this bit is tied to 1. + */ +#define DMA350_CH_DESTRANSCFG_DESPRIVATTR_Pos (11U) +#define DMA350_CH_DESTRANSCFG_DESPRIVATTR_Msk (0x1UL << DMA350_CH_DESTRANSCFG_DESPRIVATTR_Pos) /*!< 0x00000800UL*/ +#define DMA350_CH_DESTRANSCFG_DESPRIVATTR DMA350_CH_DESTRANSCFG_DESPRIVATTR_Msk +/*!< DESPRIVATTR bit Destination Transfer Privilege Attribute. + *- 0: Unprivileged + *- 1: Privileged + *When a channel is unprivileged this bit is tied to 0. + */ +#define DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos (16U) +#define DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Msk (0xFUL << DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos) /*!< 0x000F0000UL*/ +#define DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Msk + +#define DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_0 (0x1UL << DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos) /*!< 0x00010000UL*/ +#define DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_1 (0x2UL << DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos) /*!< 0x00020000UL*/ +#define DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_2 (0x4UL << DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos) /*!< 0x00040000UL*/ +#define DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_3 (0x8UL << DMA350_CH_DESTRANSCFG_DESMAXBURSTLEN_Pos) /*!< 0x00080000UL*/ +/**************** Field definitions for CH_XADDRINC register ****************/ +#define DMA350_CH_XADDRINC_SRCXADDRINC_Pos (0U) +#define DMA350_CH_XADDRINC_SRCXADDRINC_Msk (0xFFFFUL << DMA350_CH_XADDRINC_SRCXADDRINC_Pos) /*!< 0x0000FFFFUL*/ +#define DMA350_CH_XADDRINC_SRCXADDRINC DMA350_CH_XADDRINC_SRCXADDRINC_Msk +/*!< SRCXADDRINC[15:0] bits Source X dimension Address Increment. + * This value is used as the increment between each TRANSIZE transfer. + * When a single bit is used then only 0 and 1 can be set. For wider increment registers, + * two's complement used with a range between -32768 to 32767 when the counter is 16-bits wide. + * The width of the register is indicated by the INC_WIDTH parameter. SRCADDR_next = SRCADDR + 2^TRANSIZE * SRCXADDRINC + */ +#define DMA350_CH_XADDRINC_DESXADDRINC_Pos (16U) +#define DMA350_CH_XADDRINC_DESXADDRINC_Msk (0xFFFFUL << DMA350_CH_XADDRINC_DESXADDRINC_Pos) /*!< 0xFFFF0000UL*/ +#define DMA350_CH_XADDRINC_DESXADDRINC DMA350_CH_XADDRINC_DESXADDRINC_Msk +/*!< DESXADDRINC[15:0] bits Destination X dimension Address Increment. + * This value is used as the increment between each TRANSIZE transfer. + * When a single bit is used then only 0 and 1 can be set. For wider increment registers, + * two's complement used with a range between -32768 to 32767 when the counter is 16-bits wide. + * The width of the register is indicated by the INC_WIDTH parameter. + * DESADDR_next = DESADDR + 2^TRANSIZE * DESXADDRINC + */ +/************** Field definitions for CH_YADDRSTRIDE register ***************/ +#define DMA350_CH_YADDRSTRIDE_SRCYADDRSTRIDE_Pos (0U) +#define DMA350_CH_YADDRSTRIDE_SRCYADDRSTRIDE_Msk (0xFFFFUL << DMA350_CH_YADDRSTRIDE_SRCYADDRSTRIDE_Pos) +#define DMA350_CH_YADDRSTRIDE_SRCYADDRSTRIDE DMA350_CH_YADDRSTRIDE_SRCYADDRSTRIDE_Msk +/*!< SRCYADDRSTRIDE[15:0] bits Source Address Stride between lines. Calculated in TRANSIZE aligned steps. + * This value is used to increment the SRCADDR after completing the transfer of a source line. + * SRCADDR_next_line_base = SRCADDR_line_base + 2^TRANSIZE * SRCYADDRSTRIDE. + * Two's complement used with a range between -32768 to 32767. + * When set to 0 the SRCADDR is not incremented after completing one line. Not present when HAS_2D is 0. + */ +#define DMA350_CH_YADDRSTRIDE_DESYADDRSTRIDE_Pos (16U) +#define DMA350_CH_YADDRSTRIDE_DESYADDRSTRIDE_Msk (0xFFFFUL << DMA350_CH_YADDRSTRIDE_DESYADDRSTRIDE_Pos) +#define DMA350_CH_YADDRSTRIDE_DESYADDRSTRIDE DMA350_CH_YADDRSTRIDE_DESYADDRSTRIDE_Msk +/*!< DESYADDRSTRIDE[15:0] bits Destination Address Stride between lines. + * Calculated in TRANSIZE aligned steps. This value is used to increment the DESADDR after completing the transfer + * of a destination line. DESADDR_next_line_base = DESADDR_line_base + 2^TRANSIZE * DESYADDRSTRIDE. + * Two's complement used with a range between -32768 to 32767. When set to 0 the DESADDR is not incremented + * after completing one line. Not present when HAS_2D is 0. + */ +/**************** Field definitions for CH_FILLVAL register *****************/ +#define DMA350_CH_FILLVAL_FILLVAL_Pos (0U) +#define DMA350_CH_FILLVAL_FILLVAL_Msk (0xFFFFFFFFUL << DMA350_CH_FILLVAL_FILLVAL_Pos) /*!< 0xFFFFFFFFUL*/ +#define DMA350_CH_FILLVAL_FILLVAL DMA350_CH_FILLVAL_FILLVAL_Msk +/*!< FILLVAL[31:0] bits Fill pattern value. When XTYPE or YTYPE is set to fill mode, + * then this register value is used on the write data bus when the command starts to fill the memory area. + * The TRANSIZE defines the width of the FILLVAL used for the command. For byte transfers the FILLVAL[7:0] is used, + * other bits are ignored. For halfword transfers the FILLVAL[15:0] is used, other bits are ignored. + * For 64-bit and wider transfers the FILLVAL[31:0] pattern is repeated on the full width of the data bus. + * Not present when HAS_WRAP is 0. + */ +/***************** Field definitions for CH_YSIZE register ******************/ +#define DMA350_CH_YSIZE_SRCYSIZE_Pos (0U) +#define DMA350_CH_YSIZE_SRCYSIZE_Msk (0xFFFFUL << DMA350_CH_YSIZE_SRCYSIZE_Pos) /*!< 0x0000FFFFUL*/ +#define DMA350_CH_YSIZE_SRCYSIZE DMA350_CH_YSIZE_SRCYSIZE_Msk +/*!< SRCYSIZE[15:0] bits Source Y dimension or number of lines. Not present when HAS_2D is 0. + */ +#define DMA350_CH_YSIZE_DESYSIZE_Pos (16U) +#define DMA350_CH_YSIZE_DESYSIZE_Msk (0xFFFFUL << DMA350_CH_YSIZE_DESYSIZE_Pos) /*!< 0xFFFF0000UL*/ +#define DMA350_CH_YSIZE_DESYSIZE DMA350_CH_YSIZE_DESYSIZE_Msk +/*!< DESYSIZE[15:0] bits Destination Y dimension or number of lines. Not present when HAS_2D is 0. + * HAS_WRAP or HAS_STREAM configuration needs to be set to allow writes to this register, + * otherwise it is read-only. + */ +/**************** Field definitions for CH_TMPLTCFG register ****************/ +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Pos (8U) +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Msk (0x1FUL << DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Pos) /*!< 0x00001F00UL*/ +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Msk +/*!< SRCTMPLTSIZE[ 4:0] bits Source Template Size in number of transfers plus one. + *- 0: Source template is disabled. + *- 1 to 31: Bits SRCTMPLT[SRCTMPLTSIZE:0] is used as the source template. Not present when HAS_TMPLT is 0. + */ +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_0 (0x1UL << DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Pos) /*!< 0x00000100UL*/ +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_1 (0x2UL << DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Pos) /*!< 0x00000200UL*/ +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_2 (0x4UL << DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Pos) /*!< 0x00000400UL*/ +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_3 (0x8UL << DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Pos) /*!< 0x00000800UL*/ +#define DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_4 (0x10UL << DMA350_CH_TMPLTCFG_SRCTMPLTSIZE_Pos) /*!< 0x00001000UL*/ +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Pos (16U) +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Msk (0x1FUL << DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Pos) /*!< 0x001F0000UL*/ +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Msk +/*!< DESTMPLTSIZE[ 4:0] bits Destination Template Size in number of transfers plus one. + *- 0: Destination template is disabled. + *- 1 to 31: DESTMPLT[DESTMPLTSIZE:0] is used as the destination template. Not present when HAS_TMPLT is 0. + */ +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_0 (0x1UL << DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Pos) /*!< 0x00010000UL*/ +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_1 (0x2UL << DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Pos) /*!< 0x00020000UL*/ +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_2 (0x4UL << DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Pos) /*!< 0x00040000UL*/ +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_3 (0x8UL << DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Pos) /*!< 0x00080000UL*/ +#define DMA350_CH_TMPLTCFG_DESTMPLTSIZE_4 (0x10UL << DMA350_CH_TMPLTCFG_DESTMPLTSIZE_Pos) /*!< 0x00100000UL*/ +/**************** Field definitions for CH_SRCTMPLT register ****************/ +#define DMA350_CH_SRCTMPLT_SRCTMPLTLSB_Pos (0U) +#define DMA350_CH_SRCTMPLT_SRCTMPLTLSB_Msk (0x1UL << DMA350_CH_SRCTMPLT_SRCTMPLTLSB_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_SRCTMPLT_SRCTMPLTLSB DMA350_CH_SRCTMPLT_SRCTMPLTLSB_Msk +/*!< SRCTMPLTLSB bit Source Packing Template Least Significant Bit. This bit of the template is + * read only and always set to 1 as template patterns can only start from the base address of the transfer. + * Not present when HAS_TMPLT is 0. + */ +#define DMA350_CH_SRCTMPLT_SRCTMPLT_Pos (1U) +#define DMA350_CH_SRCTMPLT_SRCTMPLT_Msk (0x7FFFFFFFUL << DMA350_CH_SRCTMPLT_SRCTMPLT_Pos) /*!< 0xFFFFFFFEUL*/ +#define DMA350_CH_SRCTMPLT_SRCTMPLT DMA350_CH_SRCTMPLT_SRCTMPLT_Msk +/*!< SRCTMPLT[30:0] bits Source Packing Template. Bit[0] is read only and always set to 1 as template + * patterns can only start from the base address of the transfer. Not present when HAS_TMPLT is 0. + */ +/**************** Field definitions for CH_DESTMPLT register ****************/ +#define DMA350_CH_DESTMPLT_DESTMPLTLSB_Pos (0U) +#define DMA350_CH_DESTMPLT_DESTMPLTLSB_Msk (0x1UL << DMA350_CH_DESTMPLT_DESTMPLTLSB_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_DESTMPLT_DESTMPLTLSB DMA350_CH_DESTMPLT_DESTMPLTLSB_Msk +/*!< DESTMPLTLSB bit Destination Packing Template Least Significant Bit. + * This bit of the template is read only and always set to 1 as template patterns can + * only start from the base address of the transfer. Not present when HAS_TMPLT is 0. + */ +#define DMA350_CH_DESTMPLT_DESTMPLT_Pos (1U) +#define DMA350_CH_DESTMPLT_DESTMPLT_Msk (0x7FFFFFFFUL << DMA350_CH_DESTMPLT_DESTMPLT_Pos) /*!< 0xFFFFFFFEUL*/ +#define DMA350_CH_DESTMPLT_DESTMPLT DMA350_CH_DESTMPLT_DESTMPLT_Msk +/*!< DESTMPLT[30:0] bits Destination Packing Template. + * Bit[0] is read only and always set to 1 as template patterns can only start from the + * base address of the transfer. Not present when HAS_TMPLT is 0. + */ +/************** Field definitions for CH_SRCTRIGINCFG register **************/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos (0U) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Msk (0xFFUL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x000000FFUL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Msk +/*!< SRCTRIGINSEL[ 7:0] bits Source Trigger Input Select + */ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_0 (0x1UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_1 (0x2UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000002UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_2 (0x4UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000004UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_3 (0x8UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000008UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_4 (0x10UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000010UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_5 (0x20UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000020UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_6 (0x40UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000040UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_7 (0x80UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINSEL_Pos) /*!< 0x00000080UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Pos (8U) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Msk (0x3UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Pos) /*!< 0x00000300UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Msk +/*!< SRCTRIGINTYPE[ 1:0] bits Source Trigger Input Type: + *- 00: Software only Trigger Request. SRCTRIGINSEL is ignored. + *- 01: Reserved + *- 10: HW Trigger Request. Only allowed when HAS_TRIGIN is enabled. SRCTRIGINSEL selects between external + * trigger inputs if HAS_TRIGSEL is enabled. + *- 11: Internal Trigger Request. Only allowed when HAS_TRIGSEL is enabled and the DMAC has multiple channels, + * otherwise treated as HW Trigger Request. SRCTRIGINSEL selects between DMA channels. + * Note: SW triggers are also available when HW or Internal types are selected, but is not recommended + * and caution must be taken when the these modes are combined. + */ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_0 (0x1UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Pos) /*!< 0x00000100UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_1 (0x2UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINTYPE_Pos) /*!< 0x00000200UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Pos (10U) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Msk (0x3UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Pos) /*!< 0x00000C00UL*/ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Msk +/*!< SRCTRIGINMODE[ 1:0] bits Source Trigger Input Mode: + *- 00: Command + *- 01: Reserved + *- 10: DMA driven Flow control. Only allowed when HAS_TRIGIN is enabled. + *- 11: Peripheral driven Flow control. Only allowed when HAS_TRIGIN is enabled. + *Note: This field is ignored for Internal triggers as they only support Command triggers. + */ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_0 (0x1UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_1 (0x2UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINMODE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos (16U) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Msk (0xFFUL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Msk +/*!< SRCTRIGINBLKSIZE[ 7:0] bits Source Trigger Input Default Transfer Size. Defined transfer size per trigger + 1. + */ +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_0 (0x1UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_1 (0x2UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_2 (0x4UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_3 (0x8UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_4 (0x10UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_5 (0x20UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_6 (0x40UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +#define DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_7 (0x80UL << DMA350_CH_SRCTRIGINCFG_SRCTRIGINBLKSIZE_Pos) +/************** Field definitions for CH_DESTRIGINCFG register **************/ +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos (0U) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Msk (0xFFUL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Msk +/*!< DESTRIGINSEL[ 7:0] bits Destination Trigger Input Select + */ +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_0 (0x1UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_1 (0x2UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_2 (0x4UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_3 (0x8UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_4 (0x10UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_5 (0x20UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_6 (0x40UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_7 (0x80UL << DMA350_CH_DESTRIGINCFG_DESTRIGINSEL_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Pos (8U) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Msk (0x3UL << DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Msk +/*!< DESTRIGINTYPE[ 1:0] bits Destination Trigger Input Type: + * - 00: Software only Trigger Request. DESTRIGINSEL is ignored. + * - 01: Reserved + * - 10: HW Trigger Request. Only allowed when HAS_TRIGIN is enabled. DESTRIGINSEL selects between external trigger + * inputs if HAS_TRIGSEL is enabled. + * - 11: Internal Trigger Request. Only allowed when HAS_TRIGSEL is enabled and the DMAC has multiple channels, + * otherwise treated as HW Trigger Request. DESTRIGINSEL selects between DMA channels. + *Note: SW triggers are also available when HW or Internal types are selected, but is not recommended and caution + *must be taken when the these modes are combined. + */ +#define DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_0 (0x1UL << DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Pos) /*!< 0x00000100UL*/ +#define DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_1 (0x2UL << DMA350_CH_DESTRIGINCFG_DESTRIGINTYPE_Pos) /*!< 0x00000200UL*/ +#define DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Pos (10U) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Msk (0x3UL << DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINMODE DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Msk +/*!< DESTRIGINMODE[ 1:0] bits Destination Trigger Input Mode: + * - 00: Command + * - 01: Reserved + * - 10: DMA driven Flow control. Only allowed when HAS_TRIGIN is enabled. + * - 11: Peripheral driven Flow control. Only allowed when HAS_TRIGIN is enabled. + * Note: This field is ignored for Internal triggers as they only support Command triggers. + */ +#define DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_0 (0x1UL << DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_1 (0x2UL << DMA350_CH_DESTRIGINCFG_DESTRIGINMODE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos (16U) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Msk (0xFFUL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Msk +/*!< DESTRIGINBLKSIZE[ 7:0] bits Destination Trigger Input Default Transfer Size. + * Defined transfer size per trigger + 1. + */ +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_0 (0x1UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_1 (0x2UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_2 (0x4UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_3 (0x8UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_4 (0x10UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_5 (0x20UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_6 (0x40UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +#define DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_7 (0x80UL << DMA350_CH_DESTRIGINCFG_DESTRIGINBLKSIZE_Pos) +/*************** Field definitions for CH_TRIGOUTCFG register ***************/ +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos (0U) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Msk (0x3FUL << DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Msk +/*!< TRIGOUTSEL[ 5:0] bits Trigger Output Select + */ +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_0 (0x1UL << DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_1 (0x2UL << DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_2 (0x4UL << DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_3 (0x8UL << DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_4 (0x10UL << DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_5 (0x20UL << DMA350_CH_TRIGOUTCFG_TRIGOUTSEL_Pos) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_Pos (8U) +#define DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_Msk (0x3UL << DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_Pos) /*!< 0x00000300UL*/ +#define DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_Msk +/*!< TRIGOUTTYPE[ 1:0] bits Trigger Output Type + *- 00: Software only Trigger Acknowledgment. + *- 01: Reserved + *- 10: HW Trigger Acknowledgment. Only allowed when HAS_TRIGOUT is enabled. + *- 11: Internal Trigger Acknowledgment. Only allowed when HAS_TRIGSEL is enabled and the DMAC has multiple channels, + *otherwise treated as HW Trigger Acknowledgment. + */ +#define DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_0 (0x1UL << DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_Pos) /*!< 0x00000100UL*/ +#define DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_1 (0x2UL << DMA350_CH_TRIGOUTCFG_TRIGOUTTYPE_Pos) /*!< 0x00000200UL*/ +/***************** Field definitions for CH_GPOEN0 register *****************/ +#define DMA350_CH_GPOEN0_GPOEN0_Pos (0U) +#define DMA350_CH_GPOEN0_GPOEN0_Msk (0xFFFFFFFFUL << DMA350_CH_GPOEN0_GPOEN0_Pos) /*!< 0xFFFFFFFFUL*/ +#define DMA350_CH_GPOEN0_GPOEN0 DMA350_CH_GPOEN0_GPOEN0_Msk +/*!< GPOEN0[31:0] bits Channel General Purpose Output (GPO) bit 0 to 31 enable mask. If bit n is '1', + * then GPO[n] is selected for driving by GPOVAL0[n]. If bit 'n' is '0', then GPO[n] keeps its previous value. + * Only [GPO_WIDTH-1:0] are implemented. All unimplemented bits are RAZWI. + */ +/**************** Field definitions for CH_GPOVAL0 register *****************/ +#define DMA350_CH_GPOVAL0_GPOVAL0_Pos (0U) +#define DMA350_CH_GPOVAL0_GPOVAL0_Msk (0xFFFFFFFFUL << DMA350_CH_GPOVAL0_GPOVAL0_Pos) /*!< 0xFFFFFFFFUL*/ +#define DMA350_CH_GPOVAL0_GPOVAL0 DMA350_CH_GPOVAL0_GPOVAL0_Msk +/*!< GPOVAL0[31:0] bits General Purpose Output Value GPO[31:0]. Write to set output value. + * The actual value on the GPO port will become active when the command is enabled. + * Read returns the register value which might be different from the actual GPO port status. + * Only [GPO_WIDTH-1:0] are implemented. All unimplemented bits are RAZWI. + */ +/************** Field definitions for CH_STREAMINTCFG register **************/ +#define DMA350_CH_STREAMINTCFG_STREAMTYPE_Pos (9U) +#define DMA350_CH_STREAMINTCFG_STREAMTYPE_Msk (0x3UL << DMA350_CH_STREAMINTCFG_STREAMTYPE_Pos) /*!< 0x00000600UL*/ +#define DMA350_CH_STREAMINTCFG_STREAMTYPE DMA350_CH_STREAMINTCFG_STREAMTYPE_Msk +/*!< STREAMTYPE[ 1:0] bits Stream Interface operation Type + * - 00: Stream in and out used. + * - 01: Stream out only + * - 10: Stream in only + * - 11: Reserved + */ +#define DMA350_CH_STREAMINTCFG_STREAMTYPE_0 (0x1UL << DMA350_CH_STREAMINTCFG_STREAMTYPE_Pos) /*!< 0x00000200UL*/ +#define DMA350_CH_STREAMINTCFG_STREAMTYPE_1 (0x2UL << DMA350_CH_STREAMINTCFG_STREAMTYPE_Pos) /*!< 0x00000400UL*/ +/**************** Field definitions for CH_LINKATTR register ****************/ +#define DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos (0U) +#define DMA350_CH_LINKATTR_LINKMEMATTRLO_Msk (0xFUL << DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos) /*!< 0x0000000FUL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRLO DMA350_CH_LINKATTR_LINKMEMATTRLO_Msk +/*!< LINKMEMATTRLO[ 3:0] bits Link Address Read Transfer Memory Attribute field [3:0]. + * When LINKMEMATTRHI is Device type (0000) then this field means: + *- 0000: Device-nGnRnE + *- 0100: Device-nGnRE + *- 1000: Device-nGRE + *- 1100: Device-GRE + *- Others: Invalid resulting in UNPREDICTABLE behavior + *When LINKMEMATTRHI is Normal memory type (other than 0000) then this field means: + *- 0000: Reserved + *- 0001: Normal memory, Inner Write allocate, Inner Write-through transient + *- 0010: Normal memory, Inner Read allocate, Inner Write-through transient + *- 0011: Normal memory, Inner Read/Write allocate, Inner Write-through transient + *- 0100: Normal memory, Inner non-cacheable + *- 0101: Normal memory, Inner Write allocate, Inner Write-back transient + *- 0110: Normal memory, Inner Read allocate, Inner Write-back transient + *- 0111: Normal memory, Inner Read/Write allocate, Inner Write-back transient + *- 1000: Normal memory, Inner Write-through non-transient + *- 1001: Normal memory, Inner Write allocate, Inner Write-through non-transient + *- 1010: Normal memory, Inner Read allocate, Inner Write-through non-transient + *- 1011: Normal memory, Inner Read/Write allocate, Inner Write-through non-transient + *- 1100: Normal memory, Inner Write-back non-transient + *- 1101: Normal memory, Inner Write allocate, Inner Write-back non-transient + *- 1110: Normal memory, Inner Read allocate, Inner Write-back non-transient + *- 1111: Normal memory, Inner Read/Write allocate, Inner Write-back non-transient + */ +#define DMA350_CH_LINKATTR_LINKMEMATTRLO_0 (0x1UL << DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRLO_1 (0x2UL << DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos) /*!< 0x00000002UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRLO_2 (0x4UL << DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos) /*!< 0x00000004UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRLO_3 (0x8UL << DMA350_CH_LINKATTR_LINKMEMATTRLO_Pos) /*!< 0x00000008UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos (4U) +#define DMA350_CH_LINKATTR_LINKMEMATTRHI_Msk (0xFUL << DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos) /*!< 0x000000F0UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRHI DMA350_CH_LINKATTR_LINKMEMATTRHI_Msk +/*!< LINKMEMATTRHI[ 3:0] bits Link Address Read Transfer Memory Attribute field [7:4]. + *- 0000: Device memory + *- 0001: Normal memory, Outer Write allocate, Outer Write-through transient + *- 0010: Normal memory, Outer Read allocate, Outer Write-through transient + *- 0011: Normal memory, Outer Read/Write allocate, Outer Write-through transient + *- 0100: Normal memory, Outer non-cacheable + *- 0101: Normal memory, Outer Write allocate, Outer Write-back transient + *- 0110: Normal memory, Outer Read allocate, Outer Write-back transient + *- 0111: Normal memory, Outer Read/Write allocate, Outer Write-back transient + *- 1000: Normal memory, Outer Write-through non-transient + *- 1001: Normal memory, Outer Write allocate, Outer Write-through non-transient + *- 1010: Normal memory, Outer Read allocate, Outer Write-through non-transient + *- 1011: Normal memory, Outer Read/Write allocate, Outer Write-through non-transient + *- 1100: Normal memory, Outer Write-back non-transient + *- 1101: Normal memory, Outer Write allocate, Outer Write-back non-transient + *- 1110: Normal memory, Outer Read allocate, Outer Write-back non-transient + *- 1111: Normal memory, Outer Read/Write allocate, Outer Write-back non-transient + */ +#define DMA350_CH_LINKATTR_LINKMEMATTRHI_0 (0x1UL << DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos) /*!< 0x00000010UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRHI_1 (0x2UL << DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos) /*!< 0x00000020UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRHI_2 (0x4UL << DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos) /*!< 0x00000040UL*/ +#define DMA350_CH_LINKATTR_LINKMEMATTRHI_3 (0x8UL << DMA350_CH_LINKATTR_LINKMEMATTRHI_Pos) /*!< 0x00000080UL*/ +#define DMA350_CH_LINKATTR_LINKSHAREATTR_Pos (8U) +#define DMA350_CH_LINKATTR_LINKSHAREATTR_Msk (0x3UL << DMA350_CH_LINKATTR_LINKSHAREATTR_Pos) /*!< 0x00000300UL*/ +#define DMA350_CH_LINKATTR_LINKSHAREATTR DMA350_CH_LINKATTR_LINKSHAREATTR_Msk +/*!< LINKSHAREATTR[ 1:0] bits Link Address Transfer Shareability Attribute. + * - 00: Non-shareable + * - 01: Reserved + * - 10: Outer shareable + * - 11: Inner shareable + */ +#define DMA350_CH_LINKATTR_LINKSHAREATTR_0 (0x1UL << DMA350_CH_LINKATTR_LINKSHAREATTR_Pos) /*!< 0x00000100UL*/ +#define DMA350_CH_LINKATTR_LINKSHAREATTR_1 (0x2UL << DMA350_CH_LINKATTR_LINKSHAREATTR_Pos) /*!< 0x00000200UL*/ +/**************** Field definitions for CH_AUTOCFG register *****************/ +#define DMA350_CH_AUTOCFG_CMDRESTARTCNT_Pos (0U) +#define DMA350_CH_AUTOCFG_CMDRESTARTCNT_Msk (0xFFFFUL << DMA350_CH_AUTOCFG_CMDRESTARTCNT_Pos) /*!< 0x0000FFFFUL*/ +#define DMA350_CH_AUTOCFG_CMDRESTARTCNT DMA350_CH_AUTOCFG_CMDRESTARTCNT_Msk +/*!< CMDRESTARTCNT[15:0] bits Automatic Command Restart Counter. Defines the number of times automatic + * restarting will occur at end of DMA command. Auto restarting will occur after the command is completed, + * including output triggering if enabled and autoreloading the registers, but it will only perfrom a link + * to the next command when CMDRESTARTCNT == 0. When CMDRESTARTCNT and CMDRESTARTINF + * are both set to '0', autorestart is disabled. + */ +#define DMA350_CH_AUTOCFG_CMDRESTARTINFEN_Pos (16U) +#define DMA350_CH_AUTOCFG_CMDRESTARTINFEN_Msk (0x1UL << DMA350_CH_AUTOCFG_CMDRESTARTINFEN_Pos) /*!< 0x00010000UL*/ +#define DMA350_CH_AUTOCFG_CMDRESTARTINFEN DMA350_CH_AUTOCFG_CMDRESTARTINFEN_Msk +/*!< CMDRESTARTINFEN bit Enable Infinite Automatic Command Restart. + * When set, CMDRESTARTCNT is ignored and the command is always restarted after it is completed, + * including output triggering if enabled and autoreloading the registers but it will not perform + * a link to the next command. + * This means that the infinite loop of automatic restarts can only be broken by DISABLECMD or STOPCMD. + * When CMDRESTARTINFEN is set to '0', then the autorestarting of a command depends on CMDRESTARTCNT and when + * that counter is set to 0 the autorestarting is finished. + * In this case the next linked command is read or the command is complete. + */ +/**************** Field definitions for CH_LINKADDR register ****************/ +#define DMA350_CH_LINKADDR_LINKADDREN_Pos (0U) +#define DMA350_CH_LINKADDR_LINKADDREN_Msk (0x1UL << DMA350_CH_LINKADDR_LINKADDREN_Pos) /*!< 0x00000001UL*/ +#define DMA350_CH_LINKADDR_LINKADDREN DMA350_CH_LINKADDR_LINKADDREN_Msk +/*!< LINKADDREN bit Enable Link Address. When set to '1', the DMAC fetches the next command defined by LINKADDR. + * When set to '0' the DMAC will return to idle at the end of the current command. + * NOTE: the linked command fetched by the DMAC needs to clear this field to mark the end of the command chain. + * Otherwise it may result in an infinite loop of the same command. + */ +#define DMA350_CH_LINKADDR_LINKADDR_Pos (2U) +#define DMA350_CH_LINKADDR_LINKADDR_Msk (0x3FFFFFFFUL << DMA350_CH_LINKADDR_LINKADDR_Pos) /*!< 0xFFFFFFFCUL*/ +#define DMA350_CH_LINKADDR_LINKADDR DMA350_CH_LINKADDR_LINKADDR_Msk +/*!< LINKADDR[29:0] bits Link Address Pointer [31:2]. The DMAC fetches the next command from this address + * if LINKADDREN is set. + * NOTE: Commands are fetched with the security and privilege attribute of the + * channel and cannot be adjusted for the command link reads. + */ +/*************** Field definitions for CH_LINKADDRHI register ***************/ +#define DMA350_CH_LINKADDRHI_LINKADDRHI_Pos (0U) +#define DMA350_CH_LINKADDRHI_LINKADDRHI_Msk (0xFFFFFFFFUL << DMA350_CH_LINKADDRHI_LINKADDRHI_Pos) +#define DMA350_CH_LINKADDRHI_LINKADDRHI DMA350_CH_LINKADDRHI_LINKADDRHI_Msk +/*!< LINKADDRHI[31:0] bits Link Address Pointer [63:32]. Allows 64-bit addressing but the system + * might need less address bits. Limited by ADDR_WIDTH and the not implemented bits remain reserved. + */ + +/*************** Field definitions for Non-Secure Control register ***************/ +#define INTREN_ANYCHINTR_ENABLE (1U) + + +#endif /* __DMA350_REGDEF_H */ diff --git a/drivers/firmware/Kconfig b/drivers/firmware/Kconfig index 3f2f22e47bfa..a7ed114827d0 100644 --- a/drivers/firmware/Kconfig +++ b/drivers/firmware/Kconfig @@ -310,6 +310,7 @@ source "drivers/firmware/cirrus/Kconfig" source "drivers/firmware/google/Kconfig" source "drivers/firmware/efi/Kconfig" source "drivers/firmware/imx/Kconfig" +source "drivers/firmware/cix/Kconfig" source "drivers/firmware/meson/Kconfig" source "drivers/firmware/psci/Kconfig" source "drivers/firmware/smccc/Kconfig" diff --git a/drivers/firmware/Makefile b/drivers/firmware/Makefile index 28fcddcd688f..e02bdf758162 100644 --- a/drivers/firmware/Makefile +++ b/drivers/firmware/Makefile @@ -34,6 +34,7 @@ obj-y += meson/ obj-$(CONFIG_GOOGLE_FIRMWARE) += google/ obj-y += efi/ obj-y += imx/ +obj-y += cix/ obj-y += psci/ obj-y += smccc/ obj-y += tegra/ diff --git a/drivers/firmware/arm_scmi/Kconfig b/drivers/firmware/arm_scmi/Kconfig index ea0f5083ac47..9231f1826f33 100644 --- a/drivers/firmware/arm_scmi/Kconfig +++ b/drivers/firmware/arm_scmi/Kconfig @@ -181,6 +181,18 @@ config ARM_SCMI_POWER_DOMAIN will be called scmi_pm_domain. Note this may needed early in boot before rootfs may be available. +config ARM_SCMI_PERF_DOMAIN + tristate "SCMI performance domain driver" + depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF) + default y + select PM_GENERIC_DOMAINS if PM + help + This enables support for the SCMI performance domains which can be + enabled or disabled via the SCP firmware. + + This driver can also be built as a module. If so, the module will be + called scmi_perf_domain. + config ARM_SCMI_POWER_CONTROL tristate "SCMI system power control driver" depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF) @@ -193,4 +205,15 @@ config ARM_SCMI_POWER_CONTROL called scmi_power_control. Note this may needed early in boot to catch early shutdown/reboot SCMI requests. +config SCMI_CUSTOMIZED + tristate "SCMI CUSTOMIZED For PM" + depends on ARM_SCMI_PROTOCOL || (COMPILE_TEST && OF) + +config ARM_SCMI_SUPPORT_DT_ACPI + tristate "ARM SCMI supports both DT and ACPI or only support DT" + default n + select PM_GENERIC_DOMAINS if PM + help + This enables all implemented protocols to support for DT and ACPI. + endmenu diff --git a/drivers/firmware/arm_scmi/bus.c b/drivers/firmware/arm_scmi/bus.c index dcf774d3edfe..c27be72e05b3 100644 --- a/drivers/firmware/arm_scmi/bus.c +++ b/drivers/firmware/arm_scmi/bus.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "common.h" @@ -314,7 +315,7 @@ static void scmi_device_release(struct device *dev) static void __scmi_device_destroy(struct scmi_device *scmi_dev) { pr_debug("(%s) Destroying SCMI device '%s' for protocol 0x%x (%s)\n", - of_node_full_name(scmi_dev->dev.parent->of_node), + fwnode_get_name(scmi_dev->dev.parent->fwnode), dev_name(&scmi_dev->dev), scmi_dev->protocol_id, scmi_dev->name); @@ -326,7 +327,7 @@ static void __scmi_device_destroy(struct scmi_device *scmi_dev) } static struct scmi_device * -__scmi_device_create(struct device_node *np, struct device *parent, +__scmi_device_create(struct fwnode_handle *np, struct device *parent, int protocol, const char *name) { int id, retval; @@ -377,7 +378,7 @@ __scmi_device_create(struct device_node *np, struct device *parent, scmi_dev->id = id; scmi_dev->protocol_id = protocol; scmi_dev->dev.parent = parent; - device_set_node(&scmi_dev->dev, of_fwnode_handle(np)); + device_set_node(&scmi_dev->dev, np); scmi_dev->dev.bus = &scmi_bus_type; scmi_dev->dev.release = scmi_device_release; dev_set_name(&scmi_dev->dev, "scmi_dev.%d", id); @@ -386,8 +387,8 @@ __scmi_device_create(struct device_node *np, struct device *parent, if (retval) goto put_dev; - pr_debug("(%s) Created SCMI device '%s' for protocol 0x%x (%s)\n", - of_node_full_name(parent->of_node), + pr_info("(%s) Created SCMI device '%s' for protocol 0x%x (%s)\n", + fwnode_get_name(parent->fwnode), dev_name(&scmi_dev->dev), protocol, name); return scmi_dev; @@ -420,7 +421,7 @@ put_dev: * could have been potentially created for a whole protocol, unless no * device was found to have been requested for that specific protocol. */ -struct scmi_device *scmi_device_create(struct device_node *np, +struct scmi_device *scmi_device_create(struct fwnode_handle *np, struct device *parent, int protocol, const char *name) { @@ -451,7 +452,7 @@ struct scmi_device *scmi_device_create(struct device_node *np, scmi_dev = sdev; else pr_err("(%s) Failed to create device for protocol 0x%x (%s)\n", - of_node_full_name(parent->of_node), + fwnode_get_name(parent->fwnode), rdev->id_table->protocol_id, rdev->id_table->name); } diff --git a/drivers/firmware/arm_scmi/common.h b/drivers/firmware/arm_scmi/common.h index 039f686f4580..25a53dee02d9 100644 --- a/drivers/firmware/arm_scmi/common.h +++ b/drivers/firmware/arm_scmi/common.h @@ -147,7 +147,7 @@ extern struct bus_type scmi_bus_type; #define SCMI_BUS_NOTIFY_DEVICE_UNREQUEST 1 extern struct blocking_notifier_head scmi_requested_devices_nh; -struct scmi_device *scmi_device_create(struct device_node *np, +struct scmi_device *scmi_device_create(struct fwnode_handle *np, struct device *parent, int protocol, const char *name); void scmi_device_destroy(struct device *parent, int protocol, const char *name); @@ -201,7 +201,7 @@ struct scmi_chan_info { */ struct scmi_transport_ops { int (*link_supplier)(struct device *dev); - bool (*chan_available)(struct device_node *of_node, int idx); + bool (*chan_available)(struct fwnode_handle *fwnode, int idx); int (*chan_setup)(struct scmi_chan_info *cinfo, struct device *dev, bool tx); int (*chan_free)(int id, void *p, void *data); diff --git a/drivers/firmware/arm_scmi/driver.c b/drivers/firmware/arm_scmi/driver.c index efa9698c876a..37d918964b6e 100644 --- a/drivers/firmware/arm_scmi/driver.c +++ b/drivers/firmware/arm_scmi/driver.c @@ -260,7 +260,7 @@ EXPORT_SYMBOL_GPL(scmi_protocol_unregister); * call will lead to the creation of all the devices currently requested * for the specified protocol. */ -static void scmi_create_protocol_devices(struct device_node *np, +static void scmi_create_protocol_devices(struct fwnode_handle *np, struct scmi_info *info, int prot_id, const char *name) { @@ -1712,8 +1712,8 @@ err_xfer: ph->xops->xfer_put(ph, t); err_out: - dev_warn(ph->dev, - "Failed to get FC for protocol %X [MSG_ID:%u / RES_ID:%u] - ret:%d. Using regular messaging.\n", + dev_info(ph->dev, + "Cannot configure FC for protocol %X [MSG_ID:%u / RES_ID:%u] - ret:%d. Using regular messaging.\n", pi->proto->id, message_id, domain, ret); } @@ -1970,6 +1970,11 @@ scmi_is_protocol_implemented(const struct scmi_handle *handle, u8 prot_id) struct scmi_info *info = handle_to_scmi_info(handle); struct scmi_revision_info *rev = handle->version; +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + if (prot_id == SCMI_PROTOCOL_PM_EXCP) + return true; +#endif + if (!info->protocols_imp) return false; @@ -2300,7 +2305,7 @@ static int scmi_xfer_info_init(struct scmi_info *sinfo) return ret; } -static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, +static int scmi_chan_setup(struct scmi_info *info, struct fwnode_handle *fwnode, int prot_id, bool tx) { int ret, idx; @@ -2313,7 +2318,7 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, idx = tx ? 0 : 1; idr = tx ? &info->tx_idr : &info->rx_idr; - if (!info->desc->ops->chan_available(of_node, idx)) { + if (!info->desc->ops->chan_available(fwnode, idx)) { cinfo = idr_find(idr, SCMI_PROTOCOL_BASE); if (unlikely(!cinfo)) /* Possible only if platform has no Rx */ return -EINVAL; @@ -2331,20 +2336,20 @@ static int scmi_chan_setup(struct scmi_info *info, struct device_node *of_node, snprintf(name, 32, "__scmi_transport_device_%s_%02X", idx ? "rx" : "tx", prot_id); /* Create a uniquely named, dedicated transport device for this chan */ - tdev = scmi_device_create(of_node, info->dev, prot_id, name); + tdev = scmi_device_create(fwnode, info->dev, prot_id, name); if (!tdev) { dev_err(info->dev, "failed to create transport device (%s)\n", name); devm_kfree(info->dev, cinfo); return -EINVAL; } - of_node_get(of_node); + fwnode_handle_get(fwnode); cinfo->id = prot_id; cinfo->dev = &tdev->dev; ret = info->desc->ops->chan_setup(cinfo, info->dev, tx); if (ret) { - of_node_put(of_node); + fwnode_handle_put(fwnode); scmi_device_destroy(info->dev, prot_id, name); devm_kfree(info->dev, cinfo); return ret; @@ -2367,7 +2372,7 @@ idr_alloc: "unable to allocate SCMI idr slot err %d\n", ret); /* Destroy channel and device only if created by this call. */ if (tdev) { - of_node_put(of_node); + fwnode_handle_put(fwnode); scmi_device_destroy(info->dev, prot_id, name); devm_kfree(info->dev, cinfo); } @@ -2379,14 +2384,14 @@ idr_alloc: } static inline int -scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node, +scmi_txrx_setup(struct scmi_info *info, struct fwnode_handle *fwnode, int prot_id) { - int ret = scmi_chan_setup(info, of_node, prot_id, true); + int ret = scmi_chan_setup(info, fwnode, prot_id, true); if (!ret) { /* Rx is optional, report only memory errors */ - ret = scmi_chan_setup(info, of_node, prot_id, false); + ret = scmi_chan_setup(info, fwnode, prot_id, false); if (ret && ret != -ENOMEM) ret = 0; } @@ -2415,17 +2420,17 @@ scmi_txrx_setup(struct scmi_info *info, struct device_node *of_node, static int scmi_channels_setup(struct scmi_info *info) { int ret; - struct device_node *child, *top_np = info->dev->of_node; + struct fwnode_handle *child, *top_np = info->dev->fwnode; /* Initialize a common generic channel at first */ ret = scmi_txrx_setup(info, top_np, SCMI_PROTOCOL_BASE); if (ret) return ret; - for_each_available_child_of_node(top_np, child) { + fwnode_for_each_child_node(top_np, child) { u32 prot_id; - if (of_property_read_u32(child, "reg", &prot_id)) + if (fwnode_property_read_u32(child, "reg", &prot_id)) continue; if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) @@ -2434,7 +2439,7 @@ static int scmi_channels_setup(struct scmi_info *info) ret = scmi_txrx_setup(info, child, prot_id); if (ret) { - of_node_put(child); + fwnode_handle_put(child); return ret; } } @@ -2512,7 +2517,7 @@ static int scmi_bus_notifier(struct notifier_block *nb, static int scmi_device_request_notifier(struct notifier_block *nb, unsigned long action, void *data) { - struct device_node *np; + struct fwnode_handle *np; struct scmi_device_id *id_table = data; struct scmi_info *info = req_nb_to_scmi_info(nb); @@ -2663,9 +2668,9 @@ static int scmi_probe(struct platform_device *pdev) struct scmi_info *info; bool coex = IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT_COEX); struct device *dev = &pdev->dev; - struct device_node *child, *np = dev->of_node; + struct fwnode_handle *child, *np = dev->fwnode; - desc = of_device_get_match_data(dev); + desc = device_get_match_data(dev); if (!desc) return -EINVAL; @@ -2699,7 +2704,7 @@ static int scmi_probe(struct platform_device *pdev) handle->devm_protocol_put = scmi_devm_protocol_put; /* System wide atomic threshold for atomic ops .. if any */ - if (!of_property_read_u32(np, "atomic-threshold-us", + if (!fwnode_property_read_u32(np, "atomic-threshold-us", &info->atomic_threshold)) dev_info(dev, "SCMI System wide atomic threshold set to %d us\n", @@ -2712,7 +2717,7 @@ static int scmi_probe(struct platform_device *pdev) goto clear_ida; } - /* Setup all channels described in the DT at first */ + /* Setup all channels described in the DT/ACPI at first */ ret = scmi_channels_setup(info); if (ret) goto clear_ida; @@ -2775,10 +2780,10 @@ static int scmi_probe(struct platform_device *pdev) list_add_tail(&info->node, &scmi_list); mutex_unlock(&scmi_list_mutex); - for_each_available_child_of_node(np, child) { + fwnode_for_each_child_node(np, child) { u32 prot_id; - if (of_property_read_u32(child, "reg", &prot_id)) + if (fwnode_property_read_u32(child, "reg", &prot_id)) continue; if (!FIELD_FIT(MSG_PROTOCOL_ID_MASK, prot_id)) @@ -2802,7 +2807,7 @@ static int scmi_probe(struct platform_device *pdev) continue; } - of_node_get(child); + fwnode_handle_get(child); scmi_create_protocol_devices(child, info, prot_id, NULL); } @@ -2828,7 +2833,7 @@ static int scmi_remove(struct platform_device *pdev) { int id; struct scmi_info *info = platform_get_drvdata(pdev); - struct device_node *child; + struct fwnode_handle *child; if (IS_ENABLED(CONFIG_ARM_SCMI_RAW_MODE_SUPPORT)) scmi_raw_mode_cleanup(info->raw); @@ -2847,7 +2852,7 @@ static int scmi_remove(struct platform_device *pdev) mutex_unlock(&info->protocols_mtx); idr_for_each_entry(&info->active_protocols, child, id) - of_node_put(child); + fwnode_handle_put(child); idr_destroy(&info->active_protocols); blocking_notifier_chain_unregister(&scmi_requested_devices_nh, @@ -2928,11 +2933,25 @@ static const struct of_device_id scmi_of_match[] = { MODULE_DEVICE_TABLE(of, scmi_of_match); +#ifdef CONFIG_ARCH_CIX +static const struct acpi_device_id scmi_acpi_match[] = { +#ifdef CONFIG_ARM_SCMI_TRANSPORT_MAILBOX + { .id = "CIXHA006", .driver_data = (kernel_ulong_t)&scmi_mailbox_desc }, +#endif + { /* Sentinel */ }, +}; +#endif + +MODULE_DEVICE_TABLE(acpi, scmi_acpi_match); + static struct platform_driver scmi_driver = { .driver = { .name = "arm-scmi", .suppress_bind_attrs = true, .of_match_table = scmi_of_match, +#ifdef CONFIG_ARCH_CIX + .acpi_match_table = scmi_acpi_match, +#endif .dev_groups = versions_groups, }, .probe = scmi_probe, @@ -3026,10 +3045,17 @@ static int __init scmi_driver_init(void) scmi_voltage_register(); scmi_system_register(); scmi_powercap_register(); - +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + scmi_pm_excp_register(); +#endif return platform_driver_register(&scmi_driver); } -module_init(scmi_driver_init); + +#ifdef CONFIG_ARCH_CIX + subsys_initcall_sync(scmi_driver_init); +#else + module_init(scmi_driver_init); +#endif static void __exit scmi_driver_exit(void) { @@ -3043,6 +3069,9 @@ static void __exit scmi_driver_exit(void) scmi_voltage_unregister(); scmi_system_unregister(); scmi_powercap_unregister(); +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + scmi_pm_excp_unregister(); +#endif scmi_transports_exit(); diff --git a/drivers/firmware/arm_scmi/mailbox.c b/drivers/firmware/arm_scmi/mailbox.c index 8e513f70b75d..75f980d13bb0 100644 --- a/drivers/firmware/arm_scmi/mailbox.c +++ b/drivers/firmware/arm_scmi/mailbox.c @@ -12,6 +12,8 @@ #include #include #include +#include +#include #include "common.h" @@ -64,21 +66,29 @@ static void rx_callback(struct mbox_client *cl, void *m) scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL); } -static bool mailbox_chan_available(struct device_node *of_node, int idx) +static __maybe_unused void tx_done_callback(struct mbox_client *cl, void *m, int r) +{ + struct scmi_mailbox *smbox = client_to_scmi_mailbox(cl); + + scmi_rx_callback(smbox->cinfo, shmem_read_header(smbox->shmem), NULL); +} + +static bool mailbox_chan_available(struct fwnode_handle *fwnode, int idx) { int num_mb; + struct fwnode_reference_args fwnode_args; /* * Just check if bidirrectional channels are involved, and check the * index accordingly; proper full validation will be made later * in mailbox_chan_setup(). */ - num_mb = of_count_phandle_with_args(of_node, "mboxes", "#mbox-cells"); + num_mb = fwnode_count_reference_with_args(fwnode, "mboxes", "#mbox-cells"); if (num_mb == 3 && idx == 1) idx = 2; - return !of_parse_phandle_with_args(of_node, "mboxes", - "#mbox-cells", idx, NULL); + return !fwnode_property_get_reference_args(fwnode, "mboxes", "#mbox-cells", + 1, idx, &fwnode_args); } /** @@ -101,10 +111,10 @@ static int mailbox_chan_validate(struct device *cdev, int *a2p_rx_chan, int *p2a_chan) { int num_mb, num_sh, ret = 0; - struct device_node *np = cdev->of_node; + struct fwnode_handle *fwnode = cdev->fwnode; - num_mb = of_count_phandle_with_args(np, "mboxes", "#mbox-cells"); - num_sh = of_count_phandle_with_args(np, "shmem", NULL); + num_mb = fwnode_count_reference_with_args(fwnode, "mboxes", "#mbox-cells"); + num_sh = fwnode_count_reference_with_args(fwnode, "shmem", NULL); dev_dbg(cdev, "Found %d mboxes and %d shmems !\n", num_mb, num_sh); /* Bail out if mboxes and shmem descriptors are inconsistent */ @@ -112,24 +122,24 @@ static int mailbox_chan_validate(struct device *cdev, (num_mb == 1 && num_sh != 1) || (num_mb == 3 && num_sh != 2)) { dev_warn(cdev, "Invalid channel descriptor for '%s' - mbs:%d shm:%d\n", - of_node_full_name(np), num_mb, num_sh); + fwnode_get_name(fwnode), num_mb, num_sh); return -EINVAL; } /* Bail out if provided shmem descriptors do not refer distinct areas */ if (num_sh > 1) { - struct device_node *np_tx, *np_rx; + struct fwnode_handle *np_tx, *np_rx; - np_tx = of_parse_phandle(np, "shmem", 0); - np_rx = of_parse_phandle(np, "shmem", 1); + np_tx = fwnode_find_reference(fwnode, "shmem", 0); + np_rx = fwnode_find_reference(fwnode, "shmem", 1); if (!np_tx || !np_rx || np_tx == np_rx) { dev_warn(cdev, "Invalid shmem descriptor for '%s'\n", - of_node_full_name(np)); + fwnode_get_name(fwnode)); ret = -EINVAL; } - of_node_put(np_tx); - of_node_put(np_rx); + fwnode_handle_put(np_tx); + fwnode_handle_put(np_rx); } /* Calculate channels IDs to use depending on mboxes/shmem layout */ @@ -163,12 +173,15 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, { const char *desc = tx ? "Tx" : "Rx"; struct device *cdev = cinfo->dev; + struct device *rdev; struct scmi_mailbox *smbox; - struct device_node *shmem; + struct fwnode_handle *shmem; int ret, a2p_rx_chan, p2a_chan, idx = tx ? 0 : 1; struct mbox_client *cl; resource_size_t size; - struct resource res; + struct resource *res; + struct platform_device *pdev; + const char *str[1]; ret = mailbox_chan_validate(cdev, &a2p_rx_chan, &p2a_chan); if (ret) @@ -181,21 +194,37 @@ static int mailbox_chan_setup(struct scmi_chan_info *cinfo, struct device *dev, if (!smbox) return -ENOMEM; - shmem = of_parse_phandle(cdev->of_node, "shmem", idx); - if (!of_device_is_compatible(shmem, "arm,scmi-shmem")) { - of_node_put(shmem); - return -ENXIO; + shmem = fwnode_find_reference(cdev->fwnode, "shmem", idx); + + if (IS_ERR_OR_NULL(shmem)) + return -ENODEV; + + rdev = bus_find_device_by_fwnode(&platform_bus_type, shmem); + pdev = rdev ? to_platform_device(rdev) : NULL; + + if (IS_ERR_OR_NULL(pdev)) + return ENODEV; + + if (fwnode_property_present(shmem, "compatible")) { + ret = fwnode_property_read_string(shmem, "compatible", (const char **)&str); + + if (!strcmp(str[0], "arm,scmi-shmem")) { + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + fwnode_handle_put(shmem); + } else { + ret = -ENXIO; + } + } else { + ret = -ENXIO; } - ret = of_address_to_resource(shmem, 0, &res); - of_node_put(shmem); if (ret) { dev_err(cdev, "failed to get SCMI %s shared memory\n", desc); return ret; } - size = resource_size(&res); - smbox->shmem = devm_ioremap(dev, res.start, size); + size = resource_size(res); + smbox->shmem = devm_ioremap(dev, res->start, size); if (!smbox->shmem) { dev_err(dev, "failed to ioremap SCMI %s shared memory\n", desc); return -EADDRNOTAVAIL; @@ -333,7 +362,7 @@ static const struct scmi_transport_ops scmi_mailbox_ops = { const struct scmi_desc scmi_mailbox_desc = { .ops = &scmi_mailbox_ops, - .max_rx_timeout_ms = 30, /* We may increase this if required */ + .max_rx_timeout_ms = 300, /* We may increase this if required */ .max_msg = 20, /* Limited by MBOX_TX_QUEUE_LEN */ .max_msg_size = 128, }; diff --git a/drivers/firmware/arm_scmi/optee.c b/drivers/firmware/arm_scmi/optee.c index aa02392265d3..f2ef88b2235e 100644 --- a/drivers/firmware/arm_scmi/optee.c +++ b/drivers/firmware/arm_scmi/optee.c @@ -328,12 +328,15 @@ static int scmi_optee_link_supplier(struct device *dev) return 0; } -static bool scmi_optee_chan_available(struct device_node *of_node, int idx) +static bool scmi_optee_chan_available(struct fwnode_handle *fwnode, int idx) { - u32 channel_id; + int count; - return !of_property_read_u32_index(of_node, "linaro,optee-channel-id", - idx, &channel_id); + count = fwnode_property_count_u32(fwnode, "linaro,optee-channel-id"); + if (idx >= count) + return false; + else + return true; } static void scmi_optee_clear_channel(struct scmi_chan_info *cinfo) diff --git a/drivers/firmware/arm_scmi/perf.c b/drivers/firmware/arm_scmi/perf.c index dd344506b0a3..ffb08266e442 100644 --- a/drivers/firmware/arm_scmi/perf.c +++ b/drivers/firmware/arm_scmi/perf.c @@ -767,45 +767,59 @@ static int scmi_perf_level_limits_notify(const struct scmi_protocol_handle *ph, } static void scmi_perf_domain_init_fc(const struct scmi_protocol_handle *ph, - u32 domain, struct scmi_fc_info **p_fc) + u32 domain, struct perf_dom_info* dom) { + struct scmi_fc_info **p_fc = &dom->fc_info; struct scmi_fc_info *fc; fc = devm_kcalloc(ph->dev, PERF_FC_MAX, sizeof(*fc), GFP_KERNEL); if (!fc) return; - ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, - PERF_LEVEL_SET, 4, domain, - &fc[PERF_FC_LEVEL].set_addr, - &fc[PERF_FC_LEVEL].set_db); + if (dom->info.set_perf) { + ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, + PERF_LEVEL_SET, 4, domain, + &fc[PERF_FC_LEVEL].set_addr, + &fc[PERF_FC_LEVEL].set_db); - ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, - PERF_LEVEL_GET, 4, domain, - &fc[PERF_FC_LEVEL].get_addr, NULL); + ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, + PERF_LEVEL_GET, 4, domain, + &fc[PERF_FC_LEVEL].get_addr, NULL); + } - ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, - PERF_LIMITS_SET, 8, domain, - &fc[PERF_FC_LIMIT].set_addr, - &fc[PERF_FC_LIMIT].set_db); - - ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, - PERF_LIMITS_GET, 8, domain, - &fc[PERF_FC_LIMIT].get_addr, NULL); + if (dom->set_limits) { + ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, + PERF_LIMITS_SET, 8, domain, + &fc[PERF_FC_LIMIT].set_addr, + &fc[PERF_FC_LIMIT].set_db); + ph->hops->fastchannel_init(ph, PERF_DESCRIBE_FASTCHANNEL, + PERF_LIMITS_GET, 8, domain, + &fc[PERF_FC_LIMIT].get_addr, NULL); + } *p_fc = fc; } /* Device specific ops */ static int scmi_dev_domain_id(struct device *dev) { - struct of_phandle_args clkspec; + struct fwnode_reference_args fwnode_args; + int index; - if (of_parse_phandle_with_args(dev->of_node, "clocks", "#clock-cells", - 0, &clkspec)) - return -EINVAL; + /* Find the corresponding index for power-domain "perf". */ + index = fwnode_property_match_string(dev->fwnode, "power-domain-names", "perf"); + if (index < 0) { + if (fwnode_property_get_reference_args(dev->fwnode, "clocks", + "#clock-cells", 1, 0, &fwnode_args)) + return -EINVAL; + } else { + if (fwnode_property_get_reference_args(dev->fwnode, "power-domains", + "#power-domain-cells", 1, index, + &fwnode_args)) + return -EINVAL; + } - return clkspec.args[0]; + return fwnode_args.args[0]; } static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph, @@ -813,6 +827,10 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph, { int idx, ret, domain; unsigned long freq; +#ifdef CONFIG_ARCH_CIX + unsigned long volt; +#endif + struct scmi_opp *opp; struct perf_dom_info *dom; domain = scmi_dev_domain_id(dev); @@ -823,13 +841,14 @@ static int scmi_dvfs_device_opps_add(const struct scmi_protocol_handle *ph, if (IS_ERR(dom)) return PTR_ERR(dom); - for (idx = 0; idx < dom->opp_count; idx++) { - if (!dom->level_indexing_mode) - freq = dom->opp[idx].perf * dom->mult_factor; - else - freq = dom->opp[idx].indicative_freq * dom->mult_factor; - + for (opp = dom->opp, idx = 0; idx < dom->opp_count; idx++, opp++) { + freq = opp->perf * dom->mult_factor; +#ifdef CONFIG_ARCH_CIX + volt = opp->power * 1000; /* translate mV to uV */ + ret = dev_pm_opp_add(dev, freq, volt); +#else ret = dev_pm_opp_add(dev, freq, 0); +#endif if (ret) { dev_warn(dev, "failed to add opp %luHz\n", freq); dev_pm_opp_remove_all_dynamic(dev); @@ -1127,7 +1146,7 @@ static int scmi_perf_protocol_init(const struct scmi_protocol_handle *ph) scmi_perf_describe_levels_get(ph, dom, version); if (dom->perf_fastchannels) - scmi_perf_domain_init_fc(ph, dom->id, &dom->fc_info); + scmi_perf_domain_init_fc(ph, dom->id, dom); } ret = devm_add_action_or_reset(ph->dev, scmi_perf_xa_destroy, pinfo); diff --git a/drivers/firmware/arm_scmi/protocols.h b/drivers/firmware/arm_scmi/protocols.h index 78e1a01eb656..f54c9db5cdf0 100644 --- a/drivers/firmware/arm_scmi/protocols.h +++ b/drivers/firmware/arm_scmi/protocols.h @@ -345,5 +345,8 @@ DECLARE_SCMI_REGISTER_UNREGISTER(sensors); DECLARE_SCMI_REGISTER_UNREGISTER(voltage); DECLARE_SCMI_REGISTER_UNREGISTER(system); DECLARE_SCMI_REGISTER_UNREGISTER(powercap); +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL +DECLARE_SCMI_REGISTER_UNREGISTER(pm_excp); +#endif #endif /* _SCMI_PROTOCOLS_H */ diff --git a/drivers/firmware/arm_scmi/scmi_pm_domain.c b/drivers/firmware/arm_scmi/scmi_pm_domain.c index 0e05a79de82d..a2c50d64ed4d 100644 --- a/drivers/firmware/arm_scmi/scmi_pm_domain.c +++ b/drivers/firmware/arm_scmi/scmi_pm_domain.c @@ -146,7 +146,16 @@ static struct scmi_driver scmi_power_domain_driver = { .remove = scmi_pm_domain_remove, .id_table = scmi_id_table, }; + +#ifdef CONFIG_ARCH_CIX +static int __init scmi_power_domain_init(void) +{ + return scmi_register(&scmi_power_domain_driver); +} +subsys_initcall_sync(scmi_power_domain_init); +#else module_scmi_driver(scmi_power_domain_driver); +#endif MODULE_AUTHOR("Sudeep Holla "); MODULE_DESCRIPTION("ARM SCMI power domain driver"); diff --git a/drivers/firmware/arm_scmi/shmem.c b/drivers/firmware/arm_scmi/shmem.c index 517d52fb3bcb..ee99a10c9fd4 100644 --- a/drivers/firmware/arm_scmi/shmem.c +++ b/drivers/firmware/arm_scmi/shmem.c @@ -13,12 +13,12 @@ #include #include "common.h" - /* * SCMI specification requires all parameters, message headers, return * arguments or any protocol data to be expressed in little endian * format only. */ +#ifndef CONFIG_PM_EXCEPTION_PROTOCOL struct scmi_shared_mem { __le32 reserved; __le32 channel_status; @@ -31,12 +31,63 @@ struct scmi_shared_mem { __le32 msg_header; u8 msg_payload[]; }; +#else + +#define SCP_PM_MSG_LEN (0x7f) +#define PM_MSG_MAX_LEN_TX (12 * 4) +#define PM_MSG_MAX_LEN_RX (13 * 4) + +struct scmi_shared_mem { + union { + __le32 reserved; + struct { + __le32 buf_len : 7; + __le32 rsvd0 : 1; + __le32 msg_route: 8; + __le32 rsvd1 : 16; + } msg_info; + }; + __le32 channel_status; +#define SCMI_SHMEM_CHAN_STAT_CHANNEL_ERROR BIT(1) +#define SCMI_SHMEM_CHAN_STAT_CHANNEL_FREE BIT(0) + union { + __le32 reserved1[2]; + struct { + __le32 statusCode; + __le32 traceCode; + } stCode; + }; + __le32 flags; +#define SCMI_SHMEM_FLAG_INTR_ENABLED BIT(0) + __le32 length; + union { + __le32 msg_header; + struct { + __le32 msgID : 16; + __le32 rsvd0 : 2; + __le32 token : 10; + __le32 rsvd1 : 4; + } pm_header; + }; + u8 msg_payload[]; +}; +#endif void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, struct scmi_xfer *xfer, struct scmi_chan_info *cinfo) { ktime_t stop; +#ifdef CONFIG_ARCH_CIX + int i; +#endif +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + bool isCustomized; + if (xfer->hdr.protocol_id == 0x81) + isCustomized = true; + else + isCustomized = false; +#endif /* * Ideally channel must be free by now unless OS timeout last * request and platform continued to process the same, wait @@ -69,8 +120,25 @@ void shmem_tx_prepare(struct scmi_shared_mem __iomem *shmem, &shmem->flags); iowrite32(sizeof(shmem->msg_header) + xfer->tx.len, &shmem->length); iowrite32(pack_scmi_header(&xfer->hdr), &shmem->msg_header); - if (xfer->tx.buf) +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + if (isCustomized) + iowrite32(0xc7f, &shmem->msg_info); + else + iowrite32(0x0, &shmem->reserved); +#endif + if (xfer->tx.buf) { +#ifdef CONFIG_ARCH_CIX +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + if (isCustomized) + if (xfer->tx.len > PM_MSG_MAX_LEN_TX) + pr_err("TX Length is OVERSIZE!\n"); +#endif + for (i = 0; i < DIV_ROUND_UP(xfer->tx.len, 4); i++) + __raw_writel(((u32 *)xfer->tx.buf)[i], shmem->msg_payload + 4 * i); +#else memcpy_toio(shmem->msg_payload, xfer->tx.buf, xfer->tx.len); +#endif + } } u32 shmem_read_header(struct scmi_shared_mem __iomem *shmem) @@ -83,24 +151,86 @@ void shmem_fetch_response(struct scmi_shared_mem __iomem *shmem, { size_t len = ioread32(&shmem->length); - xfer->hdr.status = ioread32(shmem->msg_payload); - /* Skip the length of header and status in shmem area i.e 8 bytes */ - xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0); +#ifdef CONFIG_ARCH_CIX + int i; +#endif +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + bool isCustomized; + + if (xfer->hdr.protocol_id == 0x81) + isCustomized = true; + else + isCustomized = false; +#endif + +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + if (isCustomized) + xfer->hdr.status = ioread32(&shmem->stCode.statusCode); + else + xfer->hdr.status = ioread32(shmem->msg_payload); +#else + xfer->hdr.status = ioread32(shmem->msg_payload); +#endif +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + if (isCustomized) + xfer->rx.len = min_t(size_t, xfer->rx.len, len > 4 ? len - 4 : 0); + else + /* Skip the length of header and status in shmem area i.e 8 bytes */ + xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0); +#else + xfer->rx.len = min_t(size_t, xfer->rx.len, len > 8 ? len - 8 : 0); +#endif + +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + if (isCustomized) + if (xfer->rx.len > PM_MSG_MAX_LEN_RX) + pr_err("RX Length is OVERSIZE!\n"); +#endif /* Take a copy to the rx buffer.. */ +#ifdef CONFIG_ARCH_CIX +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + if (isCustomized) { + for (i = 0; i < DIV_ROUND_UP(xfer->rx.len, 4); i++) + ((u32 *)xfer->rx.buf)[i] = ioread32(shmem->msg_payload + 4 * (i + 12)); + } else { + for (i = 0; i < DIV_ROUND_UP(xfer->rx.len, 4); i++) + ((u32 *)xfer->rx.buf)[i] = ioread32(shmem->msg_payload + 4 * (i + 1)); + } +#else + for (i = 0; i < DIV_ROUND_UP(xfer->rx.len, 4); i++) + ((u32 *)xfer->rx.buf)[i] = ioread32(shmem->msg_payload + 4 * (i + 1)); +#endif +#else memcpy_fromio(xfer->rx.buf, shmem->msg_payload + 4, xfer->rx.len); +#endif } void shmem_fetch_notification(struct scmi_shared_mem __iomem *shmem, size_t max_len, struct scmi_xfer *xfer) { size_t len = ioread32(&shmem->length); +#ifdef CONFIG_ARCH_CIX + int i; +#endif +#ifdef CONFIG_PM_EXCEPTION_PROTOCOL + bool isCustomized; + if (xfer->hdr.protocol_id == 0x81) + isCustomized = true; + else + isCustomized = false; +#endif /* Skip only the length of header in shmem area i.e 4 bytes */ xfer->rx.len = min_t(size_t, max_len, len > 4 ? len - 4 : 0); /* Take a copy to the rx buffer.. */ +#ifdef CONFIG_ARCH_CIX + for (i = 0; i < DIV_ROUND_UP(xfer->rx.len, 4); i++) + ((u32 *)xfer->rx.buf)[i] = ioread32(shmem->msg_payload + 4 * i); +#else memcpy_fromio(xfer->rx.buf, shmem->msg_payload, xfer->rx.len); +#endif } void shmem_clear_channel(struct scmi_shared_mem __iomem *shmem) diff --git a/drivers/firmware/arm_scmi/smc.c b/drivers/firmware/arm_scmi/smc.c index 771797b6e268..a35f34cd0614 100644 --- a/drivers/firmware/arm_scmi/smc.c +++ b/drivers/firmware/arm_scmi/smc.c @@ -75,14 +75,16 @@ static irqreturn_t smc_msg_done_isr(int irq, void *data) return IRQ_HANDLED; } -static bool smc_chan_available(struct device_node *of_node, int idx) +static bool smc_chan_available(struct fwnode_handle *fwnode, int idx) { - struct device_node *np = of_parse_phandle(of_node, "shmem", 0); - if (!np) - return false; + struct fwnode_handle *ref_fwnode; - of_node_put(np); - return true; + ref_fwnode = fwnode_find_reference(fwnode, "shmem", 0); + if (!IS_ERR_OR_NULL(ref_fwnode)) { + fwnode_handle_put(ref_fwnode); + return true; + } + return false; } static inline void smc_channel_lock_init(struct scmi_smc *scmi_info) diff --git a/drivers/firmware/arm_scmi/virtio.c b/drivers/firmware/arm_scmi/virtio.c index d68c01cb7aa0..5fba8ba2d09d 100644 --- a/drivers/firmware/arm_scmi/virtio.c +++ b/drivers/firmware/arm_scmi/virtio.c @@ -385,7 +385,7 @@ static int virtio_link_supplier(struct device *dev) return 0; } -static bool virtio_chan_available(struct device_node *of_node, int idx) +static bool virtio_chan_available(struct fwnode_handle *fwnode, int idx) { struct scmi_vio_channel *channels, *vioch = NULL; diff --git a/drivers/firmware/arm_sdei.c b/drivers/firmware/arm_sdei.c index 3e8051fe8296..4284988ec457 100644 --- a/drivers/firmware/arm_sdei.c +++ b/drivers/firmware/arm_sdei.c @@ -31,6 +31,9 @@ #include #include #include +#ifdef CONFIG_PLAT_SDEI_EXCEPTIONS_TEST +#include +#endif /* * The call to use to reach the firmware. @@ -1068,11 +1071,13 @@ void __init sdei_init(void) int ret; ret = platform_driver_register(&sdei_driver); + if (ret || !sdei_present_acpi()) return; pdev = platform_device_register_simple(sdei_driver.driver.name, 0, NULL, 0); + if (IS_ERR(pdev)) { ret = PTR_ERR(pdev); platform_driver_unregister(&sdei_driver); diff --git a/drivers/firmware/cix/Kconfig b/drivers/firmware/cix/Kconfig new file mode 100644 index 000000000000..4842071e91f9 --- /dev/null +++ b/drivers/firmware/cix/Kconfig @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: GPL-2.0-only +config CIX_DSP + tristate "CIX DSP Protocol driver" + depends on CIX_MBOX + help + This enables DSP IPC protocol between host AP (Linux) and + the firmware running on DSP. + It acts like a doorbell. Client might use shared memory to + exchange information with DSP side. diff --git a/drivers/firmware/cix/Makefile b/drivers/firmware/cix/Makefile new file mode 100644 index 000000000000..8a64ca725239 --- /dev/null +++ b/drivers/firmware/cix/Makefile @@ -0,0 +1,2 @@ +# SPDX-License-Identifier: GPL-2.0 +obj-$(CONFIG_CIX_DSP) += cix-dsp.o diff --git a/drivers/firmware/cix/cix-dsp.c b/drivers/firmware/cix/cix-dsp.c new file mode 100644 index 000000000000..32c8018ed04f --- /dev/null +++ b/drivers/firmware/cix/cix-dsp.c @@ -0,0 +1,174 @@ +// SPDX-License-Identifier: GPL-2.0+ +/* + * Implementation of the DSP IPC interface (host side) + * + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include + +static const char * const dsp_mbox_ch_names[CIX_DSP_MBOX_NUM] = { "txdb", "rxdb" }; + +static void __maybe_unused cix_dsp_mbox_dump_regs(struct cix_dsp_ipc *dsp_ipc) +{ + void __iomem *base; + uint32_t val; + int i; +#define MBOX_BASE_AP2DSP (0x070f0000) +#define MBOX_BASE_DSP2AP (0x07100000) +#define MBOX_REG_SIZE (0x10000) +#define MBOX_RGE_DUMP_NUM (20) +#define MBOX_REG_OFFSET (0x80) + + base = ioremap(MBOX_BASE_AP2DSP, MBOX_REG_SIZE); + for (i = 0; i < MBOX_RGE_DUMP_NUM; i++) { + val = readl(base + MBOX_REG_OFFSET + 4*i); + dev_info(dsp_ipc->dev, "[0x%x]: 0x%x\n", + MBOX_REG_OFFSET + 4*i, val); + } + iounmap(base); + + base = ioremap(MBOX_BASE_DSP2AP, MBOX_REG_SIZE); + for (i = 0; i < MBOX_RGE_DUMP_NUM; i++) { + val = readl(base + MBOX_REG_OFFSET + 4*i); + dev_info(dsp_ipc->dev, "[0x%x]: 0x%x\n", + MBOX_REG_OFFSET + 4*i, val); + } + iounmap(base); +} + +int cix_dsp_ipc_send(struct cix_dsp_ipc *ipc, unsigned int idx, uint32_t msg) +{ + struct cix_dsp_chan *dsp_chan; + int ret; + + if (idx >= CIX_DSP_MBOX_NUM) + return -EINVAL; + + dsp_chan = &ipc->chans[idx]; + ret = mbox_send_message(dsp_chan->ch, &msg); + if (ret < 0) + return ret; + + return 0; +} +EXPORT_SYMBOL_GPL(cix_dsp_ipc_send); + +static void cix_dsp_rx_callback(struct mbox_client *cl, void *msg) +{ + struct cix_dsp_chan *chan = container_of(cl, struct cix_dsp_chan, cl); + struct device *dev = cl->dev; + + switch (chan->idx) { + case CIX_DSP_MBOX_REPLY: + chan->ipc->ops->handle_reply(chan->ipc); + mbox_client_txdone(chan->ch, 0); + break; + case CIX_DSP_MBOX_REQUEST: + chan->ipc->ops->handle_request(chan->ipc); + break; + default: + dev_err(dev, "wrong mbox chan %d\n", chan->idx); + break; + } +} + +int cix_dsp_request_mbox(struct cix_dsp_ipc *dsp_ipc) +{ + struct device *dev = dsp_ipc->dev; + struct cix_dsp_chan *dsp_chan; + struct mbox_client *cl; + int i, j; + int ret; + + /* + * AP req -- txdb --> DSP + * AP <-- txdb -- DSP rsp + * AP <-- rxdb -- DSP req + * AP rsp -- rxdb --> DSP + */ + for (i = 0; i < CIX_DSP_MBOX_NUM; i++) { + dsp_chan = &dsp_ipc->chans[i]; + cl = &dsp_chan->cl; + cl->dev = dev; + cl->tx_block = false; + cl->knows_txdone = false; + cl->tx_prepare = NULL; + cl->rx_callback = cix_dsp_rx_callback; + + dsp_chan->ipc = dsp_ipc; + dsp_chan->idx = i; + dsp_chan->ch = mbox_request_channel_byname(cl, dsp_mbox_ch_names[i]); + if (IS_ERR(dsp_chan->ch)) { + ret = PTR_ERR(dsp_chan->ch); + if (ret != -EPROBE_DEFER) + dev_err(dev, "Failed to request mbox chan %s ret %d\n", + dsp_mbox_ch_names[i], ret); + + for (j = 0; j < i; j++) { + dsp_chan = &dsp_ipc->chans[j]; + mbox_free_channel(dsp_chan->ch); + } + + return ret; + } + } + + dsp_ipc->dev = dev; + + dev_info(dev, "CIX DSP IPC Mbox request\n"); + + return 0; +} +EXPORT_SYMBOL(cix_dsp_request_mbox); + +void cix_dsp_free_mbox(struct cix_dsp_ipc *dsp_ipc) +{ + struct device *dev = dsp_ipc->dev; + struct cix_dsp_chan *dsp_chan; + int i; + + for (i = 0; i < CIX_DSP_MBOX_NUM; i++) { + dsp_chan = &dsp_ipc->chans[i]; + mbox_free_channel(dsp_chan->ch); + } + + dev_info(dev, "CIX DSP IPC Mbox free\n"); +} +EXPORT_SYMBOL(cix_dsp_free_mbox); + +static int cix_dsp_probe(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + struct cix_dsp_ipc *dsp_ipc; + + device_set_node(&pdev->dev, pdev->dev.parent->fwnode); + + dsp_ipc = devm_kzalloc(dev, sizeof(*dsp_ipc), GFP_KERNEL); + if (!dsp_ipc) + return -ENOMEM; + + dsp_ipc->dev = dev; + dev_set_drvdata(dev, dsp_ipc); + + dev_info(dev, "CIX DSP IPC initialized\n"); + + return 0; +} + +static struct platform_driver cix_dsp_driver = { + .driver = { + .name = "cix-dsp", + }, + .probe = cix_dsp_probe, +}; +builtin_platform_driver(cix_dsp_driver); + +MODULE_AUTHOR("Joakim Zhang "); +MODULE_DESCRIPTION("CIX DSP IPC Driver"); +MODULE_LICENSE("GPL v2"); diff --git a/drivers/firmware/efi/efi-init.c b/drivers/firmware/efi/efi-init.c index 59b0d7197b68..a3f8949330af 100644 --- a/drivers/firmware/efi/efi-init.c +++ b/drivers/firmware/efi/efi-init.c @@ -24,6 +24,10 @@ unsigned long __initdata screen_info_table = EFI_INVALID_TABLE_ADDR; +#ifdef CONFIG_PLAT_KERNELDUMP +void __init kernel_dump_mem_reserve(void); +#endif + static int __init is_memory(efi_memory_desc_t *md) { if (md->attribute & (EFI_MEMORY_WB|EFI_MEMORY_WT|EFI_MEMORY_WC)) @@ -198,6 +202,9 @@ static __init void reserve_regions(void) memblock_reserve(paddr, size); } } +#ifdef CONFIG_PLAT_KERNELDUMP + kernel_dump_mem_reserve(); +#endif } void __init efi_init(void) diff --git a/drivers/firmware/psci/psci.c b/drivers/firmware/psci/psci.c index 2328ca58bba6..4f69d595656d 100644 --- a/drivers/firmware/psci/psci.c +++ b/drivers/firmware/psci/psci.c @@ -308,6 +308,7 @@ static int get_set_conduit_method(const struct device_node *np) static int psci_sys_reset(struct notifier_block *nb, unsigned long action, void *data) { + if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) && psci_system_reset2_supported) { /* @@ -532,6 +533,9 @@ static void __init psci_init_system_suspend(void) if (!IS_ENABLED(CONFIG_SUSPEND)) return; + if (!acpi_disabled) + return; + ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND)); if (ret != PSCI_RET_NOT_SUPPORTED) @@ -774,6 +778,31 @@ int __init psci_dt_init(void) * We use PSCI 0.2+ when ACPI is deployed on ARM64 and it's * explicitly clarified in SBBR */ + +int acpi_psci_enter_sleep_state(u8 acpi_state) +{ + switch (acpi_state) { + case ACPI_STATE_S3: + return psci_system_suspend_enter(acpi_state); + case ACPI_STATE_S4: + case ACPI_STATE_S5: + psci_sys_poweroff(); + return 0; + default: + return -EFAULT; + } +} + +bool acpi_psci_valid_sleep_state(u8 acpi_state) +{ + return acpi_state >= ACPI_STATE_S3; +} + +struct acpi_fw_sleep_ops psci_sleep_ops = { + .enter = acpi_psci_enter_sleep_state, + .valid = acpi_psci_valid_sleep_state +}; + int __init psci_acpi_init(void) { if (!acpi_psci_present()) { @@ -788,6 +817,8 @@ int __init psci_acpi_init(void) else set_conduit(SMCCC_CONDUIT_SMC); + acpi_set_fw_sleep_ops(&psci_sleep_ops); + return psci_probe(); } #endif diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig index ebd4e113dc26..8ec5bab91bad 100644 --- a/drivers/gpio/Kconfig +++ b/drivers/gpio/Kconfig @@ -59,7 +59,7 @@ config DEBUG_GPIO that are most common when setting up new platforms or boards. config GPIO_SYSFS - bool "/sys/class/gpio/... (sysfs interface)" if EXPERT + bool "/sys/class/gpio/... (sysfs interface)" depends on SYSFS select GPIO_CDEV # We need to encourage the new ABI help diff --git a/drivers/gpio/gpio-cadence.c b/drivers/gpio/gpio-cadence.c index 3720b90cad10..84348f41c674 100644 --- a/drivers/gpio/gpio-cadence.c +++ b/drivers/gpio/gpio-cadence.c @@ -8,13 +8,19 @@ * Boris Brezillon */ +#include #include #include #include #include #include #include +#include #include +#include +#include +#include +#include #define CDNS_GPIO_BYPASS_MODE 0x00 #define CDNS_GPIO_DIRECTION_MODE 0x04 @@ -29,13 +35,37 @@ #define CDNS_GPIO_IRQ_VALUE 0x28 #define CDNS_GPIO_IRQ_ANY_EDGE 0x2c +#define SKY1_SIP_GPIO_PDC 0xC2000009 +#define SKY1_SIP_GPIO_PDC_SET_WAKE 0x02 +#define GPIO_ENABLE_WAKE 1 + +struct cdns_gpio_reg_saved { + u32 bypass_mode; + u32 direction_mode; + u32 output_en; + u32 output_value; + u32 irq_mask; + u32 irq_en; + u32 irq_dis; + u32 irq_type; + u32 irq_value; + u32 irq_any_edge; + u32 wake_en; +}; + struct cdns_gpio_chip { struct gpio_chip gc; struct clk *pclk; + int id; void __iomem *regs; u32 bypass_orig; + struct reset_control *apb_reset; + struct cdns_gpio_reg_saved gpio_saved_reg; + u32 hw_irq; }; +static unsigned int cdns_gpio_base = 0; + static int cdns_gpio_request(struct gpio_chip *chip, unsigned int offset) { struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip); @@ -89,6 +119,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type) unsigned long flags; u32 int_value; u32 int_type; + u32 int_oany; u32 mask = BIT(d->hwirq); int ret = 0; @@ -96,6 +127,7 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type) int_value = ioread32(cgpio->regs + CDNS_GPIO_IRQ_VALUE) & ~mask; int_type = ioread32(cgpio->regs + CDNS_GPIO_IRQ_TYPE) & ~mask; + int_oany = ioread32(cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE) & ~mask; /* * The GPIO controller doesn't have an ACK register. @@ -103,10 +135,16 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type) * Don't support edge interrupts for now. */ - if (type == IRQ_TYPE_LEVEL_HIGH) { + if (type == IRQ_TYPE_EDGE_RISING) { + int_value |= mask; + } else if (type == IRQ_TYPE_EDGE_FALLING) { + int_value = int_value; + } else if (type == IRQ_TYPE_EDGE_BOTH) { + int_oany |= mask; + } else if (type == IRQ_TYPE_LEVEL_HIGH) { int_type |= mask; int_value |= mask; - } else if (type == IRQ_TYPE_LEVEL_LOW) { + } else if (type == IRQ_TYPE_LEVEL_LOW) { int_type |= mask; } else { ret = -EINVAL; @@ -115,12 +153,26 @@ static int cdns_gpio_irq_set_type(struct irq_data *d, unsigned int type) iowrite32(int_value, cgpio->regs + CDNS_GPIO_IRQ_VALUE); iowrite32(int_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE); - + iowrite32(int_oany, cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE); err_irq_type: raw_spin_unlock_irqrestore(&chip->bgpio_lock, flags); return ret; } +static int cdns_gpio_irq_set_wake(struct irq_data *d, unsigned int enable) +{ + struct gpio_chip *chip = irq_data_get_irq_chip_data(d); + struct cdns_gpio_chip *cgpio = gpiochip_get_data(chip); + + irq_hw_number_t bit = irqd_to_hwirq(d); + + if (enable) + cgpio->gpio_saved_reg.wake_en |= BIT(bit); + else + cgpio->gpio_saved_reg.wake_en &= ~BIT(bit); + return 0; +} + static void cdns_gpio_irq_handler(struct irq_desc *desc) { struct gpio_chip *chip = irq_desc_get_handler_data(desc); @@ -145,6 +197,7 @@ static const struct irq_chip cdns_gpio_irqchip = { .irq_mask = cdns_gpio_irq_mask, .irq_unmask = cdns_gpio_irq_unmask, .irq_set_type = cdns_gpio_irq_set_type, + .irq_set_wake = cdns_gpio_irq_set_wake, .flags = IRQCHIP_IMMUTABLE, GPIOCHIP_IRQ_RESOURCE_HELPERS, }; @@ -152,9 +205,11 @@ static const struct irq_chip cdns_gpio_irqchip = { static int cdns_gpio_probe(struct platform_device *pdev) { struct cdns_gpio_chip *cgpio; + struct irq_data *irq_data = NULL; int ret, irq; u32 dir_prev; u32 num_gpios = 32; + u32 gmask; cgpio = devm_kzalloc(&pdev->dev, sizeof(*cgpio), GFP_KERNEL); if (!cgpio) @@ -164,13 +219,20 @@ static int cdns_gpio_probe(struct platform_device *pdev) if (IS_ERR(cgpio->regs)) return PTR_ERR(cgpio->regs); - of_property_read_u32(pdev->dev.of_node, "ngpios", &num_gpios); - - if (num_gpios > 32) { + ret = device_property_read_u32(&pdev->dev, "ngpios", &num_gpios); + if (ret < 0 || num_gpios > 32) { dev_err(&pdev->dev, "ngpios must be less or equal 32\n"); return -EINVAL; } + cgpio->id = of_alias_get_id(pdev->dev.of_node, "gpio"); + if (cgpio->id < 0) + if (device_property_read_u32(&pdev->dev, "id", &cgpio->id)) + return cgpio->id; + + ret = device_property_read_u32(&pdev->dev, "gpio-io-mask", &gmask); + if (ret < 0) + gmask = 0; /* * Set all pins as inputs by default, otherwise: * gpiochip_lock_as_irq: @@ -179,7 +241,7 @@ static int cdns_gpio_probe(struct platform_device *pdev) * so it needs to be changed before bgpio_init() is called. */ dir_prev = ioread32(cgpio->regs + CDNS_GPIO_DIRECTION_MODE); - iowrite32(GENMASK(num_gpios - 1, 0), + iowrite32(GENMASK(num_gpios - 1, 0) & ~gmask, cgpio->regs + CDNS_GPIO_DIRECTION_MODE); ret = bgpio_init(&cgpio->gc, &pdev->dev, 4, @@ -198,24 +260,44 @@ static int cdns_gpio_probe(struct platform_device *pdev) cgpio->gc.label = dev_name(&pdev->dev); cgpio->gc.ngpio = num_gpios; cgpio->gc.parent = &pdev->dev; - cgpio->gc.base = -1; + cgpio->gc.base = cdns_gpio_base; + cdns_gpio_base += num_gpios; cgpio->gc.owner = THIS_MODULE; cgpio->gc.request = cdns_gpio_request; cgpio->gc.free = cdns_gpio_free; - cgpio->pclk = devm_clk_get(&pdev->dev, NULL); + cgpio->pclk = devm_clk_get_optional(&pdev->dev, NULL); if (IS_ERR(cgpio->pclk)) { ret = PTR_ERR(cgpio->pclk); dev_err(&pdev->dev, "Failed to retrieve peripheral clock, %d\n", ret); - goto err_revert_dir; + cgpio->pclk = NULL; } - ret = clk_prepare_enable(cgpio->pclk); - if (ret) { - dev_err(&pdev->dev, - "Failed to enable the peripheral clock, %d\n", ret); - goto err_revert_dir; + if (cgpio->pclk) + { + ret = clk_prepare_enable(cgpio->pclk); + if (ret) { + dev_err(&pdev->dev, + "Failed to enable the peripheral clock, %d\n", ret); + goto err_revert_dir; + } + } + + if (!screen_info.lfb_linelength) { + cgpio->apb_reset = devm_reset_control_get_optional_shared(&pdev->dev, "apb_reset"); + if (IS_ERR(cgpio->apb_reset)) { + dev_info(&pdev->dev, "[%s:%d]get reset error\n", __func__, __LINE__); + cgpio->apb_reset = NULL; + } + + /* reset gpio */ + if (cgpio->apb_reset) { + reset_control_reset(cgpio->apb_reset); + } + } else { + /* disalbe all irq to prevent unpredictable events */ + iowrite32(BIT(num_gpios) - 1, cgpio->regs + CDNS_GPIO_IRQ_DIS); } /* @@ -241,6 +323,9 @@ static int cdns_gpio_probe(struct platform_device *pdev) girq->handler = handle_level_irq; } + irq_data = irq_get_irq_data(irq); + cgpio->hw_irq = irq_data->hwirq; + ret = devm_gpiochip_add_data(&pdev->dev, &cgpio->gc, cgpio); if (ret < 0) { dev_err(&pdev->dev, "Could not register gpiochip, %d\n", ret); @@ -278,19 +363,136 @@ static int cdns_gpio_remove(struct platform_device *pdev) return 0; } +static void cdns_gpio_shutdown(struct platform_device *pdev) +{ + struct cdns_gpio_chip *cgpio = platform_get_drvdata(pdev); + struct arm_smccc_res res; + u32 gpio_wake_en; + + if (cgpio->pclk) { + /* Mask out interrupts */ + iowrite32(~cgpio->gpio_saved_reg.wake_en, cgpio->regs + CDNS_GPIO_IRQ_DIS); + gpio_wake_en = cgpio->gpio_saved_reg.wake_en; + arm_smccc_smc(SKY1_SIP_GPIO_PDC, SKY1_SIP_GPIO_PDC_SET_WAKE, + cgpio->hw_irq - 32, GPIO_ENABLE_WAKE, gpio_wake_en, 0, 0, 0, &res); + + clk_disable_unprepare(cgpio->pclk); + } +} + +static void cdns_gpio_save_regs(struct cdns_gpio_chip *cgpio) +{ + cgpio->gpio_saved_reg.bypass_mode = readl(cgpio->regs + CDNS_GPIO_BYPASS_MODE); + cgpio->gpio_saved_reg.direction_mode = readl(cgpio->regs + CDNS_GPIO_DIRECTION_MODE); + cgpio->gpio_saved_reg.output_en = readl(cgpio->regs + CDNS_GPIO_OUTPUT_EN); + cgpio->gpio_saved_reg.output_value = readl(cgpio->regs + CDNS_GPIO_OUTPUT_VALUE); + cgpio->gpio_saved_reg.irq_en = readl(cgpio->regs + CDNS_GPIO_IRQ_MASK); + cgpio->gpio_saved_reg.irq_type = readl(cgpio->regs + CDNS_GPIO_IRQ_TYPE); + cgpio->gpio_saved_reg.irq_value = readl(cgpio->regs + CDNS_GPIO_IRQ_VALUE); + cgpio->gpio_saved_reg.irq_any_edge = readl(cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE); +} + +static void cdns_gpio_restore_regs(struct cdns_gpio_chip *cgpio) +{ + writel(cgpio->gpio_saved_reg.bypass_mode, cgpio->regs + CDNS_GPIO_BYPASS_MODE); + writel(cgpio->gpio_saved_reg.direction_mode, cgpio->regs + CDNS_GPIO_DIRECTION_MODE); + writel(cgpio->gpio_saved_reg.output_en, cgpio->regs + CDNS_GPIO_OUTPUT_EN); + writel(cgpio->gpio_saved_reg.output_value ,cgpio->regs + CDNS_GPIO_OUTPUT_VALUE); + writel(cgpio->gpio_saved_reg.irq_type, cgpio->regs + CDNS_GPIO_IRQ_TYPE); + writel(cgpio->gpio_saved_reg.irq_value, cgpio->regs + CDNS_GPIO_IRQ_VALUE); + writel(cgpio->gpio_saved_reg.irq_any_edge, cgpio->regs + CDNS_GPIO_IRQ_ANY_EDGE); + writel(~cgpio->gpio_saved_reg.irq_en, cgpio->regs + CDNS_GPIO_IRQ_EN); +} + +/** + * cdns_gpio_suspend - Suspend method for GPIO driver + * @dev: Address of gpio device structure + * + * This function disable gpio device and changes + * the driver state to "suspend" + * + * Return: 0 on success and error value on error + * + */ + +static int __maybe_unused cdns_gpio_suspend(struct device *dev) +{ + struct cdns_gpio_chip *cgpio = dev_get_drvdata(dev); + struct arm_smccc_res res; + u32 gpio_wake_en; + + if (cgpio->pclk) { + cdns_gpio_save_regs(cgpio); + iowrite32(~cgpio->gpio_saved_reg.wake_en, cgpio->regs + CDNS_GPIO_IRQ_DIS); + + gpio_wake_en = cgpio->gpio_saved_reg.wake_en; + arm_smccc_smc(SKY1_SIP_GPIO_PDC, SKY1_SIP_GPIO_PDC_SET_WAKE, + cgpio->hw_irq - 32, GPIO_ENABLE_WAKE, gpio_wake_en, 0, 0, 0, &res); + + clk_disable_unprepare(cgpio->pclk); + } + + return 0; +} + +/** + * cdns_gpio_resume - Resume method for GPIO driver + * @dev: Address of the GPIO device structure + * + * This function changes the driver state to "ready" + * + * Retrun: 0 on success and error value on error + */ + +static int __maybe_unused cdns_gpio_resume(struct device *dev) +{ + + int ret; + struct cdns_gpio_chip *cgpio = dev_get_drvdata(dev); + if (cgpio->pclk) { + ret = clk_prepare_enable(cgpio->pclk); + if (ret) { + dev_err(dev, + "Failed to enable the peripheral clock, %d\n", ret); + return ret; + } + + /* reset cgpio */ + reset_control_reset(cgpio->apb_reset); + + cdns_gpio_restore_regs(cgpio); + } + return 0; +} + + +static const struct dev_pm_ops cdns_gpio_dev_ops = { + LATE_SYSTEM_SLEEP_PM_OPS(cdns_gpio_suspend, cdns_gpio_resume) +}; + static const struct of_device_id cdns_of_ids[] = { { .compatible = "cdns,gpio-r1p02" }, { /* sentinel */ }, }; MODULE_DEVICE_TABLE(of, cdns_of_ids); +static const struct acpi_device_id cdns_acpi_ids[] = { + {"CIXH1002", 0}, + {"CIXH1003", 0}, + {"", 0}, +}; +MODULE_DEVICE_TABLE(acpi, cdns_acpi_ids); + static struct platform_driver cdns_gpio_driver = { .driver = { .name = "cdns-gpio", .of_match_table = cdns_of_ids, + .acpi_match_table = ACPI_PTR(cdns_acpi_ids), + .pm = &cdns_gpio_dev_ops, }, .probe = cdns_gpio_probe, .remove = cdns_gpio_remove, + .shutdown = cdns_gpio_shutdown, }; module_platform_driver(cdns_gpio_driver); diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig index a2b4c97bcb31..e49067840d17 100644 --- a/drivers/gpu/drm/Kconfig +++ b/drivers/gpu/drm/Kconfig @@ -217,6 +217,14 @@ config DRM_EXEC help Execution context for command submissions +config DRM_GPUVM + tristate + depends on DRM + select DRM_EXEC + help + GPU-VM representation providing helpers to manage a GPUs virtual + address space + config DRM_BUDDY tristate depends on DRM @@ -374,6 +382,8 @@ source "drivers/gpu/drm/lima/Kconfig" source "drivers/gpu/drm/panfrost/Kconfig" +source "drivers/gpu/drm/panthor/Kconfig" + source "drivers/gpu/drm/aspeed/Kconfig" source "drivers/gpu/drm/mcde/Kconfig" @@ -401,6 +411,8 @@ config DRM_HYPERV If M is selected the module will be called hyperv_drm. +source "drivers/gpu/drm/cix/Kconfig" + # Keep legacy drivers last menuconfig DRM_LEGACY diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile index 215e78e79125..22dbcbd4d27a 100644 --- a/drivers/gpu/drm/Makefile +++ b/drivers/gpu/drm/Makefile @@ -45,7 +45,6 @@ drm-y := \ drm_vblank.o \ drm_vblank_work.o \ drm_vma_manager.o \ - drm_gpuva_mgr.o \ drm_writeback.o drm-$(CONFIG_DRM_LEGACY) += \ drm_agpsupport.o \ @@ -81,6 +80,7 @@ obj-$(CONFIG_DRM_PANEL_ORIENTATION_QUIRKS) += drm_panel_orientation_quirks.o # # obj-$(CONFIG_DRM_EXEC) += drm_exec.o +obj-$(CONFIG_DRM_GPUVM) += drm_gpuvm.o obj-$(CONFIG_DRM_BUDDY) += drm_buddy.o @@ -189,6 +189,7 @@ obj-$(CONFIG_DRM_XEN) += xen/ obj-$(CONFIG_DRM_VBOXVIDEO) += vboxvideo/ obj-$(CONFIG_DRM_LIMA) += lima/ obj-$(CONFIG_DRM_PANFROST) += panfrost/ +obj-$(CONFIG_DRM_PANTHOR) += panthor/ obj-$(CONFIG_DRM_ASPEED_GFX) += aspeed/ obj-$(CONFIG_DRM_MCDE) += mcde/ obj-$(CONFIG_DRM_TIDSS) += tidss/ @@ -198,3 +199,4 @@ obj-$(CONFIG_DRM_HYPERV) += hyperv/ obj-y += solomon/ obj-$(CONFIG_DRM_SPRD) += sprd/ obj-$(CONFIG_DRM_LOONGSON) += loongson/ +obj-$(CONFIG_DRM_CIX) += cix/ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c index 625db444df1c..10d56979fe3b 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_amdkfd_arcturus.c @@ -290,7 +290,7 @@ static int suspend_resume_compute_scheduler(struct amdgpu_device *adev, bool sus for (i = 0; i < adev->gfx.num_compute_rings; i++) { struct amdgpu_ring *ring = &adev->gfx.compute_ring[i]; - if (!(ring && ring->sched.thread)) + if (!(ring && drm_sched_wqueue_ready(&ring->sched))) continue; /* stop secheduler and drain ring. */ diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c index cf8804fa7e97..fbbb69b40e3c 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ctx.c @@ -72,10 +72,10 @@ amdgpu_ctx_to_drm_sched_prio(int32_t ctx_prio) return DRM_SCHED_PRIORITY_NORMAL; case AMDGPU_CTX_PRIORITY_VERY_LOW: - return DRM_SCHED_PRIORITY_MIN; + return DRM_SCHED_PRIORITY_LOW; case AMDGPU_CTX_PRIORITY_LOW: - return DRM_SCHED_PRIORITY_MIN; + return DRM_SCHED_PRIORITY_LOW; case AMDGPU_CTX_PRIORITY_NORMAL: return DRM_SCHED_PRIORITY_NORMAL; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c index 963e106d32ee..ea3f5f60b597 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_debugfs.c @@ -1671,9 +1671,9 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) for (i = 0; i < AMDGPU_MAX_RINGS; i++) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; - kthread_park(ring->sched.thread); + drm_sched_wqueue_stop(&ring->sched); } seq_puts(m, "run ib test:\n"); @@ -1687,9 +1687,9 @@ static int amdgpu_debugfs_test_ib_show(struct seq_file *m, void *unused) for (i = 0; i < AMDGPU_MAX_RINGS; i++) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; - kthread_unpark(ring->sched.thread); + drm_sched_wqueue_start(&ring->sched); } up_write(&adev->reset_domain->sem); @@ -1909,7 +1909,8 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) ring = adev->rings[val]; - if (!ring || !ring->funcs->preempt_ib || !ring->sched.thread) + if (!ring || !ring->funcs->preempt_ib || + !drm_sched_wqueue_ready(&ring->sched)) return -EINVAL; /* the last preemption failed */ @@ -1927,7 +1928,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) goto pro_end; /* stop the scheduler */ - kthread_park(ring->sched.thread); + drm_sched_wqueue_stop(&ring->sched); /* preempt the IB */ r = amdgpu_ring_preempt_ib(ring); @@ -1961,7 +1962,7 @@ static int amdgpu_debugfs_ib_preempt(void *data, u64 val) failure: /* restart the scheduler */ - kthread_unpark(ring->sched.thread); + drm_sched_wqueue_start(&ring->sched); up_read(&adev->reset_domain->sem); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c index 10f5a3d0f591..126dfbbe4a1a 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_device.c @@ -2287,7 +2287,8 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev) break; } - r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, + r = drm_sched_init(&ring->sched, &amdgpu_sched_ops, NULL, + DRM_SCHED_PRIORITY_COUNT, ring->num_hw_submission, 0, timeout, adev->reset_domain->wq, ring->sched_score, ring->name, @@ -2297,6 +2298,18 @@ static int amdgpu_device_init_schedulers(struct amdgpu_device *adev) ring->name); return r; } + r = amdgpu_uvd_entity_init(adev, ring); + if (r) { + DRM_ERROR("Failed to create UVD scheduling entity on ring %s.\n", + ring->name); + return r; + } + r = amdgpu_vce_entity_init(adev, ring); + if (r) { + DRM_ERROR("Failed to create VCE scheduling entity on ring %s.\n", + ring->name); + return r; + } } amdgpu_xcp_update_partition_sched_list(adev); @@ -2457,6 +2470,9 @@ static int amdgpu_device_ip_init(struct amdgpu_device *adev) if (r) goto init_failed; + if (adev->mman.buffer_funcs_ring->sched.ready) + amdgpu_ttm_set_buffer_funcs_status(adev, true); + /* Don't init kfd if whole hive need to be reset during init */ if (!adev->gmc.xgmi.pending_reset) { kgd2kfd_init_zone_device(adev); @@ -3052,6 +3068,8 @@ int amdgpu_device_ip_suspend(struct amdgpu_device *adev) amdgpu_virt_request_full_gpu(adev, false); } + amdgpu_ttm_set_buffer_funcs_status(adev, false); + r = amdgpu_device_ip_suspend_phase1(adev); if (r) return r; @@ -3241,6 +3259,9 @@ static int amdgpu_device_ip_resume(struct amdgpu_device *adev) r = amdgpu_device_ip_resume_phase2(adev); + if (adev->mman.buffer_funcs_ring->sched.ready) + amdgpu_ttm_set_buffer_funcs_status(adev, true); + return r; } @@ -4012,6 +4033,8 @@ void amdgpu_device_fini_hw(struct amdgpu_device *adev) /* disable ras feature must before hw fini */ amdgpu_ras_pre_fini(adev); + amdgpu_ttm_set_buffer_funcs_status(adev, false); + amdgpu_device_ip_fini_early(adev); amdgpu_irq_fini_hw(adev); @@ -4190,6 +4213,8 @@ int amdgpu_device_suspend(struct drm_device *dev, bool fbcon) if (r) return r; + amdgpu_ttm_set_buffer_funcs_status(adev, false); + amdgpu_fence_driver_hw_fini(adev); amdgpu_device_ip_suspend_phase2(adev); @@ -4625,7 +4650,7 @@ bool amdgpu_device_has_job_running(struct amdgpu_device *adev) for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; spin_lock(&ring->sched.job_list_lock); @@ -4767,7 +4792,7 @@ int amdgpu_device_pre_asic_reset(struct amdgpu_device *adev, for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; /* Clear job fence from fence drv to avoid force_completion @@ -5010,6 +5035,9 @@ int amdgpu_do_asic_reset(struct list_head *device_list_handle, if (r) goto out; + if (tmp_adev->mman.buffer_funcs_ring->sched.ready) + amdgpu_ttm_set_buffer_funcs_status(tmp_adev, true); + if (vram_lost) amdgpu_device_fill_reset_magic(tmp_adev); @@ -5307,7 +5335,7 @@ int amdgpu_device_gpu_recover(struct amdgpu_device *adev, for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = tmp_adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; drm_sched_stop(&ring->sched, job ? &job->base : NULL); @@ -5382,7 +5410,7 @@ skip_hw_reset: for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = tmp_adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; drm_sched_start(&ring->sched, true); @@ -5708,7 +5736,7 @@ pci_ers_result_t amdgpu_pci_error_detected(struct pci_dev *pdev, pci_channel_sta for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; drm_sched_stop(&ring->sched, NULL); @@ -5836,7 +5864,7 @@ void amdgpu_pci_resume(struct pci_dev *pdev) for (i = 0; i < AMDGPU_MAX_RINGS; ++i) { struct amdgpu_ring *ring = adev->rings[i]; - if (!ring || !ring->sched.thread) + if (!ring || !drm_sched_wqueue_ready(&ring->sched)) continue; drm_sched_start(&ring->sched, true); diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c index 49a6b6b88843..54a64da78803 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_job.c @@ -115,7 +115,7 @@ int amdgpu_job_alloc(struct amdgpu_device *adev, struct amdgpu_vm *vm, if (!entity) return 0; - return drm_sched_job_init(&(*job)->base, entity, owner); + return drm_sched_job_init(&(*job)->base, entity, 1, owner); } int amdgpu_job_alloc_with_ib(struct amdgpu_device *adev, @@ -326,8 +326,8 @@ void amdgpu_job_stop_all_jobs_on_sched(struct drm_gpu_scheduler *sched) int i; /* Signal all jobs not yet scheduled */ - for (i = DRM_SCHED_PRIORITY_COUNT - 1; i >= DRM_SCHED_PRIORITY_MIN; i--) { - struct drm_sched_rq *rq = &sched->sched_rq[i]; + for (i = sched->num_rqs - 1; i >= DRM_SCHED_PRIORITY_LOW; i--) { + struct drm_sched_rq *rq = sched->sched_rq[i]; spin_lock(&rq->lock); list_for_each_entry(s_entity, &rq->entities, list) { while ((s_job = to_drm_sched_job(spsc_queue_pop(&s_entity->job_queue)))) { diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c index e2b9392d7f0d..12c3e8a6eb0e 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.c @@ -289,27 +289,6 @@ out: return err; } -void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev) -{ - struct amdgpu_ring *sdma; - int i; - - for (i = 0; i < adev->sdma.num_instances; i++) { - if (adev->sdma.has_page_queue) { - sdma = &adev->sdma.instance[i].page; - if (adev->mman.buffer_funcs_ring == sdma) { - amdgpu_ttm_set_buffer_funcs_status(adev, false); - break; - } - } - sdma = &adev->sdma.instance[i].ring; - if (adev->mman.buffer_funcs_ring == sdma) { - amdgpu_ttm_set_buffer_funcs_status(adev, false); - break; - } - } -} - int amdgpu_sdma_ras_sw_init(struct amdgpu_device *adev) { int err = 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h index 513ac22120c1..173a2a308078 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_sdma.h @@ -169,7 +169,6 @@ int amdgpu_sdma_init_microcode(struct amdgpu_device *adev, u32 instance, bool duplicate); void amdgpu_sdma_destroy_inst_ctx(struct amdgpu_device *adev, bool duplicate); -void amdgpu_sdma_unset_buffer_funcs_helper(struct amdgpu_device *adev); int amdgpu_sdma_ras_sw_init(struct amdgpu_device *adev); #endif diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c index b7441654e6fa..b626c69d8664 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.c @@ -399,20 +399,20 @@ int amdgpu_uvd_sw_fini(struct amdgpu_device *adev) * * @adev: amdgpu_device pointer * + * Initialize the entity used for handle management in the kernel driver. */ -int amdgpu_uvd_entity_init(struct amdgpu_device *adev) +int amdgpu_uvd_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring) { - struct amdgpu_ring *ring; - struct drm_gpu_scheduler *sched; - int r; + if (ring == &adev->uvd.inst[0].ring) { + struct drm_gpu_scheduler *sched = &ring->sched; + int r; - ring = &adev->uvd.inst[0].ring; - sched = &ring->sched; - r = drm_sched_entity_init(&adev->uvd.entity, DRM_SCHED_PRIORITY_NORMAL, - &sched, 1, NULL); - if (r) { - DRM_ERROR("Failed setting up UVD kernel entity.\n"); - return r; + r = drm_sched_entity_init(&adev->uvd.entity, DRM_SCHED_PRIORITY_NORMAL, + &sched, 1, NULL); + if (r) { + DRM_ERROR("Failed setting up UVD kernel entity.\n"); + return r; + } } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h index 9f89bb7cd60b..872499427b99 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_uvd.h @@ -73,7 +73,7 @@ struct amdgpu_uvd { int amdgpu_uvd_sw_init(struct amdgpu_device *adev); int amdgpu_uvd_sw_fini(struct amdgpu_device *adev); -int amdgpu_uvd_entity_init(struct amdgpu_device *adev); +int amdgpu_uvd_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring); int amdgpu_uvd_suspend(struct amdgpu_device *adev); int amdgpu_uvd_resume(struct amdgpu_device *adev); int amdgpu_uvd_get_create_msg(struct amdgpu_ring *ring, uint32_t handle, diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c index 8e91355ad42c..3914ae1524cc 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.c @@ -231,20 +231,20 @@ int amdgpu_vce_sw_fini(struct amdgpu_device *adev) * * @adev: amdgpu_device pointer * + * Initialize the entity used for handle management in the kernel driver. */ -int amdgpu_vce_entity_init(struct amdgpu_device *adev) +int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring) { - struct amdgpu_ring *ring; - struct drm_gpu_scheduler *sched; - int r; + if (ring == &adev->vce.ring[0]) { + struct drm_gpu_scheduler *sched = &ring->sched; + int r; - ring = &adev->vce.ring[0]; - sched = &ring->sched; - r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL, - &sched, 1, NULL); - if (r != 0) { - DRM_ERROR("Failed setting up VCE run queue.\n"); - return r; + r = drm_sched_entity_init(&adev->vce.entity, DRM_SCHED_PRIORITY_NORMAL, + &sched, 1, NULL); + if (r != 0) { + DRM_ERROR("Failed setting up VCE run queue.\n"); + return r; + } } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h index ea680fc9a6c3..6e53f872d084 100644 --- a/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h +++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_vce.h @@ -55,7 +55,7 @@ struct amdgpu_vce { int amdgpu_vce_sw_init(struct amdgpu_device *adev, unsigned long size); int amdgpu_vce_sw_fini(struct amdgpu_device *adev); -int amdgpu_vce_entity_init(struct amdgpu_device *adev); +int amdgpu_vce_entity_init(struct amdgpu_device *adev, struct amdgpu_ring *ring); int amdgpu_vce_suspend(struct amdgpu_device *adev); int amdgpu_vce_resume(struct amdgpu_device *adev); void amdgpu_vce_free_handles(struct amdgpu_device *adev, struct drm_file *filp); diff --git a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c index 52598fbc9b39..6def8691e444 100644 --- a/drivers/gpu/drm/amd/amdgpu/cik_sdma.c +++ b/drivers/gpu/drm/amd/amdgpu/cik_sdma.c @@ -308,8 +308,6 @@ static void cik_sdma_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); rb_cntl &= ~SDMA0_GFX_RB_CNTL__RB_ENABLE_MASK; @@ -498,9 +496,6 @@ static int cik_sdma_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c index 30210613dc5c..2f3054ed7b1b 100644 --- a/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/hdp_v4_0.c @@ -42,7 +42,12 @@ static void hdp_v4_0_flush_hdp(struct amdgpu_device *adev, { if (!ring || !ring->funcs->emit_wreg) { WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); - RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); + /* We just need to read back a register to post the write. + * Reading back the remapped register causes problems on + * some platforms so just read back the memory size register. + */ + if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize(adev); } else { amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); } diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c index d3962d469088..40705e13ca56 100644 --- a/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/hdp_v5_0.c @@ -33,7 +33,12 @@ static void hdp_v5_0_flush_hdp(struct amdgpu_device *adev, { if (!ring || !ring->funcs->emit_wreg) { WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); - RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); + /* We just need to read back a register to post the write. + * Reading back the remapped register causes problems on + * some platforms so just read back the memory size register. + */ + if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize(adev); } else { amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); } diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c b/drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c index f52552c5fa27..6b9f2e1d9d69 100644 --- a/drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/hdp_v5_2.c @@ -34,7 +34,17 @@ static void hdp_v5_2_flush_hdp(struct amdgpu_device *adev, if (!ring || !ring->funcs->emit_wreg) { WREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); - RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); + if (amdgpu_sriov_vf(adev)) { + /* this is fine because SR_IOV doesn't remap the register */ + RREG32_NO_KIQ((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); + } else { + /* We just need to read back a register to post the write. + * Reading back the remapped register causes problems on + * some platforms so just read back the memory size register. + */ + if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize(adev); + } } else { amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, diff --git a/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c b/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c index b6d71ec1debf..0d0c568f3839 100644 --- a/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/hdp_v6_0.c @@ -33,7 +33,12 @@ static void hdp_v6_0_flush_hdp(struct amdgpu_device *adev, { if (!ring || !ring->funcs->emit_wreg) { WREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); - RREG32((adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2); + /* We just need to read back a register to post the write. + * Reading back the remapped register causes problems on + * some platforms so just read back the memory size register. + */ + if (adev->nbio.funcs->get_memsize) + adev->nbio.funcs->get_memsize(adev); } else { amdgpu_ring_emit_wreg(ring, (adev->rmmio_remap.reg_offset + KFD_MMIO_REMAP_HDP_MEM_FLUSH_CNTL) >> 2, 0); } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c index 51afc92994a8..e3f5af4762d0 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v2_4.c @@ -339,8 +339,6 @@ static void sdma_v2_4_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -474,9 +472,6 @@ static int sdma_v2_4_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c index 344202870aeb..94dcce3c73b2 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v3_0.c @@ -513,8 +513,6 @@ static void sdma_v3_0_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32(mmSDMA0_GFX_RB_CNTL + sdma_offsets[i]); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -746,9 +744,6 @@ static int sdma_v3_0_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c index 0ba9a3d3312f..dfcb792f1047 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v4_0.c @@ -875,8 +875,6 @@ static void sdma_v4_0_gfx_enable(struct amdgpu_device *adev, bool enable) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SDMA(i, mmSDMA0_GFX_RB_CNTL); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, enable ? 1 : 0); @@ -911,8 +909,6 @@ static void sdma_v4_0_page_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SDMA(i, mmSDMA0_PAGE_RB_CNTL); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_PAGE_RB_CNTL, @@ -1399,13 +1395,7 @@ static int sdma_v4_0_start(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(page); if (r) return r; - - if (adev->mman.buffer_funcs_ring == page) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return r; @@ -1917,11 +1907,8 @@ static int sdma_v4_0_hw_fini(void *handle) struct amdgpu_device *adev = (struct amdgpu_device *)handle; int i; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } if (amdgpu_ras_is_supported(adev, AMDGPU_RAS_BLOCK__SDMA)) { for (i = 0; i < adev->sdma.num_instances; i++) { @@ -1960,7 +1947,6 @@ static int sdma_v4_0_resume(void *handle) if (adev->in_s0ix) { sdma_v4_0_enable(adev, true); sdma_v4_0_gfx_enable(adev, true); - amdgpu_ttm_set_buffer_funcs_status(adev, true); return 0; } diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c index 1cc34efb455b..7d7b86048e68 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_0.c @@ -559,8 +559,6 @@ static void sdma_v5_0_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_0_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL)); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -825,9 +823,6 @@ static int sdma_v5_0_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; @@ -1427,11 +1422,8 @@ static int sdma_v5_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } sdma_v5_0_ctx_switch_enable(adev, false); sdma_v5_0_enable(adev, false); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c index 47d4840c6275..79002b614a7f 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v5_2.c @@ -376,8 +376,6 @@ static void sdma_v5_2_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SOC15_IP(GC, sdma_v5_2_get_reg_offset(adev, i, mmSDMA0_GFX_RB_CNTL)); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_GFX_RB_CNTL, RB_ENABLE, 0); @@ -637,9 +635,6 @@ static int sdma_v5_2_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; @@ -1297,11 +1292,8 @@ static int sdma_v5_2_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } sdma_v5_2_ctx_switch_enable(adev, false); sdma_v5_2_enable(adev, false); diff --git a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c index 45be0af2570b..c35bc0f0c1dd 100644 --- a/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/sdma_v6_0.c @@ -381,8 +381,6 @@ static void sdma_v6_0_gfx_stop(struct amdgpu_device *adev) u32 rb_cntl, ib_cntl; int i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { rb_cntl = RREG32_SOC15_IP(GC, sdma_v6_0_get_reg_offset(adev, i, regSDMA0_QUEUE0_RB_CNTL)); rb_cntl = REG_SET_FIELD(rb_cntl, SDMA0_QUEUE0_RB_CNTL, RB_ENABLE, 0); @@ -594,9 +592,6 @@ static int sdma_v6_0_gfx_resume(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; @@ -1343,11 +1338,8 @@ static int sdma_v6_0_hw_fini(void *handle) { struct amdgpu_device *adev = (struct amdgpu_device *)handle; - if (amdgpu_sriov_vf(adev)) { - /* disable the scheduler for SDMA */ - amdgpu_sdma_unset_buffer_funcs_helper(adev); + if (amdgpu_sriov_vf(adev)) return 0; - } sdma_v6_0_ctxempty_int_enable(adev, false); sdma_v6_0_enable(adev, false); diff --git a/drivers/gpu/drm/amd/amdgpu/si_dma.c b/drivers/gpu/drm/amd/amdgpu/si_dma.c index 42c4547f32ec..9aa0e11ee673 100644 --- a/drivers/gpu/drm/amd/amdgpu/si_dma.c +++ b/drivers/gpu/drm/amd/amdgpu/si_dma.c @@ -115,8 +115,6 @@ static void si_dma_stop(struct amdgpu_device *adev) u32 rb_cntl; unsigned i; - amdgpu_sdma_unset_buffer_funcs_helper(adev); - for (i = 0; i < adev->sdma.num_instances; i++) { /* dma0 */ rb_cntl = RREG32(DMA_RB_CNTL + sdma_offsets[i]); @@ -177,9 +175,6 @@ static int si_dma_start(struct amdgpu_device *adev) r = amdgpu_ring_test_helper(ring); if (r) return r; - - if (adev->mman.buffer_funcs_ring == ring) - amdgpu_ttm_set_buffer_funcs_status(adev, true); } return 0; diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c index 5534c769b655..447115581251 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v3_1.c @@ -577,8 +577,6 @@ static int uvd_v3_1_sw_init(void *handle) ptr += ucode_len; memcpy(&adev->uvd.keyselect, ptr, 4); - r = amdgpu_uvd_entity_init(adev); - return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c index c108b8381795..6adf2bc1303e 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v4_2.c @@ -127,8 +127,6 @@ static int uvd_v4_2_sw_init(void *handle) if (r) return r; - r = amdgpu_uvd_entity_init(adev); - return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c index d7e31e48a2b8..759309e7a3c4 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v5_0.c @@ -125,8 +125,6 @@ static int uvd_v5_0_sw_init(void *handle) if (r) return r; - r = amdgpu_uvd_entity_init(adev); - return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c index 5fe872f4bea7..9cf958a9870c 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v6_0.c @@ -432,8 +432,6 @@ static int uvd_v6_0_sw_init(void *handle) } } - r = amdgpu_uvd_entity_init(adev); - return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c index 4fba0b3d10f1..823639f6f039 100644 --- a/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c +++ b/drivers/gpu/drm/amd/amdgpu/uvd_v7_0.c @@ -480,10 +480,6 @@ static int uvd_v7_0_sw_init(void *handle) if (r) return r; - r = amdgpu_uvd_entity_init(adev); - if (r) - return r; - r = amdgpu_virt_alloc_mm_table(adev); if (r) return r; diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c index 67eb01fef789..a08e7abca423 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v2_0.c @@ -441,8 +441,6 @@ static int vce_v2_0_sw_init(void *handle) return r; } - r = amdgpu_vce_entity_init(adev); - return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c index 18f6e62af339..f4760748d349 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v3_0.c @@ -450,8 +450,6 @@ static int vce_v3_0_sw_init(void *handle) return r; } - r = amdgpu_vce_entity_init(adev); - return r; } diff --git a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c index e0b70cd3b697..06d787385ad4 100644 --- a/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c +++ b/drivers/gpu/drm/amd/amdgpu/vce_v4_0.c @@ -486,11 +486,6 @@ static int vce_v4_0_sw_init(void *handle) return r; } - - r = amdgpu_vce_entity_init(adev); - if (r) - return r; - r = amdgpu_virt_alloc_mm_table(adev); if (r) return r; diff --git a/drivers/gpu/drm/cix/Kconfig b/drivers/gpu/drm/cix/Kconfig new file mode 100644 index 000000000000..c826b9decd7c --- /dev/null +++ b/drivers/gpu/drm/cix/Kconfig @@ -0,0 +1,55 @@ +# SPDX-License-Identifier: GPL-2.0-only +config DRM_CIX + tristate "DRM Support for CiX Socs" + select DRM_KMS_HELPER + select VIDEOMODE_HELPERS + select DRM_GEM_DMA_HELPER + depends on DRM && ARCH_CIX + help + enable CiX DRM display support + +config DRM_LINLONDP + tristate "ARMCHINA LINLON display driver" + depends on DRM && OF + depends on COMMON_CLK + depends on DRM_CIX + select DRM_KMS_HELPER + select DRM_GEM_DMA_HELPER + select VIDEOMODE_HELPERS + help + Choose this option if you want to compile the ARMCHINA Linlon display + Processor driver. It supports the DP variants of the hardware. + If compiled as a module it will be called linlondp. + +config DRM_CIX_VIRTUAL + tristate "DRM Support for CiX Virtual Encoder" + depends on DRM_CIX + default y + help + This is a virtual encoder and connector support which is + mainly used on EMU and FPGA. Disabled in default. + +config DRM_LINLONDP_CLOCK_FIXED + bool "linlondp clocks use fixed frequency" + depends on DRM_CIX + help + Choose this if linlondp clocks use fixed frequency + +config DRM_TRILIN_DP_CIX + tristate "DRM Support for Trilinear DisplayPort on CiX platforms" + depends on DRM_CIX + help + Choose this if you want to use DP display on CiX Socs + +config DRM_CIX_EDP_PANEL + tristate "DRM Support for edp panel on CiX platforms" + help + Choose this if you want to use edp panel on CiX Socs + +config DRM_CIX_COMPONENT_BIND_BYPASSED + bool "DRM bypass component bind operation" + depends on DRM_CIX + help + Choose this if you do not want to use drm component bind operation + +source "drivers/gpu/drm/cix/dptx/Kconfig" diff --git a/drivers/gpu/drm/cix/Makefile b/drivers/gpu/drm/cix/Makefile new file mode 100644 index 000000000000..10ff04825a6a --- /dev/null +++ b/drivers/gpu/drm/cix/Makefile @@ -0,0 +1,5 @@ +# SPDX-License-Identifier: GPL-2.0 + +obj-$(CONFIG_DRM_CIX_VIRTUAL) += cix_virtual.o +obj-$(CONFIG_DRM_LINLONDP) += linlon-dp/ +obj-$(CONFIG_DRM_TRILIN_DPSUB) += dptx/ diff --git a/drivers/gpu/drm/cix/cix_display.c b/drivers/gpu/drm/cix/cix_display.c new file mode 100644 index 000000000000..2f9bd7cee38e --- /dev/null +++ b/drivers/gpu/drm/cix/cix_display.c @@ -0,0 +1,204 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include + +#define DPU0_RESET_MASK BIT(16) +#define DPU1_RESET_MASK BIT(17) +#define DPU2_RESET_MASK BIT(18) +#define DPU3_RESET_MASK BIT(19) +#define DPU4_RESET_MASK BIT(20) + +#define DP0_RESET_MASK BIT(21) +#define DP1_RESET_MASK BIT(22) +#define DP2_RESET_MASK BIT(23) +#define DP3_RESET_MASK BIT(24) +#define DP4_RESET_MASK BIT(25) + +#define MMHUB_RESET_MASK BIT(4) + +#define DISPLAY0_RESET_MASK (DPU0_RESET_MASK | DP0_RESET_MASK) +#define DISPLAY1_RESET_MASK (DPU1_RESET_MASK | DP1_RESET_MASK) +#define DISPLAY2_RESET_MASK (DPU2_RESET_MASK | DP2_RESET_MASK) +#define DISPLAY3_RESET_MASK (DPU3_RESET_MASK | DP3_RESET_MASK) +#define DISPLAY4_RESET_MASK (DPU4_RESET_MASK | DP4_RESET_MASK) + +#define DISPLAY_RESET_REG 0x16000400 + +struct cix_display_dev { + struct device *dev; + u32 reset_mask[5]; + bool reset_need[5]; +}; + +struct cix_acpi_display { + u32 reset_mask[5]; + bool reset_need[5]; +}; + +static const struct of_device_id cix_display_dt_ids[] = { + { .compatible = "cix,display", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, cix_display_dt_ids); + +static const struct acpi_device_id cix_display_acpi_ids[] = { + { .id = "CIXH5008", .driver_data = 0, }, + {}, +}; +MODULE_DEVICE_TABLE(acpi, cix_display_acpi_ids); + +static int cix_display_probe(struct platform_device *pdev) +{ + struct cix_display_dev *cix_display; + struct device *dev = &pdev->dev; + void *base; + int i, ret; + u32 control, value, count; + + dev_info(dev, "%s enter.\n", __func__); + + cix_display = devm_kzalloc(dev, sizeof(*cix_display), GFP_KERNEL); + if (!cix_display) + return -ENOMEM; + + ret = device_property_read_u32(dev, "reset-control", (u32 *)&control); + if (ret) { + control = 0; + dev_info(dev, "failed to get reset-control, use default value\n"); + } + + cix_display->reset_mask[0] = DISPLAY0_RESET_MASK; + cix_display->reset_mask[1] = DISPLAY1_RESET_MASK; + cix_display->reset_mask[2] = DISPLAY2_RESET_MASK; + cix_display->reset_mask[3] = DISPLAY3_RESET_MASK; + cix_display->reset_mask[4] = DISPLAY4_RESET_MASK; + + base = ioremap(DISPLAY_RESET_REG, 0x4); + + value = readl(base); + dev_info(dev, "current reset value = 0x%x, reset-control=%d\n", value, control); + + count = 0; + for (i = 0; i < 5; i++) { + cix_display->reset_need[i] = (control >> i) & 0x1; + if (cix_display->reset_need[i]) { + count++; + value &= (~cix_display->reset_mask[i]); + } + } + + if (count) { + value &= (~MMHUB_RESET_MASK); + writel(value, base); + dev_info(dev, "assert reset, value = 0x%x, count=%d\n", value, count); + } + + for (i = 0; i < 5; i++) { + if (cix_display->reset_need[i]) { + value |= cix_display->reset_mask[i]; + } + } + + if (count) { + value |= MMHUB_RESET_MASK; + writel(value, base); + dev_info(dev, "deassert reset, value = 0x%x\n", value); + } + + value = readl(base); + dev_info(dev, "current reset value = 0x%x\n", value); + + iounmap(base); + + cix_display->dev = dev; + + dev_set_drvdata(dev, cix_display); + + return 0; +} + +static struct cix_acpi_display cix_acpi_display; +static int __init cix_acpi_display_probe(void) +{ + void *base; + int i, ret; + u32 control, value, count; + struct cix_acpi_display *cix_display = &cix_acpi_display; + memset(cix_display, 0, sizeof(*cix_display)); + control = 4; + + cix_display->reset_mask[0] = DISPLAY0_RESET_MASK; + cix_display->reset_mask[1] = DISPLAY1_RESET_MASK; + cix_display->reset_mask[2] = DISPLAY2_RESET_MASK; + cix_display->reset_mask[3] = DISPLAY3_RESET_MASK; + cix_display->reset_mask[4] = DISPLAY4_RESET_MASK; + + base = ioremap(DISPLAY_RESET_REG, 0x4); + + value = readl(base); + + count = 0; + for (i = 0; i < 5; i++) { + cix_display->reset_need[i] = (control >> i) & 0x1; + if (cix_display->reset_need[i]) { + count++; + value &= (~cix_display->reset_mask[i]); + } + } + + if (count) { + value &= (~MMHUB_RESET_MASK); + writel(value, base); + } + + for (i = 0; i < 5; i++) { + if (cix_display->reset_need[i]) { + value |= cix_display->reset_mask[i]; + } + } + + if (count) { + value |= MMHUB_RESET_MASK; + writel(value, base); + } + + value = readl(base); + + iounmap(base); + + return 0; +} + +static int cix_display_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + dev_set_drvdata(dev, NULL); + + return 0; +} + +struct platform_driver cix_display_driver = { + .probe = cix_display_probe, + .remove = cix_display_remove, + .driver = { + .name = "cix-display", + .of_match_table = of_match_ptr(cix_display_dt_ids), + .acpi_match_table = ACPI_PTR(cix_display_acpi_ids), + }, +}; + +core_initcall(cix_acpi_display_probe); + +MODULE_DESCRIPTION("Cix Display Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:cix-display"); + diff --git a/drivers/gpu/drm/cix/cix_virtual.c b/drivers/gpu/drm/cix/cix_virtual.c new file mode 100644 index 000000000000..c8b895184607 --- /dev/null +++ b/drivers/gpu/drm/cix/cix_virtual.c @@ -0,0 +1,313 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright 2024 Cix Technology Group Co., Ltd. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include + +#define XRES_MAX 4096 +#define YRES_MAX 4096 + +#define XRES_DEF 640 +#define YRES_DEF 480 + +struct cix_virtual_dev { + struct device *dev; + struct drm_encoder encoder; + struct drm_connector connector; +}; + +static const struct drm_display_mode cix_drm_dmt_modes[] = { + /* 0x04 - 640x480@60Hz */ + { DRM_MODE("640x480", DRM_MODE_TYPE_DRIVER, 25175, 640, 656, + 752, 800, 0, 480, 490, 492, 525, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 0x09 - 800x600@60Hz */ + { DRM_MODE("800x600", DRM_MODE_TYPE_DRIVER, 40000, 800, 840, + 968, 1056, 0, 600, 601, 605, 628, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 0x10 - 1024x768@60Hz */ + { DRM_MODE("1024x768", DRM_MODE_TYPE_DRIVER, 65000, 1024, 1048, + 1184, 1344, 0, 768, 771, 777, 806, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 0x55 - 1280x720@60Hz */ + { DRM_MODE("1280x720", DRM_MODE_TYPE_DRIVER, 74250, 1280, 1390, + 1430, 1650, 0, 720, 725, 730, 750, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 0x52 - 1920x1080@60Hz */ + { DRM_MODE("1920x1080", DRM_MODE_TYPE_DRIVER, 148500, 1920, 2008, + 2052, 2200, 0, 1080, 1084, 1089, 1125, 0, + DRM_MODE_FLAG_NHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 0x51 - 3840x2160@60Hz 16:9 */ + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 594000, 3840, 4016, + 4104, 4400, 0, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_PVSYNC) }, + /* 0x52 - 3840x2160@90Hz 16:9 */ + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 891000, 3840, 4016, + 4104, 4400, 0, 2160, 2168, 2178, 2250, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 0x53 - 3840x2160@120Hz 16:9 */ + { DRM_MODE("3840x2160", DRM_MODE_TYPE_DRIVER, 1075804, 3840, 3848, + 3880, 3920, 0, 2160, 2273, 2281, 2287, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, + /* 0x54 - 3840x1080@90Hz 16:9 */ + { DRM_MODE("3840x1080", DRM_MODE_TYPE_DRIVER, 397605, 3840, 3848, + 3880, 3920, 0, 1080, 1113, 1121, 1127, 0, + DRM_MODE_FLAG_PHSYNC | DRM_MODE_FLAG_NVSYNC) }, +}; + +static int +cix_virtual_encoder_atomic_check(struct drm_encoder *encoder, + struct drm_crtc_state *crtc_state, + struct drm_connector_state *conn_state) +{ + /* TODO */ + + return 0; +} + +static const struct drm_encoder_helper_funcs +cix_virtual_encoder_helper_funcs = { + .atomic_check = cix_virtual_encoder_atomic_check, +}; + +static int cix_virtual_add_modes_noedid(struct drm_connector *connector, + int hdisplay, int vdisplay) +{ + int i, count, num_modes = 0; + struct drm_display_mode *mode; + struct drm_device *dev = connector->dev; + + count = ARRAY_SIZE(cix_drm_dmt_modes); + + for (i = 0; i < count; i++) { + const struct drm_display_mode *ptr = &cix_drm_dmt_modes[i]; + + if (hdisplay && vdisplay) { + if (ptr->hdisplay > hdisplay || + ptr->vdisplay > vdisplay) + continue; + } + + mode = drm_mode_duplicate(dev, ptr); + if (mode) { + drm_mode_probed_add(connector, mode); + num_modes++; + } + } + return num_modes; +} + +static int +cix_virtual_connector_get_modes(struct drm_connector *connector) +{ + int count; + + count = cix_virtual_add_modes_noedid(connector, XRES_MAX, YRES_MAX); + drm_set_preferred_mode(connector, XRES_DEF, YRES_DEF); + + return count; +} + +static const struct drm_connector_helper_funcs +cix_virtual_connector_helper_funcs = { + .get_modes = cix_virtual_connector_get_modes, +}; + +static const struct drm_connector_funcs +cix_virtual_connector_funcs = { + .fill_modes = drm_helper_probe_single_connector_modes, + .destroy = drm_connector_cleanup, + .reset = drm_atomic_helper_connector_reset, + .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, + .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, +}; + +static uint32_t drm_acpi_crtc_port_mask(struct drm_device *dev, + struct fwnode_handle *port) +{ + unsigned int index = 0; + struct drm_crtc *tmp; + + drm_for_each_crtc(tmp, dev) { + if ((struct fwnode_handle *)tmp->port == port) { + pr_info("cix_virtual.drm_acpi_crtc_port_mask, port=%s\n", + port->ops->get_name(port)); + return 1 << index; + } + + index++; + } + + return 0; +} + +static uint32_t drm_acpi_find_possible_crtcs(struct drm_device *dev, + struct fwnode_handle *port) +{ + struct fwnode_handle *remote_port, *ep; + uint32_t possible_crtcs = 0; + + fwnode_graph_for_each_endpoint(port, ep) { + remote_port = fwnode_graph_get_remote_port(ep); + if (!remote_port) { + fwnode_handle_put(ep); + return 0; + } + + possible_crtcs |= drm_acpi_crtc_port_mask(dev, remote_port); + + fwnode_handle_put(remote_port); + } + + return possible_crtcs; +} + +static int +cix_virtual_bind(struct device *comp, struct device *master, + void *master_data) +{ + int ret; + struct drm_encoder *encoder; + struct drm_connector *connector; + struct drm_device *drm = master_data; + void *np; + + struct cix_virtual_dev *vd = dev_get_drvdata(comp); + + /* TODO: parse dt */ + + /* Init virtual encoder */ + encoder = &vd->encoder; + + drm_encoder_helper_add(encoder, &cix_virtual_encoder_helper_funcs); + + ret = drm_simple_encoder_init(drm, encoder, DRM_MODE_ENCODER_VIRTUAL); + if (ret) { + dev_err(vd->dev, "failed to init simple encoder : %d\n", ret); + return ret; + } + + if (has_acpi_companion(comp)) { + pr_info("dwx: cix_virtual start to call cix_virtual_bind via ACPI.\n"); + np = comp->fwnode; + encoder->possible_crtcs = drm_acpi_find_possible_crtcs(drm, (struct fwnode_handle *)np); + } else { + pr_info("dwx: cix_virtual start to call cix_virtual_bind via DT.\n"); + np = comp->of_node; + encoder->possible_crtcs = drm_of_find_possible_crtcs(drm, (struct device_node *)np); + } + + if (encoder->possible_crtcs == 0) + return -EPROBE_DEFER; + + /* Init virtual connector */ + connector = &vd->connector; + + drm_connector_helper_add(connector, &cix_virtual_connector_helper_funcs); + + ret = drm_connector_init(drm, connector, &cix_virtual_connector_funcs, + DRM_MODE_CONNECTOR_VIRTUAL); + if (ret) { + dev_err(vd->dev, "failed to init connector: %d\n", ret); + return ret; + } + + ret = drm_connector_attach_encoder(connector, encoder); + if (ret) { + dev_err(vd->dev, "Failed to attach connector to encoder\n"); + return ret; + } + + /* Set supported color formats */ + connector->display_info.color_formats = DRM_COLOR_FORMAT_RGB444 | + DRM_COLOR_FORMAT_YCBCR422 | + DRM_COLOR_FORMAT_YCBCR420; + + return 0; +} + +static void +cix_virtual_unbind(struct device *comp, struct device *master, + void *master_data) +{ + struct cix_virtual_dev *vd = dev_get_drvdata(comp); + + drm_connector_cleanup(&vd->connector); + drm_encoder_cleanup(&vd->encoder); +} + +const struct component_ops cix_virtual_ops = { + .bind = cix_virtual_bind, + .unbind = cix_virtual_unbind, +}; + +static const struct of_device_id cix_virtual_dt_ids[] = { + { .compatible = "cix,virtual-display", }, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(of, cix_virtual_dt_ids); + +static const struct acpi_device_id cix_virtual_acpi_ids[] = { + { .id = "CIXH503F", 0}, + { /* sentinel */ }, +}; +MODULE_DEVICE_TABLE(acpi, cix_virtual_acpi_ids); + +static int cix_virtual_probe(struct platform_device *pdev) +{ + struct cix_virtual_dev *vd; + struct device *dev = &pdev->dev; + pr_info("dwx: cix_virtual_probe enter.\n"); + vd = devm_kzalloc(dev, sizeof(*vd), GFP_KERNEL); + if (!vd) + return -ENOMEM; + + vd->dev = dev; + + dev_set_drvdata(dev, vd); + + return component_add(dev, &cix_virtual_ops); +} + +static int cix_virtual_remove(struct platform_device *pdev) +{ + struct device *dev = &pdev->dev; + + component_del(dev, &cix_virtual_ops); + + dev_set_drvdata(dev, NULL); + + return 0; +} + +struct platform_driver cix_virtual_driver = { + .probe = cix_virtual_probe, + .remove = cix_virtual_remove, + .driver = { + .name = "cix-virtual-display", + .of_match_table = of_match_ptr(cix_virtual_dt_ids), + .acpi_match_table = ACPI_PTR(cix_virtual_acpi_ids), + }, +}; + +module_platform_driver(cix_virtual_driver); + +MODULE_AUTHOR("Fancy Fang "); +MODULE_DESCRIPTION("Cix DRM Virtual Display Driver"); +MODULE_LICENSE("GPL v2"); +MODULE_ALIAS("platform:cix-virtual"); diff --git a/drivers/gpu/drm/cix/dptx/Kconfig b/drivers/gpu/drm/cix/dptx/Kconfig new file mode 100644 index 000000000000..08e5641df6a6 --- /dev/null +++ b/drivers/gpu/drm/cix/dptx/Kconfig @@ -0,0 +1,27 @@ +#SPDX - License - Identifier : GPL - 2.0 - only +config DRM_TRILIN_DPSUB + tristate "Trilinear Technologies DisplayPort Controller Driver" + depends on COMMON_CLK && DRM && OF + select DRM_KMS_HELPER + select DRM_DISPLAY_HELPER + select DRM_DISPLAY_DP_HELPER + select DRM_DISPLAY_HDMI_HELPER + select DRM_DP_AUX_CHARDEV + select GENERIC_PHY + select SND_SOC_HDMI_CODEC if SND_SOC + help + This is a DRM/KMS driver for Trilinear Technologies DisplayPort controller. + Choose this option if you are using an SoC with a Trilinear Technologies + DisplayPort subsystem. + +config TRILIN_DP_HDCP_VALIDATION + tristate "HDCP Validation for Trilinear DisplayPort on CiX platforms" + help + Choose this if you want to validate DP HDCP on CiX Socs during presilicon + +config DRM_TRILIN_CADENCE_PHY + tristate "Trilinear DisplayPort Controller with Cadence PHY" + depends on DRM_TRILIN_DPSUB + help + Choose this option if you are using a proper platform with a Trilinear + Technologies DisplayPort subsystem. diff --git a/drivers/gpu/drm/cix/dptx/Makefile b/drivers/gpu/drm/cix/dptx/Makefile new file mode 100644 index 000000000000..1d3c95b31889 --- /dev/null +++ b/drivers/gpu/drm/cix/dptx/Makefile @@ -0,0 +1,11 @@ +trilin-dpsub-y := trilin_dptx_cix.o trilin_dptx.o trilin_host_tmr.o dptx_infoframe.o trilin_dptx_audio.o trilin_drm.o trilin_drm_mst.o +trilin-dpsub-y += trilin_edp_phy.o trilin_usbdp_phy.o +trilin-dpsub-$(CONFIG_TRILIN_DP_HDCP_VALIDATION) += hdcp/hdcp2_hw_tx.o +trilin-dpsub-$(CONFIG_TRILIN_DP_HDCP_VALIDATION) += hdcp/hdcp2_key_drvn_tx.o +trilin-dpsub-$(CONFIG_TRILIN_DP_HDCP_VALIDATION) += hdcp/hdcp2_tx_state.o +trilin-dpsub-y += hdcp/hdcp2_tx_tmr.o +trilin-dpsub-y += hdcp/cix_hdcp_ioctl.o +trilin-dpsub-y += hdcp/cix_hdcp.o +trilin-dpsub-y += cix_edp_panel.o + +obj-$(CONFIG_DRM_TRILIN_DPSUB) += trilin-dpsub.o \ No newline at end of file diff --git a/drivers/gpu/drm/cix/dptx/cix_edp_panel.c b/drivers/gpu/drm/cix/dptx/cix_edp_panel.c new file mode 100644 index 000000000000..baa4c571a80d --- /dev/null +++ b/drivers/gpu/drm/cix/dptx/cix_edp_panel.c @@ -0,0 +1,881 @@ +// SPDX-License-Identifier: GPL-2.0 +/* + * Copyright (C) 2013, NVIDIA Corporation. All rights reserved. + * Copyright 2024-2025 Cix Technology Group Co., Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the "Software"), + * to deal in the Software without restriction, including without limitation + * the rights to use, copy, modify, merge, publish, distribute, sub license, + * and/or sell copies of the Software, and to permit persons to whom the + * Software is furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice (including the + * next paragraph) shall be included in all copies or substantial portions + * of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + * DEALINGS IN THE SOFTWARE. + */ + +#include +#include +#include +#include +#include +#include +#include + +#include